From 7a2465c74b13ae83c93e4c1a15c354c4e505818c Mon Sep 17 00:00:00 2001 From: hejl Date: Sat, 23 Aug 2025 09:32:36 +0800 Subject: [PATCH] =?UTF-8?q?=E5=BC=80=E5=90=AF=E7=83=AD=E5=8A=A0=E8=BD=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + gofaster/HOT_RELOAD.md | 118 ++++++++++++++++++ gofaster/app/dev-hot.bat | 8 ++ gofaster/app/dev-hot.ps1 | 7 ++ gofaster/app/dist/renderer/js/index.js | 9 +- .../src/renderer/components/LoginModal.vue | 7 +- gofaster/backend/.air.toml | 47 +++++-- gofaster/backend/dev.bat | 8 ++ gofaster/backend/dev.ps1 | 7 ++ gofaster/backend/internal/auth/model/auth.go | 7 +- .../internal/auth/service/auth_service.go | 6 +- gofaster/dev-full.ps1 | 28 +++++ 12 files changed, 228 insertions(+), 25 deletions(-) create mode 100644 gofaster/HOT_RELOAD.md create mode 100644 gofaster/app/dev-hot.bat create mode 100644 gofaster/app/dev-hot.ps1 create mode 100644 gofaster/backend/dev.bat create mode 100644 gofaster/backend/dev.ps1 create mode 100644 gofaster/dev-full.ps1 diff --git a/.gitignore b/.gitignore index f6491a5..804a403 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,4 @@ /gofaster/app/node_modules /gofaster/app/dist /gofaster/backend/logs +/gofaster/tmp/ diff --git a/gofaster/HOT_RELOAD.md b/gofaster/HOT_RELOAD.md new file mode 100644 index 0000000..ee47ff5 --- /dev/null +++ b/gofaster/HOT_RELOAD.md @@ -0,0 +1,118 @@ +# 🔥 GoFaster 热加载开发指南 + +## 概述 +GoFaster 项目支持前后端热加载,修改代码后无需手动重启服务,大大提高开发效率。 + +## 🚀 快速启动 + +### 方式1:一键启动(推荐) +```bash +# 在项目根目录执行 +./dev-full.ps1 +``` +这将同时启动前后端热加载服务。 + +### 方式2:分别启动 +```bash +# 启动后端热加载 +cd backend +./dev.ps1 + +# 启动前端热加载(新终端) +cd app +./dev-hot.ps1 +``` + +## 🔧 热加载配置 + +### 后端 Go 热加载 +- **工具**: `air` (Go 热加载工具) +- **配置文件**: `backend/.air.toml` +- **监听文件**: `.go`, `.tpl`, `.tmpl`, `.html` +- **排除目录**: `tmp`, `vendor`, `docs`, `testdata` + +### 前端 Electron 热加载 +- **工具**: `vue-cli-service` + `electron` +- **配置文件**: `app/vue.config.js` +- **监听文件**: `.vue`, `.js`, `.css`, `.html` +- **自动重载**: 代码修改后自动重新编译并重启 Electron + +## 📁 文件结构 +``` +gofaster/ +├── dev-full.ps1 # 一键启动脚本 +├── backend/ +│ ├── .air.toml # 后端热加载配置 +│ ├── dev.bat # Windows 后端启动脚本 +│ └── dev.ps1 # PowerShell 后端启动脚本 +└── app/ + ├── dev-hot.bat # Windows 前端启动脚本 + └── dev-hot.ps1 # PowerShell 前端启动脚本 +``` + +## 🎯 使用场景 + +### 后端开发 +1. 修改 Go 代码 +2. 保存文件 +3. `air` 自动检测变化 +4. 自动重新编译并重启服务 +5. 无需手动重启 + +### 前端开发 +1. 修改 Vue 组件、样式或逻辑 +2. 保存文件 +3. `vue-cli-service` 自动重新编译 +4. Electron 自动重载 +5. 界面立即更新 + +## ⚡ 性能优化 + +### 后端优化 +- 排除测试文件和文档目录 +- 设置合理的重载延迟(1秒) +- 只监听必要的文件类型 + +### 前端优化 +- 启用增量编译 +- 排除不必要的文件监听 +- 使用内存中的热重载 + +## 🐛 故障排除 + +### 后端热加载不工作 +1. 检查 `air` 是否安装:`go version -m $(which air)` +2. 确认 `.air.toml` 配置正确 +3. 检查文件权限和路径 + +### 前端热加载不工作 +1. 确认 `npm run dev` 正常运行 +2. 检查 `vue.config.js` 配置 +3. 查看控制台错误信息 + +### 端口冲突 +- 后端默认端口:8080 +- 前端开发端口:3000 +- 如遇冲突,修改相应配置文件 + +## 💡 开发技巧 + +1. **保持两个终端窗口**:一个运行后端,一个运行前端 +2. **使用 VS Code 集成终端**:方便同时查看前后端日志 +3. **合理使用日志**:热重载时日志会保留,便于调试 +4. **测试验证码接口**:修改后端代码后,验证码接口会立即生效 + +## 🔄 热加载流程 + +``` +修改代码 → 保存文件 → 自动检测 → 重新编译 → 重启服务 → 立即生效 +``` + +## 📚 相关文档 +- [Air 官方文档](https://github.com/air-verse/air) +- [Vue CLI 热重载](https://cli.vuejs.org/guide/cli-service.html#vue-cli-service-serve) +- [Electron 开发指南](https://www.electronjs.org/docs/tutorial/development) + +--- + +**享受高效的开发体验!** 🎉 diff --git a/gofaster/app/dev-hot.bat b/gofaster/app/dev-hot.bat new file mode 100644 index 0000000..e94328e --- /dev/null +++ b/gofaster/app/dev-hot.bat @@ -0,0 +1,8 @@ +@echo off +echo Starting GoFaster Frontend with Hot Reload... +echo. +echo Hot reload enabled - code changes will automatically rebuild and reload +echo Press Ctrl+C to stop +echo. + +npm run dev diff --git a/gofaster/app/dev-hot.ps1 b/gofaster/app/dev-hot.ps1 new file mode 100644 index 0000000..e3cb33b --- /dev/null +++ b/gofaster/app/dev-hot.ps1 @@ -0,0 +1,7 @@ +Write-Host "Starting GoFaster Frontend with Hot Reload..." -ForegroundColor Green +Write-Host "" +Write-Host "Hot reload enabled - code changes will automatically rebuild and reload" -ForegroundColor Yellow +Write-Host "Press Ctrl+C to stop" -ForegroundColor Yellow +Write-Host "" + +npm run dev diff --git a/gofaster/app/dist/renderer/js/index.js b/gofaster/app/dist/renderer/js/index.js index 856f00e..64b1cef 100644 --- a/gofaster/app/dist/renderer/js/index.js +++ b/gofaster/app/dist/renderer/js/index.js @@ -2375,7 +2375,7 @@ __webpack_require__.r(__webpack_exports__); username: this.loginForm.username, password: this.loginForm.password, captcha: this.loginForm.captcha, - captchaId: this.captchaId + captcha_id: this.captchaId // 修复字段名:后端期望 snake_case }) // 登录成功 @@ -2404,8 +2404,9 @@ __webpack_require__.r(__webpack_exports__); this.errorMessage = '' // 调用获取验证码接口 const response = await _services_userService__WEBPACK_IMPORTED_MODULE_0__.userService.getCaptcha() - this.captchaImage = response.captchaImage - this.captchaId = response.captchaID + // 修复字段映射:后端返回的是 snake_case,前端使用 camelCase + this.captchaImage = response.data.captcha_image + this.captchaId = response.data.captcha_id this.loginForm.captcha = '' console.log('验证码获取成功:', response) } catch (error) { @@ -6889,7 +6890,7 @@ __webpack_require__.r(__webpack_exports__); /******/ /******/ /* webpack/runtime/getFullHash */ /******/ (() => { -/******/ __webpack_require__.h = () => ("b656c4a813fb38f6") +/******/ __webpack_require__.h = () => ("d46aac25b901a9b0") /******/ })(); /******/ /******/ /* webpack/runtime/hasOwnProperty shorthand */ diff --git a/gofaster/app/src/renderer/components/LoginModal.vue b/gofaster/app/src/renderer/components/LoginModal.vue index a927736..4c88b6a 100644 --- a/gofaster/app/src/renderer/components/LoginModal.vue +++ b/gofaster/app/src/renderer/components/LoginModal.vue @@ -159,7 +159,7 @@ export default { username: this.loginForm.username, password: this.loginForm.password, captcha: this.loginForm.captcha, - captchaId: this.captchaId + captcha_id: this.captchaId // 修复字段名:后端期望 snake_case }) // 登录成功 @@ -188,8 +188,9 @@ export default { this.errorMessage = '' // 调用获取验证码接口 const response = await userService.getCaptcha() - this.captchaImage = response.captchaImage - this.captchaId = response.captchaID + // 修复字段映射:后端返回的是 snake_case,前端使用 camelCase + this.captchaImage = response.data.captcha_image + this.captchaId = response.data.captcha_id this.loginForm.captcha = '' console.log('验证码获取成功:', response) } catch (error) { diff --git a/gofaster/backend/.air.toml b/gofaster/backend/.air.toml index 087eb6b..723a85a 100644 --- a/gofaster/backend/.air.toml +++ b/gofaster/backend/.air.toml @@ -1,21 +1,44 @@ root = "." +testdata_dir = "testdata" tmp_dir = "tmp" [build] -cmd = "go build -o ./tmp/main.exe ." -args_bin = ["-v"] -bin = "./tmp/main.exe" -runner = ["./tmp/main.exe"] -include_ext = ["go", "tpl", "tmpl", "html"] -exclude_dir = ["assets", "tmp", "vendor", "docs"] + args_bin = [] + bin = "./tmp/main.exe" + cmd = "go build -o ./tmp/main.exe ." + delay = 1000 + exclude_dir = ["assets", "tmp", "vendor", "testdata", "docs"] + exclude_file = [] + exclude_regex = ["_test.go"] + exclude_unchanged = false + follow_symlink = false + full_bin = "" + include_dir = [] + include_ext = ["go", "tpl", "tmpl", "html"] + include_file = [] + kill_delay = "0s" + log = "build-errors.log" + poll = false + poll_interval = 0 + rerun = false + rerun_delay = 500 + send_interrupt = false + stop_on_root = false + +[color] + app = "" + build = "yellow" + main = "magenta" + runner = "green" + watcher = "cyan" [log] -time = true -level = "debug" + main_only = false + time = false [misc] -clean_on_exit = true -clean_before_build = true + clean_on_exit = false -[windows] -filter_extension = ["exe", "dll", "so", "a"] \ No newline at end of file +[screen] + clear_on_rebuild = false + keep_scroll = true \ No newline at end of file diff --git a/gofaster/backend/dev.bat b/gofaster/backend/dev.bat new file mode 100644 index 0000000..ed2113b --- /dev/null +++ b/gofaster/backend/dev.bat @@ -0,0 +1,8 @@ +@echo off +echo Starting GoFaster Backend with Hot Reload... +echo. +echo Hot reload enabled - code changes will automatically restart the server +echo Press Ctrl+C to stop +echo. + +air diff --git a/gofaster/backend/dev.ps1 b/gofaster/backend/dev.ps1 new file mode 100644 index 0000000..4b06790 --- /dev/null +++ b/gofaster/backend/dev.ps1 @@ -0,0 +1,7 @@ +Write-Host "Starting GoFaster Backend with Hot Reload..." -ForegroundColor Green +Write-Host "" +Write-Host "Hot reload enabled - code changes will automatically restart the server" -ForegroundColor Yellow +Write-Host "Press Ctrl+C to stop" -ForegroundColor Yellow +Write-Host "" + +air diff --git a/gofaster/backend/internal/auth/model/auth.go b/gofaster/backend/internal/auth/model/auth.go index 0a82525..3a3d6c4 100644 --- a/gofaster/backend/internal/auth/model/auth.go +++ b/gofaster/backend/internal/auth/model/auth.go @@ -4,9 +4,10 @@ import "time" // LoginRequest 登录请求 type LoginRequest struct { - Username string `json:"username" binding:"required" validate:"required,min=3,max=50"` - Password string `json:"password" binding:"required" validate:"required,min=6,max=100"` - Captcha string `json:"captcha" binding:"required" validate:"required,len=4"` + Username string `json:"username" binding:"required" validate:"required,min=3,max=50"` + Password string `json:"password" binding:"required" validate:"required,min=6,max=100"` + Captcha string `json:"captcha" binding:"required" validate:"required,len=4"` + CaptchaID string `json:"captcha_id" binding:"required" validate:"required"` } // LoginResponse 登录响应 diff --git a/gofaster/backend/internal/auth/service/auth_service.go b/gofaster/backend/internal/auth/service/auth_service.go index 568976f..e3391a9 100644 --- a/gofaster/backend/internal/auth/service/auth_service.go +++ b/gofaster/backend/internal/auth/service/auth_service.go @@ -43,7 +43,7 @@ func NewAuthService(userRepo repository.UserRepository, captchaRepo repository.C // Login 用户登录 func (s *authService) Login(ctx context.Context, req *model.LoginRequest, clientIP string) (*model.LoginResponse, error) { // 1. 验证验证码 - if err := s.ValidateCaptcha(ctx, req.Username, req.Captcha); err != nil { + if err := s.ValidateCaptcha(ctx, req.CaptchaID, req.Captcha); err != nil { return nil, fmt.Errorf("验证码错误: %w", err) } @@ -280,14 +280,14 @@ func (s *authService) generateCaptchaImage(text string) string { // 使用HTML5 Canvas风格的文本渲染 width := 120 height := 40 - + // 创建一个简单的SVG图片,包含验证码文本 svg := fmt.Sprintf(` %s `, width, height, width, height, width/2, height/2, text) - + // 将SVG转换为Base64 return fmt.Sprintf("data:image/svg+xml;base64,%s", base64.StdEncoding.EncodeToString([]byte(svg))) } diff --git a/gofaster/dev-full.ps1 b/gofaster/dev-full.ps1 new file mode 100644 index 0000000..e1cd7c0 --- /dev/null +++ b/gofaster/dev-full.ps1 @@ -0,0 +1,28 @@ +Write-Host "🚀 Starting GoFaster Full Stack Development Environment..." -ForegroundColor Cyan +Write-Host "" +Write-Host "Frontend: Electron + Vue.js with Hot Reload" -ForegroundColor Green +Write-Host "Backend: Go + Gin with Hot Reload" -ForegroundColor Green +Write-Host "" +Write-Host "Press Ctrl+C to stop all services" -ForegroundColor Yellow +Write-Host "" + +# 启动后端热加载(后台运行) +Write-Host "Starting Backend with Hot Reload..." -ForegroundColor Green +Start-Process powershell -ArgumentList "-NoExit", "-Command", "cd backend; air" -WindowStyle Normal + +# 等待2秒让后端启动 +Start-Sleep -Seconds 2 + +# 启动前端热加载(后台运行) +Write-Host "Starting Frontend with Hot Reload..." -ForegroundColor Green +Start-Process powershell -ArgumentList "-NoExit", "-Command", "cd app; npm run dev" -WindowStyle Normal + +Write-Host "" +Write-Host "✅ Both services started successfully!" -ForegroundColor Green +Write-Host "Frontend: http://localhost:3000 (Electron app)" -ForegroundColor Cyan +Write-Host "Backend: http://localhost:8080" -ForegroundColor Cyan +Write-Host "Swagger: http://localhost:8080/swagger/index.html" -ForegroundColor Cyan +Write-Host "" +Write-Host "💡 Code changes will automatically trigger rebuilds and reloads!" -ForegroundColor Yellow +Write-Host "Press any key to exit this launcher..." +$null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")