talent_account.go 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723
  1. package youngee_talent_service
  2. import (
  3. "bytes"
  4. "encoding/json"
  5. "fmt"
  6. "github.com/gogf/gf/os/gtime"
  7. "io/ioutil"
  8. "math/rand"
  9. "net/http"
  10. "net/url"
  11. "regexp"
  12. "strconv"
  13. "time"
  14. "youngmini_server/app/dao"
  15. "youngmini_server/app/model/youngee_talent_model"
  16. "youngmini_server/app/utils"
  17. "github.com/gogf/gf/frame/g"
  18. "github.com/gogf/gf/net/ghttp"
  19. "github.com/huaweicloud/huaweicloud-sdk-go-v3/core/auth/basic"
  20. ocr "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/ocr/v1"
  21. "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/ocr/v1/model"
  22. region "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/ocr/v1/region"
  23. "strings"
  24. )
  25. func GetTalentAccount(r *ghttp.Request) *TalentHttpResult {
  26. //达人id获取
  27. tid, err := utils.SessionTalentInfo.GetTalentIdFromSession(r)
  28. //定义除了youngee_platform_account_info表结构外额外还有info_third_platform的结构体(用表连接)
  29. if err != nil {
  30. return &TalentHttpResult{Code: -1, Msg: "Get talent info failed"}
  31. }
  32. //查找给定达人id之后,该达人绑定了几个平台的账号
  33. res, err := g.DB().Model("youngee_platform_account_info").All("talent_id", tid)
  34. fmt.Println("该账号社媒平台绑定结果为__________:", res)
  35. if err != nil {
  36. return &TalentHttpResult{Code: -2, Msg: "query database error"}
  37. }
  38. if res == nil {
  39. return &TalentHttpResult{Code: -3, Msg: "未绑定任何平台"}
  40. }
  41. return &TalentHttpResult{Code: 0, Msg: "success", Data: res}
  42. }
  43. func GetTalentAccountKuaishou(r *ghttp.Request) *TalentHttpResult {
  44. //达人id获取
  45. tid, err := utils.SessionTalentInfo.GetTalentIdFromSession(r)
  46. if err != nil {
  47. return &TalentHttpResult{Code: -1, Msg: "Get talent info failed"}
  48. }
  49. //查找给定达人id之后,该达人绑定了几个平台的账号
  50. res, err := g.DB().Model("platform_kuaishou_user_info").All("talent_id", tid)
  51. if err != nil {
  52. return &TalentHttpResult{Code: -2, Msg: "query database error"}
  53. }
  54. if res == nil {
  55. return &TalentHttpResult{Code: -3, Msg: "未绑定任何平台"}
  56. }
  57. return &TalentHttpResult{Code: 0, Msg: "success", Data: res}
  58. }
  59. func DelTalentAccount(r *ghttp.Request) *TalentHttpResult {
  60. tid, _ := utils.SessionTalentInfo.GetTalentIdFromSession(r)
  61. var DelAccountReq *youngee_talent_model.DelAccountReq
  62. err := r.ParseForm(&DelAccountReq)
  63. if err != nil {
  64. return &TalentHttpResult{Code: -1, Msg: "Parse form failed"}
  65. }
  66. if DelAccountReq.PlatformId == 4 || DelAccountReq.PlatformId == 8 { //删除快手
  67. _, err := g.Model("platform_kuaishou_user_info").Where("talent_id=? AND platform_id IN (4,8) And open_id=?", tid, DelAccountReq.OpenId).Delete()
  68. if err != nil {
  69. return &TalentHttpResult{Code: -1, Msg: "delete account failed"}
  70. }
  71. } else {
  72. _, err := g.Model("platform_kuaishou_user_info").Where("talent_id=? AND platform_id =? And open_id=?", tid, DelAccountReq.PlatformId, DelAccountReq.OpenId).Delete()
  73. if err != nil {
  74. return &TalentHttpResult{Code: -1, Msg: "delete account failed"}
  75. }
  76. }
  77. return &TalentHttpResult{Code: 0, Msg: "success"}
  78. }
  79. func OnAddTalentAccount(r *ghttp.Request) *TalentHttpResult {
  80. tid, err := utils.SessionTalentInfo.GetTalentIdFromSession(r)
  81. if err != nil {
  82. return &TalentHttpResult{Code: -1, Msg: "Get talent info failed"}
  83. }
  84. account := youngee_talent_model.AddAccountReq{}
  85. //account := youngee_talent_model.KuaishouUserInfo{}
  86. err = r.ParseForm(&account)
  87. if err != nil {
  88. return &TalentHttpResult{Code: -2, Msg: err.Error()}
  89. }
  90. //获取 基本信息,头像昵称、粉丝数、作品数目、点赞数
  91. //小红书
  92. if account.PlatformId == 1 {
  93. //获取用户唯一标识
  94. shareText := account.HomePageUrl
  95. //调用MoreAPI
  96. userDetail := getXHSUserDetail(shareText)
  97. if userDetail == nil {
  98. return &TalentHttpResult{Code: -1, Msg: "MoreApi调用出错"}
  99. }
  100. //是否被其他人绑定
  101. BindCode := CheckAccountBind(account.PlatformId, userDetail.RedID)
  102. if BindCode == -1 {
  103. return &TalentHttpResult{Code: -1, Msg: "查询账号表出错"}
  104. } else if BindCode == 1 {
  105. return &TalentHttpResult{Code: -5, Msg: "此小红书Id已经被绑定"}
  106. } else { //没有被其他人绑定
  107. //调用OCR
  108. var orcInfo = getXHSOCRresult(account.HomePageCaptureUrl, account.PlatformId)
  109. if orcInfo == nil {
  110. return &TalentHttpResult{Code: -1, Msg: "ORC接口出错"}
  111. }
  112. //小红书id一致且是自己的主页
  113. if orcInfo.RedId == userDetail.RedID && orcInfo.SelfHome == 1 {
  114. //获取用户基本信息
  115. XHSdata := g.Map{
  116. "talent_id": tid,
  117. "open_id": userDetail.RedID,
  118. "platform_id": account.PlatformId,
  119. "fan": userDetail.Fans,
  120. "nick_name": userDetail.Nickname,
  121. "head_uri": userDetail.Images,
  122. "city": userDetail.IPLocation,
  123. "gender": userDetail.Gender,
  124. "like_num": userDetail.LikeNum,
  125. "create_time": gtime.Now(),
  126. "update_time": gtime.Now(),
  127. "home_page_url": account.HomePageUrl,
  128. "home_page_capture_url": account.HomePageCaptureUrl,
  129. }
  130. //入库
  131. _, err := g.Model("platform_kuaishou_user_info").Insert(XHSdata)
  132. if err != nil {
  133. return &TalentHttpResult{Code: -1, Msg: "数据入库失败"}
  134. }
  135. // 修改talent表字段is_bind_account值为1
  136. _, err = g.Model(dao.YoungeeTalentInfo.Table).Data("is_bind_account=1").Where("id", tid).Update()
  137. if err != nil {
  138. return &TalentHttpResult{Code: -2, Msg: err.Error()}
  139. }
  140. return &TalentHttpResult{Code: 0, Msg: "小红书账号绑定成功"}
  141. } else {
  142. return &TalentHttpResult{Code: -6, Msg: "图片中小红书ID和主页链接不一致"}
  143. }
  144. }
  145. } else if account.PlatformId == 3 { //微博
  146. //获取用户唯一标识
  147. shareText := account.HomePageUrl
  148. //调用MoreAPI
  149. userDetail := getWBUserDetail(shareText)
  150. if userDetail == nil {
  151. return &TalentHttpResult{Code: -1, Msg: "MoreApi调用出错"}
  152. }
  153. //是否被其他人绑定
  154. BindCode := CheckAccountBind(account.PlatformId, userDetail.WBID)
  155. if BindCode == -1 {
  156. return &TalentHttpResult{Code: -1, Msg: "查询账号表出错"}
  157. } else if BindCode == 1 {
  158. return &TalentHttpResult{Code: -5, Msg: "此微博Id已经被绑定"}
  159. } else {
  160. //调用OCR
  161. var orcInfo = getWBOCRresult(account.HomePageCaptureUrl, userDetail.Nickname)
  162. if orcInfo == nil {
  163. return &TalentHttpResult{Code: -1, Msg: "ORC接口出错"}
  164. }
  165. //orc的昵称和moreapi返回的昵称一致,且主页截图是自己的截图
  166. if orcInfo.SelfHome == 1 {
  167. //获取用户基本信息
  168. WBdata := g.Map{
  169. "talent_id": tid,
  170. "open_id": userDetail.WBID,
  171. "platform_id": account.PlatformId,
  172. "fan": userDetail.Fans,
  173. "nick_name": userDetail.Nickname,
  174. "head_uri": userDetail.HeadImage,
  175. "gender": userDetail.Gender,
  176. "create_time": gtime.Now(),
  177. "update_time": gtime.Now(),
  178. "home_page_url": account.HomePageUrl,
  179. "home_page_capture_url": account.HomePageCaptureUrl,
  180. }
  181. //入库
  182. _, err := g.Model("platform_kuaishou_user_info").Insert(WBdata)
  183. if err != nil {
  184. return &TalentHttpResult{Code: -1, Msg: "数据入库失败"}
  185. }
  186. // 修改talent表字段is_bind_account值为1
  187. _, err = g.Model(dao.YoungeeTalentInfo.Table).Data("is_bind_account=1").Where("id", tid).Update()
  188. if err != nil {
  189. return &TalentHttpResult{Code: -2, Msg: err.Error()}
  190. }
  191. return &TalentHttpResult{Code: 0, Msg: "微博账号绑定成功"}
  192. } else {
  193. return &TalentHttpResult{Code: -6, Msg: "主页截图非本人主页,获取着与主页链接不匹配"}
  194. }
  195. }
  196. } else if account.PlatformId == 5 { //B站
  197. //获取用户主页URL以及uid
  198. shareText := account.HomePageUrl
  199. // 正则表达式匹配以 https:// 开头的 URL
  200. re := regexp.MustCompile(`https://[^\s]+`)
  201. shareText = re.FindString(shareText)
  202. //调用MoreAPI
  203. userDetail := getBiLiUserDetail(shareText)
  204. if userDetail == nil {
  205. return &TalentHttpResult{Code: -1, Msg: "MoreApi调用出错"}
  206. }
  207. //是否被其他人绑定
  208. BindCode := CheckAccountBind(account.PlatformId, userDetail.UID)
  209. if BindCode == -1 {
  210. return &TalentHttpResult{Code: -1, Msg: "查询账号表出错"}
  211. } else if BindCode == 1 {
  212. return &TalentHttpResult{Code: -5, Msg: "此bilibili已经被绑定"}
  213. } else {
  214. //调用OCR
  215. var orcInfo = getBliOCRresult(account.HomePageCaptureUrl, userDetail.Nickname)
  216. if orcInfo == nil {
  217. return &TalentHttpResult{Code: -1, Msg: "ORC接口出错"}
  218. }
  219. //orc的昵称和moreapi返回的昵称一致,且主页截图是自己的截图
  220. if orcInfo.SelfHome == 1 {
  221. //获取用户基本信息
  222. Blidata := g.Map{
  223. "talent_id": tid,
  224. "open_id": userDetail.UID,
  225. "platform_id": account.PlatformId,
  226. "fan": userDetail.Fans,
  227. "nick_name": userDetail.Nickname,
  228. "head_uri": userDetail.HeadImage,
  229. "gender": userDetail.Gender,
  230. "create_time": gtime.Now(),
  231. "update_time": gtime.Now(),
  232. "home_page_url": account.HomePageUrl,
  233. "home_page_capture_url": account.HomePageCaptureUrl,
  234. }
  235. //入库
  236. _, err := g.Model("platform_kuaishou_user_info").Insert(Blidata)
  237. if err != nil {
  238. return &TalentHttpResult{Code: -1, Msg: "数据入库失败"}
  239. }
  240. // 修改talent表字段is_bind_account值为1
  241. _, err = g.Model(dao.YoungeeTalentInfo.Table).Data("is_bind_account=1").Where("id", tid).Update()
  242. if err != nil {
  243. return &TalentHttpResult{Code: -2, Msg: err.Error()}
  244. }
  245. return &TalentHttpResult{Code: 0, Msg: "bli账号绑定成功"}
  246. } else {
  247. return &TalentHttpResult{Code: -6, Msg: "主页截图非本人主页,或者与主页链接不匹配"}
  248. }
  249. }
  250. } else {
  251. return &TalentHttpResult{Code: -1, Msg: "平台ID有误"}
  252. }
  253. return &TalentHttpResult{Code: 0, Msg: "success"}
  254. }
  255. //func OnUpdateTalentAccount(r *ghttp.Request) *TalentHttpResult {
  256. // tid, err := utils.SessionTalentInfo.GetTalentIdFromSession(r)
  257. // if err != nil {
  258. // return &TalentHttpResult{Code: -1, Msg: "Get talent info failed"}
  259. // }
  260. // account := youngee_talent_model.PlatformAccountInfo{}
  261. // err = r.ParseForm(&account)
  262. // if err != nil {
  263. // return &TalentHttpResult{Code: -2, Msg: err.Error()}
  264. // }
  265. // account.TalentId = tid
  266. // _, err = g.DB().Model(dao.YoungeePlatformAccountInfo.Table).Update(account, "account_id = ? and talent_id = ?", account.PlatformId, tid)
  267. // if err != nil {
  268. // return &TalentHttpResult{Code: -3, Msg: "update failed"}
  269. // }
  270. // return &TalentHttpResult{Code: 0, Msg: "success"}
  271. //}
  272. // 检查该账号是否被其他人绑定了
  273. func CheckAccountBind(pId int, openId string) int {
  274. count, err := g.Model("platform_kuaishou_user_info").Where("platform_id = ? and open_id = ?", pId, openId).Count()
  275. if err != nil {
  276. return -1
  277. }
  278. if count > 0 { //已经被绑定
  279. return 1
  280. } else {
  281. return 0
  282. }
  283. }
  284. // 用于获取 XHS 用户详细信息的函数
  285. func getXHSUserDetail(homeURL string) *youngee_talent_model.XHSBasicInfo {
  286. //todo 使用cookie池
  287. cookieList := g.Config().GetArray("xhsCookiePool.cookiesList")
  288. // 随机选择一个cookie
  289. // 将字符串解析为切片
  290. // 如果 cookies 数组为空,返回一个错误
  291. if len(cookieList) == 0 {
  292. fmt.Println("Cookie list is empty")
  293. return nil
  294. }
  295. rand.Seed(time.Now().UnixNano())
  296. cookie := cookieList[rand.Intn(len(cookieList))]
  297. //cookie := "abRequestId=023e90e1-a95a-58db-830a-d66c0cc67f60; a1=19566f0f66eglh42hy8peqvpak3xqglp49289p8xb50000109075; webId=d189df044ca380c74b5b97bc300db5a1; gid=yj2KKiyyyY4Yyj2KKi8iKjUYKdk1x4JxvYUdJCDAhU0TqY28CAk1Uj888y8j8W288q4Jif4i; xsecappid=xhs-pc-web; webBuild=4.62.3; loadts=1745844315922; acw_tc=0a4ad62517458443171336139e75772e8309d4caf46a5bbe75d13ed1f39023; websectiga=2a3d3ea002e7d92b5c9743590ebd24010cf3710ff3af8029153751e41a6af4a3; sec_poison_id=618e82ac-335a-4cc7-a4da-61f4d2b9740d; web_session=0400698c340cec15e62b1a303a3a4b527fb28b; unread={%22ub%22:%2267f51cef000000001c0051d9%22%2C%22ue%22:%2268085423000000001b027fce%22%2C%22uc%22:26}"
  298. GetDetailUrl := "http://120.46.92.62:6888/api/xhs/user_detail"
  299. // 构建请求体
  300. requestBody := map[string]string{"share_text": homeURL}
  301. jsonBody, err := json.Marshal(requestBody)
  302. if err != nil {
  303. fmt.Println("Error marshalling request body:", err)
  304. return nil
  305. }
  306. // 创建 POST 请求
  307. req, err := http.NewRequest("POST", GetDetailUrl, bytes.NewBuffer(jsonBody))
  308. if err != nil {
  309. fmt.Println("Error creating POST request:", err)
  310. return nil
  311. }
  312. // 设置请求头,包括 cookie
  313. req.Header.Set("Content-Type", "application/json")
  314. req.Header.Set("cookie", cookie.(string))
  315. // 发送请求
  316. client := &http.Client{}
  317. resp, err := client.Do(req)
  318. if err != nil {
  319. fmt.Println("Error sending POST request:", err)
  320. return nil
  321. }
  322. defer resp.Body.Close()
  323. // 读取响应体
  324. body, err := ioutil.ReadAll(resp.Body)
  325. if err != nil {
  326. fmt.Println("Error reading response body:", err)
  327. return nil
  328. }
  329. // 创建一个空的 map 用于存放解析后的 JSON 数据
  330. var responseMap map[string]interface{}
  331. err = json.Unmarshal(body, &responseMap)
  332. if err != nil {
  333. fmt.Println("Error parsing JSON:", err)
  334. return nil
  335. }
  336. fmt.Println("responseMap--", responseMap)
  337. // 提取 data.response_body.data.basic_info
  338. if responseBody, ok := responseMap["data"].(map[string]interface{}); ok {
  339. if responseBodyData, ok := responseBody["response_body"].(map[string]interface{}); ok {
  340. if data, ok := responseBodyData["data"].(map[string]interface{}); ok {
  341. if basicInfo, ok := data["basic_info"].(map[string]interface{}); ok {
  342. // 使用 json.Unmarshal 将 basic_info 直接解析到结构体中
  343. var userInfo youngee_talent_model.XHSBasicInfo
  344. userInfo.Imageb = fmt.Sprintf("%v", basicInfo["imageb"])
  345. userInfo.Nickname = fmt.Sprintf("%v", basicInfo["nickname"])
  346. userInfo.Images = fmt.Sprintf("%v", basicInfo["images"])
  347. userInfo.RedID = fmt.Sprintf("%v", basicInfo["red_id"])
  348. userInfo.Gender = fmt.Sprintf("%v", basicInfo["gender"])
  349. userInfo.IPLocation = fmt.Sprintf("%v", basicInfo["ip_location"])
  350. userInfo.Desc = fmt.Sprintf("%v", basicInfo["desc"])
  351. // 提取 interactions
  352. if interactions, ok := data["interactions"].([]interface{}); ok {
  353. for _, interaction := range interactions {
  354. interactionData := interaction.(map[string]interface{})
  355. // 提取粉丝数(name 为 "粉丝")
  356. if interactionData["name"] == "粉丝" {
  357. countStr := fmt.Sprintf("%v", interactionData["count"])
  358. countInt, _ := strconv.Atoi(countStr)
  359. userInfo.Fans = countInt
  360. }
  361. // 提取获赞与收藏数(name 为 "获赞与收藏")
  362. if interactionData["name"] == "获赞与收藏" {
  363. LikeNum := fmt.Sprintf("%v", interactionData["count"])
  364. LikeNumInt, _ := strconv.Atoi(LikeNum)
  365. userInfo.LikeNum = LikeNumInt
  366. }
  367. }
  368. }
  369. // 返回 BasicInfo 结构体
  370. return &userInfo
  371. }
  372. }
  373. }
  374. }
  375. // 如果没有找到 basic_info,返回错误
  376. return nil
  377. }
  378. // 获取WB用户详细信息
  379. func getWBUserDetail(homeURL string) *youngee_talent_model.WBBasicInfo {
  380. GetDetailUrl := "http://120.46.92.62:6888/api/weibo/user_detail"
  381. // 构建请求体
  382. requestBody := map[string]string{"share_text": homeURL}
  383. jsonBody, err := json.Marshal(requestBody)
  384. if err != nil {
  385. fmt.Println("Error marshalling request body:", err)
  386. return nil
  387. }
  388. // 创建 POST 请求
  389. req, err := http.NewRequest("POST", GetDetailUrl, bytes.NewBuffer(jsonBody))
  390. if err != nil {
  391. fmt.Println("Error creating POST request:", err)
  392. return nil
  393. }
  394. // 设置请求头,包括 cookie
  395. req.Header.Set("Content-Type", "application/json")
  396. // 发送请求
  397. client := &http.Client{}
  398. resp, err := client.Do(req)
  399. if err != nil {
  400. fmt.Println("Error sending POST request:", err)
  401. return nil
  402. }
  403. defer resp.Body.Close()
  404. // 读取响应体
  405. body, err := ioutil.ReadAll(resp.Body)
  406. if err != nil {
  407. fmt.Println("Error reading response body:", err)
  408. return nil
  409. }
  410. // 创建一个空的 map 用于存放解析后的 JSON 数据
  411. var responseMap map[string]interface{}
  412. err = json.Unmarshal(body, &responseMap)
  413. if err != nil {
  414. fmt.Println("Error parsing JSON:", err)
  415. return nil
  416. }
  417. //提取数据
  418. // 提取数据
  419. if responseBody, ok := responseMap["data"].(map[string]interface{}); ok {
  420. // 提取所需字段 responseBody["id"]
  421. openId := fmt.Sprintf("%.0f", responseBody["id"])
  422. fmt.Println("openId----->:", openId)
  423. followers, _ := utils.TypeTran.AnyToInt(responseBody["followers_count"]) // 粉丝
  424. avatarHd, _ := utils.TypeTran.AnyToString(responseBody["avatar_hd"]) //头像
  425. nickName, _ := utils.TypeTran.AnyToString(responseBody["screen_name"]) //昵称
  426. fmt.Println("nickName----->:", nickName)
  427. statusesCount, _ := utils.TypeTran.AnyToInt(responseBody["statuses_count"]) // 作品数目
  428. gender, _ := utils.TypeTran.AnyToString(responseBody["gender"])
  429. // 创建并返回 BasicInfo 结构体
  430. userInfo := youngee_talent_model.WBBasicInfo{
  431. WBID: openId,
  432. HeadImage: avatarHd,
  433. Fans: followers,
  434. PostNum: statusesCount,
  435. Gender: gender,
  436. Nickname: nickName,
  437. }
  438. return &userInfo
  439. }
  440. // 如果没有找到 basic_info,返回错误
  441. return nil
  442. }
  443. func getBiLiUserDetail(homeURL string) *youngee_talent_model.BliBasicInfo {
  444. redirectedURL, err := getRedirectedURL(homeURL)
  445. if err != nil {
  446. fmt.Println("Error:", err)
  447. return nil
  448. }
  449. userID, err := extractUserID(redirectedURL)
  450. if err != nil {
  451. fmt.Println("Error extracting user ID:", err)
  452. return nil
  453. }
  454. fmt.Println("Extracted user ID:", userID)
  455. GetDetailUrl := "http://120.46.92.62:6888/api/bilibili/user_info"
  456. // 构建请求体
  457. requestBody := map[string]string{"uid": userID}
  458. jsonBody, err := json.Marshal(requestBody)
  459. if err != nil {
  460. fmt.Println("Error marshalling request body:", err)
  461. return nil
  462. }
  463. // 创建 POST 请求
  464. req, err := http.NewRequest("POST", GetDetailUrl, bytes.NewBuffer(jsonBody))
  465. if err != nil {
  466. fmt.Println("Error creating POST request:", err)
  467. return nil
  468. }
  469. // 设置请求头,包括 cookie
  470. req.Header.Set("Content-Type", "application/json")
  471. // 发送请求
  472. client := &http.Client{}
  473. resp, err := client.Do(req)
  474. if err != nil {
  475. fmt.Println("Error sending POST request:", err)
  476. return nil
  477. }
  478. defer resp.Body.Close()
  479. // 读取响应体
  480. body, err := ioutil.ReadAll(resp.Body)
  481. if err != nil {
  482. fmt.Println("Error reading response body:", err)
  483. return nil
  484. }
  485. // 创建一个空的 map 用于存放解析后的 JSON 数据
  486. var responseMap map[string]interface{}
  487. err = json.Unmarshal(body, &responseMap)
  488. if err != nil {
  489. fmt.Println("Error parsing JSON:", err)
  490. return nil
  491. }
  492. // 提取数据
  493. if responseBody, ok := responseMap["data"].(map[string]interface{}); ok {
  494. // 提取 space 信息
  495. spaceInfo := responseBody["space"].(map[string]interface{})
  496. // 提取 space.info 中的字段
  497. mid := fmt.Sprintf("%.0f", spaceInfo["info"].(map[string]interface{})["mid"])
  498. name, _ := utils.TypeTran.AnyToString(spaceInfo["info"].(map[string]interface{})["name"]) // name
  499. sex, _ := utils.TypeTran.AnyToString(spaceInfo["info"].(map[string]interface{})["sex"]) // sex
  500. face, _ := utils.TypeTran.AnyToString(spaceInfo["info"].(map[string]interface{})["face"]) // face
  501. // 提取 stat 信息
  502. stat := responseBody["stat"].(map[string]interface{})
  503. follower, _ := utils.TypeTran.AnyToInt(stat["follower"]) // follower
  504. // 创建并返回 BasicInfo 结构体
  505. userInfo := youngee_talent_model.BliBasicInfo{
  506. UID: mid,
  507. HeadImage: face,
  508. Fans: follower, // 转换为整数
  509. Gender: sex,
  510. Nickname: name,
  511. }
  512. return &userInfo
  513. }
  514. // 如果没有找到 basic_info,返回错误
  515. return nil
  516. }
  517. // *youngee_talent_model.OCRResponse
  518. func getXHSOCRresult(homePicURL string, platform_id int) *youngee_talent_model.OCRResponse {
  519. // The AK and SK used for authentication are hard-coded or stored in plaintext, which has great security risks. It is recommended that the AK and SK be stored in ciphertext in configuration files or environment variables and decrypted during use to ensure security.
  520. auth := basic.NewCredentialsBuilder().
  521. WithAk("YJRGTOWEITSYOXN3YPJY").
  522. WithSk("Kd7WDeS2CxlLXjMhGpLW0AmdOZHafitQpBy13a0s").
  523. Build()
  524. client := ocr.NewOcrClient(
  525. ocr.OcrClientBuilder().
  526. WithRegion(region.ValueOf("cn-north-4")).
  527. WithCredential(auth).
  528. Build())
  529. request := &model.RecognizeWebImageRequest{}
  530. request.Body = &model.WebImageRequestBody{
  531. Url: &homePicURL,
  532. }
  533. // 发送请求
  534. response, err := client.RecognizeWebImage(request)
  535. if err != nil {
  536. return nil
  537. }
  538. // 输出返回的完整响应
  539. fmt.Printf("%+v\n", response)
  540. resultText := response.String()
  541. fmt.Println("resultText--->:", resultText)
  542. var orcInfo youngee_talent_model.OCRResponse
  543. if strings.Contains(resultText, "编辑资料") &&
  544. strings.Contains(resultText, "购物车") &&
  545. strings.Contains(resultText, "查看我的订单") {
  546. orcInfo.SelfHome = 1
  547. } else {
  548. orcInfo.SelfHome = 0
  549. }
  550. //获取小红书ID
  551. re := regexp.MustCompile(`小红书号:([\w-]+)`) // 匹配字母、数字或破折号的组合
  552. match := re.FindStringSubmatch(resultText)
  553. if len(match) > 1 {
  554. xhsID := match[1] // match[1] 是第一个括号中的内容,即小红书号
  555. fmt.Println("xhsID-->:", xhsID)
  556. orcInfo.RedId = xhsID
  557. }
  558. return &orcInfo
  559. }
  560. func getWBOCRresult(homePicURL string, nickName string) *youngee_talent_model.OCRResponse {
  561. // The AK and SK used for authentication are hard-coded or stored in plaintext, which has great security risks. It is recommended that the AK and SK be stored in ciphertext in configuration files or environment variables and decrypted during use to ensure security.
  562. auth := basic.NewCredentialsBuilder().
  563. WithAk("YJRGTOWEITSYOXN3YPJY").
  564. WithSk("Kd7WDeS2CxlLXjMhGpLW0AmdOZHafitQpBy13a0s").
  565. Build()
  566. client := ocr.NewOcrClient(
  567. ocr.OcrClientBuilder().
  568. WithRegion(region.ValueOf("cn-north-4")).
  569. WithCredential(auth).
  570. Build())
  571. request := &model.RecognizeWebImageRequest{}
  572. request.Body = &model.WebImageRequestBody{
  573. Url: &homePicURL,
  574. }
  575. // 发送请求
  576. response, err := client.RecognizeWebImage(request)
  577. if err != nil {
  578. return nil
  579. }
  580. // 输出返回的完整响应
  581. fmt.Printf("%+v\n", response)
  582. resultText := response.String()
  583. fmt.Println("resultText--->:", resultText)
  584. var orcInfo youngee_talent_model.OCRResponse
  585. //检测是否是自己的主页
  586. //检查是否是自己的首页
  587. if strings.Contains(resultText, "编辑个人资料") &&
  588. strings.Contains(resultText, "全部微博") &&
  589. strings.Contains(resultText, nickName) {
  590. orcInfo.SelfHome = 1
  591. } else {
  592. orcInfo.SelfHome = 0
  593. }
  594. return &orcInfo
  595. }
  596. func getBliOCRresult(homePicURL string, nickName string) *youngee_talent_model.OCRResponse {
  597. // The AK and SK used for authentication are hard-coded or stored in plaintext, which has great security risks. It is recommended that the AK and SK be stored in ciphertext in configuration files or environment variables and decrypted during use to ensure security.
  598. auth := basic.NewCredentialsBuilder().
  599. WithAk("YJRGTOWEITSYOXN3YPJY").
  600. WithSk("Kd7WDeS2CxlLXjMhGpLW0AmdOZHafitQpBy13a0s").
  601. Build()
  602. client := ocr.NewOcrClient(
  603. ocr.OcrClientBuilder().
  604. WithRegion(region.ValueOf("cn-north-4")).
  605. WithCredential(auth).
  606. Build())
  607. request := &model.RecognizeWebImageRequest{}
  608. request.Body = &model.WebImageRequestBody{
  609. Url: &homePicURL,
  610. }
  611. // 发送请求
  612. response, err := client.RecognizeWebImage(request)
  613. if err != nil {
  614. return nil
  615. }
  616. // 输出返回的完整响应
  617. fmt.Printf("%+v\n", response)
  618. resultText := response.String()
  619. fmt.Println("resultText--->:", resultText)
  620. var orcInfo youngee_talent_model.OCRResponse
  621. //检测是否是自己的主页
  622. if strings.Contains(resultText, "编辑资料") &&
  623. strings.Contains(resultText, nickName) {
  624. orcInfo.SelfHome = 1
  625. } else {
  626. orcInfo.SelfHome = 0
  627. }
  628. return &orcInfo
  629. }
  630. // 获取WB用户详细信息
  631. func TestImage(r *ghttp.Request) *TalentHttpResult {
  632. one, _ := g.Model("platform_kuaishou_user_info").Where("id", 188).One()
  633. return &TalentHttpResult{Code: 0, Msg: "success", Data: one}
  634. }
  635. func getRedirectedURL(urlStr string) (string, error) {
  636. client := &http.Client{
  637. CheckRedirect: func(req *http.Request, via []*http.Request) error {
  638. if len(via) > 0 { // 如果发生重定向,返回最终的重定向 URL
  639. return nil
  640. }
  641. return fmt.Errorf("final URL: %s", req.URL) // 获取最终的重定向 URL
  642. },
  643. }
  644. resp, err := client.Get(urlStr)
  645. if err != nil {
  646. return "", err
  647. }
  648. defer resp.Body.Close()
  649. return resp.Request.URL.String(), nil // 返回最终目标 URL
  650. }
  651. func extractUserID(urlStr string) (string, error) {
  652. // 解析 URL
  653. parsedURL, err := url.Parse(urlStr)
  654. if err != nil {
  655. return "", err
  656. }
  657. // 提取路径部分中的用户 ID
  658. // 这里我们假设用户 ID 是 URL 的路径中的一部分(如 space.bilibili.com/29408510)
  659. segments := parsedURL.Path
  660. var userID string
  661. // 假设 ID 是路径中的第二部分,如 /29408510
  662. fmt.Sscanf(segments, "/%s", &userID)
  663. return userID, nil
  664. }