2023-04-09 02:11:58 +08:00
|
|
|
package dadi
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
|
|
|
"film/base/httputil"
|
|
|
|
"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)
|
|
|
|
}
|
|
|
|
|
2023-04-09 09:58:23 +08:00
|
|
|
func (d *Processor) getCinemaFilmShowHall(cinema *Cinema, filmName, startTime string) (*FilmShowHall, error) {
|
2023-04-09 02:11:58 +08:00
|
|
|
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)
|
|
|
|
sTime := cast.ToString(pp["startTime"])
|
2023-04-09 09:58:23 +08:00
|
|
|
if startTime != sTime {
|
2023-04-09 02:11:58 +08:00
|
|
|
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
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-04-09 09:58:23 +08:00
|
|
|
return nil, fmt.Errorf("film[%s] startTime[%s] no exist", filmName, startTime)
|
2023-04-09 02:11:58 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
|
}
|
2023-04-09 09:58:23 +08:00
|
|
|
|
|
|
|
log.Debugf("[newPriceCalculate] response : %s", goutil.EncodeJSON(data))
|
2023-04-09 10:40:20 +08:00
|
|
|
realData := cast.ToStringMap(data)
|
2023-04-09 02:11:58 +08:00
|
|
|
previewOrder := new(PreviewOrder)
|
2023-04-09 10:40:20 +08:00
|
|
|
previewOrder.TotalOriginPrice = int64(cast.ToFloat64(realData["ticketOriginPrice"]) * 100)
|
|
|
|
previewOrder.TotalRealPrice = int64(cast.ToFloat64(realData["ticketRealPrice"]) * 100)
|
2023-04-09 11:38:19 +08:00
|
|
|
previewOrder.CouponPrice = int64(cast.ToFloat64(realData["ticketCouponPrice"]) * 100)
|
2023-04-09 02:11:58 +08:00
|
|
|
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
|
|
|
|
}
|
2023-04-09 09:58:23 +08:00
|
|
|
showHall, err := p.getCinemaFilmShowHall(cinema, order.MovieName, goutil.TimeToDateTime(order.ShowTime))
|
2023-04-09 02:11:58 +08:00
|
|
|
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)
|
2023-04-09 10:40:20 +08:00
|
|
|
result.TotalRealPrice = previewOrder.TotalRealPrice
|
2023-04-09 11:38:19 +08:00
|
|
|
result.TotalOriginPrice = previewOrder.TotalOriginPrice
|
|
|
|
result.CouponPrice = previewOrder.CouponPrice
|
2023-04-09 02:11:58 +08:00
|
|
|
result.BillCode = previewOrder.BillCode
|
2023-04-09 10:40:20 +08:00
|
|
|
log.Infof("check order[%s][%s] previewOrder[%s] [%s][%s][%s] success",
|
|
|
|
order.OrderId, result.BillCode, goutil.EncodeJSON(previewOrder),
|
2023-04-09 02:11:58 +08:00
|
|
|
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
|
|
|
|
}
|