package service import ( "context" "encoding/json" "errors" "fmt" "github.com/issue9/conv" "github.com/lin-jim-leon/kuaishou" "github.com/sirupsen/logrus" "strconv" "time" "youngee_m_api/db" "youngee_m_api/model/gorm_model" "youngee_m_api/model/http_model" ) var SelectionTask *selectionTask type selectionTask struct { } func (*selectionTask) GetList(ctx context.Context, request http_model.GetSecTaskListRequest) (*http_model.GetSecTaskListData, error) { // sec_task:任务id、帐号昵称、粉丝数、收货地址、主页截图、主页链接、确认时间、申请时间、结算时间 // youngee_task_logistics: 物流公司、物流单号、发货时间、探店时间 // younggee_assignment_info:数据截图、作业链接 // selection_info: 返现金额、悬赏金额 // 1. 根据选品任务阶段、账号昵称or任务id查询任务基本信息(包括任务id、账号昵称、粉丝数、主页截图、主页链接、申请时间) fmt.Println("查找信息:", request.SelectionId, request.TaskStage) secTaskList, total, err := db.GetSecTaskList(ctx, request.SelectionId, request.TaskStage, request.SearchValue, request.PageSize, request.PageNum) fmt.Println("查找报错信息:", err) if err != nil { logrus.WithContext(ctx).Errorf("[sectask_service service] call GetSecTaskList error,err:%+v", err) return nil, err } fmt.Println("查找完成:", total) // 2. 根据不同查询类型查询补充信息 switch request.Type { case 1: // 确定达人查询 // 确定达人不需要额外信息 break case 2: // 发货管理查询 youngee_task_logistics // 发货管理根据任务阶段和商品类型查询物流信息 // 查询商品类型 product, err := db.GetProductType(ctx, request.SelectionId) fmt.Println("product: ", product) if err != nil { logrus.WithContext(ctx).Errorf("[sectask_service service] call GetAllSelection error,err:%+v", err) return nil, err } secTaskList, err = db.GetSecTaskLogisticsList(ctx, secTaskList, request.TaskStage, *product) if err != nil { logrus.WithContext(ctx).Errorf("[sectask_service service] call GetSecTaskLogisticsList error,err:%+v", err) return nil, err } break case 3: // 结算管理查询 younggee_assignment_info secTaskList, err = db.GetSecTaskSettleList(ctx, secTaskList, request.SelectionId, request.SecTaskStatus) if err != nil { logrus.WithContext(ctx).Errorf("[sectask_service service] call GetSecTaskSettleList error,err:%+v", err) return nil, err } break default: // 参数有误 break } selectionListData := http_model.GetSecTaskListData{ Total: conv.MustString(total, ""), SecTaskList: secTaskList, } return &selectionListData, nil } func (*selectionTask) PassCoop(ctx context.Context, request http_model.PassSecTaskCoopRequest) (*http_model.PassSecTaskCoopData, error) { _, err := db.PassSecTaskCoop(ctx, request.SelectionId, request.TaskIds) if err != nil { logrus.WithContext(ctx).Errorf("[sectask_service service] call PassCoop error,err:%+v", err) return nil, err } selectionListData := http_model.PassSecTaskCoopData{} return &selectionListData, nil } func (*selectionTask) RefuseCoop(ctx context.Context, request http_model.RefuseSecTaskCoopRequest) (*http_model.RefuseSecTaskCoopData, error) { _, err := db.RefuseSecTaskCoop(ctx, request.TaskIds) if err != nil { logrus.WithContext(ctx).Errorf("[sectask_service service] call RefuseCoop error,err:%+v", err) return nil, err } selectionListData := http_model.RefuseSecTaskCoopData{} return &selectionListData, nil } /* func (*selectionTask) Settle(ctx context.Context, entersizeId string, request http_model.SettleSecTaskRequest) (*http_model.SettleSecTaskData, error) { // 1. 解析request data var returnMoney float64 = 0.0 var rewardMoney float64 = 0.0 payMoney, err := strconv.ParseFloat(request.TotalPayMoney, 64) if err != nil { logrus.WithContext(ctx).Errorf("[sectask_service service] call strconv.ParseFloat() error,err:%+v", err) return nil, err } // 2. 校验:任务是否正常(处于待结算阶段);企业账户可用余额是否充足;若返现则校验达人是否垫付买样;若有悬赏金额则校验是否为悬赏任务 // 1) 校验企业账户余额是否充足 entersize, err := db.GetEnterpriseByEnterpriseID(ctx, entersizeId) if err != nil { logrus.WithContext(ctx).Errorf("[sectask_service service] call GetEnterpriseByEnterpriseID error,err:%+v", err) return nil, err } if entersize.AvailableBalance < payMoney { return nil, errors.New("账户余额不足") } // 2) 若返现则校验达人是否垫付买样;若有悬赏金额则校验是否为悬赏任务 selection, err := db.GetSelectionById(ctx, request.SelectionID) if err != nil { logrus.WithContext(ctx).Errorf("[sectask_service service] call GetSelectionById error,err:%+v", err) return nil, err } if selection.SampleMode != 2 && request.IsReturnMoney == 1 { return nil, errors.New("免费领养任务不能返样品钱") } if selection.TaskMode != 1 && request.IsPayReward == 1 { return nil, errors.New("非悬赏任务不能支付悬赏") } // 3) 校验任务是否处于待结算阶段 secTask, err := db.GetSecTaskById(ctx, request.TaskID) if err != nil { logrus.WithContext(ctx).Errorf("[sectask_service service] call GetSecTaskById error,err:%+v", err) return nil, err } if secTask.TaskStage != 9 && secTask.TaskStatus != 2 { return nil, errors.New("该任务暂不可结算") } var product gorm_model.YounggeeProduct if err = json.Unmarshal([]byte(selection.ProductSnap), &product); err != nil { fmt.Println("Error:", err) return nil, err } // 4) 校验结算金额计算是否正确 if request.IsReturnMoney == 1 { returnMoney = product.ProductPrice } if request.IsPayReward == 1 { rewardMoney, err = strconv.ParseFloat(selection.TaskReward, 64) if err != nil { logrus.WithContext(ctx).Errorf("[sectask_service service] call strconv.ParseFloat() error,err:%+v", err) return nil, err } } println("payMoney: ", payMoney) println("rewardMoney+returnMoney: ", rewardMoney+returnMoney) // 3. 更新选品结算金额 _, err = db.UpdateSelectionSettleMoney(ctx, selection.SelectionID, payMoney) if err != nil { logrus.WithContext(ctx).Errorf("[sectask_service service] call UpdateSelectionSettleMoney error,err:%+v", err) return nil, err } // 4. 更新选品任务阶段 updateSecTaskData := gorm_model.YounggeeSecTaskInfo{ TaskID: request.TaskID, TaskStage: 10, AssignmentStatus: 5, IsPayReward: request.IsPayReward, IsPayPayment: request.IsReturnMoney, CompleteDate: time.Now(), } _, err = db.UpdateSecTask(ctx, updateSecTaskData) if err != nil { logrus.WithContext(ctx).Errorf("[sectask_service service] call UpdateSecTask error,err:%+v", err) return nil, err } // 5. 添加任务日志和达人消息 err = db.CreateTaskLog(ctx, request.TaskID, "结算时间") if err != nil { logrus.WithContext(ctx).Errorf("[sectask_service service] call CreateTaskLog error,err:%+v", err) return nil, err } err = db.CreateMessageBySecTaskId(ctx, 5, 1, request.TaskID) if err != nil { logrus.WithContext(ctx).Errorf("[sectask_service service] call CreateMessageBySecTaskId error,err:%+v", err) return nil, err } // 6. 创建选品收益记录 // 返现收益 t := time.Now() if request.IsReturnMoney == 1 { income := gorm_model.YounggeeTalentIncome{ TalentID: secTask.TalentID, SelectionID: secTask.SelectionID, SectaskID: secTask.TaskID, BrandName: product.BrandName, TaskName: selection.SelectionName, Income: strconv.FormatFloat(returnMoney, 'f', 10, 32), IncomeType: 1, WithdrawStatus: 1, IncomeAt: &t, WithdrawAt: nil, } err = db.CreateIncome(ctx, income, nil) if err != nil { logrus.WithContext(ctx).Errorf("[sectask_service service] call CreateIncome error,err:%+v", err) return nil, err } } // 悬赏收益 if request.IsPayReward == 1 { income := gorm_model.YounggeeTalentIncome{ TalentID: secTask.TalentID, SelectionID: secTask.SelectionID, SectaskID: secTask.TaskID, BrandName: product.BrandName, TaskName: selection.SelectionName, Income: strconv.FormatFloat(rewardMoney, 'f', 10, 32), IncomeType: 1, WithdrawStatus: 1, IncomeAt: &t, WithdrawAt: nil, } err = db.CreateIncome(ctx, income, nil) if err != nil { logrus.WithContext(ctx).Errorf("[sectask_service service] call CreateIncome error,err:%+v", err) return nil, err } } // 7. 若有young之团存在,则为young之团创建收益 settleSecTaskData := http_model.SettleSecTaskData{} return &settleSecTaskData, nil } */ // UpdateStrategyId 为带货子任务匹配满足要求的免费领样策略 func (*selectionTask) UpdateStrategyId(ctx context.Context, selectionId string) error { var taskStage int = 11 var SearchValue = "" var PageSize = int64(0) var PageNum = int64(0) secTaskList, total, err := db.GetSecTaskList(ctx, selectionId, taskStage, SearchValue, PageSize, PageNum) fmt.Println("此选品的带货子任务数量: ", total) FreeStrategys, err := db.GetFreeStrategyBySelectionId(ctx, selectionId) for i, _ := range FreeStrategys { var strate_id = FreeStrategys[i].StrategyId var fans_num = FreeStrategys[i].FansNum var sale_num = FreeStrategys[i].SaleNum var interval []int switch fans_num { case 1: interval = []int{0, 100000000} break case 2: interval = []int{0, 10000} break case 3: interval = []int{10001, 100000} break case 4: interval = []int{100001, 1000000} break case 5: interval = []int{1000000, 5000000} break case 6: interval = []int{5000000, 10000000} break case 7: interval = []int{10000000, 100000000} break } for j, _ := range secTaskList { var fans int fans, err = strconv.Atoi(secTaskList[j].FansCount) var sale int64 sale = int64(secTaskList[j].SaleNum) if fans <= interval[1] && fans >= interval[0] && sale >= sale_num { secTaskList[j].FreeStrategyId = int(strate_id) err := db.UpdataFreeStratrgyId(ctx, secTaskList[j].SecTaskId, secTaskList[j].FreeStrategyId) println("Update: ", err) } } } return err } // UpdateStrategyNumBySelectionId 统计满足某一条FreeStrategy的带货子任务数量 func (*selectionTask) UpdateStrategyNumBySelectionId(ctx context.Context, selectionId string) error { FreeStrategys, err := db.GetFreeStrategyBySelectionId(ctx, selectionId) fmt.Println(err) for i, _ := range FreeStrategys { var id = FreeStrategys[i].StrategyId var selection_id = FreeStrategys[i].SelectionId // 报名且符合策略的数量 var stage = 3 enroll_num, err := db.GetSecTaskCountByStrategyId(ctx, selection_id, int(id), stage) fmt.Println(err) fmt.Println("已申请免费领样且符合策略的数量: ", enroll_num) // 申请成功且符合策略的数量 stage = 4 choose_num, err := db.GetSecTaskCountByStrategyId(ctx, selection_id, int(id), stage) fmt.Println(err) fmt.Println("申请免费领样成功且符合策略的数量: ", choose_num) // 待发货且符合策略的数量 stage = 6 before_delivery_num, err := db.GetSecTaskCountByStrategyId(ctx, selection_id, int(id), stage) fmt.Println(err) fmt.Println("待发货且符合策略的数量: ", before_delivery_num) // 已发货且符合策略的数量 stage = 7 delivery_num, err := db.GetSecTaskCountByStrategyId(ctx, selection_id, int(id), stage) fmt.Println(err) fmt.Println("已发货且符合策略的数量: ", delivery_num) // 已收货且符合策略的数量 stage = 8 after_delivery_num, err := db.GetSecTaskCountByStrategyId(ctx, selection_id, int(id), stage) fmt.Println(err) fmt.Println("已收货且符合策略的数量: ", after_delivery_num) // 把要更新的参数初始化为结构体 updatestrategy := gorm_model.FreeStrategy{ SelectionId: selection_id, StrategyId: id, EnrollNum: enroll_num, ChooseNum: choose_num, BeforeDeliveryNum: before_delivery_num, DeliveryNum: delivery_num, AfterDeliveryNum: after_delivery_num, } // 更新 err = db.UpdateFreeStrategyNum(ctx, updatestrategy) } return err } // UpdateActualNumBySelectionId 根据带货任务ID更新达人实际带货量 func (*selectionTask) UpdateActualNumBySelectionId(ctx context.Context, selectionId string) error { // 1. 预处理 // 1.1. 根据selectionID和task_stage筛选出所有满足条件的子任务 var SecTaskStatus = 11 var SearchValue = "" var PageSize = int64(0) var PageNum = int64(0) var AppKey string = "ks651333097154138217" var SignSecret string = "bf6393dce0a2b669ee348bebb837b0da" var cpsOrderStatus int = 0 var pageSize int = 100 var endTime int64 = time.Now().Unix() * 1000 var beginTime int64 = endTime - 432000000 var pcursor = "" // var sale_num_all = 0 secTaskList, total, err := db.GetSecTaskList(ctx, selectionId, SecTaskStatus, SearchValue, PageSize, PageNum) if err != nil { return err } fmt.Println("待更新达人实际带货量的子任务数量: ", total) // 1.2. 筛选出Selection的开始时间和结束时间 selectionInfo, err := db.GetSelectionById(ctx, selectionId) if err != nil { return err } selectionPassTime := selectionInfo.PassAt selectionFinishTime := selectionInfo.FinishAt fmt.Println("带货任务开始时间和结束时间: ", selectionPassTime, selectionFinishTime) // 2. 在筛选出的secTaskList中调用SDK查询实际带货量 for i, _ := range secTaskList { // 通过talentID取出AccessToken和快手商品ID var talentID string = "223329990" KuaishouProductID, _ := db.GetProductByID(ctx, int64(secTaskList[i].ProductId)) KuaishouProductId := KuaishouProductID.KuaishouProductId var actual_num int = 0 // var sale_num_all = 0 AccessToken := db.GetKuaishouUserInfoByTalentId(ctx, talentID).AccessToken fmt.Println("AccessToken: ", AccessToken) // 根据AccessToken去查实际带货量 // 递归 for k := 1; k < 18; k++ { corderlist, err := kuaishou.Corderlist(AppKey, SignSecret, AccessToken, cpsOrderStatus, pageSize, beginTime, endTime, pcursor) fmt.Println("error: ", err) if err != nil { return err } var orderList = corderlist.Data.OrderViews pcursor = corderlist.Data.Cursor fmt.Println("pcursor: ", pcursor) // 在orderList中统计符合要求的商品销量 for j := range orderList { if KuaishouProductId == orderList[j].CPSOrderProductViews[0].ItemID { actual_num += orderList[j].CPSOrderProductViews[0].Num } } fmt.Println("len of orderList: ", len(orderList)) // 游标方式遍历100条后的订单 for { if pcursor == "nomore" || len(orderList) == 0 { println("nomore") break } corderlist_cursor, err1 := kuaishou.Corderlist(AppKey, SignSecret, AccessToken, cpsOrderStatus, pageSize, beginTime, endTime, pcursor) fmt.Println("error: ", err1) if err1 != nil { return err1 } var orderList_cursor = corderlist_cursor.Data.OrderViews pcursor = corderlist_cursor.Data.Cursor if KuaishouProductId == orderList_cursor[99].CPSOrderProductViews[0].ItemID { actual_num += orderList_cursor[99].CPSOrderProductViews[0].Num } } endTime = beginTime beginTime -= 432000000 println("k= ", k) } updateData := gorm_model.YounggeeSecTaskInfo{ TaskID: secTaskList[i].SecTaskId, SaleActual: actual_num, SaleNumAll: actual_num, } _, err = db.UpdateSecTask(ctx, updateData) fmt.Println(err) } return err } // Settle 结算 func (*selectionTask) Settle(ctx context.Context, entersizeId string, request http_model.SettleSecTaskRequest) (*http_model.SettleSecTaskData, error) { // 1. 解析request data //var returnMoney float64 = 0.0 //var rewardMoney float64 = 0.0 payMoney, err := strconv.ParseFloat(request.TotalPayMoney, 64) fmt.Println("待支付金额: ", payMoney) if err != nil { logrus.WithContext(ctx).Errorf("[sectask_service service] call strconv.ParseFloat() error,err:%+v", err) return nil, err } // 2. 校验:任务是否正常(处于待结算阶段);企业账户可用余额是否充足;若返现则校验达人是否垫付买样;若有悬赏金额则校验是否为悬赏任务 // 1) 校验企业账户余额是否充足 entersize, err := db.GetEnterpriseByEnterpriseID(ctx, entersizeId) if err != nil { logrus.WithContext(ctx).Errorf("[sectask_service service] call GetEnterpriseByEnterpriseID error,err:%+v", err) return nil, err } if entersize.AvailableBalance < payMoney { return nil, errors.New("账户余额不足") } fmt.Println("余额充足") // 2) 若返现则校验达人是否垫付买样;若有悬赏金额则校验是否为悬赏任务 selection, err := db.GetSelectionById(ctx, request.SelectionID) if err != nil { logrus.WithContext(ctx).Errorf("[sectask_service service] call GetSelectionById error,err:%+v", err) return nil, err } /* if selection.SampleMode != 2 && request.IsReturnMoney == 1 { return nil, errors.New("免费领养任务不能返样品钱") } */ if selection.TaskMode != 1 && request.IsPayReward == 1 { return nil, errors.New("非悬赏任务不能支付悬赏") } fmt.Println("是悬赏任务") // 3) 校验任务是否处于待结算阶段 secTask, err := db.GetSecTaskById(ctx, request.TaskID) if err != nil { logrus.WithContext(ctx).Errorf("[sectask_service service] call GetSecTaskById error,err:%+v", err) return nil, err } /* if secTask.TaskStage != 9 && secTask.TaskStatus != 2 { return nil, errors.New("该任务暂不可结算") } */ if secTask.RewardStage != 1 && secTask.TaskStatus != 2 { return nil, errors.New("该任务暂不可结算") } fmt.Println("可结算") var product gorm_model.YounggeeProduct if err = json.Unmarshal([]byte(selection.ProductSnap), &product); err != nil { fmt.Println("Error:", err) return nil, err } // 4) 校验结算金额计算是否正确 /* if request.IsReturnMoney == 1 { returnMoney = product.ProductPrice } if request.IsPayReward == 1 { rewardMoney, err = strconv.ParseFloat(selection.TaskReward, 64) if err != nil { logrus.WithContext(ctx).Errorf("[sectask_service service] call strconv.ParseFloat() error,err:%+v", err) return nil, err } } println("payMoney: ", payMoney) println("rewardMoney+returnMoney: ", rewardMoney+returnMoney) if rewardMoney+returnMoney != payMoney { return nil, errors.New("结算金额有误") } */ // 3. 更新选品结算金额 _, err = db.UpdateSelectionSettleMoney(ctx, selection.SelectionID, payMoney) if err != nil { logrus.WithContext(ctx).Errorf("[sectask_service service] call UpdateSelectionSettleMoney error,err:%+v", err) return nil, err } fmt.Println("已结算") // 4. 更新选品任务阶段 updateSecTaskData := gorm_model.YounggeeSecTaskInfo{ TaskID: request.TaskID, TaskStage: 10, RewardStage: 2, AssignmentStatus: 5, IsPayReward: request.IsPayReward, IsPayPayment: request.IsReturnMoney, CompleteDate: time.Now(), } _, err = db.UpdateSecTask(ctx, updateSecTaskData) if err != nil { logrus.WithContext(ctx).Errorf("[sectask_service service] call UpdateSecTask error,err:%+v", err) return nil, err } // 5. 添加任务日志和达人消息 err = db.CreateTaskLog(ctx, request.TaskID, "结算时间") if err != nil { logrus.WithContext(ctx).Errorf("[sectask_service service] call CreateTaskLog error,err:%+v", err) return nil, err } err = db.CreateMessageBySecTaskId(ctx, 5, 1, request.TaskID) if err != nil { logrus.WithContext(ctx).Errorf("[sectask_service service] call CreateMessageBySecTaskId error,err:%+v", err) return nil, err } // 6. 创建选品收益记录 // 返现收益 /* t := time.Now() if request.IsReturnMoney == 1 { income := gorm_model.YounggeeTalentIncome{ TalentID: secTask.TalentID, SelectionID: secTask.SelectionID, SectaskID: secTask.TaskID, BrandName: product.BrandName, TaskName: selection.SelectionName, Income: strconv.FormatFloat(returnMoney, 'f', 10, 32), IncomeType: 1, WithdrawStatus: 1, IncomeAt: &t, WithdrawAt: nil, } err = db.CreateIncome(ctx, income, nil) if err != nil { logrus.WithContext(ctx).Errorf("[sectask_service service] call CreateIncome error,err:%+v", err) return nil, err } } */ // 悬赏收益 t := time.Now() if request.IsPayReward == 1 { income := gorm_model.YounggeeTalentIncome{ TalentID: secTask.TalentID, SelectionID: secTask.SelectionID, SectaskID: secTask.TaskID, BrandName: product.BrandName, TaskName: selection.SelectionName, Income: strconv.FormatFloat(payMoney, 'f', 10, 32), IncomeType: 1, WithdrawStatus: 1, IncomeAt: &t, WithdrawAt: nil, } err = db.CreateIncome(ctx, income, nil) if err != nil { logrus.WithContext(ctx).Errorf("[sectask_service service] call CreateIncome error,err:%+v", err) return nil, err } } fmt.Println("成功写入达人信息") // 7. 若有young之团存在,则为young之团创建收益 settleSecTaskData := http_model.SettleSecTaskData{} // 8. 统计 println("开始为每个带货子任务绑定免费领样策略") err1 := SelectionTask.UpdateStrategyId(ctx, request.SelectionID) nerr := SelectionTask.UpdateStrategyNumBySelectionId(ctx, request.SelectionID) fmt.Println(nerr, err1) println("完成为每个带货子任务绑定免费领样策略") return &settleSecTaskData, nil }