feat(request): 实现请求参数获取方法

- 完成 ReqParam/ReqParams 方法实现,用于获取 URL 参数并返回 *Obj
- 完成 ReqForm/ReqForms 方法实现,用于获取表单数据并返回 *Obj
- 完成 ReqJson/ReqJsons 方法实现,用于获取 JSON Body 并返回 *Obj
- 完成 ReqFile/ReqFiles 方法实现,用于获取上传文件
- 完成 ReqData/ReqDatas 方法实现,用于统一封装请求数据获取并返回 *Obj
- 更新计划文件状态,标记所有相关功能模块为已完成
This commit is contained in:
2026-01-22 04:59:53 +08:00
parent b755519fc6
commit f2f1fcc9aa
16 changed files with 2881 additions and 2441 deletions
+104 -3
View File
@@ -1,12 +1,17 @@
package hotime
import (
. "code.hoteas.com/golang/hotime/common"
. "code.hoteas.com/golang/hotime/db"
"bytes"
"encoding/json"
"io"
"mime/multipart"
"net/http"
"strings"
"sync"
"time"
. "code.hoteas.com/golang/hotime/common"
. "code.hoteas.com/golang/hotime/db"
)
type Context struct {
@@ -23,6 +28,10 @@ type Context struct {
SessionIns
DataSize int
HandlerStr string //复写请求url
// 请求参数缓存
reqJsonCache Map // JSON Body 缓存
reqMu sync.Once // 确保 JSON 只解析一次
}
// Mtd 唯一标志
@@ -100,5 +109,97 @@ func (that *Context) View() {
that.DataSize = len(d)
that.RespData = nil
that.Resp.Write(d)
return
}
// ==================== 请求参数获取方法 ====================
// ReqParam 获取 URL 查询参数,返回 *Obj 支持链式调用
// 用法: that.ReqParam("id").ToInt()
func (that *Context) ReqParam(key string) *Obj {
v := that.Req.URL.Query().Get(key)
if v == "" {
return &Obj{Data: nil}
}
return &Obj{Data: v}
}
// ReqForm 获取表单参数,返回 *Obj 支持链式调用
// 用法: that.ReqForm("name").ToStr()
func (that *Context) ReqForm(key string) *Obj {
v := that.Req.FormValue(key)
if v == "" {
return &Obj{Data: nil}
}
return &Obj{Data: v}
}
// ReqJson 获取 JSON Body 中的字段,返回 *Obj 支持链式调用
// 用法: that.ReqJson("data").ToMap()
func (that *Context) ReqJson(key string) *Obj {
that.parseJsonBody()
if that.reqJsonCache == nil {
return &Obj{Data: nil}
}
return &Obj{Data: that.reqJsonCache.Get(key)}
}
// parseJsonBody 解析 JSON Body(只解析一次,并发安全)
func (that *Context) parseJsonBody() {
that.reqMu.Do(func() {
if that.Req.Body == nil {
return
}
body, err := io.ReadAll(that.Req.Body)
if err != nil || len(body) == 0 {
return
}
// 恢复 Body 以便后续代码可以再次读取
that.Req.Body = io.NopCloser(bytes.NewBuffer(body))
that.reqJsonCache = ObjToMap(string(body))
})
}
// ReqData 统一获取请求参数,优先级: JSON > Form > URL
// 用法: that.ReqData("id").ToInt()
func (that *Context) ReqData(key string) *Obj {
// 1. 优先从 JSON Body 获取
that.parseJsonBody()
if that.reqJsonCache != nil {
if v := that.reqJsonCache.Get(key); v != nil {
return &Obj{Data: v}
}
}
// 2. 其次从 Form 获取
if v := that.Req.FormValue(key); v != "" {
return &Obj{Data: v}
}
// 3. 最后从 URL 参数获取
if v := that.Req.URL.Query().Get(key); v != "" {
return &Obj{Data: v}
}
return &Obj{Data: nil}
}
// ReqFile 获取单个上传文件
// 用法: file, header, err := that.ReqFile("avatar")
func (that *Context) ReqFile(name string) (multipart.File, *multipart.FileHeader, error) {
return that.Req.FormFile(name)
}
// ReqFiles 获取多个同名上传文件(批量上传场景)
// 用法: files, err := that.ReqFiles("images")
func (that *Context) ReqFiles(name string) ([]*multipart.FileHeader, error) {
if that.Req.MultipartForm == nil {
if err := that.Req.ParseMultipartForm(32 << 20); err != nil {
return nil, err
}
}
if that.Req.MultipartForm == nil || that.Req.MultipartForm.File == nil {
return nil, http.ErrMissingFile
}
files, ok := that.Req.MultipartForm.File[name]
if !ok {
return nil, http.ErrMissingFile
}
return files, nil
}