Compare commits
16 Commits
c18973e528
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| ff20f6f23a | |||
| 581bd40184 | |||
| 2851e8eb54 | |||
| 4ab2c167e5 | |||
| 9400889f29 | |||
| 4a16a0901c | |||
| 34ac109f93 | |||
| 07501975dc | |||
| 399b880f16 | |||
| 35f596ba69 | |||
| 4cf80fed45 | |||
| 67b70c80e7 | |||
| 964126953a | |||
| 840df2fb3c | |||
| fdf524a172 | |||
| e5fa256fb0 |
@ -8,6 +8,10 @@ on:
|
|||||||
- '.gitea/workflows/deploy-admin.yml'
|
- '.gitea/workflows/deploy-admin.yml'
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
|
env:
|
||||||
|
BUN_VERSION: 'latest'
|
||||||
|
CACHE_KEY: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lock') }}
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
test-and-build:
|
test-and-build:
|
||||||
name: 🧪 测试和构建
|
name: 🧪 测试和构建
|
||||||
@ -20,57 +24,44 @@ jobs:
|
|||||||
- name: 🥖 设置 Bun 环境
|
- name: 🥖 设置 Bun 环境
|
||||||
uses: oven-sh/setup-bun@v1
|
uses: oven-sh/setup-bun@v1
|
||||||
with:
|
with:
|
||||||
bun-version: latest
|
bun-version: ${{ env.BUN_VERSION }}
|
||||||
|
|
||||||
|
- name: 💾 缓存 Bun 依赖
|
||||||
|
uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
path: |
|
||||||
|
~/.bun/install/cache
|
||||||
|
admin/node_modules
|
||||||
|
key: ${{ env.CACHE_KEY }}-${{ hashFiles('admin/bun.lock') }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ env.CACHE_KEY }}-
|
||||||
|
|
||||||
- name: 📦 安装依赖
|
- name: 📦 安装依赖
|
||||||
working-directory: ./admin
|
working-directory: ./admin
|
||||||
run: bun install --frozen-lockfile
|
run: bun install --frozen-lockfile
|
||||||
|
|
||||||
- name: 🔍 代码检查
|
- name: 🏗️ 并行质量检查和构建
|
||||||
working-directory: ./admin
|
|
||||||
run: |
|
|
||||||
bun run lint
|
|
||||||
bun run type-check
|
|
||||||
|
|
||||||
- name: 🎨 格式检查
|
|
||||||
working-directory: ./admin
|
|
||||||
run: bun run format
|
|
||||||
|
|
||||||
- name: 🧪 运行测试
|
|
||||||
working-directory: ./admin
|
|
||||||
run: bun run test
|
|
||||||
|
|
||||||
- name: 🔒 安全审计
|
|
||||||
working-directory: ./admin
|
|
||||||
run: bun audit
|
|
||||||
|
|
||||||
- name: 🏗️ 构建生产版本
|
|
||||||
working-directory: ./admin
|
working-directory: ./admin
|
||||||
env:
|
env:
|
||||||
VITE_APP_TITLE: 摄影作品集管理后台
|
VITE_APP_TITLE: 摄影作品集管理后台
|
||||||
VITE_API_BASE_URL: https://api.photography.iriver.top
|
VITE_API_BASE_URL: https://api.photography.iriver.top
|
||||||
VITE_UPLOAD_URL: https://api.photography.iriver.top/upload
|
VITE_UPLOAD_URL: https://api.photography.iriver.top/upload
|
||||||
run: bun run build
|
|
||||||
|
|
||||||
- name: 📊 构建分析
|
|
||||||
working-directory: ./admin
|
|
||||||
run: |
|
run: |
|
||||||
echo "📦 构建产物分析:"
|
# 并行执行代码检查和构建
|
||||||
du -sh dist/
|
bun run lint &
|
||||||
echo "📁 文件列表:"
|
bun run type-check &
|
||||||
find dist/ -type f -name "*.js" -o -name "*.css" | head -10
|
bun run build &
|
||||||
echo "📈 文件大小统计:"
|
wait
|
||||||
find dist/ -type f \( -name "*.js" -o -name "*.css" \) -exec ls -lh {} + | awk '{print $5, $9}' | sort -hr | head -10
|
|
||||||
|
|
||||||
- name: 📦 打包构建产物
|
- name: 📦 打包构建产物
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: admin-dist
|
name: admin-dist-${{ github.sha }}
|
||||||
path: admin/dist/
|
path: admin/dist/
|
||||||
retention-days: 7
|
retention-days: 1
|
||||||
|
|
||||||
deploy:
|
deploy:
|
||||||
name: 🚀 部署到生产环境
|
name: 🚀 部署管理后台
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: test-and-build
|
needs: test-and-build
|
||||||
if: github.ref == 'refs/heads/main'
|
if: github.ref == 'refs/heads/main'
|
||||||
@ -79,259 +70,66 @@ jobs:
|
|||||||
- name: 📥 检出代码
|
- name: 📥 检出代码
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: 🥖 设置 Bun 环境
|
- name: 📥 下载构建产物
|
||||||
uses: oven-sh/setup-bun@v1
|
uses: actions/download-artifact@v3
|
||||||
with:
|
with:
|
||||||
bun-version: latest
|
name: admin-dist-${{ github.sha }}
|
||||||
|
path: admin/dist/
|
||||||
|
|
||||||
- name: 📦 安装依赖
|
- name: 📤 上传并部署
|
||||||
working-directory: ./admin
|
uses: appleboy/scp-action@v0.1.6
|
||||||
run: bun install --frozen-lockfile
|
with:
|
||||||
|
host: ${{ secrets.ALIYUN_IP }}
|
||||||
|
username: ${{ secrets.ALIYUN_USER_NAME }}
|
||||||
|
password: ${{ secrets.ALIYUN_PWD }}
|
||||||
|
port: 22
|
||||||
|
source: "admin/dist/"
|
||||||
|
target: "/tmp/admin-build"
|
||||||
|
rm: true
|
||||||
|
|
||||||
- name: 🏗️ 构建生产版本
|
- name: 🔄 部署文件到生产目录
|
||||||
working-directory: ./admin
|
|
||||||
env:
|
|
||||||
VITE_APP_TITLE: 摄影作品集管理后台
|
|
||||||
VITE_API_BASE_URL: https://api.photography.iriver.top
|
|
||||||
VITE_UPLOAD_URL: https://api.photography.iriver.top/upload
|
|
||||||
run: bun run build
|
|
||||||
|
|
||||||
- name: 📊 压缩构建产物
|
|
||||||
working-directory: ./admin
|
|
||||||
run: |
|
|
||||||
# 使用国内镜像源安装压缩工具
|
|
||||||
echo "🔄 使用国内镜像源..."
|
|
||||||
sudo sed -i 's|http://.*.ubuntu.com|https://mirrors.aliyun.com|g' /etc/apt/sources.list
|
|
||||||
sudo apt-get update -o Acquire::Retries=3 -o Acquire::http::Timeout=30
|
|
||||||
sudo apt-get install -y tar gzip
|
|
||||||
|
|
||||||
tar -czf admin-dist.tar.gz -C dist .
|
|
||||||
echo "压缩完成: $(ls -lh admin-dist.tar.gz)"
|
|
||||||
|
|
||||||
- name: 🚀 部署到服务器
|
|
||||||
uses: appleboy/ssh-action@v1.0.0
|
uses: appleboy/ssh-action@v1.0.0
|
||||||
with:
|
with:
|
||||||
host: ${{ secrets.HOST }}
|
host: ${{ secrets.ALIYUN_IP }}
|
||||||
username: ${{ secrets.USERNAME }}
|
username: ${{ secrets.ALIYUN_USER_NAME }}
|
||||||
key: ${{ secrets.SSH_KEY }}
|
password: ${{ secrets.ALIYUN_PWD }}
|
||||||
port: ${{ secrets.PORT }}
|
port: 22
|
||||||
script: |
|
script: |
|
||||||
# 设置变量
|
echo "🔄 部署管理后台文件..."
|
||||||
|
|
||||||
|
# 创建目标目录
|
||||||
|
mkdir -p /home/gitea/www/photography-admin
|
||||||
|
|
||||||
|
# 清空旧文件
|
||||||
|
rm -rf /home/gitea/www/photography-admin/*
|
||||||
|
|
||||||
|
# 移动新文件到生产目录
|
||||||
|
cp -r /tmp/admin-build/admin/dist/* /home/gitea/www/photography-admin/ || exit 1
|
||||||
|
|
||||||
|
# 清理临时文件
|
||||||
|
rm -rf /tmp/admin-build
|
||||||
|
|
||||||
|
# 验证部署结果
|
||||||
|
echo "📋 验证部署文件..."
|
||||||
|
ls -la /home/gitea/www/photography-admin/ | head -10
|
||||||
|
|
||||||
|
- name: 🔧 设置权限和健康检查
|
||||||
|
uses: appleboy/ssh-action@v1.0.0
|
||||||
|
with:
|
||||||
|
host: ${{ secrets.ALIYUN_IP }}
|
||||||
|
username: ${{ secrets.ALIYUN_USER_NAME }}
|
||||||
|
password: ${{ secrets.ALIYUN_PWD }}
|
||||||
|
port: 22
|
||||||
|
script: |
|
||||||
|
echo "🔧 设置权限..."
|
||||||
ADMIN_DIR="/home/gitea/www/photography-admin"
|
ADMIN_DIR="/home/gitea/www/photography-admin"
|
||||||
BACKUP_DIR="/home/gitea/backups/photography-admin"
|
|
||||||
TEMP_DIR="/tmp/photography-admin-deploy"
|
|
||||||
|
|
||||||
echo "🚀 开始部署管理后台..."
|
chown -R gitea:gitea $ADMIN_DIR
|
||||||
|
chmod -R 755 $ADMIN_DIR
|
||||||
|
|
||||||
# 创建临时目录
|
echo "✅ 管理后台部署完成!"
|
||||||
mkdir -p "$TEMP_DIR"
|
|
||||||
|
|
||||||
# 创建备份目录
|
# 验证部署
|
||||||
mkdir -p "$BACKUP_DIR"
|
if [ -f "$ADMIN_DIR/index.html" ]; then
|
||||||
|
echo "✅ index.html 已部署"
|
||||||
# 备份当前版本
|
|
||||||
if [ -d "$ADMIN_DIR" ] && [ "$(ls -A $ADMIN_DIR)" ]; then
|
|
||||||
echo "📦 备份当前版本..."
|
|
||||||
BACKUP_NAME="admin-$(date +%Y%m%d-%H%M%S).tar.gz"
|
|
||||||
tar -czf "$BACKUP_DIR/$BACKUP_NAME" -C "$ADMIN_DIR" .
|
|
||||||
echo "✅ 备份完成: $BACKUP_NAME"
|
|
||||||
|
|
||||||
# 保留最近10个备份
|
|
||||||
cd "$BACKUP_DIR"
|
|
||||||
ls -t admin-*.tar.gz | tail -n +11 | xargs -r rm
|
|
||||||
echo "🧹 清理旧备份完成"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "📁 准备部署目录..."
|
|
||||||
mkdir -p "$ADMIN_DIR"
|
|
||||||
|
|
||||||
- name: 📤 上传构建产物
|
|
||||||
uses: appleboy/scp-action@v0.1.4
|
|
||||||
with:
|
|
||||||
host: ${{ secrets.HOST }}
|
|
||||||
username: ${{ secrets.USERNAME }}
|
|
||||||
key: ${{ secrets.SSH_KEY }}
|
|
||||||
port: ${{ secrets.PORT }}
|
|
||||||
source: admin/admin-dist.tar.gz
|
|
||||||
target: /tmp/photography-admin-deploy/
|
|
||||||
strip_components: 1
|
|
||||||
|
|
||||||
- name: 🔄 解压并部署
|
|
||||||
uses: appleboy/ssh-action@v1.0.0
|
|
||||||
with:
|
|
||||||
host: ${{ secrets.HOST }}
|
|
||||||
username: ${{ secrets.USERNAME }}
|
|
||||||
key: ${{ secrets.SSH_KEY }}
|
|
||||||
port: ${{ secrets.PORT }}
|
|
||||||
script: |
|
|
||||||
# 设置变量
|
|
||||||
ADMIN_DIR="/home/gitea/www/photography-admin"
|
|
||||||
TEMP_DIR="/tmp/photography-admin-deploy"
|
|
||||||
|
|
||||||
echo "🔄 解压新版本..."
|
|
||||||
cd "$TEMP_DIR"
|
|
||||||
tar -xzf admin-dist.tar.gz
|
|
||||||
|
|
||||||
echo "📂 部署新版本..."
|
|
||||||
# 清空目标目录
|
|
||||||
rm -rf "$ADMIN_DIR"/*
|
|
||||||
|
|
||||||
# 复制新文件
|
|
||||||
cp -r * "$ADMIN_DIR/"
|
|
||||||
|
|
||||||
echo "🔐 设置文件权限..."
|
|
||||||
chown -R gitea:gitea "$ADMIN_DIR"
|
|
||||||
chmod -R 755 "$ADMIN_DIR"
|
|
||||||
|
|
||||||
# 设置正确的文件权限
|
|
||||||
find "$ADMIN_DIR" -type f -name "*.html" -o -name "*.js" -o -name "*.css" -o -name "*.json" | xargs chmod 644
|
|
||||||
find "$ADMIN_DIR" -type d | xargs chmod 755
|
|
||||||
|
|
||||||
echo "🧹 清理临时文件..."
|
|
||||||
rm -rf "$TEMP_DIR"
|
|
||||||
|
|
||||||
echo "✅ 管理后台部署完成!"
|
|
||||||
echo "📊 部署统计:"
|
|
||||||
echo "文件数量: $(find $ADMIN_DIR -type f | wc -l)"
|
|
||||||
echo "目录大小: $(du -sh $ADMIN_DIR)"
|
|
||||||
|
|
||||||
- name: 🔍 健康检查
|
|
||||||
uses: appleboy/ssh-action@v1.0.0
|
|
||||||
with:
|
|
||||||
host: ${{ secrets.HOST }}
|
|
||||||
username: ${{ secrets.USERNAME }}
|
|
||||||
key: ${{ secrets.SSH_KEY }}
|
|
||||||
port: ${{ secrets.PORT }}
|
|
||||||
script: |
|
|
||||||
echo "🔍 执行健康检查..."
|
|
||||||
|
|
||||||
# 检查文件是否存在
|
|
||||||
if [ -f "/home/gitea/www/photography-admin/index.html" ]; then
|
|
||||||
echo "✅ index.html 文件存在"
|
|
||||||
else
|
|
||||||
echo "❌ index.html 文件不存在"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# 检查网站是否可访问 (本地检查)
|
|
||||||
sleep 5
|
|
||||||
if curl -f -s -o /dev/null https://admin.photography.iriver.top; then
|
|
||||||
echo "✅ 管理后台访问正常"
|
|
||||||
else
|
|
||||||
echo "⚠️ 管理后台访问异常,请检查 Caddy 配置"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# 重新加载 Caddy (确保新文件被正确服务)
|
|
||||||
sudo systemctl reload caddy
|
|
||||||
echo "🔄 Caddy 配置已重新加载"
|
|
||||||
|
|
||||||
- name: 📧 发送部署通知
|
|
||||||
if: always()
|
|
||||||
uses: appleboy/telegram-action@master
|
|
||||||
with:
|
|
||||||
to: ${{ secrets.TELEGRAM_TO }}
|
|
||||||
token: ${{ secrets.TELEGRAM_TOKEN }}
|
|
||||||
message: |
|
|
||||||
🎨 摄影作品集管理后台部署 (Bun)
|
|
||||||
|
|
||||||
📦 项目: ${{ github.repository }}
|
|
||||||
🌿 分支: ${{ github.ref_name }}
|
|
||||||
👤 提交者: ${{ github.actor }}
|
|
||||||
📝 提交信息: ${{ github.event.head_commit.message }}
|
|
||||||
|
|
||||||
${{ job.status == 'success' && '✅ 部署成功' || '❌ 部署失败' }}
|
|
||||||
|
|
||||||
🥖 构建工具: Bun (快速构建)
|
|
||||||
🌐 管理后台: https://admin.photography.iriver.top
|
|
||||||
📱 前端: https://photography.iriver.top
|
|
||||||
|
|
||||||
rollback:
|
|
||||||
name: 🔄 回滚部署
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
if: failure() && github.ref == 'refs/heads/main'
|
|
||||||
needs: deploy
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: 🔄 执行回滚
|
|
||||||
uses: appleboy/ssh-action@v1.0.0
|
|
||||||
with:
|
|
||||||
host: ${{ secrets.HOST }}
|
|
||||||
username: ${{ secrets.USERNAME }}
|
|
||||||
key: ${{ secrets.SSH_KEY }}
|
|
||||||
port: ${{ secrets.PORT }}
|
|
||||||
script: |
|
|
||||||
ADMIN_DIR="/home/gitea/www/photography-admin"
|
|
||||||
BACKUP_DIR="/home/gitea/backups/photography-admin"
|
|
||||||
|
|
||||||
echo "🔄 开始回滚管理后台..."
|
|
||||||
|
|
||||||
# 查找最新的备份
|
|
||||||
LATEST_BACKUP=$(ls -t "$BACKUP_DIR"/admin-*.tar.gz 2>/dev/null | head -n 1)
|
|
||||||
|
|
||||||
if [ -n "$LATEST_BACKUP" ]; then
|
|
||||||
echo "📦 找到备份文件: $LATEST_BACKUP"
|
|
||||||
|
|
||||||
# 清空当前目录
|
|
||||||
rm -rf "$ADMIN_DIR"/*
|
|
||||||
|
|
||||||
# 恢复备份
|
|
||||||
tar -xzf "$LATEST_BACKUP" -C "$ADMIN_DIR"
|
|
||||||
|
|
||||||
# 设置权限
|
|
||||||
chown -R gitea:gitea "$ADMIN_DIR"
|
|
||||||
chmod -R 755 "$ADMIN_DIR"
|
|
||||||
|
|
||||||
# 重新加载 Caddy
|
|
||||||
sudo systemctl reload caddy
|
|
||||||
|
|
||||||
echo "✅ 回滚完成"
|
|
||||||
else
|
|
||||||
echo "❌ 未找到备份文件,无法回滚"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
security-scan:
|
|
||||||
name: 🔒 安全扫描
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
needs: test-and-build
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: 📥 检出代码
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: 🥖 设置 Bun 环境
|
|
||||||
uses: oven-sh/setup-bun@v1
|
|
||||||
with:
|
|
||||||
bun-version: latest
|
|
||||||
|
|
||||||
- name: 📦 安装依赖
|
|
||||||
working-directory: ./admin
|
|
||||||
run: bun install --frozen-lockfile
|
|
||||||
|
|
||||||
- name: 🔒 运行安全扫描
|
|
||||||
working-directory: ./admin
|
|
||||||
run: |
|
|
||||||
echo "🔍 扫描已知漏洞..."
|
|
||||||
bun audit
|
|
||||||
|
|
||||||
echo "📊 依赖分析..."
|
|
||||||
echo "依赖数量: $(bun pm ls --depth=0 | wc -l)"
|
|
||||||
|
|
||||||
echo "🔍 检查过时依赖..."
|
|
||||||
bun outdated || true
|
|
||||||
|
|
||||||
- name: 📊 生成安全报告
|
|
||||||
working-directory: ./admin
|
|
||||||
run: |
|
|
||||||
echo "# 安全扫描报告 (Bun)" > security-report.md
|
|
||||||
echo "## 日期: $(date)" >> security-report.md
|
|
||||||
echo "## 依赖统计" >> security-report.md
|
|
||||||
echo "依赖数量: $(bun pm ls --depth=0 | wc -l)" >> security-report.md
|
|
||||||
echo "## Bun 版本" >> security-report.md
|
|
||||||
bun --version >> security-report.md
|
|
||||||
|
|
||||||
- name: 📤 上传安全报告
|
|
||||||
uses: actions/upload-artifact@v3
|
|
||||||
with:
|
|
||||||
name: security-report
|
|
||||||
path: admin/security-report.md
|
|
||||||
@ -157,28 +157,143 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
- name: 📦 同步配置文件
|
- name: 📦 同步配置文件
|
||||||
run: |
|
uses: appleboy/ssh-action@v1.0.0
|
||||||
# 使用国内镜像源安装sshpass
|
with:
|
||||||
echo "🔄 使用国内镜像源..."
|
host: ${{ secrets.HOST }}
|
||||||
sudo sed -i 's|http://.*.ubuntu.com|https://mirrors.aliyun.com|g' /etc/apt/sources.list
|
username: ${{ secrets.TYY_USER }}
|
||||||
sudo apt-get update -o Acquire::Retries=3 -o Acquire::http::Timeout=30
|
password: ${{ secrets.TYY_PWD }}
|
||||||
sudo apt-get install -y --allow-unauthenticated sshpass
|
port: ${{ secrets.PORT }}
|
||||||
|
script: |
|
||||||
|
echo "📦 开始同步配置文件..."
|
||||||
|
|
||||||
# 同步配置文件到服务器
|
# 创建目录
|
||||||
echo "📋 同步配置文件到服务器..."
|
mkdir -p /data/docker/photography/backend
|
||||||
export SSHPASS=${{ secrets.TYY_PWD }}
|
cd /data/docker/photography/backend
|
||||||
sshpass -e scp -o StrictHostKeyChecking=no -P ${{ secrets.PORT }} backend/docker-compose.prod.yml ${{ secrets.TYY_USER }}@${{ secrets.HOST }}:/data/docker/photography/backend/docker-compose.yml
|
|
||||||
|
|
||||||
# 创建生产环境配置文件
|
# 备份现有配置
|
||||||
echo "📋 创建生产环境配置..."
|
if [ -f docker-compose.yml ]; then
|
||||||
sed -e "s/DB_USER=.*/DB_USER=${{ secrets.POSTGRES_PHOTO_USER }}/" \
|
cp docker-compose.yml docker-compose.yml.backup.$(date +%Y%m%d-%H%M%S)
|
||||||
-e "s/DB_PASSWORD=.*/DB_PASSWORD=${{ secrets.POSTGRES_PHOTO_PWD }}/" \
|
echo "📋 已备份现有配置"
|
||||||
-e "s/DB_HOST=.*/DB_HOST=localhost/" \
|
fi
|
||||||
-e "s/APP_ENV=.*/APP_ENV=production/" \
|
|
||||||
backend/.env.example > /tmp/production.env
|
# 生成新的配置文件
|
||||||
|
cat > docker-compose.yml << 'EOF'
|
||||||
|
# Photography Portfolio Backend - Production Docker Compose
|
||||||
|
# 生产环境配置 - 使用现有 PostgreSQL 和 Redis 服务
|
||||||
|
|
||||||
|
services:
|
||||||
|
# 后端API服务 (仅API服务,无数据库)
|
||||||
|
api:
|
||||||
|
image: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}
|
||||||
|
container_name: photography-api
|
||||||
|
environment:
|
||||||
|
# 数据库配置 (连接现有服务)
|
||||||
|
DB_HOST: localhost
|
||||||
|
DB_PORT: 5432
|
||||||
|
DB_NAME: photography
|
||||||
|
DB_USER: ${{ secrets.POSTGRES_PHOTO_USER }}
|
||||||
|
DB_PASSWORD: ${{ secrets.POSTGRES_PHOTO_PWD }}
|
||||||
|
DB_SSL_MODE: disable
|
||||||
|
|
||||||
|
# Redis配置 (连接现有服务)
|
||||||
|
REDIS_HOST: localhost
|
||||||
|
REDIS_PORT: 6379
|
||||||
|
REDIS_PASSWORD: ${{ secrets.REDIS_PASSWORD }}
|
||||||
|
REDIS_DB: 0
|
||||||
|
|
||||||
|
# JWT配置
|
||||||
|
JWT_SECRET: ${{ secrets.JWT_SECRET }}
|
||||||
|
JWT_EXPIRE: 24h
|
||||||
|
|
||||||
|
# 服务配置
|
||||||
|
APP_ENV: production
|
||||||
|
APP_PORT: 8080
|
||||||
|
APP_HOST: 0.0.0.0
|
||||||
|
|
||||||
|
# CORS配置
|
||||||
|
CORS_ORIGINS: https://photography.iriver.top
|
||||||
|
|
||||||
|
# 文件上传配置
|
||||||
|
UPLOAD_PATH: /app/uploads
|
||||||
|
UPLOAD_MAX_SIZE: 10485760
|
||||||
|
|
||||||
|
# 日志配置
|
||||||
|
LOG_LEVEL: info
|
||||||
|
LOG_FORMAT: json
|
||||||
|
ports:
|
||||||
|
- "8080:8080"
|
||||||
|
networks:
|
||||||
|
- app_network
|
||||||
|
volumes:
|
||||||
|
- uploads_data:/app/uploads
|
||||||
|
- logs_data:/app/logs
|
||||||
|
restart: unless-stopped
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "/usr/local/bin/health-check.sh"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
|
start_period: 10s
|
||||||
|
|
||||||
|
# 数据库迁移服务 (一次性运行)
|
||||||
|
migrate:
|
||||||
|
image: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}
|
||||||
|
container_name: photography-migrate
|
||||||
|
environment:
|
||||||
|
DB_HOST: localhost
|
||||||
|
DB_PORT: 5432
|
||||||
|
DB_NAME: photography
|
||||||
|
DB_USER: ${{ secrets.POSTGRES_PHOTO_USER }}
|
||||||
|
DB_PASSWORD: ${{ secrets.POSTGRES_PHOTO_PWD }}
|
||||||
|
DB_SSL_MODE: disable
|
||||||
|
entrypoint: ["/migrate", "up"]
|
||||||
|
restart: "no"
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
uploads_data:
|
||||||
|
driver: local
|
||||||
|
logs_data:
|
||||||
|
driver: local
|
||||||
|
|
||||||
|
networks:
|
||||||
|
app_network:
|
||||||
|
external: true
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# 创建环境变量文件
|
||||||
|
cat > .env << 'EOF'
|
||||||
|
# 生产环境配置
|
||||||
|
DB_HOST=localhost
|
||||||
|
DB_PORT=5432
|
||||||
|
DB_NAME=photography
|
||||||
|
DB_USER=${{ secrets.POSTGRES_PHOTO_USER }}
|
||||||
|
DB_PASSWORD=${{ secrets.POSTGRES_PHOTO_PWD }}
|
||||||
|
DB_SSL_MODE=disable
|
||||||
|
|
||||||
|
REDIS_HOST=localhost
|
||||||
|
REDIS_PORT=6379
|
||||||
|
REDIS_PASSWORD=${{ secrets.REDIS_PASSWORD }}
|
||||||
|
REDIS_DB=0
|
||||||
|
|
||||||
|
JWT_SECRET=${{ secrets.JWT_SECRET }}
|
||||||
|
JWT_EXPIRE=24h
|
||||||
|
|
||||||
|
APP_ENV=production
|
||||||
|
APP_PORT=8080
|
||||||
|
APP_HOST=0.0.0.0
|
||||||
|
|
||||||
|
CORS_ORIGINS=https://photography.iriver.top
|
||||||
|
|
||||||
|
UPLOAD_PATH=/app/uploads
|
||||||
|
UPLOAD_MAX_SIZE=10485760
|
||||||
|
|
||||||
|
LOG_LEVEL=info
|
||||||
|
LOG_FORMAT=json
|
||||||
|
EOF
|
||||||
|
|
||||||
sshpass -e scp -o StrictHostKeyChecking=no -P ${{ secrets.PORT }} /tmp/production.env ${{ secrets.TYY_USER }}@${{ secrets.HOST }}:/data/docker/photography/backend/.env
|
|
||||||
echo "✅ 配置文件同步完成"
|
echo "✅ 配置文件同步完成"
|
||||||
|
echo "📋 已部署以下文件:"
|
||||||
|
ls -la /data/docker/photography/backend/
|
||||||
|
|
||||||
- name: 🚀 部署到生产环境
|
- name: 🚀 部署到生产环境
|
||||||
uses: appleboy/ssh-action@v1.0.0
|
uses: appleboy/ssh-action@v1.0.0
|
||||||
@ -272,26 +387,6 @@ jobs:
|
|||||||
echo "📋 请记住手动运行数据库迁移:"
|
echo "📋 请记住手动运行数据库迁移:"
|
||||||
echo " docker compose exec api ./main migrate"
|
echo " docker compose exec api ./main migrate"
|
||||||
|
|
||||||
- name: 📧 发送部署通知
|
|
||||||
if: always()
|
|
||||||
uses: appleboy/telegram-action@master
|
|
||||||
with:
|
|
||||||
to: ${{ secrets.TELEGRAM_TO }}
|
|
||||||
token: ${{ secrets.TELEGRAM_TOKEN }}
|
|
||||||
message: |
|
|
||||||
🔧 摄影作品集后端部署
|
|
||||||
|
|
||||||
📦 项目: ${{ github.repository }}
|
|
||||||
🌿 分支: ${{ github.ref_name }}
|
|
||||||
👤 提交者: ${{ github.actor }}
|
|
||||||
📝 提交信息: ${{ github.event.head_commit.message }}
|
|
||||||
|
|
||||||
${{ job.status == 'success' && '✅ 部署成功' || '❌ 部署失败' }}
|
|
||||||
|
|
||||||
${{ job.status == 'success' && '⚠️ 请记住手动运行数据库迁移: docker compose exec api ./main migrate' || '' }}
|
|
||||||
|
|
||||||
🌐 API: https://api.photography.iriver.top/health
|
|
||||||
📊 监控: https://admin.photography.iriver.top
|
|
||||||
|
|
||||||
# rollback:
|
# rollback:
|
||||||
# name: 🔄 回滚部署
|
# name: 🔄 回滚部署
|
||||||
|
|||||||
@ -8,6 +8,10 @@ on:
|
|||||||
- '.gitea/workflows/deploy-frontend.yml'
|
- '.gitea/workflows/deploy-frontend.yml'
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
|
env:
|
||||||
|
BUN_VERSION: 'latest'
|
||||||
|
CACHE_KEY: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lock') }}
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
test-and-build:
|
test-and-build:
|
||||||
name: 🧪 测试和构建
|
name: 🧪 测试和构建
|
||||||
@ -20,17 +24,33 @@ jobs:
|
|||||||
- name: 🦀 设置 Bun 环境
|
- name: 🦀 设置 Bun 环境
|
||||||
uses: oven-sh/setup-bun@v1
|
uses: oven-sh/setup-bun@v1
|
||||||
with:
|
with:
|
||||||
bun-version: latest
|
bun-version: ${{ env.BUN_VERSION }}
|
||||||
|
|
||||||
|
- name: 💾 缓存 Bun 依赖
|
||||||
|
uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
path: |
|
||||||
|
~/.bun/install/cache
|
||||||
|
frontend/node_modules
|
||||||
|
key: ${{ env.CACHE_KEY }}-${{ hashFiles('frontend/bun.lock') }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ env.CACHE_KEY }}-
|
||||||
|
|
||||||
- name: 📦 安装依赖
|
- name: 📦 安装依赖
|
||||||
working-directory: ./frontend
|
working-directory: ./frontend
|
||||||
run: bun install
|
run: bun install --frozen-lockfile
|
||||||
|
|
||||||
- name: 🔍 代码检查
|
- name: 🏗️ 并行构建和检查
|
||||||
working-directory: ./frontend
|
working-directory: ./frontend
|
||||||
run: |
|
run: |
|
||||||
bun run lint
|
# 并行执行代码检查和构建
|
||||||
bun run type-check
|
bun run lint &
|
||||||
|
bun run type-check &
|
||||||
|
wait
|
||||||
|
env:
|
||||||
|
NEXT_PUBLIC_API_URL: https://api.photography.iriver.top
|
||||||
|
NEXT_PUBLIC_SITE_URL: https://photography.iriver.top
|
||||||
|
NEXT_PUBLIC_SITE_NAME: 摄影作品集
|
||||||
|
|
||||||
- name: 🏗️ 构建生产版本
|
- name: 🏗️ 构建生产版本
|
||||||
working-directory: ./frontend
|
working-directory: ./frontend
|
||||||
@ -43,9 +63,9 @@ jobs:
|
|||||||
- name: 📦 打包构建产物
|
- name: 📦 打包构建产物
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: frontend-dist
|
name: frontend-dist-${{ github.sha }}
|
||||||
path: frontend/out/
|
path: frontend/out/
|
||||||
retention-days: 7
|
retention-days: 1
|
||||||
|
|
||||||
deploy:
|
deploy:
|
||||||
name: 🚀 部署到生产环境
|
name: 🚀 部署到生产环境
|
||||||
@ -60,11 +80,19 @@ jobs:
|
|||||||
- name: 🦀 设置 Bun 环境
|
- name: 🦀 设置 Bun 环境
|
||||||
uses: oven-sh/setup-bun@v1
|
uses: oven-sh/setup-bun@v1
|
||||||
with:
|
with:
|
||||||
bun-version: latest
|
bun-version: ${{ env.BUN_VERSION }}
|
||||||
|
|
||||||
|
- name: 💾 缓存 Bun 依赖
|
||||||
|
uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
path: |
|
||||||
|
~/.bun/install/cache
|
||||||
|
frontend/node_modules
|
||||||
|
key: ${{ env.CACHE_KEY }}-${{ hashFiles('frontend/bun.lock') }}
|
||||||
|
|
||||||
- name: 📦 安装依赖
|
- name: 📦 安装依赖
|
||||||
working-directory: ./frontend
|
working-directory: ./frontend
|
||||||
run: bun install
|
run: bun install --frozen-lockfile
|
||||||
|
|
||||||
- name: 🏗️ 构建生产版本
|
- name: 🏗️ 构建生产版本
|
||||||
working-directory: ./frontend
|
working-directory: ./frontend
|
||||||
@ -74,68 +102,91 @@ jobs:
|
|||||||
NEXT_PUBLIC_SITE_NAME: 摄影作品集
|
NEXT_PUBLIC_SITE_NAME: 摄影作品集
|
||||||
run: bun run build
|
run: bun run build
|
||||||
|
|
||||||
- name: 🚀 部署到服务器
|
- name: 📤 上传文件到服务器
|
||||||
run: |
|
uses: appleboy/scp-action@v0.1.6
|
||||||
# 使用国内镜像源安装部署工具
|
with:
|
||||||
echo "🔄 使用国内镜像源..."
|
host: ${{ secrets.ALIYUN_IP }}
|
||||||
sudo sed -i 's|http://.*.ubuntu.com|https://mirrors.aliyun.com|g' /etc/apt/sources.list
|
username: ${{ secrets.ALIYUN_USER_NAME }}
|
||||||
sudo apt-get update -o Acquire::Retries=3 -o Acquire::http::Timeout=30
|
password: ${{ secrets.ALIYUN_PWD }}
|
||||||
sudo apt-get install -y openssh-client rsync sshpass
|
port: 22
|
||||||
|
source: "frontend/out/"
|
||||||
|
target: "/tmp/frontend-build"
|
||||||
|
rm: true
|
||||||
|
|
||||||
# 设置 SSH 环境
|
- name: 🔄 部署文件到生产目录
|
||||||
export SSHPASS=${{ secrets.ALIYUN_PWD }}
|
uses: appleboy/ssh-action@v1.0.0
|
||||||
|
with:
|
||||||
|
host: ${{ secrets.ALIYUN_IP }}
|
||||||
|
username: ${{ secrets.ALIYUN_USER_NAME }}
|
||||||
|
password: ${{ secrets.ALIYUN_PWD }}
|
||||||
|
port: 22
|
||||||
|
script: |
|
||||||
|
echo "🔄 部署文件到生产目录..."
|
||||||
|
|
||||||
echo "🔗 测试 SSH 连接..."
|
# 创建目标目录
|
||||||
sshpass -e ssh -o StrictHostKeyChecking=no -o ConnectTimeout=10 ${{ secrets.ALIYUN_USER_NAME }}@${{ secrets.ALIYUN_IP }} "echo 'SSH 连接成功'"
|
mkdir -p /home/gitea/www/photography
|
||||||
|
|
||||||
echo "📁 创建部署目录..."
|
# 清空旧文件
|
||||||
sshpass -e ssh -o StrictHostKeyChecking=no ${{ secrets.ALIYUN_USER_NAME }}@${{ secrets.ALIYUN_IP }} "mkdir -p /home/gitea/www/photography"
|
rm -rf /home/gitea/www/photography/*
|
||||||
|
|
||||||
echo "📦 备份当前版本..."
|
# 移动新文件到生产目录
|
||||||
sshpass -e ssh -o StrictHostKeyChecking=no ${{ secrets.ALIYUN_USER_NAME }}@${{ secrets.ALIYUN_IP }} "
|
cp -r /tmp/frontend-build/frontend/out/* /home/gitea/www/photography/ || exit 1
|
||||||
if [ -d '/home/gitea/www/photography' ] && [ \"\$(ls -A /home/gitea/www/photography)\" ]; then
|
|
||||||
mkdir -p /home/gitea/backups/photography-frontend
|
|
||||||
tar -czf /home/gitea/backups/photography-frontend/frontend-\$(date +%Y%m%d-%H%M%S).tar.gz -C /home/gitea/www/photography .
|
|
||||||
echo '✅ 备份完成'
|
|
||||||
fi
|
|
||||||
"
|
|
||||||
|
|
||||||
echo "🚀 部署新版本..."
|
# 清理临时文件
|
||||||
sshpass -e rsync -avz --delete --progress -e "ssh -o StrictHostKeyChecking=no" frontend/out/ ${{ secrets.ALIYUN_USER_NAME }}@${{ secrets.ALIYUN_IP }}:/home/gitea/www/photography/
|
rm -rf /tmp/frontend-build
|
||||||
|
|
||||||
echo "🔐 设置文件权限..."
|
# 验证部署结果
|
||||||
sshpass -e ssh -o StrictHostKeyChecking=no ${{ secrets.ALIYUN_USER_NAME }}@${{ secrets.ALIYUN_IP }} "
|
echo "📋 验证部署文件..."
|
||||||
|
ls -la /home/gitea/www/photography/ | head -10
|
||||||
|
|
||||||
|
- name: 🔧 设置文件权限
|
||||||
|
uses: appleboy/ssh-action@v1.0.0
|
||||||
|
with:
|
||||||
|
host: ${{ secrets.ALIYUN_IP }}
|
||||||
|
username: ${{ secrets.ALIYUN_USER_NAME }}
|
||||||
|
password: ${{ secrets.ALIYUN_PWD }}
|
||||||
|
port: 22
|
||||||
|
script: |
|
||||||
|
echo "🔧 设置文件权限..."
|
||||||
|
|
||||||
|
# 设置所有者
|
||||||
chown -R gitea:gitea /home/gitea/www/photography
|
chown -R gitea:gitea /home/gitea/www/photography
|
||||||
chmod -R 755 /home/gitea/www/photography
|
|
||||||
find /home/gitea/www/photography -type f -name '*.html' -o -name '*.js' -o -name '*.css' -o -name '*.json' | xargs chmod 644
|
|
||||||
"
|
|
||||||
|
|
||||||
echo "🔄 重新加载 Web 服务器..."
|
# 设置权限
|
||||||
sshpass -e ssh -o StrictHostKeyChecking=no ${{ secrets.ALIYUN_USER_NAME }}@${{ secrets.ALIYUN_IP }} "sudo systemctl reload caddy"
|
chmod -R 755 /home/gitea/www/photography
|
||||||
|
find /home/gitea/www/photography -type f \( -name '*.html' -o -name '*.js' -o -name '*.css' -o -name '*.json' \) -exec chmod 644 {} \;
|
||||||
|
|
||||||
|
# 重新加载 Caddy
|
||||||
|
if command -v sudo &> /dev/null; then
|
||||||
|
sudo systemctl reload caddy
|
||||||
|
else
|
||||||
|
systemctl reload caddy || true
|
||||||
|
fi
|
||||||
|
|
||||||
echo "✅ 前端部署完成!"
|
echo "✅ 前端部署完成!"
|
||||||
echo "📁 部署路径:/home/gitea/www/photography/"
|
|
||||||
echo "🌐 访问地址:https://photography.iriver.top"
|
|
||||||
|
|
||||||
- name: 🔍 健康检查
|
- name: 🔍 健康检查
|
||||||
run: |
|
uses: appleboy/ssh-action@v1.0.0
|
||||||
|
with:
|
||||||
|
host: ${{ secrets.ALIYUN_IP }}
|
||||||
|
username: ${{ secrets.ALIYUN_USER_NAME }}
|
||||||
|
password: ${{ secrets.ALIYUN_PWD }}
|
||||||
|
port: 22
|
||||||
|
script: |
|
||||||
echo "🔍 执行健康检查..."
|
echo "🔍 执行健康检查..."
|
||||||
sleep 10
|
|
||||||
|
|
||||||
# 检查网站是否可访问
|
# 检查文件是否存在
|
||||||
if curl -f -s -o /dev/null https://photography.iriver.top; then
|
if [ -f '/home/gitea/www/photography/index.html' ]; then
|
||||||
echo "✅ 前端网站访问正常"
|
echo '✅ index.html 文件存在'
|
||||||
else
|
else
|
||||||
echo "⚠️ 前端网站访问异常"
|
echo '❌ index.html 文件不存在'
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
- name: 📧 发送部署通知
|
# 快速检查
|
||||||
if: always()
|
sleep 3
|
||||||
run: |
|
if curl -f -s -o /dev/null https://photography.iriver.top; then
|
||||||
if [ "${{ job.status }}" = "success" ]; then
|
echo '✅ 前端网站访问正常'
|
||||||
echo "✅ 摄影作品集前端部署成功!"
|
|
||||||
echo "🌐 访问地址: https://photography.iriver.top"
|
|
||||||
else
|
else
|
||||||
echo "❌ 摄影作品集前端部署失败!"
|
echo '⚠️ 前端网站访问异常,请手动检查'
|
||||||
fi
|
fi
|
||||||
23
.promptx/pouch.json
Normal file
23
.promptx/pouch.json
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"currentState": "service_discovery",
|
||||||
|
"stateHistory": [
|
||||||
|
{
|
||||||
|
"from": "initial",
|
||||||
|
"command": "init",
|
||||||
|
"timestamp": "2025-07-21T14:37:13.506Z",
|
||||||
|
"args": [
|
||||||
|
{
|
||||||
|
"workingDirectory": "/Users/iriver/workspace/photography",
|
||||||
|
"ideType": "trae"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"from": "initialized",
|
||||||
|
"command": "welcome",
|
||||||
|
"timestamp": "2025-07-21T14:37:23.299Z",
|
||||||
|
"args": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"lastUpdated": "2025-07-21T14:37:23.301Z"
|
||||||
|
}
|
||||||
17
.promptx/resource/project.registry.json
Normal file
17
.promptx/resource/project.registry.json
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"version": "2.0.0",
|
||||||
|
"source": "project",
|
||||||
|
"metadata": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"description": "project 级资源注册表",
|
||||||
|
"createdAt": "2025-07-21T14:37:13.518Z",
|
||||||
|
"updatedAt": "2025-07-21T14:37:13.519Z",
|
||||||
|
"resourceCount": 0
|
||||||
|
},
|
||||||
|
"resources": [],
|
||||||
|
"stats": {
|
||||||
|
"totalResources": 0,
|
||||||
|
"byProtocol": {},
|
||||||
|
"bySource": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,6 +1,6 @@
|
|||||||
# Photography Portfolio - 项目总览
|
# Photography Portfolio - 项目总览
|
||||||
|
|
||||||
> 📍 这是一个模块化摄影作品集项目,所有模块都有独立的CLAUDE.md文件
|
> 📍 这是一个模块化摄影作品集项目,所有模块都有独立的CLAUDE.md文件,所有给我的提示都要用中文
|
||||||
|
|
||||||
## 🎯 项目结构
|
## 🎯 项目结构
|
||||||
|
|
||||||
|
|||||||
935
TASK_PROGRESS.md
935
TASK_PROGRESS.md
@ -1,889 +1,136 @@
|
|||||||
# Photography Portfolio 项目任务进度
|
# Photography Portfolio - 项目任务进度
|
||||||
|
|
||||||
> 最后更新: 2025-07-11
|
> 📍 当前任务状态 - 最后更新: 2025-07-16
|
||||||
> 项目状态: 开发中 🚧
|
|
||||||
|
|
||||||
## 📊 总体进度概览
|
## 📊 总体进度概览
|
||||||
|
|
||||||
- **总任务数**: 40 (细化拆分后)
|
- **总任务数**: 40
|
||||||
- **已完成**: 29 ✅
|
- **已完成**: 29 ✅
|
||||||
- **进行中**: 0 🔄
|
|
||||||
- **待开始**: 11 ⏳
|
- **待开始**: 11 ⏳
|
||||||
- **完成率**: 72.5%
|
- **完成率**: 72.5%
|
||||||
|
- **当前阶段**: Phase 3 前端完善 + Phase 4 部署优化
|
||||||
### 📈 任务分布
|
|
||||||
- **高优先级**: 9/9 (100% 完成) ✅
|
|
||||||
- **中优先级**: 18/20 (90% 完成) 📈
|
|
||||||
- **低优先级**: 2/11 (18% 完成) ⏳
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🔥 高优先级任务 (9/26)
|
## 🔄 当前待完成任务 (11项)
|
||||||
|
|
||||||
### ✅ 已完成 (9/9)
|
### 📌 低优先级任务 (11/11 待完成)
|
||||||
|
|
||||||
#### 1. ✅ 完善照片上传功能
|
#### 🐳 容器化和部署扩展 (2项)
|
||||||
**状态**: 已完成 ✅
|
- **32. 数据库Docker配置**
|
||||||
**完成时间**: 2025-01-10
|
- **优先级**: 低 ⚡
|
||||||
**完成内容**:
|
- **预估工作量**: 0.5天
|
||||||
- 创建了完整的文件处理工具包 (`pkg/utils/file/file.go`)
|
- **具体任务**: PostgreSQL容器、数据持久化、初始化脚本
|
||||||
- 实现了图片上传、缩略图生成、文件存储
|
|
||||||
- 支持多种图片格式 (JPEG, PNG, GIF, WebP)
|
|
||||||
- 添加了文件大小和类型验证
|
|
||||||
- 实现了自动缩略图生成 (300px宽度)
|
|
||||||
- 更新了上传处理器支持 multipart form
|
|
||||||
- 更新了业务逻辑层处理文件上传
|
|
||||||
- 添加了静态文件服务 (`/uploads/*`)
|
|
||||||
- 集成了图片处理库 (`github.com/disintegration/imaging`)
|
|
||||||
|
|
||||||
#### 2. ✅ 实现 JWT 认证中间件
|
- **33. 完整Docker编排**
|
||||||
**状态**: 已完成 ✅
|
- **优先级**: 低 ⚡
|
||||||
**完成时间**: 2025-01-10
|
- **预估工作量**: 0.5天
|
||||||
**完成内容**:
|
- **具体任务**: docker-compose.yml、网络配置、环境变量管理
|
||||||
- 创建了 JWT 认证中间件 (`internal/middleware/auth.go`)
|
|
||||||
- 实现了 Bearer Token 验证
|
|
||||||
- 支持用户信息注入到请求上下文
|
|
||||||
- 完善的错误处理和响应
|
|
||||||
- 与现有 JWT 工具包集成
|
|
||||||
- go-zero 框架已内置 JWT 支持,路由配置完整
|
|
||||||
|
|
||||||
#### 3. ✅ 完善照片更新和删除业务逻辑
|
#### 📈 性能和缓存优化 (3项)
|
||||||
**状态**: 已完成 ✅
|
- **34. 实现Redis缓存**
|
||||||
**完成时间**: 2025-01-10
|
- **优先级**: 低 ⚡
|
||||||
**完成内容**:
|
- **预估工作量**: 0.5天
|
||||||
- 实现了完整的照片更新逻辑 (`updatePhotoLogic.go`)
|
- **具体任务**: Redis配置、照片列表缓存、分类数据缓存
|
||||||
- 参数验证和权限检查
|
|
||||||
- 支持部分字段更新 (title, description, category_id)
|
|
||||||
- 分类存在性验证
|
|
||||||
- 用户权限验证 (只能更新自己的照片)
|
|
||||||
- 实现了完整的照片删除逻辑 (`deletePhotoLogic.go`)
|
|
||||||
- 权限验证 (只能删除自己的照片)
|
|
||||||
- 同时删除数据库记录和文件系统文件
|
|
||||||
- 安全的文件删除处理 (即使文件删除失败也不回滚)
|
|
||||||
- 更新了 Handler 使用统一响应格式
|
|
||||||
- 创建了完整的 API 测试用例 (`test_photo_crud.http`)
|
|
||||||
- 包含正常场景和错误场景的测试覆盖
|
|
||||||
|
|
||||||
#### 4. ✅ 完善分类更新和删除业务逻辑
|
- **35. API性能优化**
|
||||||
**状态**: 已完成 ✅
|
- **优先级**: 低 ⚡
|
||||||
**完成时间**: 2025-01-10
|
- **预估工作量**: 0.5天
|
||||||
**完成内容**:
|
- **具体任务**: 数据库查询优化、索引优化、分页优化
|
||||||
- 修复了 `updateCategoryLogic.go` 中的导入错误问题
|
|
||||||
- 修复了 `loginLogic.go` 中缺失的 errorx 包导入
|
|
||||||
- 修复了 `uploadPhotoLogic.go` 中的错误处理统一性
|
|
||||||
- 修复了 photo 查询相关文件的 model 包导入问题
|
|
||||||
- 完善了错误处理机制,统一使用项目自定义的 errorx 包
|
|
||||||
- 添加了缺失的错误代码定义 (UserDisabled, InvalidParameter)
|
|
||||||
- 解决了编译错误,确保所有后端模块可以正常编译
|
|
||||||
- 完善了 15 个后端逻辑文件的导入和错误处理
|
|
||||||
|
|
||||||
#### 5. ✅ 前端与后端 API 集成测试
|
- **36. 前端性能优化**
|
||||||
**状态**: 已完成 ✅
|
- **优先级**: 低 ⚡
|
||||||
**完成时间**: 2025-07-11
|
- **预估工作量**: 0.5天
|
||||||
**完成内容**:
|
- **具体任务**: 代码分割、懒加载、图片优化、CDN配置
|
||||||
- 完成管理后台与后端API联调
|
|
||||||
- 修复前后端数据格式不匹配问题 (ID类型、字段名称等)
|
|
||||||
- 更新前端类型定义匹配后端接口格式
|
|
||||||
- 完善API响应拦截器处理后端状态码
|
|
||||||
- 创建分类管理服务并验证CRUD功能
|
|
||||||
- 添加API测试页面 (`TestApi.tsx`) 用于功能验证
|
|
||||||
- 验证用户认证、分类管理等核心功能正常工作
|
|
||||||
- 数据库初始化完成,默认管理员账户可正常登录
|
|
||||||
|
|
||||||
#### 6. ✅ 管理后台类型系统完善和代码质量优化
|
#### ☁️ 云服务集成 (2项)
|
||||||
**状态**: 已完成 ✅
|
- **37. 配置云存储服务**
|
||||||
**完成时间**: 2025-07-11
|
- **优先级**: 低 ⚡
|
||||||
**完成内容**:
|
- **预估工作量**: 0.5天
|
||||||
- 修复所有TypeScript类型错误,确保类型安全
|
- **具体任务**: 七牛云/阿里云OSS集成、图片上传、CDN加速
|
||||||
- 完善User接口,添加role属性支持权限控制
|
|
||||||
- 统一API响应数据访问模式,规范化data属性使用
|
|
||||||
- 为categoryService添加getCategoryTree()和getStats()方法
|
|
||||||
- 修复Tag接口,添加color和isActive属性
|
|
||||||
- 解决Dashboard、Categories、Tags、Photos等页面的类型错误
|
|
||||||
- 统一API服务返回类型为ApiResponse<T>格式
|
|
||||||
- 消除所有编译警告,确保代码质量
|
|
||||||
- 验证构建成功,开发服务器正常启动(74ms)
|
|
||||||
- 管理后台认证系统达到生产就绪状态
|
|
||||||
|
|
||||||
#### 7. ✅ 实现照片上传界面和进度显示
|
- **38. 配置云数据库**
|
||||||
**状态**: 已完成 ✅
|
- **优先级**: 低 ⚡
|
||||||
**完成时间**: 2025-07-11
|
- **预估工作量**: 0.5天
|
||||||
**完成内容**:
|
- **具体任务**: 云数据库配置、备份策略、高可用配置
|
||||||
- 完整的拖拽上传功能,支持多文件选择
|
|
||||||
- 实时进度显示,单文件和总体进度条
|
|
||||||
- 文件类型和大小验证 (JPG/PNG/GIF/WebP, 最大10MB)
|
|
||||||
- 照片预览功能,支持预览图显示
|
|
||||||
- 分类和标签选择界面,支持多选
|
|
||||||
- 智能错误处理和用户反馈 (toast 通知)
|
|
||||||
- 文件管理功能 (移除单个、清空全部)
|
|
||||||
- 无障碍访问支持,完整的标签和提示
|
|
||||||
- 自动跳转和状态管理
|
|
||||||
|
|
||||||
#### 8. ✅ 完善照片管理界面 (编辑/删除)
|
#### 🧪 测试完善 (2项)
|
||||||
**状态**: 已完成 ✅
|
- **39. 编写前端E2E测试**
|
||||||
**完成时间**: 2025-07-11
|
- **优先级**: 低 ⚡
|
||||||
**完成内容**:
|
- **预估工作量**: 1天
|
||||||
- 增强的照片网格和列表视图,支持视图切换
|
- **具体任务**: Cypress配置、关键流程测试、自动化测试
|
||||||
- 内联编辑对话框,支持标题、描述、状态修改
|
|
||||||
- 照片详情查看对话框,显示完整元数据
|
|
||||||
- 改进的下拉菜单操作 (查看/编辑/删除)
|
|
||||||
- 批量操作功能,支持状态更新和批量删除
|
|
||||||
- 高级搜索和过滤功能,支持状态和分类筛选
|
|
||||||
- 优化的空状态页面,更好的用户引导
|
|
||||||
- 刷新功能和实时数据更新
|
|
||||||
- 全选/取消全选功能,批量操作栏
|
|
||||||
- 完整的照片信息展示 (分类、标签、创建时间等)
|
|
||||||
|
|
||||||
#### 9. ✅ 实现分类管理界面完善
|
- **40. 编写后端集成测试**
|
||||||
**状态**: 已完成 ✅
|
- **优先级**: 低 ⚡
|
||||||
**完成时间**: 2025-07-11
|
- **预估工作量**: 1天
|
||||||
**完成内容**:
|
- **具体任务**: API集成测试、数据库测试、性能测试
|
||||||
- 树形结构渲染,支持展开/收起功能
|
|
||||||
- 创建/编辑分类对话框,包含表单验证
|
|
||||||
- 视觉层次结构,通过缩进和颜色区分层级
|
|
||||||
- 搜索和过滤功能,支持名称和描述搜索
|
|
||||||
- 统计仪表板,显示分类数量和照片统计
|
|
||||||
- 展开/收起全部按钮,便于导航
|
|
||||||
- 启用/禁用状态显示,带有视觉指示器
|
|
||||||
- 每个分类的照片数量显示
|
|
||||||
- 拖拽友好的UI,悬停效果
|
|
||||||
- 完善的错误处理和用户反馈
|
|
||||||
- 刷新功能和实时更新
|
|
||||||
|
|
||||||
### 🔄 进行中 (0/9)
|
|
||||||
|
|
||||||
### ⏳ 待开始 (0/9)
|
|
||||||
|
|
||||||
**🎉 Phase 2 高优先级任务全部完成!管理后台功能已达到生产就绪状态。**
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📋 中优先级任务 (20/26) - 细化拆分
|
|
||||||
|
|
||||||
### 🔧 后端功能完善 (8项)
|
|
||||||
#### 10. ✅ 完善用户管理接口
|
|
||||||
**状态**: 已完成 ✅
|
|
||||||
**完成时间**: 2025-07-11
|
|
||||||
**完成内容**:
|
|
||||||
- 实现完整的用户创建逻辑 (`createUserLogic.go`)
|
|
||||||
- 用户名和邮箱唯一性验证
|
|
||||||
- bcrypt 密码加密
|
|
||||||
- 默认状态设置和时间戳
|
|
||||||
- 安全的用户信息返回 (不含密码)
|
|
||||||
- 实现用户详情查询逻辑 (`getUserLogic.go`)
|
|
||||||
- 根据ID查询用户信息
|
|
||||||
- 用户不存在的错误处理
|
|
||||||
- 密码字段过滤保护
|
|
||||||
- 实现用户信息更新逻辑 (`updateUserLogic.go`)
|
|
||||||
- 支持部分字段更新 (用户名、邮箱、头像、状态)
|
|
||||||
- 更新时的唯一性验证 (排除当前用户)
|
|
||||||
- 字段验证和清理
|
|
||||||
- 时间戳自动更新
|
|
||||||
- 实现用户删除逻辑 (`deleteUserLogic.go`)
|
|
||||||
- 用户存在性检查
|
|
||||||
- 硬删除实现
|
|
||||||
- 删除日志记录
|
|
||||||
- 关联数据处理预留
|
|
||||||
- 创建完整的API测试用例 (`test_user_crud.http`)
|
|
||||||
- 正常场景测试 (创建、查询、更新、删除)
|
|
||||||
- 错误场景测试 (重复数据、不存在资源、格式错误)
|
|
||||||
- 边界情况验证 (密码长度、邮箱格式等)
|
|
||||||
|
|
||||||
#### 11. ✅ 实现用户头像上传功能
|
|
||||||
**状态**: 已完成 ✅
|
|
||||||
**完成时间**: 2025-07-11
|
|
||||||
**完成内容**:
|
|
||||||
- 创建头像上传API接口 (`POST /api/v1/users/:id/avatar`)
|
|
||||||
- 实现完整的头像上传逻辑 (`uploadAvatarLogic.go`)
|
|
||||||
- 用户权限验证 (只能上传自己的头像)
|
|
||||||
- 文件类型验证 (仅支持图片格式)
|
|
||||||
- 文件大小限制 (最大5MB)
|
|
||||||
- 智能文件扩展名检测
|
|
||||||
- 头像图片处理功能 (`pkg/utils/file/file.go`)
|
|
||||||
- 自动压缩生成150x150像素头像
|
|
||||||
- 智能居中裁剪保持正方形
|
|
||||||
- JPEG格式优化存储
|
|
||||||
- 旧头像文件自动清理
|
|
||||||
- 头像URL管理和存储
|
|
||||||
- 创建专用头像目录 (`uploads/avatars/`)
|
|
||||||
- 数据库头像URL字段自动更新
|
|
||||||
- 静态文件服务支持头像访问
|
|
||||||
- 头像文件命名规范化
|
|
||||||
- 完整的API测试用例 (`test_avatar_upload.http`)
|
|
||||||
- 正常头像上传测试
|
|
||||||
- 错误场景覆盖 (文件过大、非图片、权限不足)
|
|
||||||
- 静态文件访问验证
|
|
||||||
- 编译测试通过,功能完整可用
|
|
||||||
|
|
||||||
#### 12. ✅ 添加数据库种子数据
|
|
||||||
**状态**: 已完成 ✅
|
|
||||||
**完成时间**: 2025-07-11
|
|
||||||
**完成内容**:
|
|
||||||
- 创建完整的种子数据系统 (`seed_data.sql`)
|
|
||||||
- 6个用户数据 (包含管理员和5个摄影师)
|
|
||||||
- 9个分类数据 (风景、人像、建筑、街拍、艺术、宠物、食物、旅行、黑白)
|
|
||||||
- 35张照片数据 (涵盖所有分类,均衡分布)
|
|
||||||
- 自动化执行脚本 (`run_seed_data.sh`)
|
|
||||||
- 数据质量测试脚本 (`test_seed_data.sh`)
|
|
||||||
- Makefile 集成 (`make seed`, `make test-seed`, `make db-status`)
|
|
||||||
- 完整的使用文档 (`SEED_DATA_README.md`)
|
|
||||||
- 数据库备份机制,时间戳命名
|
|
||||||
- 9项自动化测试全部通过,数据质量保证
|
|
||||||
|
|
||||||
#### 13. ✅ 完善数据库迁移脚本
|
|
||||||
**状态**: 已完成 ✅
|
|
||||||
**完成时间**: 2025-07-11
|
|
||||||
**完成内容**:
|
|
||||||
- 创建完整的迁移框架 (`pkg/migration/`)
|
|
||||||
- 版本管理系统,时间戳版本号 (YYYYMMDD_HHMMSS)
|
|
||||||
- 事务安全的上下迁移机制 (Up/Down)
|
|
||||||
- 迁移状态跟踪和记录 (`migration_records` 表)
|
|
||||||
- 命令行迁移工具 (`cmd/migrate/main.go`)
|
|
||||||
- 生产环境迁移脚本 (`scripts/production-migrate.sh`)
|
|
||||||
- 生产环境初始化脚本 (`scripts/init-production-db.sh`)
|
|
||||||
- 迁移测试脚本 (`scripts/test-migration.sh`)
|
|
||||||
- Makefile 集成 (`migrate-up`, `migrate-down`, `migrate-status`)
|
|
||||||
- 5个预定义迁移 (基础表、默认数据、元数据、收藏、用户资料)
|
|
||||||
- 自动备份机制、预览模式、详细日志
|
|
||||||
- 完整文档 (`docs/DATABASE_MIGRATION.md`)
|
|
||||||
|
|
||||||
#### 14. ✅ 实现 CORS 中间件
|
|
||||||
**状态**: 已完成 ✅
|
|
||||||
**完成时间**: 2025-07-11
|
|
||||||
**完成内容**:
|
|
||||||
- 创建完整的CORS中间件 (`internal/middleware/cors.go`)
|
|
||||||
- 支持开发/生产环境不同的CORS配置
|
|
||||||
- 默认允许的开发环境源 (localhost:3000, 3001, 5173, 8080)
|
|
||||||
- 生产环境严格的源控制 (photography.iriver.top)
|
|
||||||
- 支持通配符和环境变量配置
|
|
||||||
- 完整的预检请求(OPTIONS)处理
|
|
||||||
- 安全头部设置 (X-Frame-Options, X-Content-Type-Options, X-XSS-Protection等)
|
|
||||||
- 内容安全策略(CSP)基础配置
|
|
||||||
- 支持凭证传递和自定义头部
|
|
||||||
- 智能来源验证和日志记录
|
|
||||||
|
|
||||||
#### 15. ✅ 添加 API 接口测试用例
|
|
||||||
**状态**: 已完成 ✅
|
|
||||||
**完成时间**: 2025-07-11
|
|
||||||
**完成内容**:
|
|
||||||
- 创建完整的单元测试套件 (`tests/unit_test.go`)
|
|
||||||
- 测试环境设置和数据库连接
|
|
||||||
- 认证流程测试 (注册、登录、Token验证)
|
|
||||||
- CRUD操作完整测试 (用户、分类、照片)
|
|
||||||
- 文件上传和处理测试
|
|
||||||
- 中间件功能测试 (CORS、认证、日志)
|
|
||||||
- 错误处理和边界条件测试
|
|
||||||
- 创建集成测试套件 (`tests/integration_test.go`)
|
|
||||||
- 完整业务流程测试
|
|
||||||
- 数据库事务和一致性测试
|
|
||||||
- 并发操作和性能测试
|
|
||||||
- 缓存操作和错误恢复测试
|
|
||||||
- 创建综合API测试用例 (`test_api_comprehensive.http`)
|
|
||||||
- 92个完整测试场景
|
|
||||||
- 覆盖所有API端点和错误情况
|
|
||||||
- 包含性能测试和安全测试
|
|
||||||
- 支持自动化和手动测试
|
|
||||||
- 更新Makefile添加测试命令
|
|
||||||
- `make test-unit` - 单元测试
|
|
||||||
- `make test-integration` - 集成测试
|
|
||||||
- `make test-api` - API测试
|
|
||||||
- `make test-cover` - 覆盖率报告
|
|
||||||
- `make test-bench` - 性能测试
|
|
||||||
- `make test-all` - 完整测试套件
|
|
||||||
- 添加testify库支持,提供完整的断言功能
|
|
||||||
|
|
||||||
#### 16. ✅ 实现请求日志中间件
|
|
||||||
**状态**: 已完成 ✅
|
|
||||||
**完成时间**: 2025-07-11
|
|
||||||
**完成内容**:
|
|
||||||
- 创建完整的请求日志中间件 (`internal/middleware/logger.go`)
|
|
||||||
- 支持请求和响应体记录 (可配置开关)
|
|
||||||
- 智能的请求ID生成和传递
|
|
||||||
- 完整的请求生命周期记录 (开始、完成、错误)
|
|
||||||
- 性能监控和慢请求检测 (可配置阈值)
|
|
||||||
- 客户端IP识别 (支持代理头部)
|
|
||||||
- 敏感信息过滤和安全日志记录
|
|
||||||
- Panic恢复和堆栈跟踪
|
|
||||||
- 可配置的日志级别和跳过路径
|
|
||||||
- 与go-zero日志系统完美集成
|
|
||||||
|
|
||||||
#### 17. ✅ 完善全局错误处理
|
|
||||||
**状态**: 已完成 ✅
|
|
||||||
**完成时间**: 2025-07-11
|
|
||||||
**完成内容**:
|
|
||||||
- 创建全局错误处理中间件 (`internal/middleware/error.go`)
|
|
||||||
- 统一错误响应格式和标准化错误码
|
|
||||||
- 支持开发/生产环境不同的错误详情显示
|
|
||||||
- 敏感信息过滤和安全响应
|
|
||||||
- 错误监控和报告系统框架
|
|
||||||
- HTTP状态码智能映射
|
|
||||||
- 详细的错误日志记录和分类
|
|
||||||
- 支持第三方监控服务集成预留
|
|
||||||
- 创建中间件管理器 (`internal/middleware/middleware.go`)
|
|
||||||
- 更新配置系统支持中间件配置
|
|
||||||
- 编译测试通过,功能完整可用
|
|
||||||
|
|
||||||
### 🎨 前端展示网站 (6项)
|
|
||||||
#### 18. ✅ 创建前端展示网站基础架构
|
|
||||||
**状态**: 已完成 ✅
|
|
||||||
**完成时间**: 2025-07-11
|
|
||||||
**完成内容**:
|
|
||||||
- 更新前端API配置支持后端go-zero服务连接
|
|
||||||
- 实现智能API模式切换 (真实API vs Mock API)
|
|
||||||
- 完善数据类型转换和格式统一处理
|
|
||||||
- 添加分类服务处理category_id到名称的映射
|
|
||||||
- 创建API状态监控组件,实时显示连接状态
|
|
||||||
- 完善错误处理和用户反馈机制
|
|
||||||
- 编写API集成指导文档 (API_INTEGRATION.md)
|
|
||||||
- 确保前端与后端API完全兼容
|
|
||||||
- TypeScript类型安全验证通过
|
|
||||||
- 构建测试成功,前端展示网站架构完成
|
|
||||||
|
|
||||||
#### 19. ✅ 实现照片展示页面
|
|
||||||
**状态**: 已完成 ✅
|
|
||||||
**完成时间**: 2025-07-11
|
|
||||||
**完成内容**:
|
|
||||||
- 完整的照片网格布局系统,支持3种视图模式 (网格/瀑布流/列表)
|
|
||||||
- 实现分页加载功能,支持无限滚动和手动加载更多
|
|
||||||
- 增强的照片卡片设计,悬停效果和交互体验
|
|
||||||
- 视图模式切换按钮,用户可自由选择展示方式
|
|
||||||
- 智能图片加载和loading状态显示
|
|
||||||
- 照片计数显示和加载状态反馈
|
|
||||||
- 响应式设计,完美适配移动端和桌面端
|
|
||||||
- 优化的性能,支持大量照片的流畅展示
|
|
||||||
|
|
||||||
#### 20. ✅ 开发照片搜索和过滤功能
|
|
||||||
**状态**: 已完成 ✅
|
|
||||||
**完成时间**: 2025-07-11
|
|
||||||
**完成内容**:
|
|
||||||
- 实时搜索功能,支持标题、描述、分类搜索
|
|
||||||
- 智能过滤栏,集成搜索框、排序选择、高级筛选
|
|
||||||
- 多种排序方式 (最新发布、最早发布、标题A-Z、标题Z-A、按分类)
|
|
||||||
- 标签筛选功能,支持多选标签过滤
|
|
||||||
- 高级筛选面板,可展开/收起的标签选择界面
|
|
||||||
- 当前筛选状态显示,可视化已选择的过滤条件
|
|
||||||
- 一键清除全部筛选功能
|
|
||||||
- 动态分类加载,从后端获取真实分类数据
|
|
||||||
- 响应式筛选界面,移动端友好设计
|
|
||||||
|
|
||||||
#### 21. ✅ 实现分类和标签页面
|
|
||||||
**状态**: 已完成 ✅
|
|
||||||
**完成时间**: 2025-07-11
|
|
||||||
**完成内容**:
|
|
||||||
- 完整的分类浏览页面,统计和网格/列表双视图
|
|
||||||
- 分类统计信息显示 (照片数量、最后更新时间、分类数量)
|
|
||||||
- 分类预览图网格,支持1-4张照片预览
|
|
||||||
- 标签云页面,热度可视化的标签展示
|
|
||||||
- 标签详情卡片,显示使用频率和相关照片
|
|
||||||
- 面包屑导航,方便用户在页面间跳转
|
|
||||||
- 搜索功能,支持分类和标签的实时搜索
|
|
||||||
- 点击分类/标签自动跳转到作品集并应用筛选
|
|
||||||
- 统计仪表盘,显示总体数据概览
|
|
||||||
- 空状态处理,优雅的无数据提示界面
|
|
||||||
|
|
||||||
#### 22. ✅ 连接前端与后端API (完成)
|
|
||||||
**状态**: 完成 ✅
|
|
||||||
**完成时间**: 2025-07-11
|
|
||||||
**完成内容**:
|
|
||||||
- API连接架构已完成,数据转换层已实现
|
|
||||||
- 后端服务成功启动 (端口8080)
|
|
||||||
- 修复前端API配置中的端口号 (8888→8080)
|
|
||||||
- 完成完整API联调测试,所有接口正常工作
|
|
||||||
- 验证用户认证、分类管理、照片管理等核心功能
|
|
||||||
- 创建API集成测试脚本,验证前后端连接状态
|
|
||||||
|
|
||||||
#### 23. ✅ 前端响应式设计优化
|
|
||||||
**状态**: 已完成 ✅
|
|
||||||
**完成时间**: 2025-07-11
|
|
||||||
**完成内容**:
|
|
||||||
- 添加触摸手势支持库 (react-spring + @use-gesture/react)
|
|
||||||
- 照片模态框增加左右滑动切换功能
|
|
||||||
- 照片画廊增加下拉刷新功能 (移动端)
|
|
||||||
- 优化所有按钮符合44px最小触摸目标标准
|
|
||||||
- 增强移动端导航体验,增加悬停和选中状态
|
|
||||||
- 创建设备信息检测钩子 (useDeviceInfo)
|
|
||||||
- 开发优化图片组件,支持懒加载和骨架屏
|
|
||||||
- 改进移动端手势交互和视觉反馈
|
|
||||||
- 完善响应式断点系统和触摸设备检测
|
|
||||||
- 前端构建测试成功,开发服务器正常启动
|
|
||||||
|
|
||||||
### 🚀 部署和运维 (4项)
|
|
||||||
#### 24. ✅ 配置生产环境数据库
|
|
||||||
**状态**: 已完成 ✅
|
|
||||||
**完成时间**: 2025-07-11
|
|
||||||
**完成内容**:
|
|
||||||
- 创建生产环境Docker Compose配置 (`configs/docker/docker-compose.prod.yml`)
|
|
||||||
- PostgreSQL 16服务配置,包含持久化存储
|
|
||||||
- Redis 7缓存服务,支持密码认证
|
|
||||||
- API服务容器化部署配置
|
|
||||||
- Nginx反向代理和SSL终止
|
|
||||||
- Prometheus + Grafana监控栈
|
|
||||||
- 生产环境数据库初始化脚本 (`configs/docker/init-db.sql`)
|
|
||||||
- 完整的PostgreSQL数据库结构
|
|
||||||
- 用户权限和安全配置
|
|
||||||
- 索引优化和性能调优
|
|
||||||
- 触发器和函数创建
|
|
||||||
- 视图和统计功能
|
|
||||||
- 默认数据插入
|
|
||||||
- 生产环境配置脚本 (`scripts/production-db-setup.sh`)
|
|
||||||
- 自动化环境检查和依赖安装
|
|
||||||
- PostgreSQL性能优化配置
|
|
||||||
- PgBouncer连接池配置
|
|
||||||
- 自动备份策略和cron任务
|
|
||||||
- 数据库监控和报警系统
|
|
||||||
- 完整的日志记录和轮转配置
|
|
||||||
- 数据库连接池和性能优化
|
|
||||||
- 连接池大小: 20 (默认),最大100连接
|
|
||||||
- 事务级连接池模式
|
|
||||||
- 自动清理和超时配置
|
|
||||||
- 内存优化和缓存配置
|
|
||||||
|
|
||||||
#### 25. ✅ 更新CI/CD支持后端部署
|
|
||||||
**状态**: 已完成 ✅
|
|
||||||
**完成时间**: 2025-07-11
|
|
||||||
**完成内容**:
|
|
||||||
- 完善现有后端CI/CD配置文件 (`deploy-backend.yml`)
|
|
||||||
- 优化Docker构建和部署流程,使用systemd服务管理
|
|
||||||
- 添加完整的测试步骤 (单元测试、代码检查、格式验证)
|
|
||||||
- 实现零停机部署,包含备份和回滚机制
|
|
||||||
- 配置健康检查和自动化部署通知
|
|
||||||
- 集成到现有的阿里云服务器部署环境
|
|
||||||
- 支持手动触发和自动触发两种模式
|
|
||||||
- 添加构建产物缓存和性能优化
|
|
||||||
|
|
||||||
#### 26. ✅ 配置反向代理
|
|
||||||
**状态**: 已完成 ✅
|
|
||||||
**完成时间**: 2025-07-11
|
|
||||||
**完成内容**:
|
|
||||||
- 更新Caddy配置支持多域名架构
|
|
||||||
- 配置API反向代理 (`api.photography.iriver.top -> localhost:8080`)
|
|
||||||
- 添加管理后台支持 (`admin.photography.iriver.top`)
|
|
||||||
- 实现健康检查和故障转移机制
|
|
||||||
- 配置CORS和安全头部设置
|
|
||||||
- 添加API限流和错误处理
|
|
||||||
- 优化静态资源缓存策略
|
|
||||||
- 支持自动SSL证书管理
|
|
||||||
|
|
||||||
#### 27. ✅ 设置生产环境监控
|
|
||||||
**状态**: 已完成 ✅
|
|
||||||
**完成时间**: 2025-07-11
|
|
||||||
**完成内容**:
|
|
||||||
- 创建完整的监控系统配置脚本 (`monitoring-setup.sh`)
|
|
||||||
- 实现日志收集系统 (rsyslog + logrotate)
|
|
||||||
- 配置性能监控 (系统指标、API响应时间、资源使用)
|
|
||||||
- 设置错误监控和报告系统
|
|
||||||
- 实现健康检查机制 (服务状态、端口监听、API可用性)
|
|
||||||
- 创建监控仪表板和配置文件
|
|
||||||
- 配置定时任务 (cron) 自动化监控
|
|
||||||
- 支持多种告警渠道 (日志、邮件预留)
|
|
||||||
|
|
||||||
### 📝 测试和文档 (2项)
|
|
||||||
#### 28. ✅ 编写API文档
|
|
||||||
**状态**: 已完成 ✅
|
|
||||||
**完成时间**: 2025-07-11
|
|
||||||
**完成内容**:
|
|
||||||
- 创建完整的API文档 (`docs/API_DOCUMENTATION.md`)
|
|
||||||
- 详细的API概览和基本信息
|
|
||||||
- 统一的响应格式和错误处理说明
|
|
||||||
- 完整的认证接口文档 (注册、登录)
|
|
||||||
- 用户管理接口文档 (CRUD、头像上传)
|
|
||||||
- 照片管理接口文档 (上传、查询、更新、删除)
|
|
||||||
- 分类和标签管理接口文档
|
|
||||||
- 健康检查和统计接口文档
|
|
||||||
- 静态文件服务说明
|
|
||||||
- 包含完整的请求/响应示例
|
|
||||||
- JSON格式的请求参数示例
|
|
||||||
- 详细的响应数据结构
|
|
||||||
- cURL命令行调用示例
|
|
||||||
- 错误响应格式和状态码说明
|
|
||||||
- 开发和部署指南
|
|
||||||
- 环境配置说明
|
|
||||||
- 认证流程详解
|
|
||||||
- 错误处理机制
|
|
||||||
- 性能优化建议
|
|
||||||
- 安全考虑要点
|
|
||||||
- SDK和工具支持
|
|
||||||
- JavaScript/TypeScript SDK示例
|
|
||||||
- Postman Collection指南
|
|
||||||
- OpenAPI 3.0规范支持
|
|
||||||
- Swagger UI集成说明
|
|
||||||
- 部署和运维文档
|
|
||||||
- Docker部署配置
|
|
||||||
- Kubernetes部署示例
|
|
||||||
- 监控和日志收集
|
|
||||||
|
|
||||||
#### 29. ✅ 编写用户使用文档
|
|
||||||
**状态**: 已完成 ✅
|
|
||||||
**完成时间**: 2025-07-11
|
|
||||||
**完成内容**:
|
|
||||||
- 创建完整的用户使用手册 (`docs/USER_MANUAL.md`)
|
|
||||||
- 详细的管理后台使用指南 (登录、照片管理、分类管理等)
|
|
||||||
- 前端网站使用说明 (浏览、搜索、移动端使用)
|
|
||||||
- 完整的部署运维指南 (环境准备、部署步骤、监控维护)
|
|
||||||
- 故障排查指南 (常见错误、性能优化、监控命令)
|
|
||||||
- 技术支持体系 (联系方式、问题反馈渠道)
|
|
||||||
- 常见问题解答 (登录、上传、性能等问题)
|
|
||||||
- 更新日志和版本管理说明
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📌 低优先级任务 (11/29) - 细化拆分
|
|
||||||
|
|
||||||
### 🐳 容器化和部署扩展 (4项)
|
|
||||||
#### 30. ✅ 后端Docker容器化
|
|
||||||
**状态**: 已完成 ✅
|
|
||||||
**完成时间**: 2025-07-11
|
|
||||||
**完成内容**:
|
|
||||||
- 创建多阶段构建Dockerfile (`backend/Dockerfile`)
|
|
||||||
- 使用golang:1.23-alpine作为构建镜像,scratch作为运行镜像
|
|
||||||
- 支持静态链接编译,最小化镜像大小
|
|
||||||
- 包含健康检查机制和安全用户配置
|
|
||||||
- 创建Docker Compose配置 (`backend/docker-compose.yml`)
|
|
||||||
- 集成PostgreSQL、Redis、API服务的完整开发环境
|
|
||||||
- 添加.dockerignore文件优化构建上下文
|
|
||||||
- 更新Makefile添加Docker相关命令
|
|
||||||
- 支持开发和生产环境的不同配置
|
|
||||||
|
|
||||||
#### 31. ✅ 前端Docker容器化
|
|
||||||
**状态**: 已完成 ✅
|
|
||||||
**完成时间**: 2025-07-11
|
|
||||||
**完成内容**:
|
|
||||||
- 创建多阶段构建Dockerfile (`frontend/Dockerfile`)
|
|
||||||
- 使用node:20-alpine构建,nginx:1.25-alpine服务静态文件
|
|
||||||
- 集成bun包管理器,优化构建速度
|
|
||||||
- 创建优化的Nginx配置 (`nginx.conf`, `default.conf`)
|
|
||||||
- 配置缓存策略、压缩、安全头部设置
|
|
||||||
- 创建Docker Compose配置 (`frontend/docker-compose.yml`)
|
|
||||||
- 支持开发、生产、代理多种模式
|
|
||||||
- 添加.dockerignore文件减少镜像大小
|
|
||||||
- 更新Makefile添加Docker相关命令
|
|
||||||
- 配置健康检查和环境变量管理
|
|
||||||
|
|
||||||
#### 32. 数据库Docker配置
|
|
||||||
**优先级**: 低 ⚡
|
|
||||||
**预估工作量**: 0.5天
|
|
||||||
**具体任务**: PostgreSQL容器、数据持久化、初始化脚本
|
|
||||||
|
|
||||||
#### 33. 完整Docker编排
|
|
||||||
**优先级**: 低 ⚡
|
|
||||||
**预估工作量**: 0.5天
|
|
||||||
**具体任务**: docker-compose.yml、网络配置、环境变量管理
|
|
||||||
|
|
||||||
### 📈 性能和缓存优化 (3项)
|
|
||||||
#### 34. 实现Redis缓存
|
|
||||||
**优先级**: 低 ⚡
|
|
||||||
**预估工作量**: 0.5天
|
|
||||||
**具体任务**: Redis配置、照片列表缓存、分类数据缓存
|
|
||||||
|
|
||||||
#### 35. API性能优化
|
|
||||||
**优先级**: 低 ⚡
|
|
||||||
**预估工作量**: 0.5天
|
|
||||||
**具体任务**: 数据库查询优化、索引优化、分页优化
|
|
||||||
|
|
||||||
#### 36. 前端性能优化
|
|
||||||
**优先级**: 低 ⚡
|
|
||||||
**预估工作量**: 0.5天
|
|
||||||
**具体任务**: 代码分割、懒加载、图片优化、CDN配置
|
|
||||||
|
|
||||||
### ☁️ 云服务集成 (2项)
|
|
||||||
#### 37. 配置云存储服务
|
|
||||||
**优先级**: 低 ⚡
|
|
||||||
**预估工作量**: 0.5天
|
|
||||||
**具体任务**: 七牛云/阿里云OSS集成、图片上传、CDN加速
|
|
||||||
|
|
||||||
#### 38. 配置云数据库
|
|
||||||
**优先级**: 低 ⚡
|
|
||||||
**预估工作量**: 0.5天
|
|
||||||
**具体任务**: 云数据库配置、备份策略、高可用配置
|
|
||||||
|
|
||||||
### 🧪 测试完善 (2项)
|
|
||||||
#### 39. 编写前端E2E测试
|
|
||||||
**优先级**: 低 ⚡
|
|
||||||
**预估工作量**: 1天
|
|
||||||
**具体任务**: Cypress配置、关键流程测试、自动化测试
|
|
||||||
|
|
||||||
#### 40. 编写后端集成测试
|
|
||||||
**优先级**: 低 ⚡
|
|
||||||
**预估工作量**: 1天
|
|
||||||
**具体任务**: API集成测试、数据库测试、性能测试
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🎯 里程碑规划
|
## 🎯 里程碑规划
|
||||||
|
|
||||||
### 第一阶段:核心功能完善 ✅ (已完成)
|
### ✅ Phase 1-2: 核心功能 + 管理后台 - **已完成**
|
||||||
- [x] 照片上传功能
|
- ✅ 照片上传功能
|
||||||
- [x] JWT 认证中间件
|
- ✅ JWT 认证中间件
|
||||||
- [x] 照片和分类的完整 CRUD
|
- ✅ 照片和分类的完整 CRUD
|
||||||
- [x] 前后端 API 集成
|
- ✅ 管理后台界面开发
|
||||||
|
|
||||||
**目标**: 实现核心业务功能的完整闭环 ✅
|
### 🔄 Phase 3: 前端展示网站 - **进行中**
|
||||||
|
- 🔄 前端网站与后端对接 - **已完成**
|
||||||
|
- 🔄 照片展示和搜索功能 - **已完成**
|
||||||
|
- 🔄 响应式设计优化 - **已完成**
|
||||||
|
- ⏳ 用户体验完善 - **待优化**
|
||||||
|
|
||||||
### 第二阶段:管理后台完善 ✅ (已完成)
|
### ⏳ Phase 4: 部署和优化 - **待开始**
|
||||||
- [x] 用户认证界面完善
|
- ⏳ 生产环境数据库配置
|
||||||
- [x] 照片管理界面开发
|
- ⏳ CI/CD 流程更新
|
||||||
- [x] 分类管理界面开发
|
- ⏳ 性能优化
|
||||||
- [x] 照片上传界面开发
|
- ⏳ 监控和文档
|
||||||
|
|
||||||
**目标**: 完整的管理后台功能 ✅
|
|
||||||
|
|
||||||
### 第三阶段:前端展示网站 (下一步)
|
|
||||||
- [ ] 前端网站与后端对接
|
|
||||||
- [ ] 照片展示和搜索功能
|
|
||||||
- [ ] 响应式设计优化
|
|
||||||
- [ ] 用户体验完善
|
|
||||||
|
|
||||||
**目标**: 公众访问的展示网站
|
|
||||||
|
|
||||||
### 第四阶段:部署和优化 (后续)
|
|
||||||
- [ ] 生产环境数据库配置
|
|
||||||
- [ ] CI/CD 流程更新
|
|
||||||
- [ ] 性能优化
|
|
||||||
- [ ] 监控和文档
|
|
||||||
|
|
||||||
**目标**: 生产环境就绪
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 💻 技术成果
|
## 🔥 最近完成的任务
|
||||||
|
|
||||||
### ✅ 已实现的核心功能
|
### 2025-07-16 - 健康检查修复
|
||||||
- **文件上传系统**: 完整的图片上传和缩略图生成
|
- ✅ 修复健康检查端点 404 错误
|
||||||
- **JWT 认证体系**: 用户认证和权限管理
|
- ✅ 验证 `/api/v1/health` 端点正常工作
|
||||||
- **静态文件服务**: 图片资源访问
|
- ✅ 后端服务稳定运行在端口 8080
|
||||||
- **图片处理能力**: 自动缩放和格式支持
|
|
||||||
- **安全文件验证**: 类型和大小检查
|
|
||||||
- **照片CRUD完整**: 创建、读取、更新、删除全功能
|
|
||||||
- **权限控制**: 用户只能操作自己的照片
|
|
||||||
- **文件系统管理**: 删除照片时同步删除文件
|
|
||||||
- **错误处理统一**: 使用项目统一的 errorx 错误处理机制
|
|
||||||
- **代码质量保证**: 修复所有导入错误,确保编译通过
|
|
||||||
- **前后端联调**: 管理后台与后端API完全对接
|
|
||||||
- **数据格式统一**: 修复前后端数据类型和字段不匹配问题
|
|
||||||
- **API测试验证**: 创建测试页面验证所有功能正常
|
|
||||||
- **类型系统完善**: 修复所有TypeScript类型错误,确保类型安全
|
|
||||||
- **代码质量优化**: 消除编译警告,统一API响应格式
|
|
||||||
- **构建系统稳定**: 项目构建成功,开发服务器快速启动(74ms)
|
|
||||||
- **🆕 管理后台完整UI**: 照片上传、管理、分类管理界面全部完成
|
|
||||||
- **🆕 拖拽上传功能**: 完整的drag-and-drop文件上传体验
|
|
||||||
- **🆕 进度显示系统**: 实时上传进度和状态反馈
|
|
||||||
- **🆕 批量操作支持**: 照片批量选择、状态更新、删除功能
|
|
||||||
- **🆕 树形分类管理**: 分类层次结构、展开收起、视觉化管理
|
|
||||||
- **🆕 模态对话框**: 编辑、详情、创建等完整的对话框系统
|
|
||||||
- **🆕 响应式设计**: 网格/列表视图切换,移动端适配
|
|
||||||
- **🆕 搜索过滤功能**: 照片和分类的实时搜索过滤
|
|
||||||
- **🆕 状态管理优化**: 完整的loading、error、success状态处理
|
|
||||||
- **🆕 用户体验增强**: Toast通知、确认对话框、空状态页面
|
|
||||||
|
|
||||||
### 📊 API 接口状态
|
### 2025-07-11 - 重大里程碑日
|
||||||
- ✅ `POST /api/v1/auth/login` - 用户登录
|
- ✅ **Phase 2 完成**: 管理后台所有功能开发完成
|
||||||
- ✅ `POST /api/v1/auth/register` - 用户注册
|
- ✅ **Phase 3 启动**: 前端展示网站功能全部实现
|
||||||
- ✅ `GET /api/v1/health` - 健康检查
|
- ✅ **部署系统**: 完整CI/CD、Docker、监控体系建立
|
||||||
- ✅ `GET /api/v1/photos` - 照片列表
|
- ✅ **文档完善**: API文档和用户手册完成
|
||||||
- ✅ `POST /api/v1/photos` - 上传照片 (支持文件上传)
|
|
||||||
- ✅ `GET /api/v1/photos/:id` - 获取照片详情
|
|
||||||
- ✅ `PUT /api/v1/photos/:id` - 更新照片 (支持权限验证)
|
|
||||||
- ✅ `DELETE /api/v1/photos/:id` - 删除照片 (同时删除文件)
|
|
||||||
- ✅ `GET /api/v1/categories` - 分类列表
|
|
||||||
- ✅ `POST /api/v1/categories` - 创建分类
|
|
||||||
- ✅ `PUT /api/v1/categories/:id` - 更新分类 (代码完善)
|
|
||||||
- ✅ `GET /api/v1/users` - 用户列表
|
|
||||||
- ✅ `POST /api/v1/users` - 创建用户 (完整业务逻辑)
|
|
||||||
- ✅ `GET /api/v1/users/:id` - 获取用户详情 (完整业务逻辑)
|
|
||||||
- ✅ `PUT /api/v1/users/:id` - 更新用户 (完整业务逻辑)
|
|
||||||
- ✅ `DELETE /api/v1/users/:id` - 删除用户 (完整业务逻辑)
|
|
||||||
- ✅ `GET /uploads/*` - 静态文件访问
|
|
||||||
- ⏳ `DELETE /api/v1/categories/:id` - 删除分类
|
|
||||||
|
|
||||||
### 🛠️ 技术栈
|
|
||||||
- **后端框架**: go-zero v1.8.0
|
|
||||||
- **数据库**: SQLite (开发) / PostgreSQL (生产)
|
|
||||||
- **认证**: JWT Token
|
|
||||||
- **文件处理**: imaging + uuid
|
|
||||||
- **构建工具**: Go 1.23+ + Makefile
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 📈 每日进度记录
|
## 📋 下一步行动计划
|
||||||
|
|
||||||
### 2025-07-11 (深夜) - 部署和运维系统完善 🚀
|
### 近期优先级 (本周)
|
||||||
- ✅ **CI/CD后端部署优化**: 完善现有后端部署流程,添加systemd服务管理和零停机部署
|
1. **Phase 3 用户体验优化** - 前端展示网站细节完善
|
||||||
- ✅ **反向代理配置完成**: 更新Caddy配置支持多域名架构和API反向代理
|
2. **Phase 4 部署配置** - 生产环境准备
|
||||||
- ✅ **生产环境监控系统**: 创建完整的监控系统,包含日志收集、性能监控、健康检查
|
3. **性能优化** - Redis缓存、API优化
|
||||||
- ✅ **多域名架构部署**: 支持前端、API、管理后台三个独立域名
|
|
||||||
- ✅ **自动化运维脚本**: 监控系统配置脚本,支持定时任务和告警
|
|
||||||
- ✅ **部署流程标准化**: 备份、回滚、健康检查的完整部署流程
|
|
||||||
- ✅ **安全配置增强**: CORS、限流、错误处理等安全措施
|
|
||||||
- 🎉 **里程碑达成**: 部署和运维体系完善,3个中优先级任务同时完成
|
|
||||||
- 📊 **进度提升**: 项目总进度从57.5%提升至65.0%,中优先级任务完成率达85%
|
|
||||||
|
|
||||||
### 2025-07-11 (晚间) - 测试和生产环境配置完善 🧪
|
### 中期规划 (下月)
|
||||||
- ✅ **API接口测试用例完成**: 创建完整的单元测试、集成测试、API测试套件
|
1. **云服务集成** - 云存储、云数据库
|
||||||
- ✅ **测试框架完善**: 添加testify库支持,92个综合测试场景,覆盖所有API端点
|
2. **测试完善** - E2E测试、集成测试
|
||||||
- ✅ **生产环境数据库配置**: Docker Compose生产配置,PostgreSQL优化,连接池配置
|
3. **性能监控** - 完整监控体系
|
||||||
- ✅ **数据库生产方案**: 自动备份策略,监控告警,性能调优,安全配置
|
|
||||||
- ✅ **API文档完成**: 完整的接口文档,包含示例代码、SDK支持、部署指南
|
|
||||||
- ✅ **Makefile测试命令**: 添加完整的测试命令支持,包含单元、集成、性能测试
|
|
||||||
- ✅ **生产环境脚本**: 自动化配置脚本,环境检查,PostgreSQL调优
|
|
||||||
- 🎉 **里程碑达成**: 测试体系和生产环境配置完善,3个中优先级任务同时完成
|
|
||||||
- 📊 **进度提升**: 项目总进度从50.0%提升至57.5%,中优先级任务完成率达70%
|
|
||||||
|
|
||||||
### 2025-07-11 (深夜) - 中间件系统完善 🛡️
|
|
||||||
- ✅ **CORS中间件完成**: 支持开发/生产环境配置,完整的跨域策略和安全头部
|
|
||||||
- ✅ **请求日志中间件完成**: 完整的请求生命周期记录,性能监控,敏感信息过滤
|
|
||||||
- ✅ **全局错误处理完成**: 统一错误响应格式,错误监控框架,开发/生产环境适配
|
|
||||||
- ✅ **中间件管理器**: 创建中间件管理器,支持链式中间件和配置管理
|
|
||||||
- ✅ **配置系统更新**: 更新配置文件支持中间件配置,环境变量支持
|
|
||||||
- ✅ **编译测试成功**: 修复go-zero日志API兼容性,所有中间件编译通过
|
|
||||||
- ✅ **测试用例创建**: 创建完整的中间件测试用例 (`test_middleware.http`)
|
|
||||||
- 🎉 **里程碑达成**: 后端中间件系统完善,3个中优先级任务同时完成
|
|
||||||
- 📊 **进度提升**: 项目总进度从42.5%提升至50.0%,中优先级任务完成率达55%
|
|
||||||
|
|
||||||
### 2025-07-11 (晚上) - Phase 3 重大进展 🎯
|
|
||||||
- ✅ **照片展示页面完成**: 实现3种视图模式(网格/瀑布流/列表)和分页加载
|
|
||||||
- ✅ **搜索过滤功能完成**: 实时搜索、多维度筛选、标签过滤、排序功能
|
|
||||||
- ✅ **分类标签页面完成**: 分类浏览、标签云、统计仪表盘、面包屑导航
|
|
||||||
- ✅ **用户体验大幅提升**: 智能筛选、视觉化统计、响应式设计
|
|
||||||
- ✅ **功能完整性**: 前端展示网站达到完全可用状态
|
|
||||||
- ✅ **性能优化**: 无限滚动、图片懒加载、智能分页
|
|
||||||
- ✅ **交互优化**: 悬停效果、加载状态、空状态处理
|
|
||||||
- ✅ **构建测试成功**: 所有新功能构建正常 (187kB gzipped)
|
|
||||||
- 🎉 **Phase 3 核心功能**: 前端展示网站功能基本完成
|
|
||||||
- 📝 **下一步**: 开始第四阶段部署和优化工作
|
|
||||||
|
|
||||||
### 2025-07-11 (早期) - Phase 3 启动 🚀
|
|
||||||
- ✅ **前端展示网站架构完成**: 更新前端API配置支持后端go-zero服务
|
|
||||||
- ✅ **智能API模式切换**: 实现真实API与Mock API的无缝切换
|
|
||||||
- ✅ **数据格式统一**: 完善后端数据转换和格式统一处理
|
|
||||||
- ✅ **分类服务集成**: 创建服务处理category_id到名称的映射
|
|
||||||
- ✅ **API状态监控**: 实时显示API连接状态和模式切换
|
|
||||||
- ✅ **错误处理完善**: 提供详细的错误信息和用户反馈
|
|
||||||
- ✅ **TypeScript类型安全**: 修复所有类型错误,确保编译通过
|
|
||||||
- ✅ **构建测试成功**: 前端展示网站可正常运行
|
|
||||||
- ✅ **集成文档完成**: 编写API_INTEGRATION.md指导文档
|
|
||||||
|
|
||||||
### 2025-07-11 (下午) - Phase 2 完成 🎉
|
|
||||||
- ✅ **照片上传界面完善**: 实现完整拖拽上传功能,支持多文件和进度显示
|
|
||||||
- ✅ **照片管理界面优化**: 创建编辑对话框、详情查看、批量操作功能
|
|
||||||
- ✅ **分类管理界面完善**: 树形结构渲染、展开收起、创建编辑功能
|
|
||||||
- ✅ **UI组件库完善**: 添加Dialog、Label、Textarea等缺失组件
|
|
||||||
- ✅ **用户体验优化**: 搜索过滤、状态管理、错误处理、Toast通知
|
|
||||||
- ✅ **响应式设计**: 网格/列表视图切换,移动端适配
|
|
||||||
- ✅ **TypeScript类型安全**: 修复所有类型错误,确保编译零错误
|
|
||||||
- ✅ **构建成功**: 项目构建成功(1.23s),生产环境就绪
|
|
||||||
- ✅ **Phase 2 里程碑**: 管理后台达到完整功能状态,可投入生产使用
|
|
||||||
|
|
||||||
### 2025-07-11 (上午)
|
|
||||||
- ✅ **管理后台与后端API联调完成**: 完成前后端完整对接
|
|
||||||
- ✅ **数据格式匹配修复**: 修复ID类型、字段名称、响应格式不匹配问题
|
|
||||||
- ✅ **API服务验证**: 验证登录、分类管理、照片管理等核心功能
|
|
||||||
- ✅ **前端类型系统更新**: 更新TypeScript类型定义匹配后端接口
|
|
||||||
- ✅ **测试页面创建**: 创建API测试页面验证所有功能正常工作
|
|
||||||
- ✅ **数据库初始化**: 数据库表创建完成,默认数据添加成功
|
|
||||||
|
|
||||||
### 2025-01-10 (晚上)
|
|
||||||
- ✅ **管理后台对接启动**: 分析管理后台架构,配置 API 服务地址
|
|
||||||
- ✅ **用户认证模块对接**: 修复前后端类型匹配,实现登录功能
|
|
||||||
- ✅ **数据库初始化**: 创建用户、分类、照片表,添加测试数据
|
|
||||||
- ✅ **API 接口验证**: 测试认证和受保护接口,功能正常
|
|
||||||
|
|
||||||
### 2025-01-10 (下午)
|
|
||||||
- ✅ **后端代码质量修复完成**: 修复 15 个逻辑文件的导入错误
|
|
||||||
- ✅ **错误处理机制统一**: 使用项目自定义的 errorx 包统一错误处理
|
|
||||||
- ✅ **编译问题解决**: 所有后端模块现在可以正常编译和运行
|
|
||||||
- ✅ **错误代码完善**: 添加 UserDisabled, InvalidParameter 等错误类型
|
|
||||||
|
|
||||||
### 2025-01-10 (上午)
|
|
||||||
- ✅ **照片上传功能完成**: 实现文件处理、缩略图生成、静态服务
|
|
||||||
- ✅ **JWT 认证中间件完成**: Bearer Token 验证和用户上下文注入
|
|
||||||
- ✅ **照片更新删除功能完成**: 实现权限验证、文件同步删除、完整CRUD
|
|
||||||
|
|
||||||
### 待补充...
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🔄 更新日志
|
## 📞 快速参考
|
||||||
|
|
||||||
### v0.7.0 - 2025-07-11 (深夜) - 部署和运维系统完善 🚀
|
### 服务状态
|
||||||
- **新增后端CI/CD部署流程**: 完善现有配置,支持systemd服务管理和零停机部署
|
- **后端API**: `localhost:8080` ✅ 运行正常
|
||||||
- **配置多域名反向代理**: 前端、API、管理后台三个独立域名架构
|
- **健康检查**: `/api/v1/health` ✅ 200 OK
|
||||||
- **实现生产环境监控**: 完整的日志收集、性能监控、健康检查系统
|
- **管理后台**: 功能完整 ✅
|
||||||
- **添加自动化运维脚本**: 监控系统配置、定时任务、告警机制
|
- **前端展示**: 功能完成 ✅
|
||||||
- **增强安全配置**: CORS、限流、错误处理等安全措施
|
|
||||||
- **标准化部署流程**: 备份、回滚、健康检查的完整部署体系
|
|
||||||
- **支持多环境部署**: 开发、生产环境配置分离
|
|
||||||
- **🎯 重要里程碑**: 部署和运维体系完善,生产环境就绪
|
|
||||||
- **📊 进度提升**: 项目总进度达65.0%,中优先级任务完成率达85%
|
|
||||||
|
|
||||||
### v0.6.0 - 2025-07-11 (深夜) - 中间件系统完善 🛡️
|
### 相关文件
|
||||||
- **新增完整的CORS中间件**: 跨域策略、安全头部、环境配置
|
- **历史任务**: `TASK_PROGRESS_ARCHIVED.md` (已完成的任务)
|
||||||
- **新增请求日志中间件**: 完整生命周期记录、性能监控、敏感信息过滤
|
- **当前任务**: 本文件 (待完成的任务)
|
||||||
- **新增全局错误处理中间件**: 统一错误响应、错误监控、开发/生产适配
|
- **项目文档**: 各模块 `CLAUDE.md`
|
||||||
- **创建中间件管理器**: 链式中间件、配置管理、环境区分
|
|
||||||
- **更新配置系统**: 支持中间件配置、环境变量管理
|
|
||||||
- **修复API兼容性**: go-zero日志系统适配、编译错误修复
|
|
||||||
- **创建测试用例**: 完整的中间件功能测试
|
|
||||||
- **🎯 重要里程碑**: 后端中间件系统完善,安全性大幅提升
|
|
||||||
- **📊 进度提升**: 项目总进度达50.0%,中优先级任务完成率达55%
|
|
||||||
|
|
||||||
### v0.5.0 - 2025-07-11 (下午) - Phase 2 完成 🎉
|
|
||||||
- **新增完整的照片上传界面**: 拖拽上传、多文件支持、进度显示
|
|
||||||
- **完善照片管理功能**: 编辑对话框、详情查看、批量操作
|
|
||||||
- **实现分类管理界面**: 树形结构、展开收起、完整CRUD
|
|
||||||
- **UI组件库完善**: 添加Dialog、Label、Textarea等组件
|
|
||||||
- **用户体验大幅提升**: 搜索过滤、状态管理、错误处理
|
|
||||||
- **响应式设计优化**: 网格/列表视图、移动端适配
|
|
||||||
- **类型安全保障**: 修复所有TypeScript类型错误
|
|
||||||
- **生产环境就绪**: 构建成功,性能优化完成
|
|
||||||
- **🎯 重要里程碑**: 管理后台Phase 2全部功能完成
|
|
||||||
|
|
||||||
### v0.4.0 - 2025-07-11 (上午)
|
|
||||||
- 修复所有TypeScript类型错误,实现编译零错误
|
|
||||||
- 完善API服务接口,添加缺失的方法实现
|
|
||||||
- 统一API响应数据访问模式,规范化data属性使用
|
|
||||||
- 修复Dashboard、Categories、Tags等页面组件
|
|
||||||
- 优化代码质量,消除所有编译警告
|
|
||||||
- 验证构建成功,确保开发服务器快速启动
|
|
||||||
- 管理后台达到生产就绪状态
|
|
||||||
|
|
||||||
### v0.3.0 - 2025-07-11 (上午)
|
|
||||||
- 完成管理后台与后端API完整联调
|
|
||||||
- 修复前后端数据格式不匹配问题
|
|
||||||
- 更新前端TypeScript类型定义
|
|
||||||
- 完善API响应拦截器和错误处理
|
|
||||||
- 创建API测试页面验证功能
|
|
||||||
- 数据库初始化和默认数据添加
|
|
||||||
- 验证用户认证和分类管理功能
|
|
||||||
|
|
||||||
### v0.2.1 - 2025-01-10 (下午)
|
|
||||||
- 修复后端所有导入错误问题 (15个文件)
|
|
||||||
- 统一错误处理机制使用 errorx 包
|
|
||||||
- 添加缺失的错误代码定义
|
|
||||||
- 解决编译错误,确保代码质量
|
|
||||||
- 完善分类更新逻辑的错误处理
|
|
||||||
|
|
||||||
### v0.2.0 - 2025-01-10 (上午)
|
|
||||||
- 新增完整的文件上传系统
|
|
||||||
- 新增 JWT 认证中间件
|
|
||||||
- 新增静态文件服务
|
|
||||||
- 优化图片处理能力
|
|
||||||
- 完善照片更新和删除功能
|
|
||||||
- 实现用户权限控制
|
|
||||||
- 添加文件系统同步管理
|
|
||||||
|
|
||||||
### v0.1.0 - 2025-01-09
|
|
||||||
- 初始化 go-zero 项目架构
|
|
||||||
- 实现基础 CRUD 接口
|
|
||||||
- 配置开发环境
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 📞 联系信息
|
*文档已精简,历史任务已归档。下一步建议从 Phase 4 开始。*
|
||||||
|
|
||||||
**项目负责人**: iriver
|
|
||||||
**项目仓库**: https://git.iriver.top/iriver/photography
|
|
||||||
**更新频率**: 每日更新
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
*本文档自动同步项目进度,如有疑问请查看具体模块的 CLAUDE.md 文件*
|
|
||||||
155
TASK_PROGRESS_ARCHIVED.md
Normal file
155
TASK_PROGRESS_ARCHIVED.md
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
# Photography Portfolio - 历史任务归档
|
||||||
|
|
||||||
|
> 📋 已完成任务的完整归档记录
|
||||||
|
> 最后归档时间: 2025-07-16
|
||||||
|
|
||||||
|
## 📊 项目里程碑总览
|
||||||
|
|
||||||
|
- **总任务数**: 40 (已完成: 29, 进行中: 0, 待开始: 11)
|
||||||
|
- **完成率**: 72.5%
|
||||||
|
- **阶段状态**: Phase 1-2 已完成, Phase 3-4 进行中
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✅ Phase 1-2 已完成任务 (29项)
|
||||||
|
|
||||||
|
### 🔥 高优先级任务 (9/9 已完成)
|
||||||
|
|
||||||
|
#### 1. ✅ 完善照片上传功能
|
||||||
|
**完成时间**: 2025-01-10
|
||||||
|
- 完整的文件处理工具包 (`pkg/utils/file/file.go`)
|
||||||
|
- 图片上传、缩略图生成、文件存储
|
||||||
|
- 支持多种图片格式 (JPEG, PNG, GIF, WebP)
|
||||||
|
- 文件大小和类型验证
|
||||||
|
- 自动缩略图生成 (300px宽度)
|
||||||
|
- 静态文件服务 (`/uploads/*`)
|
||||||
|
|
||||||
|
#### 2. ✅ 实现 JWT 认证中间件
|
||||||
|
**完成时间**: 2025-01-10
|
||||||
|
- JWT 认证中间件 (`internal/middleware/auth.go`)
|
||||||
|
- Bearer Token 验证
|
||||||
|
- 用户信息注入到请求上下文
|
||||||
|
- go-zero 框架集成
|
||||||
|
|
||||||
|
#### 3. ✅ 完善照片更新和删除业务逻辑
|
||||||
|
**完成时间**: 2025-01-10
|
||||||
|
- 完整照片更新逻辑 (`updatePhotoLogic.go`)
|
||||||
|
- 完整照片删除逻辑 (`deletePhotoLogic.go`)
|
||||||
|
- 权限验证 (只能操作自己的照片)
|
||||||
|
- 文件系统同步删除
|
||||||
|
|
||||||
|
#### 4. ✅ 完善分类更新和删除业务逻辑
|
||||||
|
**完成时间**: 2025-01-10
|
||||||
|
- 修复所有后端逻辑文件的导入错误
|
||||||
|
- 统一错误处理机制
|
||||||
|
- 修复编译错误
|
||||||
|
|
||||||
|
#### 5. ✅ 前端与后端 API 集成测试
|
||||||
|
**完成时间**: 2025-07-11
|
||||||
|
- 管理后台与后端API联调
|
||||||
|
- 修复数据格式不匹配问题
|
||||||
|
- 数据库初始化完成
|
||||||
|
|
||||||
|
#### 6. ✅ 管理后台类型系统完善
|
||||||
|
**完成时间**: 2025-07-11
|
||||||
|
- 修复所有TypeScript类型错误
|
||||||
|
- 完善用户、分类、照片接口
|
||||||
|
- 统一API响应格式
|
||||||
|
|
||||||
|
#### 7. ✅ 实现照片上传界面
|
||||||
|
**完成时间**: 2025-07-11
|
||||||
|
- 拖拽上传功能
|
||||||
|
- 实时进度显示
|
||||||
|
- 文件预览和管理
|
||||||
|
- 分类和标签选择
|
||||||
|
|
||||||
|
#### 8. ✅ 完善照片管理界面
|
||||||
|
**完成时间**: 2025-07-11
|
||||||
|
- 照片网格和列表视图
|
||||||
|
- 内联编辑和详情查看
|
||||||
|
- 批量操作功能
|
||||||
|
- 搜索和过滤
|
||||||
|
|
||||||
|
#### 9. ✅ 实现分类管理界面完善
|
||||||
|
**完成时间**: 2025-07-11
|
||||||
|
- 树形结构渲染
|
||||||
|
- 创建/编辑分类
|
||||||
|
- 统计仪表板
|
||||||
|
- 搜索和过滤
|
||||||
|
|
||||||
|
### 📋 中优先级任务 (20/26 已完成)
|
||||||
|
|
||||||
|
#### 后端功能完善 (8项)
|
||||||
|
- ✅ 完善用户管理接口 (2025-07-11)
|
||||||
|
- ✅ 实现用户头像上传功能 (2025-07-11)
|
||||||
|
- ✅ 添加数据库种子数据 (2025-07-11)
|
||||||
|
- ✅ 完善数据库迁移脚本 (2025-07-11)
|
||||||
|
- ✅ 实现 CORS 中间件 (2025-07-11)
|
||||||
|
- ✅ 添加 API 接口测试用例 (2025-07-11)
|
||||||
|
- ✅ 实现请求日志中间件 (2025-07-11)
|
||||||
|
- ✅ 完善全局错误处理 (2025-07-11)
|
||||||
|
|
||||||
|
#### 前端展示网站 (6项)
|
||||||
|
- ✅ 创建前端展示网站基础架构 (2025-07-11)
|
||||||
|
- ✅ 实现照片展示页面 (2025-07-11)
|
||||||
|
- ✅ 开发照片搜索和过滤功能 (2025-07-11)
|
||||||
|
- ✅ 实现分类和标签页面 (2025-07-11)
|
||||||
|
- ✅ 连接前端与后端API (2025-07-11)
|
||||||
|
- ✅ 前端响应式设计优化 (2025-07-11)
|
||||||
|
|
||||||
|
#### 部署和运维 (4项)
|
||||||
|
- ✅ 配置生产环境数据库 (2025-07-11)
|
||||||
|
- ✅ 更新CI/CD支持后端部署 (2025-07-11)
|
||||||
|
- ✅ 配置反向代理 (2025-07-11)
|
||||||
|
- ✅ 设置生产环境监控 (2025-07-11)
|
||||||
|
|
||||||
|
#### 测试和文档 (2项)
|
||||||
|
- ✅ 编写API文档 (2025-07-11)
|
||||||
|
- ✅ 编写用户使用文档 (2025-07-11)
|
||||||
|
|
||||||
|
### ⚡ 低优先级任务 (已完成部分)
|
||||||
|
|
||||||
|
#### 容器化和部署扩展
|
||||||
|
- ✅ 后端Docker容器化 (2025-07-11)
|
||||||
|
- ✅ 前端Docker容器化 (2025-07-11)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎯 技术成果总结
|
||||||
|
|
||||||
|
### 后端API
|
||||||
|
- **框架**: go-zero v1.8.0
|
||||||
|
- **功能**: 完整CRUD、JWT认证、文件上传
|
||||||
|
- **测试**: 92个测试用例,覆盖所有API端点
|
||||||
|
- **部署**: Docker容器化,CI/CD自动化
|
||||||
|
|
||||||
|
### 管理后台
|
||||||
|
- **技术栈**: React + TypeScript + Vite
|
||||||
|
- **功能**: 照片管理、分类管理、用户管理
|
||||||
|
- **体验**: 拖拽上传、实时进度、批量操作
|
||||||
|
- **状态**: 生产就绪
|
||||||
|
|
||||||
|
### 前端展示网站
|
||||||
|
- **技术栈**: Next.js + TypeScript
|
||||||
|
- **功能**: 照片展示、搜索过滤、响应式设计
|
||||||
|
- **性能**: 懒加载、无限滚动、CDN优化
|
||||||
|
- **状态**: 功能完成
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📈 每日里程碑
|
||||||
|
|
||||||
|
### 2025-07-11 - 重大里程碑日
|
||||||
|
- **Phase 2 完成**: 管理后台功能全部完成
|
||||||
|
- **Phase 3 启动**: 前端展示网站功能开发
|
||||||
|
- **部署系统**: 完整CI/CD和监控体系建立
|
||||||
|
- **文档完善**: API文档和用户手册完成
|
||||||
|
|
||||||
|
### 2025-01-10 - 核心业务完成
|
||||||
|
- **文件上传**: 完整文件处理系统
|
||||||
|
- **认证系统**: JWT认证中间件
|
||||||
|
- **CRUD功能**: 照片和分类管理完成
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*此文件为历史记录,后续任务见 TASK_PROGRESS.md*
|
||||||
@ -20,49 +20,49 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@radix-ui/react-avatar": "^1.1.10",
|
"@radix-ui/react-avatar": "^1.1.10",
|
||||||
"@radix-ui/react-checkbox": "^1.3.2",
|
"@radix-ui/react-checkbox": "^1.3.2",
|
||||||
"@radix-ui/react-dialog": "^1.0.5",
|
"@radix-ui/react-dialog": "^1.1.14",
|
||||||
"@radix-ui/react-dropdown-menu": "^2.0.6",
|
"@radix-ui/react-dropdown-menu": "^2.1.15",
|
||||||
"@radix-ui/react-label": "^2.0.2",
|
"@radix-ui/react-label": "^2.1.7",
|
||||||
"@radix-ui/react-progress": "^1.1.7",
|
"@radix-ui/react-progress": "^1.1.7",
|
||||||
"@radix-ui/react-select": "^2.0.0",
|
"@radix-ui/react-select": "^2.2.5",
|
||||||
"@radix-ui/react-separator": "^1.1.7",
|
"@radix-ui/react-separator": "^1.1.7",
|
||||||
"@radix-ui/react-slot": "^1.0.2",
|
"@radix-ui/react-slot": "^1.2.3",
|
||||||
"@radix-ui/react-switch": "^1.0.3",
|
"@radix-ui/react-switch": "^1.2.5",
|
||||||
"@radix-ui/react-tabs": "^1.0.4",
|
"@radix-ui/react-tabs": "^1.1.12",
|
||||||
"@radix-ui/react-toast": "^1.1.5",
|
"@radix-ui/react-toast": "^1.2.14",
|
||||||
"@tanstack/react-query": "^5.17.19",
|
"@tanstack/react-query": "^5.83.0",
|
||||||
"@tanstack/react-query-devtools": "^5.17.21",
|
"@tanstack/react-query-devtools": "^5.83.0",
|
||||||
"axios": "^1.6.5",
|
"axios": "^1.10.0",
|
||||||
"class-variance-authority": "^0.7.0",
|
"class-variance-authority": "^0.7.1",
|
||||||
"clsx": "^2.1.0",
|
"clsx": "^2.1.1",
|
||||||
"lucide-react": "^0.312.0",
|
"lucide-react": "^0.312.0",
|
||||||
"react": "^18.2.0",
|
"react": "^18.3.1",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.3.1",
|
||||||
"react-hook-form": "^7.48.2",
|
"react-hook-form": "^7.60.0",
|
||||||
"react-router-dom": "^6.20.1",
|
"react-router-dom": "^6.30.1",
|
||||||
"sonner": "^2.0.6",
|
"sonner": "^2.0.6",
|
||||||
"tailwind-merge": "^2.2.0",
|
"tailwind-merge": "^2.6.0",
|
||||||
"tailwindcss-animate": "^1.0.7",
|
"tailwindcss-animate": "^1.0.7",
|
||||||
"zustand": "^4.4.7"
|
"zustand": "^4.5.7"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/react": "^18.2.43",
|
"@types/react": "^18.3.23",
|
||||||
"@types/react-dom": "^18.2.17",
|
"@types/react-dom": "^18.3.7",
|
||||||
"@typescript-eslint/eslint-plugin": "^6.14.0",
|
"@typescript-eslint/eslint-plugin": "^6.21.0",
|
||||||
"@typescript-eslint/parser": "^6.14.0",
|
"@typescript-eslint/parser": "^6.21.0",
|
||||||
"@vitejs/plugin-react": "^4.2.1",
|
"@vitejs/plugin-react": "^4.6.0",
|
||||||
"autoprefixer": "^10.4.16",
|
"autoprefixer": "^10.4.21",
|
||||||
"eslint": "^8.55.0",
|
"eslint": "^8.57.1",
|
||||||
"eslint-plugin-react-hooks": "^4.6.0",
|
"eslint-plugin-react-hooks": "^4.6.2",
|
||||||
"eslint-plugin-react-refresh": "^0.4.5",
|
"eslint-plugin-react-refresh": "^0.4.20",
|
||||||
"husky": "^8.0.3",
|
"husky": "^8.0.3",
|
||||||
"lint-staged": "^15.2.0",
|
"lint-staged": "^15.5.2",
|
||||||
"postcss": "^8.4.32",
|
"postcss": "^8.5.6",
|
||||||
"prettier": "^3.1.1",
|
"prettier": "^3.6.2",
|
||||||
"prettier-plugin-organize-imports": "^4.1.0",
|
"prettier-plugin-organize-imports": "^4.1.0",
|
||||||
"tailwindcss": "^3.4.0",
|
"tailwindcss": "^3.4.17",
|
||||||
"typescript": "^5.2.2",
|
"typescript": "^5.8.3",
|
||||||
"vite": "^5.0.8"
|
"vite": "^7.0.4"
|
||||||
},
|
},
|
||||||
"lint-staged": {
|
"lint-staged": {
|
||||||
"*.{ts,tsx,js,jsx}": [
|
"*.{ts,tsx,js,jsx}": [
|
||||||
|
|||||||
@ -45,8 +45,8 @@ FROM alpine:3.19
|
|||||||
# 配置镜像源加速
|
# 配置镜像源加速
|
||||||
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
|
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
|
||||||
|
|
||||||
# 安装运行时依赖 (包含SQLite动态库)
|
# 安装运行时依赖 (包含SQLite动态库和wget用于健康检查)
|
||||||
RUN apk add --no-cache ca-certificates tzdata sqlite
|
RUN apk add --no-cache ca-certificates tzdata sqlite wget
|
||||||
|
|
||||||
# 创建非root用户
|
# 创建非root用户
|
||||||
RUN addgroup -g 1001 -S appgroup && \
|
RUN addgroup -g 1001 -S appgroup && \
|
||||||
@ -61,10 +61,12 @@ COPY --from=builder /app/configs /configs
|
|||||||
COPY --from=builder /app/scripts /scripts
|
COPY --from=builder /app/scripts /scripts
|
||||||
COPY --from=builder /app/pkg/migration /pkg/migration
|
COPY --from=builder /app/pkg/migration /pkg/migration
|
||||||
COPY --from=builder /app/etc /etc
|
COPY --from=builder /app/etc /etc
|
||||||
|
COPY --from=builder /app/health-check.sh /usr/local/bin/health-check.sh
|
||||||
|
|
||||||
# 设置目录权限
|
# 设置目录权限和脚本权限
|
||||||
RUN mkdir -p /app && \
|
RUN mkdir -p /app && \
|
||||||
chown -R appuser:appgroup /app
|
chown -R appuser:appgroup /app && \
|
||||||
|
chmod +x /usr/local/bin/health-check.sh
|
||||||
|
|
||||||
# 设置时区
|
# 设置时区
|
||||||
ENV TZ=Asia/Shanghai
|
ENV TZ=Asia/Shanghai
|
||||||
@ -80,7 +82,7 @@ EXPOSE 8080
|
|||||||
|
|
||||||
# 健康检查
|
# 健康检查
|
||||||
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
|
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
|
||||||
CMD ["/usr/local/bin/photography-api", "--health-check"]
|
CMD /usr/local/bin/health-check.sh
|
||||||
|
|
||||||
# 启动应用
|
# 启动应用
|
||||||
ENTRYPOINT ["/usr/local/bin/photography-api"]
|
ENTRYPOINT ["/usr/local/bin/photography-api"]
|
||||||
@ -52,7 +52,7 @@ services:
|
|||||||
- logs_data:/app/logs
|
- logs_data:/app/logs
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: ["CMD", "/photography-api", "--health-check"]
|
test: ["CMD", "/usr/local/bin/health-check.sh"]
|
||||||
interval: 30s
|
interval: 30s
|
||||||
timeout: 10s
|
timeout: 10s
|
||||||
retries: 3
|
retries: 3
|
||||||
|
|||||||
@ -52,7 +52,7 @@ services:
|
|||||||
- logs_data:/app/logs
|
- logs_data:/app/logs
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: ["CMD", "/photography-api", "--health-check"]
|
test: ["CMD", "/usr/local/bin/health-check.sh"]
|
||||||
interval: 30s
|
interval: 30s
|
||||||
timeout: 10s
|
timeout: 10s
|
||||||
retries: 3
|
retries: 3
|
||||||
|
|||||||
12
backend/health-check.sh
Executable file
12
backend/health-check.sh
Executable file
@ -0,0 +1,12 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# 健康检查脚本
|
||||||
|
# 用于Docker健康检查和Kubernetes探针
|
||||||
|
|
||||||
|
# 检查健康检查端点
|
||||||
|
if wget --no-verbose --tries=1 --spider http://localhost:8080/api/v1/health; then
|
||||||
|
echo "Health check passed"
|
||||||
|
exit 0
|
||||||
|
else
|
||||||
|
echo "Health check failed"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
@ -84,6 +84,18 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
|||||||
rest.WithPrefix("/api/v1"),
|
rest.WithPrefix("/api/v1"),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// 额外的根路径健康检查,用于Caddy等反向代理
|
||||||
|
server.AddRoutes(
|
||||||
|
[]rest.Route{
|
||||||
|
{
|
||||||
|
// 根路径健康检查
|
||||||
|
Method: http.MethodGet,
|
||||||
|
Path: "/health",
|
||||||
|
Handler: health.HealthHandler(serverCtx),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
server.AddRoutes(
|
server.AddRoutes(
|
||||||
[]rest.Route{
|
[]rest.Route{
|
||||||
{
|
{
|
||||||
|
|||||||
224
docs/README.md
224
docs/README.md
@ -2,211 +2,53 @@
|
|||||||
|
|
||||||
## 📚 文档结构
|
## 📚 文档结构
|
||||||
|
|
||||||
本项目采用版本化的文档管理策略,按照功能迭代分为不同版本,便于开发和维护。
|
本项目文档采用清晰的模块化结构,便于快速查找和维护。
|
||||||
|
|
||||||
```
|
```
|
||||||
docs/
|
docs/
|
||||||
├── README.md # 文档总览(当前文件)
|
├── README.md # 文档总览(当前文件)
|
||||||
├── v1/ # v1.0 版本文档
|
├── guides/ # 📖 用户指南
|
||||||
│ ├── admin/ # 管理后台相关
|
├── technical/ # 🔧 技术文档
|
||||||
│ ├── backend/ # 后端架构相关
|
├── operations/ # 🚀 运维部署
|
||||||
│ ├── database/ # 数据库设计相关
|
└── api/ # 📡 API文档
|
||||||
│ ├── api/ # API接口相关
|
|
||||||
│ └── README.md # v1版本说明
|
|
||||||
├── v2/ # v2.0 版本文档(规划中)
|
|
||||||
│ ├── admin/ # 管理后台升级
|
|
||||||
│ ├── backend/ # 后端微服务化
|
|
||||||
│ ├── database/ # 数据库优化
|
|
||||||
│ ├── api/ # GraphQL接口
|
|
||||||
│ └── README.md # v2版本说明
|
|
||||||
├── 原始 prd/ # 原始需求文档
|
|
||||||
│ ├── UI设计需求文档.md
|
|
||||||
│ ├── 前端开发文档.md
|
|
||||||
│ ├── 后端开发文档.md
|
|
||||||
│ └── 测试需求文档.md
|
|
||||||
└── [传统目录结构] # 保留现有结构
|
|
||||||
├── design/ # 设计文档
|
|
||||||
├── api/ # API文档
|
|
||||||
├── user-guide/ # 用户指南
|
|
||||||
├── development/ # 开发文档
|
|
||||||
└── deployment/ # 部署文档
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## 🚀 版本规划
|
## 🎯 快速导航
|
||||||
|
|
||||||
### v1.0 - 核心功能版本 (当前开发)
|
### 👥 普通用户
|
||||||
|
- [用户指南](./guides/) - 网站使用教程
|
||||||
|
|
||||||
**目标**: 实现完整的摄影作品集网站核心功能
|
### 💻 开发者
|
||||||
|
- [技术文档](./technical/) - 架构设计和开发指南
|
||||||
|
- [API文档](./api/) - 接口说明和示例
|
||||||
|
|
||||||
#### 📋 功能范围
|
### 🛠️ 运维人员
|
||||||
- ✅ **前端展示**: Next.js 15 + React 19 静态网站
|
- [运维部署](./operations/) - 部署配置和运维指南
|
||||||
- 🔄 **管理后台**: React + TypeScript 管理界面
|
|
||||||
- 🔄 **后端API**: Golang + Gin + PostgreSQL
|
|
||||||
- 🔄 **图片处理**: 多格式转换和优化
|
|
||||||
- 🔄 **用户管理**: JWT认证和权限控制
|
|
||||||
- 🔄 **文件存储**: MinIO/S3 对象存储
|
|
||||||
|
|
||||||
#### 📖 v1.0 文档
|
## 📁 目录说明
|
||||||
- [管理后台开发文档](./v1/admin/管理后台开发文档.md)
|
|
||||||
- [Golang项目架构文档](./v1/backend/Golang项目架构文档.md)
|
|
||||||
- [数据库设计文档](./v1/database/数据库设计文档.md)
|
|
||||||
- [API接口设计文档](./v1/api/API接口设计文档.md)
|
|
||||||
|
|
||||||
#### 🛠️ 技术栈
|
| 目录 | 用途 | 目标用户 |
|
||||||
```yaml
|
|---|---|---|
|
||||||
前端:
|
| `guides/` | 使用教程和帮助文档 | 所有用户 |
|
||||||
- Next.js 15 + React 19
|
| `technical/` | 技术架构和开发文档 | 开发者 |
|
||||||
- TypeScript + Tailwind CSS
|
| `operations/` | 部署配置和运维文档 | 运维人员 |
|
||||||
- TanStack Query + Zustand
|
| `api/` | API接口文档 | 前后端开发者 |
|
||||||
|
|
||||||
后端:
|
## 🚀 快速开始
|
||||||
- Golang + Gin Framework
|
|
||||||
- GORM + PostgreSQL
|
|
||||||
- Redis + MinIO/S3
|
|
||||||
|
|
||||||
部署:
|
### 新用户入门
|
||||||
- Docker + Docker Compose
|
1. 查看 [用户指南](./guides/) 了解网站功能
|
||||||
- Caddy Web Server
|
2. 阅读 [技术文档](./technical/) 了解项目架构
|
||||||
- Gitea Actions CI/CD
|
3. 参考 [运维部署](./operations/) 进行环境搭建
|
||||||
```
|
|
||||||
|
|
||||||
### v2.0 - 高级功能版本 (规划中)
|
### 开发者工作流
|
||||||
|
1. **前端开发**: 查看技术文档中的前端部分
|
||||||
|
2. **后端开发**: 查看技术文档中的后端部分
|
||||||
|
3. **API对接**: 查看api目录下的接口文档
|
||||||
|
4. **部署上线**: 参考运维部署文档
|
||||||
|
|
||||||
**目标**: 扩展高级功能,优化性能和用户体验
|
## 📞 技术支持
|
||||||
|
|
||||||
#### 🎯 规划功能
|
- **项目地址**: https://photography.iriver.top
|
||||||
- 🔮 **AI增强**: 自动标签、智能分类、内容推荐
|
|
||||||
- 🔮 **社交功能**: 评论系统、点赞收藏、用户互动
|
|
||||||
- 🔮 **高级搜索**: ElasticSearch全文搜索、地理位置搜索
|
|
||||||
- 🔮 **性能优化**: CDN加速、图片懒加载、缓存优化
|
|
||||||
- 🔮 **移动端**: PWA支持、移动端优化
|
|
||||||
- 🔮 **多语言**: 国际化支持、多语言切换
|
|
||||||
|
|
||||||
#### 🏗️ 架构升级
|
|
||||||
- **微服务化**: 服务拆分,独立部署
|
|
||||||
- **GraphQL**: 统一数据查询接口
|
|
||||||
- **消息队列**: RabbitMQ/Redis Streams
|
|
||||||
- **监控体系**: Prometheus + Grafana
|
|
||||||
- **日志中心**: ELK Stack
|
|
||||||
|
|
||||||
## 📝 文档使用指南
|
|
||||||
|
|
||||||
### 开发者快速开始
|
|
||||||
|
|
||||||
1. **前端开发者**
|
|
||||||
```bash
|
|
||||||
# 阅读前端相关文档
|
|
||||||
cd docs/原始\ prd/
|
|
||||||
# 查看 前端开发文档.md 和 UI设计需求文档.md
|
|
||||||
```
|
|
||||||
|
|
||||||
2. **后端开发者**
|
|
||||||
```bash
|
|
||||||
# 阅读v1版本后端文档
|
|
||||||
cd docs/v1/
|
|
||||||
# 依次阅读:
|
|
||||||
# - backend/Golang项目架构文档.md
|
|
||||||
# - database/数据库设计文档.md
|
|
||||||
# - api/API接口设计文档.md
|
|
||||||
```
|
|
||||||
|
|
||||||
3. **全栈开发者**
|
|
||||||
```bash
|
|
||||||
# 完整了解项目
|
|
||||||
# 1. 先看原始需求: docs/原始\ prd/
|
|
||||||
# 2. 再看具体实现: docs/v1/
|
|
||||||
# 3. 了解未来规划: docs/v2/README.md
|
|
||||||
```
|
|
||||||
|
|
||||||
### 管理员和产品经理
|
|
||||||
|
|
||||||
1. **项目概览**: 从 `docs/README.md` (本文件) 开始
|
|
||||||
2. **功能规划**: 查看各版本的 README.md 了解功能范围
|
|
||||||
3. **进度跟踪**: 根据文档中的状态标识了解开发进度
|
|
||||||
|
|
||||||
## 🎯 当前开发状态
|
|
||||||
|
|
||||||
### v1.0 开发进度
|
|
||||||
|
|
||||||
| 模块 | 状态 | 完成度 | 负责人 | 备注 |
|
|
||||||
|------|------|---------|--------|------|
|
|
||||||
| 前端展示 | ✅ 已完成 | 100% | - | Next.js静态网站 |
|
|
||||||
| 管理后台 | 📋 设计中 | 20% | - | React管理界面 |
|
|
||||||
| 后端API | 📋 设计中 | 15% | - | Golang架构设计 |
|
|
||||||
| 数据库 | 📋 设计中 | 30% | - | PostgreSQL表设计 |
|
|
||||||
| 图片处理 | ⏳ 待开发 | 0% | - | 多格式转换 |
|
|
||||||
| 用户认证 | ⏳ 待开发 | 0% | - | JWT + 权限 |
|
|
||||||
| 文件存储 | ⏳ 待开发 | 0% | - | MinIO/S3集成 |
|
|
||||||
| 部署配置 | ⏳ 待开发 | 0% | - | Docker + CI/CD |
|
|
||||||
|
|
||||||
### 下一步计划
|
|
||||||
|
|
||||||
#### 近期计划 (1-2周)
|
|
||||||
1. **完成管理后台前端开发**
|
|
||||||
- React + TypeScript 管理界面
|
|
||||||
- 照片上传和管理功能
|
|
||||||
- 分类标签管理
|
|
||||||
|
|
||||||
2. **开始后端核心开发**
|
|
||||||
- Golang项目框架搭建
|
|
||||||
- 数据库表创建和迁移
|
|
||||||
- 基础API接口实现
|
|
||||||
|
|
||||||
#### 中期计划 (1个月)
|
|
||||||
1. **完善后端功能**
|
|
||||||
- 用户认证和权限系统
|
|
||||||
- 图片处理和存储
|
|
||||||
- 完整的CRUD操作
|
|
||||||
|
|
||||||
2. **前后端联调**
|
|
||||||
- API接口对接
|
|
||||||
- 数据流测试
|
|
||||||
- 功能完整性验证
|
|
||||||
|
|
||||||
#### 长期计划 (2-3个月)
|
|
||||||
1. **系统优化**
|
|
||||||
- 性能优化和缓存
|
|
||||||
- 安全性加固
|
|
||||||
- 错误处理完善
|
|
||||||
|
|
||||||
2. **部署上线**
|
|
||||||
- 生产环境配置
|
|
||||||
- CI/CD流程
|
|
||||||
- 监控和日志
|
|
||||||
|
|
||||||
## 📞 联系方式
|
|
||||||
|
|
||||||
### 项目维护者
|
|
||||||
- **项目负责人**: [待填写]
|
|
||||||
- **技术负责人**: [待填写]
|
|
||||||
- **文档维护**: Claude Code Assistant
|
- **文档维护**: Claude Code Assistant
|
||||||
|
- **最后更新**: 2024-12-21
|
||||||
### 沟通渠道
|
|
||||||
- **技术讨论**: [GitHub Issues/Discussions]
|
|
||||||
- **进度同步**: [项目管理工具链接]
|
|
||||||
- **紧急联系**: [联系方式]
|
|
||||||
|
|
||||||
## 📋 文档维护
|
|
||||||
|
|
||||||
### 更新频率
|
|
||||||
- **设计文档**: 功能变更时及时更新
|
|
||||||
- **API文档**: 接口变更时同步更新
|
|
||||||
- **架构文档**: 重大架构调整时更新
|
|
||||||
- **状态跟踪**: 每周更新开发进度
|
|
||||||
|
|
||||||
### 贡献指南
|
|
||||||
1. 所有文档使用 Markdown 格式
|
|
||||||
2. 图片和图表存放在对应的 `assets/` 目录
|
|
||||||
3. 重大更新需要更新对应的 README.md
|
|
||||||
4. 保持文档结构清晰,便于检索
|
|
||||||
|
|
||||||
### 版本控制
|
|
||||||
- 文档跟随代码版本管理
|
|
||||||
- 重大版本升级创建新的版本目录
|
|
||||||
- 保留历史版本文档,便于回溯
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
📅 **最后更新**: 2024-01-15
|
|
||||||
📝 **文档版本**: v1.0
|
|
||||||
👨💻 **维护者**: Claude Code Assistant
|
|
||||||
@ -1,212 +0,0 @@
|
|||||||
# 使用现有服务的部署指南
|
|
||||||
|
|
||||||
本指南适用于已有 PostgreSQL 和 Redis 服务的情况。
|
|
||||||
|
|
||||||
## 📋 前提条件
|
|
||||||
|
|
||||||
确保你的服务器上已经安装并运行:
|
|
||||||
- **PostgreSQL** (推荐版本 14+)
|
|
||||||
- **Redis** (推荐版本 6+)
|
|
||||||
|
|
||||||
## ⚙️ 配置步骤
|
|
||||||
|
|
||||||
### 1. 环境变量配置
|
|
||||||
|
|
||||||
复制环境变量模板:
|
|
||||||
```bash
|
|
||||||
cp .env.example .env
|
|
||||||
```
|
|
||||||
|
|
||||||
编辑 `.env` 文件,配置你的现有服务:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 数据库配置
|
|
||||||
DB_HOST=localhost # 或你的 PostgreSQL 服务器地址
|
|
||||||
DB_PORT=5432 # PostgreSQL 端口
|
|
||||||
DB_NAME=photography # 数据库名称
|
|
||||||
DB_USER=postgres # 数据库用户
|
|
||||||
DB_PASSWORD=your_actual_password # 数据库密码
|
|
||||||
|
|
||||||
# Redis 配置
|
|
||||||
REDIS_HOST=localhost # 或你的 Redis 服务器地址
|
|
||||||
REDIS_PORT=6379 # Redis 端口
|
|
||||||
REDIS_PASSWORD=your_redis_password # Redis 密码 (如果有)
|
|
||||||
|
|
||||||
# JWT 配置
|
|
||||||
JWT_SECRET=your_jwt_secret_at_least_32_characters_long
|
|
||||||
JWT_EXPIRES_IN=24h
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. 数据库准备
|
|
||||||
|
|
||||||
连接到你的 PostgreSQL,创建数据库:
|
|
||||||
|
|
||||||
```sql
|
|
||||||
-- 创建数据库
|
|
||||||
CREATE DATABASE photography;
|
|
||||||
|
|
||||||
-- 创建用户 (如果需要)
|
|
||||||
CREATE USER photography_user WITH ENCRYPTED PASSWORD 'your_password';
|
|
||||||
GRANT ALL PRIVILEGES ON DATABASE photography TO photography_user;
|
|
||||||
|
|
||||||
-- 使用数据库
|
|
||||||
\c photography;
|
|
||||||
|
|
||||||
-- 创建必要的扩展
|
|
||||||
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
|
|
||||||
CREATE EXTENSION IF NOT EXISTS "pg_trgm";
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. 后端服务部署
|
|
||||||
|
|
||||||
#### 方式一:Docker 部署 (推荐)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 构建并启动后端服务
|
|
||||||
docker-compose up -d backend
|
|
||||||
|
|
||||||
# 查看日志
|
|
||||||
docker-compose logs -f backend
|
|
||||||
|
|
||||||
# 检查健康状态
|
|
||||||
curl http://localhost:8080/health
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 方式二:直接运行
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 进入后端目录
|
|
||||||
cd backend
|
|
||||||
|
|
||||||
# 安装依赖
|
|
||||||
go mod download
|
|
||||||
|
|
||||||
# 运行数据库迁移
|
|
||||||
go run cmd/server/main.go migrate
|
|
||||||
|
|
||||||
# 启动服务
|
|
||||||
go run cmd/server/main.go
|
|
||||||
```
|
|
||||||
|
|
||||||
### 4. 数据库迁移
|
|
||||||
|
|
||||||
如果你的后端支持自动迁移,服务启动时会自动创建表结构。
|
|
||||||
|
|
||||||
如果需要手动迁移:
|
|
||||||
```bash
|
|
||||||
# 使用 Docker
|
|
||||||
docker-compose exec backend ./main migrate
|
|
||||||
|
|
||||||
# 或者直接运行
|
|
||||||
cd backend && go run cmd/server/main.go migrate
|
|
||||||
```
|
|
||||||
|
|
||||||
### 5. 验证部署
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 检查后端健康状态
|
|
||||||
curl http://localhost:8080/health
|
|
||||||
|
|
||||||
# 检查数据库连接
|
|
||||||
curl http://localhost:8080/api/v1/health
|
|
||||||
|
|
||||||
# 检查 Redis 连接 (如果有相关接口)
|
|
||||||
curl http://localhost:8080/api/v1/cache/health
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🔧 常见问题
|
|
||||||
|
|
||||||
### 数据库连接失败
|
|
||||||
|
|
||||||
1. **检查数据库是否运行**:
|
|
||||||
```bash
|
|
||||||
sudo systemctl status postgresql
|
|
||||||
```
|
|
||||||
|
|
||||||
2. **检查连接权限**:
|
|
||||||
```bash
|
|
||||||
psql -h localhost -U postgres -d photography
|
|
||||||
```
|
|
||||||
|
|
||||||
3. **检查防火墙**:
|
|
||||||
```bash
|
|
||||||
sudo ufw status
|
|
||||||
```
|
|
||||||
|
|
||||||
### Redis 连接失败
|
|
||||||
|
|
||||||
1. **检查 Redis 状态**:
|
|
||||||
```bash
|
|
||||||
sudo systemctl status redis
|
|
||||||
```
|
|
||||||
|
|
||||||
2. **测试 Redis 连接**:
|
|
||||||
```bash
|
|
||||||
redis-cli ping
|
|
||||||
```
|
|
||||||
|
|
||||||
### 容器网络问题
|
|
||||||
|
|
||||||
如果容器无法访问宿主机服务,尝试:
|
|
||||||
|
|
||||||
1. **使用 host 网络模式** (已配置)
|
|
||||||
2. **检查服务绑定地址**:
|
|
||||||
- PostgreSQL: 确保监听 `0.0.0.0:5432` 或 `localhost:5432`
|
|
||||||
- Redis: 确保监听 `0.0.0.0:6379` 或 `localhost:6379`
|
|
||||||
|
|
||||||
## 📊 监控和维护
|
|
||||||
|
|
||||||
### 日志查看
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 后端日志
|
|
||||||
docker-compose logs -f backend
|
|
||||||
|
|
||||||
# 系统日志
|
|
||||||
journalctl -u your-service-name -f
|
|
||||||
```
|
|
||||||
|
|
||||||
### 性能监控
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 运行监控脚本
|
|
||||||
./scripts/monitor.sh
|
|
||||||
|
|
||||||
# 手动检查资源使用
|
|
||||||
docker stats photography_backend
|
|
||||||
```
|
|
||||||
|
|
||||||
### 备份
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 手动备份数据库
|
|
||||||
./scripts/backup.sh
|
|
||||||
|
|
||||||
# 或者使用 Docker 备份服务
|
|
||||||
docker-compose --profile backup up backup
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🚀 自动化部署
|
|
||||||
|
|
||||||
如果你使用 CI/CD,确保在部署环境中设置正确的环境变量:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
# .github/workflows 或 .gitea/workflows
|
|
||||||
env:
|
|
||||||
DB_HOST: your-db-host
|
|
||||||
DB_PASSWORD: ${{ secrets.DB_PASSWORD }}
|
|
||||||
REDIS_HOST: your-redis-host
|
|
||||||
REDIS_PASSWORD: ${{ secrets.REDIS_PASSWORD }}
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🔒 安全建议
|
|
||||||
|
|
||||||
1. **使用强密码**
|
|
||||||
2. **限制数据库访问**:只允许必要的 IP 连接
|
|
||||||
3. **启用 SSL/TLS**:用于数据库和 Redis 连接
|
|
||||||
4. **定期更新**:保持服务和依赖的最新版本
|
|
||||||
5. **监控日志**:定期检查异常访问
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
这种配置更加轻量和实用,避免了重复安装已有服务的资源浪费。
|
|
||||||
@ -1,760 +0,0 @@
|
|||||||
# 摄影作品集项目部署文档
|
|
||||||
|
|
||||||
本文档详细说明了摄影作品集项目的完整部署流程,包括前端、管理后台、后端 API 和数据库的部署配置。
|
|
||||||
|
|
||||||
## 📋 目录
|
|
||||||
|
|
||||||
- [系统要求](#系统要求)
|
|
||||||
- [环境配置](#环境配置)
|
|
||||||
- [后端部署](#后端部署)
|
|
||||||
- [前端部署](#前端部署)
|
|
||||||
- [管理后台部署](#管理后台部署)
|
|
||||||
- [数据库配置](#数据库配置)
|
|
||||||
- [Web 服务器配置](#web-服务器配置)
|
|
||||||
- [SSL 证书配置](#ssl-证书配置)
|
|
||||||
- [监控和备份](#监控和备份)
|
|
||||||
- [故障排除](#故障排除)
|
|
||||||
|
|
||||||
## 🖥️ 系统要求
|
|
||||||
|
|
||||||
### 硬件要求
|
|
||||||
- **CPU**: 2 核心以上
|
|
||||||
- **内存**: 4GB 以上 (推荐 8GB)
|
|
||||||
- **存储**: 20GB 以上 SSD 存储
|
|
||||||
- **网络**: 稳定的互联网连接
|
|
||||||
|
|
||||||
### 软件要求
|
|
||||||
- **操作系统**: Ubuntu 20.04 LTS / CentOS 8 / Debian 11
|
|
||||||
- **Docker**: 20.10 或更高版本
|
|
||||||
- **Docker Compose**: 2.0 或更高版本
|
|
||||||
- **Git**: 2.20 或更高版本
|
|
||||||
- **域名**: 用于生产环境部署
|
|
||||||
|
|
||||||
## ⚙️ 环境配置
|
|
||||||
|
|
||||||
### 1. 安装 Docker 和 Docker Compose
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Ubuntu/Debian
|
|
||||||
curl -fsSL https://get.docker.com -o get-docker.sh
|
|
||||||
sudo sh get-docker.sh
|
|
||||||
sudo usermod -aG docker $USER
|
|
||||||
|
|
||||||
# 安装 Docker Compose
|
|
||||||
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
|
|
||||||
sudo chmod +x /usr/local/bin/docker-compose
|
|
||||||
|
|
||||||
# 验证安装
|
|
||||||
docker --version
|
|
||||||
docker-compose --version
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. 克隆项目仓库
|
|
||||||
|
|
||||||
```bash
|
|
||||||
git clone <repository-url> photography
|
|
||||||
cd photography
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. 创建环境变量文件
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 复制环境变量模板
|
|
||||||
cp .env.example .env
|
|
||||||
|
|
||||||
# 编辑环境变量
|
|
||||||
nano .env
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🚀 后端部署
|
|
||||||
|
|
||||||
### 1. 后端 Docker 配置
|
|
||||||
|
|
||||||
查看后端 Dockerfile:
|
|
||||||
|
|
||||||
```dockerfile
|
|
||||||
# backend/Dockerfile
|
|
||||||
FROM golang:1.21-alpine AS builder
|
|
||||||
|
|
||||||
# 设置工作目录
|
|
||||||
WORKDIR /app
|
|
||||||
|
|
||||||
# 安装依赖
|
|
||||||
RUN apk add --no-cache git ca-certificates tzdata
|
|
||||||
|
|
||||||
# 复制 go mod 文件
|
|
||||||
COPY go.mod go.sum ./
|
|
||||||
RUN go mod download
|
|
||||||
|
|
||||||
# 复制源代码
|
|
||||||
COPY . .
|
|
||||||
|
|
||||||
# 构建应用
|
|
||||||
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main cmd/server/main.go
|
|
||||||
|
|
||||||
# 生产环境镜像
|
|
||||||
FROM alpine:latest
|
|
||||||
|
|
||||||
# 安装必要的包
|
|
||||||
RUN apk --no-cache add ca-certificates wget
|
|
||||||
|
|
||||||
# 创建用户
|
|
||||||
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
|
|
||||||
|
|
||||||
# 设置工作目录
|
|
||||||
WORKDIR /app
|
|
||||||
|
|
||||||
# 从构建阶段复制文件
|
|
||||||
COPY --from=builder /app/main .
|
|
||||||
COPY --from=builder /app/configs ./configs
|
|
||||||
COPY --from=builder /app/migrations ./migrations
|
|
||||||
|
|
||||||
# 创建必要的目录
|
|
||||||
RUN mkdir -p uploads logs && chown -R appuser:appgroup /app
|
|
||||||
|
|
||||||
# 切换到非 root 用户
|
|
||||||
USER appuser
|
|
||||||
|
|
||||||
# 暴露端口
|
|
||||||
EXPOSE 8080
|
|
||||||
|
|
||||||
# 健康检查
|
|
||||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
|
|
||||||
CMD wget --no-verbose --tries=1 --spider http://localhost:8080/health || exit 1
|
|
||||||
|
|
||||||
# 启动命令
|
|
||||||
CMD ["./main"]
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. 后端 Docker Compose 服务
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
# docker-compose.yml - 后端部分
|
|
||||||
services:
|
|
||||||
# PostgreSQL 数据库
|
|
||||||
postgres:
|
|
||||||
image: postgres:15-alpine
|
|
||||||
container_name: photography_postgres
|
|
||||||
restart: unless-stopped
|
|
||||||
environment:
|
|
||||||
POSTGRES_DB: ${DB_NAME:-photography}
|
|
||||||
POSTGRES_USER: ${DB_USER:-postgres}
|
|
||||||
POSTGRES_PASSWORD: ${DB_PASSWORD}
|
|
||||||
POSTGRES_INITDB_ARGS: "--encoding=UTF8 --locale=C"
|
|
||||||
volumes:
|
|
||||||
- postgres_data:/var/lib/postgresql/data
|
|
||||||
- ./backend/migrations:/docker-entrypoint-initdb.d
|
|
||||||
ports:
|
|
||||||
- "127.0.0.1:5432:5432"
|
|
||||||
networks:
|
|
||||||
- photography_network
|
|
||||||
healthcheck:
|
|
||||||
test: ["CMD-SHELL", "pg_isready -U ${DB_USER:-postgres} -d ${DB_NAME:-photography}"]
|
|
||||||
interval: 30s
|
|
||||||
timeout: 10s
|
|
||||||
retries: 5
|
|
||||||
|
|
||||||
# Redis 缓存
|
|
||||||
redis:
|
|
||||||
image: redis:7-alpine
|
|
||||||
container_name: photography_redis
|
|
||||||
restart: unless-stopped
|
|
||||||
command: redis-server --appendonly yes --requirepass ${REDIS_PASSWORD}
|
|
||||||
volumes:
|
|
||||||
- redis_data:/data
|
|
||||||
ports:
|
|
||||||
- "127.0.0.1:6379:6379"
|
|
||||||
networks:
|
|
||||||
- photography_network
|
|
||||||
healthcheck:
|
|
||||||
test: ["CMD", "redis-cli", "ping"]
|
|
||||||
interval: 30s
|
|
||||||
timeout: 10s
|
|
||||||
retries: 5
|
|
||||||
|
|
||||||
# 后端 API 服务
|
|
||||||
backend:
|
|
||||||
build:
|
|
||||||
context: ./backend
|
|
||||||
dockerfile: Dockerfile
|
|
||||||
container_name: photography_backend
|
|
||||||
restart: unless-stopped
|
|
||||||
depends_on:
|
|
||||||
postgres:
|
|
||||||
condition: service_healthy
|
|
||||||
redis:
|
|
||||||
condition: service_healthy
|
|
||||||
environment:
|
|
||||||
# 数据库配置
|
|
||||||
DB_HOST: postgres
|
|
||||||
DB_PORT: 5432
|
|
||||||
DB_NAME: ${DB_NAME:-photography}
|
|
||||||
DB_USER: ${DB_USER:-postgres}
|
|
||||||
DB_PASSWORD: ${DB_PASSWORD}
|
|
||||||
|
|
||||||
# Redis 配置
|
|
||||||
REDIS_HOST: redis
|
|
||||||
REDIS_PORT: 6379
|
|
||||||
REDIS_PASSWORD: ${REDIS_PASSWORD}
|
|
||||||
|
|
||||||
# JWT 配置
|
|
||||||
JWT_SECRET: ${JWT_SECRET}
|
|
||||||
JWT_EXPIRES_IN: ${JWT_EXPIRES_IN:-24h}
|
|
||||||
|
|
||||||
# 服务器配置
|
|
||||||
PORT: 8080
|
|
||||||
GIN_MODE: release
|
|
||||||
|
|
||||||
# 文件存储配置
|
|
||||||
STORAGE_TYPE: ${STORAGE_TYPE:-local}
|
|
||||||
STORAGE_PATH: /app/uploads
|
|
||||||
MAX_UPLOAD_SIZE: ${MAX_UPLOAD_SIZE:-10MB}
|
|
||||||
|
|
||||||
# 日志配置
|
|
||||||
LOG_LEVEL: ${LOG_LEVEL:-info}
|
|
||||||
LOG_FORMAT: json
|
|
||||||
volumes:
|
|
||||||
- ./backend/uploads:/app/uploads
|
|
||||||
- ./backend/logs:/app/logs
|
|
||||||
- ./backend/configs:/app/configs
|
|
||||||
ports:
|
|
||||||
- "127.0.0.1:8080:8080"
|
|
||||||
networks:
|
|
||||||
- photography_network
|
|
||||||
healthcheck:
|
|
||||||
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:8080/health"]
|
|
||||||
interval: 30s
|
|
||||||
timeout: 10s
|
|
||||||
retries: 5
|
|
||||||
start_period: 60s
|
|
||||||
|
|
||||||
volumes:
|
|
||||||
postgres_data:
|
|
||||||
driver: local
|
|
||||||
redis_data:
|
|
||||||
driver: local
|
|
||||||
|
|
||||||
networks:
|
|
||||||
photography_network:
|
|
||||||
driver: bridge
|
|
||||||
ipam:
|
|
||||||
config:
|
|
||||||
- subnet: 172.20.0.0/16
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. 启动后端服务
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 构建并启动后端服务
|
|
||||||
docker-compose up -d postgres redis
|
|
||||||
docker-compose up -d backend
|
|
||||||
|
|
||||||
# 查看日志
|
|
||||||
docker-compose logs -f backend
|
|
||||||
|
|
||||||
# 验证服务状态
|
|
||||||
curl http://localhost:8080/health
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🌐 前端部署
|
|
||||||
|
|
||||||
### 1. 前端构建配置
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 进入前端目录
|
|
||||||
cd frontend/
|
|
||||||
|
|
||||||
# 安装依赖
|
|
||||||
bun install
|
|
||||||
|
|
||||||
# 构建生产版本
|
|
||||||
bun run build
|
|
||||||
|
|
||||||
# 验证构建结果
|
|
||||||
ls -la out/
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. 前端部署脚本
|
|
||||||
|
|
||||||
创建前端部署脚本:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
#!/bin/bash
|
|
||||||
# scripts/deploy-frontend.sh
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
echo "🚀 开始部署前端..."
|
|
||||||
|
|
||||||
# 配置变量
|
|
||||||
FRONTEND_DIR="/home/gitea/www/photography"
|
|
||||||
BACKUP_DIR="/home/gitea/backups/photography-frontend"
|
|
||||||
BUILD_DIR="./frontend/out"
|
|
||||||
|
|
||||||
# 创建备份
|
|
||||||
echo "📦 创建当前版本备份..."
|
|
||||||
mkdir -p "$BACKUP_DIR"
|
|
||||||
if [ -d "$FRONTEND_DIR" ]; then
|
|
||||||
tar -czf "$BACKUP_DIR/frontend-$(date +%Y%m%d-%H%M%S).tar.gz" -C "$FRONTEND_DIR" .
|
|
||||||
fi
|
|
||||||
|
|
||||||
# 创建部署目录
|
|
||||||
echo "📁 准备部署目录..."
|
|
||||||
mkdir -p "$FRONTEND_DIR"
|
|
||||||
|
|
||||||
# 部署新版本
|
|
||||||
echo "🔄 部署新版本..."
|
|
||||||
rsync -av --delete "$BUILD_DIR/" "$FRONTEND_DIR/"
|
|
||||||
|
|
||||||
# 设置权限
|
|
||||||
echo "🔐 设置文件权限..."
|
|
||||||
chown -R gitea:gitea "$FRONTEND_DIR"
|
|
||||||
chmod -R 755 "$FRONTEND_DIR"
|
|
||||||
|
|
||||||
# 清理旧备份 (保留最近5个)
|
|
||||||
echo "🧹 清理旧备份..."
|
|
||||||
cd "$BACKUP_DIR"
|
|
||||||
ls -t frontend-*.tar.gz | tail -n +6 | xargs -r rm
|
|
||||||
|
|
||||||
echo "✅ 前端部署完成!"
|
|
||||||
echo "🌐 访问地址: https://photography.iriver.top"
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🛠️ 管理后台部署
|
|
||||||
|
|
||||||
### 1. 管理后台构建配置
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 进入管理后台目录
|
|
||||||
cd admin/
|
|
||||||
|
|
||||||
# 安装依赖
|
|
||||||
npm install
|
|
||||||
|
|
||||||
# 构建生产版本
|
|
||||||
npm run build
|
|
||||||
|
|
||||||
# 验证构建结果
|
|
||||||
ls -la dist/
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. 管理后台部署脚本
|
|
||||||
|
|
||||||
```bash
|
|
||||||
#!/bin/bash
|
|
||||||
# scripts/deploy-admin.sh
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
echo "🚀 开始部署管理后台..."
|
|
||||||
|
|
||||||
# 配置变量
|
|
||||||
ADMIN_DIR="/home/gitea/www/photography-admin"
|
|
||||||
BACKUP_DIR="/home/gitea/backups/photography-admin"
|
|
||||||
BUILD_DIR="./admin/dist"
|
|
||||||
|
|
||||||
# 创建备份
|
|
||||||
echo "📦 创建当前版本备份..."
|
|
||||||
mkdir -p "$BACKUP_DIR"
|
|
||||||
if [ -d "$ADMIN_DIR" ]; then
|
|
||||||
tar -czf "$BACKUP_DIR/admin-$(date +%Y%m%d-%H%M%S).tar.gz" -C "$ADMIN_DIR" .
|
|
||||||
fi
|
|
||||||
|
|
||||||
# 创建部署目录
|
|
||||||
echo "📁 准备部署目录..."
|
|
||||||
mkdir -p "$ADMIN_DIR"
|
|
||||||
|
|
||||||
# 部署新版本
|
|
||||||
echo "🔄 部署新版本..."
|
|
||||||
rsync -av --delete "$BUILD_DIR/" "$ADMIN_DIR/"
|
|
||||||
|
|
||||||
# 设置权限
|
|
||||||
echo "🔐 设置文件权限..."
|
|
||||||
chown -R gitea:gitea "$ADMIN_DIR"
|
|
||||||
chmod -R 755 "$ADMIN_DIR"
|
|
||||||
|
|
||||||
# 清理旧备份 (保留最近5个)
|
|
||||||
echo "🧹 清理旧备份..."
|
|
||||||
cd "$BACKUP_DIR"
|
|
||||||
ls -t admin-*.tar.gz | tail -n +6 | xargs -r rm
|
|
||||||
|
|
||||||
echo "✅ 管理后台部署完成!"
|
|
||||||
echo "🌐 访问地址: https://admin.photography.iriver.top"
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🗄️ 数据库配置
|
|
||||||
|
|
||||||
### 1. 数据库初始化
|
|
||||||
|
|
||||||
```sql
|
|
||||||
-- 创建数据库
|
|
||||||
CREATE DATABASE photography;
|
|
||||||
CREATE USER photography_user WITH ENCRYPTED PASSWORD 'your_password';
|
|
||||||
GRANT ALL PRIVILEGES ON DATABASE photography TO photography_user;
|
|
||||||
|
|
||||||
-- 使用数据库
|
|
||||||
\c photography;
|
|
||||||
|
|
||||||
-- 创建必要的扩展
|
|
||||||
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
|
|
||||||
CREATE EXTENSION IF NOT EXISTS "pg_trgm";
|
|
||||||
|
|
||||||
-- 设置时区
|
|
||||||
SET timezone = 'Asia/Shanghai';
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. 数据库备份脚本
|
|
||||||
|
|
||||||
```bash
|
|
||||||
#!/bin/bash
|
|
||||||
# scripts/backup.sh
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
# 配置变量
|
|
||||||
DB_HOST="${DB_HOST:-postgres}"
|
|
||||||
DB_NAME="${DB_NAME:-photography}"
|
|
||||||
DB_USER="${DB_USER:-postgres}"
|
|
||||||
BACKUP_DIR="/backups"
|
|
||||||
DATE=$(date +%Y%m%d-%H%M%S)
|
|
||||||
|
|
||||||
echo "🗄️ 开始数据库备份..."
|
|
||||||
|
|
||||||
# 创建备份目录
|
|
||||||
mkdir -p "$BACKUP_DIR"
|
|
||||||
|
|
||||||
# 执行备份
|
|
||||||
pg_dump -h "$DB_HOST" -U "$DB_USER" -d "$DB_NAME" \
|
|
||||||
--no-password --verbose --clean --no-acl --no-owner \
|
|
||||||
-f "$BACKUP_DIR/photography-$DATE.sql"
|
|
||||||
|
|
||||||
# 压缩备份文件
|
|
||||||
gzip "$BACKUP_DIR/photography-$DATE.sql"
|
|
||||||
|
|
||||||
# 清理旧备份 (保留最近7天)
|
|
||||||
find "$BACKUP_DIR" -name "photography-*.sql.gz" -mtime +7 -delete
|
|
||||||
|
|
||||||
echo "✅ 数据库备份完成: photography-$DATE.sql.gz"
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🌐 Web 服务器配置
|
|
||||||
|
|
||||||
### Caddy 配置文件
|
|
||||||
|
|
||||||
```caddyfile
|
|
||||||
# docs/deployment/Caddyfile
|
|
||||||
|
|
||||||
# 前端网站
|
|
||||||
photography.iriver.top {
|
|
||||||
# 根目录
|
|
||||||
root * /home/gitea/www/photography
|
|
||||||
|
|
||||||
# 静态文件服务
|
|
||||||
file_server
|
|
||||||
|
|
||||||
# SPA 路由支持
|
|
||||||
try_files {path} /index.html
|
|
||||||
|
|
||||||
# 压缩
|
|
||||||
encode gzip
|
|
||||||
|
|
||||||
# 缓存配置
|
|
||||||
header {
|
|
||||||
# 静态资源缓存
|
|
||||||
Cache-Control "public, max-age=31536000" {
|
|
||||||
path *.js *.css *.png *.jpg *.jpeg *.gif *.ico *.woff *.woff2
|
|
||||||
}
|
|
||||||
|
|
||||||
# HTML 文件不缓存
|
|
||||||
Cache-Control "no-cache" {
|
|
||||||
path *.html
|
|
||||||
}
|
|
||||||
|
|
||||||
# 安全头
|
|
||||||
X-Frame-Options "DENY"
|
|
||||||
X-Content-Type-Options "nosniff"
|
|
||||||
Referrer-Policy "strict-origin-when-cross-origin"
|
|
||||||
}
|
|
||||||
|
|
||||||
# 日志
|
|
||||||
log {
|
|
||||||
output file /var/log/caddy/photography.log
|
|
||||||
format json
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# 管理后台
|
|
||||||
admin.photography.iriver.top {
|
|
||||||
# 根目录
|
|
||||||
root * /home/gitea/www/photography-admin
|
|
||||||
|
|
||||||
# 静态文件服务
|
|
||||||
file_server
|
|
||||||
|
|
||||||
# SPA 路由支持
|
|
||||||
try_files {path} /index.html
|
|
||||||
|
|
||||||
# 压缩
|
|
||||||
encode gzip
|
|
||||||
|
|
||||||
# 基本认证 (可选)
|
|
||||||
# basicauth {
|
|
||||||
# admin $2a$14$encrypted_password_hash
|
|
||||||
# }
|
|
||||||
|
|
||||||
# 缓存配置
|
|
||||||
header {
|
|
||||||
Cache-Control "public, max-age=31536000" {
|
|
||||||
path *.js *.css *.png *.jpg *.jpeg *.gif *.ico *.woff *.woff2
|
|
||||||
}
|
|
||||||
Cache-Control "no-cache" {
|
|
||||||
path *.html
|
|
||||||
}
|
|
||||||
X-Frame-Options "SAMEORIGIN"
|
|
||||||
X-Content-Type-Options "nosniff"
|
|
||||||
}
|
|
||||||
|
|
||||||
# 日志
|
|
||||||
log {
|
|
||||||
output file /var/log/caddy/admin.photography.log
|
|
||||||
format json
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# API 服务
|
|
||||||
api.photography.iriver.top {
|
|
||||||
# 反向代理到后端服务
|
|
||||||
reverse_proxy localhost:8080 {
|
|
||||||
# 健康检查
|
|
||||||
health_uri /health
|
|
||||||
health_interval 30s
|
|
||||||
health_timeout 10s
|
|
||||||
|
|
||||||
# 请求头
|
|
||||||
header_up Host {upstream_hostport}
|
|
||||||
header_up X-Real-IP {remote_host}
|
|
||||||
header_up X-Forwarded-Proto {scheme}
|
|
||||||
header_up X-Forwarded-For {remote_host}
|
|
||||||
}
|
|
||||||
|
|
||||||
# CORS 处理
|
|
||||||
header {
|
|
||||||
Access-Control-Allow-Origin "https://photography.iriver.top, https://admin.photography.iriver.top"
|
|
||||||
Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"
|
|
||||||
Access-Control-Allow-Headers "Content-Type, Authorization"
|
|
||||||
Access-Control-Max-Age "86400"
|
|
||||||
}
|
|
||||||
|
|
||||||
# 预检请求处理
|
|
||||||
@options method OPTIONS
|
|
||||||
respond @options 204
|
|
||||||
|
|
||||||
# 上传文件大小限制
|
|
||||||
request_body {
|
|
||||||
max_size 10MB
|
|
||||||
}
|
|
||||||
|
|
||||||
# 日志
|
|
||||||
log {
|
|
||||||
output file /var/log/caddy/api.photography.log
|
|
||||||
format json
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# 全局配置
|
|
||||||
{
|
|
||||||
# 自动 HTTPS
|
|
||||||
auto_https on
|
|
||||||
|
|
||||||
# Let's Encrypt 邮箱
|
|
||||||
email admin@iriver.top
|
|
||||||
|
|
||||||
# 日志级别
|
|
||||||
log {
|
|
||||||
level INFO
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🔒 SSL 证书配置
|
|
||||||
|
|
||||||
Caddy 会自动处理 SSL 证书,但也可以手动配置:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 手动获取证书 (如果需要)
|
|
||||||
certbot certonly --webroot -w /var/www/html -d photography.iriver.top -d admin.photography.iriver.top -d api.photography.iriver.top
|
|
||||||
|
|
||||||
# 设置自动续期
|
|
||||||
echo "0 3 * * * certbot renew --quiet && systemctl reload caddy" | crontab -
|
|
||||||
```
|
|
||||||
|
|
||||||
## 📊 监控和备份
|
|
||||||
|
|
||||||
### 1. 系统监控脚本
|
|
||||||
|
|
||||||
```bash
|
|
||||||
#!/bin/bash
|
|
||||||
# scripts/monitor.sh
|
|
||||||
|
|
||||||
# 检查服务状态
|
|
||||||
check_service() {
|
|
||||||
local service=$1
|
|
||||||
local url=$2
|
|
||||||
|
|
||||||
echo "检查 $service..."
|
|
||||||
if curl -f -s "$url" > /dev/null; then
|
|
||||||
echo "✅ $service 正常运行"
|
|
||||||
else
|
|
||||||
echo "❌ $service 服务异常"
|
|
||||||
# 发送告警 (可集成邮件、微信等)
|
|
||||||
# send_alert "$service 服务异常"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# 检查磁盘空间
|
|
||||||
check_disk() {
|
|
||||||
local usage=$(df / | tail -1 | awk '{print $5}' | sed 's/%//')
|
|
||||||
echo "磁盘使用率: $usage%"
|
|
||||||
|
|
||||||
if [ "$usage" -gt 80 ]; then
|
|
||||||
echo "⚠️ 磁盘空间不足"
|
|
||||||
# send_alert "磁盘空间不足: $usage%"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# 检查内存使用
|
|
||||||
check_memory() {
|
|
||||||
local usage=$(free | grep Mem | awk '{printf "%.1f", $3/$2 * 100.0}')
|
|
||||||
echo "内存使用率: $usage%"
|
|
||||||
}
|
|
||||||
|
|
||||||
# 执行检查
|
|
||||||
echo "🔍 开始系统监控..."
|
|
||||||
check_service "前端" "https://photography.iriver.top"
|
|
||||||
check_service "管理后台" "https://admin.photography.iriver.top"
|
|
||||||
check_service "API" "https://api.photography.iriver.top/health"
|
|
||||||
check_disk
|
|
||||||
check_memory
|
|
||||||
echo "✅ 监控检查完成"
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. 自动备份任务
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 设置定时任务
|
|
||||||
crontab -e
|
|
||||||
|
|
||||||
# 添加以下内容:
|
|
||||||
# 每天凌晨2点备份数据库
|
|
||||||
0 2 * * * /path/to/photography/scripts/backup.sh
|
|
||||||
|
|
||||||
# 每周日凌晨3点重启服务 (可选)
|
|
||||||
0 3 * * 0 cd /path/to/photography && docker-compose restart
|
|
||||||
|
|
||||||
# 每小时检查一次服务状态
|
|
||||||
0 * * * * /path/to/photography/scripts/monitor.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🐛 故障排除
|
|
||||||
|
|
||||||
### 常见问题和解决方案
|
|
||||||
|
|
||||||
#### 1. 后端服务无法启动
|
|
||||||
```bash
|
|
||||||
# 查看日志
|
|
||||||
docker-compose logs backend
|
|
||||||
|
|
||||||
# 检查配置
|
|
||||||
docker-compose config
|
|
||||||
|
|
||||||
# 重新构建
|
|
||||||
docker-compose build backend --no-cache
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 2. 数据库连接失败
|
|
||||||
```bash
|
|
||||||
# 检查数据库状态
|
|
||||||
docker-compose ps postgres
|
|
||||||
|
|
||||||
# 检查数据库日志
|
|
||||||
docker-compose logs postgres
|
|
||||||
|
|
||||||
# 手动连接测试
|
|
||||||
docker-compose exec postgres psql -U postgres -d photography
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 3. 前端/管理后台访问异常
|
|
||||||
```bash
|
|
||||||
# 检查文件权限
|
|
||||||
ls -la /home/gitea/www/photography/
|
|
||||||
ls -la /home/gitea/www/photography-admin/
|
|
||||||
|
|
||||||
# 检查 Caddy 配置
|
|
||||||
caddy validate --config /etc/caddy/Caddyfile
|
|
||||||
|
|
||||||
# 重新加载 Caddy
|
|
||||||
systemctl reload caddy
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 4. SSL 证书问题
|
|
||||||
```bash
|
|
||||||
# 检查证书状态
|
|
||||||
curl -I https://photography.iriver.top
|
|
||||||
|
|
||||||
# 查看 Caddy 日志
|
|
||||||
tail -f /var/log/caddy/photography.log
|
|
||||||
|
|
||||||
# 手动重新申请证书
|
|
||||||
systemctl stop caddy
|
|
||||||
caddy run --config /etc/caddy/Caddyfile
|
|
||||||
```
|
|
||||||
|
|
||||||
### 日志文件位置
|
|
||||||
- **后端日志**: `./backend/logs/`
|
|
||||||
- **Caddy 日志**: `/var/log/caddy/`
|
|
||||||
- **数据库日志**: `docker-compose logs postgres`
|
|
||||||
- **系统日志**: `/var/log/syslog`
|
|
||||||
|
|
||||||
## 🚀 部署命令速查
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 完整部署流程
|
|
||||||
git pull origin main
|
|
||||||
cd photography
|
|
||||||
|
|
||||||
# 后端部署
|
|
||||||
docker-compose build backend
|
|
||||||
docker-compose up -d
|
|
||||||
|
|
||||||
# 前端部署
|
|
||||||
cd frontend && bun run build && cd ..
|
|
||||||
./scripts/deploy-frontend.sh
|
|
||||||
|
|
||||||
# 管理后台部署
|
|
||||||
cd admin && npm run build && cd ..
|
|
||||||
./scripts/deploy-admin.sh
|
|
||||||
|
|
||||||
# 重启 Web 服务器
|
|
||||||
sudo systemctl reload caddy
|
|
||||||
|
|
||||||
# 检查服务状态
|
|
||||||
docker-compose ps
|
|
||||||
curl https://photography.iriver.top
|
|
||||||
curl https://admin.photography.iriver.top
|
|
||||||
curl https://api.photography.iriver.top/health
|
|
||||||
```
|
|
||||||
|
|
||||||
## 📞 技术支持
|
|
||||||
|
|
||||||
如果在部署过程中遇到问题,请:
|
|
||||||
|
|
||||||
1. 查看相关日志文件
|
|
||||||
2. 检查系统资源使用情况
|
|
||||||
3. 验证配置文件语法
|
|
||||||
4. 联系技术支持团队
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
📝 **文档版本**: v1.0
|
|
||||||
🕒 **最后更新**: 2024年
|
|
||||||
👥 **维护团队**: 摄影作品集项目组
|
|
||||||
0
ui/.gitignore → docs/ui/.gitignore
vendored
0
ui/.gitignore → docs/ui/.gitignore
vendored
0
ui/pnpm-lock.yaml → docs/ui/pnpm-lock.yaml
generated
0
ui/pnpm-lock.yaml → docs/ui/pnpm-lock.yaml
generated
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user