maycur.go 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. package maycur
  2. import (
  3. "crypto/sha256"
  4. "encoding/hex"
  5. "encoding/json"
  6. "fmt"
  7. "hongze/hz_crm_api/services/alarm_msg"
  8. "hongze/hz_crm_api/utils"
  9. "io/ioutil"
  10. "net/http"
  11. "strings"
  12. "time"
  13. )
  14. const (
  15. AppKey = "AP3MLZIOZR9AIH"
  16. AppSecret = "vuarTISZiRM4U3CcSkQLlKLQSDhZZkxG"
  17. ApiSuccessCode = "ACK" // 接口请求成功标识
  18. CompanyProfileCode = "RD2203231L27R3B4" // 客户档案编码
  19. OpenApiTokenCacheKey = "admin_maycur_token" // Token缓存Key
  20. OpenApiAuthLoginUrl = "/api/openapi/auth/login" // 鉴权接口
  21. ApiEmployeeDetailUrl = "/api/openapi/employee/details" // 员工详情接口
  22. ApiCompanyProfilePageListUrl = "/api/openapi/reference/data/detail/query" // 客户档案列表接口-分页
  23. ApiImportCompanyProfileUrl = "/api/openapi/reference/data/detail" // 批量导入客户档案接口
  24. AuthGroupCode = "UG21277004535961787" // 所有客户档案可见的用户组编码
  25. )
  26. // OpenApiTokenReq 获取OpenApiToken请求体
  27. type OpenApiTokenReq struct {
  28. Secret string `json:"secret" description:"secret, 非AppSecret"`
  29. AppCode string `json:"appCode" description:"MayCurAppKey"`
  30. Timestamp int64 `json:"timestamp" description:"毫秒级时间戳"`
  31. }
  32. // OpenApiTokenResp 获取OpenApiToken响应体
  33. type OpenApiTokenResp struct {
  34. Code string `json:"code" description:"状态码"`
  35. Message string `json:"message" description:"返回信息"`
  36. Data OpenApiToken
  37. }
  38. // OpenApiToken OpenApiToken
  39. type OpenApiToken struct {
  40. EntCode string `json:"entCode" description:"企业编码"`
  41. TokenId string `json:"tokenId" description:"Token"`
  42. }
  43. // CurlOpenApiToken 请求OpenApiToken接口
  44. func CurlOpenApiToken() (result *OpenApiTokenResp, err error) {
  45. // 生成secret
  46. millTime := time.Now().UnixNano() / 1e6
  47. hexBase := fmt.Sprintf("%s:%s:%d", AppSecret, AppKey, millTime)
  48. m := sha256.New()
  49. m.Write([]byte(hexBase))
  50. secret := hex.EncodeToString(m.Sum(nil))
  51. // 请求参数
  52. params := new(OpenApiTokenReq)
  53. params.Secret = secret
  54. params.AppCode = AppKey
  55. params.Timestamp = millTime
  56. // 请求体
  57. url := fmt.Sprintf("%s%s", utils.MayCurBaseUrl, OpenApiAuthLoginUrl)
  58. paramsByte, e := json.Marshal(params)
  59. if e != nil {
  60. err = fmt.Errorf("params to json err: %s", e.Error())
  61. return
  62. }
  63. postParam := string(paramsByte)
  64. // 响应结果
  65. body, e := buildHttpRequest(url, "POST", postParam, false)
  66. result = new(OpenApiTokenResp)
  67. if e = json.Unmarshal(body, &result); e != nil {
  68. err = fmt.Errorf("resp unmarshal err: %s", e.Error())
  69. return
  70. }
  71. return
  72. }
  73. // GetOpenApiToken 获取OpenApiToken
  74. func GetOpenApiToken() (apiToken *OpenApiToken, err error) {
  75. defer func() {
  76. if err != nil {
  77. utils.FileLog.Error("GetOpenApiToken Err: %s", err.Error())
  78. alarm_msg.SendAlarmMsg(fmt.Sprintf("获取OpenApiToken失败, ErrMsg: %s", err.Error()), 3)
  79. }
  80. }()
  81. apiToken = new(OpenApiToken)
  82. // 缓存读取token
  83. t, _ := utils.Rc.RedisString(OpenApiTokenCacheKey)
  84. if t != "" {
  85. lastToken := new(OpenApiToken)
  86. if e := json.Unmarshal([]byte(t), &lastToken); e != nil {
  87. err = fmt.Errorf("OpenApiToken缓存解析失败, Err: %s", e.Error())
  88. return
  89. }
  90. if lastToken != nil && lastToken.EntCode != "" && lastToken.TokenId != "" {
  91. apiToken = lastToken
  92. return
  93. }
  94. }
  95. // 获取新的token
  96. result, e := CurlOpenApiToken()
  97. if e != nil {
  98. err = fmt.Errorf("请求OpenApiToken接口失败, Err: %s", e.Error())
  99. return
  100. }
  101. if result == nil {
  102. err = fmt.Errorf("请求OpenApiToken接口结果为nil")
  103. return
  104. }
  105. if result.Code != ApiSuccessCode {
  106. err = fmt.Errorf("请求OpenApiToken接口Code异常: %s, ErrMsg: %s", result.Code, result.Message)
  107. return
  108. }
  109. apiToken.TokenId = result.Data.TokenId
  110. apiToken.EntCode = result.Data.EntCode
  111. // 写入缓存
  112. cacheByte, e := json.Marshal(apiToken)
  113. if e != nil {
  114. err = fmt.Errorf("OpenApiToken转Json失败, Err: %s", e.Error())
  115. return
  116. }
  117. if e = utils.Rc.Put(OpenApiTokenCacheKey, cacheByte, 28*time.Minute); e != nil {
  118. err = fmt.Errorf("OpenApiToken写入缓存失败, Err: %s", e.Error())
  119. return
  120. }
  121. return
  122. }
  123. // buildHttpRequest 创建请求
  124. func buildHttpRequest(url, method, payload string, hasAuth bool) (result []byte, err error) {
  125. client := http.Client{}
  126. req, e := http.NewRequest(method, url, strings.NewReader(payload))
  127. if e != nil {
  128. err = fmt.Errorf("http new request err: %s", e.Error())
  129. return
  130. }
  131. req.Header.Set("Content-Type", "application/json")
  132. // 鉴权信息
  133. if hasAuth {
  134. token, e := GetOpenApiToken()
  135. if e != nil {
  136. err = fmt.Errorf("获取Token失败, Err: %s", e.Error())
  137. return
  138. }
  139. if token == nil {
  140. err = fmt.Errorf("获取Token失败, nil")
  141. return
  142. }
  143. if token.EntCode == "" || token.TokenId == "" {
  144. err = fmt.Errorf("获取Token异常, EntCode: %s, TokenId: %s", token.EntCode, token.TokenId)
  145. return
  146. }
  147. req.Header.Set("entCode", token.EntCode)
  148. req.Header.Set("tokenId", token.TokenId)
  149. //utils.FileLog.Info("EntCode: %s, TokenId: %s", token.EntCode, token.TokenId)
  150. }
  151. resp, e := client.Do(req)
  152. if e != nil {
  153. err = fmt.Errorf("client request err: %s", e.Error())
  154. return
  155. }
  156. defer func() {
  157. _ = resp.Body.Close()
  158. }()
  159. body, e := ioutil.ReadAll(resp.Body)
  160. if e != nil {
  161. err = fmt.Errorf("ioutil read err: %s", e.Error())
  162. return
  163. }
  164. utils.FileLog.Info("maycur http resp: %s", string(body))
  165. return body, nil
  166. }
  167. // SyncCompanyProfile 同步客户档案及可见性
  168. func SyncCompanyProfile() (err error) {
  169. defer func() {
  170. if err != nil {
  171. utils.FileLog.Error("SyncCompanyProfile ErrMsg: %s", err.Error())
  172. alarm_msg.SendAlarmMsg(fmt.Sprintf("每刻-同步客户档案及可见性失败, ErrMsg: %s", err.Error()), 3)
  173. return
  174. }
  175. //alarm_msg.SendAlarmMsg(fmt.Sprintf("每刻-同步客户档案成功"), 1)
  176. }()
  177. // 同步每刻客户档案到本地
  178. utils.FileLog.Info("下载客户档案至本地")
  179. if e := DownloadCompanyProfile(); e != nil {
  180. err = fmt.Errorf("同步客户档案至本地失败, Err: %s", e.Error())
  181. return
  182. }
  183. // 更新公募销售、公募客户信息
  184. utils.FileLog.Info("更新公募客户及销售")
  185. if e := SyncPublicOfferingSale(); e != nil {
  186. err = fmt.Errorf("同步公募销售信息失败, Err: %s", e.Error())
  187. return
  188. }
  189. if e := SyncPublicOfferingCompany(); e != nil {
  190. err = fmt.Errorf("同步公募客户信息失败, Err: %s", e.Error())
  191. return
  192. }
  193. // 生成导入数据
  194. utils.FileLog.Info("生成导入数据")
  195. importsData, e := GetImportCompanyData()
  196. if e != nil {
  197. err = fmt.Errorf("生成导入数据失败, Err: %s", e.Error())
  198. return
  199. }
  200. // Test
  201. //for _, v := range importsData {
  202. // b, e := json.Marshal(v)
  203. // if e != nil {
  204. // err = fmt.Errorf("request json marshal err: %s", e.Error())
  205. // return
  206. // }
  207. // utils.FileLog.Info("%s", string(b))
  208. //}
  209. // 导入
  210. utils.FileLog.Info("导入数据长度: %d", len(importsData))
  211. if e := ImportCompanyProfile(importsData); e != nil {
  212. err = fmt.Errorf("导入失败, Err: %s", e.Error())
  213. return
  214. }
  215. return
  216. }
  217. //func ApiTest() (err error) {
  218. // defer func() {
  219. // if err != nil {
  220. // fmt.Println(err.Error())
  221. // }
  222. // }()
  223. //
  224. // time.Sleep(2 * time.Second)
  225. //
  226. // var req ImportCompanyProfileReq
  227. // req.BizCode = CompanyProfileCode
  228. //
  229. // var dataDetails []ImportCompanyProfileReferenceData
  230. // authArr := make([]*ReferenceDataAuth, 0)
  231. // authArr = append(authArr, &ReferenceDataAuth{
  232. // BizCode: "0155",
  233. // Type: "STAFF",
  234. // })
  235. // //HZCP0155
  236. // dataDetails = append(dataDetails, ImportCompanyProfileReferenceData{
  237. // Name: "测试导入",
  238. // BizCode: "HZCP0155",
  239. // Enabled: true,
  240. // ReferenceDataAuthz: authArr,
  241. // })
  242. // req.ReferenceDataDetails = dataDetails
  243. //
  244. // _, _ = CurlImportCompanyProfile(req)
  245. // fmt.Println("操作成功")
  246. // return
  247. //}
  248. //func ApiTest2() (err error) {
  249. // defer func() {
  250. // if err != nil {
  251. // fmt.Println(err.Error())
  252. // }
  253. // }()
  254. //
  255. // url := fmt.Sprintf("%s%s", utils.MayCurBaseUrl, `/api/openapi/reference/data/detail/RD2203231L27R3B4/HZCP1680171ELGFQ3`)
  256. // _, e := buildHttpRequest(url, "GET", ``, true)
  257. // if e != nil {
  258. // err = fmt.Errorf("操作失败, Err: %s", e.Error())
  259. // return
  260. // }
  261. // fmt.Println("操作成功")
  262. // return
  263. //}