talent_ks_auth.go 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702
  1. package youngee_talent_service
  2. import (
  3. "context"
  4. "fmt"
  5. "github.com/chromedp/chromedp"
  6. "github.com/gogf/gf/frame/g"
  7. "github.com/gogf/gf/net/ghttp"
  8. "github.com/gogf/gf/os/gtime"
  9. "github.com/gogf/gf/util/gconv"
  10. "github.com/lin-jim-leon/kuaishou/open/merchant"
  11. "github.com/lin-jim-leon/kuaishou/open/user"
  12. "log"
  13. "time"
  14. "youngmini_server/app/model/youngee_talent_model"
  15. "youngmini_server/app/utils"
  16. )
  17. const (
  18. //快手电商
  19. ClientKey = "ks651333097154138217"
  20. ClientSecret = "dBt0rVRhTpUqcrOYGGpv0A"
  21. SignSecret = "bf6393dce0a2b669ee348bebb837b0da"
  22. //快手平台
  23. ClientKey1 = "ks671599294546520767"
  24. ClientSecret1 = "8VSrp3O09nunjLMXR1uotg"
  25. //SignSecret1 = "bf6393dce0a2b669ee348bebb837b0da"
  26. //抖音平台
  27. ClientKey2 = "awi77xl5kpl16hmi"
  28. ClientSecret2 = "7ce6d2531bd4489122d89658063fd76e"
  29. //SignSecret1 = "bf6393dce0a2b669ee348bebb837b0da"
  30. )
  31. func GetQrcode(r *ghttp.Request) *TalentHttpResult {
  32. //达人id获取
  33. tid, err := utils.SessionTalentInfo.GetTalentIdFromSession(r)
  34. if err != nil {
  35. return &TalentHttpResult{Code: -1, Msg: "Get talent id failed"}
  36. }
  37. println("here")
  38. // 记录开始时间
  39. startTime := time.Now()
  40. // 创建一个新的上下文
  41. ctx, cancel := chromedp.NewContext(context.Background())
  42. // 构建包含 tid 的 urlstr
  43. var urlstr string
  44. typePlatform := r.GetInt("platform_id")
  45. if typePlatform == 4 { //快手电商
  46. urlstr = fmt.Sprintf("https://open.kuaishou.com/oauth2/connect?state=%s&app_id=ks651333097154138217&redirect_uri=https://younggee.com/kuaishouauth&scope=merchant_distribution,merchant_refund,merchant_item,merchant_order,user_info,merchant_servicemarket,merchant_user,merchant_logistics&response_type=code", tid)
  47. } else if typePlatform == 8 { //快手平台
  48. urlstr = fmt.Sprintf("https://open.kuaishou.com/oauth2/connect?state=%s&app_id=ks671599294546520767&redirect_uri=https://younggee.com/kuaishouauthVideo&scope=user_video_info,user_info&response_type=code", tid)
  49. } else if typePlatform == 2 { //抖音平台
  50. urlstr = fmt.Sprintf("https://open.kuaishou.com/oauth2/connect?state=%s&app_id=ks671599294546520767&redirect_uri=https://younggee.com/kuaishouauthVideo&scope=user_video_info,user_info&response_type=code", tid)
  51. } else {
  52. urlstr = "unknow"
  53. }
  54. // 执行任务
  55. //var buf []byte
  56. var text string
  57. var ok bool
  58. var tasks chromedp.Tasks
  59. if typePlatform == 2 { //抖音
  60. tasks = chromedp.Tasks{
  61. chromedp.Navigate(urlstr),
  62. // chromedp.WaitVisible(`#semiTabPanelqr > div > div > div.qr-container > img`, chromedp.ByQuery),
  63. chromedp.AttributeValue(`#semiTabPanelqr > div > div > div.qr-container > img`, "src", &text, &ok),
  64. }
  65. } else { //快手
  66. tasks = chromedp.Tasks{
  67. chromedp.Navigate(urlstr),
  68. // chromedp.WaitVisible(`body > div > div > div > div.qr-code-main > img:nth-child(1)`, chromedp.ByQuery),
  69. chromedp.AttributeValue(`body > div > div > div > div.qr-code-main > img:nth-child(1)`, "src", &text, &ok),
  70. }
  71. }
  72. //浏览器启动!
  73. err = chromedp.Run(ctx, tasks)
  74. if err != nil {
  75. log.Fatal(err)
  76. }
  77. println("text----->", text)
  78. println("ok----->", ok)
  79. println("url----->", urlstr)
  80. fmt.Println("代码运行时间:", time.Since(startTime))
  81. //r.Response.WriteJson(text)
  82. // 在300秒后取消上下文
  83. time.AfterFunc(300*time.Second, func() {
  84. cancel()
  85. })
  86. return &TalentHttpResult{Code: 0, Msg: "success", Data: text}
  87. }
  88. // 检查数据库表中是否有达人对应的数据 且 token未过期
  89. func CheckAccount(r *ghttp.Request) *TalentHttpResult {
  90. fmt.Println("into check")
  91. //达人id获取
  92. tid, err := utils.SessionTalentInfo.GetTalentIdFromSession(r)
  93. if err != nil {
  94. return &TalentHttpResult{Code: -1, Msg: "Get talent id failed"}
  95. }
  96. userInfo := &youngee_talent_model.KuaishouUserInfo{}
  97. err = g.DB().Model(userInfo).Where("talent_id", tid).Scan(&userInfo)
  98. fmt.Println("userInfo*********", userInfo)
  99. if err != nil {
  100. // 查询失败(未找到结果),返回失败结果
  101. return &TalentHttpResult{Code: -1, Msg: "Query failed", Data: nil}
  102. }
  103. //有查询结果,看是否accessToken是否有效
  104. key, err1 := g.DB().Model("platform_kuaishou_user_info").Fields("access_token").Where("talent_id = ?", tid).Value()
  105. if err1 != nil {
  106. return &TalentHttpResult{Code: -1, Msg: "query database fail"}
  107. }
  108. AccessToken := key.String()
  109. _, err2 := user.GetUserinfo(ClientKey, AccessToken)
  110. if err2 != nil {
  111. //前端接收code=-2表示token过期
  112. return &TalentHttpResult{Code: -2, Msg: "accessToken过期", Data: nil}
  113. }
  114. // 查询成功,返回成功结果和数据
  115. return &TalentHttpResult{Code: 0, Msg: "success", Data: userInfo}
  116. }
  117. // 检查数据库表中是否有达人对应的数据,有就删掉,/kuaishouath中会插入。
  118. func CheckNewAccount(r *ghttp.Request) *TalentHttpResult {
  119. //check到了更新时间在两秒内的插入的数据。则说明已绑定。弹窗消失。
  120. //达人id获取
  121. fmt.Println("***********into checknewaccount")
  122. tid, err := utils.SessionTalentInfo.GetTalentIdFromSession(r)
  123. if err != nil {
  124. return &TalentHttpResult{Code: -1, Msg: "Get talent id failed"}
  125. }
  126. // 获取当前时间
  127. currentTime := gtime.Now()
  128. // 查询数据库中是否有符合条件的数据
  129. userInfo := &youngee_talent_model.KuaishouUserInfo{}
  130. err = g.DB().Model("platform_kuaishou_user_info").
  131. Where("talent_id = ?", tid).
  132. Scan(&userInfo)
  133. if err != nil {
  134. return &TalentHttpResult{Code: -2, Msg: "platform_kuaishou_user_info query failed"}
  135. }
  136. //找到数据,判断时间差
  137. if userInfo != nil {
  138. // 计算创建时间与当前时间的差值
  139. timeDiff := currentTime.Sub(userInfo.CreateTime)
  140. fmt.Println("***********kifasfa", timeDiff)
  141. if timeDiff <= 3*time.Second {
  142. return &TalentHttpResult{Code: 0, Msg: "success", Data: nil}
  143. }
  144. }
  145. // 如果没有符合条件的数据,返回失败
  146. return &TalentHttpResult{Code: -20, Msg: "No valid data found", Data: nil}
  147. }
  148. func CheckTokenExp(r *ghttp.Request) *TalentHttpResult {
  149. //达人id获取
  150. tid, err := utils.SessionTalentInfo.GetTalentIdFromSession(r)
  151. if err != nil {
  152. return &TalentHttpResult{Code: -1, Msg: "Get talent id failed"}
  153. }
  154. key, err1 := g.DB().Model("platform_kuaishou_user_info").Fields("access_token").Where("talent_id = ?", tid).Value()
  155. if err1 != nil {
  156. return &TalentHttpResult{Code: -1, Msg: "query database fail"}
  157. }
  158. AccessToken := key.String()
  159. res_info, err2 := user.GetUserinfo(ClientKey, AccessToken)
  160. if err2 != nil {
  161. //前端接收code=-2表示token过期
  162. return &TalentHttpResult{Code: -2, Msg: "accessToken过期", Data: nil}
  163. }
  164. // 查询成功,返回成功结果和数据
  165. return &TalentHttpResult{Code: 0, Msg: "success", Data: res_info}
  166. }
  167. func AddWindow(r *ghttp.Request) *TalentHttpResult {
  168. pId := r.GetString("product_id")
  169. //通过pId获取kuaishou_product_id
  170. pIdSlice := []string{pId}
  171. //达人id获取
  172. tid, err := utils.SessionTalentInfo.GetTalentIdFromSession(r)
  173. //加入橱窗-条件不满足的快手账号不能被选中
  174. //条件1. 没有开通橱窗
  175. //判断此快手账号是否绑定了两
  176. openId := r.GetString("open_id")
  177. // 执行数据库查询
  178. count, err := g.DB().Model("platform_kuaishou_user_info").
  179. Where("talent_id = ? AND open_id = ?", tid, openId).
  180. Count()
  181. if err != nil {
  182. // 处理错误
  183. return &TalentHttpResult{Code: -4, Msg: "出错了"}
  184. }
  185. if count != 2 {
  186. return &TalentHttpResult{Code: -5, Msg: "达人需要授权两个码"}
  187. }
  188. if err != nil {
  189. return &TalentHttpResult{Code: -1, Msg: "Get talent id failed"}
  190. }
  191. key, err := g.DB().Model("platform_kuaishou_user_info").Fields("access_token").Where("talent_id = ?", tid).Value()
  192. if err != nil {
  193. return &TalentHttpResult{Code: -2, Msg: "query database fail"}
  194. }
  195. AccessToken := key.String()
  196. res_info, err := merchant.AddItemsToShelf(ClientKey, SignSecret, AccessToken, pIdSlice)
  197. if err != nil {
  198. //前端接收code=-3表示添加失敗,沒有開通
  199. return &TalentHttpResult{Code: -3, Msg: "未開通、商品不存在或已下线", Data: nil}
  200. }
  201. // 查询成功,返回成功结果和数据
  202. return &TalentHttpResult{Code: 0, Msg: "加入橱窗成功", Data: res_info}
  203. }
  204. func GetKuaishouFansNum(r *ghttp.Request) *TalentHttpResult {
  205. //达人id获取
  206. tid, err := utils.SessionTalentInfo.GetTalentIdFromSession(r)
  207. fmt.Println("********&&&&&&&&&&,tid", tid)
  208. if err != nil {
  209. return &TalentHttpResult{Code: -1, Msg: "Get talent id failed"}
  210. }
  211. key, err1 := g.DB().Model("platform_kuaishou_user_info").Fields("access_token").Where("talent_id = ? ", tid).Value()
  212. if err1 != nil {
  213. return &TalentHttpResult{Code: -2, Msg: "query database fail"}
  214. }
  215. AccessToken := key.String()
  216. res_user, err2 := user.GetUserinfo(ClientKey, AccessToken)
  217. if err2 != nil {
  218. //前端接收code=-3表示添加失敗,沒有開通
  219. return &TalentHttpResult{Code: -3, Msg: "获取快手用户信息出错", Data: nil}
  220. }
  221. // 查询成功,返回成功结果和数据
  222. return &TalentHttpResult{Code: 0, Msg: "获取快手用户信息成功", Data: res_user.Data}
  223. }
  224. func QuerySalesFor30Days(r *ghttp.Request) *TalentHttpResult {
  225. fmt.Println("into querySalesFor30Days")
  226. ClientKey := "ks651333097154138217"
  227. //ClientSecret := "dBt0rVRhTpUqcrOYGGpv0A"
  228. SignSecret := "bf6393dce0a2b669ee348bebb837b0da"
  229. tid, _ := utils.SessionTalentInfo.GetTalentIdFromSession(r)
  230. // 创建一个 KuaishouUserInfo 结构体的实例
  231. userInfo := &youngee_talent_model.KuaishouUserInfo{}
  232. // 查询数据库中的 access_token 字段
  233. // 使用 g.DB() 获取数据库连接,并执行查询
  234. key, err := g.DB().Model(userInfo).Fields("access_token").Where("talent_id = ?", tid).Value()
  235. AccessToken := key.String()
  236. if err != nil {
  237. // 处理错误
  238. fmt.Println("Error querying access_token:", err)
  239. }
  240. // 输出查询到的 access_token 值
  241. fmt.Println("Access Token:", AccessToken)
  242. // 获取当前时间的时间戳(毫秒)
  243. currentTime := time.Now().UnixNano() / int64(time.Millisecond)
  244. // 30天前的时间戳(毫秒)
  245. beginTime30DaysAgo := currentTime - 30*24*60*60*1000
  246. // 定义每段查询的天数
  247. intervalDays := 7
  248. intervalMillis := int64(intervalDays * 24 * 60 * 60 * 1000)
  249. // 初始化 beginTime 和 endTime
  250. beginTime := beginTime30DaysAgo
  251. endTime := beginTime + intervalMillis
  252. saleNum := 0 //30天总销量
  253. // 循环查询,先处理四个7天的时间段
  254. for i := 0; i < 4; i++ {
  255. // 调整 endTime,确保不会超过当前时间
  256. if endTime > currentTime {
  257. endTime = currentTime
  258. }
  259. saleNum += GetSaleNumByDayInterval(ClientKey, SignSecret, AccessToken, beginTime, endTime)
  260. // 更新时间段
  261. beginTime = endTime
  262. endTime = beginTime + intervalMillis
  263. }
  264. // 最后处理剩余的2天时间段
  265. endTime = currentTime
  266. saleNum += GetSaleNumByDayInterval(ClientKey, SignSecret, AccessToken, beginTime, endTime)
  267. // 查询成功,返回成功结果和数据
  268. return &TalentHttpResult{Code: 0, Msg: "获取30天销售量成功", Data: saleNum}
  269. }
  270. func QueryOkSaleNum(r *ghttp.Request) *TalentHttpResult {
  271. tid, _ := utils.SessionTalentInfo.GetTalentIdFromSession(r)
  272. // 创建一个 KuaishouUserInfo 结构体的实例
  273. userInfo := &youngee_talent_model.KuaishouUserInfo{}
  274. // 查询数据库中的 access_token 字段
  275. // 使用 g.DB() 获取数据库连接,并执行查询
  276. key, err := g.DB().Model(userInfo).Fields("access_token").Where("talent_id = ?", tid).Value()
  277. AccessToken := key.String()
  278. if err != nil {
  279. // 处理错误
  280. fmt.Println("Error querying access_token:", err)
  281. }
  282. if key == nil {
  283. // 处理错误
  284. fmt.Println("can not find talentId's bindinfo :", err)
  285. }
  286. //循环使用接口
  287. //
  288. // 获取当前时间的时间戳(毫秒)
  289. currentTime := time.Now().UnixNano() / int64(time.Millisecond)
  290. // 90天前的时间戳(毫秒)
  291. beginTime90DaysAgo := currentTime - 90*24*60*60*1000
  292. // 定义每段查询的天数
  293. intervalDays := 7
  294. intervalMillis := int64(intervalDays * 24 * 60 * 60 * 1000)
  295. // 初始化 beginTime 和 endTime
  296. beginTime := beginTime90DaysAgo
  297. endTime := beginTime + intervalMillis
  298. saleNum := 0 //90天总销量
  299. // 循环查询,先处理四个7天的时间段
  300. for i := 0; i < 12; i++ {
  301. // 调整 endTime,确保不会超过当前时间
  302. if endTime > currentTime {
  303. endTime = currentTime
  304. }
  305. saleNum += GetSaleNumByDayInterval_Ok(ClientKey, SignSecret, AccessToken, beginTime, endTime)
  306. // 更新时间段
  307. beginTime = endTime
  308. endTime = beginTime + intervalMillis
  309. }
  310. // 最后处理剩余的6天时间段
  311. endTime = currentTime
  312. saleNum += GetSaleNumByDayInterval_Ok(ClientKey, SignSecret, AccessToken, beginTime, endTime)
  313. // 查询成功,返回成功结果和数据
  314. return &TalentHttpResult{Code: 0, Msg: "获取30天销售量成功", Data: saleNum}
  315. }
  316. func DyLikeCount(r *ghttp.Request) *TalentHttpResult {
  317. tid, _ := utils.SessionTalentInfo.GetTalentIdFromSession(r)
  318. // 创建一个 KuaishouUserInfo 结构体的实例
  319. userInfo := &youngee_talent_model.KuaishouUserInfo{}
  320. // 查询数据库中的 access_token 字段
  321. // 使用 g.DB() 获取数据库连接,并执行查询
  322. key, err := g.DB().Model(userInfo).Fields("access_token").Where("talent_id = ? AND platform_id = ?", tid, 2).Value()
  323. AccessToken := key.String()
  324. if err != nil {
  325. // 处理错误
  326. fmt.Println("Error querying access_token:", err)
  327. }
  328. if key == nil {
  329. // 处理错误
  330. fmt.Println("can not find talentId's bindinfo :", err)
  331. }
  332. //todo : API
  333. count, err := GetLikeCount(ClientKey1, AccessToken)
  334. return &TalentHttpResult{Code: 0, Msg: "获取总点赞数成功", Data: count}
  335. }
  336. func DyVideoCount(r *ghttp.Request) *TalentHttpResult {
  337. tid, _ := utils.SessionTalentInfo.GetTalentIdFromSession(r)
  338. // 创建一个 KuaishouUserInfo 结构体的实例
  339. userInfo := &youngee_talent_model.KuaishouUserInfo{}
  340. // 查询数据库中的 access_token 字段
  341. // 使用 g.DB() 获取数据库连接,并执行查询
  342. key, err := g.DB().Model(userInfo).Fields("access_token").Where("talent_id = ? AND platform_id = ?", tid, 2).Value()
  343. AccessToken := key.String()
  344. if err != nil {
  345. // 处理错误
  346. fmt.Println("Error querying access_token:", err)
  347. }
  348. if key == nil {
  349. // 处理错误
  350. fmt.Println("can not find talentId's bindinfo :", err)
  351. }
  352. //todo : API
  353. count, err := GetLikeCount(ClientKey1, AccessToken)
  354. return &TalentHttpResult{Code: 0, Msg: "获取总点赞数成功", Data: count}
  355. }
  356. func VideoCount(r *ghttp.Request) *TalentHttpResult {
  357. tid, _ := utils.SessionTalentInfo.GetTalentIdFromSession(r)
  358. // 创建一个 KuaishouUserInfo 结构体的实例
  359. userInfo := &youngee_talent_model.KuaishouUserInfo{}
  360. // 查询数据库中的 access_token 字段
  361. // 使用 g.DB() 获取数据库连接,并执行查询
  362. key, err := g.DB().Model(userInfo).Fields("access_token").Where("talent_id = ? AND platform_id = ?", tid, 8).Value()
  363. AccessToken := key.String()
  364. if err != nil {
  365. // 处理错误
  366. fmt.Println("Error querying access_token:", err)
  367. }
  368. if key == nil {
  369. // 处理错误
  370. fmt.Println("can not find talentId's bindinfo :", err)
  371. }
  372. count, err := GetVideoCount(ClientKey1, AccessToken)
  373. return &TalentHttpResult{Code: 0, Msg: "获取总作品数成功", Data: count}
  374. }
  375. func LikeCount(r *ghttp.Request) *TalentHttpResult {
  376. tid, _ := utils.SessionTalentInfo.GetTalentIdFromSession(r)
  377. // 创建一个 KuaishouUserInfo 结构体的实例
  378. userInfo := &youngee_talent_model.KuaishouUserInfo{}
  379. // 查询数据库中的 access_token 字段
  380. // 使用 g.DB() 获取数据库连接,并执行查询
  381. key, err := g.DB().Model(userInfo).Fields("access_token").Where("talent_id = ? AND platform_id = ?", tid, 8).Value()
  382. AccessToken := key.String()
  383. if err != nil {
  384. // 处理错误
  385. fmt.Println("Error querying access_token:", err)
  386. }
  387. if key == nil {
  388. // 处理错误
  389. fmt.Println("can not find talentId's bindinfo :", err)
  390. }
  391. count, err := GetLikeCount(ClientKey1, AccessToken)
  392. return &TalentHttpResult{Code: 0, Msg: "获取总点赞数成功", Data: count}
  393. }
  394. // 获取用户快手平台账号列表
  395. func GetKuaishouList(r *ghttp.Request) *TalentHttpResult {
  396. // 从 session 中获取 talent_id
  397. tid, _ := utils.SessionTalentInfo.GetTalentIdFromSession(r)
  398. userInfo := &youngee_talent_model.KuaishouUserInfo{}
  399. // 查询 platformId 为 8 或 4 的所有数据
  400. results, err := g.DB().Model(userInfo).Where("talent_id = ?", tid).
  401. Where("platform_Id IN (?, ?)", 4, 8).
  402. Order("platform_Id DESC").
  403. All()
  404. if err != nil {
  405. fmt.Println("Error querying access_token:", err)
  406. return &TalentHttpResult{Code: -1, Msg: "查询出错", Data: nil}
  407. }
  408. // 检查查询结果是否为空
  409. if results.IsEmpty() {
  410. return &TalentHttpResult{Code: -2, Msg: "此达人无快手账号绑定", Data: nil}
  411. }
  412. // 使用集合来存储唯一的 open_id,并计算不同的 open_id 的个数
  413. openIDSet := make(map[string]struct{})
  414. userInfoMap := make(map[string]*youngee_talent_model.KuaishouUserInfo)
  415. for _, record := range results.List() {
  416. openID := gconv.String(record["open_id"])
  417. platformID := record["platform_id"] //int类型
  418. status := 0 //初始化
  419. // 检查 userInfoMap 中是否已经存在 openID
  420. //肯定会先处理8,所以遇到重复情况肯定是两个都授权了
  421. _, exists := userInfoMap[openID]
  422. if exists {
  423. status = 1 //同时授权了两个码
  424. userInfoMap[openID] = &youngee_talent_model.KuaishouUserInfo{
  425. OpenId: openID,
  426. HeadUri: gconv.String(record["head_uri"]),
  427. NickName: gconv.String(record["nick_name"]),
  428. // 添加其他需要的字段
  429. Fan: gconv.Int(record["fan"]),
  430. //这两个值默认为0
  431. LikeNum: gconv.Int(record["like_num"]),
  432. VideoNum: gconv.Int(record["video_num"]),
  433. Status: status,
  434. }
  435. }
  436. //若同时有8和4的平台。处理了8就不会处理4了
  437. if !exists {
  438. //只有一个且为4
  439. if platformID == 4 {
  440. status = 2 //仅授权了电商
  441. } else {
  442. status = 3 //仅授权了平台
  443. }
  444. openIDSet[openID] = struct{}{}
  445. // 根据 platformID 赋值
  446. userInfoMap[openID] = &youngee_talent_model.KuaishouUserInfo{
  447. OpenId: openID,
  448. HeadUri: gconv.String(record["head_uri"]),
  449. NickName: gconv.String(record["nick_name"]),
  450. // 添加其他需要的字段
  451. Fan: gconv.Int(record["fan"]),
  452. //这两个值默认为0
  453. LikeNum: gconv.Int(record["like_num"]),
  454. VideoNum: gconv.Int(record["video_num"]),
  455. Status: status,
  456. }
  457. }
  458. }
  459. // 构建 UserInfo 列表 参数分别表示初始长度和容量
  460. userInfoList := make([]*youngee_talent_model.KuaishouUserInfo, 0, len(userInfoMap))
  461. for _, info := range userInfoMap {
  462. //将 info 添加到 userInfoList 列表的末尾。
  463. userInfoList = append(userInfoList, info)
  464. }
  465. // 计算不同的 open_id 的个数
  466. uniqueOpenIDCount := len(openIDSet)
  467. // 创建 KSListResult 变量并赋值
  468. ksListResult := &youngee_talent_model.KSListResult{
  469. Count: uniqueOpenIDCount,
  470. UserInfo: userInfoList,
  471. }
  472. // 返回结果
  473. return &TalentHttpResult{Code: 1, Msg: "返回快手列表成功", Data: ksListResult}
  474. }
  475. // 获取用户快手平台账号列表
  476. func GetKuaishouListWithCondition(r *ghttp.Request) *TalentHttpResult {
  477. // 从 session 中获取 talent_id
  478. tid, _ := utils.SessionTalentInfo.GetTalentIdFromSession(r)
  479. userInfo := &youngee_talent_model.KuaishouUserInfo{}
  480. //1.获取该tid下的所有账户信息
  481. //2.openid去重,遍历userInfoMap<openid,userInfo>openid对应了两个accesstokn就都去验证是否过期
  482. //3.openId对应的accessToken调用是否过期接口,过期则use_code=1
  483. //4.调用是否已领取接口 ,领取则use_code=2
  484. //5.领样条件(粉丝数+橱窗销量)不满足 use_code=3
  485. // 创建 KSListResult 变量并赋值
  486. ksListResult := &youngee_talent_model.KSListResult{
  487. Count: uniqueOpenIDCount,
  488. UserInfo: userInfoList,
  489. }
  490. // 返回结果
  491. return &TalentHttpResult{Code: 1, Msg: "返回快手列表成功", Data: ksListResult}
  492. }
  493. func QuerySalesFor90Days(r *ghttp.Request) *TalentHttpResult {
  494. tid, _ := utils.SessionTalentInfo.GetTalentIdFromSession(r)
  495. // 创建一个 KuaishouUserInfo 结构体的实例
  496. userInfo := &youngee_talent_model.KuaishouUserInfo{}
  497. // 查询数据库中的 access_token 字段
  498. // 使用 g.DB() 获取数据库连接,并执行查询
  499. key, err := g.DB().Model(userInfo).Fields("access_token").Where("talent_id = ?", tid).Value()
  500. AccessToken := key.String()
  501. if err != nil {
  502. // 处理错误
  503. fmt.Println("Error querying access_token:", err)
  504. }
  505. if key == nil {
  506. // 处理错误
  507. fmt.Println("can not find talentId's bindinfo :", err)
  508. }
  509. //循环使用接口
  510. //
  511. // 获取当前时间的时间戳(毫秒)
  512. currentTime := time.Now().UnixNano() / int64(time.Millisecond)
  513. // 30天前的时间戳(毫秒)
  514. beginTime90DaysAgo := currentTime - 90*24*60*60*1000
  515. // 定义每段查询的天数
  516. intervalDays := 7
  517. intervalMillis := int64(intervalDays * 24 * 60 * 60 * 1000)
  518. // 初始化 beginTime 和 endTime
  519. beginTime := beginTime90DaysAgo
  520. endTime := beginTime + intervalMillis
  521. saleNum := 0 //90天总销量
  522. // 循环查询,先处理四个7天的时间段
  523. for i := 0; i < 12; i++ {
  524. // 调整 endTime,确保不会超过当前时间
  525. if endTime > currentTime {
  526. endTime = currentTime
  527. }
  528. saleNum += GetSaleNumByDayInterval(ClientKey, SignSecret, AccessToken, beginTime, endTime)
  529. // 更新时间段
  530. beginTime = endTime
  531. endTime = beginTime + intervalMillis
  532. }
  533. // 最后处理剩余的6天时间段
  534. endTime = currentTime
  535. saleNum += GetSaleNumByDayInterval(ClientKey, SignSecret, AccessToken, beginTime, endTime)
  536. // 查询成功,返回成功结果和数据
  537. return &TalentHttpResult{Code: 0, Msg: "获取30天销售量成功", Data: saleNum}
  538. }
  539. func GetSaleNumByDayInterval(ClientKey string, SignSecret string, AccessToken string, beginTime int64, endTime int64) int {
  540. pageSize := 100
  541. totalSaleNum := 0
  542. // 定义要查询的订单状态
  543. // [30:已付款] [50:已收货] [60:已结算] [80:已失效]
  544. statuses := []int{30, 50, 60}
  545. // 遍历所有订单状态并调用 Corderlist 函数
  546. for _, status := range statuses {
  547. // 初始化 pcursor
  548. pcursor := ""
  549. for {
  550. // 调用 Corderlist 函数获取订单列表
  551. response, err := merchant.Corderlist(ClientKey, SignSecret, AccessToken, status, pageSize, beginTime, endTime, pcursor)
  552. fmt.Println("response********", response)
  553. if err != nil {
  554. fmt.Printf("Error calling Corderlist: %v\n", err)
  555. break
  556. }
  557. // 检查响应代码
  558. if response.Code != "1" {
  559. fmt.Printf("Corderlist response error: %s\n", response.Msg)
  560. break
  561. }
  562. // 累加订单中商品的数量
  563. for _, order := range response.Data.OrderViews {
  564. for _, product := range order.CPSOrderProductViews {
  565. totalSaleNum += product.Num
  566. }
  567. }
  568. // 检查分页指针 pcursor
  569. //100个订单以内的情况
  570. if response.Data.Cursor == "nomore" {
  571. break
  572. }
  573. //大于等于100个订单
  574. // 更新 pcursor 以获取下一页数据
  575. pcursor = response.Data.Cursor
  576. // 处理分页后的数据
  577. // 如果 pcursor 不是 "nomore",我们需要累加最后一条订单的数量
  578. if len(response.Data.OrderViews) > 0 {
  579. lastOrder := response.Data.OrderViews[len(response.Data.OrderViews)-1]
  580. if len(lastOrder.CPSOrderProductViews) > 0 {
  581. lastProduct := lastOrder.CPSOrderProductViews[len(lastOrder.CPSOrderProductViews)-1]
  582. totalSaleNum += lastProduct.Num
  583. }
  584. }
  585. }
  586. }
  587. return totalSaleNum
  588. }
  589. func GetSaleNumByDayInterval_Ok(ClientKey string, SignSecret string, AccessToken string, beginTime int64, endTime int64) int {
  590. pageSize := 100
  591. totalSaleNum := 0
  592. // 定义要查询的订单状态
  593. // [30:已付款] [50:已收货] [60:已结算] [80:已失效]
  594. statuses := []int{60}
  595. // 遍历所有订单状态并调用 Corderlist 函数
  596. for _, status := range statuses {
  597. // 初始化 pcursor
  598. pcursor := ""
  599. for {
  600. // 调用 Corderlist 函数获取订单列表
  601. response, err := merchant.Corderlist(ClientKey, SignSecret, AccessToken, status, pageSize, beginTime, endTime, pcursor)
  602. fmt.Println("response********", response)
  603. if err != nil {
  604. fmt.Printf("Error calling Corderlist: %v\n", err)
  605. break
  606. }
  607. // 检查响应代码
  608. if response.Code != "1" {
  609. fmt.Printf("Corderlist response error: %s\n", response.Msg)
  610. break
  611. }
  612. // 累加订单中商品的数量
  613. for _, order := range response.Data.OrderViews {
  614. for _, product := range order.CPSOrderProductViews {
  615. totalSaleNum += product.Num
  616. }
  617. }
  618. // 检查分页指针 pcursor
  619. //100个订单以内的情况
  620. if response.Data.Cursor == "nomore" {
  621. break
  622. }
  623. //大于等于100个订单
  624. // 更新 pcursor 以获取下一页数据
  625. pcursor = response.Data.Cursor
  626. // 处理分页后的数据
  627. // 如果 pcursor 不是 "nomore",我们需要累加最后一条订单的数量
  628. if len(response.Data.OrderViews) > 0 {
  629. lastOrder := response.Data.OrderViews[len(response.Data.OrderViews)-1]
  630. if len(lastOrder.CPSOrderProductViews) > 0 {
  631. lastProduct := lastOrder.CPSOrderProductViews[len(lastOrder.CPSOrderProductViews)-1]
  632. totalSaleNum += lastProduct.Num
  633. }
  634. }
  635. }
  636. }
  637. return totalSaleNum
  638. }