package ctx import ( "encoding/json" "fmt" "io" "net/http" "net/url" "os" "path/filepath" "strings" "be.ems/src/framework/constants" "be.ems/src/framework/token" "github.com/gorilla/mux" ) // GetParam 地址栏参数{id} func GetParam(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) } // GetHeader 请求头参数 func GetHeader(r *http.Request, key string) string { return r.Header.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 } // ShouldBindQuery 查询参数读取json请求结构团体 &xxx func ShouldBindQuery(r *http.Request, args any) error { queryParams := QueryMap(r) body, err := json.Marshal(queryParams) if err != nil { return err } return json.Unmarshal(body, args) } // ShouldBindJSON 读取json请求结构团体 &xxx 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 { // Query请求查询 if authQuery := r.URL.Query().Get(constants.ACCESS_TOKEN); authQuery != "" { return authQuery } // Header请求头 if authHeader := r.Header.Get(constants.ACCESS_TOKEN); authHeader != "" { return authHeader } // Query请求查询 if authQuery := r.URL.Query().Get(constants.ACCESS_TOKEN_QUERY); authQuery != "" { return authQuery } // Header请求头 authHeader := r.Header.Get(constants.HEADER_KEY) if authHeader == "" { return "" } // 拆分 Authorization 请求头,提取 JWT 令牌部分 tokenStr := strings.Replace(authHeader, constants.HEADER_PREFIX, "", 1) if len(tokenStr) > 64 { return strings.TrimSpace(tokenStr) // 去除可能存在的空格 } return "" } // ContextKey 定义自定义类型作为键 type ContextKey string // LoginUser 登录用户信息需要Authorize中间件 func LoginUser(r *http.Request) (token.UserInfo, error) { // 获取请求头标识信息 tokenStr := Authorization(r) if tokenStr == "" { return token.UserInfo{}, fmt.Errorf("not token info") } if tokenStr == "" { return token.UserInfo{}, fmt.Errorf("authorization token is empty") } // 验证令牌 claims, err := token.UserTokenVerify(tokenStr, "access") if err != nil { return token.UserInfo{}, err } // 获取缓存的用户信息 info := token.UserInfoGet(claims) if info.UserId <= 0 { return token.UserInfo{}, fmt.Errorf("invalid login user information") } return info, nil } // LoginUserToUserName 登录用户信息-用户名称 func LoginUserToUserName(r *http.Request) string { loginUser, err := LoginUser(r) if err != nil { return "" } return loginUser.User.UserName }