package bidding import ( "fmt" "git.rosy.net.cn/baseapi/platformapi/mtwmapi" "git.rosy.net.cn/baseapi/utils" "git.rosy.net.cn/jx-callback/business/model" "git.rosy.net.cn/jx-callback/business/model/dao" "git.rosy.net.cn/jx-callback/globals" "git.rosy.net.cn/jx-callback/globals/api" "sort" "strconv" "strings" "time" ) // GetStatisticsList 京西数据查询 func GetStatisticsList(start, end time.Time, storeIds []int, offset, pageSize int) (*model.PagedInfo, error) { return dao.GetStatistics(dao.GetDB(), start, end, storeIds, offset, pageSize) } // GetMTInfo 更新美团门店信息 func GetMTInfo() []error { var db = dao.GetDB() var errList = make([]error, 0, 0) // 获取当前一月有效订单的门店信息 effectiveStores, err := dao.StoreInformationStatistics(db) if err != nil { return append(errList, err) } var mtApi *mtwmapi.API for _, v := range effectiveStores { if v.VendorOrgCode == globals.Mtwm2Code { mtApi = api.Mtwm2API mtApi.SetToken(v.MtwmToken) } else { mtApi = api.MtwmAPI } statistics := &model.ActivityStation{ StoreID: v.JxStoreID, VendorID: model.VendorIDMTWM, VendorStoreID: v.VendorStoreID, BrandID: v.VendorOrgCode, //Activity1: 0, //Activity2: 0, //Activity: 0, //StoreSkuNum: 0, //StoreRating: 0, //DeliveryFee: "", //DeliveryFee2: "", PromotionFee: "暂无法获取", //BusinessHours: "", } dao.WrapAddIDCULEntity(statistics, "system") down, up := getActivityCount(mtApi, v.VendorStoreID) statistics.Activity1 = int64(down) statistics.Activity2 = int64(up) statistics.Activity = int64(down + up) score, err := mtApi.CommentScore(v.VendorStoreID) if err != nil { errList = append(errList, fmt.Errorf("%s获取评分错误:%s", v.VendorStoreID, err.Error())) } if score != nil { statistics.StoreRating = score.AvgPoiScore } else { statistics.StoreRating = 0 } // 获取门店营业时长 detail, _ := mtApi.PoiMGet([]string{v.VendorStoreID}) if detail != nil { statistics.BusinessHours, err = getStoreShippingTime(detail[0].ShippingTime) if err != nil { errList = append(errList, fmt.Errorf("%s获取营业时长错误:%s", v.VendorStoreID, err.Error())) statistics.BusinessHours = err.Error() } statistics.DeliveryFee2 = utils.Float64ToStr(detail[0].ShippingFee) } // 获取门店起送价 result, err := mtApi.ShippingList(v.VendorStoreID) if err != nil { errList = append(errList, fmt.Errorf("%s获取起送价错误:%s", v.VendorStoreID, err.Error())) statistics.DeliveryFee = err.Error() } shippingList := make([]ShippingList, 0, 0) for _, v2 := range result { shippingList = append(shippingList, ShippingList{ TimeRange: utils.Interface2String(v2["time_range"]), MinPrice: utils.MustInterface2Float64(v2["min_price"]), ShippingFee: utils.MustInterface2Float64(v2["shipping_fee"]), }) } statistics.DeliveryFee = utils.Format4Output(shippingList, false) dao.CreateEntity(db, statistics) } return errList } // 获取门店折扣活动商品数量 func getActivityCount(api *mtwmapi.API, vendorStoreId string) (int, int) { threefoldDown := 0 // 0-3 折活动数量 threefoldUp := 0 // 3.01-9 折活动 // 获取美团活动 directList, _ := api.RetailDiscountList(vendorStoreId, mtwmapi.RetailActTypeDirectDown) // 折扣活动 for _, v := range directList { if v.ActPrice/v.OriginalPrice >= 3.01 { threefoldUp++ } else { threefoldDown++ } } secKillList, _ := api.RetailDiscountList(vendorStoreId, mtwmapi.RetailActTypeSecKill) // 爆品活动 if secKillList != nil { threefoldDown = threefoldDown + len(secKillList) } return threefoldDown, threefoldUp } func getStoreShippingTime(storeTime string) (string, error) { time2 := strings.Split(storeTime, ";") aa := int(time.Now().Weekday()) if aa == 0 { aa = 7 } if len(time2) == 1 { aa = 1 } intervals, err := parseIntervals(time2[aa-1]) if err != nil { fmt.Printf("解析错误: %v\n", err) return "", err } merged := mergeIntervals(intervals) totalMinutes := 0 for _, iv := range merged { totalMinutes += iv.end - iv.start } return fmt.Sprintf("%.2f", float64(totalMinutes)/float64(60)), err } // timeToMinutes 将 "HH:MM" 转为当天第几分钟(0 ~ 1439) func timeToMinutes(t string) (int, error) { parts := strings.Split(t, ":") if len(parts) != 2 { return 0, fmt.Errorf("invalid time format: %s", t) } h, err := strconv.Atoi(parts[0]) if err != nil || h < 0 || h > 23 { return 0, fmt.Errorf("invalid hour in %s", t) } m, err := strconv.Atoi(parts[1]) if err != nil || m < 0 || m > 59 { return 0, fmt.Errorf("invalid minute in %s", t) } return h*60 + m, nil } // parseIntervals 解析 "00:00-01:00,01:05-23:59" → []interval type interval struct { start, end int // minutes since 00:00 } func parseIntervals(s string) ([]interval, error) { var intervals []interval for _, seg := range strings.Split(s, ",") { seg = strings.TrimSpace(seg) if seg == "" { continue } parts := strings.Split(seg, "-") if len(parts) != 2 { return nil, fmt.Errorf("invalid interval format: %s", seg) } startMins, err := timeToMinutes(strings.TrimSpace(parts[0])) if err != nil { return nil, err } endMins, err := timeToMinutes(strings.TrimSpace(parts[1])) if err != nil { return nil, err } if startMins > endMins { return nil, fmt.Errorf("start after end in interval: %s", seg) } intervals = append(intervals, interval{start: startMins, end: endMins}) } return intervals, nil } // mergeIntervals 合并重叠/相邻区间(如 [0,60], [65,1439] → 保留两个;若 [0,60], [60,120] → 可合并为 [0,120]) func mergeIntervals(ints []interval) []interval { if len(ints) == 0 { return ints } // 排序 sort.Slice(ints, func(i, j int) bool { return ints[i].start < ints[j].start }) merged := make([]interval, 0, len(ints)) curr := ints[0] for i := 1; i < len(ints); i++ { if ints[i].start <= curr.end { // 重叠或紧邻(如 end=60, next.start=60 → 合并) if ints[i].end > curr.end { curr.end = ints[i].end } } else { merged = append(merged, curr) curr = ints[i] } } merged = append(merged, curr) return merged } type ShippingList struct { TimeRange string `json:"time_range"` // 配送生效时间范围 MinPrice float64 `json:"min_price"` // 最小起送价 ShippingFee float64 `json:"shipping_fee"` // 配送费 }