浏览代码

9.5带货存档

yankun 7 月之前
父节点
当前提交
e5314f42fb
共有 41 个文件被更改,包括 1411 次插入299 次删除
  1. 84 18
      app/api/youngee_talent_api/talent_auth_get_api.go
  2. 5 13
      app/api/youngee_talent_api/talent_auth_post_api.go
  3. 0 1
      app/api/youngee_talent_api/talent_get_api.go
  4. 11 1
      app/api/youngee_talent_api/talent_post_api.go
  5. 25 2
      app/model/youngee_talent_model/auth_model.go
  6. 8 2
      app/model/youngee_talent_model/project_info.go
  7. 16 0
      app/model/youngee_talent_model/selection.go
  8. 8 7
      app/model/youngee_talent_model/selection_task.go
  9. 167 103
      app/service/youngee_sectask_service/seletion_square.go
  10. 110 0
      app/service/youngee_talent_service/BrowseHistory.go
  11. 1 0
      app/service/youngee_talent_service/LoginFromSms.go
  12. 49 2
      app/service/youngee_talent_service/SendSmsCode.go
  13. 137 3
      app/service/youngee_talent_service/talentVideoInfo.go
  14. 1 1
      app/service/youngee_talent_service/talent_info.go
  15. 394 95
      app/service/youngee_talent_service/talent_ks_auth.go
  16. 41 3
      app/service/youngee_task_service/task_data.go
  17. 38 35
      app/system/assignment/assignment_model.go
  18. 39 0
      app/system/assignment/assignment_service.go
  19. 二进制
      bin/main
  20. 1 0
      config/config.toml
  21. 0 1
      main.go
  22. 二进制
      public/swagger/favicon-16x16.png
  23. 二进制
      public/swagger/favicon-32x32.png
  24. 16 0
      public/swagger/index.css
  25. 19 0
      public/swagger/index.html
  26. 79 0
      public/swagger/oauth2-redirect.html
  27. 21 0
      public/swagger/swagger-initializer.js
  28. 1 0
      public/swagger/swagger-ui-bundle.js
  29. 0 0
      public/swagger/swagger-ui-bundle.js.map
  30. 1 0
      public/swagger/swagger-ui-es-bundle-core.js
  31. 0 0
      public/swagger/swagger-ui-es-bundle-core.js.map
  32. 1 0
      public/swagger/swagger-ui-es-bundle.js
  33. 0 0
      public/swagger/swagger-ui-es-bundle.js.map
  34. 1 0
      public/swagger/swagger-ui-standalone-preset.js
  35. 0 0
      public/swagger/swagger-ui-standalone-preset.js.map
  36. 0 0
      public/swagger/swagger-ui.css
  37. 0 0
      public/swagger/swagger-ui.css.map
  38. 0 0
      public/swagger/swagger-ui.js
  39. 0 0
      public/swagger/swagger-ui.js.map
  40. 24 0
      public/swagger/swagger.json
  41. 113 12
      router/router.go

+ 84 - 18
app/api/youngee_talent_api/talent_auth_get_api.go

@@ -86,7 +86,7 @@ func (*talentAuthGetApi) GetTalentAccountKuaishou(r *ghttp.Request) {
 	}
 }
 
-// 达人授权二维码展示
+// 达人授权二维码展示(包括抖音,快手),需携带platform_id)
 func (*talentAuthGetApi) DisplayQrcode(r *ghttp.Request) {
 	res := youngee_talent_service.GetQrcode(r)
 	err := r.Response.WriteJson(res)
@@ -105,9 +105,18 @@ func (*talentAuthGetApi) CheckAccount(r *ghttp.Request) {
 	}
 }
 
