mirror of http://gitlab.batiao8.com/yic/film.git
sync
This commit is contained in:
parent
9515fdd61a
commit
603f72e657
|
@ -0,0 +1,84 @@
|
||||||
|
package httputil
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"crypto/tls"
|
||||||
|
"fmt"
|
||||||
|
"github.com/spf13/cast"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func HttpPostForm(requestUrl string, header map[string]interface{}, forms map[string]interface{}) ([]byte, error) {
|
||||||
|
client := &http.Client{Timeout: 20 * time.Second}
|
||||||
|
|
||||||
|
client.Transport = &http.Transport{
|
||||||
|
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
||||||
|
}
|
||||||
|
values := url.Values{}
|
||||||
|
if forms != nil {
|
||||||
|
for k, v := range forms {
|
||||||
|
values.Set(k, cast.ToString(v))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
req, err := http.NewRequest("POST", requestUrl, bytes.NewBufferString(values.Encode()))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if header != nil {
|
||||||
|
for k, v := range header {
|
||||||
|
req.Header.Set(k, cast.ToString(v))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
// PostJson 请求
|
||||||
|
func HttpPostJson(link string, params map[string]interface{}, header map[string]interface{}, json []byte) ([]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(link)
|
||||||
|
if params != nil {
|
||||||
|
for k, v := range params {
|
||||||
|
p.Set(k, cast.ToString(v))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
u.RawQuery = p.Encode()
|
||||||
|
req, err := http.NewRequest("POST", u.String(), bytes.NewBuffer(json))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
req.Header.Add("Content-Type", "application/json")
|
||||||
|
if header != nil {
|
||||||
|
for k, v := range header {
|
||||||
|
req.Header.Add(k, cast.ToString(v))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
|
@ -1 +1,7 @@
|
||||||
package util
|
package util
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
func MoneyFen(money int64) string {
|
||||||
|
return fmt.Sprintf("%.2f", float64(money)/100)
|
||||||
|
}
|
||||||
|
|
22
cmd/film.go
22
cmd/film.go
|
@ -55,24 +55,6 @@ func main() {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
dadiProcessor := &worker.Dadi{
|
work := &worker.Worker{}
|
||||||
Token: cfg.Film.DadiToken,
|
work.Run()
|
||||||
}
|
|
||||||
if err := dadiProcessor.Init(); err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
orderWorker := &worker.Orders{
|
|
||||||
Token: config.GetConfig().Film.HahaToken,
|
|
||||||
Dadi: dadiProcessor,
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := orderWorker.Init(); err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
order, _ := model.GetOrder(582589)
|
|
||||||
|
|
||||||
dadiProcessor.NewOrder(order)
|
|
||||||
select {}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,4 +18,4 @@ qiye_agent = "1000013"
|
||||||
|
|
||||||
[film]
|
[film]
|
||||||
haha_token = "cc5f1d4c36f7e9544d641a174b298f94"
|
haha_token = "cc5f1d4c36f7e9544d641a174b298f94"
|
||||||
dadi_token = "321566:b891effb-5493-4f26-ac54-bfa5581ca8c3"
|
dadi_token = "321566:7b84a0b1-832a-4492-a96a-23002d6c8715"
|
|
@ -19,4 +19,5 @@ qiye_agent = "1000013"
|
||||||
|
|
||||||
[film]
|
[film]
|
||||||
haha_token = "cc5f1d4c36f7e9544d641a174b298f94"
|
haha_token = "cc5f1d4c36f7e9544d641a174b298f94"
|
||||||
dadi_token = "321566:b891effb-5493-4f26-ac54-bfa5581ca8c3"
|
dadi_token = "321566:7b84a0b1-832a-4492-a96a-23002d6c8715"
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
package common
|
||||||
|
|
||||||
|
import "film/model"
|
||||||
|
|
||||||
|
type CheckInfo struct {
|
||||||
|
TotalPrice int64
|
||||||
|
UnitPrice int64
|
||||||
|
BillCode string
|
||||||
|
}
|
||||||
|
|
||||||
|
type OrderInfo struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
type Processor interface {
|
||||||
|
CheckOrder(*model.Order) (*CheckInfo, error)
|
||||||
|
CreateOrder(*model.Order) (*OrderInfo, error)
|
||||||
|
CancelOrder(*model.Order, *CheckInfo) error
|
||||||
|
}
|
258
worker/dadi.go
258
worker/dadi.go
|
@ -1,258 +0,0 @@
|
||||||
package worker
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"film/base/httputil"
|
|
||||||
"film/config"
|
|
||||||
"film/model"
|
|
||||||
"fmt"
|
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
"github.com/smbrave/goutil"
|
|
||||||
"github.com/spf13/cast"
|
|
||||||
"gitlab.com/jiangyong27/gobase/wxapi"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Dadi struct {
|
|
||||||
Token string
|
|
||||||
citys map[string]*DadiCity
|
|
||||||
qyClient *wxapi.WxQiye
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Dadi) Init() error {
|
|
||||||
cityUrl := "https://appapi.dadicinema.com/app-web/v1/web/cinema/cbticket/cbase/cityAndCinemaList"
|
|
||||||
|
|
||||||
params := d.getBaseParam(&DadiCinema{
|
|
||||||
Name: "大地影院(北京十里河铭泽店)",
|
|
||||||
Id: 118,
|
|
||||||
UnifiedCode: 11050621,
|
|
||||||
})
|
|
||||||
body, err := httputil.HttpGet(cityUrl, params, d.getBaseHeader())
|
|
||||||
if err != nil {
|
|
||||||
log.Errorf(" httputil.HttpGet url : %s error: %s", cityUrl, err.Error())
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
result, err := d.checkError(body)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
citys := make(map[string]*DadiCity)
|
|
||||||
datas := cast.ToSlice(result)
|
|
||||||
|
|
||||||
for _, d := range datas {
|
|
||||||
data := cast.ToStringMap(d)
|
|
||||||
|
|
||||||
cinemas := make([]*DadiCinema, 0)
|
|
||||||
for _, c := range cast.ToSlice(data["cinemas"]) {
|
|
||||||
cin := cast.ToStringMap(c)
|
|
||||||
cinema := new(DadiCinema)
|
|
||||||
cinema.Name = cast.ToString(cin["name"])
|
|
||||||
cinema.Address = cast.ToString(cin["address"])
|
|
||||||
cinema.Latitude = cast.ToString(cin["latitude"])
|
|
||||||
cinema.Longitude = cast.ToString(cin["longitude"])
|
|
||||||
cinema.CityId = cast.ToInt64(cin["cityId"])
|
|
||||||
cinema.UnifiedCode = cast.ToInt64(cin["unifiedCode"])
|
|
||||||
cinemas = append(cinemas, cinema)
|
|
||||||
}
|
|
||||||
cityInfo := cast.ToStringMap(data["cityInfo"])
|
|
||||||
city := new(DadiCity)
|
|
||||||
city.Name = cast.ToString(cityInfo["chName"])
|
|
||||||
city.ShortName = cast.ToString(cityInfo["shortName"])
|
|
||||||
city.CityId = cast.ToInt64(data["cityId"])
|
|
||||||
city.CityCode = cast.ToInt64(data["cityCode"])
|
|
||||||
city.Cinemas = cinemas
|
|
||||||
|
|
||||||
citys[city.ShortName] = city
|
|
||||||
}
|
|
||||||
|
|
||||||
d.citys = citys
|
|
||||||
log.Infof("load dadi citys : %d", len(d.citys))
|
|
||||||
|
|
||||||
cfg := config.GetConfig()
|
|
||||||
d.qyClient = wxapi.NewQiye(&wxapi.QiyeConfig{
|
|
||||||
Corpid: cfg.Weixin.QiyeAppid,
|
|
||||||
Secret: cfg.Weixin.Qiyesecret,
|
|
||||||
Sender: cfg.Weixin.QiyeAgent,
|
|
||||||
})
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Dadi) UpdateOrder(order *model.Order) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Dadi) NewOrder(order *model.Order) {
|
|
||||||
|
|
||||||
cinema, err := d.getCinema(order)
|
|
||||||
if err != nil {
|
|
||||||
log.Errorf("getcinema order : %s error : %s", goutil.EncodeJSON(order), err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
hall, err := d.getCinemaFilm(order, cinema)
|
|
||||||
if err != nil {
|
|
||||||
log.Errorf("getCinemaFilm order : %s error : %s", goutil.EncodeJSON(order), err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
dadiOrder, err := d.holdSeats(order, cinema, hall)
|
|
||||||
if err != nil {
|
|
||||||
log.Errorf("holdSeats order : %s error : %s", goutil.EncodeJSON(order), err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
message := make([]string, 0)
|
|
||||||
message = append(message, "【哈哈票订单信息】")
|
|
||||||
message = append(message, fmt.Sprintf("城市:%s", order.CityName))
|
|
||||||
message = append(message, fmt.Sprintf("影院:%s", order.CinemaName))
|
|
||||||
message = append(message, fmt.Sprintf("影厅:%s", order.Ting))
|
|
||||||
message = append(message, fmt.Sprintf("影片:%s", order.MovieName))
|
|
||||||
message = append(message, fmt.Sprintf("座位:%s,%s,%s", order.Seats,
|
|
||||||
goutil.If(order.IsSeat == 3, "可以调座", "不可调座"),
|
|
||||||
goutil.If(order.LoverSeat == 1, "情侣座", "普通座")))
|
|
||||||
message = append(message, fmt.Sprintf("订单编号:%s", order.OrderId))
|
|
||||||
message = append(message, fmt.Sprintf("订单金额:%.2f", float64(order.TotalPrice)/100))
|
|
||||||
message = append(message, fmt.Sprintf("原价:%.2f", float64(order.MaoyanPrice)/100))
|
|
||||||
message = append(message, fmt.Sprintf("报价范围:%.2f~%.2f", float64(order.MinPrice)/100, float64(order.MaxPrice)/100))
|
|
||||||
message = append(message, fmt.Sprintf("订单时间:%s", time.Unix(order.PayTime, 0).Format("2006-01-02 15:04")))
|
|
||||||
message = append(message, fmt.Sprintf("放映时间:%s", time.Unix(order.ShowTime, 0).Format("2006-01-02 15:04")))
|
|
||||||
message = append(message, "\n")
|
|
||||||
message = append(message, "【大地订单信息】")
|
|
||||||
message = append(message, fmt.Sprintf("订单编号:%s", dadiOrder.OrderId))
|
|
||||||
if err := d.qyClient.SendText([]string{"jiangyong"}, strings.Join(message, "\n")); err != nil {
|
|
||||||
log.Errorf("send message error : %s", err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Dadi) checkError(body []byte) (interface{}, error) {
|
|
||||||
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 nil, err
|
|
||||||
}
|
|
||||||
if cast.ToInt(result["code"]) != 200 || cast.ToBool(result["success"]) != true {
|
|
||||||
log.Errorf("code[%d] message[%s]", cast.ToInt(result["code"]), cast.ToString(result["msg"]))
|
|
||||||
return nil, fmt.Errorf("code[%d] message[%s]", cast.ToInt(result["code"]), cast.ToString(result["msg"]))
|
|
||||||
}
|
|
||||||
|
|
||||||
return result["data"], nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Dadi) getBaseHeader() map[string]interface{} {
|
|
||||||
return map[string]interface{}{
|
|
||||||
"User-Agent": "apifox/1.0.0 (https://www.apifox.cn)",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Dadi) getBaseParam(cinema *DadiCinema) map[string]interface{} {
|
|
||||||
params := map[string]interface{}{
|
|
||||||
"channelCode": "SYH-DDZY-DD",
|
|
||||||
"channelName": "大地自营-大地",
|
|
||||||
"channelNo": "SYH-DDZY-DD",
|
|
||||||
"channelUid": "SYH-DDZY-DD",
|
|
||||||
"cinema": cast.ToString(cinema.UnifiedCode),
|
|
||||||
"cinemaCode": cast.ToString(cinema.UnifiedCode),
|
|
||||||
"cinemaUid": cast.ToString(cinema.Id),
|
|
||||||
"d": "iPhone14,3",
|
|
||||||
"i": "00000000-0000-0000-0000-000000000000",
|
|
||||||
"k": d.Token,
|
|
||||||
"r": "1",
|
|
||||||
"s": "iOS15.2.1",
|
|
||||||
"t": "1",
|
|
||||||
"tenantId": "321566",
|
|
||||||
"unifiedCinemaId": cast.ToString(cinema.Id),
|
|
||||||
"unifiedCinemaName": cinema.Name,
|
|
||||||
"unifiedCode": cast.ToString(cinema.UnifiedCode),
|
|
||||||
"v": "8.7.3",
|
|
||||||
}
|
|
||||||
return params
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Dadi) getCinema(order *model.Order) (*DadiCinema, error) {
|
|
||||||
if _, ok := d.citys[order.CityName]; !ok {
|
|
||||||
log.Errorf("city[%s] not exist dadi cinema", order.CityName)
|
|
||||||
return nil, fmt.Errorf("city[%s] not exist dadi cinema", order.CityName)
|
|
||||||
}
|
|
||||||
city := d.citys[order.CityName]
|
|
||||||
for _, cinema := range city.Cinemas {
|
|
||||||
if cinema.Name != order.CinemaName {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
return cinema, nil
|
|
||||||
}
|
|
||||||
return nil, fmt.Errorf("city[%s] not[%s]", order.CityName, order.CinemaName)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Dadi) getCinemaFilm(order *model.Order, cinema *DadiCinema) (*DadiFilmShowHall, error) {
|
|
||||||
baseReq := d.getBaseParam(cinema)
|
|
||||||
reqUrl := "https://appapi.dadicinema.com/app-web/v1/web/film/getHitFilmAndFilmSession"
|
|
||||||
body, err := httputil.HttpGet(reqUrl, baseReq, d.getBaseHeader())
|
|
||||||
if err != nil {
|
|
||||||
log.Errorf("httpGet[%s] error : %s", reqUrl, err.Error())
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
result, err := d.checkError(body)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
orderShowDay := time.Unix(order.ShowTime, 0).Format("2006-01-02")
|
|
||||||
var hall *DadiFilmShowHall = nil
|
|
||||||
for _, f := range cast.ToSlice(cast.ToStringMap(result)["filmList"]) {
|
|
||||||
ff := cast.ToStringMap(f)
|
|
||||||
filmName := cast.ToString(ff["name"])
|
|
||||||
if filmName != order.MovieName {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
for _, s := range cast.ToSlice(ff["showList"]) {
|
|
||||||
ss := cast.ToStringMap(s)
|
|
||||||
showDay := cast.ToString(ss["dayStr"])
|
|
||||||
if showDay != orderShowDay {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
for _, p := range cast.ToSlice(ss["plist"]) {
|
|
||||||
pp := cast.ToStringMap(p)
|
|
||||||
hallName := cast.ToString(pp["hallName"])
|
|
||||||
if hallName != order.Ting {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
hall = new(DadiFilmShowHall)
|
|
||||||
hall.FilmName = filmName
|
|
||||||
hall.ShowDay = showDay
|
|
||||||
hall.HallName = cast.ToString(pp["hallName"])
|
|
||||||
hall.SessionId = cast.ToString(pp["sessionId"])
|
|
||||||
hall.StartTime = cast.ToString(pp["startTime"])
|
|
||||||
hall.EndTime = cast.ToString(pp["endTime"])
|
|
||||||
return hall, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
return nil, fmt.Errorf("film[%s] day[%s] ting[%s] nohas", order.MovieName, orderShowDay, order.Ting)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Dadi) getCinemaSeats(order *model.Order, cinema *DadiCinema, hall *DadiFilmShowHall) error {
|
|
||||||
baseReq := d.getBaseParam(cinema)
|
|
||||||
baseReq["sessionId"] = hall.SessionId
|
|
||||||
reqUrl := "https://appapi.dadicinema.com/app-web/v1/web/cinema/cbticket/cticket/getSessionSeat"
|
|
||||||
body, err := httputil.HttpGet(reqUrl, baseReq, d.getBaseHeader())
|
|
||||||
if err != nil {
|
|
||||||
log.Errorf("http get url: %s, error: %s", reqUrl, err.Error())
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
_, err = d.checkError(body)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
//baseReq := d.getBaseParam(cinema)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Dadi) holdSeats(order *model.Order, cinema *DadiCinema, hall *DadiFilmShowHall) (*DadiFilmOrder, error) {
|
|
||||||
return &DadiFilmOrder{
|
|
||||||
OrderId: "test",
|
|
||||||
}, nil
|
|
||||||
}
|
|
|
@ -0,0 +1,332 @@
|
||||||
|
package dadi
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"film/base/httputil"
|
||||||
|
"film/base/util"
|
||||||
|
"film/model"
|
||||||
|
"film/worker/common"
|
||||||
|
"fmt"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
"github.com/smbrave/goutil"
|
||||||
|
"github.com/spf13/cast"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ProcessorConfig struct {
|
||||||
|
Token string
|
||||||
|
}
|
||||||
|
|
||||||
|
type Processor struct {
|
||||||
|
token string
|
||||||
|
citys map[string]*City
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewProcessor(cfg *ProcessorConfig) (common.Processor, error) {
|
||||||
|
processor := &Processor{
|
||||||
|
token: cfg.Token,
|
||||||
|
}
|
||||||
|
if err := processor.init(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return processor, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Processor) init() error {
|
||||||
|
cityUrl := "https://appapi.dadicinema.com/app-web/v1/web/cinema/cbticket/cbase/cityAndCinemaList"
|
||||||
|
|
||||||
|
params := d.getBaseParam(&Cinema{
|
||||||
|
Name: "大地影院(北京十里河铭泽店)",
|
||||||
|
Id: 118,
|
||||||
|
UnifiedCode: 11050621,
|
||||||
|
})
|
||||||
|
body, err := httputil.HttpGet(cityUrl, params, d.getBaseHeader())
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf(" httputil.HttpGet url : %s error: %s", cityUrl, err.Error())
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
result, err := d.checkError(body)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
citys := make(map[string]*City)
|
||||||
|
datas := cast.ToSlice(result)
|
||||||
|
|
||||||
|
for _, d := range datas {
|
||||||
|
data := cast.ToStringMap(d)
|
||||||
|
|
||||||
|
cinemas := make([]*Cinema, 0)
|
||||||
|
for _, c := range cast.ToSlice(data["cinemas"]) {
|
||||||
|
cin := cast.ToStringMap(c)
|
||||||
|
cinema := new(Cinema)
|
||||||
|
cinema.Name = cast.ToString(cin["name"])
|
||||||
|
cinema.Address = cast.ToString(cin["address"])
|
||||||
|
cinema.Latitude = cast.ToString(cin["latitude"])
|
||||||
|
cinema.Longitude = cast.ToString(cin["longitude"])
|
||||||
|
cinema.CityId = cast.ToInt64(cin["cityId"])
|
||||||
|
cinema.UnifiedCode = cast.ToInt64(cin["unifiedCode"])
|
||||||
|
cinemas = append(cinemas, cinema)
|
||||||
|
}
|
||||||
|
cityInfo := cast.ToStringMap(data["cityInfo"])
|
||||||
|
city := new(City)
|
||||||
|
city.Name = cast.ToString(cityInfo["chName"])
|
||||||
|
city.ShortName = cast.ToString(cityInfo["shortName"])
|
||||||
|
city.CityId = cast.ToInt64(data["cityId"])
|
||||||
|
city.CityCode = cast.ToInt64(data["cityCode"])
|
||||||
|
city.Cinemas = cinemas
|
||||||
|
|
||||||
|
citys[city.ShortName] = city
|
||||||
|
}
|
||||||
|
|
||||||
|
d.citys = citys
|
||||||
|
log.Infof("load dadi procoessor citys : %d", len(d.citys))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Processor) checkError(body []byte) (interface{}, error) {
|
||||||
|
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 nil, err
|
||||||
|
}
|
||||||
|
if cast.ToInt(result["code"]) != 200 {
|
||||||
|
log.Errorf("code[%d] message[%s]", cast.ToInt(result["code"]), cast.ToString(result["msg"]))
|
||||||
|
return nil, fmt.Errorf("code[%d] message[%s]", cast.ToInt(result["code"]), cast.ToString(result["msg"]))
|
||||||
|
}
|
||||||
|
|
||||||
|
return result["data"], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Processor) getBaseHeader() map[string]interface{} {
|
||||||
|
return map[string]interface{}{
|
||||||
|
"User-Agent": "DaDiCinemaApp/8.7.3 (iPhone; iOS 15.2.1; Scale/3.00)",
|
||||||
|
"c-User-Token": d.token,
|
||||||
|
"c-tenantId": strings.Split(d.token, ":")[0],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Processor) getBaseParam(cinema *Cinema) map[string]interface{} {
|
||||||
|
params := map[string]interface{}{
|
||||||
|
"channelCode": "SYH-DDZY-DD",
|
||||||
|
"channelName": "大地自营-大地",
|
||||||
|
"channelNo": "SYH-DDZY-DD",
|
||||||
|
"channelUid": "SYH-DDZY-DD",
|
||||||
|
"cinema": cast.ToString(cinema.UnifiedCode),
|
||||||
|
"cinemaCode": cast.ToString(cinema.UnifiedCode),
|
||||||
|
"cinemaUid": cast.ToString(cinema.Id),
|
||||||
|
"d": "iPhone14,3",
|
||||||
|
"i": "00000000-0000-0000-0000-000000000000",
|
||||||
|
"k": p.token,
|
||||||
|
"r": "1",
|
||||||
|
"s": "iOS15.2.1",
|
||||||
|
"t": "1",
|
||||||
|
"tenantId": "321566",
|
||||||
|
"unifiedCinemaId": cast.ToString(cinema.Id),
|
||||||
|
"unifiedCinemaName": cinema.Name,
|
||||||
|
"unifiedCode": cast.ToString(cinema.UnifiedCode),
|
||||||
|
"v": "8.7.3",
|
||||||
|
}
|
||||||
|
return params
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Processor) getCinema(cityName, cinemaName string) (*Cinema, error) {
|
||||||
|
if _, ok := p.citys[cityName]; !ok {
|
||||||
|
log.Errorf("city[%s] not exist dadi cinema", cityName)
|
||||||
|
return nil, fmt.Errorf("city[%s] not exist dadi cinema", cityName)
|
||||||
|
}
|
||||||
|
city := p.citys[cityName]
|
||||||
|
for _, cinema := range city.Cinemas {
|
||||||
|
if cinema.Name != cinemaName {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
return cinema, nil
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("city[%s] not[%s]", cityName, cinemaName)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Processor) getCinemaFilmShowHall(cinema *Cinema, filmName, startTime, hallName string) (*FilmShowHall, error) {
|
||||||
|
baseReq := d.getBaseParam(cinema)
|
||||||
|
reqUrl := "https://appapi.dadicinema.com/app-web/v1/web/film/getHitFilmAndFilmSession"
|
||||||
|
body, err := httputil.HttpGet(reqUrl, baseReq, d.getBaseHeader())
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("httpGet[%s] error : %s", reqUrl, err.Error())
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
result, err := d.checkError(body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var hall *FilmShowHall = nil
|
||||||
|
for _, f := range cast.ToSlice(cast.ToStringMap(result)["filmList"]) {
|
||||||
|
ff := cast.ToStringMap(f)
|
||||||
|
moveName := cast.ToString(ff["name"])
|
||||||
|
if moveName != filmName {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
for _, s := range cast.ToSlice(ff["showList"]) {
|
||||||
|
ss := cast.ToStringMap(s)
|
||||||
|
day := cast.ToString(ss["dayStr"])
|
||||||
|
for _, p := range cast.ToSlice(ss["plist"]) {
|
||||||
|
pp := cast.ToStringMap(p)
|
||||||
|
hName := cast.ToString(pp["hallName"])
|
||||||
|
sTime := cast.ToString(pp["startTime"])
|
||||||
|
if startTime != sTime || hName != hallName {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
hall = new(FilmShowHall)
|
||||||
|
hall.FilmName = filmName
|
||||||
|
hall.ShowDay = day
|
||||||
|
hall.HallName = cast.ToString(pp["hallName"])
|
||||||
|
hall.SessionId = cast.ToString(pp["sessionId"])
|
||||||
|
hall.StartTime = cast.ToString(pp["startTime"])
|
||||||
|
hall.EndTime = cast.ToString(pp["endTime"])
|
||||||
|
return hall, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("film[%s] startTime[%s] ting[%s] nohas", filmName, startTime, hallName)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Processor) getSeatGoods(cinema *Cinema, sessionId, seats string) ([]*SeatGoods, error) {
|
||||||
|
baseReq := p.getBaseParam(cinema)
|
||||||
|
baseReq["sessionId"] = sessionId
|
||||||
|
reqUrl := "https://appapi.dadicinema.com/app-web/v1/web/cinema/cbticket/cticket/getSessionSeat"
|
||||||
|
body, err := httputil.HttpGet(reqUrl, baseReq, p.getBaseHeader())
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("http get url: %s, error: %s", reqUrl, err.Error())
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
data, err := p.checkError(body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
existMap := make(map[string]bool)
|
||||||
|
for _, s := range strings.Split(seats, "|") {
|
||||||
|
existMap[s] = true
|
||||||
|
}
|
||||||
|
|
||||||
|
allSeatGoods := make([]*SeatGoods, 0)
|
||||||
|
for _, s := range cast.ToSlice(cast.ToStringMap(data)["seats"]) {
|
||||||
|
seat := cast.ToStringMap(s)
|
||||||
|
key := fmt.Sprintf("%d:%d", cast.ToInt(seat["phyRowId"]), cast.ToInt(seat["phyColId"]))
|
||||||
|
if _, ok := existMap[key]; !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
areanInfo := cast.ToStringMap(seat["areaInfo"])
|
||||||
|
ticketPriceInfo := cast.ToStringMap(areanInfo["ticketPriceInfo"])
|
||||||
|
seatGoods := new(SeatGoods)
|
||||||
|
seatGoods.SeatCode = cast.ToString(seat["seatCode"])
|
||||||
|
seatGoods.PlanCode = sessionId
|
||||||
|
seatGoods.LevelCode = ""
|
||||||
|
seatGoods.StandPrice = cast.ToString(ticketPriceInfo["standPrice"])
|
||||||
|
seatGoods.AddPrice = fmt.Sprintf("%.2f", cast.ToFloat64(ticketPriceInfo["addPrice"]))
|
||||||
|
seatGoods.ServiceFee = fmt.Sprintf("%.2f", cast.ToFloat64(ticketPriceInfo["servicePrice"]))
|
||||||
|
seatGoods.PlatServiceFee = fmt.Sprintf("%.2f", cast.ToFloat64(ticketPriceInfo["platServicePrice"]))
|
||||||
|
allSeatGoods = append(allSeatGoods, seatGoods)
|
||||||
|
}
|
||||||
|
return allSeatGoods, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Processor) prevOrderInfo(cinema *Cinema, seatGoods []*SeatGoods) (*PreviewOrder, error) {
|
||||||
|
// 座位下单
|
||||||
|
reqUrl := "https://appapi.dadicinema.com/app-web/v1/web/order/trade/order/ticket"
|
||||||
|
baseReq := p.getBaseParam(cinema)
|
||||||
|
baseReq["seatGoodsAddList"] = seatGoods
|
||||||
|
baseReq["existsAreasPrice"] = false
|
||||||
|
baseReq["phoneNo"] = "17610351227"
|
||||||
|
reqBody := goutil.EncodeJSON(baseReq)
|
||||||
|
baseHeader := p.getBaseHeader()
|
||||||
|
baseHeader["Cookie"] = "HWWAFSESID=d527bdc7a4a18b8e40; HWWAFSESTIME=1680956218712"
|
||||||
|
body, err := httputil.HttpPostJson(reqUrl, nil, baseHeader, []byte(reqBody))
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("httpPost url[%s] error : %s", reqUrl, err.Error())
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
data, err := p.checkError(body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
billCode := cast.ToString(data)
|
||||||
|
|
||||||
|
// 计算价格
|
||||||
|
reqUrl = "https://appapi.dadicinema.com/app-web/v1/web/order/newPriceCalculate"
|
||||||
|
baseReq = p.getBaseParam(cinema)
|
||||||
|
baseReq["billCode"] = billCode
|
||||||
|
baseReq["firstPriceCalculateFlag"] = 1
|
||||||
|
reqBody = goutil.EncodeJSON(baseReq)
|
||||||
|
body, err = httputil.HttpPostJson(reqUrl, nil, p.getBaseHeader(), []byte(reqBody))
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("httpPost url[%s] error : %s", reqUrl, err.Error())
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
data, err = p.checkError(body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
totalRealPrice := cast.ToFloat64(cast.ToStringMap(data)["totalRealPrice"])
|
||||||
|
|
||||||
|
previewOrder := new(PreviewOrder)
|
||||||
|
previewOrder.TotalPrice = int64(totalRealPrice * 100)
|
||||||
|
previewOrder.BillCode = billCode
|
||||||
|
|
||||||
|
return previewOrder, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Processor) CheckOrder(order *model.Order) (*common.CheckInfo, error) {
|
||||||
|
cinema, err := p.getCinema(order.CityName, order.CinemaName)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
showHall, err := p.getCinemaFilmShowHall(cinema, order.MovieName, goutil.TimeToDateTime(order.ShowTime), order.Ting)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
seatGoods, err := p.getSeatGoods(cinema, showHall.SessionId, order.Seats)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
previewOrder, err := p.prevOrderInfo(cinema, seatGoods)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
result := new(common.CheckInfo)
|
||||||
|
result.UnitPrice = previewOrder.TotalPrice / int64(order.SeatNum)
|
||||||
|
result.TotalPrice = previewOrder.TotalPrice
|
||||||
|
result.BillCode = previewOrder.BillCode
|
||||||
|
log.Infof("check order[%s][%s] totalPrice[%s] [%s][%s][%s] success",
|
||||||
|
order.OrderId, result.BillCode, util.MoneyFen(previewOrder.TotalPrice),
|
||||||
|
order.CityName, order.CinemaName, order.MovieName)
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Processor) CreateOrder(*model.Order) (*common.OrderInfo, error) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Processor) CancelOrder(order *model.Order, checkInfo *common.CheckInfo) error {
|
||||||
|
cinema, err := p.getCinema(order.CityName, order.CinemaName)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
reqUrl := "https://appapi.dadicinema.com/app-web/v1/web/order/cancel"
|
||||||
|
baseReq := p.getBaseParam(cinema)
|
||||||
|
baseReq["billCode"] = checkInfo.BillCode
|
||||||
|
|
||||||
|
body, err := httputil.HttpPostJson(reqUrl, nil, p.getBaseHeader(), []byte(goutil.EncodeJSON(baseReq)))
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("http request url[%s] error[%s]", reqUrl, err.Error())
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = p.checkError(body)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
log.Infof("cancel order[%s][%s] [%s][%s][%s] success",
|
||||||
|
order.OrderId, checkInfo.BillCode, order.CityName, order.CinemaName, order.MovieName)
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
package dadi
|
||||||
|
|
||||||
|
type PreviewOrder struct {
|
||||||
|
BillCode string
|
||||||
|
TotalPrice int64
|
||||||
|
}
|
||||||
|
|
||||||
|
type SeatGoods struct {
|
||||||
|
StandPrice string `json:"standPrice"`
|
||||||
|
SeatCode string `json:"seatCode"`
|
||||||
|
PlanCode string `json:"planCode"`
|
||||||
|
LevelCode string `json:"levelCode"`
|
||||||
|
AddPrice string `json:"addPrice"`
|
||||||
|
PlatServiceFee string `json:"platServiceFee"`
|
||||||
|
ServiceFee string `json:"serviceFee"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type FilmShowHall struct {
|
||||||
|
ShowDay string
|
||||||
|
FilmName string
|
||||||
|
HallName string
|
||||||
|
StartTime string
|
||||||
|
EndTime string
|
||||||
|
SessionId string
|
||||||
|
}
|
||||||
|
|
||||||
|
type Cinema struct {
|
||||||
|
Id int64
|
||||||
|
UnifiedCode int64
|
||||||
|
Name string
|
||||||
|
Address string
|
||||||
|
Latitude string
|
||||||
|
Longitude string
|
||||||
|
CityId int64
|
||||||
|
}
|
||||||
|
|
||||||
|
type City struct {
|
||||||
|
Name string
|
||||||
|
ShortName string
|
||||||
|
CityCode int64
|
||||||
|
CityId int64
|
||||||
|
Cinemas []*Cinema
|
||||||
|
}
|
|
@ -0,0 +1,58 @@
|
||||||
|
package haha
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"film/base/httputil"
|
||||||
|
"fmt"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
"github.com/spf13/cast"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ProcessorConfig struct {
|
||||||
|
Token string
|
||||||
|
}
|
||||||
|
type Processor struct {
|
||||||
|
token string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewProcessor(cfg *ProcessorConfig) *Processor {
|
||||||
|
return &Processor{
|
||||||
|
token: cfg.Token,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Processor) checkError(body []byte) (interface{}, error) {
|
||||||
|
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 nil, err
|
||||||
|
}
|
||||||
|
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 nil, fmt.Errorf("%d:%s", cast.ToInt(result["code"]), cast.ToString(result["msg"]))
|
||||||
|
}
|
||||||
|
return result["data"], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Processor) BidPrice(id int64, price int64) error {
|
||||||
|
reqUrl := "https://hahapiao.cn/api/Synchro/toPrice"
|
||||||
|
params := map[string]interface{}{
|
||||||
|
"id": cast.ToString(id),
|
||||||
|
"price": fmt.Sprintf("%.2f", float64(price)/100),
|
||||||
|
}
|
||||||
|
header := map[string]interface{}{
|
||||||
|
"token": p.token,
|
||||||
|
}
|
||||||
|
body, err := httputil.HttpPostForm(reqUrl, header, params)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("httpPost error : %s", err.Error())
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = p.checkError(body)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package worker
|
package haha
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
|
@ -11,57 +11,43 @@ import (
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strings"
|
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Orders struct {
|
type SyncOrderConfig struct {
|
||||||
Token string
|
Token string
|
||||||
Dadi *Dadi
|
NewOrder chan *model.Order
|
||||||
|
UpdateOrder chan *model.Order
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *Orders) Init() error {
|
type SyncOrder struct {
|
||||||
|
token string
|
||||||
|
newOrder chan *model.Order
|
||||||
|
updateOrder chan *model.Order
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewSyncOrder(cfg *SyncOrderConfig) *SyncOrder {
|
||||||
|
return &SyncOrder{
|
||||||
|
token: cfg.Token,
|
||||||
|
newOrder: cfg.NewOrder,
|
||||||
|
updateOrder: cfg.UpdateOrder,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SyncOrder) Sync() {
|
||||||
timezone, _ := time.LoadLocation("Asia/Shanghai")
|
timezone, _ := time.LoadLocation("Asia/Shanghai")
|
||||||
cron := gocron.NewScheduler(timezone)
|
cron := gocron.NewScheduler(timezone)
|
||||||
|
|
||||||
cron.Every(30).Seconds().Do(func() {
|
cron.Every(30).Seconds().Do(func() {
|
||||||
w.syncOrder()
|
s.run()
|
||||||
})
|
})
|
||||||
|
|
||||||
cron.StartAsync()
|
cron.StartAsync()
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *Orders) httpPost(requestUrl string) ([]byte, error) {
|
func (s *SyncOrder) run() {
|
||||||
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", w.Token)
|
|
||||||
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *Orders) syncOrder() {
|
|
||||||
orderUrl := "https://hahapiao.cn/api/Synchro/toList"
|
orderUrl := "https://hahapiao.cn/api/Synchro/toList"
|
||||||
body, err := w.httpPost(orderUrl)
|
body, err := s.httpPost(orderUrl)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("syncOrder error : %s", err.Error())
|
log.Errorf("syncOrder error : %s", err.Error())
|
||||||
return
|
return
|
||||||
|
@ -116,15 +102,46 @@ func (w *Orders) syncOrder() {
|
||||||
|
|
||||||
if isAdd {
|
if isAdd {
|
||||||
model.AddOrder(order)
|
model.AddOrder(order)
|
||||||
if strings.Contains(order.CinemaName, "大地影院") {
|
select {
|
||||||
w.Dadi.NewOrder(order)
|
case s.newOrder <- order:
|
||||||
|
default:
|
||||||
|
log.Errorf("new order chan is full!")
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
model.UpdateOrder(order)
|
model.UpdateOrder(order)
|
||||||
if strings.Contains(order.CinemaName, "大地影院") {
|
select {
|
||||||
w.Dadi.UpdateOrder(order)
|
case s.updateOrder <- order:
|
||||||
|
default:
|
||||||
|
log.Errorf("update order chan is full!")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
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)
|
||||||
}
|
}
|
|
@ -1,46 +0,0 @@
|
||||||
package worker
|
|
||||||
|
|
||||||
type DadiFilmShowHall struct {
|
|
||||||
ShowDay string
|
|
||||||
FilmName string
|
|
||||||
HallName string
|
|
||||||
StartTime string
|
|
||||||
EndTime string
|
|
||||||
SessionId string
|
|
||||||
}
|
|
||||||
|
|
||||||
type DadiFilmShow struct {
|
|
||||||
Day string
|
|
||||||
Halls []*DadiFilmShowHall
|
|
||||||
}
|
|
||||||
|
|
||||||
type DadiFilmOrder struct {
|
|
||||||
OrderId string
|
|
||||||
}
|
|
||||||
|
|
||||||
type DadiFilmSeat struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
type DadiFilm struct {
|
|
||||||
Id int64
|
|
||||||
Name string
|
|
||||||
Shows []*DadiFilmShow
|
|
||||||
}
|
|
||||||
|
|
||||||
type DadiCinema struct {
|
|
||||||
Id int64
|
|
||||||
UnifiedCode int64
|
|
||||||
Name string
|
|
||||||
Address string
|
|
||||||
Latitude string
|
|
||||||
Longitude string
|
|
||||||
CityId int64
|
|
||||||
}
|
|
||||||
|
|
||||||
type DadiCity struct {
|
|
||||||
Name string
|
|
||||||
ShortName string
|
|
||||||
CityCode int64
|
|
||||||
CityId int64
|
|
||||||
Cinemas []*DadiCinema
|
|
||||||
}
|
|
|
@ -0,0 +1,101 @@
|
||||||
|
package worker
|
||||||
|
|
||||||
|
import (
|
||||||
|
"film/base/util"
|
||||||
|
"film/config"
|
||||||
|
"film/model"
|
||||||
|
"film/worker/dadi"
|
||||||
|
"film/worker/haha"
|
||||||
|
"fmt"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
"github.com/smbrave/goutil"
|
||||||
|
"gitlab.com/jiangyong27/gobase/wxapi"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Worker struct {
|
||||||
|
qyClient *wxapi.WxQiye
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *Worker) initQyWeixin() {
|
||||||
|
cfg := config.GetConfig()
|
||||||
|
w.qyClient = wxapi.NewQiye(&wxapi.QiyeConfig{
|
||||||
|
Corpid: cfg.Weixin.QiyeAppid,
|
||||||
|
Secret: cfg.Weixin.Qiyesecret,
|
||||||
|
Sender: cfg.Weixin.QiyeAgent,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
func (w *Worker) Run() {
|
||||||
|
w.initQyWeixin()
|
||||||
|
cfg := config.GetConfig()
|
||||||
|
newOrderChan := make(chan *model.Order, 100000)
|
||||||
|
updateOrderChan := make(chan *model.Order, 100000)
|
||||||
|
hahaSyncer := haha.NewSyncOrder(&haha.SyncOrderConfig{
|
||||||
|
Token: cfg.Film.HahaToken,
|
||||||
|
NewOrder: newOrderChan,
|
||||||
|
UpdateOrder: updateOrderChan,
|
||||||
|
})
|
||||||
|
|
||||||
|
hahaSyncer.Sync()
|
||||||
|
|
||||||
|
//order, _ := model.GetOrder(590623)
|
||||||
|
//newOrderChan <- order
|
||||||
|
|
||||||
|
//hahaProcessor := haha.NewProcessor(&haha.ProcessorConfig{Token: cfg.Film.HahaToken})
|
||||||
|
dadiProcessor, err := dadi.NewProcessor(&dadi.ProcessorConfig{Token: cfg.Film.DadiToken})
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case order := <-newOrderChan:
|
||||||
|
if order.IsSeat == 2 || order.IsSeat == 1 {
|
||||||
|
w.qyClient.SendText([]string{"jiangyong"}, order.CinemaName+":"+order.MovieName)
|
||||||
|
}
|
||||||
|
if !strings.Contains(order.CinemaName, "大地影院") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
checkInfo, err := dadiProcessor.CheckOrder(order)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("check orrder[%s] error : %s", order.OrderId, err.Error())
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
//hahaProcessor.BidPrice(order.Id, checkInfo.UnitPrice)
|
||||||
|
go func() {
|
||||||
|
time.Sleep(60 * time.Second)
|
||||||
|
if err := dadiProcessor.CancelOrder(order, checkInfo); err != nil {
|
||||||
|
log.Errorf("cancel order[%s] error[%s]", order.OrderId, err.Error())
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
// 发送信息
|
||||||
|
message := make([]string, 0)
|
||||||
|
message = append(message, "【哈哈票订单信息】")
|
||||||
|
message = append(message, fmt.Sprintf("城市:%s", order.CityName))
|
||||||
|
message = append(message, fmt.Sprintf("影院:%s", order.CinemaName))
|
||||||
|
message = append(message, fmt.Sprintf("影厅:%s", order.Ting))
|
||||||
|
message = append(message, fmt.Sprintf("影片:%s", order.MovieName))
|
||||||
|
message = append(message, fmt.Sprintf("座位:%s,%s,%s", order.Seats,
|
||||||
|
goutil.If(order.IsSeat == 3, "可以调座", "不可调座"),
|
||||||
|
goutil.If(order.LoverSeat == 1, "情侣座", "普通座")))
|
||||||
|
message = append(message, fmt.Sprintf("原价:%.2f", float64(order.MaoyanPrice)/100))
|
||||||
|
message = append(message, fmt.Sprintf("编号:%s", order.OrderId))
|
||||||
|
message = append(message, fmt.Sprintf("总金额:%.2f(%d)", float64(order.TotalPrice)/100, order.SeatNum))
|
||||||
|
message = append(message, fmt.Sprintf("报价范围:%.2f~%.2f", float64(order.MinPrice)/100, float64(order.MaxPrice)/100))
|
||||||
|
message = append(message, fmt.Sprintf("订单时间:%s", time.Unix(order.PayTime, 0).Format("2006-01-02 15:04")))
|
||||||
|
message = append(message, fmt.Sprintf("放映时间:%s", time.Unix(order.ShowTime, 0).Format("2006-01-02 15:04")))
|
||||||
|
message = append(message, "\n")
|
||||||
|
message = append(message, "【大地订单信息】")
|
||||||
|
message = append(message, fmt.Sprintf("单价:%s", util.MoneyFen(checkInfo.UnitPrice)))
|
||||||
|
message = append(message, fmt.Sprintf("总价:%s", util.MoneyFen(checkInfo.TotalPrice)))
|
||||||
|
if err := w.qyClient.SendText([]string{"jiangyong"}, strings.Join(message, "\n")); err != nil {
|
||||||
|
log.Errorf("send message error : %s", err.Error())
|
||||||
|
}
|
||||||
|
case updateOrder := <-updateOrderChan:
|
||||||
|
log.Debugf("update:", goutil.EncodeJSON(updateOrder))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue