package ctx import ( "encoding/json" "fmt" "io" "net/http" "net/url" "os" "path/filepath" "strings" "ems.agt/lib/core/vo" commonConstants "ems.agt/src/framework/constants/common" tokenConst "ems.agt/src/framework/constants/token" "github.com/gorilla/mux" ) // Param 地址栏参数{id} func Param(r *http.Request, key string) string { vars := mux.Vars(r) v, ok := vars[key] if ok { return v } return "" } // GetQuery 查询参数 func GetQuery(r *http.Request, key string) string { return r.URL.Query().Get(key) } // QueryMap 查询参数转换Map func QueryMap(r *http.Request) map[string]any { queryValues := r.URL.Query() queryParams := make(map[string]any) for key, values := range queryValues { queryParams[key] = values[0] } return queryParams } // 读取json请求结构团体 func ShouldBindJSON(r *http.Request, args any) error { body, err := io.ReadAll(io.LimitReader(r.Body, 1<<20)) // 设置较大的长度,例如 1<<20 (1MB) if err != nil { return err } err = json.Unmarshal(body, args) return err } // JSON 相应json数据 func JSON(w http.ResponseWriter, code int, data any) { w.Header().Set("Content-Type", "application/json;charset=UTF-8") response, err := json.Marshal(data) if err != nil { w.WriteHeader(500) w.Write([]byte(err.Error())) } else { w.WriteHeader(code) w.Write(response) } } // 将文件导出到外部下载 func FileAttachment(w http.ResponseWriter, r *http.Request, filepath, filename string) { w.Header().Set("Content-Disposition", `attachment; filename=`+url.QueryEscape(filename)) w.Header().Set("Content-Type", "application/octet-stream") http.ServeFile(w, r, filepath) } // 将文件上传保存到指定目录 // file, handler, err := r.FormFile("file") // SaveUploadedFile uploads the form file to specific dst. func SaveUploadedFile(r *http.Request, dst string) error { // 解析请求中的文件 _, handler, err := r.FormFile("file") if err != nil { return err } src, err := handler.Open() if err != nil { return err } defer src.Close() if err = os.MkdirAll(filepath.Dir(dst), 0750); err != nil { return err } out, err := os.Create(dst) if err != nil { return err } defer out.Close() _, err = io.Copy(out, src) return err } /// ==== 登录用户信息, 通过中间件后预置入 // Authorization 解析请求头 func Authorization(r *http.Request) string { authHeader := r.Header.Get(tokenConst.HEADER_KEY) if authHeader == "" { return "" } // 拆分 Authorization 请求头,提取 JWT 令牌部分 arr := strings.Split(authHeader, tokenConst.HEADER_PREFIX) if len(arr) == 2 && arr[1] == "" { return "" } return arr[1] } // 定义自定义类型作为键 type ContextKey string // LoginUser 登录用户信息需要Authorize中间件 func LoginUser(r *http.Request) (vo.LoginUser, error) { // 上下文 v := r.Context().Value(ContextKey(commonConstants.CTX_LOGIN_USER)) if v != nil { return v.(vo.LoginUser), nil } return vo.LoginUser{}, fmt.Errorf("No user information") } // LoginUserToUserID 登录用户信息-用户ID func LoginUserToUserID(r *http.Request) string { loginUser, err := LoginUser(r) if err != nil { return "" } return loginUser.UserID } // LoginUserToUserName 登录用户信息-用户名称 func LoginUserToUserName(r *http.Request) string { loginUser, err := LoginUser(r) if err != nil { return "" } return loginUser.UserName }