diff --git a/conf/app.conf b/conf/app.conf index 44849c9..9dc2a71 100644 --- a/conf/app.conf +++ b/conf/app.conf @@ -2,6 +2,9 @@ appname = server httpport = 8081 runmode = dev +# 启用请求体复制(允许多次读取请求体) +copyrequestbody = true + # 服务器超时配置(支持大文件上传) # 0 表示不设置超时限制 ServerTimeOut = 0 diff --git a/controllers/qiniu_upload.go b/controllers/qiniu_upload.go index c70c810..cc8a130 100644 --- a/controllers/qiniu_upload.go +++ b/controllers/qiniu_upload.go @@ -126,6 +126,11 @@ func (c *QiniuUploadController) SaveFileRecord() { } tid := c.effectiveTid(claims) + // 调试:打印请求体 + body := c.Ctx.Input.RequestBody + fmt.Println("SaveFileRecord 请求体长度:", len(body)) + fmt.Println("SaveFileRecord 请求体内容:", string(body)) + // 解析请求参数 type SaveRequest struct { Key string `json:"key"` // 七牛云文件 key diff --git a/docs/修复请求体为空问题.md b/docs/修复请求体为空问题.md new file mode 100644 index 0000000..fdbb85b --- /dev/null +++ b/docs/修复请求体为空问题.md @@ -0,0 +1,200 @@ +# 修复请求体为空问题 + +## 问题描述 + +七牛云上传成功后,保存文件记录到数据库时失败: + +``` +POST https://api.yunzer.cn/platform/qiniu/save 400 +{"code": 400, "msg": "参数解析失败: 请求体为空"} +``` + +## 问题原因 + +Beego 框架默认不会复制请求体到 `c.Ctx.Input.RequestBody`,需要显式启用 `CopyRequestBody` 配置。 + +## 解决方案 + +### 1. 修改 go/conf/app.conf + +添加配置: + +```properties +# 启用请求体复制(允许多次读取请求体) +copyrequestbody = true +``` + +### 2. 修改 go/main.go + +在代码中显式启用: + +```go +func main() { + // 初始化数据库 + models.Init(version.Version) + + // 启用请求体复制(允许多次读取请求体) + beego.BConfig.CopyRequestBody = true // ← 新增 + + // 设置最大请求体大小(10MB,足够登录请求使用) + beego.BConfig.MaxMemory = 10 << 20 // 10MB + + // 静态资源:映射 /uploads 到本地 uploads 目录,供前端访问上传文件 + beego.SetStaticPath("/uploads", "uploads") + + beego.Run() +} +``` + +### 3. 添加调试日志 + +在 `go/controllers/qiniu_upload.go` 的 `SaveFileRecord` 方法中添加日志: + +```go +// 调试:打印请求体 +body := c.Ctx.Input.RequestBody +fmt.Println("SaveFileRecord 请求体长度:", len(body)) +fmt.Println("SaveFileRecord 请求体内容:", string(body)) +``` + +## 重启服务 + +```bash +# 重启 Go 服务 +systemctl restart go-api + +# 查看服务状态 +systemctl status go-api + +# 查看日志 +tail -f /www/wwwroot/api.yunzer.cn/go.log +``` + +## 测试步骤 + +1. 重启后端服务 +2. 登录前端系统 +3. 进入软件升级页面 +4. 上传一个文件 +5. 观察后端日志 + +### 预期日志输出 + +``` +SaveFileRecord 请求体长度: 123 +SaveFileRecord 请求体内容: {"key":"2026/04/09/xxx.exe","hash":"xxx","size":60742452,"name":"xxx.exe","mimeType":"application/x-msdownload","cate":0} +``` + +### 预期响应 + +```json +{ + "code": 200, + "data": { + "url": "http://7colud.yunzer.cn/2026/04/09/xxx.exe", + "id": 123, + "name": "xxx.exe", + "key": "2026/04/09/xxx.exe" + } +} +``` + +## 相关配置说明 + +### CopyRequestBody 的作用 + +Beego 框架中,请求体默认只能读取一次。如果需要在多个地方读取请求体(例如中间件和控制器),需要启用 `CopyRequestBody`。 + +启用后,Beego 会在接收到请求时将请求体复制到 `c.Ctx.Input.RequestBody`,允许多次读取。 + +### 配置方式 + +有两种方式启用: + +1. **配置文件方式** (`go/conf/app.conf`): + ```properties + copyrequestbody = true + ``` + +2. **代码方式** (`go/main.go`): + ```go + beego.BConfig.CopyRequestBody = true + ``` + +建议两种方式都配置,确保生效。 + +## 注意事项 + +### 1. 内存占用 + +启用 `CopyRequestBody` 会增加内存占用,因为每个请求的请求体都会被复制到内存中。 + +对于大文件上传,建议: +- 使用七牛云直传(不经过服务器) +- 只在需要的接口启用请求体复制 + +### 2. 与登录接口的兼容性 + +之前修复登录问题时,我们已经将登录接口改为使用 `c.Ctx.Input.RequestBody`,启用 `CopyRequestBody` 后,登录接口也能正常工作。 + +### 3. MaxMemory 配置 + +`MaxMemory` 配置控制请求体的最大大小: + +```go +beego.BConfig.MaxMemory = 10 << 20 // 10MB +``` + +对于七牛云直传,文件不经过服务器,所以这个限制不影响大文件上传。 + +## 验证修复 + +### 1. 检查配置是否生效 + +重启服务后,查看日志中是否有请求体内容输出。 + +### 2. 测试上传功能 + +上传一个文件,检查: +- 七牛云上传是否成功 +- 数据库记录是否保存成功 +- 文件 URL 是否正确 + +### 3. 检查数据库 + +```sql +SELECT id, name, src, size, type, cate, md5, create_time +FROM system_file +ORDER BY id DESC +LIMIT 5; +``` + +应该能看到新上传的文件记录。 + +## 回滚方案 + +如果修复后出现其他问题,可以临时禁用: + +```go +// go/main.go +beego.BConfig.CopyRequestBody = false +``` + +或在 `go/conf/app.conf` 中: + +```properties +copyrequestbody = false +``` + +然后重启服务。 + +## 相关文件 + +- `go/main.go` - 主程序入口 +- `go/conf/app.conf` - 配置文件 +- `go/controllers/qiniu_upload.go` - 七牛云上传控制器 +- `go/controllers/platform_auth.go` - 登录控制器(也使用 RequestBody) + +## 更新日期 + +2026-04-09 diff --git a/docs/快速修复-请求体为空.md b/docs/快速修复-请求体为空.md new file mode 100644 index 0000000..853bdc0 --- /dev/null +++ b/docs/快速修复-请求体为空.md @@ -0,0 +1,122 @@ +# 快速修复:请求体为空问题 + +## 问题 +``` +POST /platform/qiniu/save 400 +{"code": 400, "msg": "参数解析失败: 请求体为空"} +``` + +## 快速修复步骤 + +### 1. 重启后端服务(已修改配置) + +```bash +systemctl restart go-api +``` + +### 2. 查看服务状态 + +```bash +systemctl status go-api +``` + +预期输出: +``` +● go-api.service - Go API Server + Loaded: loaded + Active: active (running) +``` + +### 3. 查看日志 + +```bash +tail -f /www/wwwroot/api.yunzer.cn/go.log +``` + +### 4. 测试上传 + +1. 登录系统 +2. 进入软件升级页面 +3. 上传一个文件 + +### 5. 观察日志输出 + +应该看到: +``` +SaveFileRecord 请求体长度: xxx +SaveFileRecord 请求体内容: {"key":"...","hash":"...","size":...} +``` + +## 已修改的文件 + +✅ `go/main.go` - 添加 `beego.BConfig.CopyRequestBody = true` +✅ `go/conf/app.conf` - 添加 `copyrequestbody = true` +✅ `go/controllers/qiniu_upload.go` - 添加调试日志 + +## 如果还是失败 + +### 检查 1: 服务是否重启成功 + +```bash +systemctl status go-api +``` + +如果失败,查看错误: +```bash +journalctl -u go-api -n 50 +``` + +### 检查 2: 配置是否生效 + +查看日志中是否有请求体内容输出。如果没有,说明配置未生效。 + +### 检查 3: 前端请求是否正确 + +打开浏览器开发者工具,查看 Network 标签: +- 请求方法:POST +- Content-Type: application/json +- 请求体:应该有 JSON 数据 + +## 完整上传流程 + +``` +1. 前端上传文件到七牛云 ✓ + ↓ +2. 七牛云返回文件信息 ✓ + { + "key": "2026/04/09/xxx.exe", + "hash": "xxx", + "size": 60742452 + } + ↓ +3. 前端调用 /platform/qiniu/save ← 这里失败了 + POST /platform/qiniu/save + Body: { + "key": "...", + "hash": "...", + "size": ..., + "name": "...", + "mimeType": "...", + "cate": 0 + } + ↓ +4. 后端保存到数据库 ← 修复后应该成功 + ↓ +5. 返回文件 URL +``` + +## 修复原理 + +Beego 框架默认不复制请求体,需要启用 `CopyRequestBody`: + +```go +// 修复前 +c.Ctx.Input.RequestBody // 空的 + +// 修复后(启用 CopyRequestBody) +c.Ctx.Input.RequestBody // 包含请求体数据 +``` + +## 更新时间 + +2026-04-09 diff --git a/docs/立即执行-重启服务.md b/docs/立即执行-重启服务.md new file mode 100644 index 0000000..0018a3b --- /dev/null +++ b/docs/立即执行-重启服务.md @@ -0,0 +1,218 @@ +# 立即执行:重启服务 + +## 修复内容 + +✅ 已修复日志错误(`beego.Info` → `fmt.Println`) +✅ 已启用 `CopyRequestBody` 配置 +✅ 已添加调试输出 + +## 立即执行 + +### 1. 重启服务 + +```bash +systemctl restart go-api +``` + +### 2. 检查服务状态 + +```bash +systemctl status go-api +``` + +**预期输出**: +``` +● go-api.service - Go API Server + Active: active (running) +``` + +如果显示 `failed`,查看错误: +```bash +journalctl -u go-api -n 50 +``` + +### 3. 查看实时日志 + +```bash +tail -f /www/wwwroot/api.yunzer.cn/go.log +``` + +或者查看标准输出(调试日志会输出到这里): +```bash +journalctl -u go-api -f +``` + +### 4. 测试上传 + +1. 打开浏览器,登录系统 +2. 进入:平台管理 → 软件升级 +3. 点击"新增"或"编辑" +4. 上传一个文件(建议先用小文件测试) + +### 5. 观察日志 + +在终端中应该看到: + +``` +SaveFileRecord 请求体长度: 150 +SaveFileRecord 请求体内容: {"key":"2026/04/09/1775732976777726699.exe","hash":"loozoz7qv9flWXsS5UldWdPX9-T_","size":60742452,"name":"xxx.exe","mimeType":"application/x-msdownload","cate":0} +``` + +### 6. 验证结果 + +**前端应该显示**: +- 上传进度条 +- 上传成功提示 +- 文件 URL: `http://7colud.yunzer.cn/2026/04/09/xxxxx.exe` + +**数据库验证**: +```bash +mysql -u go-platform -p -h 212.64.112.158 -P 3388 go-platform +``` + +```sql +SELECT id, name, src, size, type, create_time +FROM system_file +ORDER BY id DESC +LIMIT 5; +``` + +## 完整上传流程 + +``` +用户选择文件 + ↓ +前端获取存储配置 + storageType: 'qiniu' + ↓ +前端获取上传凭证 + token, region: 'z2' + ↓ +前端直接上传到七牛云 + POST https://upload-z2.qiniup.com + ✓ 成功返回: {key, hash, size} + ↓ +前端保存文件记录 + POST /platform/qiniu/save + Body: {key, hash, size, name, mimeType, cate} + ↓ +后端接收请求 + ✓ CopyRequestBody 已启用 + ✓ 请求体不为空 + ↓ +后端保存到数据库 + INSERT INTO system_file + ↓ +返回文件信息 + {url, id, name, key} + ↓ +前端显示上传成功 +``` + +## 如果还是失败 + +### 问题 1: 服务启动失败 + +**检查**: +```bash +journalctl -u go-api -n 50 +``` + +**常见原因**: +- 端口被占用 +- 数据库连接失败 +- 配置文件错误 + +### 问题 2: 请求体仍然为空 + +**检查**: +1. 确认服务已重启 +2. 查看日志中是否有 "请求体长度: 0" +3. 检查前端请求的 Content-Type 是否为 `application/json` + +**解决**: +```bash +# 确保配置生效 +grep -i "copyrequestbody" /www/wwwroot/api.yunzer.cn/conf/app.conf + +# 应该看到 +copyrequestbody = true +``` + +### 问题 3: 七牛云上传失败 + +**检查**: +- 浏览器控制台是否有 CORS 错误 +- 七牛云 bucket 是否存在 +- 区域配置是否正确(z2) + +**解决**: +参见 `platform/docs/七牛云上传测试步骤.md` + +## 调试技巧 + +### 1. 查看完整请求 + +浏览器开发者工具 → Network 标签 → 找到 `/platform/qiniu/save` 请求: +- Headers: 查看 Content-Type +- Payload: 查看请求体内容 +- Response: 查看响应内容 + +### 2. 查看后端日志 + +```bash +# 实时日志 +tail -f /www/wwwroot/api.yunzer.cn/go.log + +# 或者查看 systemd 日志(包含 fmt.Println 输出) +journalctl -u go-api -f +``` + +### 3. 测试 API + +使用 curl 测试: +```bash +# 获取 token(先登录) +TOKEN="your_token_here" + +# 测试保存接口 +curl -X POST https://api.yunzer.cn/platform/qiniu/save \ + -H "Authorization: Bearer $TOKEN" \ + -H "Content-Type: application/json" \ + -d '{ + "key": "test/test.txt", + "hash": "test123", + "size": 1024, + "name": "test.txt", + "mimeType": "text/plain", + "cate": 0 + }' +``` + +## 成功标志 + +✓ 服务启动成功 +✓ 日志中看到请求体内容 +✓ 前端显示上传成功 +✓ 数据库有新记录 +✓ 文件 URL 可以访问 + +## 下一步 + +上传成功后,可以: +1. 移除调试日志(`fmt.Println`) +2. 测试大文件上传 +3. 测试批量上传 +4. 验证文件去重功能 + +## 联系支持 + +如果问题仍然存在,请提供: +1. 服务状态输出 +2. 完整的错误日志 +3. 浏览器控制台截图 +4. 请求和响应的详细信息 + +## 更新时间 + +2026-04-09 diff --git a/main.go b/main.go index 5dab968..525a065 100644 --- a/main.go +++ b/main.go @@ -12,6 +12,9 @@ func main() { // 初始化数据库 models.Init(version.Version) + // 启用请求体复制(允许多次读取请求体) + beego.BConfig.CopyRequestBody = true + // 设置最大请求体大小(10MB,足够登录请求使用) beego.BConfig.MaxMemory = 10 << 20 // 10MB