Files
empty 48d61a1e15 feat: 新增签到墙、摇一摇等功能及开发环境配置
新功能:
- 签到墙页面 (CheckinWallView) 及后端接口
- 摇一摇互动页面 (ShakeView) 及服务
- 头像服务 (avatar.service)
- 微信公众号静默授权登录增强

开发环境:
- 新增 dev-tunnel skill 用于本地调试
- docker-compose.dev.yml 开发环境配置
- 客户端 .env.development 配置文件

其他改进:
- VoteView 投票页面功能增强
- AdminControl 管理控制台更新
- 连接状态管理优化
- 新增马蹄声音效

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 17:25:56 +08:00

6.9 KiB
Raw Permalink Blame History

dev-tunnel - 本地开发隧道

通过 SSH 反向隧道将本地服务暴露到生产服务器,实现完整的本地开发调试(前端+后端),同时使用生产域名和微信授权。

使用场景

  • 本地调试需要微信授权回调
  • 本地调试需要使用生产域名
  • 需要同时调试前端和后端
  • 本地没有公网 IP

命令

/dev-tunnel start   # 启动本地调试模式
/dev-tunnel stop    # 恢复生产环境
/dev-tunnel status  # 查看当前状态

架构说明

生产环境:
  /api/*, /socket.io/* → localhost:3000 → PM2(gala-server)
  /screen*             → 静态文件 (client-screen/dist)
  其他                 → 静态文件 (client-mobile/dist)

调试模式:
  /api/*, /socket.io/* → localhost:3001 → 隧道 → 本地:3000 (后端)
  /screen*             → localhost:5174 → 隧道 → 本地:5174 (大屏 dev)
  其他                 → localhost:5173 → 隧道 → 本地:5173 (移动端 dev)

隧道端口映射

服务 服务器端口 本地端口
后端 API 3001 3000
移动端前端 5173 5173
大屏端前端 5174 5174

操作步骤

start - 启动调试模式

  1. 服务器: 停止 PM2 后端服务
  2. 服务器: 切换 Caddy 为调试模式配置
  3. 本地: 切换 MOBILE_CLIENT_URL 为生产域名(自动执行)
  4. 本地: 建立 SSH 隧道(自动执行)
  5. 本地: 启动后端和前端 dev server手动执行

stop - 恢复生产环境

  1. 本地: 终止 SSH 隧道进程(自动执行)
  2. 本地: 恢复 MOBILE_CLIENT_URL 为本地地址(自动执行)
  3. 服务器: 恢复 Caddy 生产环境配置
  4. 服务器: 重启 PM2 后端服务

具体命令

启动调试模式

# 1. 停止服务器后端
ssh vote "pm2 stop gala-server"

# 2. 切换 Caddy 为调试模式配置
# 注意:需要先将 Caddyfile.debug 上传到服务器,或直接替换内容
ssh vote "cat > /etc/caddy/Caddyfile << 'EOF'
{
    email let5sne@gmail.com
}

2026.cptp.let5see.xyz {
    handle /A6e75lM1ge.txt {
        respond \"3a5d2d7f410fbcbc32e3c222b2cf28bf\"
    }
    handle /screen* {
        reverse_proxy localhost:5174
    }
    handle /api/* {
        header Cache-Control \"no-store, no-cache, must-revalidate\"
        reverse_proxy localhost:3001
    }
    handle /socket.io/* {
        reverse_proxy localhost:3001
    }
    handle /avatars/* {
        reverse_proxy localhost:3001
    }
    handle {
        reverse_proxy localhost:5173
    }
    encode gzip
}
EOF"

# 3. 重载 Caddy
ssh vote "caddy reload --config /etc/caddy/Caddyfile"

# 4. 切换 MOBILE_CLIENT_URL 为生产域名
sed -i '' 's|MOBILE_CLIENT_URL=http://localhost:5173|MOBILE_CLIENT_URL=https://2026.cptp.let5see.xyz|g' packages/server/.env

# 5. 切换大屏端 VITE_MOBILE_URL 为生产域名
sed -i '' 's|VITE_MOBILE_URL=http://localhost:5173|VITE_MOBILE_URL=https://2026.cptp.let5see.xyz|g' packages/client-screen/.env.development

# 6. 切换移动端 VITE_SOCKET_URL/VITE_API_URL 为生产域名
sed -i '' 's|VITE_SOCKET_URL=http://localhost:3000|VITE_SOCKET_URL=https://2026.cptp.let5see.xyz|g' packages/client-mobile/.env.development
sed -i '' 's|VITE_API_URL=http://localhost:3000|VITE_API_URL=https://2026.cptp.let5see.xyz|g' packages/client-mobile/.env.development

# 7. 建立 SSH 隧道(自动后台运行)
ssh -R 3001:localhost:3000 -R 5173:localhost:5173 -R 5174:localhost:5174 vote -N -o ServerAliveInterval=30

# 6. 本地启动服务3个终端手动执行
# 终端1: 后端
pnpm --filter @gala/server dev

# 终端2: 移动端前端
pnpm --filter @gala/client-mobile dev --host

# 终端3: 大屏端前端
pnpm --filter @gala/client-screen dev --host

恢复生产环境

# 1. 终止本地 SSH 隧道进程
pkill -f "ssh -R 3001:localhost:3000"

# 2. 恢复 MOBILE_CLIENT_URL 为本地地址
sed -i '' 's|MOBILE_CLIENT_URL=https://2026.cptp.let5see.xyz|MOBILE_CLIENT_URL=http://localhost:5173|g' packages/server/.env

# 3. 恢复大屏端 VITE_MOBILE_URL 为本地地址
sed -i '' 's|VITE_MOBILE_URL=https://2026.cptp.let5see.xyz|VITE_MOBILE_URL=http://localhost:5173|g' packages/client-screen/.env.development

# 4. 恢复移动端 VITE_SOCKET_URL/VITE_API_URL 为本地地址
sed -i '' 's|VITE_SOCKET_URL=https://2026.cptp.let5see.xyz|VITE_SOCKET_URL=http://localhost:3000|g' packages/client-mobile/.env.development
sed -i '' 's|VITE_API_URL=https://2026.cptp.let5see.xyz|VITE_API_URL=http://localhost:3000|g' packages/client-mobile/.env.development

# 5. 恢复 Caddy 生产环境配置
ssh vote "cat > /etc/caddy/Caddyfile << 'EOF'
{
    email let5sne@gmail.com
}

2026.cptp.let5see.xyz {
    handle /A6e75lM1ge.txt {
        respond \"3a5d2d7f410fbcbc32e3c222b2cf28bf\"
    }
    handle /screen* {
        root * /root/company-celebration/packages/client-screen/dist
        uri strip_prefix /screen
        try_files {path} /index.html
        file_server
        header Cache-Control \"no-cache, no-store, must-revalidate\"
        @screenassets path_regexp assets \\/assets\\/.*
        header @screenassets Cache-Control \"public, max-age=31536000, immutable\"
    }
    handle /api/* {
        header Cache-Control \"no-store, no-cache, must-revalidate\"
        reverse_proxy localhost:3000
    }
    handle /socket.io/* {
        reverse_proxy localhost:3000
    }
    handle {
        root * /root/company-celebration/packages/client-mobile/dist
        try_files {path} /index.html
        file_server
        header Cache-Control \"no-cache, no-store, must-revalidate\"
        @mobileassets path_regexp assets \\/assets\\/.*
        header @mobileassets Cache-Control \"public, max-age=31536000, immutable\"
    }
    encode gzip
}
EOF"

# 3. 重载 Caddy
ssh vote "caddy reload --config /etc/caddy/Caddyfile"

# 4. 重启服务器后端
ssh vote "pm2 restart gala-server"

前端 dev server 配置

必需配置

两个前端项目的 vite.config.ts 需要包含以下配置:

client-mobile (端口 5173):

server: {
  host: '0.0.0.0',
  port: 5173,
  allowedHosts: ['2026.cptp.let5see.xyz'],
}

client-screen (端口 5174):

server: {
  host: '0.0.0.0',
  port: 5174,
  allowedHosts: ['2026.cptp.let5see.xyz'],
}

配置说明

配置项 说明
host: '0.0.0.0' 允许外部网络访问
allowedHosts 允许通过生产域名访问,否则 Vite 会拒绝请求
base: '/screen/' 大屏端需要配置,支持 /screen 路径前缀

注意事项

  • SSH 隧道断开后,生产环境将不可用,务必及时恢复
  • 调试完成后必须执行 stop 恢复生产环境
  • 隧道命令需要保持终端运行,关闭终端会断开隧道
  • 本地需要同时运行 4 个终端(后端 + 2个前端 + 隧道)

文件说明

  • Caddyfile.production - 生产环境 Caddy 配置模板
  • Caddyfile.debug - 调试模式 Caddy 配置模板