talent_ks_auth.go 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071
  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. douyinUser "github.com/lin-jim-leon/douyin/open/user"
  11. "github.com/lin-jim-leon/kuaishou/open/merchant"
  12. "github.com/lin-jim-leon/kuaishou/open/user"
  13. "log"
  14. "sync"
  15. "time"
  16. "youngmini_server/app/model/youngee_talent_model"
  17. "youngmini_server/app/service/youngee_sectask_service"
  18. "youngmini_server/app/utils"
  19. )
  20. const (
  21. //快手电商
  22. ClientKey = "ks651333097154138217"
  23. ClientSecret = "dBt0rVRhTpUqcrOYGGpv0A"
  24. SignSecret = "bf6393dce0a2b669ee348bebb837b0da"
  25. //快手平台
  26. ClientKey1 = "ks671599294546520767"
  27. ClientSecret1 = "8VSrp3O09nunjLMXR1uotg"
  28. //SignSecret1 = "bf6393dce0a2b669ee348bebb837b0da"
  29. //抖音平台
  30. ClientKey2 = "awi77xl5kpl16hmi"
  31. ClientSecret2 = "7ce6d2531bd4489122d89658063fd76e"
  32. //SignSecret1 = "bf6393dce0a2b669ee348bebb837b0da"
  33. )
  34. // 定义全局变量保存上下文
  35. var ctx context.Context
  36. var cancel context.CancelFunc
  37. var once sync.Once // 确保上下文只被初始化一次
  38. // 初始化 chromedp 上下文的函数
  39. func initChromedpContext() {
  40. once.Do(func() {
  41. // 初始化 chromedp 上下文
  42. ctx, cancel = chromedp.NewContext(context.Background())
  43. fmt.Println("Chromedp 上下文已初始化")
  44. })
  45. }
  46. // 清理上下文的函数,用于关闭浏览器和取消上下文
  47. func CleanupChromedpContext() {
  48. if cancel != nil {
  49. cancel()
  50. fmt.Println("Chromedp 上下文已关闭")
  51. }
  52. }
  53. func GetQrcode(r *ghttp.Request) *TalentHttpResult {
  54. //达人id获取
  55. tid, err := utils.SessionTalentInfo.GetTalentIdFromSession(r)
  56. fmt.Println("tid:", tid, "err:", err)
  57. if err != nil {
  58. return &TalentHttpResult{Code: -1, Msg: "Get talent id failed"}
  59. }
  60. // 记录开始时间
  61. startTime := time.Now()
  62. // 创建一个新的上下文
  63. // 确保 chromedp 上下文已初始化
  64. initChromedpContext()
  65. //ctx, cancel := chromedp.NewContext(context.Background())
  66. // 构建包含 tid 的 urlstr
  67. var urlstr string
  68. typePlatform := r.GetInt("platform_id")
  69. if typePlatform == 4 { //快手电商
  70. 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)
  71. } else if typePlatform == 8 { //快手平台
  72. urlstr = fmt.Sprintf("https://open.kuaishou.com/oauth2/connect?state=%s&app_id=ks671599294546520767&redirect_uri=https://younggee.com/kuaishouVideoVideo&scope=user_video_info,user_info&response_type=code", tid)
  73. } else if typePlatform == 2 { //抖音平台
  74. urlstr = fmt.Sprintf("https://open.kuaishou.com/oauth2/connect?state=%s&app_id=ks671599294546520767&redirect_uri=https://younggee.com/douyinauth&scope=user_info,data.external.user,video.list.bind&response_type=code", tid)
  75. } else {
  76. urlstr = "unknow"
  77. }
  78. // 执行任务
  79. //var buf []byte
  80. var text string
  81. var ok bool
  82. var tasks chromedp.Tasks
  83. if typePlatform == 2 { //抖音
  84. tasks = chromedp.Tasks{
  85. chromedp.Navigate(urlstr),
  86. // chromedp.WaitVisible(`#semiTabPanelqr > div > div > div.qr-container > img`, chromedp.ByQuery),
  87. chromedp.AttributeValue(`#semiTabPanelqr > div > div > div.qr-container > img`, "src", &text, &ok),
  88. }
  89. } else { //快手
  90. tasks = chromedp.Tasks{
  91. chromedp.Navigate(urlstr),
  92. // chromedp.WaitVisible(`body > div > div > div > div.qr-code-main > img:nth-child(1)`, chromedp.ByQuery),
  93. chromedp.AttributeValue(`body > div > div > div > div.qr-code-main > img:nth-child(1)`, "src", &text, &ok),
  94. }
  95. }
  96. //浏览器启动!
  97. err = chromedp.Run(ctx, tasks)
  98. if err != nil {
  99. log.Fatal(err)
  100. }
  101. println("text----->", text)
  102. println("ok----->", ok)
  103. println("url----->", urlstr)
  104. fmt.Println("代码运行时间:", time.Since(startTime))
  105. return &TalentHttpResult{Code: 0, Msg: "success", Data: text}
  106. }
  107. func GetKsEcomQrcode(r *ghttp.Request) *TalentHttpResult {
  108. fmt.Println("GetKsEcomQrcode-----")
  109. //达人id获取
  110. tid, err := utils.SessionTalentInfo.GetTalentIdFromSession(r)
  111. fmt.Println("tid:", tid, "err:", err)
  112. if err != nil {
  113. return &TalentHttpResult{Code: -1, Msg: "Get talent id failed"}
  114. }
  115. // 记录开始时间
  116. startTime := time.Now()
  117. // 确保上下文只初始化一次
  118. once.Do(func() {
  119. ctx, _ = chromedp.NewContext(context.Background())
  120. fmt.Println("Chromedp 上下文已初始化")
  121. })
  122. // 创建一个新的上下文
  123. //ctx, _ := chromedp.NewContext(context.Background())
  124. //需要访问的网址,无state,扫码后跳转到订购页面
  125. urlstr := fmt.Sprintf("https://login.kwaixiaodian.com/?biz=fuwu&redirect_url=https://fuwu.kwaixiaodian.com/new/detail?id=22328015871939")
  126. // 执行任务
  127. var text string
  128. var ok bool
  129. var tasks chromedp.Tasks
  130. //快手
  131. tasks = chromedp.Tasks{
  132. chromedp.Navigate(urlstr),
  133. //点击出现二维码
  134. chromedp.Click(`#root > div > div.UqM2VqEDB3qdOFvSOHAB > div > div > div > div.container__content > div:nth-child(1) > div`),
  135. // 获取二维码
  136. chromedp.AttributeValue(`#root > div > div.UqM2VqEDB3qdOFvSOHAB > div > div > div > div.Kmu1OHb3un0JBPZDkGa8 > div.JAc4fjotOx_h8lOtGzuB > div.dIaAe1BsCdQL6GtURkNI > img`, "src", &text, &ok),
  137. }
  138. //浏览器启动!
  139. err = chromedp.Run(ctx, tasks)
  140. if err != nil {
  141. fmt.Println("errInfo---", err.Error())
  142. }
  143. println("text----->", text)
  144. println("ok----->", ok)
  145. println("url----->", urlstr)
  146. fmt.Println("代码运行时间:", time.Since(startTime))
  147. // 在300秒后取消上下文
  148. //time.AfterFunc(300*time.Second, func() {
  149. // cancel()
  150. //})
  151. // 返回二维码的操作已经完成,后续操作(go fun)在后台继续进行
  152. return &TalentHttpResult{Code: 0, Msg: "二维码已生成", Data: text}
  153. }
  154. // 检查数据库表中是否有达人对应的数据 且 token未过期
  155. func CheckAccount(r *ghttp.Request) *TalentHttpResult {
  156. fmt.Println("into check")
  157. //达人id获取
  158. tid, err := utils.SessionTalentInfo.GetTalentIdFromSession(r)
  159. if err != nil {
  160. return &TalentHttpResult{Code: -1, Msg: "Get talent id failed"}
  161. }
  162. userInfo := &youngee_talent_model.KuaishouUserInfo{}
  163. err = g.DB().Model(userInfo).Where("talent_id", tid).Scan(&userInfo)
  164. fmt.Println("userInfo*********", userInfo)
  165. if err != nil {
  166. // 查询失败(未找到结果),返回失败结果
  167. return &TalentHttpResult{Code: -1, Msg: "Query failed", Data: nil}
  168. }
  169. //有查询结果,看是否accessToken是否有效
  170. key, err1 := g.DB().Model("platform_kuaishou_user_info").Fields("access_token").Where("talent_id = ?", tid).Value()
  171. if err1 != nil {
  172. return &TalentHttpResult{Code: -1, Msg: "query database fail"}
  173. }
  174. AccessToken := key.String()
  175. _, err2 := user.GetUserinfo(ClientKey, AccessToken)
  176. if err2 != nil {
  177. //前端接收code=-2表示token过期
  178. return &TalentHttpResult{Code: -2, Msg: "accessToken过期", Data: nil}
  179. }
  180. // 查询成功,返回成功结果和数据
  181. return &TalentHttpResult{Code: 0, Msg: "success", Data: userInfo}
  182. }
  183. // / 抖音二维码绑定,轮询此接口,
  184. func CheckDyNewAccount(r *ghttp.Request) *TalentHttpResult {
  185. //check到了更新时间在两秒内的插入的数据。则说明已绑定。弹窗消失。
  186. tid, err := utils.SessionTalentInfo.GetTalentIdFromSession(r)
  187. redisDyBindStatusKey := fmt.Sprintf("DyBind:%s", tid)
  188. bindStatus, err := g.Redis().DoVar("GET", redisDyBindStatusKey)
  189. if bindStatus.String() == "bound_to_other" {
  190. return &TalentHttpResult{Code: -1, Msg: "此账号已被其他达人绑定", Data: nil}
  191. }
  192. if err != nil {
  193. return &TalentHttpResult{Code: -1, Msg: "Get talent id failed"}
  194. }
  195. // 获取当前时间
  196. currentTime := gtime.Now()
  197. // 查询数据库中符合条件的所有记录
  198. var userInfos []youngee_talent_model.KuaishouUserInfo
  199. err = g.DB().Model("platform_kuaishou_user_info").
  200. Where("talent_id = ?", tid).
  201. Scan(&userInfos)
  202. if err != nil {
  203. return &TalentHttpResult{Code: -4, Msg: "Database query failed"}
  204. }
  205. if len(userInfos) == 0 {
  206. // 如果没有符合条件的数据,返回失败
  207. return &TalentHttpResult{Code: -5, Msg: "No valid data found"}
  208. }
  209. // 找到 CreateTime 最新的记录
  210. latestUserInfo := userInfos[0]
  211. for _, info := range userInfos[1:] {
  212. if info.CreateTime.After(latestUserInfo.CreateTime) {
  213. latestUserInfo = info
  214. }
  215. }
  216. // 计算创建时间与当前时间的差值
  217. timeDiff := currentTime.Sub(latestUserInfo.CreateTime)
  218. if timeDiff <= 3*time.Second {
  219. return &TalentHttpResult{Code: 0, Msg: "success"}
  220. }
  221. // 超过时间差,返回失败
  222. return &TalentHttpResult{Code: -6, Msg: "Time difference exceeds 3 seconds"}
  223. }
  224. // 用于轮询,检查数据库表中是否有达人对应的数据,有就删掉,/kuaishouath中会插入。
  225. func CheckKsNewAccount(r *ghttp.Request) *TalentHttpResult {
  226. //check到了更新时间在两秒内的插入的数据。则说明已绑定。弹窗消失。
  227. tid, err := utils.SessionTalentInfo.GetTalentIdFromSession(r)
  228. if err != nil {
  229. return &TalentHttpResult{Code: -2, Msg: "Get talent id failed"}
  230. }
  231. redisKsBindStatusKey := fmt.Sprintf("KsBind:%s", tid)
  232. bindStatus, err := g.Redis().DoVar("GET", redisKsBindStatusKey)
  233. if bindStatus.String() == "bound_to_other" {
  234. return &TalentHttpResult{Code: -1, Msg: "此快手账号已被其他达人绑定", Data: nil}
  235. }
  236. if err != nil {
  237. return &TalentHttpResult{Code: -3, Msg: "Get talent id failed"}
  238. }
  239. // 获取当前时间
  240. currentTime := gtime.Now()
  241. // 查询数据库中符合条件的所有记录
  242. var userInfos []youngee_talent_model.KuaishouUserInfo
  243. err = g.DB().Model("platform_kuaishou_user_info").
  244. Where("talent_id = ?", tid).
  245. Scan(&userInfos)
  246. if err != nil {
  247. return &TalentHttpResult{Code: -4, Msg: "Database query failed"}
  248. }
  249. //当前达人没有绑定过账号
  250. if len(userInfos) == 0 {
  251. // 如果没有符合条件的数据,返回失败
  252. }
  253. // 找到 CreateTime 最新的记录
  254. latestUserInfo := userInfos[0]
  255. for _, info := range userInfos[1:] {
  256. if info.CreateTime.After(latestUserInfo.CreateTime) {
  257. latestUserInfo = info
  258. }
  259. }
  260. // 计算创建时间与当前时间的差值
  261. timeDiff := currentTime.Sub(latestUserInfo.CreateTime)
  262. if timeDiff <= 3*time.Second {
  263. return &TalentHttpResult{Code: 0, Msg: "授权完成,数据已入库"}
  264. }
  265. // 超过时间差,返回失败
  266. return &TalentHttpResult{Code: -6, Msg: "Time difference exceeds 3 seconds"}
  267. }
  268. func CheckTokenExp(openId string, platformId int, talentId string) int {
  269. fmt.Println("into checktoken")
  270. //检查平台8
  271. if platformId == 8 {
  272. key, err := g.DB().Model("platform_kuaishou_user_info").Fields("access_token").Where("talent_id = ? & platform_id = ? & open_id = ? ", talentId, platformId, openId).Value()
  273. if err != nil {
  274. fmt.Println("query database fail")
  275. return -1
  276. }
  277. AccessToken := key.String()
  278. _, err = user.GetUserinfo(ClientKey1, AccessToken)
  279. if err != nil { //过期
  280. fmt.Println("平台accessToken过期")
  281. //前端接收code=-2表示token过期
  282. return 0
  283. } else {
  284. fmt.Println("平台AT未过期")
  285. return 1
  286. }
  287. //检查电商授权4
  288. } else {
  289. key, err := g.DB().Model("platform_kuaishou_user_info").Fields("access_token").Where("talent_id = ? & platform_id = ? & open_id = ? ", talentId, platformId, openId).Value()
  290. if err != nil {
  291. fmt.Println("query database fail")
  292. return 2
  293. }
  294. AccessToken := key.String()
  295. _, err = user.GetUserinfo(ClientKey, AccessToken)
  296. if err != nil { //过期
  297. //前端接收code=-2表示token过期
  298. fmt.Println("电商accessToken过期")
  299. return 3
  300. } else {
  301. fmt.Println("电商accessToken未过期")
  302. return 4
  303. }
  304. }
  305. }
  306. // func CheckTokenExp(r *ghttp.Request) *TalentHttpResult {
  307. // //达人id获取
  308. // tid, err := utils.SessionTalentInfo.GetTalentIdFromSession(r)
  309. // //平台id获取
  310. // platformId := r.GetInt("platform_id")
  311. // //openId获取
  312. // openId := r.GetString("open_id")
  313. // //检查平台授权
  314. // if platformId == 8 {
  315. // key, err := g.DB().Model("platform_kuaishou_user_info").Fields("access_token").Where("talent_id = ? & platform_id = ? & open_id = ? ", tid, platformId, openId).Value()
  316. // if err != nil {
  317. // return &TalentHttpResult{Code: -1, Msg: "query database fail"}
  318. // }
  319. // AccessToken := key.String()
  320. // res_info1, err := user.GetUserinfo(ClientKey1, AccessToken)
  321. // if err != nil { //过期
  322. // //前端接收code=-2表示token过期
  323. // return &TalentHttpResult{Code: -2, Msg: "平台accessToken过期", Data: nil}
  324. // } else {
  325. // return &TalentHttpResult{Code: 0, Msg: "平台accessToken未过期", Data: res_info1}
  326. // }
  327. // //检查电商授权
  328. // } else {
  329. // key, err := g.DB().Model("platform_kuaishou_user_info").Fields("access_token").Where("talent_id = ? & platform_id = ? & open_id = ? ", tid, platformId, openId).Value()
  330. // if err != nil {
  331. // return &TalentHttpResult{Code: -1, Msg: "query database fail"}
  332. // }
  333. // AccessToken := key.String()
  334. // res_info, err := user.GetUserinfo(ClientKey, AccessToken)
  335. // if err != nil { //过期
  336. // //前端接收code=-2表示token过期
  337. // return &TalentHttpResult{Code: -2, Msg: "电商accessToken过期", Data: nil}
  338. // } else {
  339. // return &TalentHttpResult{Code: 0, Msg: "平台accessToken未过期", Data: res_info}
  340. // }
  341. // }
  342. //
  343. // if err != nil {
  344. // return &TalentHttpResult{Code: -3, Msg: "Get talent id failed"}
  345. // }
  346. // key, err1 := g.DB().Model("platform_kuaishou_user_info").Fields("access_token").Where("talent_id = ? & platform_id = ? & open_id = ? ", tid, platformId, openId).Value()
  347. // if err1 != nil {
  348. // return &TalentHttpResult{Code: -1, Msg: "query database fail"}
  349. // }
  350. // AccessToken := key.String()
  351. // res_info, err2 := user.GetUserinfo(ClientKey, AccessToken)
  352. // if err2 != nil {
  353. // //前端接收code=-2表示token过期
  354. // return &TalentHttpResult{Code: -2, Msg: "accessToken过期", Data: nil}
  355. // }
  356. // // 查询成功,返回成功结果和数据
  357. // return &TalentHttpResult{Code: 0, Msg: "success", Data: res_info}
  358. // }
  359. func AddWindowKuaishouList(r *ghttp.Request) *TalentHttpResult {
  360. // 定义用于存储查询结果的结构体切片
  361. var results []*youngee_talent_model.KuaishouUserInfo
  362. // 获取talent_id
  363. tid, _ := utils.SessionTalentInfo.GetTalentIdFromSession(r)
  364. // 查询此达人下,platform_id 为 8 或 4 的所有数据,并将结果扫描到结构体切片中
  365. err := g.DB().Model(&youngee_talent_model.KuaishouUserInfo{}).
  366. Where("talent_id = ?", tid).
  367. Where("platform_id IN (?, ?)", 4, 8).
  368. Order("open_id ASC, platform_id DESC"). // 按 open_id 排序,确保每组的数据连续,并且 platform_id=4 的数据排在前面
  369. Scan(&results)
  370. if err != nil {
  371. return &TalentHttpResult{Code: 1, Msg: "查询失败", Data: nil}
  372. }
  373. // 创建一个 map,用于记录每个 open_id 对应的记录
  374. //key是openid,value是数组,从而实现一对多
  375. openIdMap := make(map[string][]*youngee_talent_model.KuaishouUserInfo)
  376. // 将查询结果按 open_id 分组
  377. for _, record := range results {
  378. openIdMap[record.OpenId] = append(openIdMap[record.OpenId], record)
  379. }
  380. // 筛选出 open_id 对应两条数据且 platform_id = 4 的记录
  381. var resInfo []*youngee_talent_model.KuaishouUserInfo
  382. for _, records := range openIdMap {
  383. if len(records) == 2 { // 确保有两条数据,排除只有一个 platform_id 的情况
  384. for _, record := range records {
  385. if record.PlatformId == 4 { // 选取 platform_id = 4(电商) 的记录,含有粉丝数就好,因为需要加入橱窗
  386. resInfo = append(resInfo, record)
  387. break
  388. }
  389. }
  390. }
  391. }
  392. // 遍历 resInfo 检查过期和是否报名
  393. for _, record := range resInfo {
  394. // 调用 CheckKuaishouTokenExp 函数,检查 openId 是否过期
  395. expired := CheckKuaishouTokenExp(record.OpenId)
  396. // 将过期检查结果赋值给 expired 属性 ,过期则不能被选中用于加入橱窗
  397. record.Expired = expired
  398. }
  399. return &TalentHttpResult{Code: 0, Msg: "快手列表展示成功", Data: resInfo}
  400. }
  401. func SignUpSecKuaishouList(r *ghttp.Request) *TalentHttpResult {
  402. selectionId := r.GetString("selection_id")
  403. // 定义用于存储查询结果的结构体切片
  404. var results []*youngee_talent_model.KuaishouUserInfo
  405. // 获取talent_id
  406. tid, _ := utils.SessionTalentInfo.GetTalentIdFromSession(r)
  407. // 查询此达人下,platform_id 为 8 或 4 的所有数据,并将结果扫描到结构体切片中
  408. err := g.DB().Model(&youngee_talent_model.KuaishouUserInfo{}).
  409. Where("talent_id = ?", tid).
  410. Where("platform_id IN (?, ?)", 4, 8).
  411. Order("open_id ASC, platform_id DESC"). // 按 open_id 排序,确保每组的数据连续,并且 platform_id=4 的数据排在前面
  412. Scan(&results)
  413. if err != nil {
  414. return &TalentHttpResult{Code: 1, Msg: "查询失败", Data: nil}
  415. }
  416. // 创建一个 map,用于记录每个 open_id 对应的记录
  417. //key是openid,value是数组,从而实现一对多
  418. openIdMap := make(map[string][]*youngee_talent_model.KuaishouUserInfo)
  419. // 将查询结果按 open_id 分组
  420. for _, record := range results {
  421. openIdMap[record.OpenId] = append(openIdMap[record.OpenId], record)
  422. }
  423. // 筛选出 open_id 对应两条数据且 platform_id = 4 的记录
  424. var resInfo []*youngee_talent_model.KuaishouUserInfo
  425. for _, records := range openIdMap {
  426. if len(records) == 2 { // 确保有两条数据,排除只有一个 platform_id 的情况
  427. for _, record := range records {
  428. if record.PlatformId == 4 { // 选取 platform_id = 4(电商) 的记录,含有粉丝数就好,因为需要加入橱窗
  429. resInfo = append(resInfo, record)
  430. break
  431. }
  432. }
  433. }
  434. }
  435. // 遍历 resInfo 检查过期和是否报名
  436. for _, record := range resInfo {
  437. // 调用 CheckKuaishouTokenExp 函数,检查 openId 是否过期
  438. expired := CheckKuaishouTokenExp(record.OpenId)
  439. // 将过期检查结果赋值给 expired 属性 ,过期则不能被选中用于加入橱窗
  440. record.Expired = expired
  441. //是否报名
  442. isSignResult, err := g.DB().Model("younggee_sec_task_info").Where("selection_id=? AND open_id=? talent_id=? sample_mode=?", selectionId, record.OpenId, tid, 1).One()
  443. // 根据查询结果设置 IsSign 属性
  444. if err != nil || isSignResult.IsEmpty() {
  445. record.IsSign = 0 // 没有查到数据,设置为 0
  446. } else {
  447. record.IsSign = 1 // 查到数据,设置为 1
  448. }
  449. }
  450. return &TalentHttpResult{Code: 0, Msg: "加入橱窗成功", Data: resInfo}
  451. }
  452. // 只有绑定两个快手,且快手电商没有过期,才能访问到这
  453. func AddWindowWithKsAccount(r *ghttp.Request) *TalentHttpResult {
  454. // 获取talent_id
  455. tid, _ := utils.SessionTalentInfo.GetTalentIdFromSession(r)
  456. pId := r.GetString("product_id")
  457. openId := r.GetString("open_id")
  458. value, err := g.DB().Model("platform_kuaishou_user_info").Fields("open_id").Where("talent_id=? AND open_id = ?", tid, openId).Value()
  459. if err != nil {
  460. fmt.Println("query db fail")
  461. }
  462. accessToken := value.String()
  463. //通过pId获取kuaishou_product_id
  464. pIdSlice := []string{pId}
  465. //如果此tId。此openId下已有此product的task则不
  466. //res_info, err := merchant.AddItemsToShelf(ClientKey, SignSecret, accessToken, pIdSlice)
  467. httpResult := youngee_sectask_service.IsCreateSecTask(r)
  468. if httpResult.Code == 1 { //存在报名信息,仅添加橱窗
  469. _, err := merchant.AddItemsToShelf(ClientKey, SignSecret, accessToken, pIdSlice)
  470. if err != nil {
  471. //表示添加失敗,沒有開通
  472. return &TalentHttpResult{Code: -1, Msg: "快手未開通橱窗、商品不存在或已下线", Data: nil}
  473. }
  474. // 查询成功,返回成功结果和数据
  475. return &TalentHttpResult{Code: 0, Msg: "无需创建任务,加入橱窗成功", Data: nil}
  476. } else { //不存在报名信息
  477. //创建并插入报名信息
  478. code := youngee_sectask_service.SignUpSecTaskFromWindow(r).Code
  479. if code != 0 {
  480. fmt.Println("错误代码为----》", code)
  481. }
  482. //加入橱窗
  483. _, err := merchant.AddItemsToShelf(ClientKey, SignSecret, accessToken, pIdSlice)
  484. if err != nil {
  485. //表示添加失敗,沒有開通
  486. return &TalentHttpResult{Code: -1, Msg: "快手未開通橱窗、商品不存在或已下线", Data: nil}
  487. }
  488. // 查询成功,返回成功结果和数据
  489. return &TalentHttpResult{Code: 0, Msg: "创建了任务,加入橱窗成功", Data: nil}
  490. }
  491. }
  492. func AddWindow(r *ghttp.Request) *TalentHttpResult {
  493. pId := r.GetString("product_id")
  494. //通过pId获取kuaishou_product_id
  495. pIdSlice := []string{pId}
  496. //达人id获取
  497. tid, err := utils.SessionTalentInfo.GetTalentIdFromSession(r)
  498. //加入橱窗-条件不满足的快手账号不能被选中
  499. //条件1. 没有开通橱窗
  500. //判断此快手账号是否绑定了两
  501. openId := r.GetString("open_id")
  502. // 执行数据库查询
  503. count, err := g.DB().Model("platform_kuaishou_user_info").
  504. Where("talent_id = ? AND open_id = ?", tid, openId).
  505. Count()
  506. if err != nil {
  507. // 处理错误
  508. return &TalentHttpResult{Code: -4, Msg: "出错了"}
  509. }
  510. if count != 2 {
  511. return &TalentHttpResult{Code: -5, Msg: "达人需要授权两个码"}
  512. }
  513. if err != nil {
  514. return &TalentHttpResult{Code: -1, Msg: "Get talent id failed"}
  515. }
  516. key, err := g.DB().Model("platform_kuaishou_user_info").Fields("access_token").Where("talent_id = ?", tid).Value()
  517. if err != nil {
  518. return &TalentHttpResult{Code: -2, Msg: "query database fail"}
  519. }
  520. AccessToken := key.String()
  521. res_info, err := merchant.AddItemsToShelf(ClientKey, SignSecret, AccessToken, pIdSlice)
  522. if err != nil {
  523. //前端接收code=-3表示添加失敗,沒有開通
  524. return &TalentHttpResult{Code: -3, Msg: "未開通、商品不存在或已下线", Data: nil}
  525. }
  526. // 查询成功,返回成功结果和数据
  527. return &TalentHttpResult{Code: 0, Msg: "加入橱窗成功", Data: res_info}
  528. }
  529. func GetKuaishouFansNum(r *ghttp.Request) *TalentHttpResult {
  530. //达人id获取
  531. tid, err := utils.SessionTalentInfo.GetTalentIdFromSession(r)
  532. fmt.Println("********&&&&&&&&&&,tid", tid)
  533. if err != nil {
  534. return &TalentHttpResult{Code: -1, Msg: "Get talent id failed"}
  535. }
  536. key, err1 := g.DB().Model("platform_kuaishou_user_info").Fields("access_token").Where("talent_id = ? ", tid).Value()
  537. if err1 != nil {
  538. return &TalentHttpResult{Code: -2, Msg: "query database fail"}
  539. }
  540. AccessToken := key.String()
  541. res_user, err2 := user.GetUserinfo(ClientKey, AccessToken)
  542. if err2 != nil {
  543. //前端接收code=-3表示添加失敗,沒有開通
  544. return &TalentHttpResult{Code: -3, Msg: "获取快手用户信息出错", Data: nil}
  545. }
  546. // 查询成功,返回成功结果和数据
  547. return &TalentHttpResult{Code: 0, Msg: "获取快手用户信息成功", Data: res_user.Data}
  548. }
  549. func QuerySalesFor30Days(r *ghttp.Request) *TalentHttpResult {
  550. fmt.Println("into querySalesFor30Days")
  551. ClientKey := "ks651333097154138217"
  552. //ClientSecret := "dBt0rVRhTpUqcrOYGGpv0A"
  553. SignSecret := "bf6393dce0a2b669ee348bebb837b0da"
  554. tid, _ := utils.SessionTalentInfo.GetTalentIdFromSession(r)
  555. // 创建一个 KuaishouUserInfo 结构体的实例
  556. userInfo := &youngee_talent_model.KuaishouUserInfo{}
  557. // 查询数据库中的 access_token 字段
  558. // 使用 g.DB() 获取数据库连接,并执行查询
  559. key, err := g.DB().Model(userInfo).Fields("access_token").Where("talent_id = ?", tid).Value()
  560. AccessToken := key.String()
  561. if err != nil {
  562. // 处理错误
  563. fmt.Println("Error querying access_token:", err)
  564. }
  565. // 输出查询到的 access_token 值
  566. fmt.Println("Access Token:", AccessToken)
  567. // 获取当前时间的时间戳(毫秒)
  568. currentTime := time.Now().UnixNano() / int64(time.Millisecond)
  569. // 30天前的时间戳(毫秒)
  570. beginTime30DaysAgo := currentTime - 30*24*60*60*1000
  571. // 定义每段查询的天数
  572. intervalDays := 7
  573. intervalMillis := int64(intervalDays * 24 * 60 * 60 * 1000)
  574. // 初始化 beginTime 和 endTime
  575. beginTime := beginTime30DaysAgo
  576. endTime := beginTime + intervalMillis
  577. saleNum := 0 //30天总销量
  578. // 循环查询,先处理四个7天的时间段
  579. for i := 0; i < 4; i++ {
  580. // 调整 endTime,确保不会超过当前时间
  581. if endTime > currentTime {
  582. endTime = currentTime
  583. }
  584. saleNum += GetSaleNumByDayInterval(ClientKey, SignSecret, AccessToken, beginTime, endTime)
  585. // 更新时间段
  586. beginTime = endTime
  587. endTime = beginTime + intervalMillis
  588. }
  589. // 最后处理剩余的2天时间段
  590. endTime = currentTime
  591. saleNum += GetSaleNumByDayInterval(ClientKey, SignSecret, AccessToken, beginTime, endTime)
  592. // 查询成功,返回成功结果和数据
  593. return &TalentHttpResult{Code: 0, Msg: "获取30天销售量成功", Data: saleNum}
  594. }
  595. func QueryOkSaleNum(r *ghttp.Request) *TalentHttpResult {
  596. tid, _ := utils.SessionTalentInfo.GetTalentIdFromSession(r)
  597. openID := r.GetString("open_id")
  598. // 创建一个 KuaishouUserInfo 结构体的实例
  599. userInfo := &youngee_talent_model.KuaishouUserInfo{}
  600. // 查询数据库中的 access_token 字段
  601. // 使用 g.DB() 获取数据库连接,并执行查询
  602. key, err := g.DB().Model(userInfo).Fields("access_token").Where("talent_id = ? AND open_id= ? AND platform_id = ?", tid, openID, 4).Value()
  603. AccessToken := key.String()
  604. if err != nil {
  605. // 处理错误
  606. fmt.Println("Error querying access_token:", err)
  607. }
  608. if key == nil {
  609. // 处理错误
  610. fmt.Println("can not find talentId's bindinfo :", err)
  611. }
  612. //循环使用接口
  613. //
  614. // 获取当前时间的时间戳(毫秒)
  615. currentTime := time.Now().UnixNano() / int64(time.Millisecond)
  616. // 90天前的时间戳(毫秒)
  617. beginTime90DaysAgo := currentTime - 90*24*60*60*1000
  618. // 定义每段查询的天数
  619. intervalDays := 7
  620. intervalMillis := int64(intervalDays * 24 * 60 * 60 * 1000)
  621. // 初始化 beginTime 和 endTime
  622. beginTime := beginTime90DaysAgo
  623. endTime := beginTime + intervalMillis
  624. saleNum := 0 //90天总销量
  625. // 循环查询,先处理四个7天的时间段
  626. for i := 0; i < 12; i++ {
  627. // 调整 endTime,确保不会超过当前时间
  628. if endTime > currentTime {
  629. endTime = currentTime
  630. }
  631. saleNum += GetSaleNumByDayInterval_Ok(ClientKey, SignSecret, AccessToken, beginTime, endTime)
  632. // 更新时间段
  633. beginTime = endTime
  634. endTime = beginTime + intervalMillis
  635. }
  636. // 最后处理剩余的6天时间段
  637. endTime = currentTime
  638. saleNum += GetSaleNumByDayInterval_Ok(ClientKey, SignSecret, AccessToken, beginTime, endTime)
  639. // 查询成功,返回成功结果和数据
  640. return &TalentHttpResult{Code: 0, Msg: "获取90天销售量成功", Data: saleNum}
  641. }
  642. //func VideoCount(r *ghttp.Request) *TalentHttpResult {
  643. // tid, _ := utils.SessionTalentInfo.GetTalentIdFromSession(r)
  644. // // 创建一个 KuaishouUserInfo 结构体的实例
  645. // userInfo := &youngee_talent_model.KuaishouUserInfo{}
  646. //
  647. // // 查询数据库中的 access_token 字段
  648. // // 使用 g.DB() 获取数据库连接,并执行查询
  649. // key, err := g.DB().Model(userInfo).Fields("access_token").Where("talent_id = ? AND platform_id = ?", tid, 8).Value()
  650. // AccessToken := key.String()
  651. // if err != nil {
  652. // // 处理错误
  653. // fmt.Println("Error querying access_token:", err)
  654. // }
  655. // if key == nil {
  656. // // 处理错误
  657. // fmt.Println("can not find talentId's bindinfo :", err)
  658. // }
  659. //
  660. // count, err := GetVideoCount(ClientKey1, AccessToken)
  661. // return &TalentHttpResult{Code: 0, Msg: "获取总作品数成功", Data: count}
  662. //}
  663. //
  664. //func LikeCount(r *ghttp.Request) *TalentHttpResult {
  665. // tid, _ := utils.SessionTalentInfo.GetTalentIdFromSession(r)
  666. // // 创建一个 KuaishouUserInfo 结构体的实例
  667. // userInfo := &youngee_talent_model.KuaishouUserInfo{}
  668. //
  669. // // 查询数据库中的 access_token 字段
  670. // // 使用 g.DB() 获取数据库连接,并执行查询
  671. // key, err := g.DB().Model(userInfo).Fields("access_token").Where("talent_id = ? AND platform_id = ?", tid, 8).Value()
  672. // AccessToken := key.String()
  673. // if err != nil {
  674. // // 处理错误
  675. // fmt.Println("Error querying access_token:", err)
  676. // }
  677. // if key == nil {
  678. // // 处理错误
  679. // fmt.Println("can not find talentId's bindinfo :", err)
  680. // }
  681. // count, err := GetLikeCount(ClientKey1, AccessToken)
  682. // return &TalentHttpResult{Code: 0, Msg: "获取总点赞数成功", Data: count}
  683. //}
  684. // 获取用户快手平台账号列表
  685. func GetKuaishouList(r *ghttp.Request) *TalentHttpResult {
  686. // 从 session 中获取 talent_id
  687. tid, _ := utils.SessionTalentInfo.GetTalentIdFromSession(r)
  688. userInfo := &youngee_talent_model.KuaishouUserInfo{}
  689. // 查询 platformId 为 8 或 4 的所有数据
  690. results, err := g.DB().Model(userInfo).Where("talent_id = ?", tid).
  691. Where("platform_Id IN (?, ?)", 4, 8).
  692. Order("platform_Id DESC").
  693. All()
  694. if err != nil {
  695. fmt.Println("Error querying access_token:", err)
  696. return &TalentHttpResult{Code: -1, Msg: "查询出错", Data: nil}
  697. }
  698. // 检查查询结果是否为空
  699. if results.IsEmpty() {
  700. return &TalentHttpResult{Code: -2, Msg: "此达人无快手账号绑定", Data: nil}
  701. }
  702. // 使用集合来存储唯一的 open_id,并计算不同的 open_id 的个数
  703. openIDSet := make(map[string]struct{})
  704. userInfoMap := make(map[string]*youngee_talent_model.KuaishouUserInfo)
  705. for _, record := range results.List() {
  706. openID := gconv.String(record["open_id"])
  707. platformID := record["platform_id"] //int类型
  708. status := 0 //初始化
  709. // 检查 userInfoMap 中是否已经存在 openID
  710. //肯定会先处理8,所以遇到重复情况肯定是两个都授权了
  711. _, exists := userInfoMap[openID]
  712. if exists {
  713. status = 1 //同时授权了两个码
  714. userInfoMap[openID] = &youngee_talent_model.KuaishouUserInfo{
  715. OpenId: openID,
  716. HeadUri: gconv.String(record["head_uri"]),
  717. NickName: gconv.String(record["nick_name"]),
  718. // 添加其他需要的字段
  719. Fan: gconv.Int(record["fan"]),
  720. //这两个值默认为0
  721. LikeNum: gconv.Int(record["like_num"]),
  722. VideoNum: gconv.Int(record["video_num"]),
  723. Status: status,
  724. }
  725. }
  726. //若同时有8和4的平台。处理了8就不会处理4了
  727. if !exists {
  728. //只有一个且为4
  729. if platformID == 4 {
  730. status = 2 //仅授权了电商
  731. } else {
  732. status = 3 //仅授权了平台
  733. }
  734. openIDSet[openID] = struct{}{}
  735. // 根据 platformID 赋值
  736. userInfoMap[openID] = &youngee_talent_model.KuaishouUserInfo{
  737. OpenId: openID,
  738. HeadUri: gconv.String(record["head_uri"]),
  739. NickName: gconv.String(record["nick_name"]),
  740. // 添加其他需要的字段
  741. Fan: gconv.Int(record["fan"]),
  742. //这两个值默认为0
  743. LikeNum: gconv.Int(record["like_num"]),
  744. VideoNum: gconv.Int(record["video_num"]),
  745. Status: status,
  746. }
  747. }
  748. }
  749. // 构建 UserInfo 列表 参数分别表示初始长度和容量
  750. userInfoList := make([]*youngee_talent_model.KuaishouUserInfo, 0, len(userInfoMap))
  751. for _, info := range userInfoMap {
  752. //将 info 添加到 userInfoList 列表的末尾。
  753. userInfoList = append(userInfoList, info)
  754. }
  755. // 计算不同的 open_id 的个数
  756. uniqueOpenIDCount := len(openIDSet)
  757. // 创建 KSListResult 变量并赋值
  758. ksListResult := &youngee_talent_model.KSListResult{
  759. Count: uniqueOpenIDCount,
  760. UserInfo: userInfoList,
  761. }
  762. // 返回结果
  763. return &TalentHttpResult{Code: 1, Msg: "返回快手列表成功", Data: ksListResult}
  764. }
  765. // 获取用户快手电商过期信息 肯定绑定两个码,因为只是用于加入橱窗---我只检查电商是否过期
  766. func CheckKuaishouTokenExp(openId string) int {
  767. fmt.Println("into checktoken")
  768. //一个openId同时对应了8和4,才进行过期检查,两个都检查,有一个过期则过期
  769. key, err := g.DB().Model("platform_kuaishou_user_info").Fields("access_token").Where("open_id = ? ", openId).Value()
  770. if err != nil {
  771. fmt.Println("query database fail")
  772. return -1
  773. }
  774. AccessToken := key.String()
  775. _, err = douyinUser.GetUserInfo(openId, AccessToken)
  776. if err != nil { //过期
  777. fmt.Println("平台accessToken过期")
  778. return 1
  779. } else {
  780. fmt.Println("未过期")
  781. return 0
  782. }
  783. }
  784. func CheckDouyinTokenExp(openId string) int {
  785. fmt.Println("into checktoken")
  786. key, err := g.DB().Model("platform_kuaishou_user_info").Fields("access_token").Where("open_id = ? ", openId).Value()
  787. if err != nil {
  788. fmt.Println("query database fail")
  789. return -1
  790. }
  791. AccessToken := key.String()
  792. _, err = douyinUser.GetUserInfo(openId, AccessToken)
  793. if err != nil { //过期
  794. fmt.Println("平台accessToken过期")
  795. return 1
  796. } else {
  797. fmt.Println("未过期")
  798. return 0
  799. }
  800. }
  801. func GetDouyinList(r *ghttp.Request) *TalentHttpResult {
  802. // 获取达人对应的平台为2的列表,含基本信息
  803. tid, _ := utils.SessionTalentInfo.GetTalentIdFromSession(r)
  804. userInfo := &youngee_talent_model.KuaishouUserInfo{}
  805. results, err := g.DB().Model(userInfo).Where("talent_id = ?", tid).
  806. Where("platform_Id IN (?)", 2).
  807. All()
  808. if err != nil {
  809. fmt.Println("Error querying ", err)
  810. return &TalentHttpResult{Code: 0, Msg: "查询抖音列表失败", Data: nil}
  811. }
  812. // 创建一个存储用户信息的切片
  813. updatedUserInfoList := []*youngee_talent_model.KuaishouUserInfo{}
  814. // 遍历列表,判断是否过期并更新 Expired 属性
  815. for _, record := range results.List() {
  816. openID := gconv.String(record["open_id"])
  817. // 调用 CheckDouyinTokenExp 函数,获取过期状态 0/1
  818. expiredStatus := CheckDouyinTokenExp(openID)
  819. // 更新 record 中的 Expired 字段值
  820. record["Expired"] = expiredStatus
  821. err := gconv.Struct(record, userInfo)
  822. if err != nil {
  823. return nil
  824. } // 将 map 转换为 KuaishouUserInfo 结构体
  825. // 添加到用户信息列表
  826. updatedUserInfoList = append(updatedUserInfoList, userInfo)
  827. // 如果需要将更新后的 record 保存到数据库中,请取消注释以下代码
  828. // if _, err := g.DB().Model(userInfo).Where("open_id = ?", openID).Data(record).Update(); err != nil {
  829. // fmt.Println("Error updating Expired status: ", err)
  830. // }
  831. }
  832. // 返回 DYListResult 类型
  833. return &TalentHttpResult{Code: 1, Msg: "返回抖音列表成功", Data: &youngee_talent_model.DYListResult{
  834. Count: len(updatedUserInfoList),
  835. UserInfo: updatedUserInfoList,
  836. }}
  837. }
  838. func QuerySalesFor90Days(r *ghttp.Request) *TalentHttpResult {
  839. tid, _ := utils.SessionTalentInfo.GetTalentIdFromSession(r)
  840. // 创建一个 KuaishouUserInfo 结构体的实例
  841. userInfo := &youngee_talent_model.KuaishouUserInfo{}
  842. // 查询数据库中的 access_token 字段
  843. // 使用 g.DB() 获取数据库连接,并执行查询
  844. key, err := g.DB().Model(userInfo).Fields("access_token").Where("talent_id = ?", tid).Value()
  845. AccessToken := key.String()
  846. if err != nil {
  847. // 处理错误
  848. fmt.Println("Error querying access_token:", err)
  849. }
  850. if key == nil {
  851. // 处理错误
  852. fmt.Println("can not find talentId's bindinfo :", err)
  853. }
  854. //循环使用接口
  855. //
  856. // 获取当前时间的时间戳(毫秒)
  857. currentTime := time.Now().UnixNano() / int64(time.Millisecond)
  858. // 30天前的时间戳(毫秒)
  859. beginTime90DaysAgo := currentTime - 90*24*60*60*1000
  860. // 定义每段查询的天数
  861. intervalDays := 7
  862. intervalMillis := int64(intervalDays * 24 * 60 * 60 * 1000)
  863. // 初始化 beginTime 和 endTime
  864. beginTime := beginTime90DaysAgo
  865. endTime := beginTime + intervalMillis
  866. saleNum := 0 //90天总销量
  867. // 循环查询,先处理四个7天的时间段
  868. for i := 0; i < 12; i++ {
  869. // 调整 endTime,确保不会超过当前时间
  870. if endTime > currentTime {
  871. endTime = currentTime
  872. }
  873. saleNum += GetSaleNumByDayInterval(ClientKey, SignSecret, AccessToken, beginTime, endTime)
  874. // 更新时间段
  875. beginTime = endTime
  876. endTime = beginTime + intervalMillis
  877. }
  878. // 最后处理剩余的6天时间段
  879. endTime = currentTime
  880. saleNum += GetSaleNumByDayInterval(ClientKey, SignSecret, AccessToken, beginTime, endTime)
  881. // 查询成功,返回成功结果和数据
  882. return &TalentHttpResult{Code: 0, Msg: "获取30天销售量成功", Data: saleNum}
  883. }
  884. func GetSaleNumByDayInterval(ClientKey string, SignSecret string, AccessToken string, beginTime int64, endTime int64) int {
  885. pageSize := 100
  886. totalSaleNum := 0
  887. // 定义要查询的订单状态
  888. // [30:已付款] [50:已收货] [60:已结算] [80:已失效]
  889. statuses := []int{30, 50, 60}
  890. // 遍历所有订单状态并调用 Corderlist 函数
  891. for _, status := range statuses {
  892. // 初始化 pcursor
  893. pcursor := ""
  894. for {
  895. // 调用 Corderlist 函数获取订单列表
  896. response, err := merchant.Corderlist(ClientKey, SignSecret, AccessToken, status, pageSize, beginTime, endTime, pcursor)
  897. fmt.Println("response********", response)
  898. if err != nil {
  899. fmt.Printf("Error calling Corderlist: %v\n", err)
  900. break
  901. }
  902. // 检查响应代码
  903. if response.Code != "1" {
  904. fmt.Printf("Corderlist response error: %s\n", response.Msg)
  905. break
  906. }
  907. // 累加订单中商品的数量
  908. for _, order := range response.Data.OrderViews {
  909. for _, product := range order.CPSOrderProductViews {
  910. totalSaleNum += product.Num
  911. }
  912. }
  913. // 检查分页指针 pcursor
  914. //100个订单以内的情况
  915. if response.Data.Cursor == "nomore" {
  916. break
  917. }
  918. //大于等于100个订单
  919. // 更新 pcursor 以获取下一页数据
  920. pcursor = response.Data.Cursor
  921. // 处理分页后的数据
  922. // 如果 pcursor 不是 "nomore",我们需要累加最后一条订单的数量
  923. if len(response.Data.OrderViews) > 0 {
  924. lastOrder := response.Data.OrderViews[len(response.Data.OrderViews)-1]
  925. if len(lastOrder.CPSOrderProductViews) > 0 {
  926. lastProduct := lastOrder.CPSOrderProductViews[len(lastOrder.CPSOrderProductViews)-1]
  927. totalSaleNum += lastProduct.Num
  928. }
  929. }
  930. }
  931. }
  932. return totalSaleNum
  933. }
  934. func GetSaleNumByDayInterval_Ok(ClientKey string, SignSecret string, AccessToken string, beginTime int64, endTime int64) int {
  935. pageSize := 100
  936. totalSaleNum := 0
  937. // 定义要查询的订单状态
  938. // [30:已付款] [50:已收货] [60:已结算] [80:已失效]
  939. statuses := []int{60}
  940. // 遍历所有订单状态并调用 Corderlist 函数
  941. for _, status := range statuses {
  942. // 初始化 pcursor
  943. pcursor := ""
  944. for {
  945. // 调用 Corderlist 函数获取订单列表
  946. response, err := merchant.Corderlist(ClientKey, SignSecret, AccessToken, status, pageSize, beginTime, endTime, pcursor)
  947. fmt.Println("response********", response)
  948. if err != nil {
  949. fmt.Printf("Error calling Corderlist: %v\n", err)
  950. break
  951. }
  952. // 检查响应代码
  953. if response.Code != "1" {
  954. fmt.Printf("Corderlist response error: %s\n", response.Msg)
  955. break
  956. }
  957. // 累加订单中商品的数量
  958. for _, order := range response.Data.OrderViews {
  959. for _, product := range order.CPSOrderProductViews {
  960. totalSaleNum += product.Num
  961. }
  962. }
  963. // 检查分页指针 pcursor
  964. //100个订单以内的情况
  965. if response.Data.Cursor == "nomore" {
  966. break
  967. }
  968. //大于等于100个订单
  969. // 更新 pcursor 以获取下一页数据
  970. pcursor = response.Data.Cursor
  971. // 处理分页后的数据
  972. // 如果 pcursor 不是 "nomore",我们需要累加最后一条订单的数量
  973. if len(response.Data.OrderViews) > 0 {
  974. lastOrder := response.Data.OrderViews[len(response.Data.OrderViews)-1]
  975. if len(lastOrder.CPSOrderProductViews) > 0 {
  976. lastProduct := lastOrder.CPSOrderProductViews[len(lastOrder.CPSOrderProductViews)-1]
  977. totalSaleNum += lastProduct.Num
  978. }
  979. }
  980. }
  981. }
  982. return totalSaleNum
  983. }