-// 轮询用户是否扫码了,/kuangshouauth中删除老数据。此接口code=0时,说明查到了新数据进来。弹窗消失
-func (*talentAuthGetApi) CheckNewAccount(r *ghttp.Request) {
-	res := youngee_talent_service.CheckNewAccount(r)
+// 轮询用户是否扫码了,,好让弹窗消失 1.避免重复绑定 2.扫码之后弹窗消失。/kuangshouauth中删除老数据。此接口code=0时,说明查到了新数据进来。弹窗消失
+func (*talentAuthGetApi) CheckKsNewAccount(r *ghttp.Request) {
+	res := youngee_talent_service.CheckKsNewAccount(r)
+	err := r.Response.WriteJson(res)
+	if err != nil {
+		panic("write response error")
+	}
+}
+
+// 轮询用户是否扫码了,好让弹窗消失/douyinauth中检查是否已被绑定,未绑定则,删除老数据。此接口code=0时,说明查到了新数据进来。弹窗消失
+func (*talentAuthGetApi) CheckDyNewAccount(r *ghttp.Request) {
+	res := youngee_talent_service.CheckDyNewAccount(r)
 	err := r.Response.WriteJson(res)
 	if err != nil {
 		panic("write response error")
@@ -159,49 +168,52 @@ func (*talentAuthGetApi) LikeCount(r *ghttp.Request) {
 	}
 }
 
-// 抖音总点赞数
-func (*talentAuthGetApi) DyVideoCount(r *ghttp.Request) {
-	res := youngee_talent_service.DyVideoCount(r)
+// 获取用户快手平台账号列表
+func (*talentAuthGetApi) GetKuaishouList(r *ghttp.Request) {
+	res := youngee_talent_service.GetKuaishouList(r)
 	err := r.Response.WriteJson(res)
 	if err != nil {
 		panic("write response error")
 	}
 }
 
-// 查询抖音总点赞数
-func (*talentAuthGetApi) DyLikeCount(r *ghttp.Request) {
-	res := youngee_talent_service.DyLikeCount(r)
+// 获取用户抖音平台账号列表
+func (*talentAuthGetApi) GetDouyinList(r *ghttp.Request) {
+	res := youngee_talent_service.GetDouyinList(r)
 	err := r.Response.WriteJson(res)
 	if err != nil {
 		panic("write response error")
 	}
 }
 
-// 获取用户快手平台账号列表
-func (*talentAuthGetApi) GetKuaishouList(r *ghttp.Request) {
-	res := youngee_talent_service.GetKuaishouList(r)
+// 带货---点击添加橱窗---展示可选择的快手信息
+// 带货---免费领样---展示可选择的快手信息
+func (*talentAuthGetApi) AddWindowKuaishouList(r *ghttp.Request) {
+	res := youngee_talent_service.AddWindowKuaishouList(r)
 	err := r.Response.WriteJson(res)
 	if err != nil {
 		panic("write response error")
 	}
 }
 
-// 获取快手平台账号列表(标记条件不满足的)
-func (*talentAuthGetApi) GetKuaishouListWithCondition(r *ghttp.Request) {
-	res := youngee_talent_service.GetKuaishouListWithCondition(r)
+// 带货---免费领样---展示可选择的快手信息(多了对是否报名的判断)
+func (*talentAuthGetApi) SignUpSecKuaishouList(r *ghttp.Request) {
+	res := youngee_talent_service.SignUpSecKuaishouList(r)
 	err := r.Response.WriteJson(res)
 	if err != nil {
 		panic("write response error")
 	}
 }
 
-func (*talentAuthGetApi) CheckTokenExp(r *ghttp.Request) {
-	res := youngee_talent_service.CheckTokenExp(r)
+// 带货加入橱窗---选中账号---点击提交(选品不存在/未开通)--需要提供productid和openid和粉丝数和销量(他们来自list中)
+func (*talentAuthGetApi) AddWindowWithKsAccount(r *ghttp.Request) {
+	res := youngee_talent_service.AddWindowWithKsAccount(r)
 	err := r.Response.WriteJson(res)
 	if err != nil {
 		panic("write response error")
 	}
 }
+
 func (*talentAuthGetApi) AddWindow(r *ghttp.Request) {
 	res := youngee_talent_service.AddWindow(r)
 	err := r.Response.WriteJson(res)
@@ -572,3 +584,57 @@ func (*talentAuthGetApi) UpdateRewardStage(r *ghttp.Request) {
 		panic("write response error")
 	}
 }
+
+// 收藏/取消收藏种草项目
+func (*talentAuthGetApi) ProjectCollection(r *ghttp.Request) {
+	res := youngee_task_service.ProjectCollection(r)
+	err := r.Response.WriteJson(res)
+	if err != nil {
+		panic("write response error")
+	}
+}
+
+// 种草收藏列表,点击收藏卡片调用getdetail即可进入详情页
+func (*talentAuthGetApi) GetProjectCollectionList(r *ghttp.Request) {
+	res := youngee_sectask_service.GetProjectCollectionList(r)
+	err := r.Response.WriteJson(res)
+	if err != nil {
+		panic("write response error")
+	}
+}
+
+// 收藏/取消收藏 收藏表中插入数据。带货项目 参数:selectionId,productId
+func (*talentAuthGetApi) SelectionCollection(r *ghttp.Request) {
+	res := youngee_task_service.SelectionCollection(r)
+	err := r.Response.WriteJson(res)
+	if err != nil {
+		panic("write response error")
+	}
+}
+
+// 带货收藏列表,点击收藏卡片调用getdetail即可进入详情页
+func (*talentAuthGetApi) GetSelectionCollectionList(r *ghttp.Request) {
+	res := youngee_sectask_service.GetSelectionCollectionList(r)
+	err := r.Response.WriteJson(res)
+	if err != nil {
+		panic("write response error")
+	}
+}
+
+// 获取种草浏览历史列表
+func (*talentAuthGetApi) GetProjectBrowseHistory(r *ghttp.Request) {
+	res := youngee_talent_service.GetProjectBrowseHistory(r)
+	err := r.Response.WriteJson(res)
+	if err != nil {
+		panic("write response error")
+	}
+}
+
+// 获取带货浏览历史列表 get selectionid,productid
+func (*talentAuthGetApi) GetSelectionBrowseHistory(r *ghttp.Request) {
+	res := youngee_talent_service.GetSelectionBrowseHistory(r)
+	err := r.Response.WriteJson(res)
+	if err != nil {
+		panic("write response error")
+	}
+}

+ 5 - 13
app/api/youngee_talent_api/talent_auth_post_api.go

@@ -149,15 +149,6 @@ func (*talentAuthPostApi) AddTaskData(r *ghttp.Request) {
 	}
 }
 
-// 收藏种草项目
-func (*talentAuthPostApi) ProjectCollection(r *ghttp.Request) {
-	res := youngee_task_service.ProjectCollection(r)
-	err := r.Response.WriteJson(res)
-	if err != nil {
-		panic("write response error")
-	}
-}
-
 // UpdateLogisticsAddress 修改达人收货地址
 // youngee_task_info
 func (*talentAuthPostApi) UpdateLogisticsAddress(r *ghttp.Request) {
@@ -219,16 +210,17 @@ func (*talentAuthPostApi) AddYoungTeam(r *ghttp.Request) {
 	}
 }
 
-func (*talentAuthPostApi) SignUpSecTask(r *ghttp.Request) {
-	res := youngee_sectask_service.SignUpSecTask(r)
+func (*talentAuthPostApi) SignUpSecTaskFromWindow(r *ghttp.Request) {
+	res := youngee_sectask_service.SignUpSecTaskFromWindow(r)
 	err := r.Response.WriteJson(res)
 	if err != nil {
 		panic("write response error")
 	}
 }
 
-func (*talentAuthPostApi) SignUpSecTaskFromWindow(r *ghttp.Request) {
-	res := youngee_sectask_service.SignUpSecTaskFromWindow(r)
+// 已选中账号--点击立即报名并加入橱窗
+func (*talentAuthPostApi) SignUpSecTaskWithKsAccount(r *ghttp.Request) {
+	res := youngee_sectask_service.SignUpSecTaskWithKsAccount(r)
 	err := r.Response.WriteJson(res)
 	if err != nil {
 		panic("write response error")

+ 0 - 1
app/api/youngee_talent_api/talent_get_api.go

@@ -39,7 +39,6 @@ func (*talentGetApi) GetProjectList(r *ghttp.Request) {
 // 前端可能传过来筛选和搜索的参数
 // 筛选参数参数形如&secform[]=2&secform[]=3&secform[]=9
 func (*talentGetApi) GetSelectionList(r *ghttp.Request) {
-	fmt.Println("biaaach")
 	res := youngee_sectask_service.GetSelectionList(r)
 
 	err := r.Response.WriteJson(res)

+ 11 - 1
app/api/youngee_talent_api/talent_post_api.go

@@ -30,7 +30,6 @@ func (*talentPostApi) Login(r *ghttp.Request) {
 //	}
 //}
 
-// Login 达人端手机号登录
 func (*talentPostApi) SmsLogin(r *ghttp.Request) {
 	// 向微信服务端校验登录凭证
 	res := youngee_talent_service.LoginFromSms(r)
@@ -58,3 +57,14 @@ func (*talentPostApi) SendSmsCode(r *ghttp.Request) {
 		r.Response.WriteJson("短信发送失败")
 	}
 }
+
+// 达人更换手机号码
+// post 请求体:手机号和验证码
+func (*talentPostApi) ChangePhone(r *ghttp.Request) {
+	// 向微信服务端校验登录凭证
+	res := youngee_talent_service.ChangePhone(r)
+	err := r.Response.WriteJson(res)
+	if err != nil {
+		r.Response.WriteJson("短信发送失败")
+	}
+}

+ 25 - 2
app/model/youngee_talent_model/auth_model.go

@@ -5,6 +5,24 @@ import (
 	"github.com/gogf/gf/util/gmeta"
 )
 
+// 商家端快手信息表
+type M_KuaishouUserInfo struct {
+	gmeta.Meta   `orm:"table:youngee_m_kuaishou_userinfo"`
+	Id           int         `json:"id" orm:"id,primary"`
+	OpenId       string      `json:"open_id" orm:"open_id"`
+	Code         string      `json:"code" orm:"code"`
+	AccessToken  string      `json:"access_token" orm:"access_token"`
+	RefreshToken string      `json:"refresh_token" orm:"refresh_token"`
+	Name         string      `json:"name" orm:"name"`                 //账号所属人  表单中填写
+	Ksnumber     string      `json:"ks_number" orm:"ks_number"`       //快手号 ,表单中填写
+	PhoneNumber  string      `json:"phone_number" orm:"phone_number"` //手机号,表单中填写
+	NickName     string      `json:"nick_name" orm:"nick_name"`
+	Expired      int         `json:"expired" orm:"expired"`           ////0表示没有过期,1表示过期
+	CreateTime   *gtime.Time `json:"create_time" orm:"create_time"  ` // 创建时间
+	UpdateTime   *gtime.Time `json:"update_time" orm:"update_time"  ` // 创建时间
+	IsDelete     int         `json:"is_delete" orm:"is_delete"`
+}
+
 type KuaishouUserInfo struct {
 	gmeta.Meta   `orm:"table:platform_kuaishou_user_info"`
 	Id           int         `json:"id" orm:"id,primary"`
@@ -17,7 +35,7 @@ type KuaishouUserInfo struct {
 	NickName     string      `json:"nick_name" orm:"nick_name"`
 	HeadUri      string      `json:"head_uri" orm:"head_uri"`
 	Fan          int         `json:"fan" orm:"fan"`
-	Expired      bool        `json:"expired" orm:"expired"`
+	Expired      int         `json:"expired" orm:"expired"` //0表示没有过期,1表示过期
 	SaleNum30day int         `json:"sale_num_30day" orm:"sale_num_30day"`
 	SaleNumTotal int         `json:"sale_num_total" orm:"sale_num_total"`
 	CreateTime   *gtime.Time `json:"create_time" orm:"create_time"  ` // 创建时间
@@ -28,7 +46,7 @@ type KuaishouUserInfo struct {
 	Status       int         `json:"status"`
 	UseCode      int         `json:"use_code" ` //满足条件的账号可被选择
 	BindCode     int         `json:"bind_code"` //账号绑定情况
-	Exipired     int         `json:"exipired"`
+	IsSign       int         `json:"is_sign"`   //是否报名该任务
 }
 
 // 快手列表返回的结果
@@ -37,3 +55,8 @@ type KSListResult struct {
 	Count    int                 // 不同 open_id 的个数
 	UserInfo []*KuaishouUserInfo // 用户信息列表
 }
+
+type DYListResult struct {
+	Count    int
+	UserInfo []*KuaishouUserInfo // 用户信息列表
+}

+ 8 - 2
app/model/youngee_talent_model/project_info.go

@@ -34,14 +34,20 @@ type ProjectInfo struct {
 	ProductPhotoSnap string             `orm:"product_photo_snap"   json:"product_photo_snap"` // 商品图片快照
 }
 
-// 种草收藏
+// 种草收藏表信息
 type ProjectCollection struct {
 	gmeta.Meta   `orm:"younggee_project_collect_info"`
 	CollectionId int         `json:"collection_id"` // 主键自增长
 	TalentId     string      `json:"talent_id"`     //
 	ProjectId    string      `json:"project_id"`
 	CreateTime   *gtime.Time `json:"create_time"`
-	Delete       int         `json:"delete"` //默认为0。0:收藏。1:取消收藏
+	Deleted      int         `json:"deleted"` //默认为0。0:收藏。1:取消收藏
+}
+
+// 展示种草收藏list
+type ProjectCollectionInfoList struct {
+	Count                 int              `json:"count"`
+	ProjectCollectionList []*ProjectDetail `json:"ProjectCollectionList"`
 }
 
 type ProjectInfoList struct {

+ 16 - 0
app/model/youngee_talent_model/selection.go

@@ -45,6 +45,11 @@ type SelectionInfoList struct {
 	//SeletionInfos []interface{}
 }
 
+type SelectionCollectionInfoList struct {
+	Count                   int                `json:"count"`
+	SelectionCollectionList []*SelectionDetail `json:"selectionCollectionList"`
+}
+
 type FreeStrategy struct {
 	gmeta.Meta        `orm:"table:free_strategy"`
 	FreeStrategyId    int    `orm:"free_strategy_id" json:"free_strategy_id"`       // 免费领样策略id
@@ -129,3 +134,14 @@ type SelectionDetail struct {
 	YounggeeProductPhoto []*YounggeeProductPhoto `orm:"with:product_id=product_id"`     // 商品图片表
 	PlatformInfo         *PlatformInfo           `orm:"with:platform_id=platform"`      //一个selection只有一个平台,直接指针对象object
 }
+
+// 种草收藏列表
+type SelectionCollection struct {
+	gmeta.Meta   `orm:"younggee_selection_collect_info"`
+	CollectionId int         `json:"collection_id"` // 主键自增长
+	TalentId     string      `json:"talent_id"`     //
+	SelectionId  string      `json:"selection_id"`
+	ProductId    string      `json:"product_id"`
+	CreateTime   *gtime.Time `json:"create_time"`
+	Deleted      int         `json:"deleted"` //默认为0。0:收藏。1:取消收藏
+}

+ 8 - 7
app/model/youngee_talent_model/selection_task.go

@@ -8,10 +8,10 @@ import (
 
 type SignSecTaskReq struct {
 	SelectionId string `json:"selection_id"`
-	ProductId   int    `json:"product_id"`
-	AddressId   uint64 `json:"address_id"`
-	LeadTeamId  string `json:"lead_team_id"`
-	TeamId      string `json:"team_id"`
+	ProductId   string `json:"product_id"`
+	AddressId   uint64 `json:"address_id"`   //添加橱窗不需要
+	LeadTeamId  string `json:"lead_team_id"` //添加橱窗不需要
+	TeamId      string `json:"team_id"`      //添加橱窗不需要
 	SaleNum     int    `json:"saleNum"`
 	FansNum     int    `json:"fans"`
 	OpenId      string `json:"open_id"`
@@ -26,8 +26,8 @@ type SecTaskInfoDetail struct {
 	Id                     int                          `orm:"id,primary"                json:"id"`           // 递增id
 	TaskId                 string                       `orm:"task_id"                   json:"task_id"`      // 选品任务id
 	SelectionId            string                       `orm:"selection_id"              json:"selection_id"` // 选品id
-	OpenId                 string                       `orm:"open_id"                  json:"open_id"`
-	ProductId              int                          `orm:"product_id"                json:"product_id"`
+	OpenId                 string                       `orm:"open_id"                  json:"open_id"`       //快手唯一标识
+	ProductId              string                       `orm:"product_id"                json:"product_id"`
 	TalentId               string                       `orm:"talent_id"                 json:"talent_id"`                 // 达人id
 	AccountId              int                          `orm:"account_id"                json:"account_id"`                // 账号id
 	PlatformId             int                          `orm:"platform_id"                json:"platform_id"`              // 平台id
@@ -75,7 +75,8 @@ type SecTaskInfoWindowDetail struct {
 	Id                     int    `orm:"id,primary"                json:"id"`           // 递增id
 	TaskId                 string `orm:"task_id"                   json:"task_id"`      // 选品任务id
 	SelectionId            string `orm:"selection_id"              json:"selection_id"` // 选品id
-	ProductId              int    `orm:"product_id"                json:"product_id"`
+	OpenId                 string `orm:"open_id"                  json:"open_id"`       //快手账号标识
+	ProductId              string `orm:"product_id"                json:"product_id"`
 	TalentId               string `orm:"talent_id"                 json:"talent_id"`                 // 达人id
 	AccountId              int    `orm:"account_id"                json:"account_id"`                // 账号id
 	PlatformId             int    `orm:"platform_id"                json:"platform_id"`              // 平台id

+ 167 - 103
app/service/youngee_sectask_service/seletion_square.go

@@ -5,6 +5,7 @@ import (
 	"encoding/json"
 	"fmt"
 	"github.com/gogf/gf/database/gdb"
+	"github.com/lin-jim-leon/kuaishou/open/merchant"
 	"reflect"
 	"youngmini_server/app/dao"
 	"youngmini_server/app/model"
@@ -26,6 +27,18 @@ const (
 	selectionStatusInProgress
 	selectionStatusInvalid
 	selectionStatusClosed
+	//快手电商
+	ClientKey    = "ks651333097154138217"
+	ClientSecret = "dBt0rVRhTpUqcrOYGGpv0A"
+	SignSecret   = "bf6393dce0a2b669ee348bebb837b0da"
+	//快手平台
+	ClientKey1    = "ks671599294546520767"
+	ClientSecret1 = "8VSrp3O09nunjLMXR1uotg"
+	//SignSecret1   = "bf6393dce0a2b669ee348bebb837b0da"
+	//抖音平台
+	ClientKey2    = "awi77xl5kpl16hmi"
+	ClientSecret2 = "7ce6d2531bd4489122d89658063fd76e"
+	//SignSecret1   = "bf6393dce0a2b669ee348bebb837b0da"
 )
 
 // 获取项目信息列表service
@@ -178,16 +191,122 @@ func GetSelectionList(r *ghttp.Request) *TalentHttpResult {
 	return &TalentHttpResult{Code: 0, Msg: "success", Data: selectionInfoList}
 }
 
+// 获取带货收藏列表
+func GetSelectionCollectionList(r *ghttp.Request) *TalentHttpResult {
+	// 从 session 中获取 talent_id
+	tId, err := utils.SessionTalentInfo.GetTalentIdFromSession(r)
+	if err != nil {
+		return nil
+	}
+
+	// 获取 younggee_selection_collect_info 表中符合条件的 selection_id 列表
+	var selectionIds []string
+	type SelectionInfo struct {
+		SelectionID string `json:"selection_id"`
+	}
+	var selectionInfos []SelectionInfo
+	err = g.DB().Model("younggee_selection_collect_info").Where("talent_id = ? AND delete = ?", tId, 0).Fields("selection_id").Scan(&selectionInfos)
+	fmt.Println("-----", selectionInfos)
+	if err != nil {
+		fmt.Println("查询 selection_id 失败---", err.Error())
+		return &TalentHttpResult{Code: -6, Msg: "查询数据库失败"}
+	}
+	for _, info := range selectionInfos {
+		selectionIds = append(selectionIds, info.SelectionID)
+	}
+
+	// 如果没有符合条件的 selection_id,则直接返回空的列表
+	if len(selectionIds) == 0 {
+		return &TalentHttpResult{Code: 0, Msg: "success", Data: youngee_talent_model.SelectionCollectionInfoList{Count: 0}}
+	}
+
+	// 根据获取到的 selection_id 列表,从 younggee_selection_info 表中获取对应的信息
+	var selectionCollectionInfoList = youngee_talent_model.SelectionCollectionInfoList{
+		Count: len(selectionInfos),
+	}
+	err = g.DB().Model("younggee_selection_info").WithAll().Where("selection_id IN(?)", selectionIds).Scan(&selectionCollectionInfoList.SelectionCollectionList)
+	if err != nil {
+		return &TalentHttpResult{Code: -6, Msg: "查询数据库失败"}
+	}
+
+	// 返回结果
+	return &TalentHttpResult{Code: 0, Msg: "success", Data: selectionCollectionInfoList}
+}
+
+// 获取种草收藏列表
+func GetProjectCollectionList(r *ghttp.Request) *TalentHttpResult {
+	// 从 session 中获取 talent_id
+	tId, err := utils.SessionTalentInfo.GetTalentIdFromSession(r)
+	if err != nil {
+		return nil
+	}
+
+	// 获取 younggee_selection_collect_info 表中符合条件的 selection_id 列表
+	var projectIds []string
+	type ProjectInfo struct {
+		ProjectID string `json:"project_id"`
+	}
+	var projectInfos []ProjectInfo
+	err = g.DB().Model("younggee_project_collect_info").Where("talent_id = ? AND deleted = ?", tId, 0).Fields("project_id").Scan(&projectInfos)
+	fmt.Println("-----", projectInfos)
+	if err != nil {
+		fmt.Println("查询 project_id 失败---", err.Error())
+		return &TalentHttpResult{Code: -6, Msg: "查询数据库失败"}
+	}
+	for _, info := range projectInfos {
+		projectIds = append(projectIds, info.ProjectID)
+	}
+
+	// 如果没有符合条件的 selection_id,则直接返回空的列表
+	if len(projectIds) == 0 {
+		return &TalentHttpResult{Code: 0, Msg: "success", Data: youngee_talent_model.ProjectCollectionInfoList{Count: 0}}
+	}
+
+	// 根据获取到的 selection_id 列表,从 younggee_selection_info 表中获取对应的信息
+	var projectCollectionInfoList = youngee_talent_model.ProjectCollectionInfoList{
+		Count: len(projectIds),
+	}
+	err = g.DB().Model("project_info").WithAll().Where("project_id IN(?)", projectIds).Scan(&projectCollectionInfoList.ProjectCollectionList)
+	if err != nil {
+		return &TalentHttpResult{Code: -6, Msg: "查询数据库失败"}
+	}
+
+	// 返回结果
+	return &TalentHttpResult{Code: 0, Msg: "success", Data: projectCollectionInfoList}
+}
+
 // 获取单个选品详情service
 func GetSelectionDetail(r *ghttp.Request) *TalentHttpResult {
+	tid, err := utils.SessionTalentInfo.GetTalentIdFromSession(r)
+	if err != nil {
+		return &TalentHttpResult{Code: -1, Msg: "Get talent info failed"}
+	}
 	sid := r.GetQueryString("selectionid", 0)
 	pid := r.GetQueryString("productid", 0)
 	if sid == "" {
 		return &TalentHttpResult{Code: -2, Msg: "data query failed"}
 	}
 
+	//带货浏览历史
+	//浏览历史
+	currentDate := gtime.Now().Format("Ymd")
+	fmt.Println("date-----:", currentDate)
+	// 设计 Redis Key
+	redisBrowseKey := fmt.Sprintf("browseSelection:%s:%s", currentDate, tid)
+	fmt.Println("redis浏览记录的key为——————————", redisBrowseKey)
+	// 将 selection_id 添加到 Redis 中的 SET
+	_, err = g.Redis().Do("SADD", redisBrowseKey, sid)
+	if err != nil {
+		return &TalentHttpResult{Code: -1, Msg: "Redis 存浏览历史数据失败"}
+	}
+	// 设置 Key 的过期时间为 7 天
+	_, err = g.Redis().Do("EXPIRE", redisBrowseKey, 7*24*60*60) // 7 天的秒数
+	if err != nil {
+		return &TalentHttpResult{Code: -2, Msg: "Redis 设置过期时间失败"}
+	}
+
 	var selectionDetail *youngee_talent_model.SelectionDetail
-	err := g.DB().Model(youngee_talent_model.SelectionDetail{}).WithAll().Where("selection_id", sid).Scan(&selectionDetail)
+	err = g.DB().Model(youngee_talent_model.SelectionDetail{}).WithAll().Where("selection_id", sid).Scan(&selectionDetail)
 	if err != nil {
 		return &TalentHttpResult{Code: -3, Msg: err.Error()}
 	}
@@ -261,8 +380,10 @@ func IsSignUpSecTask(r *ghttp.Request) *TalentHttpResult {
 	return &TalentHttpResult{Code: 0, Msg: "success", Data: isSign}
 }
 
+// 添加橱窗--选中账号--此账号是否有报名信息
 func IsCreateSecTask(r *ghttp.Request) *TalentHttpResult {
 	tid, err := utils.SessionTalentInfo.GetTalentIdFromSession(r)
+	openId := r.GetString("open_id", "")
 	if err != nil {
 		return &TalentHttpResult{Code: -1, Msg: "Get talent info failed"}
 	}
@@ -271,7 +392,7 @@ func IsCreateSecTask(r *ghttp.Request) *TalentHttpResult {
 	//1.查task表全部数据
 	var task []youngee_talent_model.SecTaskInfoDetail
 	err = g.DB().Model(youngee_talent_model.SecTaskInfoDetail{}).WithAll().
-		Where("talent_id = ? AND selection_id = ? ", tid, selectionId).
+		Where("talent_id = ? AND selection_id = ? open_id = ?", tid, selectionId, openId).
 		Scan(&task)
 	if err != nil {
 		return &TalentHttpResult{Code: 0, Msg: err.Error(), Data: nil}
@@ -282,20 +403,21 @@ func IsCreateSecTask(r *ghttp.Request) *TalentHttpResult {
 	if len(task) != 0 {
 		isSign.IsSign = 1
 		isSign.SecTaskInfo = &task[0]
+		return &TalentHttpResult{Code: 1, Msg: "存在报名信息", Data: isSign}
 	} else {
 		isSign.IsSign = 0
+		return &TalentHttpResult{Code: 2, Msg: "不存在报名信息", Data: isSign}
 	}
-	return &TalentHttpResult{Code: 0, Msg: "success", Data: isSign}
+
 }
 
-// 选品任务报名service
-func SignUpSecTask(r *ghttp.Request) *TalentHttpResult {
+// 已选中账号--点击立即报名并加入橱窗--此时肯定未过期,未报名,提供免费领
+func SignUpSecTaskWithKsAccount(r *ghttp.Request) *TalentHttpResult {
 	tid, err := utils.SessionTalentInfo.GetTalentIdFromSession(r)
 	if err != nil {
 		return &TalentHttpResult{Code: -1, Msg: "Get talent info failed"}
 	}
-
-	// 解析前端传来的参数
+	// 解析前端post请求传来的参数,
 	var signSecTaskReq *youngee_talent_model.SignSecTaskReq
 	err = r.ParseForm(&signSecTaskReq)
 	if err != nil {
@@ -360,7 +482,6 @@ func SignUpSecTask(r *ghttp.Request) *TalentHttpResult {
 	if err != nil {
 		return &TalentHttpResult{Code: -9, Msg: "encode delivery address snap failed"}
 	}
-
 	secTaskInfo := youngee_talent_model.SecTaskInfoDetail{
 		TaskId:                 newTaskId,
 		SelectionId:            signSecTaskReq.SelectionId,
@@ -396,105 +517,46 @@ func SignUpSecTask(r *ghttp.Request) *TalentHttpResult {
 		TaskDdl:                selectionInfo.TaskDdl,
 	}
 
-	//删除添加橱窗时创建的不完整的数据
+	//加入橱窗逻辑,
+	productId := signSecTaskReq.ProductId
+	pIdSlice := []string{productId}
+	value, err := g.DB().Model("platform_kuaishou_user_info").Fields("open_id").Where("talent_id=? AND open_id = ?", tid, signSecTaskReq.OpenId).Value()
+	if err != nil {
+		fmt.Println("query db fail")
+	}
+	accessToken := value.String()
+	_, err = merchant.AddItemsToShelf(ClientKey, SignSecret, accessToken, pIdSlice)
+	if err != nil {
+		//表示添加失敗,沒有開通
+		return &TalentHttpResult{Code: -1, Msg: "快手未開通橱窗、商品不存在或已下线", Data: nil}
+	}
+	// 查询成功,返回成功结果和数据
+	fmt.Println("加入橱窗成功")
+
+	//删除仅点击添加橱窗时创建的不完整的数据
 	_, err = g.DB().Model("younggee_sec_task_info").
-		Where("talent_id = ? AND selection_id = ? ", tid, signSecTaskReq.SelectionId).
+		Where("talent_id = ? AND selection_id = ? AND open_id=?", tid, signSecTaskReq.SelectionId, signSecTaskReq.OpenId).
 		Delete()
 	if err != nil {
 		return &TalentHttpResult{Code: -17, Msg: "younggee_sec_task_info delete failed"}
 	}
-
 	err = g.DB().Transaction(context.TODO(), func(ctx context.Context, tx *gdb.TX) error {
-		// young之团收益计算
-		var rewardConfig *model.YounggeeTeamRewardConfig
-		whereCondition := g.Map{
-			dao.YounggeeTeamRewardConfig.Columns.ProjectType:  2,
-			dao.YounggeeTeamRewardConfig.Columns.TaskForm:     selectionDetail.TaskMode + 3,
-			dao.YounggeeTeamRewardConfig.Columns.ContentForm:  selectionDetail.ContentType,
-			dao.YounggeeTeamRewardConfig.Columns.RewardReason: talentInfo.UserType,
+		// 减少选品库存
+		whereCondition1 := g.Map{
+			dao.YounggeeSelectionInfo.Columns.SelectionId: selectionDetail.SelectionId,
 		}
-		err = tx.Model(dao.YounggeeTeamRewardConfig.Table).Where(whereCondition).Scan(&rewardConfig)
+		updateData := g.Map{
+			dao.YounggeeSelectionInfo.Columns.RemainNum: gdb.Raw(fmt.Sprintf("%s - 1", dao.YounggeeSelectionInfo.Columns.RemainNum)),
+		}
+		_, err = tx.Ctx(ctx).Model(dao.YounggeeSelectionInfo.Table).Where(whereCondition1).Data(updateData).Update()
 		if err != nil {
-			fmt.Println(err)
 			return err
 		}
-		if rewardConfig != nil {
-			secTaskInfo.TeamPoint = rewardConfig.Point
-			secTaskInfo.TeamIncome = rewardConfig.Money
-
-			whereCondition = g.Map{
-				dao.YounggeeTalentTeam.Columns.TeamId: signSecTaskReq.LeadTeamId,
-			}
-			whereCondition1 := g.Map{
-				dao.YounggeeTalentTeam.Columns.TeamId: signSecTaskReq.TeamId,
-			}
-			updateData := g.Map{
-				dao.YounggeeTalentTeam.Columns.PointIncome: gdb.Raw(fmt.Sprintf("%s + %d", dao.YounggeeTalentTeam.Columns.PointIncome, rewardConfig.Point)),
-				dao.YounggeeTalentTeam.Columns.MoneyIncome: gdb.Raw(fmt.Sprintf("%s + %f", dao.YounggeeTalentTeam.Columns.MoneyIncome, float64(rewardConfig.Money)*secTaskInfo.TaskReward/100)),
-			}
-			_, err = tx.Ctx(ctx).Model(dao.YounggeeTalentTeam.Table).Data(updateData).Where(whereCondition).Update()
-			if err != nil {
-				return err
-			}
-			_, err = tx.Ctx(ctx).Model(dao.YounggeeTalentTeam.Table).Data(updateData).Where(whereCondition1).Update()
-			if err != nil {
-				return err
-			}
-
-			// young之团状态变更
-			if signSecTaskReq.LeadTeamId != "" {
-				// 更新young之团状态
-				whereCondition2 := g.Map{
-					dao.YounggeeTalentTeam.Columns.TeamStatus: 1,
-				}
-				updateData = g.Map{
-					dao.YounggeeTalentTeam.Columns.TeamStatus: 2,
-				}
-				_, err = tx.Ctx(ctx).Model(dao.YounggeeTalentTeam.Table).Where(whereCondition).Where(whereCondition2).Data(updateData).Update()
-				if err != nil {
-					return err
-				}
-			}
-			if signSecTaskReq.TeamId != "" {
-				// 更新young之团状态
-				whereCondition2 := g.Map{
-					dao.YounggeeTalentTeam.Columns.TeamStatus: 1,
-				}
-				updateData = g.Map{
-					dao.YounggeeTalentTeam.Columns.TeamStatus: 2,
-				}
-				_, err = tx.Ctx(ctx).Model(dao.YounggeeTalentTeam.Table).Where(whereCondition1).Where(whereCondition2).Data(updateData).Update()
-				if err != nil {
-					return err
-				}
-			}
-		}
-
-		if selectionDetail.SampleMode == 2 {
-			// 减少选品库存
-			whereCondition1 := g.Map{
-				dao.YounggeeSelectionInfo.Columns.SelectionId: selectionDetail.SelectionId,
-			}
-			updateData := g.Map{
-				dao.YounggeeSelectionInfo.Columns.RemainNum: gdb.Raw(fmt.Sprintf("%s - 1", dao.YounggeeSelectionInfo.Columns.RemainNum)),
-			}
-			_, err = tx.Ctx(ctx).Model(dao.YounggeeSelectionInfo.Table).Where(whereCondition1).Data(updateData).Update()
-			if err != nil {
-				return err
-			}
-			// 新建任务,初始化状态为待发货
-			secTaskInfo.TaskStage = 6
-			_, err = tx.Ctx(ctx).Model(dao.YounggeeSecTaskInfo.Table).Data(&secTaskInfo).Insert()
-			if err != nil {
-				return err
-			}
-
-		} else {
-			// 新建任务,初始化状态为待确认
-			_, err = tx.Ctx(ctx).Model(dao.YounggeeSecTaskInfo.Table).Data(&secTaskInfo).Insert()
-			if err != nil {
-				return err
-			}
+		// 新建任务,初始化状态为待发货
+		secTaskInfo.TaskStage = 6
+		_, err = tx.Ctx(ctx).Model(dao.YounggeeSecTaskInfo.Table).Data(&secTaskInfo).Insert()
+		if err != nil {
+			return err
 		}
 		return nil
 	})
@@ -511,7 +573,6 @@ func SignUpSecTask(r *ghttp.Request) *TalentHttpResult {
 }
 
 func SignUpSecTaskFromWindow(r *ghttp.Request) *TalentHttpResult {
-
 	tid, err := utils.SessionTalentInfo.GetTalentIdFromSession(r)
 	if err != nil {
 		return &TalentHttpResult{Code: -1, Msg: "Get talent info failed"}
@@ -563,6 +624,7 @@ func SignUpSecTaskFromWindow(r *ghttp.Request) *TalentHttpResult {
 	if err != nil {
 		return &TalentHttpResult{Code: -8, Msg: "encode talent info snap failed"}
 	}
+	//没有任务被创建时,用此数据
 	secTaskInfo := youngee_talent_model.SecTaskInfoWindowDetail{
 		TaskId:                 newTaskId,
 		SelectionId:            signSecTaskReq.SelectionId,
@@ -570,6 +632,7 @@ func SignUpSecTaskFromWindow(r *ghttp.Request) *TalentHttpResult {
 		SaleNum:                signSecTaskReq.SaleNum,
 		FansNum:                signSecTaskReq.FansNum,
 		TalentId:               tid,
+		OpenId:                 signSecTaskReq.OpenId,
 		AccountId:              accountInfo.AccountId,
 		TalentPlatformInfoSnap: string(accountSnap),
 		TalentPersonalInfoSnap: string(talentSnap),
@@ -580,7 +643,7 @@ func SignUpSecTaskFromWindow(r *ghttp.Request) *TalentHttpResult {
 		IsPayReward:      0,
 		TaskMode:         selectionInfo.TaskMode,
 		SampleMode:       3, //添加橱窗,当作不提供领样处理
-		PlatformId:       4, //快手平台
+		PlatformId:       4, //快手电商平台
 		TaskStage:        3,
 		TaskStatus:       1,
 		CreateDate:       gtime.Now(),
@@ -597,20 +660,21 @@ func SignUpSecTaskFromWindow(r *ghttp.Request) *TalentHttpResult {
 	}
 	//如果已经有数据了,删除。模拟在快手侧里把橱窗商品删了,想再加回来
 
-	//1.查task表全部数据
+	//1.查task表全部数据 , 有的话,只会有一条数据
 	var secTaskInfoList []youngee_talent_model.SecTaskInfoDetail
 	err = g.DB().Model(youngee_talent_model.SecTaskInfoDetail{}).WithAll().
-		Where("talent_id = ? AND selection_id = ? ", tid, signSecTaskReq.SelectionId).
+		Where("talent_id = ? AND selection_id = ? AND open_id = ?", tid, signSecTaskReq.SelectionId, signSecTaskReq.OpenId).
 		Scan(&secTaskInfoList)
 	if err != nil {
-		return &TalentHttpResult{Code: 0, Msg: err.Error(), Data: nil}
+		return &TalentHttpResult{Code: -16, Msg: err.Error(), Data: nil}
 	}
 	//2.如果task不为空。取出free_stage的值。插入的值含有删除数据的free_stage
+	//这种情况出现在报名只有又点击加入橱窗
 	if len(secTaskInfoList) != 0 {
 		free_stage := secTaskInfoList[0].FreeStage
 		//删除旧的,
 		_, err = g.DB().Model("younggee_sec_task_info").
-			Where("talent_id = ? AND selection_id = ? ", tid, signSecTaskReq.SelectionId).
+			Where("talent_id = ? AND selection_id = ? AND open_id = ?", tid, signSecTaskReq.SelectionId, signSecTaskReq.OpenId).
 			Delete()
 		if err != nil {
 			return &TalentHttpResult{Code: -17, Msg: "younggee_sec_task_info delete failed"}

+ 110 - 0
app/service/youngee_talent_service/BrowseHistory.go

@@ -0,0 +1,110 @@
+package youngee_talent_service
+
+import (
+	"fmt"
+	"github.com/gogf/gf/frame/g"
+	"github.com/gogf/gf/net/ghttp"
+	"github.com/gogf/gf/util/gconv"
+	"strings"
+	"youngmini_server/app/model/youngee_talent_model"
+	"youngmini_server/app/utils"
+)
+
+// 存储每个日期和对应的种草列表
+type BrowseProjectHistory struct {
+	Date        string                               `json:"date"`
+	ProjectList []youngee_talent_model.ProjectDetail `json:"projectList"`
+}
+
+// 存储每个日期和对应的带货列表
+type BrowseSelectionHistory struct {
+	Date          string                                 `json:"date"`
+	SelectionList []youngee_talent_model.SelectionDetail `json:"selectionList"`
+}
+
+func GetProjectBrowseHistory(r *ghttp.Request) *TalentHttpResult {
+	tid, err := utils.SessionTalentInfo.GetTalentIdFromSession(r)
+	if err != nil {
+		return &TalentHttpResult{Code: -1, Msg: "Get talent info failed"}
+	}
+	// 获取所有相关的 Redis Key
+	redisKeyPattern := fmt.Sprintf("browseProject:*:%s", tid)
+	keys, err := g.Redis().DoVar("KEYS", redisKeyPattern)
+	if err != nil {
+		fmt.Println("Get redis keys error", err)
+	}
+
+	// 初始化返回的数据
+	var browseProjectHistories []BrowseProjectHistory
+
+	// 遍历所有的日期 Key
+	for _, key := range keys.Slice() {
+		// 获取日期部分
+		keyStr := gconv.String(key)
+		date := strings.Split(keyStr, ":")[1]
+		// 获取该日期下的所有 pid
+		pids, err := g.Redis().DoVar("SMEMBERS", keyStr)
+		if err != nil {
+			println("Get redis keys error", err)
+		}
+
+		// 使用 pids 查询数据库,获取商品列表
+		var projectList []youngee_talent_model.ProjectDetail
+		err = g.DB().Model("project_info").WithAll().Where("project_id IN(?)", pids.Strings()).Scan(&projectList)
+		if err != nil {
+			println("Get redis projects error", err)
+		}
+		// 构建 BrowseHistory 对象
+		browseProjectHistory := BrowseProjectHistory{
+			Date:        date,
+			ProjectList: projectList,
+		}
+		// 添加到结果列表中
+		browseProjectHistories = append(browseProjectHistories, browseProjectHistory)
+	}
+	return &TalentHttpResult{Code: 0, Msg: "success", Data: browseProjectHistories}
+}
+
+// 获取带货浏览记录
+func GetSelectionBrowseHistory(r *ghttp.Request) *TalentHttpResult {
+	tid, err := utils.SessionTalentInfo.GetTalentIdFromSession(r)
+	if err != nil {
+		return &TalentHttpResult{Code: -1, Msg: "Get talent info failed"}
+	}
+	// 获取所有相关的 Redis Key
+	redisKeyPattern := fmt.Sprintf("browseSelection:*:%s", tid)
+	keys, err := g.Redis().DoVar("KEYS", redisKeyPattern)
+	if err != nil {
+		fmt.Println("Get redis keys error", err)
+	}
+
+	// 初始化返回的数据
+	var browseSelectionHistories []BrowseSelectionHistory
+
+	// 遍历所有的日期 Key
+	for _, key := range keys.Slice() {
+		// 获取日期部分
+		keyStr := gconv.String(key)
+		date := strings.Split(keyStr, ":")[1]
+		// 获取该日期下的所有 pid
+		selctionIds, err := g.Redis().DoVar("SMEMBERS", keyStr)
+		if err != nil {
+			println("Get redis keys error", err)
+		}
+
+		// 使用 pids 查询数据库,获取商品列表
+		var selectionList []youngee_talent_model.SelectionDetail
+		err = g.DB().Model("younggee_selection_info").WithAll().Where("selection_id IN(?)", selctionIds.Strings()).Scan(&selectionList)
+		if err != nil {
+			println("Get redis selections error", err)
+		}
+		// 构建 BrowseHistory 对象
+		browseSelectionHistory := BrowseSelectionHistory{
+			Date:          date,
+			SelectionList: selectionList,
+		}
+		// 添加到结果列表中
+		browseSelectionHistories = append(browseSelectionHistories, browseSelectionHistory)
+	}
+	return &TalentHttpResult{Code: 0, Msg: "success", Data: browseSelectionHistories}
+}

+ 1 - 0
app/service/youngee_talent_service/LoginFromSms.go

@@ -21,6 +21,7 @@ type LoginReq struct {
 }
 
 // 通过短信登录
+
 func LoginFromSms(r *ghttp.Request) *TalentHttpResult {
 	l := LoginReq{}
 	err := r.ParseForm(&l)

+ 49 - 2
app/service/youngee_talent_service/SendSmsCode.go

@@ -15,6 +15,8 @@ import (
 	"net/url"
 	"strings"
 	"time"
+	"youngmini_server/app/model/youngee_talent_model"
+	"youngmini_server/app/utils"
 )
 
 // 无需修改,用于格式化鉴权头域,给"X-WSSE"参数赋值
@@ -37,7 +39,7 @@ func SendSmsCode(r *ghttp.Request) *TalentHttpResult {
 	vcode := GetCode()
 	fmt.Println("验证码为=====>", vcode)
 
-	err = SendCode(l.Phone, vcode)
+	err = SendCodeImp(l.Phone, vcode)
 	if err != nil {
 		return &TalentHttpResult{Code: -1, Msg: "短信发送失败"}
 	}
@@ -61,7 +63,7 @@ func getRedisKey(phone string) string {
 }
 
 // 发送验证码具体实现
-func SendCode(phone string, vcode string) error {
+func SendCodeImp(phone string, vcode string) error {
 	//必填,请参考"开发准备"获取如下数据,替换为实际值
 	apiAddress := "https://smsapi.cn-south-1.myhuaweicloud.com:443/sms/batchSendSms/v1" //APP接入地址(在控制台"应用管理"页面获取)+接口访问URI
 	appKey := "NETTvTJJie9ax03v9K5T4DFB9EV6"                                            //APP_Key
@@ -157,3 +159,48 @@ func GetCode() string {
 	vcode := fmt.Sprintf("%06v", rnd.Int31n(1000000))
 	return vcode
 }
+
+type ChangeReq struct {
+	Phone string `json:"phone"`
+	Vcode string `json:"vcode"`
+}
+
+// 更换手机号
+func ChangePhone(r *ghttp.Request) *TalentHttpResult {
+	tid, err := utils.SessionTalentInfo.GetTalentIdFromSession(r)
+	if err != nil {
+		return &TalentHttpResult{Code: -1, Msg: "Get talent info failed"}
+	}
+	l := ChangeReq{}
+	err = r.ParseForm(&l)
+	if err != nil {
+		fmt.Printf("前端数据解析错误")
+	}
+	//手机号是否被绑定
+	existingTalent := &youngee_talent_model.TalentInfo{}
+	record, err := g.DB().Model(existingTalent).Where("talent_phone_number = ?", l.Phone).One()
+	if err != nil {
+		fmt.Println("查询错误:", err)
+		return &TalentHttpResult{Code: -3, Msg: "查询失败"}
+	}
+	// 检查是否找到了记录
+	if record != nil {
+		fmt.Println("手机号已存在:", record["talent_phone_number"])
+		return &TalentHttpResult{Code: -1, Msg: "手机号已绑定"}
+	} else {
+		VcodeKey := fmt.Sprintf("%s%s", "c_user:", l.Phone)
+		Vcode, _ := g.Redis().DoVar("GET", VcodeKey)
+		//验证码正确
+		if Vcode.String() == l.Vcode {
+			//修改youngee_talent_info表中手机号
+			_, err := g.DB().Model(existingTalent).Where("id=?", tid).Update(g.Map{"talent_phone_number": l.Phone})
+			if err != nil {
+				fmt.Println("更新失败")
+				return &TalentHttpResult{Code: -4, Msg: "手机号更新失败"}
+			}
+			return &TalentHttpResult{Code: 0, Msg: "更新成功"}
+		} else {
+			return &TalentHttpResult{Code: -2, Msg: "验证码错误"}
+		}
+	}
+}

+ 137 - 3
app/service/youngee_talent_service/talentVideoInfo.go

@@ -4,6 +4,8 @@ import (
 	"encoding/json"
 	"fmt"
 	"github.com/lin-jim-leon/kuaishou/util"
+	"io/ioutil"
+	"net/http"
 )
 
 const (
@@ -87,10 +89,142 @@ func GetLikeCount(appid string, accesstoken string) (int, error) {
 
 // 获取抖音视频列表
 // 获取快手视频列表(暂时最多统计200个视频)
-func GetDyVideoList(openid string, accesstoken string) (info VideoListResponse, err error) {
+type DyVideoStatistics struct {
+	ForwardCount  int `json:"forward_count"`
+	CommentCount  int `json:"comment_count"`
+	DiggCount     int `json:"digg_count"`
+	DownloadCount int `json:"download_count"`
+	PlayCount     int `json:"play_count"`
+	ShareCount    int `json:"share_count"`
+}
+
+type DyVideo struct {
+	Title       string            `json:"title"`
+	IsTop       bool              `json:"is_top"`
+	CreateTime  int64             `json:"create_time"`
+	IsReviewed  bool              `json:"is_reviewed"`
+	VideoStatus int               `json:"video_status"`
+	ShareURL    string            `json:"share_url"`
+	ItemID      string            `json:"item_id"`
+	MediaType   int               `json:"media_type"`
+	Cover       string            `json:"cover"`
+	Statistics  DyVideoStatistics `json:"statistics"`
+	VideoId     string            `json:"video_id"`
+}
+
+type DyExtraData struct {
+	ErrorCode      int    `json:"error_code"`
+	Description    string `json:"description"`
+	SubErrorCode   int    `json:"sub_error_code"`
+	SubDescription string `json:"sub_description"`
+	LogID          string `json:"logid"`
+	Now            int64  `json:"now"`
+}
+type DyData struct {
+	List        []DyVideo `json:"list"` // 视频列表
+	Cursor      int       `json:"cursor"`
+	Description string    `json:"description"`
+	ErrorCode   int       `json:"error_code"`
+	HasMore     bool      `json:"has_more"`
+}
+
+type DyVideoResponse struct {
+	Data      DyData      `json:"data"`
+	ExtraData DyExtraData `json:"extra"`
+}
+
+type DyVideoResult struct {
+	LikeCount  int `json:"like_count"`
+	VideoCount int `json:"video_count"`
+}
+
+func GetDyVideoInfo(openid string, accesstoken string) (info DyVideoResult, err error) {
+
+	var totalLikeCount int
+	var videoCount int
+
+	cursor := 0
+	hasMore := true
+
+	for hasMore {
+		// 调用 GetDyVideoList 获取视频列表
+		videoListRes, err := GetDyVideoList(openid, cursor, accesstoken)
+		if err != nil {
+			fmt.Println("GetDyVideoInfo error", err)
+			return DyVideoResult{}, err
+		}
+
+		// 统计 video_status=5 的视频总点赞数和视频数
+		for _, video := range videoListRes.Data.List {
+			if video.VideoStatus == 1 {
+				fmt.Println("*******")
+				fmt.Println(totalLikeCount)
+				totalLikeCount += video.Statistics.DiggCount
+				videoCount++
+			}
+		}
+
+		// 更新 cursor 和 hasMore
+		cursor = videoListRes.Data.Cursor
+		hasMore = videoListRes.Data.HasMore
+	}
+	fmt.Println("totalLikeCount", totalLikeCount)
+	fmt.Println("videoCount", videoCount)
+	return DyVideoResult{
+		LikeCount:  totalLikeCount,
+		VideoCount: videoCount,
+	}, nil
 
 }
 
-//获取抖音总点赞数
+// GetDyVideoInfo 发送GET请求并返回抖音视频列表信息
+func GetDyVideoList(openid string, cursor int, accesstoken string) (info DyVideoResponse, err error) {
+	// 请求URL
+	url := fmt.Sprintf("https://open.douyin.com/api/douyin/v1/video/video_list?count=20&cursor=%d&open_id=%s", cursor, openid)
+
+	// 创建请求
+	req, err := http.NewRequest("GET", url, nil)
+	if err != nil {
+		return info, err
+	}
+	// 设置请求头
+	req.Header.Set("access-token", accesstoken)
+	req.Header.Set("Content-Type", "application/json")
+
+	// 发送请求
+	client := &http.Client{}
+	resp, err := client.Do(req)
+	if err != nil {
+		return info, err
+	}
+	defer resp.Body.Close()
+	// 检查HTTP状态码是否为200
+	if resp.StatusCode != http.StatusOK {
+		return info, fmt.Errorf("request failed with status code: %d", resp.StatusCode)
+	}
+
+	// 读取响应
+	body, err := ioutil.ReadAll(resp.Body)
+	if err != nil {
+		return info, err
+	}
+
+	// 输出原始响应数据进行调试
+	fmt.Println("Raw Response:", string(body))
+
+	// 解析响应
+	var result DyVideoResponse
+	err = json.Unmarshal(body, &result)
+
+	if err != nil {
+		return result, err
+	}
+	// 检查API响应中的错误码
+	if result.ExtraData.ErrorCode != 0 {
+		return result, fmt.Errorf("API error: %d, description: %s", result.ExtraData.ErrorCode, result.ExtraData.Description)
+	}
+
+	return result, nil
+}
 
-//获取抖音总评论数
+//

+ 1 - 1
app/service/youngee_talent_service/talent_info.go

@@ -52,7 +52,7 @@ func GetTalentInfo(r *ghttp.Request) *TalentHttpResult {
 		return &TalentHttpResult{Code: -1, Msg: "Get talent info failed"}
 	}
 
-	talentInfo := youngee_talent_model.TalentInfo{}
+	talentInfo := youngee_talent_model.TalentInfo{} //结构体实例化
 	err = g.DB().Model("youngee_talent_info").WithAll().Where("id", tid).Scan(&talentInfo)
 
 	if err != nil {

+ 394 - 95
app/service/youngee_talent_service/talent_ks_auth.go

@@ -8,11 +8,13 @@ import (
 	"github.com/gogf/gf/net/ghttp"
 	"github.com/gogf/gf/os/gtime"
 	"github.com/gogf/gf/util/gconv"
+	douyinUser "github.com/lin-jim-leon/douyin/open/user"
 	"github.com/lin-jim-leon/kuaishou/open/merchant"
 	"github.com/lin-jim-leon/kuaishou/open/user"
 	"log"
 	"time"
 	"youngmini_server/app/model/youngee_talent_model"
+	"youngmini_server/app/service/youngee_sectask_service"
 	"youngmini_server/app/utils"
 )
 
@@ -37,7 +39,6 @@ func GetQrcode(r *ghttp.Request) *TalentHttpResult {
 	if err != nil {
 		return &TalentHttpResult{Code: -1, Msg: "Get talent id failed"}
 	}
-	println("here")
 	// 记录开始时间
 	startTime := time.Now()
 	// 创建一个新的上下文
@@ -48,9 +49,9 @@ func GetQrcode(r *ghttp.Request) *TalentHttpResult {
 	if typePlatform == 4 { //快手电商
 		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)
 	} else if typePlatform == 8 { //快手平台
-		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)
+		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)
 	} else if typePlatform == 2 { //抖音平台
-		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)
+		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)
 	} else {
 		urlstr = "unknow"
 	}
@@ -123,55 +124,340 @@ func CheckAccount(r *ghttp.Request) *TalentHttpResult {
 	return &TalentHttpResult{Code: 0, Msg: "success", Data: userInfo}
 }
 
-// 检查数据库表中是否有达人对应的数据,有就删掉,/kuaishouath中会插入。
-func CheckNewAccount(r *ghttp.Request) *TalentHttpResult {
+// / 抖音二维码绑定,轮询此接口,
+func CheckDyNewAccount(r *ghttp.Request) *TalentHttpResult {
 	//check到了更新时间在两秒内的插入的数据。则说明已绑定。弹窗消失。
-	//达人id获取
-	fmt.Println("***********into checknewaccount")
 	tid, err := utils.SessionTalentInfo.GetTalentIdFromSession(r)
+	redisDyBindStatusKey := fmt.Sprintf("DyBind:%s", tid)
+	bindStatus, err := g.Redis().DoVar("GET", redisDyBindStatusKey)
+	if bindStatus.String() == "bound_to_other" {
+		return &TalentHttpResult{Code: -1, Msg: "此账号已被其他达人绑定", Data: nil}
+	}
 	if err != nil {
 		return &TalentHttpResult{Code: -1, Msg: "Get talent id failed"}
 	}
 	// 获取当前时间
 	currentTime := gtime.Now()
-	// 查询数据库中是否有符合条件的数据
-	userInfo := &youngee_talent_model.KuaishouUserInfo{}
+	// 查询数据库中符合条件的所有记录
+	var userInfos []youngee_talent_model.KuaishouUserInfo
 	err = g.DB().Model("platform_kuaishou_user_info").
 		Where("talent_id = ?", tid).
-		Scan(&userInfo)
+		Scan(&userInfos)
 	if err != nil {
-		return &TalentHttpResult{Code: -2, Msg: "platform_kuaishou_user_info query failed"}
-	}
-	//找到数据,判断时间差
-	if userInfo != nil {
-		// 计算创建时间与当前时间的差值
-		timeDiff := currentTime.Sub(userInfo.CreateTime)
-		fmt.Println("***********kifasfa", timeDiff)
-		if timeDiff <= 3*time.Second {
-			return &TalentHttpResult{Code: 0, Msg: "success", Data: nil}
+		return &TalentHttpResult{Code: -4, Msg: "Database query failed"}
+	}
+
+	if len(userInfos) == 0 {
+		// 如果没有符合条件的数据,返回失败
+		return &TalentHttpResult{Code: -5, Msg: "No valid data found"}
+	}
+
+	// 找到 CreateTime 最新的记录
+	latestUserInfo := userInfos[0]
+	for _, info := range userInfos[1:] {
+		if info.CreateTime.After(latestUserInfo.CreateTime) {
+			latestUserInfo = info
 		}
 	}
-	// 如果没有符合条件的数据,返回失败
-	return &TalentHttpResult{Code: -20, Msg: "No valid data found", Data: nil}
+
+	// 计算创建时间与当前时间的差值
+	timeDiff := currentTime.Sub(latestUserInfo.CreateTime)
+	if timeDiff <= 3*time.Second {
+		return &TalentHttpResult{Code: 0, Msg: "success"}
+	}
+
+	// 超过时间差,返回失败
+	return &TalentHttpResult{Code: -6, Msg: "Time difference exceeds 3 seconds"}
 }
-func CheckTokenExp(r *ghttp.Request) *TalentHttpResult {
-	//达人id获取
+
+// 用于轮询,检查数据库表中是否有达人对应的数据,有就删掉,/kuaishouath中会插入。
+func CheckKsNewAccount(r *ghttp.Request) *TalentHttpResult {
+	//check到了更新时间在两秒内的插入的数据。则说明已绑定。弹窗消失。
 	tid, err := utils.SessionTalentInfo.GetTalentIdFromSession(r)
 	if err != nil {
 		return &TalentHttpResult{Code: -1, Msg: "Get talent id failed"}
 	}
-	key, err1 := g.DB().Model("platform_kuaishou_user_info").Fields("access_token").Where("talent_id = ?", tid).Value()
-	if err1 != nil {
-		return &TalentHttpResult{Code: -1, Msg: "query database fail"}
+	redisKsBindStatusKey := fmt.Sprintf("KsBind:%s", tid)
+	bindStatus, err := g.Redis().DoVar("GET", redisKsBindStatusKey)
+	if bindStatus.String() == "bound_to_other" {
+		return &TalentHttpResult{Code: -1, Msg: "此快手账号已被其他达人绑定", Data: nil}
 	}
-	AccessToken := key.String()
-	res_info, err2 := user.GetUserinfo(ClientKey, AccessToken)
-	if err2 != nil {
-		//前端接收code=-2表示token过期
-		return &TalentHttpResult{Code: -2, Msg: "accessToken过期", Data: nil}
+	if err != nil {
+		return &TalentHttpResult{Code: -1, Msg: "Get talent id failed"}
 	}
-	// 查询成功,返回成功结果和数据
-	return &TalentHttpResult{Code: 0, Msg: "success", Data: res_info}
+
+	// 获取当前时间
+	currentTime := gtime.Now()
+	// 查询数据库中符合条件的所有记录
+	var userInfos []youngee_talent_model.KuaishouUserInfo
+	err = g.DB().Model("platform_kuaishou_user_info").
+		Where("talent_id = ?", tid).
+		Scan(&userInfos)
+	if err != nil {
+		return &TalentHttpResult{Code: -4, Msg: "Database query failed"}
+	}
+
+	if len(userInfos) == 0 {
+		// 如果没有符合条件的数据,返回失败
+		return &TalentHttpResult{Code: -5, Msg: "No valid data found"}
+	}
+
+	// 找到 CreateTime 最新的记录
+	latestUserInfo := userInfos[0]
+	for _, info := range userInfos[1:] {
+		if info.CreateTime.After(latestUserInfo.CreateTime) {
+			latestUserInfo = info
+		}
+	}
+
+	// 计算创建时间与当前时间的差值
+	timeDiff := currentTime.Sub(latestUserInfo.CreateTime)
+	if timeDiff <= 3*time.Second {
+		return &TalentHttpResult{Code: 0, Msg: "success"}
+	}
+
+	// 超过时间差,返回失败
+	return &TalentHttpResult{Code: -6, Msg: "Time difference exceeds 3 seconds"}
+}
+
+func CheckTokenExp(openId string, platformId int, talentId string) int {
+	fmt.Println("into checktoken")
+	//检查平台8
+	if platformId == 8 {
+		key, err := g.DB().Model("platform_kuaishou_user_info").Fields("access_token").Where("talent_id = ? & platform_id = ? &  open_id = ? ", talentId, platformId, openId).Value()
+		if err != nil {
+			fmt.Println("query database fail")
+			return -1
+		}
+		AccessToken := key.String()
+		_, err = user.GetUserinfo(ClientKey1, AccessToken)
+		if err != nil { //过期
+			fmt.Println("平台accessToken过期")
+			//前端接收code=-2表示token过期
+			return 0
+		} else {
+			fmt.Println("平台AT未过期")
+			return 1
+		}
+		//检查电商授权4
+	} else {
+		key, err := g.DB().Model("platform_kuaishou_user_info").Fields("access_token").Where("talent_id = ? & platform_id = ? &  open_id = ? ", talentId, platformId, openId).Value()
+		if err != nil {
+			fmt.Println("query database fail")
+			return 2
+		}
+		AccessToken := key.String()
+		_, err = user.GetUserinfo(ClientKey, AccessToken)
+		if err != nil { //过期
+			//前端接收code=-2表示token过期
+			fmt.Println("电商accessToken过期")
+			return 3
+		} else {
+			fmt.Println("电商accessToken未过期")
+			return 4
+		}
+	}
+}
+
+//	func CheckTokenExp(r *ghttp.Request) *TalentHttpResult {
+//		//达人id获取
+//		tid, err := utils.SessionTalentInfo.GetTalentIdFromSession(r)
+//		//平台id获取
+//		platformId := r.GetInt("platform_id")
+//		//openId获取
+//		openId := r.GetString("open_id")
+//		//检查平台授权
+//		if platformId == 8 {
+//			key, err := g.DB().Model("platform_kuaishou_user_info").Fields("access_token").Where("talent_id = ? & platform_id = ? &  open_id = ? ", tid, platformId, openId).Value()
+//			if err != nil {
+//				return &TalentHttpResult{Code: -1, Msg: "query database fail"}
+//			}
+//			AccessToken := key.String()
+//			res_info1, err := user.GetUserinfo(ClientKey1, AccessToken)
+//			if err != nil { //过期
+//				//前端接收code=-2表示token过期
+//				return &TalentHttpResult{Code: -2, Msg: "平台accessToken过期", Data: nil}
+//			} else {
+//				return &TalentHttpResult{Code: 0, Msg: "平台accessToken未过期", Data: res_info1}
+//			}
+//			//检查电商授权
+//		} else {
+//			key, err := g.DB().Model("platform_kuaishou_user_info").Fields("access_token").Where("talent_id = ? & platform_id = ? &  open_id = ? ", tid, platformId, openId).Value()
+//			if err != nil {
+//				return &TalentHttpResult{Code: -1, Msg: "query database fail"}
+//			}
+//			AccessToken := key.String()
+//			res_info, err := user.GetUserinfo(ClientKey, AccessToken)
+//			if err != nil { //过期
+//				//前端接收code=-2表示token过期
+//				return &TalentHttpResult{Code: -2, Msg: "电商accessToken过期", Data: nil}
+//			} else {
+//				return &TalentHttpResult{Code: 0, Msg: "平台accessToken未过期", Data: res_info}
+//			}
+//		}
+//
+//		if err != nil {
+//			return &TalentHttpResult{Code: -3, Msg: "Get talent id failed"}
+//		}
+//		key, err1 := g.DB().Model("platform_kuaishou_user_info").Fields("access_token").Where("talent_id = ? & platform_id = ? &  open_id = ? ", tid, platformId, openId).Value()
+//		if err1 != nil {
+//			return &TalentHttpResult{Code: -1, Msg: "query database fail"}
+//		}
+//		AccessToken := key.String()
+//		res_info, err2 := user.GetUserinfo(ClientKey, AccessToken)
+//		if err2 != nil {
+//			//前端接收code=-2表示token过期
+//			return &TalentHttpResult{Code: -2, Msg: "accessToken过期", Data: nil}
+//		}
+//		// 查询成功,返回成功结果和数据
+//		return &TalentHttpResult{Code: 0, Msg: "success", Data: res_info}
+//	}
+func AddWindowKuaishouList(r *ghttp.Request) *TalentHttpResult {
+	// 定义用于存储查询结果的结构体切片
+	var results []*youngee_talent_model.KuaishouUserInfo
+
+	// 获取talent_id
+	tid, _ := utils.SessionTalentInfo.GetTalentIdFromSession(r)
+
+	// 查询此达人下,platform_id 为 8 或 4 的所有数据,并将结果扫描到结构体切片中
+	err := g.DB().Model(&youngee_talent_model.KuaishouUserInfo{}).
+		Where("talent_id = ?", tid).
+		Where("platform_id IN (?, ?)", 4, 8).
+		Order("open_id ASC, platform_id DESC"). // 按 open_id 排序,确保每组的数据连续,并且 platform_id=4 的数据排在前面
+		Scan(&results)
+	if err != nil {
+		return &TalentHttpResult{Code: 1, Msg: "查询失败", Data: nil}
+	}
+
+	// 创建一个 map,用于记录每个 open_id 对应的记录
+	//key是openid,value是数组,从而实现一对多
+	openIdMap := make(map[string][]*youngee_talent_model.KuaishouUserInfo)
+
+	// 将查询结果按 open_id 分组
+	for _, record := range results {
+		openIdMap[record.OpenId] = append(openIdMap[record.OpenId], record)
+	}
+
+	// 筛选出 open_id 对应两条数据且 platform_id = 4 的记录
+	var resInfo []*youngee_talent_model.KuaishouUserInfo
+	for _, records := range openIdMap {
+		if len(records) == 2 { // 确保有两条数据,排除只有一个 platform_id 的情况
+			for _, record := range records {
+				if record.PlatformId == 4 { // 选取 platform_id = 4(电商) 的记录,含有粉丝数就好,因为需要加入橱窗
+					resInfo = append(resInfo, record)
+					break
+				}
+			}
+		}
+	}
+	// 遍历 resInfo 检查过期和是否报名
+	for _, record := range resInfo {
+		// 调用 CheckKuaishouTokenExp 函数,检查 openId 是否过期
+		expired := CheckKuaishouTokenExp(record.OpenId)
+		// 将过期检查结果赋值给 expired 属性 ,过期则不能被选中用于加入橱窗
+		record.Expired = expired
+	}
+	return &TalentHttpResult{Code: 0, Msg: "加入橱窗成功", Data: resInfo}
+}
+
+func SignUpSecKuaishouList(r *ghttp.Request) *TalentHttpResult {
+	selectionId := r.GetString("selection_id")
+	// 定义用于存储查询结果的结构体切片
+	var results []*youngee_talent_model.KuaishouUserInfo
+
+	// 获取talent_id
+	tid, _ := utils.SessionTalentInfo.GetTalentIdFromSession(r)
+
+	// 查询此达人下,platform_id 为 8 或 4 的所有数据,并将结果扫描到结构体切片中
+	err := g.DB().Model(&youngee_talent_model.KuaishouUserInfo{}).
+		Where("talent_id = ?", tid).
+		Where("platform_id IN (?, ?)", 4, 8).
+		Order("open_id ASC, platform_id DESC"). // 按 open_id 排序,确保每组的数据连续,并且 platform_id=4 的数据排在前面
+		Scan(&results)
+	if err != nil {
+		return &TalentHttpResult{Code: 1, Msg: "查询失败", Data: nil}
+	}
+
+	// 创建一个 map,用于记录每个 open_id 对应的记录
+	//key是openid,value是数组,从而实现一对多
+	openIdMap := make(map[string][]*youngee_talent_model.KuaishouUserInfo)
+
+	// 将查询结果按 open_id 分组
+	for _, record := range results {
+		openIdMap[record.OpenId] = append(openIdMap[record.OpenId], record)
+	}
+
+	// 筛选出 open_id 对应两条数据且 platform_id = 4 的记录
+	var resInfo []*youngee_talent_model.KuaishouUserInfo
+	for _, records := range openIdMap {
+		if len(records) == 2 { // 确保有两条数据,排除只有一个 platform_id 的情况
+			for _, record := range records {
+				if record.PlatformId == 4 { // 选取 platform_id = 4(电商) 的记录,含有粉丝数就好,因为需要加入橱窗
+					resInfo = append(resInfo, record)
+					break
+				}
+			}
+		}
+	}
+	// 遍历 resInfo 检查过期和是否报名
+	for _, record := range resInfo {
+		// 调用 CheckKuaishouTokenExp 函数,检查 openId 是否过期
+		expired := CheckKuaishouTokenExp(record.OpenId)
+		// 将过期检查结果赋值给 expired 属性 ,过期则不能被选中用于加入橱窗
+		record.Expired = expired
+		//是否报名
+		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()
+		// 根据查询结果设置 IsSign 属性
+		if err != nil || isSignResult.IsEmpty() {
+			record.IsSign = 0 // 没有查到数据,设置为 0
+		} else {
+			record.IsSign = 1 // 查到数据,设置为 1
+		}
+
+	}
+	return &TalentHttpResult{Code: 0, Msg: "加入橱窗成功", Data: resInfo}
+}
+
+// 只有绑定两个快手,且快手电商没有过期,才能访问到这
+func AddWindowWithKsAccount(r *ghttp.Request) *TalentHttpResult {
+	// 获取talent_id
+	tid, _ := utils.SessionTalentInfo.GetTalentIdFromSession(r)
+	pId := r.GetString("product_id")
+	openId := r.GetString("open_id")
+	value, err := g.DB().Model("platform_kuaishou_user_info").Fields("open_id").Where("talent_id=? AND open_id = ?", tid, openId).Value()
+	if err != nil {
+		fmt.Println("query db fail")
+	}
+	accessToken := value.String()
+	//通过pId获取kuaishou_product_id
+	pIdSlice := []string{pId}
+	//如果此tId。此openId下已有此product的task则不
+	//res_info, err := merchant.AddItemsToShelf(ClientKey, SignSecret, accessToken, pIdSlice)
+	httpResult := youngee_sectask_service.IsCreateSecTask(r)
+	if httpResult.Code == 1 { //存在报名信息,仅添加橱窗
+		_, err := merchant.AddItemsToShelf(ClientKey, SignSecret, accessToken, pIdSlice)
+		if err != nil {
+			//表示添加失敗,沒有開通
+			return &TalentHttpResult{Code: -1, Msg: "快手未開通橱窗、商品不存在或已下线", Data: nil}
+		}
+		// 查询成功,返回成功结果和数据
+		return &TalentHttpResult{Code: 0, Msg: "无需创建任务,加入橱窗成功", Data: nil}
+	} else { //不存在报名信息
+		//创建并插入报名信息
+		code := youngee_sectask_service.SignUpSecTaskFromWindow(r).Code
+		if code != 0 {
+			fmt.Println("错误代码为----》", code)
+		}
+		//加入橱窗
+		_, err := merchant.AddItemsToShelf(ClientKey, SignSecret, accessToken, pIdSlice)
+		if err != nil {
+			//表示添加失敗,沒有開通
+			return &TalentHttpResult{Code: -1, Msg: "快手未開通橱窗、商品不存在或已下线", Data: nil}
+		}
+		// 查询成功,返回成功结果和数据
+		return &TalentHttpResult{Code: 0, Msg: "创建了任务,加入橱窗成功", Data: nil}
+	}
+
 }
 
 func AddWindow(r *ghttp.Request) *TalentHttpResult {
@@ -334,50 +620,6 @@ func QueryOkSaleNum(r *ghttp.Request) *TalentHttpResult {
 	return &TalentHttpResult{Code: 0, Msg: "获取30天销售量成功", Data: saleNum}
 }
 
-func DyLikeCount(r *ghttp.Request) *TalentHttpResult {
-	tid, _ := utils.SessionTalentInfo.GetTalentIdFromSession(r)
-	// 创建一个 KuaishouUserInfo 结构体的实例
-	userInfo := &youngee_talent_model.KuaishouUserInfo{}
-
-	// 查询数据库中的 access_token 字段
-	// 使用 g.DB() 获取数据库连接,并执行查询
-	key, err := g.DB().Model(userInfo).Fields("access_token").Where("talent_id = ? AND platform_id = ?", tid, 2).Value()
-	AccessToken := key.String()
-	if err != nil {
-		// 处理错误
-		fmt.Println("Error querying access_token:", err)
-	}
-	if key == nil {
-		// 处理错误
-		fmt.Println("can not find talentId's bindinfo :", err)
-	}
-	//todo : API
-	count, err := GetLikeCount(ClientKey1, AccessToken)
-	return &TalentHttpResult{Code: 0, Msg: "获取总点赞数成功", Data: count}
-}
-
-func DyVideoCount(r *ghttp.Request) *TalentHttpResult {
-	tid, _ := utils.SessionTalentInfo.GetTalentIdFromSession(r)
-	// 创建一个 KuaishouUserInfo 结构体的实例
-	userInfo := &youngee_talent_model.KuaishouUserInfo{}
-
-	// 查询数据库中的 access_token 字段
-	// 使用 g.DB() 获取数据库连接,并执行查询
-	key, err := g.DB().Model(userInfo).Fields("access_token").Where("talent_id = ? AND platform_id = ?", tid, 2).Value()
-	AccessToken := key.String()
-	if err != nil {
-		// 处理错误
-		fmt.Println("Error querying access_token:", err)
-	}
-	if key == nil {
-		// 处理错误
-		fmt.Println("can not find talentId's bindinfo :", err)
-	}
-	//todo : API
-	count, err := GetLikeCount(ClientKey1, AccessToken)
-	return &TalentHttpResult{Code: 0, Msg: "获取总点赞数成功", Data: count}
-}
-
 func VideoCount(r *ghttp.Request) *TalentHttpResult {
 	tid, _ := utils.SessionTalentInfo.GetTalentIdFromSession(r)
 	// 创建一个 KuaishouUserInfo 结构体的实例
@@ -511,28 +753,85 @@ func GetKuaishouList(r *ghttp.Request) *TalentHttpResult {
 	return &TalentHttpResult{Code: 1, Msg: "返回快手列表成功", Data: ksListResult}
 }
 
-// 获取用户快手平台账号列表
-func GetKuaishouListWithCondition(r *ghttp.Request) *TalentHttpResult {
-	// 从 session 中获取 talent_id
-	tid, _ := utils.SessionTalentInfo.GetTalentIdFromSession(r)
-	userInfo := &youngee_talent_model.KuaishouUserInfo{}
-	//1.获取该tid下的所有账户信息
-
-	//2.openid去重,遍历userInfoMap<openid,userInfo>openid对应了两个accesstokn就都去验证是否过期
+// 获取用户快手电商过期信息 肯定绑定两个码,因为只是用于加入橱窗---我只检查电商是否过期
+func CheckKuaishouTokenExp(openId string) int {
+	fmt.Println("into checktoken")
+	//一个openId同时对应了8和4,才进行过期检查,两个都检查,有一个过期则过期
+	key, err := g.DB().Model("platform_kuaishou_user_info").Fields("access_token").Where("open_id = ? ", openId).Value()
+	if err != nil {
+		fmt.Println("query database fail")
+		return -1
+	}
+	AccessToken := key.String()
+	_, err = douyinUser.GetUserInfo(openId, AccessToken)
+	if err != nil { //过期
+		fmt.Println("平台accessToken过期")
+		return 1
+	} else {
+		fmt.Println("未过期")
+		return 0
+	}
+}
 
-	//3.openId对应的accessToken调用是否过期接口,过期则use_code=1
+func CheckDouyinTokenExp(openId string) int {
+	fmt.Println("into checktoken")
+	key, err := g.DB().Model("platform_kuaishou_user_info").Fields("access_token").Where("open_id = ? ", openId).Value()
+	if err != nil {
+		fmt.Println("query database fail")
+		return -1
+	}
+	AccessToken := key.String()
+	_, err = douyinUser.GetUserInfo(openId, AccessToken)
+	if err != nil { //过期
+		fmt.Println("平台accessToken过期")
+		return 1
+	} else {
+		fmt.Println("未过期")
+		return 0
+	}
+}
 
-	//4.调用是否已领取接口 ,领取则use_code=2
+func GetDouyinList(r *ghttp.Request) *TalentHttpResult {
+	// 获取达人对应的平台为2的列表,含基本信息
+	tid, _ := utils.SessionTalentInfo.GetTalentIdFromSession(r)
+	userInfo := &youngee_talent_model.KuaishouUserInfo{}
+	results, err := g.DB().Model(userInfo).Where("talent_id = ?", tid).
+		Where("platform_Id IN (?)", 2).
+		All()
+	if err != nil {
+		fmt.Println("Error querying ", err)
+		return &TalentHttpResult{Code: 0, Msg: "查询抖音列表失败", Data: nil}
+	}
 
-	//5.领样条件(粉丝数+橱窗销量)不满足  use_code=3
+	// 创建一个存储用户信息的切片
+	updatedUserInfoList := []*youngee_talent_model.KuaishouUserInfo{}
 
-	// 创建 KSListResult 变量并赋值
-	ksListResult := &youngee_talent_model.KSListResult{
-		Count:    uniqueOpenIDCount,
-		UserInfo: userInfoList,
-	}
-	// 返回结果
-	return &TalentHttpResult{Code: 1, Msg: "返回快手列表成功", Data: ksListResult}
+	// 遍历列表,判断是否过期并更新 Expired 属性
+	for _, record := range results.List() {
+		openID := gconv.String(record["open_id"])
+		// 调用 CheckDouyinTokenExp 函数,获取过期状态 0/1
+		expiredStatus := CheckDouyinTokenExp(openID)
+
+		// 更新 record 中的 Expired 字段值
+		record["Expired"] = expiredStatus
+		err := gconv.Struct(record, userInfo)
+		if err != nil {
+			return nil
+		} // 将 map 转换为 KuaishouUserInfo 结构体
+
+		// 添加到用户信息列表
+		updatedUserInfoList = append(updatedUserInfoList, userInfo)
+
+		// 如果需要将更新后的 record 保存到数据库中,请取消注释以下代码
+		// if _, err := g.DB().Model(userInfo).Where("open_id = ?", openID).Data(record).Update(); err != nil {
+		//     fmt.Println("Error updating Expired status: ", err)
+		// }
+	}
+	// 返回 DYListResult 类型
+	return &TalentHttpResult{Code: 1, Msg: "返回抖音列表成功", Data: &youngee_talent_model.DYListResult{
+		Count:    len(updatedUserInfoList),
+		UserInfo: updatedUserInfoList,
+	}}
 }
 
 func QuerySalesFor90Days(r *ghttp.Request) *TalentHttpResult {

+ 41 - 3
app/service/youngee_task_service/task_data.go

@@ -178,7 +178,7 @@ func ProjectCollection(r *ghttp.Request) *TalentHttpResult {
 			TalentId:   tId,
 			ProjectId:  pId,
 			CreateTime: gtime.Now(),
-			Delete:     0,
+			Deleted:    0,
 		}
 
 		_, err = g.DB().Model("younggee_project_collect_info").Data(collectionInfo).Insert()
@@ -186,12 +186,50 @@ func ProjectCollection(r *ghttp.Request) *TalentHttpResult {
 	} else {
 		// 如果记录存在,更新 Delete 字段的值 和 收藏时间
 		fmt.Println("*******", record)
-		currentDeleteValue := gconv.Int(record["delete"])
+		currentDeleteValue := gconv.Int(record["deleted"])
 		newDeleteValue := 1 - currentDeleteValue // 0 改成 1,1 改成 0
 		_, err = g.DB().Model("younggee_project_collect_info").
 			Where("talent_id = ? and project_id = ?", tId, pId).
 			Data(g.Map{
-				"delete":      newDeleteValue,
+				"deleted":     newDeleteValue,
+				"create_time": gtime.Now(),
+			}).Update()
+		if err != nil {
+			return &TalentHttpResult{Code: -2, Msg: err.Error()}
+		}
+	}
+	return &TalentHttpResult{Code: 0, Msg: "collection success"}
+}
+
+// 收藏带货项目
+func SelectionCollection(r *ghttp.Request) *TalentHttpResult {
+	tId, _ := utils.SessionTalentInfo.GetTalentIdFromSession(r)
+	selectionId := r.GetQueryString("selection_id")
+	productionId := r.GetQueryString("production_id")
+	record, err := g.DB().Model("younggee_selection_collect_info").Where("talent_id = ? and selection_id = ?", tId, selectionId).One()
+	if err != nil {
+		return &TalentHttpResult{Code: -1, Msg: err.Error()}
+	}
+	if record == nil {
+		collectionInfo := youngee_talent_model.SelectionCollection{
+			TalentId:    tId,
+			SelectionId: selectionId,
+			ProductId:   productionId,
+			CreateTime:  gtime.Now(),
+			Deleted:     0,
+		}
+
+		_, err = g.DB().Model("younggee_selection_collect_info").Data(collectionInfo).Insert()
+
+	} else {
+		// 如果记录存在,更新 Delete 字段的值 和 收藏时间
+		fmt.Println("*******", record)
+		currentDeleteValue := gconv.Int(record["deleted"])
+		newDeleteValue := 1 - currentDeleteValue // 0 改成 1,1 改成 0
+		_, err = g.DB().Model("younggee_selection_collect_info").
+			Where("talent_id = ? and selection_id = ?", tId, selectionId).
+			Data(g.Map{
+				"deleted":     newDeleteValue,
 				"create_time": gtime.Now(),
 			}).Update()
 		if err != nil {

+ 38 - 35
app/system/assignment/assignment_model.go

@@ -1,35 +1,38 @@
-package assignment
-
-import "github.com/gogf/gf/os/gtime"
-
-type AddAssignmentReq struct {
-	TaskId        string      `json:"task_id"`         // 任务id
-	LinkUrl       string      `json:"link_url"`        // 作业连接
-	PhotoUrl      string      `json:"photo_url"`       // 作业截图
-	ReviseOpinion string      `json:"revise_opinion"`  // 审核意见
-	IsSubmit      int         `json:"is_submit" d:"1"` // 是否提交
-	IsReview      int         `json:"is_review" d:"0"` // 是否审核
-	IsOk          int         `json:"is_ok" d:"0"`     // 是否合格
-	CreateAt      *gtime.Time `json:"create_at"`       // 创建时间
-	SubmitAt      *gtime.Time `json:"submit_at"`       // 提交时间
-	AgreeAt       *gtime.Time `json:"agree_at" d:""`   // 同意时间
-	RejectAt      *gtime.Time `json:"reject_at" d:""`  // 驳回时间
-}
-
-type ListAssignmentRes struct {
-	AssignmentList []*ListAssignmentSql `json:"assignment_list"`
-}
-
-type ListAssignmentSql struct {
-	TaskId        string      `json:"task_id"`        // 任务id
-	LinkUrl       string      `json:"link_url"`       // 作业连接
-	PhotoUrl      string      `json:"photo_url"`      // 作业截图
-	ReviseOpinion string      `json:"revise_opinion"` // 审核意见
-	IsSubmit      int         `json:"is_submit"`      // 是否提交
-	IsReview      int         `json:"is_review"`      // 是否审核
-	IsOk          int         `json:"is_ok"`          // 是否合格
-	CreateAt      *gtime.Time `json:"create_at"`      // 创建时间
-	SubmitAt      *gtime.Time `json:"submit_at"`      // 提交时间
-	AgreeAt       *gtime.Time `json:"agree_at"`       // 同意时间
-	RejectAt      *gtime.Time `json:"reject_at"`      // 驳回时间
-}
+package assignment
+
+import "github.com/gogf/gf/os/gtime"
+
+type AddAssignmentReq struct {
+	TaskId        string      `json:"task_id"`         // 任务id
+	EnterpriseId  string      `json:"enterprise_id"`   //商家id
+	SelectionId   string      `json:"selection_id"`    //选品id
+	PayMoney      int         `json:"pay_money"`       // 悬赏结算金额
+	LinkUrl       string      `json:"link_url"`        // 作业连接
+	PhotoUrl      string      `json:"photo_url"`       // 作业截图
+	ReviseOpinion string      `json:"revise_opinion"`  // 审核意见
+	IsSubmit      int         `json:"is_submit" d:"1"` // 是否提交
+	IsReview      int         `json:"is_review" d:"0"` // 是否审核
+	IsOk          int         `json:"is_ok" d:"0"`     // 是否合格
+	CreateAt      *gtime.Time `json:"create_at"`       // 创建时间
+	SubmitAt      *gtime.Time `json:"submit_at"`       // 提交时间
+	AgreeAt       *gtime.Time `json:"agree_at" d:""`   // 同意时间
+	RejectAt      *gtime.Time `json:"reject_at" d:""`  // 驳回时间
+}
+
+type ListAssignmentRes struct {
+	AssignmentList []*ListAssignmentSql `json:"assignment_list"`
+}
+
+type ListAssignmentSql struct {
+	TaskId        string      `json:"task_id"`        // 任务id
+	LinkUrl       string      `json:"link_url"`       // 作业连接
+	PhotoUrl      string      `json:"photo_url"`      // 作业截图
+	ReviseOpinion string      `json:"revise_opinion"` // 审核意见
+	IsSubmit      int         `json:"is_submit"`      // 是否提交
+	IsReview      int         `json:"is_review"`      // 是否审核
+	IsOk          int         `json:"is_ok"`          // 是否合格
+	CreateAt      *gtime.Time `json:"create_at"`      // 创建时间
+	SubmitAt      *gtime.Time `json:"submit_at"`      // 提交时间
+	AgreeAt       *gtime.Time `json:"agree_at"`       // 同意时间
+	RejectAt      *gtime.Time `json:"reject_at"`      // 驳回时间
+}

+ 39 - 0
app/system/assignment/assignment_service.go

@@ -2,6 +2,7 @@ package assignment
 
 import (
 	"database/sql"
+	"fmt"
 	"github.com/gogf/gf/frame/g"
 	"github.com/gogf/gf/net/ghttp"
 	"github.com/gogf/gf/os/gtime"
@@ -24,6 +25,7 @@ func (s *assignmentService) Add(r *ghttp.Request, req *AddAssignmentReq) (res sq
 	if err != nil {
 		return nil, err
 	}
+
 	res, err = dao.YounggeeAssignmentInfo.Ctx(r.GetCtx()).Insert(req)
 	if err != nil {
 		return nil, err
@@ -36,6 +38,7 @@ func (s *assignmentService) Add(r *ghttp.Request, req *AddAssignmentReq) (res sq
 		AssignmentStatus: 2, //作业上传状态变成2(已添加)
 		RewardStage:      1, //上传截图,变成待领悬赏
 	}
+	//更新任务表中的状态
 	SecTaskInfo := &youngee_talent_model.SecTaskInfoDetail{}
 	_, err = g.DB().Model(SecTaskInfo).Data(g.Map{
 		"task_stage":        updateStageReq.TaskStage,
@@ -77,6 +80,42 @@ func (s *assignmentService) Add(r *ghttp.Request, req *AddAssignmentReq) (res sq
 	if err != nil {
 		return nil, err
 	}
+
+	//悬赏结算
+	//1.检查余额是否足够
+	remainMoney, err := g.DB().Model("enterprise").Fields("available_balance").Where("enterprise_id = ?", req).Value()
+	if err != nil {
+		fmt.Println("database")
+	}
+	remain := remainMoney.Int()
+	if remain < req.PayMoney {
+		fmt.Println("余额不足")
+		return nil, err
+	}
+	fmt.Println("余额充足")
+	_, err = g.DB().Model("enterprise").Data(g.Map{"available_balance": remain - req.PayMoney}).Where("enterprise_id = ?", req.EnterpriseId).Update()
+	//2.更新selection的settelamout
+	oldvalue, err := g.DB().Model("younggee_selection_info").Fields("settlement_amount").Where("selection_id=?", req.SelectionId).Value()
+	oldvalue1 := oldvalue.Int()
+	_, err = g.DB().Model("younggee_selection_info").Data(g.Map{"settlement_amount": oldvalue1 + req.PayMoney}).Where("selection_id=?", req.SelectionId).Update()
+	//3.更新sectask表中的任务状态
+	_, err = g.DB().Model("younggee_sec_task_info").Data(g.Map{
+		"updated_at":     gtime.Now(),
+		"completed_data": gtime.Now(),
+		"task_stage":     10,
+		"reward_stage":   2, //已结算
+	}).Where("task_id=?", req.TaskId).Update()
+	//4.插入一条达人收入数据
+	_, err = g.DB().Model("younggee_talent_income").Data(g.Map{
+		"selection_id": req.SelectionId,
+		"talent_id":    tid,
+		"sectask_id":   req.TaskId,
+		"income":       req.PayMoney,
+		"income_at":    gtime.Now(),
+	}).Save()
+	if err != nil {
+		return nil, err
+	}
 	return
 }
 

二进制
bin/main


+ 1 - 0
config/config.toml

@@ -30,6 +30,7 @@ Level = "all"
 Path = "/tmp/log/gf-app"
 Stdout = true
 
+
 # Template.
 [viewer]
 DefaultFile = "index.html"

+ 0 - 1
main.go

@@ -23,6 +23,5 @@ func main() {
 	//fmt.Printf("resp=%+v\n", resp)
 	//var resp = service.ShowLogisticsDetail("2508915060")
 	//fmt.Printf("resp=%+v\n", resp)
-
 	g.Server().Run()
 }

二进制
public/swagger/favicon-16x16.png


二进制
public/swagger/favicon-32x32.png


+ 16 - 0
public/swagger/index.css

@@ -0,0 +1,16 @@
+html {
+    box-sizing: border-box;
+    overflow: -moz-scrollbars-vertical;
+    overflow-y: scroll;
+}
+
+*,
+*:before,
+*:after {
+    box-sizing: inherit;
+}
+
+body {
+    margin: 0;
+    background: #fafafa;
+}

+ 19 - 0
public/swagger/index.html

@@ -0,0 +1,19 @@
+<!-- HTML for static distribution bundle build -->
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="UTF-8">
+    <title>Swagger UI</title>
+    <link rel="stylesheet" type="text/css" href="./swagger-ui.css" />
+    <link rel="stylesheet" type="text/css" href="index.css" />
+    <link rel="icon" type="image/png" href="./favicon-32x32.png" sizes="32x32" />
+    <link rel="icon" type="image/png" href="./favicon-16x16.png" sizes="16x16" />
+  </head>
+
+  <body>
+    <div id="swagger-ui"></div>
+    <script src="./swagger-ui-bundle.js" charset="UTF-8"> </script>
+    <script src="./swagger-ui-standalone-preset.js" charset="UTF-8"> </script>
+    <script src="./swagger-initializer.js" charset="UTF-8"> </script>
+  </body>
+</html>

+ 79 - 0
public/swagger/oauth2-redirect.html

@@ -0,0 +1,79 @@
+<!doctype html>
+<html lang="en-US">
+<head>
+    <title>Swagger UI: OAuth2 Redirect</title>
+</head>
+<body>
+<script>
+    'use strict';
+    function run () {
+        var oauth2 = window.opener.swaggerUIRedirectOauth2;
+        var sentState = oauth2.state;
+        var redirectUrl = oauth2.redirectUrl;
+        var isValid, qp, arr;
+
+        if (/code|token|error/.test(window.location.hash)) {
+            qp = window.location.hash.substring(1).replace('?', '&');
+        } else {
+            qp = location.search.substring(1);
+        }
+
+        arr = qp.split("&");
+        arr.forEach(function (v,i,_arr) { _arr[i] = '"' + v.replace('=', '":"') + '"';});
+        qp = qp ? JSON.parse('{' + arr.join() + '}',
+                function (key, value) {
+                    return key === "" ? value : decodeURIComponent(value);
+                }
+        ) : {};
+
+        isValid = qp.state === sentState;
+
+        if ((
+          oauth2.auth.schema.get("flow") === "accessCode" ||
+          oauth2.auth.schema.get("flow") === "authorizationCode" ||
+          oauth2.auth.schema.get("flow") === "authorization_code"
+        ) && !oauth2.auth.code) {
+            if (!isValid) {
+                oauth2.errCb({
+                    authId: oauth2.auth.name,
+                    source: "auth",
+                    level: "warning",
+                    message: "Authorization may be unsafe, passed state was changed in server. The passed state wasn't returned from auth server."
+                });
+            }
+
+            if (qp.code) {
+                delete oauth2.state;
+                oauth2.auth.code = qp.code;
+                oauth2.callback({auth: oauth2.auth, redirectUrl: redirectUrl});
+            } else {
+                let oauthErrorMsg;
+                if (qp.error) {
+                    oauthErrorMsg = "["+qp.error+"]: " +
+                        (qp.error_description ? qp.error_description+ ". " : "no accessCode received from the server. ") +
+                        (qp.error_uri ? "More info: "+qp.error_uri : "");
+                }
+
+                oauth2.errCb({
+                    authId: oauth2.auth.name,
+                    source: "auth",
+                    level: "error",
+                    message: oauthErrorMsg || "[Authorization failed]: no accessCode received from the server."
+                });
+            }
+        } else {
+            oauth2.callback({auth: oauth2.auth, token: qp, isValid: isValid, redirectUrl: redirectUrl});
+        }
+        window.close();
+    }
+
+    if (document.readyState !== 'loading') {
+        run();
+    } else {
+        document.addEventListener('DOMContentLoaded', function () {
+            run();
+        });
+    }
+</script>
+</body>
+</html>

+ 21 - 0
public/swagger/swagger-initializer.js

@@ -0,0 +1,21 @@
+window.onload = function() {
+  //<editor-fold desc="Changeable Configuration Block">
+
+  // the following lines will be replaced by docker/configurator, when it runs in a docker-container
+  window.ui = SwaggerUIBundle({
+    // url: "https://petstore.swagger.io/v2/swagger.json",
+    url: "http://localhost:8201/swagger/swagger.json",
+    dom_id: '#swagger-ui',
+    deepLinking: true,
+    presets: [
+      SwaggerUIBundle.presets.apis,
+      SwaggerUIStandalonePreset
+    ],
+    plugins: [
+      SwaggerUIBundle.plugins.DownloadUrl
+    ],
+    layout: "StandaloneLayout"
+  });
+
+  //</editor-fold>
+};

文件差异内容过多而无法显示
+ 1 - 0
public/swagger/swagger-ui-bundle.js


文件差异内容过多而无法显示
+ 0 - 0
public/swagger/swagger-ui-bundle.js.map


文件差异内容过多而无法显示
+ 1 - 0
public/swagger/swagger-ui-es-bundle-core.js


文件差异内容过多而无法显示
+ 0 - 0
public/swagger/swagger-ui-es-bundle-core.js.map


文件差异内容过多而无法显示
+ 1 - 0
public/swagger/swagger-ui-es-bundle.js


文件差异内容过多而无法显示
+ 0 - 0
public/swagger/swagger-ui-es-bundle.js.map


文件差异内容过多而无法显示
+ 1 - 0
public/swagger/swagger-ui-standalone-preset.js


文件差异内容过多而无法显示
+ 0 - 0
public/swagger/swagger-ui-standalone-preset.js.map


文件差异内容过多而无法显示
+ 0 - 0
public/swagger/swagger-ui.css


文件差异内容过多而无法显示
+ 0 - 0
public/swagger/swagger-ui.css.map


文件差异内容过多而无法显示
+ 0 - 0
public/swagger/swagger-ui.js


文件差异内容过多而无法显示
+ 0 - 0
public/swagger/swagger-ui.js.map


+ 24 - 0
public/swagger/swagger.json

@@ -0,0 +1,24 @@
+{
+    "swagger": "2.0",
+    "info": {
+        "contact": {}
+    },
+    "paths": {
+        "/youngee/c/p/sms-login": {
+            "post": {
+                "description": "通过验证码登录",
+                "consumes": [
+                    "application/json"
+                ],
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "用户模块"
+                ],
+                "summary": "用户登录",
+                "responses": {}
+            }
+        }
+    }
+}

+ 113 - 12
router/router.go

@@ -15,6 +15,7 @@ import (
 	"strconv"
 	youngeetalentapi "youngmini_server/app/api/youngee_talent_api"
 	"youngmini_server/app/model/youngee_talent_model"
+	"youngmini_server/app/service/youngee_talent_service"
 	"youngmini_server/app/system/assignment"
 	"youngmini_server/app/system/sectask"
 	"youngmini_server/app/system/wxpay"
@@ -85,6 +86,10 @@ func init() {
 	// v2小程序端接口
 	s.Group("/youngee/c", func(group *ghttp.RouterGroup) {
 		group.Middleware(middleware.ErrorHandler)
+		//用于接口测试
+		s.BindHandler("/apitest", func(r *ghttp.Request) {
+			r.Response.WriteJson("成功访问服务端")
+		})
 		//用于快手电商:nignx转发含code的请求到此处
 		s.BindHandler("/kuaishouauth", func(r *ghttp.Request) {
 			fmt.Println("****进入rounter中的/kuaishouauth*******")
@@ -93,10 +98,64 @@ func init() {
 			//SignSecret := "bf6393dce0a2b669ee348bebb837b0da"
 			code := r.GetString("code")
 			state := r.GetString("state")
-			//获取accesstoken
+			//来自管理后台的用户,state是手机号码
+			if len(state) == 11 {
+				record, err := g.DB().Model("youngee_m_kuaishou_userinfo").Where("phone_num = ? ", state).One()
+				if record.IsEmpty() {
+					fmt.Println("未找到符合条件的记录")
+					return
+				}
+				if err != nil {
+					fmt.Println("查询youngee_m_kuaishou_userinfo表出错")
+				}
+				//发起请求,将数据存在record中
+				m_res_auth, _ := oauth.GetAccessToken(ClientKey, ClientSecret, code)
+				AccessToken := m_res_auth.AccessToken
+				//获取基本信息
+				m_res_info, _ := user.GetUserinfo(ClientKey, AccessToken)
+
+				//将值update到表中
+				// 将值更新到表中的记录中
+				_, err = g.DB().Model("youngee_m_kuaishou_userinfo").
+					Where("phone_number = ?", state).
+					Data(g.Map{
+						"access_token": AccessToken,
+						// 假设 m_res_info 中有 fields 例如 nickname 和 avatar
+						"nickname":      m_res_info.Data.Name,
+						"code":          code,
+						"refresh_token": m_res_auth.RefreshToken,
+						"open_id":       m_res_auth.OpenId,
+						"create_time":   gtime.Now(),
+						"update_time":   gtime.Now(),
+						"expired":       0, //是否到期   1.后台两个小时刷新一次  2.获取list的时候需要将这个字段更新到数据中
+						"is_delete":     0,
+					}).
+					Update()
+			}
+			//来自达人授权,获取accesstoken
 			res_auth, _ := oauth.GetAccessToken(ClientKey, ClientSecret, code)
+
+			//防止一个快手账号重复绑定
+			userInfo := youngee_talent_model.KuaishouUserInfo{}
+			//这个openid存在(如果对应到两条数据,只保留一条) 且对应的达人不是我,
+			err := g.DB().Model("platform_kuaishou_user_info").Where("open_id = ? ", res_auth.OpenId).Order("platform_id DESC").Scan(&userInfo)
+			if err != nil {
+				fmt.Println("查询数据库失败")
+			}
+			//快手电商账号重复绑定,提示前端
+			//此openId在表中有对应数据,且对应的达人不是当前达人,
+			if userInfo.TalentId != "" && userInfo.TalentId != state {
+				redisKsBindStatusKey := fmt.Sprintf("KsBind:%s", state)
+				//redis设置绑定状态为
+				_, err := g.Redis().Do("SETEX", 10, redisKsBindStatusKey, "bound_to_other")
+				if err != nil {
+					fmt.Println("redis出错")
+				}
+				return
+			}
+
 			//如果该快手账号(openID)已经有数据了,更新数据。没有数据则插入数据。
-			_, err := g.DB().Model("platform_kuaishou_user_info").
+			_, err = g.DB().Model("platform_kuaishou_user_info").
 				Where("open_id = ? AND platform_id = ?", res_auth.OpenId, 4).
 				Delete()
 			if err != nil {
@@ -127,7 +186,7 @@ func init() {
 				TalentId:     state,
 				AccessToken:  AccessToken,
 				OpenId:       res_auth.OpenId,
-				PlatformId:   4, //快手平台
+				PlatformId:   4, //快手电商
 				RefreshToken: res_auth.RefreshToken,
 				HeadUri:      res_info.Data.Head,
 				NickName:     res_info.Data.Name,
@@ -142,7 +201,6 @@ func init() {
 				return
 			}
 		})
-
 		//用于快手平台:nignx转发含code的请求到此处
 		s.BindHandler("/kuaishouVideo", func(r *ghttp.Request) {
 			fmt.Println("****进入rounter中的/kuaishouVideo*******")
@@ -154,8 +212,26 @@ func init() {
 
 			//获取accesstoken
 			res_auth, _ := oauth.GetAccessToken(ClientKey, ClientSecret, code)
+
+			userInfo := youngee_talent_model.KuaishouUserInfo{}
+			//这个openid存在 且对应的达人不是我
+			err := g.DB().Model("platform_kuaishou_user_info").Where("open_id = ? ", userInfo.OpenId).Scan(&userInfo)
+			if err != nil {
+				fmt.Println("查询数据库失败")
+			}
+			//抖音账号重复绑定,提示前端
+			//此openId在表中有对应数据,且对应的达人不是当前达人,
+			if userInfo.TalentId != "" && userInfo.TalentId != state {
+				redisKsBindStatusKey := fmt.Sprintf("KsBind:%s", state)
+				//redis设置绑定状态为
+				_, err := g.Redis().Do("SETEX", 10, redisKsBindStatusKey, "bound_to_other")
+				if err != nil {
+					fmt.Println("redis出错")
+				}
+				return
+			}
 			//如果该快手账号(openID)已经有数据了,删除。模拟在快手刷新授权 没有数据则空操作
-			_, err := g.DB().Model("platform_kuaishou_user_info").
+			_, err = g.DB().Model("platform_kuaishou_user_info").
 				Where("open_id = ? AND platform_id = ?", res_auth.OpenId, 8).
 				Delete()
 			if err != nil {
@@ -164,7 +240,9 @@ func init() {
 			AccessToken := res_auth.AccessToken
 			//获取基本信息
 			res_info, _ := user.GetUserinfo(ClientKey, AccessToken)
-			//视频数据不在扫码时获取。
+			//视频数据
+			videoCount, err := youngee_talent_service.GetVideoCount(ClientKey, AccessToken)
+			likeCount, err := youngee_talent_service.GetLikeCount(ClientKey, AccessToken)
 			//用户进入主页获取,并存入数据库中
 			err_auth := r.Response.WriteJson(res_auth)
 			err_info := r.Response.WriteJson(res_info)
@@ -191,6 +269,8 @@ func init() {
 				HeadUri:      res_info.Data.Head,
 				NickName:     res_info.Data.Name,
 				Fan:          res_info.Data.Fan,
+				LikeNum:      likeCount,              //点赞数
+				VideoNum:     videoCount.PublicCount, //作品数目
 				UpdateTime:   gtime.Now(),
 				CreateTime:   gtime.Now(),
 			}
@@ -210,10 +290,26 @@ func init() {
 			//获取accesstoken
 			res_auth, _ := douyinOauth.GetAccessToken(ClientKey, ClientSecret, code)
 			douyinOpenId := res_auth.Data.OpenId
-
-			//如果该快手账号(openID)已经有数据了,删除。模拟在快手刷新授权 没有数据则空操作
-			_, err := g.DB().Model("platform_kuaishou_user_info").
-				Where("open_id = ? AND platform_id = ?", douyinOpenId, 2).
+			userInfo := youngee_talent_model.KuaishouUserInfo{}
+			//这个openid存在 且对应的达人不是我,
+			err := g.DB().Model("platform_kuaishou_user_info").Where("open_id = ? ", douyinOpenId).Scan(&userInfo)
+			if err != nil {
+				fmt.Println("查询数据库失败")
+			}
+			//抖音账号重复绑定,提示前端
+			//此openId在表中有对应数据,且对应的达人不是当前达人,
+			if userInfo.TalentId != "" && userInfo.TalentId != state {
+				redisDyBindStatusKey := fmt.Sprintf("DyBind:%s", state)
+				//redis设置绑定状态为  10s过期
+				_, err := g.Redis().Do("SETEX", 10, redisDyBindStatusKey, "bound_to_other")
+				if err != nil {
+					fmt.Println("redis出错")
+				}
+				return
+			}
+			//如果达人已经有抖音数据了,删除。模拟在抖音刷新授权 没有数据则空操作
+			_, err = g.DB().Model("platform_kuaishou_user_info").
+				Where("open_id = ? AND platform_id = ?  AND  talent_id = ?", douyinOpenId, 2, state).
 				Delete()
 			if err != nil {
 				r.Response.WriteJson("抖音账号覆盖失败")
@@ -221,7 +317,7 @@ func init() {
 			AccessToken := res_auth.Data.AccessToken
 			//获取基本信息
 			res_info, _ := douyinUser.GetUserInfo(res_auth.Data.OpenId, AccessToken)
-			//获取用户粉丝数
+			//获取用户粉丝数  千粉以上
 			res_fans, _ := douyinUser.GetUserFans(AccessToken, "7", douyinOpenId) //近7天,返回一个列表每天都有总粉丝数
 			errCode := res_fans.Data.ErrorCode
 			var fansNumStr string
@@ -235,7 +331,8 @@ func init() {
 				fmt.Println("Error converting string to int:", err)
 				// 可以在这里添加错误处理逻辑
 			}
-			//视频数据不在扫码时获取。
+			//获取抖音作品数目和点赞数目
+			VideoInfo, _ := youngee_talent_service.GetDyVideoInfo(douyinOpenId, AccessToken)
 			//用户进入主页获取,并存入数据库中
 			err_auth := r.Response.WriteJson(res_auth)
 			err_info := r.Response.WriteJson(res_info)
@@ -262,9 +359,12 @@ func init() {
 				HeadUri:      res_info.Data.Avatar,
 				NickName:     res_info.Data.Nickname,
 				Fan:          fansNum, //专门获取粉丝数的接口,默认为0。
+				VideoNum:     VideoInfo.VideoCount,
+				LikeNum:      VideoInfo.LikeCount,
 				UpdateTime:   gtime.Now(),
 				CreateTime:   gtime.Now(),
 			}
+			//sava,有数据则更新,没有数据则插入
 			if _, err := g.DB().Model("platform_kuaishou_user_info").Save(authInfo); err != nil {
 				r.Response.WriteJson(g.Map{
 					"error": err.Error(),
@@ -272,6 +372,7 @@ func init() {
 				return
 			}
 		})
+
 		// 达人不需要鉴权的接口
 		group.GET("/g", youngeetalentapi.TalentGetApi)
 		group.POST("/p", youngeetalentapi.TalentPostApi)

部分文件因为文件数量过多而无法显示