| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336 |
- package utils
- import (
- "crypto/hmac"
- "crypto/sha256"
- "encoding/hex"
- "encoding/json"
- "fmt"
- "git.sxidc.com/student-physical-examination/contract_lock_sdk/commons"
- "git.sxidc.com/student-physical-examination/contract_lock_sdk/config"
- "git.sxidc.com/student-physical-examination/contract_lock_sdk/constant"
- "git.sxidc.com/student-physical-examination/contract_lock_sdk/http"
- "github.com/tjfoc/gmsm/sm3"
- "io/ioutil"
- "log"
- "os"
- "reflect"
- "strconv"
- "strings"
- )
- type SdkClient struct {
- ServerUrl string
- AccessToken string
- AccessSecret string
- SignatureVersion string
- TraceId string
- IdempotentToken string
- EnableNonce bool
- CustomHeaders map[string]string
- ProxyInfo *config.ProxyInfo
- }
- func NewSdkClient(serverUrl string, accessToken string, accessSecret string) *SdkClient {
- sdkClient := SdkClient{
- ServerUrl: serverUrl,
- AccessToken: accessToken,
- AccessSecret: accessSecret,
- SignatureVersion: commons.MD5,
- EnableNonce: true,
- }
- return &sdkClient
- }
- // 返回字符串
- func (sdk *SdkClient) ServiceAsString(request SdkRequest) string {
- return sdk.SdkRequest(request)
- }
- // 只返回code、message
- func (sdk *SdkClient) Service(request SdkRequest) *SdkResponse {
- jsonStr := sdk.SdkRequest(request)
- response := SdkResponse{}
- var jsonObj map[string]interface{}
- if err := json.Unmarshal([]byte(jsonStr), &jsonObj); err != nil {
- log.Println("Error parsing JSON:", err)
- return &response
- }
- codeStr := fmt.Sprintf("%v", jsonObj["code"])
- code, _ := strconv.ParseInt(codeStr, 10, 64)
- response.Code = code
- response.Message = jsonObj["message"].(string)
- response.ResultStream = false
- return &response
- }
- // code、message、result(包括基本类型和对象类型和对象数组类型)
- func (sdk *SdkClient) ServiceAsModel(request SdkRequest, obj interface{}) *SdkResponse {
- jsonStr := sdk.SdkRequest(request)
- response := SdkResponse{}
- var jsonObj map[string]interface{}
- if err := json.Unmarshal([]byte(jsonStr), &jsonObj); err != nil {
- log.Println("Error parsing JSON:", err)
- return &response
- }
- codeStr := fmt.Sprintf("%v", jsonObj["code"])
- code, _ := strconv.ParseInt(codeStr, 10, 64)
- response.Code = code
- response.Message = jsonObj["message"].(string)
- response.ResultStream = false
- delete(jsonObj, "code")
- delete(jsonObj, "message")
- num := len(jsonObj)
- // 返回结果只存在code、message
- if num == 0 {
- return &response
- }
- //处理返回值为code、message、result(基础类型)
- basicType := isBasicType(obj)
- if basicType {
- // 检查是否存在某个键
- value, exists := constant.BASICS_TYPE[request.GetUrl()]
- if exists {
- result, _ := jsonObj[value]
- response.Result = result
- } else {
- for _, result := range jsonObj {
- response.Result = result
- }
- }
- return &response
- }
- //处理返回值为code、message、result(对象类型)
- // 返回结果除去code、message之后,只有一个字段,可能出现的结果如下:
- // 1、基本类型
- // 2、对象类型
- var resultData interface{}
- if num == 1 {
- for key, value := range jsonObj {
- valueType := reflect.ValueOf(value).Kind()
- if valueType == reflect.Map {
- resultData = value
- } else {
- flag := commons.IsPropertyExists(obj, key)
- if flag {
- resultData = jsonObj
- }
- }
- jsonBytes, _ := json.Marshal(resultData)
- json.Unmarshal(jsonBytes, obj)
- response.Result = obj
- return &response
- }
- }
- //处理返回值为code、message、result1(任意类型)、result2(任意类型)【将result1、result2封装为一个对象中的两个字段】
- if num > 1 {
- fieldName, exists := constant.EXTRA_FIELD[request.GetUrl()]
- if exists {
- result, _ := jsonObj[fieldName]
- switch reflect.TypeOf(result).Kind() {
- case reflect.Map:
- if resultMap, ok := result.(map[string]interface{}); ok {
- for key, value := range jsonObj {
- if fieldName != key {
- resultMap[key] = value
- }
- }
- resultData = resultMap
- }
- case reflect.Slice:
- if resultList, ok := result.([]interface{}); ok {
- for _, value := range resultList {
- if resultMap, ok := value.(map[string]interface{}); ok {
- for key, value := range jsonObj {
- if fieldName != key {
- resultMap[key] = value
- }
- }
- }
- }
- resultData = result
- }
- }
- } else {
- resultData = jsonObj
- }
- }
- jsonBytes, _ := json.Marshal(resultData)
- json.Unmarshal(jsonBytes, obj)
- response.Result = obj
- return &response
- }
- // 文件下载
- func (sdk *SdkClient) Download(request SdkRequest, file *os.File) *SdkResponse {
- if strings.HasSuffix(sdk.ServerUrl, "/") {
- sdk.ServerUrl = sdk.ServerUrl[:len(sdk.ServerUrl)-1]
- }
- url := sdk.ServerUrl + request.GetUrl()
- parameter := request.GetHttpParameter()
- header := sdk.buildHttpHeader(parameter)
- jsonStr := ""
- if parameter.IsJson() {
- jsonStr = http.DoDownloadWithJson(url, parameter, header, file, sdk.ProxyInfo)
- } else {
- jsonStr = http.DoDownload(url, parameter, header, file, sdk.ProxyInfo)
- }
- response := SdkResponse{}
- if len(jsonStr) <= 0 {
- response.Code = 0
- response.Message = "SUCCESS"
- response.ResultStream = true
- return &response
- }
- response.ResultStream = false
- var jsonObj map[string]interface{}
- if err := json.Unmarshal([]byte(jsonStr), &jsonObj); err != nil {
- log.Println("Error parsing JSON:", err)
- return &response
- }
- codeStr := fmt.Sprintf("%v", jsonObj["code"])
- code, _ := strconv.ParseInt(codeStr, 10, 64)
- response.Code = code
- response.Message = jsonObj["message"].(string)
- delete(jsonObj, "code")
- delete(jsonObj, "message")
- num := len(jsonObj)
- // 返回结果只存在code、message
- if num == 0 {
- return &response
- }
- var resultObj interface{}
- for _, result := range jsonObj {
- resultObj = result
- }
- resultData, _ := json.Marshal(resultObj)
- reflectObj, exists := constant.STREAM_RESULT[request.GetUrl()]
- if exists {
- personValue := reflect.New(reflectObj).Elem()
- err := json.Unmarshal(resultData, personValue.Addr().Interface())
- if err != nil {
- fmt.Println("Error unmarshalling JSON:", err)
- return &response
- }
- obj := personValue.Interface()
- response.Result = obj
- return &response
- }
- return &response
- }
- func (sdk *SdkClient) SdkRequest(request SdkRequest) string {
- if strings.HasSuffix(sdk.ServerUrl, "/") {
- sdk.ServerUrl = sdk.ServerUrl[:len(sdk.ServerUrl)-1]
- }
- url := sdk.ServerUrl + request.GetUrl()
- parameter := request.GetHttpParameter()
- header := sdk.buildHttpHeader(parameter)
- if parameter.IsJson() {
- return http.DoServiceWithJson(url, parameter, header, sdk.ProxyInfo)
- }
- return http.DoService(url, parameter, header, sdk.ProxyInfo)
- }
- func (sdk *SdkClient) buildHttpHeader(httpParameter *http.HttpParameter) *http.HttpHeader {
- timestamp := commons.GetTimeStamp()
- nonce := ""
- if sdk.EnableNonce {
- nonce = commons.GetUUID()
- }
- var signature string
- if commons.HMACSHA256 == sdk.SignatureVersion {
- hmacSignatureList := make([]ParameterBody, 0)
- hmacSignatureList = append(hmacSignatureList, NewStringParameter(commons.ACCESS_TOKEN, sdk.AccessToken))
- hmacSignatureList = append(hmacSignatureList, NewStringParameter(commons.TIMESTAMP, timestamp))
- hmacSignatureList = append(hmacSignatureList, NewStringParameter(commons.NONCE, nonce))
- hmacSignatureList = append(hmacSignatureList, NewStringParameter(commons.SIGNATURE_VERSION, sdk.SignatureVersion))
- hmacSignatureList = append(hmacSignatureList, NewStringParameter(commons.IDEMPOTENTTOKEN, sdk.IdempotentToken))
- hmacSignatureList = append(hmacSignatureList, NewStringParameter(commons.TRACEID, sdk.TraceId))
- if httpParameter.IsJson() {
- hmacSignatureList = append(hmacSignatureList, NewStringParameter(commons.BODY, httpParameter.JsonParamer()))
- } else {
- hmacSignatureList = append(hmacSignatureList, NewStringParameter(commons.BODY, ""))
- params := httpParameter.Params()
- for key, value := range params {
- if commons.IsNil(value) {
- continue
- }
- switch t := value.(type) {
- case string:
- if len(t) != 0 {
- hmacSignatureList = append(hmacSignatureList, NewStringParameter(key, fmt.Sprintf("%v", t)))
- }
- case *int, *int32, *int64:
- if f, ok := value.(*int64); ok {
- hmacSignatureList = append(hmacSignatureList, NewStringParameter(key, fmt.Sprintf("%d", *f)))
- }
- case *float32, *float64:
- if f, ok := value.(*float64); ok {
- hmacSignatureList = append(hmacSignatureList, NewStringParameter(key, fmt.Sprintf("%f", *f)))
- }
- case *bool:
- if f, ok := value.(*bool); ok {
- hmacSignatureList = append(hmacSignatureList, NewStringParameter(key, fmt.Sprintf("%t", *f)))
- }
- default:
- hmacSignatureList = append(hmacSignatureList, NewStringParameter(key, fmt.Sprintf("%v", value)))
- }
- }
- files := httpParameter.Files()
- for key, file := range files {
- defer file.Close()
- bytes, _ := ioutil.ReadAll(file)
- hmacSignatureList = append(hmacSignatureList, NewBytesParameter(key, bytes))
- }
- listFiles := httpParameter.ListFiles()
- for key, fileList := range listFiles {
- for _, file := range fileList {
- defer file.Close()
- bytes, _ := ioutil.ReadAll(file)
- hmacSignatureList = append(hmacSignatureList, NewBytesParameter(key, bytes))
- }
- }
- }
- signature = sdk.CalculateSignature(httpParameter.HttpMethod(), hmacSignatureList)
- } else if commons.SM3 == sdk.SignatureVersion {
- rawSig := sdk.AccessToken + sdk.AccessSecret + timestamp + nonce
- hash := sm3.New()
- hash.Write([]byte(rawSig))
- result := hash.Sum(nil)
- signature = hex.EncodeToString(result)
- } else {
- signature = commons.GetMD5(sdk.AccessToken + sdk.AccessSecret + timestamp + nonce)
- }
- header := http.HttpHeader{
- AccessToken: sdk.AccessToken,
- Timestamp: timestamp,
- Nonce: nonce,
- Signature: signature,
- SignatureVersion: sdk.SignatureVersion,
- TraceId: sdk.TraceId,
- IdempotentToken: sdk.IdempotentToken,
- CustomHeaders: sdk.CustomHeaders,
- }
- return &header
- }
- func (sdk *SdkClient) CalculateSignature(method string, hmacSignatureList []ParameterBody) string {
- SortParameterBody(hmacSignatureList)
- mac := hmac.New(sha256.New, []byte(sdk.AccessSecret))
- mac.Write([]byte(method))
- for _, parameterBody := range hmacSignatureList {
- str := commons.CONNECTOR + parameterBody.Name + commons.EQUALSIGN
- mac.Write([]byte(str))
- if parameterBody.Bytes != nil {
- mac.Write(parameterBody.Bytes)
- }
- }
- sum := mac.Sum(nil)
- hexMac := make([]byte, len(sum)*2)
- hex.Encode(hexMac, sum)
- return fmt.Sprintf("%s", hexMac)
- }
|