218 lines
5.0 KiB
Go
218 lines
5.0 KiB
Go
package ctx
|
||
|
||
import (
|
||
"encoding/json"
|
||
"fmt"
|
||
"io"
|
||
"net/http"
|
||
"net/url"
|
||
"os"
|
||
"path/filepath"
|
||
"strings"
|
||
|
||
"be.ems/src/framework/constants/token"
|
||
tokenUtils "be.ems/src/framework/utils/token"
|
||
"be.ems/src/framework/vo"
|
||
"github.com/gorilla/mux"
|
||
"golang.org/x/text/language"
|
||
)
|
||
|
||
// 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)
|
||
}
|
||
|
||
// 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请求结构团体
|
||
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)
|
||
}
|
||
|
||
// 读取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 {
|
||
// Query请求查询
|
||
if authQuery := r.URL.Query().Get(token.ACCESS_TOKEN); authQuery != "" {
|
||
return authQuery
|
||
}
|
||
// Header请求头
|
||
if authHeader := r.Header.Get(token.ACCESS_TOKEN); authHeader != "" {
|
||
return authHeader
|
||
}
|
||
|
||
// Query请求查询
|
||
if authQuery := r.URL.Query().Get(token.RESPONSE_FIELD); authQuery != "" {
|
||
return authQuery
|
||
}
|
||
// Header请求头
|
||
authHeader := r.Header.Get(token.HEADER_KEY)
|
||
if authHeader == "" {
|
||
return ""
|
||
}
|
||
// 拆分 Authorization 请求头,提取 JWT 令牌部分
|
||
arr := strings.Split(authHeader, token.HEADER_PREFIX)
|
||
if len(arr) == 2 && arr[1] == "" {
|
||
return ""
|
||
}
|
||
return arr[1]
|
||
}
|
||
|
||
// AcceptLanguage 解析客户端接收语言 zh:中文 en: 英文
|
||
func AcceptLanguage(r *http.Request) string {
|
||
preferredLanguage := language.English
|
||
|
||
// Query请求查询
|
||
if v := GetQuery(r, "language"); v != "" {
|
||
tags, _, _ := language.ParseAcceptLanguage(v)
|
||
if len(tags) > 0 {
|
||
preferredLanguage = tags[0]
|
||
}
|
||
}
|
||
// Header请求头
|
||
if v := GetHeader(r, "Accept-Language"); v != "" {
|
||
tags, _, _ := language.ParseAcceptLanguage(v)
|
||
if len(tags) > 0 {
|
||
preferredLanguage = tags[0]
|
||
}
|
||
}
|
||
|
||
// 只取前缀
|
||
lang := preferredLanguage.String()
|
||
arr := strings.Split(lang, "-")
|
||
return arr[0]
|
||
}
|
||
|
||
// ContextKey 定义自定义类型作为键
|
||
type ContextKey string
|
||
|
||
// LoginUser 登录用户信息需要Authorize中间件
|
||
func LoginUser(r *http.Request) (vo.LoginUser, error) {
|
||
// 获取请求头标识信息
|
||
tokenStr := Authorization(r)
|
||
if tokenStr == "" {
|
||
return vo.LoginUser{}, fmt.Errorf("not token info")
|
||
}
|
||
// 验证令牌
|
||
claims, err := tokenUtils.Verify(tokenStr)
|
||
if err != nil {
|
||
return vo.LoginUser{}, fmt.Errorf("token verify fail")
|
||
}
|
||
|
||
// 获取缓存的用户信息
|
||
loginUser := tokenUtils.LoginUser(claims)
|
||
if loginUser.UserID == "" {
|
||
return vo.LoginUser{}, fmt.Errorf("not user info")
|
||
}
|
||
|
||
return loginUser, nil
|
||
}
|
||
|
||
// 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.User.UserName
|
||
}
|