bilibili-backup/app/service/openplatform/ticket-item/dao/project.go
2019-04-22 02:59:20 +00:00

378 lines
11 KiB
Go

package dao
import (
"context"
"encoding/json"
"go-common/app/service/openplatform/ticket-item/model"
"go-common/library/ecode"
"go-common/library/log"
"strconv"
"github.com/jinzhu/gorm"
)
// ProjectMainInfo 项目版本内容
type ProjectMainInfo struct {
Name string `json:"name"`
Type string `json:"type"`
Size string `json:"size"`
ProvinceID string `json:"province_id"`
CityID string `json:"city_id"`
DistrictID string `json:"district_id"`
VenueID string `json:"venue_id"`
PlaceID string `json:"place_id"`
StartTime int32 `json:"start_time"`
EndTime int32 `json:"end_time"`
Docs []ImgInfo `json:"docs"`
Screens []Screen `json:"screens"`
TicketsSingle []TicketSingle `json:"tickets_single"`
TicketsPass []TicketPass `json:"tickets_pass"`
TicketsAllPass []TicketPass `json:"tickets_allpass"`
PerformanceImg PerformanceImg `json:"performance_image"`
PerformanceDesc string `json:"performance_desc"`
SellingProp string `json:"selling_prop"`
TagIDs []string `json:"tag_ids"`
GuestIDs []int64 `json:"guest_ids"`
GuestImgs []GuestImg `json:"guest_imgs"`
CompID string `json:"comp_id"`
Label string `json:"label"`
SponsorType string `json:"sponsor_type"`
}
// ImgInfo 图片信息
type ImgInfo struct {
URL string `json:"url"`
Desc string `json:"desc"`
}
// GuestImg 嘉宾图片信息
type GuestImg struct {
ID int64 `json:"id"`
ImgURL string `json:"img_url"`
}
// Screen 场次信息
type Screen struct {
ScreenName string `json:"screen_name"`
ScreenStartTime int32 `json:"screen_start_time"`
ScreenEndTime int32 `json:"screen_end_time"`
ScreenType string `json:"screen_type"`
PickSeat int32 `json:"pick_seat"`
TicketType string `json:"ticket_type"`
DeliveryType string `json:"delivery_type"`
ScreenID string `json:"screen_id"`
}
// TicketSingle 单场票信息
type TicketSingle struct {
Name string `json:"name"`
Type string `json:"type"`
Color string `json:"color"`
BuyLimit string `json:"buy_limit"`
PayValue int64 `json:"pay_value"`
PayMethod string `json:"pay_method"`
Desc string `json:"descrp"`
TicketID string `json:"ticket_sc_id"`
BuyLimitNum []string `json:"buy_limit_num"`
}
// TicketPass 通票信息
type TicketPass struct {
Name string `json:"name"`
LinkTicket int32 `json:"link_ticket"`
LinkScreens []int32 `json:"link_screens"`
Color string `json:"color"`
BuyLimit string `json:"buy_limit"`
PayValue int64 `json:"pay_value"`
PayMethod string `json:"pay_method"`
Desc string `json:"descrp"`
TicketID string `json:"ticket_sc_id"`
BuyLimitNum []string `json:"buy_limit_num"`
}
// PerformanceImg 项目图片信息
type PerformanceImg struct {
First ImgInfo `json:"first"`
Banner ImgInfo `json:"banner"`
}
const (
// BuyNumLimit 默认限购值
BuyNumLimit = `{"per":8}`
)
// AddProject 项目初始化
func (d *Dao) AddProject(c context.Context, verID uint64) (pid int64, err error) {
var verExtInfo model.VersionExt
if dbErr := d.db.Where("ver_id = ?", verID).First(&verExtInfo).Error; dbErr != nil {
log.Error("获取项目版本详情失败:%s", dbErr)
return 0, dbErr
}
decodedMainInfo := d.GetDefaultMainInfo()
err = json.Unmarshal([]byte(verExtInfo.MainInfo), &decodedMainInfo)
if err != nil {
return
}
// 开启事务
tx := d.db.Begin()
// 创建新project
var project model.Item
if project, err = d.CreateProject(c, tx, verID, decodedMainInfo); err != nil {
return
}
pid = project.ID
if pid == 0 {
tx.Rollback()
log.Error("pid not initialized")
return 0, ecode.TicketPidIsEmpty
}
// 创建新项目详情在project_extra表
if err = d.CreateProjectExtInfo(c, tx, pid, decodedMainInfo.PerformanceDesc); err != nil {
return
}
// 创建场次screen
scIDList := make(map[int32]int64)
scStartTimes := make(map[int32]int32)
scEndTimes := make(map[int32]int32)
var screen model.Screen
for k, v := range decodedMainInfo.Screens {
screenType, _ := strconv.ParseInt(v.ScreenType, 10, 64)
ticketType, _ := strconv.ParseInt(v.TicketType, 10, 64)
deliveryType, _ := strconv.ParseInt(v.DeliveryType, 10, 64)
screen = model.Screen{
ProjectID: pid,
Name: v.ScreenName,
StartTime: v.ScreenStartTime,
EndTime: v.ScreenEndTime,
Type: int32(screenType),
TicketType: int32(ticketType),
DeliveryType: int32(deliveryType),
PickSeat: v.PickSeat,
ScreenType: 1, // 单场票场次
}
if screen, err = d.CreateOrUpdateScreen(c, tx, screen); err != nil {
return
}
// 获取的screen自增id复制到maininfo内
decodedMainInfo.Screens[k].ScreenID = strconv.FormatInt(screen.ID, 10)
scIDList[int32(k)] = screen.ID
scStartTimes[int32(k)] = screen.StartTime
scEndTimes[int32(k)] = screen.EndTime
}
// 创建票价
TkSingleIDList := make(map[int32]int64)
TkSingleTypeList := make(map[int32]int32)
var tkPrice model.TicketPrice
for k, v := range decodedMainInfo.TicketsSingle {
saleType, _ := strconv.ParseInt(v.Type, 10, 64)
buyLimit, _ := strconv.ParseInt(v.BuyLimit, 10, 64)
payMethod, _ := strconv.ParseInt(v.PayMethod, 10, 64)
ticketID, baseErr := model.GetTicketIDFromBase()
if ticketID == 0 || baseErr != nil {
tx.Rollback()
log.Error("baseCenter获取ticketID失败 ticketid:%s,baseErr:%s", ticketID, baseErr)
return 0, baseErr
}
tkPrice = model.TicketPrice{
ID: ticketID,
ProjectID: pid,
Desc: v.Name,
Type: 1, // 单场票
SaleType: int32(saleType),
Color: v.Color,
BuyLimit: int32(buyLimit),
PaymentMethod: int32(payMethod),
PaymentValue: v.PayValue,
DescDetail: v.Desc,
IsSale: 1, // 可售
IsRefund: -10, // 不可退
OriginPrice: -1, // 未設置
MarketPrice: -1,
SaleStart: TimeNull, // 0000-00-00 00:00:00
SaleEnd: TimeNull,
}
if tkPrice, err = d.CreateOrUpdateTkPrice(c, tx, tkPrice, 0); err != nil {
return
}
//票价限购
limitData := d.FormatByPrefix(v.BuyLimitNum, "buy_limit_")
if err = d.CreateOrUpdateTkPriceExtra(c, tx, limitData, ticketID, pid); err != nil {
return
}
// 获取的ticketPrice自增id复制到mainInfo内
decodedMainInfo.TicketsSingle[k].TicketID = strconv.FormatInt(tkPrice.ID, 10)
TkSingleIDList[int32(k)] = ticketID
TkSingleTypeList[int32(k)] = int32(saleType)
}
var passScID, allPassScID int64
// 创建通票场次
passScID, err = d.GetOrUpdatePassSc(c, tx, pid, decodedMainInfo.TicketsPass, scStartTimes, scEndTimes, scTypePass, 0)
if err != nil {
return
}
decodedMainInfo.TicketsPass, err = d.InsertOrUpdateTkPass(c, tx, pid, passScID, decodedMainInfo.TicketsPass, TkTypePass, scIDList, TkSingleIDList, TkSingleTypeList)
if err != nil {
return
}
// 创建联票场次
allPassScID, err = d.GetOrUpdatePassSc(c, tx, pid, decodedMainInfo.TicketsAllPass, scStartTimes, scEndTimes, scTypeAllPass, 0)
if err != nil {
return
}
decodedMainInfo.TicketsAllPass, err = d.InsertOrUpdateTkPass(c, tx, pid, allPassScID, decodedMainInfo.TicketsAllPass, TkTypeAllPass, scIDList, TkSingleIDList, TkSingleTypeList)
if err != nil {
return
}
// 创建标签
for _, tagID := range decodedMainInfo.TagIDs {
err = d.CreateTag(c, tx, pid, tagID)
if err != nil {
return
}
}
// 创建嘉宾
guestImgMap := make(map[int64]string)
// 组合嘉宾对应头像map
if decodedMainInfo.GuestIDs != nil {
if decodedMainInfo.GuestImgs == nil {
var guestInfoList []model.Guest
if err = d.db.Select("id, guest_img").Where("id IN (?)", decodedMainInfo.GuestIDs).Find(&guestInfoList).Error; err != nil {
log.Error("获取嘉宾信息失败:%s", err)
tx.Rollback()
return
}
for _, v := range guestInfoList {
guestImgMap[v.ID] = v.GuestImg
}
} else {
for _, v := range decodedMainInfo.GuestImgs {
guestImgMap[v.ID] = v.ImgURL
}
}
}
var position int64
for _, guestID := range decodedMainInfo.GuestIDs {
if err = tx.Create(&model.ProjectGuest{
ProjectID: pid,
GuestID: guestID,
Position: position,
GuestImg: guestImgMap[guestID],
}).Error; err != nil {
log.Error("项目嘉宾添加失败:%s", err)
tx.Rollback()
return
}
position++
}
// 将有场次票价id的mainInfo更新到version_ext
encodedMainInfo, jsonErr := json.Marshal(decodedMainInfo)
if jsonErr != nil {
log.Error("JSONEncode MainInfo失败")
tx.Rollback()
return pid, jsonErr
}
finalMainInfo := string(encodedMainInfo)
if len(finalMainInfo) > 4000 {
log.Error("信息量过大")
tx.Rollback()
return pid, ecode.TicketMainInfoTooLarge
}
// 编辑version_ext
err = tx.Model(&model.VersionExt{}).Where("ver_id = ? and type = ?", verID, 1).Update("main_info", finalMainInfo).Error
if err != nil {
tx.Rollback()
log.Error("更新versionext失败: %s", err)
}
// 提交事务
tx.Commit()
return pid, nil
}
// CreateProject 灌入项目表
func (d *Dao) CreateProject(c context.Context, tx *gorm.DB, verID uint64, decodedMainInfo ProjectMainInfo) (project model.Item, err error) {
// 创建新project
venueID, _ := strconv.ParseInt(decodedMainInfo.VenueID, 10, 64)
placeID, _ := strconv.ParseInt(decodedMainInfo.PlaceID, 10, 64)
compID, _ := strconv.ParseInt(decodedMainInfo.CompID, 10, 64)
projectType, _ := strconv.ParseInt(decodedMainInfo.Type, 10, 64)
projectSponsorType, _ := strconv.ParseInt(decodedMainInfo.SponsorType, 10, 64)
performanceImg, _ := json.Marshal(decodedMainInfo.PerformanceImg)
projectInfo := model.Item{
Name: decodedMainInfo.Name,
StartTime: decodedMainInfo.StartTime,
EndTime: decodedMainInfo.EndTime,
VenueID: venueID,
PlaceID: placeID,
CompID: compID,
PerformanceImage: string(performanceImg),
TicketDesc: decodedMainInfo.SellingProp,
Type: int32(projectType),
VerID: verID,
SponsorType: int32(projectSponsorType),
Label: decodedMainInfo.Label,
BuyNumLimit: BuyNumLimit,
IsSale: 1, // 默认值可售
ExpressFee: -2, //默认值
}
if err = tx.Create(&projectInfo).Error; err != nil {
log.Error("新建项目失败:%s", err)
tx.Rollback()
return model.Item{}, err
}
return projectInfo, nil
}
// CreateProjectExtInfo 灌入项目详情表
func (d *Dao) CreateProjectExtInfo(c context.Context, tx *gorm.DB, projectID int64, performanceDesc string) (err error) {
projectExtInfo := model.ItemDetail{
ProjectID: projectID,
PerformanceDesc: performanceDesc,
}
if err = tx.Create(&projectExtInfo).Error; err != nil {
log.Error("新建项目详情失败:%s", err)
tx.Rollback()
return err
}
return nil
}
// GetDefaultMainInfo 获取初始化数组的mainInfo
func (d *Dao) GetDefaultMainInfo() ProjectMainInfo {
return ProjectMainInfo{
Docs: []ImgInfo{},
Screens: []Screen{},
TicketsSingle: []TicketSingle{},
TicketsPass: []TicketPass{},
TicketsAllPass: []TicketPass{},
TagIDs: []string{},
GuestIDs: []int64{},
GuestImgs: []GuestImg{},
}
}