From 252fa4683bb957ec7ebb689f9376a2c3c91b4531 Mon Sep 17 00:00:00 2001 From: junleea <354425203@qq.com> Date: Sun, 1 Jun 2025 16:34:37 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BD=BF=E7=94=A8=E7=94=A8=E6=88=B7=E4=B8=AD?= =?UTF-8?q?=E5=BF=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- handler/cid.go | 7 +- main.go | 8 +- service/userService.go | 66 +++++++++++++ worker/req.go | 220 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 295 insertions(+), 6 deletions(-) diff --git a/handler/cid.go b/handler/cid.go index ca79ba8..2154dc5 100644 --- a/handler/cid.go +++ b/handler/cid.go @@ -11,6 +11,7 @@ import ( "time" "videoplayer/dao" "videoplayer/proto" + "videoplayer/service" "videoplayer/worker" ) @@ -62,7 +63,8 @@ func RunCID(c *gin.Context) { id, _ := c.Get("id") authID := int(id.(float64)) //获取权限 - user := dao.FindUserByUserID(authID) + //user := dao.FindUserByUserID(authID) + user := service.GetUserByIDFromUserCenter(authID) if user.Run == false { c.JSON(200, gin.H{"error": "no run Permissions", "code": proto.NoRunPermissions, "message": "no run Permissions"}) return @@ -197,7 +199,8 @@ func CIDCallback(c *gin.Context) { return } - user := dao.FindUserByUserID(res.Auth_id) + //user := dao.FindUserByUserID(res.Auth_id) + user := service.GetUserByIDFromUserCenter(res.Auth_id) if user.Run == false { c.JSON(200, gin.H{"error": "no run Permissions", "code": proto.NoRunPermissions, "message": "the user has no run Permissions"}) return diff --git a/main.go b/main.go index 5f00575..d9674d0 100644 --- a/main.go +++ b/main.go @@ -31,9 +31,9 @@ func main() { panic("failed to connect redis:" + err.Error()) } r.Use(handler.CrosHandler()) - r.Use(JWTAuthMiddleware()) // 使用 JWT 认证中间件 - handler.SetUpVideoGroup(r) // Video - handler.SetUpUserGroup(r) // User + r.Use(JWTAuthMiddleware()) // 使用 JWT 认证中间件 + handler.SetUpVideoGroup(r) // Video + //handler.SetUpUserGroup(r) // User handler.SetUpDeviceGroup(r) // Device handler.SetUpIMGroup(r) // IM handler.SetUpCIDGroup(r) // CID,持续集成、部署 @@ -351,7 +351,7 @@ func RunGeneralCron() { // 用户功能拦截,返回true表示拦截,false表示不拦截 func UserFuncIntercept(id int, url string) bool { //先查看是否有权限 - user := dao.FindUserByUserID(id) + user := service.GetUserByIDFromUserCenter(id) //如果用户有权限,则不拦截 for k, v := range proto.Per_menu_map { if strings.Contains(url, k) { diff --git a/service/userService.go b/service/userService.go index 6cf4e86..e2585dd 100644 --- a/service/userService.go +++ b/service/userService.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "github.com/golang-jwt/jwt" + "log" "regexp" "strconv" "time" @@ -400,3 +401,68 @@ func CreateTokenAndSave(user dao.User) (string, error) { // 返回令牌 return tokenString, err } + +// 获取用户信息,有redis缓存 +func GetUserByIDFromUserCenter(id int) dao.User { + if id <= 0 { + return dao.User{} + } + var user dao.User + //先从redis获取 + key := "user_info_" + strconv.Itoa(id) + user_str := worker.GetRedis(key) + if user_str != "" { + err := json.Unmarshal([]byte(user_str), &user) + if err != nil { + fmt.Println("get user info , json unmarshal error:", err, "\tuser_str:", user_str) + return dao.User{} + } + } else { + user = GetUserInfoByIDFromUserCenterHttp(id) + if user.ID != 0 { + userJson, err := json.Marshal(user) + if err != nil { + fmt.Println("get user info , json marshal error:", err) + return dao.User{} + } + success := worker.SetRedisWithExpire(key, string(userJson), time.Second*10) + if !success { + fmt.Println("set redis error,user json:", string(userJson)) + } + } + } + return user +} + +type UserInfoResponse struct { + Code int `json:"code"` + Message string `json:"message"` + Data dao.User `json:"data"` +} + +func GetUserInfoByIDFromUserCenterHttp(id int) dao.User { + var resp UserInfoResponse + url := "https://uc.ljsea.top/user/info?super_id=1" + tokens := worker.GetRedisSetMembers("super_permission_tokens") + if len(tokens) == 0 { + return resp.Data + } + token := tokens[0] + //请求参数 + req := map[string]int{ + "id": id, + } + headers := map[string]string{ + "token": token, + } + reqByte, _ := json.Marshal(req) + err, respBytes := worker.DoPostRequestJSON(url, reqByte, headers) + if err != nil { + log.Println("GetUserInfoByIDFromUserCenterHttp error:", err) + return resp.Data + } + if err2 := json.Unmarshal(respBytes, &resp); err2 != nil { + log.Println("GetUserInfoByIDFromUserCenterHttp json unmarshal error:", err2) + } + return resp.Data +} diff --git a/worker/req.go b/worker/req.go index 56615cb..bff6bc9 100644 --- a/worker/req.go +++ b/worker/req.go @@ -6,7 +6,11 @@ import ( "fmt" "io" "io/ioutil" + "log" + "mime/multipart" "net/http" + "net/url" + "strconv" "strings" "videoplayer/dao" "videoplayer/proto" @@ -279,3 +283,219 @@ func SyncDataFromMasterShellReq3(url string, data proto.SyncUserShellResp) ([]pr res = response.Data return res, nil } + +func DoPostRequestJSON(url string, jsonData []byte, headers map[string]string) (error, []byte) { + httpClient := &http.Client{} + defer func() { + if r := recover(); r != nil { + fmt.Println("SyncDataFromMasterReq2 error:", r) + } + }() + + //从接口获取数据 + req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData)) + if err != nil { + return err, nil + } + req.Header.Set("Content-Type", "application/json") + req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36 Edg/136.0.0.0") + //设置header + for k, v := range headers { + req.Header.Set(k, v) + } + //传输数据 + if httpClient == nil { + httpClient = &http.Client{} + } + //获取数据 + resp, err := httpClient.Do(req) + if err != nil { + return err, nil + } + defer resp.Body.Close() + //解析数据 + responseBod, err := io.ReadAll(resp.Body) + if err != nil { + return err, nil + } + return err, responseBod +} + +func DoPostRequestForm(url string, jsonData []byte, headers map[string]string) (error, []byte) { + httpClient := &http.Client{} + defer func() { + if r := recover(); r != nil { + fmt.Println("SyncDataFromMasterReq2 error:", r) + } + }() + + // 创建一个新的 buffer 用于存储 multipart/form-data 请求体 + body := &bytes.Buffer{} + writer := multipart.NewWriter(body) + // 修改 data 类型为 map[string]interface{} 以支持不同类型的值 + var data map[string]interface{} + err2 := json.Unmarshal(jsonData, &data) + if err2 != nil { + log.Println("do post json unmarshal error:", err2) + return err2, nil + } + + var err error + for k, v := range data { + switch val := v.(type) { + case bool: + // 处理布尔类型的值 + err = writer.WriteField(k, strconv.FormatBool(val)) + case string: + // 处理字符串类型的值 + err = writer.WriteField(k, val) + default: + // 其他类型可以根据需要扩展处理逻辑 + log.Printf("Unsupported type for field %s: %T\n", k, v) + continue + } + if err != nil { + log.Println("write field error:", err) + return err, nil + } + } + + // 关闭 writer 以完成请求体的构建 + err = writer.Close() + if err != nil { + return err, nil + } + + // 创建 POST 请求 + req, err := http.NewRequest("POST", url, body) + req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36 Edg/136.0.0.0") + if err != nil { + return err, nil + } + + // 设置 Content-Type 为 multipart/form-data,并带上 boundary + req.Header.Set("Content-Type", writer.FormDataContentType()) + + // 设置其他自定义请求头 + for k, v := range headers { + req.Header.Set(k, v) + } + + // 发送请求 + resp, err := httpClient.Do(req) + if err != nil { + return err, nil + } + defer resp.Body.Close() + + // 读取响应体 + responseBod, err := io.ReadAll(resp.Body) + if err != nil { + return err, nil + } + + return nil, responseBod +} + +func DoPostRequestFormUrlEncoded(url_ string, jsonData []byte, headers map[string]string) (error, []byte) { + httpClient := &http.Client{} + defer func() { + if r := recover(); r != nil { + log.Println("SyncDataFromMasterReq2 error:", r) + } + }() + + // 解析 JSON 数据 + var data map[string]interface{} + err := json.Unmarshal(jsonData, &data) + if err != nil { + log.Println("do post json unmarshal error:", err) + return err, nil + } + + // 创建 url.Values 来存储请求参数 + reqData := url.Values{} + for k, v := range data { + switch val := v.(type) { + case bool: + // 处理布尔类型的值 + reqData.Set(k, strconv.FormatBool(val)) + case string: + // 处理字符串类型的值 + reqData.Set(k, val) + default: + // 其他类型可以根据需要扩展处理逻辑 + log.Printf("Unsupported type for field %s: %T\n", k, v) + continue + } + } + + // 将 url.Values 编码为 URL 编码的格式 + encodedData := reqData.Encode() + + // 创建 POST 请求 + req, err := http.NewRequest("POST", url_, bytes.NewBufferString(encodedData)) + if err != nil { + return err, nil + } + + // 设置请求头 + req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36 Edg/136.0.0.0") + req.Header.Set("Content-Type", "application/x-www-form-urlencoded") + + // 设置其他自定义请求头 + for k, v := range headers { + req.Header.Set(k, v) + } + + // 发送请求 + resp, err := httpClient.Do(req) + if err != nil { + return err, nil + } + defer resp.Body.Close() + + // 读取响应体 + responseBod, err := io.ReadAll(resp.Body) + if err != nil { + return err, nil + } + + return nil, responseBod +} + +func DoGetRequest(url string, headers map[string]string) (error, []byte) { + httpClient := &http.Client{} + defer func() { + if r := recover(); r != nil { + fmt.Println("SyncDataFromMasterReq2 error:", r) + } + }() + + //从接口获取数据 + req, err := http.NewRequest("GET", url, nil) + req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36 Edg/136.0.0.0") + if err != nil { + return err, nil + } + //设置header + for k, v := range headers { + req.Header.Set(k, v) + } + //传输数据 + if httpClient == nil { + httpClient = &http.Client{} + } + //获取数据 + resp, err := httpClient.Do(req) + if err != nil { + return err, nil + } + defer resp.Body.Close() + //解析数据 + responseBod, err := io.ReadAll(resp.Body) + if err != nil { + return err, nil + } + return err, responseBod +}