package haha import ( "crypto/tls" "encoding/json" "film/base/util" "film/model" "film/worker/common" "fmt" "github.com/go-co-op/gocron" log "github.com/sirupsen/logrus" "github.com/smbrave/goutil" "github.com/spf13/cast" "io" "net/http" "net/url" "strings" "time" ) type SyncOrderConfig struct { Token string NewOrder chan *model.Order UpdateOrder chan *model.Order SyncInterval int } type SyncOrder struct { token string syncInterval int newOrder chan *model.Order updateOrder chan *model.Order } func NewSyncOrder(cfg *SyncOrderConfig) *SyncOrder { return &SyncOrder{ token: cfg.Token, newOrder: cfg.NewOrder, updateOrder: cfg.UpdateOrder, syncInterval: goutil.If(cfg.SyncInterval == 0, 30, cfg.SyncInterval), } } func (s *SyncOrder) Sync() { timezone, _ := time.LoadLocation("Asia/Shanghai") cron := gocron.NewScheduler(timezone) cron.Every(s.syncInterval).Seconds().Do(func() { s.run() }) cron.StartAsync() } func (s *SyncOrder) run() { orderUrl := "https://hahapiao.cn/api/Synchro/pcToList" body, err := s.httpPost(orderUrl) if err != nil { log.Errorf("syncOrder error : %s", err.Error()) return } result := make(map[string]interface{}) if err := json.Unmarshal(body, &result); err != nil { log.Errorf("json.unmarshal [%s] error : %s", string(body), err.Error()) return } if cast.ToInt(result["status"]) != 200 || cast.ToInt(result["code"]) != 200 { log.Errorf("status[%d] code[%d] message[%s]", cast.ToInt(result["status"]), cast.ToInt(result["code"]), cast.ToString(result["msg"])) return } cipherText := cast.ToString(result["data"]) originText, err := common.Decrypt(cipherText, s.token) if err != nil { log.Errorf("common.Decrypt error :%s", err.Error()) return } var arrs []interface{} if err := json.Unmarshal([]byte(strings.Trim(originText, "\r\n\t ")), &arrs); err != nil { log.Errorf("json.Unmarshal error :%s", err.Error()) return } for _, d := range arrs { data := cast.ToStringMap(d) id := cast.ToInt64(data["id"]) order, err := model.GetOrder(id) if err != nil { log.Errorf("get order id : %d error :%s", id, err.Error()) } isAdd := false if order == nil { order = new(model.Order) order.Id = id isAdd = true } order.OrderNo = cast.ToString(data["order_id"]) order.PayPrice = int64(cast.ToFloat64(data["payPrice"]) * 100) order.TotalPrice = int64(cast.ToFloat64(data["total_price"]) * 100) order.MaoyanPrice = int64(cast.ToFloat64(data["maoyan_price"]) * 100) order.StartTime = cast.ToString(data["startTime"]) order.StartDate = cast.ToString(data["invalidateDate"]) order.SeatNum = cast.ToInt(data["seat_num"]) order.Seats = cast.ToString(data["seats"]) order.ShowTime = cast.ToInt64(data["show_time"]) order.PayTime = cast.ToInt64(data["pay_time"]) order.OrderCreateTime = cast.ToInt64(data["create_time"]) order.CityName = cast.ToString(data["cityName"]) order.ProvinceName = cast.ToString(data["provinceName"]) order.MovieName = cast.ToString(data["movieName"]) order.Address = cast.ToString(data["address"]) order.Ting = cast.ToString(data["ting"]) order.CinemaName = cast.ToString(data["cinemaName"]) order.CinemaBrand = util.CinemaBrand(order.CinemaName) order.Count = cast.ToInt(data["count"]) order.IsSeat = cast.ToInt(data["is_seat"]) order.LoverSeat = cast.ToInt(data["loverSeat"]) order.MinPrice = int64(cast.ToFloat64(data["minPrice"]) * 100) order.MaxPrice = int64(cast.ToFloat64(data["maxPrice"]) * 100) if isAdd { model.AddOrder(order) select { case s.newOrder <- order: default: log.Errorf("new order chan is full!") } log.Infof("add order :%s", order.OrderNo) } else { model.UpdateOrder(order) select { case s.updateOrder <- order: default: log.Errorf("update order chan is full!") } log.Infof("update order :%s", order.OrderNo) } } log.Infof("update/add order total:%d", len(arrs)) } func (s *SyncOrder) httpPost(requestUrl string) ([]byte, error) { client := &http.Client{Timeout: 20 * time.Second} //忽略https的证书 client.Transport = &http.Transport{ TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, } p := url.Values{} u, _ := url.Parse(requestUrl) u.RawQuery = p.Encode() req, err := http.NewRequest("POST", u.String(), nil) if err != nil { return nil, err } req.Header.Set("token", s.token) req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36") resp, err := client.Do(req) if err != nil { return nil, err } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { return nil, fmt.Errorf("%d:%s", resp.StatusCode, resp.Status) } return io.ReadAll(resp.Body) }