talent_ks_auth.go 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458
  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/lin-jim-leon/kuaishou/open/merchant"
  10. "github.com/lin-jim-leon/kuaishou/open/user"
  11. "log"
  12. "time"
  13. "youngmini_server/app/model/youngee_talent_model"
  14. "youngmini_server/app/utils"
  15. )
  16. const (
  17. ClientKey = "ks651333097154138217"
  18. ClientSecret = "dBt0rVRhTpUqcrOYGGpv0A"
  19. SignSecret = "bf6393dce0a2b669ee348bebb837b0da"
  20. )
  21. func GetQrcode(r *ghttp.Request) *TalentHttpResult {
  22. //达人id获取
  23. tid, err := utils.SessionTalentInfo.GetTalentIdFromSession(r)
  24. if err != nil {
  25. return &TalentHttpResult{Code: -1, Msg: "Get talent id failed"}
  26. }
  27. println("here")
  28. // 记录开始时间
  29. startTime := time.Now()
  30. // 创建一个新的上下文
  31. ctx, cancel := chromedp.NewContext(context.Background())
  32. // 构建包含 tid 的 urlstr
  33. 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)
  34. // 执行任务
  35. //var buf []byte
  36. var text string
  37. var ok bool
  38. //浏览器启动!
  39. err = chromedp.Run(ctx,
  40. //打开授权网址
  41. chromedp.Navigate(urlstr),
  42. //等待元素可见
  43. //chromedp.WaitVisible(`#semiTabPanelqr > div > div > div.qr-container > img`, chromedp.ByQuery),
  44. // 获取元素的src属性值
  45. //chromedp.AttributeValue(`#semiTabPanelqr > div > div > div.qr-container > img`, "src", &text, &ok), //抖音
  46. chromedp.AttributeValue(`body > div > div > div > div.qr-code-main > img:nth-child(1)`, "src", &text, &ok), //快手
  47. //chromedp.AttributeValue(`#app > div > section > header > div > div.head-menu > ul > li:nth-child(1) > img`, "src", &text, &ok),
  48. )
  49. if err != nil {
  50. log.Fatal(err)
  51. }
  52. println("text----->", text)
  53. println("ok----->", ok)
  54. println("url----->", urlstr)
  55. fmt.Println("代码运行时间:", time.Since(startTime))
  56. //r.Response.WriteJson(text)
  57. // 在300秒后取消上下文
  58. time.AfterFunc(300*time.Second, func() {
  59. cancel()
  60. })
  61. return &TalentHttpResult{Code: 0, Msg: "success", Data: text}
  62. }
  63. // 检查数据库表中是否有达人对应的数据 且 token未过期
  64. func CheckAccount(r *ghttp.Request) *TalentHttpResult {
  65. fmt.Println("into check")
  66. //达人id获取
  67. tid, err := utils.SessionTalentInfo.GetTalentIdFromSession(r)
  68. if err != nil {
  69. return &TalentHttpResult{Code: -1, Msg: "Get talent id failed"}
  70. }
  71. userInfo := &youngee_talent_model.KuaishouUserInfo{}
  72. err = g.DB().Model(userInfo).Where("talent_id", tid).Scan(&userInfo)
  73. fmt.Println("userInfo*********", userInfo)
  74. if err != nil {
  75. // 查询失败(未找到结果),返回失败结果
  76. return &TalentHttpResult{Code: -1, Msg: "Query failed", Data: nil}
  77. }
  78. //有查询结果,看是否accessToken是否有效
  79. key, err1 := g.DB().Model("platform_kuaishou_user_info").Fields("access_token").Where("talent_id = ?", tid).Value()
  80. if err1 != nil {
  81. return &TalentHttpResult{Code: -1, Msg: "query database fail"}
  82. }
  83. AccessToken := key.String()
  84. _, err2 := user.GetUserinfo(ClientKey, AccessToken)
  85. if err2 != nil {
  86. //前端接收code=-2表示token过期
  87. return &TalentHttpResult{Code: -2, Msg: "accessToken过期", Data: nil}
  88. }
  89. // 查询成功,返回成功结果和数据
  90. return &TalentHttpResult{Code: 0, Msg: "success", Data: userInfo}
  91. }
  92. // 检查数据库表中是否有达人对应的数据,有就删掉,/kuaishouath中会插入。
  93. func CheckNewAccount(r *ghttp.Request) *TalentHttpResult {
  94. //check到了更新时间在两秒内的插入的数据。则说明已绑定。弹窗消失。
  95. //达人id获取
  96. fmt.Println("***********into checknewaccount")
  97. tid, err := utils.SessionTalentInfo.GetTalentIdFromSession(r)
  98. if err != nil {
  99. return &TalentHttpResult{Code: -1, Msg: "Get talent id failed"}
  100. }
  101. // 获取当前时间
  102. currentTime := gtime.Now()
  103. // 查询数据库中是否有符合条件的数据
  104. userInfo := &youngee_talent_model.KuaishouUserInfo{}
  105. err = g.DB().Model("platform_kuaishou_user_info").
  106. Where("talent_id = ?", tid).
  107. Scan(&userInfo)
  108. if err != nil {
  109. return &TalentHttpResult{Code: -2, Msg: "platform_kuaishou_user_info query failed"}
  110. }
  111. //找到数据,判断时间差
  112. if userInfo != nil {
  113. // 计算创建时间与当前时间的差值
  114. timeDiff := currentTime.Sub(userInfo.CreateTime)
  115. fmt.Println("***********kifasfa", timeDiff)
  116. if timeDiff <= 3*time.Second {
  117. return &TalentHttpResult{Code: 0, Msg: "success", Data: nil}
  118. }
  119. }
  120. // 如果没有符合条件的数据,返回失败
  121. return &TalentHttpResult{Code: -20, Msg: "No valid data found", Data: nil}
  122. }
  123. func CheckTokenExp(r *ghttp.Request) *TalentHttpResult {
  124. //达人id获取
  125. tid, err := utils.SessionTalentInfo.GetTalentIdFromSession(r)
  126. if err != nil {
  127. return &TalentHttpResult{Code: -1, Msg: "Get talent id failed"}
  128. }
  129. key, err1 := g.DB().Model("platform_kuaishou_user_info").Fields("access_token").Where("talent_id = ?", tid).Value()
  130. if err1 != nil {
  131. return &TalentHttpResult{Code: -1, Msg: "query database fail"}
  132. }
  133. AccessToken := key.String()
  134. res_info, err2 := user.GetUserinfo(ClientKey, AccessToken)
  135. if err2 != nil {
  136. //前端接收code=-2表示token过期
  137. return &TalentHttpResult{Code: -2, Msg: "accessToken过期", Data: nil}
  138. }
  139. // 查询成功,返回成功结果和数据
  140. return &TalentHttpResult{Code: 0, Msg: "success", Data: res_info}
  141. }
  142. func AddWindow(r *ghttp.Request) *TalentHttpResult {
  143. pId := r.GetString("product_id")
  144. //通过pId获取kuaishou_product_id
  145. pIdSlice := []string{pId}
  146. //达人id获取
  147. tid, err := utils.SessionTalentInfo.GetTalentIdFromSession(r)
  148. if err != nil {
  149. return &TalentHttpResult{Code: -1, Msg: "Get talent id failed"}
  150. }
  151. key, err1 := g.DB().Model("platform_kuaishou_user_info").Fields("access_token").Where("talent_id = ?", tid).Value()
  152. if err1 != nil {
  153. return &TalentHttpResult{Code: -2, Msg: "query database fail"}
  154. }
  155. AccessToken := key.String()
  156. res_info, err2 := merchant.AddItemsToShelf(ClientKey, SignSecret, AccessToken, pIdSlice)
  157. if err2 != nil {
  158. //前端接收code=-3表示添加失敗,沒有開通
  159. return &TalentHttpResult{Code: -3, Msg: "未開通、商品不存在或已下线", Data: nil}
  160. }
  161. // 查询成功,返回成功结果和数据
  162. return &TalentHttpResult{Code: 0, Msg: "加入橱窗成功", Data: res_info}
  163. }
  164. func GetKuaishouFansNum(r *ghttp.Request) *TalentHttpResult {
  165. //达人id获取
  166. tid, err := utils.SessionTalentInfo.GetTalentIdFromSession(r)
  167. fmt.Println("********&&&&&&&&&&,tid", tid)
  168. if err != nil {
  169. return &TalentHttpResult{Code: -1, Msg: "Get talent id failed"}
  170. }
  171. key, err1 := g.DB().Model("platform_kuaishou_user_info").Fields("access_token").Where("talent_id = ?", tid).Value()
  172. if err1 != nil {
  173. return &TalentHttpResult{Code: -2, Msg: "query database fail"}
  174. }
  175. AccessToken := key.String()
  176. res_user, err2 := user.GetUserinfo(ClientKey, AccessToken)
  177. if err2 != nil {
  178. //前端接收code=-3表示添加失敗,沒有開通
  179. return &TalentHttpResult{Code: -3, Msg: "获取快手用户信息出错", Data: nil}
  180. }
  181. // 查询成功,返回成功结果和数据
  182. return &TalentHttpResult{Code: 0, Msg: "获取快手用户信息成功", Data: res_user.Data}
  183. }
  184. func QuerySalesFor30Days(r *ghttp.Request) *TalentHttpResult {
  185. fmt.Println("into querySalesFor30Days")
  186. ClientKey := "ks651333097154138217"
  187. //ClientSecret := "dBt0rVRhTpUqcrOYGGpv0A"
  188. SignSecret := "bf6393dce0a2b669ee348bebb837b0da"
  189. tid, _ := utils.SessionTalentInfo.GetTalentIdFromSession(r)
  190. // 创建一个 KuaishouUserInfo 结构体的实例
  191. userInfo := &youngee_talent_model.KuaishouUserInfo{}
  192. // 查询数据库中的 access_token 字段
  193. // 使用 g.DB() 获取数据库连接,并执行查询
  194. key, err := g.DB().Model(userInfo).Fields("access_token").Where("talent_id = ?", tid).Value()
  195. AccessToken := key.String()
  196. if err != nil {
  197. // 处理错误
  198. fmt.Println("Error querying access_token:", err)
  199. }
  200. // 输出查询到的 access_token 值
  201. fmt.Println("Access Token:", AccessToken)
  202. // 获取当前时间的时间戳(毫秒)
  203. currentTime := time.Now().UnixNano() / int64(time.Millisecond)
  204. // 30天前的时间戳(毫秒)
  205. beginTime30DaysAgo := currentTime - 30*24*60*60*1000
  206. // 定义每段查询的天数
  207. intervalDays := 7
  208. intervalMillis := int64(intervalDays * 24 * 60 * 60 * 1000)
  209. // 初始化 beginTime 和 endTime
  210. beginTime := beginTime30DaysAgo
  211. endTime := beginTime + intervalMillis
  212. saleNum := 0 //30天总销量
  213. // 循环查询,先处理四个7天的时间段
  214. for i := 0; i < 4; i++ {
  215. // 调整 endTime,确保不会超过当前时间
  216. if endTime > currentTime {
  217. endTime = currentTime
  218. }
  219. saleNum += GetSaleNumByDayInterval(ClientKey, SignSecret, AccessToken, beginTime, endTime)
  220. // 更新时间段
  221. beginTime = endTime
  222. endTime = beginTime + intervalMillis
  223. }
  224. // 最后处理剩余的2天时间段
  225. endTime = currentTime
  226. saleNum += GetSaleNumByDayInterval(ClientKey, SignSecret, AccessToken, beginTime, endTime)
  227. // 查询成功,返回成功结果和数据
  228. return &TalentHttpResult{Code: 0, Msg: "获取30天销售量成功", Data: saleNum}
  229. }
  230. func QueryOkSaleNum(r *ghttp.Request) *TalentHttpResult {
  231. tid, _ := utils.SessionTalentInfo.GetTalentIdFromSession(r)
  232. // 创建一个 KuaishouUserInfo 结构体的实例
  233. userInfo := &youngee_talent_model.KuaishouUserInfo{}
  234. // 查询数据库中的 access_token 字段
  235. // 使用 g.DB() 获取数据库连接,并执行查询
  236. key, err := g.DB().Model(userInfo).Fields("access_token").Where("talent_id = ?", tid).Value()
  237. AccessToken := key.String()
  238. if err != nil {
  239. // 处理错误
  240. fmt.Println("Error querying access_token:", err)
  241. }
  242. if key == nil {
  243. // 处理错误
  244. fmt.Println("can not find talentId's bindinfo :", err)
  245. }
  246. //循环使用接口
  247. //
  248. // 获取当前时间的时间戳(毫秒)
  249. currentTime := time.Now().UnixNano() / int64(time.Millisecond)
  250. // 90天前的时间戳(毫秒)
  251. beginTime90DaysAgo := currentTime - 90*24*60*60*1000
  252. // 定义每段查询的天数
  253. intervalDays := 7
  254. intervalMillis := int64(intervalDays * 24 * 60 * 60 * 1000)
  255. // 初始化 beginTime 和 endTime
  256. beginTime := beginTime90DaysAgo
  257. endTime := beginTime + intervalMillis
  258. saleNum := 0 //90天总销量
  259. // 循环查询,先处理四个7天的时间段
  260. for i := 0; i < 12; i++ {
  261. // 调整 endTime,确保不会超过当前时间
  262. if endTime > currentTime {
  263. endTime = currentTime
  264. }
  265. saleNum += GetSaleNumByDayInterval_Ok(ClientKey, SignSecret, AccessToken, beginTime, endTime)
  266. // 更新时间段
  267. beginTime = endTime
  268. endTime = beginTime + intervalMillis
  269. }
  270. // 最后处理剩余的6天时间段
  271. endTime = currentTime
  272. saleNum += GetSaleNumByDayInterval_Ok(ClientKey, SignSecret, AccessToken, beginTime, endTime)
  273. // 查询成功,返回成功结果和数据
  274. return &TalentHttpResult{Code: 0, Msg: "获取30天销售量成功", Data: saleNum}
  275. }
  276. func QuerySalesFor90Days(r *ghttp.Request) *TalentHttpResult {
  277. tid, _ := utils.SessionTalentInfo.GetTalentIdFromSession(r)
  278. // 创建一个 KuaishouUserInfo 结构体的实例
  279. userInfo := &youngee_talent_model.KuaishouUserInfo{}
  280. // 查询数据库中的 access_token 字段
  281. // 使用 g.DB() 获取数据库连接,并执行查询
  282. key, err := g.DB().Model(userInfo).Fields("access_token").Where("talent_id = ?", tid).Value()
  283. AccessToken := key.String()
  284. if err != nil {
  285. // 处理错误
  286. fmt.Println("Error querying access_token:", err)
  287. }
  288. if key == nil {
  289. // 处理错误
  290. fmt.Println("can not find talentId's bindinfo :", err)
  291. }
  292. //循环使用接口
  293. //
  294. // 获取当前时间的时间戳(毫秒)
  295. currentTime := time.Now().UnixNano() / int64(time.Millisecond)
  296. // 30天前的时间戳(毫秒)
  297. beginTime90DaysAgo := currentTime - 90*24*60*60*1000
  298. // 定义每段查询的天数
  299. intervalDays := 7
  300. intervalMillis := int64(intervalDays * 24 * 60 * 60 * 1000)
  301. // 初始化 beginTime 和 endTime
  302. beginTime := beginTime90DaysAgo
  303. endTime := beginTime + intervalMillis
  304. saleNum := 0 //90天总销量
  305. // 循环查询,先处理四个7天的时间段
  306. for i := 0; i < 12; i++ {
  307. // 调整 endTime,确保不会超过当前时间
  308. if endTime > currentTime {
  309. endTime = currentTime
  310. }
  311. saleNum += GetSaleNumByDayInterval(ClientKey, SignSecret, AccessToken, beginTime, endTime)
  312. // 更新时间段
  313. beginTime = endTime
  314. endTime = beginTime + intervalMillis
  315. }
  316. // 最后处理剩余的6天时间段
  317. endTime = currentTime
  318. saleNum += GetSaleNumByDayInterval(ClientKey, SignSecret, AccessToken, beginTime, endTime)
  319. // 查询成功,返回成功结果和数据
  320. return &TalentHttpResult{Code: 0, Msg: "获取30天销售量成功", Data: saleNum}
  321. }
  322. func GetSaleNumByDayInterval(ClientKey string, SignSecret string, AccessToken string, beginTime int64, endTime int64) int {
  323. pageSize := 100
  324. totalSaleNum := 0
  325. // 定义要查询的订单状态
  326. // [30:已付款] [50:已收货] [60:已结算] [80:已失效]
  327. statuses := []int{30, 50, 60}
  328. // 遍历所有订单状态并调用 Corderlist 函数
  329. for _, status := range statuses {
  330. // 初始化 pcursor
  331. pcursor := ""
  332. for {
  333. // 调用 Corderlist 函数获取订单列表
  334. response, err := merchant.Corderlist(ClientKey, SignSecret, AccessToken, status, pageSize, beginTime, endTime, pcursor)
  335. fmt.Println("response********", response)
  336. if err != nil {
  337. fmt.Printf("Error calling Corderlist: %v\n", err)
  338. break
  339. }
  340. // 检查响应代码
  341. if response.Code != "1" {
  342. fmt.Printf("Corderlist response error: %s\n", response.Msg)
  343. break
  344. }
  345. // 累加订单中商品的数量
  346. for _, order := range response.Data.OrderViews {
  347. for _, product := range order.CPSOrderProductViews {
  348. totalSaleNum += product.Num
  349. }
  350. }
  351. // 检查分页指针 pcursor
  352. //100个订单以内的情况
  353. if response.Data.Cursor == "nomore" {
  354. break
  355. }
  356. //大于等于100个订单
  357. // 更新 pcursor 以获取下一页数据
  358. pcursor = response.Data.Cursor
  359. // 处理分页后的数据
  360. // 如果 pcursor 不是 "nomore",我们需要累加最后一条订单的数量
  361. if len(response.Data.OrderViews) > 0 {
  362. lastOrder := response.Data.OrderViews[len(response.Data.OrderViews)-1]
  363. if len(lastOrder.CPSOrderProductViews) > 0 {
  364. lastProduct := lastOrder.CPSOrderProductViews[len(lastOrder.CPSOrderProductViews)-1]
  365. totalSaleNum += lastProduct.Num
  366. }
  367. }
  368. }
  369. }
  370. return totalSaleNum
  371. }
  372. func GetSaleNumByDayInterval_Ok(ClientKey string, SignSecret string, AccessToken string, beginTime int64, endTime int64) int {
  373. pageSize := 100
  374. totalSaleNum := 0
  375. // 定义要查询的订单状态
  376. // [30:已付款] [50:已收货] [60:已结算] [80:已失效]
  377. statuses := []int{60}
  378. // 遍历所有订单状态并调用 Corderlist 函数
  379. for _, status := range statuses {
  380. // 初始化 pcursor
  381. pcursor := ""
  382. for {
  383. // 调用 Corderlist 函数获取订单列表
  384. response, err := merchant.Corderlist(ClientKey, SignSecret, AccessToken, status, pageSize, beginTime, endTime, pcursor)
  385. fmt.Println("response********", response)
  386. if err != nil {
  387. fmt.Printf("Error calling Corderlist: %v\n", err)
  388. break
  389. }
  390. // 检查响应代码
  391. if response.Code != "1" {
  392. fmt.Printf("Corderlist response error: %s\n", response.Msg)
  393. break
  394. }
  395. // 累加订单中商品的数量
  396. for _, order := range response.Data.OrderViews {
  397. for _, product := range order.CPSOrderProductViews {
  398. totalSaleNum += product.Num
  399. }
  400. }
  401. // 检查分页指针 pcursor
  402. //100个订单以内的情况
  403. if response.Data.Cursor == "nomore" {
  404. break
  405. }
  406. //大于等于100个订单
  407. // 更新 pcursor 以获取下一页数据
  408. pcursor = response.Data.Cursor
  409. // 处理分页后的数据
  410. // 如果 pcursor 不是 "nomore",我们需要累加最后一条订单的数量
  411. if len(response.Data.OrderViews) > 0 {
  412. lastOrder := response.Data.OrderViews[len(response.Data.OrderViews)-1]
  413. if len(lastOrder.CPSOrderProductViews) > 0 {
  414. lastProduct := lastOrder.CPSOrderProductViews[len(lastOrder.CPSOrderProductViews)-1]
  415. totalSaleNum += lastProduct.Num
  416. }
  417. }
  418. }
  419. }
  420. return totalSaleNum
  421. }