package service import ( "encoding/json" "errors" "fmt" "os" "strings" "sync/atomic" "time" "github.com/plutov/paypal" "github.com/w3liu/go-common/constant/timeformat" "pure/dto" "pure/global" "pure/model" "pure/model/request" "pure/utils" ) func GetOrderData(userId string, info *request.SceneParams) (dto.OrderData, error) { var ( // err error result dto.OrderData ) // TODO 全部数据包含哪些状态 switch info.Scene { case "my": result.Unship, _ = getOrderCount(userId, &request.SearchOrderList{Status: 2}) result.Shipped, _ = getOrderCount(userId, &request.SearchOrderList{Status: 3}) result.Finished, _ = getOrderCount(userId, &request.SearchOrderList{Status: 4}) result.Cancel, _ = getOrderCount(userId, &request.SearchOrderList{Status: 5}) default: result.All, _ = getOrderCount(userId, &request.SearchOrderList{Status: 0}) result.Unship, _ = getOrderCount(userId, &request.SearchOrderList{Status: 2}) result.Shipped, _ = getOrderCount(userId, &request.SearchOrderList{Status: 3}) result.Finished, _ = getOrderCount(userId, &request.SearchOrderList{Status: 4}) result.Cancel, _ = getOrderCount(userId, &request.SearchOrderList{Status: 5}) } return result, nil } func getOrderCount(userId string, info *request.SearchOrderList) (int64, error) { var ( err error result int64 ) db := global.MG_DB.Model(&model.Order{}).Joins("INNER JOIN mission_claim ON mission_claim.claim_no = `order`.`code`"). Where("`order`.`status` IN (2,3,4,5) AND mission_claim.create_by = ?", userId) if info.Status != 0 { db = db.Where("`order`.status = ?", info.Status) } if info.Code != "" { db = db.Where("`order`.`code` = ?", info.Code) } switch info.Group { case "user": // 下单人数 db = db.Group("`order`.user_id") err = db.Count(&result).Error default: err = db.Count(&result).Error } return result, err } func GetOrderList(userId string, info *request.SearchOrderList) (error, any, int64) { var ( err error data []model.OrderList total int64 ) limit := info.PageSize offset := info.PageSize * (info.Page - 1) db := global.MG_DB.Model(&model.Order{}).Joins("INNER JOIN mission_claim ON mission_claim.claim_no = `order`.`code`"). Where("`order`.`status` IN (2,3,4,5) AND mission_claim.create_by = ?", userId) if info.Status != 0 { db = db.Where("`order`.`status` = ?", info.Status) } if info.Code != "" { db = db.Where("`order`.`code` = ?", info.Code) } err = db.Order("order.id desc").Offset(offset).Limit(limit).Find(&data).Error if err != nil { return errors.New("获取订单失败"), data, total } if len(data) == 0 { return nil, data, total } var orderIds, userIds, claimNos, platforms []string for _, val := range data { orderIds = append(orderIds, val.OrderID) userIds = append(userIds, val.UserID) if val.Code != "" { claimNos = append(claimNos, val.Code) } if val.Platform != "" { platforms = append(platforms, val.Platform) } } var ( orderGoodsList []model.OrderGoodsDetail goodsMap = make(map[string]model.OrderGoodsDetail) ) err = global.MG_DB.Model(&model.OrderGoods{}).Where("order_id IN (?)", orderIds).Find(&orderGoodsList).Error if err != nil { return errors.New("获取订单商品信息失败"), data, total } for _, goods := range orderGoodsList { goodsMap[goods.OrderID] = goods } var ( users []model.UserSimple userMap = make(map[string]model.UserSimple) ) err = global.MG_DB.Model(&model.User{}).Where("`type` = 'customer' AND uuid IN (?)", userIds).Find(&users).Error if err != nil { return errors.New("获取订单用户信息失败"), data, total } for _, user := range users { userMap[user.UUID.String()] = user } var ( missions []model.MissionClaimInfo hireRatioMap = make(map[string]float64) ) err = global.MG_DB.Model(&model.MissionClaim{}).Select("mission_claim.claim_no,mission_claim.mission_id,b.hire_type,b.hire_money,b.hire_ratio"). Joins("inner join mission b on mission_claim.mission_id=b.id").Where("claim_no IN (?) AND b.hire_type = 2", claimNos).Find(&missions).Error if err != nil { return errors.New("获取任务详情失败"), data, total } for _, val := range missions { hireRatioMap[val.ClaimNo] = val.HireRatio } dictMap := getDictMap("release_channel", platforms) for v := range data { if val, ok := goodsMap[data[v].OrderID]; ok { data[v].Goods = val } if val, ok := userMap[data[v].UserID]; ok { data[v].User = val } if val, ok := hireRatioMap[data[v].Code]; ok { data[v].InfluencerAmount = utils.FormatFloatToString(data[v].PaidPrice * val / 100) } if val, ok := dictMap[data[v].Platform]; ok { data[v].Platform = val } } return nil, data, total } func GetOrderDetail(userId string, info *request.GetOrderParams) (error, model.OrderDetail) { var ( err error data model.OrderDetail tCommod model.TbGoods ) err = global.MG_DB.Model(&model.Order{}).Joins("INNER JOIN mission_claim ON mission_claim.claim_no = `order`.`code`"). Where("mission_claim.create_by = ? AND order_id = ?", userId, info.OrderID).Find(&data).Error if err != nil { return errors.New("获取订单失败"), data } err = global.MG_DB.Model(&model.OrderAddress{}).Where("order_id=?", info.OrderID).Find(&data.Address).Error if err != nil { return errors.New("获取订单地址失败"), data } err = global.MG_DB.Model(&model.OrderGoods{}).Where("order_id=?", info.OrderID).Find(&data.Goods).Error if err != nil { return errors.New("获取订单商品信息失败"), data } err = global.MG_DB.Model(&model.OrderDeliver{}).Where("order_id=?", info.OrderID).Find(&data.Deliver).Error if err != nil { return errors.New("获取发货信息失败"), data } if data.Code != "" { var mission model.MissionClaimInfo _ = global.MG_DB.Model(&model.MissionClaim{}).Joins("inner join mission b on mission_claim.mission_id=b.id"). Select("mission_claim.claim_no,mission_claim.mission_id,b.hire_type,b.hire_money,b.hire_ratio").Where("claim_no = ? AND b.hire_type = 2", data.Code).First(&mission) if mission.MissionId != 0 { amount := data.PaidPrice * mission.HireRatio / 100 data.InfluencerAmount = utils.FormatFloatToString(amount) } } if data.Platform != "" { data.Platform = GetSysDictDataLabel("release_channel", data.Platform) } global.MG_DB.Model(&model.TbGoods{}).Where("id=?", data.CommodID).Find(&tCommod) global.MG_DB.Model(&model.SellerStore{}).Select("store_no,`type`,email").Where("store_no = ?", tCommod.StoreNo).Find(&data.Store) _ = global.MG_DB.Model(&model.OrderPostSale{}).Select("id,order_id,status,remark,examine_time,refund_time,refund_status,created_at").Where("order_id = ? AND status IN (1,2,3)", data.OrderID).First(&data.PostSale).Error if data.PayTime != nil { data.Bill, _ = getBillView(data.OrderID) } data.Chain = model.Chain{Address: "b714e5508531a7b50d0696abdc83d2333bd896db24f68eb1470bb9529390ef3e"} return nil, data } func GetOrderGoods(userId string, info *request.GetOrderParams) (error, model.OrderGoodsDetail) { var ( err error order model.Order result model.OrderGoodsDetail ) err = global.MG_DB.Model(&model.Order{}).Joins("INNER JOIN mission_claim ON mission_claim.claim_no = `order`.`code`"). Where("mission_claim.create_by = ? AND order_id = ?", userId, info.OrderID).Find(&order).Error if err != nil { return errors.New("获取订单失败"), result } err = global.MG_DB.Model(&model.OrderGoods{}).Where("order_id = ?", info.OrderID).Find(&result).Error if err != nil { return errors.New("获取订单商品信息失败"), result } err = global.MG_DB.Model(&model.OrderGoodsSpecs{}).Where("order_goods_id = ?", result.ID).Find(&result.GoodsSpecs).Error if err != nil { return errors.New("获取订单商品规格信息失败"), result } attributeValues := make(map[uint]*model.TbAttributeValueJson) for i := 0; i < len(result.GoodsSpecs); i++ { var attributeList []model.TbAttributeDetail err = json.Unmarshal([]byte(result.GoodsSpecs[i].Specs), &attributeList) if err != nil { return err, result } if i == 0 { var attributes []uint for j := 0; j < len(attributeList); j++ { attributes = append(attributes, attributeList[j].AttributeId) } orderSql := "FIELD(id" for _, attribute := range attributes { orderSql += fmt.Sprintf(",'%v'", attribute) } orderSql += ")" err = global.MG_DB.Model(&model.TbAttribute{}).Select("id,`name`").Where("id IN (?)", attributes).Order(orderSql).Find(&result.Attributes).Error if err != nil { return err, result } } for _, attribute := range attributeList { if _, ok := attributeValues[attribute.AttributeId]; ok { if !strings.Contains(attributeValues[attribute.AttributeId].Str, attribute.Value) { attributeValues[attribute.AttributeId].Str += attribute.Value + "," attributeValues[attribute.AttributeId].Items = append(attributeValues[attribute.AttributeId].Items, model.TbAttributeValueItem{Id: attribute.ValueId, Name: attribute.Value, Image: result.GoodsSpecs[i].Image}) } } else { attributeValues[attribute.AttributeId] = &model.TbAttributeValueJson{Items: []model.TbAttributeValueItem{{Id: attribute.ValueId, Name: attribute.Value, Image: result.GoodsSpecs[i].Image}}, Str: attribute.Value + ","} } } } for i := 0; i < len(result.Attributes); i++ { if val, ok := attributeValues[result.Attributes[i].ID]; ok { result.Attributes[i].Values = val.Items } } return err, result } // 用户提现 func CreatePayOutPayer(paypalName, amount, withdID string) (error, *paypal.PayoutResponse) { var ( err error c *paypal.Client ) if global.MG_CONFIG.Paypal.Env == "SandBox" { c, err = paypal.NewClient(global.MG_CONFIG.Paypal.ClientID, global.MG_CONFIG.Paypal.Secret, paypal.APIBaseSandBox) if err != nil { return err, nil } } else { c, err = paypal.NewClient(global.MG_CONFIG.Paypal.ClientID, global.MG_CONFIG.Paypal.Secret, paypal.APIBaseLive) if err != nil { return err, nil } } _, err = c.GetAccessToken() if err != nil { return err, nil } payout := paypal.Payout{} send := &paypal.SenderBatchHeader{ SenderBatchID: withdID, } item := make([]paypal.PayoutItem, 1) fmt.Println(amount) item[0] = paypal.PayoutItem{ RecipientType: "EMAIL", Receiver: paypalName, Amount: &paypal.AmountPayout{ Currency: "USD", // 收款类型 Value: amount, // 收款数量 }, Note: "打款", } payout.SenderBatchHeader = send payout.Items = item fmt.Println(payout.Items[0].Amount) resp, err := c.CreateSinglePayout(payout) if err != nil { fmt.Println(err.Error()) fmt.Println(resp) return err, nil } return err, resp } // 生成24位订单号 // 前面17位代表时间精确到毫秒,中间3位代表进程id,最后4位代表序号 var num int64 func Generate() string { t := time.Now() s := t.Format(timeformat.Continuity) m := t.UnixNano()/1e6 - t.UnixNano()/1e9*1e3 ms := sup(m, 3) p := os.Getpid() % 1000 ps := sup(int64(p), 3) i := atomic.AddInt64(&num, 1) r := i % 10000 rs := sup(r, 4) n := fmt.Sprintf("%s%s%s%s", s, ms, ps, rs) return n } // 对长度不足n的数字前面补0 func sup(i int64, n int) string { m := fmt.Sprintf("%d", i) for len(m) < n { m = fmt.Sprintf("0%s", m) } return m } func GetOrderTotalList(info *request.SearchOrderList) (error, any) { var ( err error data model.OrderTotal ) if info.Code == "" { return errors.New("任务码不可为空"), nil } db := global.MG_DB.Model(&model.Order{}) if info.Status != 0 { db = db.Where("status=?", info.Status) } if info.Code != "" { db = db.Where("code=?", info.Code) } err = db.Select("sum(case when `status`=2 then 1 else 0 end) status2,sum(case when `status`=3 then 1 else 0 end) status3,sum(case when `status`=4 then 1 else 0 end) status4").Scan(&data).Error if err != nil { return errors.New("获取订单失败"), data } return nil, data } func GetMissionOrderStatistic(userId, claimNo string) (dto.MissionOrderStatistic, error) { var ( err error claim model.MissionClaim statistic model.DtStatisticOrder result dto.MissionOrderStatistic ) err, claim = getMissionClaim(userId, claimNo) if err != nil { return result, err } statistic, _ = getStatisticsOrderByValues([]string{}, "", "2", claimNo) visits := GetGoodsVisit(claimNo) result = dto.MissionOrderStatistic{ OrderNum: statistic.OrderNum, OrderDoneNum: statistic.OrderDoneNum, OrderMoney: statistic.OrderMoney, SettleReward: claim.RewardFinished, TransitReward: claim.RewardUnfinished, RewardRatio: 0.1, Uv: visits, SellNum: claim.AchieveNum, } result.OrderUserNum, _ = getOrderCount(userId, &request.SearchOrderList{Group: "user", Code: claimNo}) return result, nil } func getStatisticsOrder(value, unit, relationId string) (model.DtStatisticOrder, error) { var ( err error result model.DtStatisticOrder ) db := global.MG_DB.Model(&model.DtStatisticOrder{}).Where("`value` = ? AND `unit` = ?", value, unit) if relationId != "" { db = db.Where("`relation_id` = ?", relationId) } err = db.First(&result).Error return result, err } // 累计销量 "all","all","goods_id" // 30天销量 "day","30","goods_id" func GetStatisticsOrderByValues(unit string, value int, relationId string) (model.DtStatisticOrder, error) { if value < 0 { return model.DtStatisticOrder{}, errors.New("value error") } var values = make([]string, 0) now := time.Now() switch unit { case "day": if value == 0 { values = append(values, now.Format("20060102")) } else { tmp := now.AddDate(0, 0, -value) for i := 0; i < value; i++ { values = append(values, tmp.Format("20060102")) tmp = tmp.AddDate(0, 0, 1) } } case "month": } return getStatisticsOrderByValues(values, "day", "", relationId) } func getStatisticsOrderByValues(values []string, unit, t, relationId string) (model.DtStatisticOrder, error) { var ( err error result model.DtStatisticOrder ) db := global.MG_DB.Model(&model.DtStatisticOrder{}).Where("`unit` = ?", unit). Select("SUM(order_num) as order_num,SUM(order_done_num) as order_done_num,SUM(order_money) as order_money,SUM(sale_volume) as sale_volume,SUM(settle_reward) as settle_reward,SUM(order_cancel_num) as order_cancel_num,SUM(order_cancel_money) as order_cancel_money") if len(values) != 0 { db = db.Where("`value` IN (?) ", values) } if t != "" { db = db.Where("`type` = ?", t) } if relationId != "" { db = db.Where("`relation_id` = ?", relationId) } err = db.First(&result).Error return result, err } // 获取网红维度订单数据统计 func getStatisticsOrderInfluence(uuid, unit string, timeArea []string) (model.DtStatisticOrder, error) { var ( err error result model.DtStatisticOrder ) db := global.MG_DB.Model(&model.DtStatisticOrder{}).Joins("INNER JOIN mission_claim ON mission_claim.claim_no = dt_statistic_order.relation_id"). Where("dt_statistic_order.`type` = 2 AND mission_claim.create_by = ? AND dt_statistic_order.`unit` = ?", uuid, unit) if len(timeArea) == 2 { db = db.Where("dt_statistic_order.created_at >= ? AND dt_statistic_order.created_at < ?", timeArea[0], timeArea[1]) } err = db.Select("SUM(dt_statistic_order.order_num) as order_num,SUM(dt_statistic_order.order_done_num) as order_done_num,SUM(dt_statistic_order.order_money) as order_money,SUM(dt_statistic_order.sale_volume) as sale_volume,SUM(dt_statistic_order.settle_reward) as settle_reward,SUM(dt_statistic_order.order_cancel_num) as order_cancel_num,SUM(dt_statistic_order.order_cancel_money) as order_cancel_money").First(&result).Error return result, err } func GetGoodsVisit(claimNo string) (count int64) { global.MG_DB.Model(&model.GoodsVisit{}).Where("claim_no=?", claimNo).Count(&count) return count }