package service import ( "errors" "fmt" "time" "shop-api/global" "shop-api/model" "shop-api/model/request" "shop-api/utils" "gorm.io/gorm" ) func GetMissionDetail(uuid string, id uint) (error, model.MissionDetail) { var ( err error result model.MissionDetail ) err = global.MG_DB.Model(&model.Mission{}). Select("id,title,goods_id,goods_status,num,hire_type,hire_money,hire_ratio,start_time,end_time,status,create_by"). Where("id = ?", id).Preload("Goods", func(db *gorm.DB) *gorm.DB { return db.Select("id,spu_no,title,title_eng,images,tags,retail_price,price_min,price_max").Unscoped() }).First(&result).Error if err != nil { return err, result } if result.HireType == 1 { // 1:固定佣金 result.HireMoneyExpect = utils.FormatFloatToString(result.HireMoney) } else { // 2:比例抽成 if result.Goods.PriceMin == result.Goods.PriceMax { result.HireMoneyExpect = utils.FormatFloatToString(result.Goods.PriceMin * (result.HireRatio / 100)) } else { result.HireMoneyExpect = utils.FormatFloatToString(result.Goods.PriceMin*(result.HireRatio/100)) + "-" + utils.FormatFloatToString(result.Goods.PriceMax*(result.HireRatio/100)) } } if result.CreateBy != "" { _, result.Store = GetSellerStoreInfo(result.CreateBy) } result.CollectStatus = getMissionCollectStatus(uuid, result.ID) return nil, result } func GetMissionList(uuid string, info request.SearchMission) (err error, list interface{}, total int64) { limit := info.PageSize offset := info.PageSize * (info.Page - 1) db := global.MG_DB.Model(&model.Mission{}).Joins("INNER JOIN tb_goods ON tb_goods.id = mission.goods_id"). Where("mission.`status` = 2 AND mission.goods_status = 1 AND tb_goods.stock > 0") err = db.Count(&total).Error var res []model.MissionDetail err = db.Select("mission.id,mission.title,mission.goods_id,mission.goods_status,mission.num,mission.hire_type,mission.hire_money,mission.hire_ratio,mission.start_time,mission.end_time,mission.`status`,mission.create_by"). Preload("Goods", func(db *gorm.DB) *gorm.DB { return db.Select("id,spu_no,title,title_eng,images,tags,retail_price,price_min,price_max").Unscoped() }).Limit(limit).Offset(offset).Order("id desc").Find(&res).Error if err != nil { return err, nil, 0 } var ( ids []uint uuids []string ) for i := 0; i < len(res); i++ { if res[i].HireType == 1 { // 1:固定佣金 res[i].HireMoneyExpect = utils.FormatFloatToString(res[i].HireMoney) } else { // 2:比例抽成 if res[i].Goods.PriceMin == res[i].Goods.PriceMax { // res[i].HireMoneyExpect = fmt.Sprintf("%v", res[i].Goods.PriceMin*(res[i].HireRatio/100)) res[i].HireMoneyExpect = utils.FormatFloatToString(res[i].Goods.PriceMin * (res[i].HireRatio / 100)) } else { res[i].HireMoneyExpect = utils.FormatFloatToString(res[i].Goods.PriceMin*(res[i].HireRatio/100)) + "-" + utils.FormatFloatToString(res[i].Goods.PriceMax*(res[i].HireRatio/100)) } } if res[i].CreateBy != "" { uuids = append(uuids, res[i].CreateBy) } ids = append(ids, res[i].ID) } if len(ids) != 0 { statusMap := getMissionCollectStatusMap(uuid, ids) for i := 0; i < len(res); i++ { if val, ok := statusMap[res[i].ID]; ok { res[i].CollectStatus = val } } } if len(uuids) != 0 { _, storeMap := getSellerStoreInfoMap(uuids) for i := 0; i < len(res); i++ { if val, ok := storeMap[res[i].CreateBy]; ok { res[i].Store = val } } } return err, res, total } func GetMissionClaim(uuid string, id uint) (err error, res model.MissionClaimDetail) { err = global.MG_DB.Model(&model.MissionClaim{}).Where("create_by = ? AND id = ?", uuid, id). Select("id,mission_id,claim_no,achieve_num,`status`,created_at,updated_at"). Preload("Order", func(db *gorm.DB) *gorm.DB { return db.Select("order_id,mission_claim_id,`status`,courier,courier_url,courier_number") }). Preload("Mission", func(db *gorm.DB) *gorm.DB { return db.Select("id,title,goods_id,goods_status,num,hire_type,hire_money,hire_ratio,start_time,end_time,`status`,create_by"). Preload("Goods", func(db *gorm.DB) *gorm.DB { return db.Select("id,spu_no,title,title_eng,images,tags,retail_price,price_min,price_max").Unscoped() }) }).Preload("Works").First(&res).Error if err != nil { return } if res.Mission.CreateBy != "" { _, res.Mission.Store = GetSellerStoreInfo(res.Mission.CreateBy) } if res.Mission.HireType == 1 { // 1:固定佣金 res.Mission.HireMoneyExpect = utils.FormatFloatToString(res.Mission.HireMoney) } else { // 2:比例抽成 if res.Mission.Goods.PriceMin == res.Mission.Goods.PriceMax { res.Mission.HireMoneyExpect = utils.FormatFloatToString(res.Mission.Goods.PriceMin * (res.Mission.HireRatio / 100)) } else { res.Mission.HireMoneyExpect = utils.FormatFloatToString(res.Mission.Goods.PriceMin*(res.Mission.HireRatio/100)) + "-" + utils.FormatFloatToString(res.Mission.Goods.PriceMax*(res.Mission.HireRatio/100)) } } if res.Mission.ID != 0 { res.Mission.CollectStatus = getMissionCollectStatus(uuid, res.Mission.ID) } res.SpreadUrl = global.MG_CONFIG.Tools.CustomerUrl + "/CommodityDetails?id=" + fmt.Sprintf("%v", res.Mission.Goods.ID) + "&spu_no=" + res.Mission.Goods.SpuNo + "&claim_no=" + res.ClaimNo return } func GetMissionClaimList(uuid string, info request.SearchMissionClaim) (err error, list interface{}, total int64) { limit := info.PageSize offset := info.PageSize * (info.Page - 1) db := global.MG_DB.Model(&model.MissionClaim{}).Where("create_by = ?", uuid) err = db.Count(&total).Error var res []model.MissionClaimDetail err = db.Select("id,mission_id,claim_no,achieve_num,`status`,created_at,updated_at").Preload("Order", func(db *gorm.DB) *gorm.DB { return db.Select("order_id,mission_claim_id,`status`,courier,courier_url,courier_number") }).Preload("Mission", func(db *gorm.DB) *gorm.DB { return db.Select("id,title,goods_id,goods_status,num,hire_type,hire_money,hire_ratio,start_time,end_time,`status`"). Preload("Goods", func(db *gorm.DB) *gorm.DB { return db.Select("id,spu_no,title,title_eng,images,tags,retail_price,price_min,price_max").Unscoped() }) }).Order("id DESC").Limit(limit).Offset(offset).Find(&res).Error if err != nil { return err, nil, 0 } var ( ids []uint uuids []string ) for i := 0; i < len(res); i++ { if res[i].Mission.CreateBy != "" { uuids = append(uuids, res[i].Mission.CreateBy) } if res[i].Mission.HireType == 1 { // 1:固定佣金 res[i].Mission.HireMoneyExpect = utils.FormatFloatToString(res[i].Mission.HireMoney) } else { // 2:比例抽成 if res[i].Mission.Goods.PriceMin == res[i].Mission.Goods.PriceMax { res[i].Mission.HireMoneyExpect = utils.FormatFloatToString(res[i].Mission.Goods.PriceMin * (res[i].Mission.HireRatio / 100)) } else { res[i].Mission.HireMoneyExpect = utils.FormatFloatToString(res[i].Mission.Goods.PriceMin*(res[i].Mission.HireRatio/100)) + "-" + utils.FormatFloatToString(res[i].Mission.Goods.PriceMax*(res[i].Mission.HireRatio/100)) } } if res[i].Mission.ID != 0 { ids = append(ids, res[i].Mission.ID) } } if len(ids) != 0 { statusMap := getMissionCollectStatusMap(uuid, ids) for i := 0; i < len(res); i++ { res[i].Mission.CollectStatus = statusMap[res[i].ID] } } if len(uuids) != 0 { _, storeMap := getSellerStoreInfoMap(uuids) for i := 0; i < len(res); i++ { if val, ok := storeMap[res[i].Mission.CreateBy]; ok { res[i].Mission.Store = val } } } return err, res, total } func ClaimMission(uuid string, info request.ClaimMission) (err error, id uint) { var mission model.Mission if global.MG_DB.Model(&model.Mission{}).Where("id = ?", info.MissionId).First(&mission).Error != nil { return errors.New("抱歉,未找到任务信息"), 0 } if mission.Status != 2 || mission.GoodsStatus != 1 { return errors.New("抱歉,当前任务不可领取"), 0 } now := time.Now().UTC().Unix() if mission.StartTime.Unix() > now || mission.EndTime.Unix() < now { return errors.New("抱歉,不在任务领取时间内"), 0 } var address model.Address if !errors.Is(global.MG_DB.Model(&model.MissionClaim{}).Where("create_by = ? AND mission_id = ?", uuid, info.MissionId).First(&model.MissionClaim{}).Error, gorm.ErrRecordNotFound) { // 判断email是否注册 return errors.New("不可重复领取"), 0 } if global.MG_DB.Model(&model.Address{}).Where("user_id = ? AND id = ?", uuid, info.AddressId).First(&address).Error != nil { return errors.New("抱歉,未找到地址信息"), 0 } var ( missionClaim model.MissionClaim missionClaimOrder model.MissionClaimOrder missionClaimOrderGoods model.MissionClaimOrderGoods missionClaimAddress model.MissionClaimAddress ) tx := global.MG_DB.Begin() missionClaim.MissionId = info.MissionId missionClaim.ClaimNo = utils.GetInvitationLowerLen(20) missionClaim.AchieveNum = 0 missionClaim.CreateBy = uuid missionClaim.Status = 1 err = tx.Model(&model.MissionClaim{}).Create(&missionClaim).Error if err != nil { tx.Rollback() return } // 任务领取人数+1 err = tx.Model(&model.Mission{}).Where("id = ?", info.MissionId).UpdateColumn("claim_num", gorm.Expr("`claim_num` + 1")).Error if err != nil { tx.Rollback() return } // 创建任务订单 var ( goods model.TbGoods goodsSpec model.TbGoodsSpecs ) err = tx.Model(&model.TbGoods{}).Where("online = 'on' AND spu_no = ?", info.SpuNo).First(&goods).Error if err != nil { tx.Rollback() err = errors.New("未找到商品信息") return } err = tx.Model(&model.TbGoodsSpecs{}).Where("status = 1 AND goods_id = ? AND sku_no = ?", goods.ID, info.SkuNo).First(&goodsSpec).Error if err != nil { tx.Rollback() err = errors.New("未找到商品规格信息") return } missionClaimOrder.OrderID = Generate() missionClaimOrder.MissionClaimId = missionClaim.ID missionClaimOrder.SpuNo = info.SpuNo missionClaimOrder.SkuNo = info.SkuNo missionClaimOrder.Number = 1 missionClaimOrder.CreateBy = uuid missionClaimOrder.Status = 2 // 待发货 err = tx.Model(&model.MissionClaimOrder{}).Create(&missionClaimOrder).Error if err != nil { tx.Rollback() err = errors.New("创建任务订单失败") return } missionClaimOrderGoods.OrderID = missionClaimOrder.OrderID missionClaimOrderGoods.SkuNo = info.SkuNo missionClaimOrderGoods.Title = goods.Title missionClaimOrderGoods.Image = goodsSpec.Image missionClaimOrderGoods.Specs = goodsSpec.Specs missionClaimOrderGoods.Price = goodsSpec.Price err = tx.Model(&model.MissionClaimOrderGoods{}).Create(&missionClaimOrderGoods).Error if err != nil { tx.Rollback() err = errors.New("创建任务订单失败") return } // 创建任务收获地址 missionClaimAddress.Address = address missionClaimAddress.ID = 0 missionClaimAddress.AddressId = address.ID missionClaimAddress.MissionClaimId = missionClaim.ID missionClaimAddress.OrderID = missionClaimOrder.OrderID err = tx.Model(&model.MissionClaimAddress{}).Create(&missionClaimAddress).Error if err != nil { tx.Rollback() return } tx.Commit() id = missionClaim.ID return } func SubmitClaimMissionWorks(uuid string, info request.ClaimMissionWorksList) (err error) { err = global.MG_DB.Model(&model.MissionClaim{}).Where("create_by = ? AND id = ?", uuid, info.MissionClaimId).First(&model.MissionClaim{}).Error if err != nil { err = errors.New("not found mission claim record") return err } tx := global.MG_DB.Begin() for i := 0; i < len(info.Works); i++ { var works model.MissionClaimWorks works.Type = info.Works[i].Type works.Homepage = info.Works[i].Homepage works.Image = info.Works[i].Image if info.Works[i].ID != 0 { if info.Works[i].Homepage == "" { err = tx.Model(&model.MissionClaimWorks{}).Where("id = ?", info.Works[i].ID).Delete(&model.MissionClaimWorks{}).Error if err != nil { tx.Rollback() return err } } else { err = tx.Model(&model.MissionClaimWorks{}).Where("id = ?", info.Works[i].ID).Select("Type", "Homepage", "Image").Updates(&works).Error if err != nil { tx.Rollback() return err } } } else { works.MissionClaimId = info.MissionClaimId err = tx.Model(&model.MissionClaimWorks{}).Create(&works).Error if err != nil { tx.Rollback() return err } } } err = tx.Model(&model.MissionClaim{}).Where("id = ? AND status = 2", info.MissionClaimId).UpdateColumn("status", 3).Error if err != nil { tx.Rollback() return err } tx.Commit() return nil } func GetMissionBonus(req *request.MissionCode) interface{} { var bonus model.MissionBonus global.MG_DB.Model(&model.Bill{}).Select("sum(bill.price) total").Joins("inner join `order` b on bill.order_id=b.order_id and b.code=?", req.Code).Where("bill.status=2 and bill.type=1").Scan(&bonus) return bonus }