package maycur import ( "crypto/sha256" "encoding/hex" "encoding/json" "fmt" "hongze/hz_crm_api/services/alarm_msg" "hongze/hz_crm_api/utils" "io/ioutil" "net/http" "strings" "time" ) const ( AppKey = "AP3MLZIOZR9AIH" AppSecret = "vuarTISZiRM4U3CcSkQLlKLQSDhZZkxG" ApiSuccessCode = "ACK" // 接口请求成功标识 CompanyProfileCode = "RD2203231L27R3B4" // 客户档案编码 OpenApiTokenCacheKey = "admin_maycur_token" // Token缓存Key OpenApiAuthLoginUrl = "/api/openapi/auth/login" // 鉴权接口 ApiEmployeeDetailUrl = "/api/openapi/employee/details" // 员工详情接口 ApiCompanyProfilePageListUrl = "/api/openapi/reference/data/detail/query" // 客户档案列表接口-分页 ApiImportCompanyProfileUrl = "/api/openapi/reference/data/detail" // 批量导入客户档案接口 AuthGroupCode = "UG21277004535961787" // 所有客户档案可见的用户组编码 ) // OpenApiTokenReq 获取OpenApiToken请求体 type OpenApiTokenReq struct { Secret string `json:"secret" description:"secret, 非AppSecret"` AppCode string `json:"appCode" description:"MayCurAppKey"` Timestamp int64 `json:"timestamp" description:"毫秒级时间戳"` } // OpenApiTokenResp 获取OpenApiToken响应体 type OpenApiTokenResp struct { Code string `json:"code" description:"状态码"` Message string `json:"message" description:"返回信息"` Data OpenApiToken } // OpenApiToken OpenApiToken type OpenApiToken struct { EntCode string `json:"entCode" description:"企业编码"` TokenId string `json:"tokenId" description:"Token"` } // CurlOpenApiToken 请求OpenApiToken接口 func CurlOpenApiToken() (result *OpenApiTokenResp, err error) { // 生成secret millTime := time.Now().UnixNano() / 1e6 hexBase := fmt.Sprintf("%s:%s:%d", AppSecret, AppKey, millTime) m := sha256.New() m.Write([]byte(hexBase)) secret := hex.EncodeToString(m.Sum(nil)) // 请求参数 params := new(OpenApiTokenReq) params.Secret = secret params.AppCode = AppKey params.Timestamp = millTime // 请求体 url := fmt.Sprintf("%s%s", utils.MayCurBaseUrl, OpenApiAuthLoginUrl) paramsByte, e := json.Marshal(params) if e != nil { err = fmt.Errorf("params to json err: %s", e.Error()) return } postParam := string(paramsByte) // 响应结果 body, e := buildHttpRequest(url, "POST", postParam, false) result = new(OpenApiTokenResp) if e = json.Unmarshal(body, &result); e != nil { err = fmt.Errorf("resp unmarshal err: %s", e.Error()) return } return } // GetOpenApiToken 获取OpenApiToken func GetOpenApiToken() (apiToken *OpenApiToken, err error) { defer func() { if err != nil { utils.FileLog.Error("GetOpenApiToken Err: %s", err.Error()) alarm_msg.SendAlarmMsg(fmt.Sprintf("获取OpenApiToken失败, ErrMsg: %s", err.Error()), 3) } }() apiToken = new(OpenApiToken) // 缓存读取token t, _ := utils.Rc.RedisString(OpenApiTokenCacheKey) if t != "" { lastToken := new(OpenApiToken) if e := json.Unmarshal([]byte(t), &lastToken); e != nil { err = fmt.Errorf("OpenApiToken缓存解析失败, Err: %s", e.Error()) return } if lastToken != nil && lastToken.EntCode != "" && lastToken.TokenId != "" { apiToken = lastToken return } } // 获取新的token result, e := CurlOpenApiToken() if e != nil { err = fmt.Errorf("请求OpenApiToken接口失败, Err: %s", e.Error()) return } if result == nil { err = fmt.Errorf("请求OpenApiToken接口结果为nil") return } if result.Code != ApiSuccessCode { err = fmt.Errorf("请求OpenApiToken接口Code异常: %s, ErrMsg: %s", result.Code, result.Message) return } apiToken.TokenId = result.Data.TokenId apiToken.EntCode = result.Data.EntCode // 写入缓存 cacheByte, e := json.Marshal(apiToken) if e != nil { err = fmt.Errorf("OpenApiToken转Json失败, Err: %s", e.Error()) return } if e = utils.Rc.Put(OpenApiTokenCacheKey, cacheByte, 28*time.Minute); e != nil { err = fmt.Errorf("OpenApiToken写入缓存失败, Err: %s", e.Error()) return } return } // buildHttpRequest 创建请求 func buildHttpRequest(url, method, payload string, hasAuth bool) (result []byte, err error) { client := http.Client{} req, e := http.NewRequest(method, url, strings.NewReader(payload)) if e != nil { err = fmt.Errorf("http new request err: %s", e.Error()) return } req.Header.Set("Content-Type", "application/json") // 鉴权信息 if hasAuth { token, e := GetOpenApiToken() if e != nil { err = fmt.Errorf("获取Token失败, Err: %s", e.Error()) return } if token == nil { err = fmt.Errorf("获取Token失败, nil") return } if token.EntCode == "" || token.TokenId == "" { err = fmt.Errorf("获取Token异常, EntCode: %s, TokenId: %s", token.EntCode, token.TokenId) return } req.Header.Set("entCode", token.EntCode) req.Header.Set("tokenId", token.TokenId) //utils.FileLog.Info("EntCode: %s, TokenId: %s", token.EntCode, token.TokenId) } resp, e := client.Do(req) if e != nil { err = fmt.Errorf("client request err: %s", e.Error()) return } defer func() { _ = resp.Body.Close() }() body, e := ioutil.ReadAll(resp.Body) if e != nil { err = fmt.Errorf("ioutil read err: %s", e.Error()) return } utils.FileLog.Info("maycur http resp: %s", string(body)) return body, nil } // SyncCompanyProfile 同步客户档案及可见性 func SyncCompanyProfile() (err error) { defer func() { if err != nil { utils.FileLog.Error("SyncCompanyProfile ErrMsg: %s", err.Error()) alarm_msg.SendAlarmMsg(fmt.Sprintf("每刻-同步客户档案及可见性失败, ErrMsg: %s", err.Error()), 3) return } //alarm_msg.SendAlarmMsg(fmt.Sprintf("每刻-同步客户档案成功"), 1) }() // 同步每刻客户档案到本地 utils.FileLog.Info("下载客户档案至本地") if e := DownloadCompanyProfile(); e != nil { err = fmt.Errorf("同步客户档案至本地失败, Err: %s", e.Error()) return } // 更新公募销售、公募客户信息 utils.FileLog.Info("更新公募客户及销售") if e := SyncPublicOfferingSale(); e != nil { err = fmt.Errorf("同步公募销售信息失败, Err: %s", e.Error()) return } if e := SyncPublicOfferingCompany(); e != nil { err = fmt.Errorf("同步公募客户信息失败, Err: %s", e.Error()) return } // 生成导入数据 utils.FileLog.Info("生成导入数据") importsData, e := GetImportCompanyData() if e != nil { err = fmt.Errorf("生成导入数据失败, Err: %s", e.Error()) return } // Test //for _, v := range importsData { // b, e := json.Marshal(v) // if e != nil { // err = fmt.Errorf("request json marshal err: %s", e.Error()) // return // } // utils.FileLog.Info("%s", string(b)) //} // 导入 utils.FileLog.Info("导入数据长度: %d", len(importsData)) if e := ImportCompanyProfile(importsData); e != nil { err = fmt.Errorf("导入失败, Err: %s", e.Error()) return } return } //func ApiTest() (err error) { // defer func() { // if err != nil { // fmt.Println(err.Error()) // } // }() // // time.Sleep(2 * time.Second) // // var req ImportCompanyProfileReq // req.BizCode = CompanyProfileCode // // var dataDetails []ImportCompanyProfileReferenceData // authArr := make([]*ReferenceDataAuth, 0) // authArr = append(authArr, &ReferenceDataAuth{ // BizCode: "0155", // Type: "STAFF", // }) // //HZCP0155 // dataDetails = append(dataDetails, ImportCompanyProfileReferenceData{ // Name: "测试导入", // BizCode: "HZCP0155", // Enabled: true, // ReferenceDataAuthz: authArr, // }) // req.ReferenceDataDetails = dataDetails // // _, _ = CurlImportCompanyProfile(req) // fmt.Println("操作成功") // return //} //func ApiTest2() (err error) { // defer func() { // if err != nil { // fmt.Println(err.Error()) // } // }() // // url := fmt.Sprintf("%s%s", utils.MayCurBaseUrl, `/api/openapi/reference/data/detail/RD2203231L27R3B4/HZCP1680171ELGFQ3`) // _, e := buildHttpRequest(url, "GET", ``, true) // if e != nil { // err = fmt.Errorf("操作失败, Err: %s", e.Error()) // return // } // fmt.Println("操作成功") // return //}