// Package thirdParty // @Author 铁憨憨[cory] 2025/7/4 14:06:00 package thirdParty import ( "bytes" "context" "crypto/rand" "crypto/rsa" "crypto/x509" "encoding/base64" "encoding/json" "fmt" "github.com/gogf/gf/v2/frame/g" "github.com/tiger1103/gfast-cache/cache" commonService "github.com/tiger1103/gfast/v3/internal/app/common/service" "github.com/tiger1103/gfast/v3/library/liberr" "net/http" "time" ) /* 第三方接口: 1、获取token 2、推送第三方数据 3、获取第三方数据 */ const publicKeyBase64 = `MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCoaejbjbttHyHuEzHL8lIX5GZZ6zIYrqJpEDlPM4V5LHn19rSAYp2FyAr8y5Ctny9uUdaYbkoFiVQgxWrAYo4X/3O0OFDsowE25FMOLQY0Mn5B6CvVR7Sdt3DqzIzM1tUnJCIbVGNfDMgxLrLwFN8RvOW8MPlB6LgOvlGMDbj+OQIDAQAB` type LoginRequest struct { Username string `json:"username"` Password string `json:"password"` } type LoginResponse struct { Code int `json:"code"` Msg string `json:"msg"` Token string `json:"token"` } // CheckIfThereAreTokens redis中获取token,没有就获取 func CheckIfThereAreTokens(ctx context.Context) (token string, err error) { key := "thirdParty:tiandon:token" prefix := g.Cfg().MustGet(ctx, "system.cache.prefix").String() gfCache := cache.New(prefix) get, err := g.Redis().Get(ctx, gfCache.CachePrefix+key) if err != nil && get.String() != "" { token = get.String() return token, err } else { token, err = getTheToken(ctx) //过期时间为30分钟(1800秒),我这里少300秒,防止过期 commonService.Cache().Set(ctx, key, token, time.Duration(1500)*time.Second) return token, err } } // getTheToken token获取 func getTheToken(ctx context.Context) (token string, err error) { err = g.Try(ctx, func(ctx g.Ctx) { // 1、构造加密密码 encryptedPassword, err := rsaEncryptWithBase64PublicKey([]byte("Hkrsoft@#2023"), publicKeyBase64) if err != nil { liberr.ErrIsNil(ctx, err, "密码加密失败") } // 2、构造 JSON 请求体 data, _ := json.Marshal(LoginRequest{ Username: "zhangweiwei", Password: encryptedPassword, }) // 3、构造 HTTP 请求 req, _ := http.NewRequest("POST", "https://claritypm.powerchina.cn/neSmartsite-api/loginCli", bytes.NewReader(data)) req.Header.Set("Content-Type", "application/json; charset=UTF-8") req.Header.Set("User-Agent", "Mozilla/5.0") req.Header.Set("Accept", "application/json") req.Header.Set("Origin", "https://claritypm.powerchina.cn") req.Header.Set("Referer", "https://claritypm.powerchina.cn/") // 4、发送请求 resp, err := http.DefaultClient.Do(req) if err != nil { liberr.ErrIsNil(ctx, err, "推送第三方数据失败") } defer resp.Body.Close() // 5、解析响应体 var result LoginResponse if err := json.NewDecoder(resp.Body).Decode(&result); err != nil { liberr.ErrIsNil(ctx, err, "解析第三方数据失败") } token = result.Token }) return } // rsaEncryptWithBase64PublicKey RSA加密函数 func rsaEncryptWithBase64PublicKey(data []byte, base64PubKey string) (string, error) { decoded, err := base64.StdEncoding.DecodeString(base64PubKey) if err != nil { return "", err } pubInterface, err := x509.ParsePKIXPublicKey(decoded) if err != nil { return "", err } pub := pubInterface.(*rsa.PublicKey) encrypted, err := rsa.EncryptPKCS1v15(rand.Reader, pub, data) if err != nil { return "", err } return base64.StdEncoding.EncodeToString(encrypted), nil } type RealUser struct { UserName string `json:"userName"` ClassManagerFlag string `json:"classManagerFlag,omitempty"` Phone string `json:"phone"` Sex string `json:"sex"` CardType string `json:"cardType"` CardNumber string `json:"cardNumber"` UserType string `json:"userType"` CardDept string `json:"cardDept,omitempty"` Nation string `json:"nation,omitempty"` Birthday string `json:"birthday,omitempty"` // 格式:2025-01-01 00:00:00 Address string `json:"address,omitempty"` Avatar string `json:"avatar,omitempty"` // 限一张 http 地址 Pic string `json:"pic,omitempty"` // 限一张 http 地址 SafetyEdu string `json:"safetyEdu,omitempty"` // 限一张 http 地址 Technology string `json:"technology,omitempty"` // 限一张 http 地址 CardStartTime string `json:"cardStartTime,omitempty"` // 格式:2025-01-01 00:00:00 CardEndTime string `json:"cardEndTime,omitempty"` StudyLevel string `json:"studyLevel,omitempty"` PoliticsType string `json:"politicsType,omitempty"` InsuranceFlag string `json:"insuranceFlag,omitempty"` DiseaseFlag string `json:"diseaseFlag,omitempty"` LaborContractFlag string `json:"laborContractFlag,omitempty"` Contacts string `json:"contacts,omitempty"` ContactsPhone string `json:"contactsPhone,omitempty"` MarryRemark string `json:"marryRemark,omitempty"` } // SendRy 发送工人信息 func SendRy(ctx context.Context, user []*RealUser) (err error) { err = g.Try(ctx, func(ctx context.Context) { //1、获取token token, err := CheckIfThereAreTokens(ctx) liberr.ErrIsNil(ctx, err, "获取token失败") // 2、创建请求 jsonData, _ := json.Marshal(user) fmt.Println(":::::::::::::::::::::: " + string(jsonData)) req, err := http.NewRequest("POST", "https://claritypm.powerchina.cn/neSmartsite-api/realUser/tiandong/insertRealUser", bytes.NewReader(jsonData), ) liberr.ErrIsNil(ctx, err, "创建客户端失败") // 3、设置请求头 req.Header.Set("Content-Type", "application/json") req.Header.Set("Authorization", "Bearer "+token) req.Header.Set("User-Agent", "Mozilla/5.0") req.Header.Set("Accept", "application/json") // 4、发送请求 resp, err := http.DefaultClient.Do(req) if err != nil { liberr.ErrIsNil(ctx, err, "发送数据到第三方失败") return } defer resp.Body.Close() var result LoginResponse if err := json.NewDecoder(resp.Body).Decode(&result); err != nil { liberr.ErrIsNil(ctx, err, "解析第三方数据失败") } fmt.Println("l111响应状态码:", result.Code) fmt.Println("c222响应内容:", result.Msg) }) return err }