123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412 |
- package service
- import (
- "bytes"
- "context"
- "encoding/json"
- "net/http"
- "strconv"
- "time"
- "go-common/app/admin/main/tv/model"
- "go-common/library/ecode"
- "go-common/library/log"
- "github.com/jinzhu/gorm"
- )
- const (
- _configTableName = "tv_price_config"
- _valid = 0
- _invalid = 1
- _noPid = 0
- _orderField = "ctime"
- _vip = 10
- _online = 0
- _delete = 2
- )
- // PanelInfo select panel info by id
- func (s *Service) PanelInfo(id int64) (panelInfo *model.TvPriceConfigResp, err error) {
- if panelInfo, err = s.dao.GetById(id); err != nil {
- if err == gorm.ErrRecordNotFound {
- return nil, nil
- }
- log.Error("PanelInfo (%v) error(%v)", panelInfo, err)
- return
- }
- if panelInfo != nil {
- panelInfo.OriginPrice = panelInfo.Price
- hasDiscount, price, discountInfos := s.hasDiscount(nil, panelInfo.ID)
- if hasDiscount {
- panelInfo.Price = price
- }
- panelInfo.Items = discountInfos
- }
- return
- }
- // PanelStatus change panel status by id
- func (s *Service) PanelStatus(id, status int64) (err error) {
- var (
- flag bool
- panelInfo *model.TvPriceConfigResp
- )
- if panelInfo, err = s.dao.GetById(id); err != nil {
- log.Error("PanelInfo (%v) error(%v)", panelInfo, err)
- }
- if status == _online && panelInfo.SuitType == _vip {
- if flag, err = s.hasOnlineUpgradeVipProduct(); err != nil {
- log.Error("GetValidUpgradeVipProduct Err %v", err)
- return
- }
- if flag {
- err = ecode.TVVipSuitTypeConflict
- return err
- }
- }
- if panelInfo.PID == 0 && status == _delete {
- if err = s.dao.DB.Table(_configTableName).Where("pid = ?", id).Update("status", _delete).Error; err != nil {
- log.Error("PanelStatus discount (%v) error(%v)", id, err)
- }
- }
- if err = s.dao.PanelStatus(id, status); err != nil {
- log.Error("PanelStatus (%v) error(%v)", id, err)
- }
- return
- }
- // SavePanel add or update panel info
- func (s *Service) SavePanel(c context.Context, panel *model.TvPriceConfig) (err error) {
- opType := s.c.YSTParam.Update
- //start tx
- tx := s.DB.Begin()
- if panel.PID != 0 {
- _, _, discounts := s.hasDiscount(nil, panel.PID)
- if flag := checkDisCountTime(discounts, panel); !flag {
- err = ecode.TvPriceTimeConflict
- return err
- }
- s.copyParentExtraField(panel)
- }
- if panel.ID != 0 && panel.PID == 0 {
- if err = tx.Table(_configTableName).Where("pid = ?", panel.ID).
- Update(map[string]interface{}{
- "suit_type": panel.SuitType,
- "sub_type": panel.SubType,
- "selected": panel.Selected,
- "superscript": panel.Superscript,
- "month": panel.Month,
- }).Error; err != nil {
- log.Error("Update discount failed while update panel, Err %v", err)
- tx.Rollback()
- return
- }
- _, _, discounts := s.hasDiscount(tx, panel.ID)
- for _, discount := range discounts {
- if err = s.syncPanels(c, opType, &discount); err != nil {
- err = ecode.TvVipProdSyncErr
- tx.Rollback()
- return err
- }
- }
- }
- if panel.ID == 0 {
- opType = s.c.YSTParam.Insert
- if panel.PID == 0 {
- panel.Status = _invalid
- } else {
- s.copyParentExtraField(panel)
- }
- if flag := s.dao.ExistProduct(panel.ProductID); flag {
- err = ecode.TvVipProductExit
- return err
- }
- }
- if err = tx.Save(panel).Error; err != nil {
- log.Error("SavePanel %s, Err %v", panel, err)
- return err
- }
- if err = s.syncPanels(c, opType, panel); err != nil {
- err = ecode.TvVipProdSyncErr
- tx.Rollback()
- return err
- }
- tx.Commit()
- return
- }
- // PanelList get panle list
- func (s *Service) PanelList(platform, month, subType, suitType int64) (panels []*model.TvPriceConfigListResp, err error) {
- var (
- db = s.dao.DB.Model(&model.TvPriceConfigListResp{}).Where("pid = ? and status in (?, ?)", _noPid, _valid, _invalid)
- )
- if platform != 0 {
- db = db.Where("platform = ?", platform)
- }
- if month != 0 {
- db = db.Where("month = ?", month)
- }
- if subType != -1 {
- db = db.Where("sub_type = ?", subType)
- }
- if suitType != -1 {
- db = db.Where("suit_type = ?", suitType)
- }
- if err = db.Order("suit_type, sub_type desc, month desc").Find(&panels).Error; err != nil {
- log.Error("OrderList %v, Err %v", panels, err)
- return panels, err
- }
- for _, panel := range panels {
- hasDiscount, price, _ := s.hasDiscount(nil, panel.ID)
- panel.OriginPrice = panel.Price
- if hasDiscount {
- panel.Price = price
- }
- }
- return
- }
- // HasDiscount Judge whether there is a discount
- func (s *Service) hasDiscount(tx *gorm.DB, id int64) (hasDiscount bool, price int64, panels []model.TvPriceConfig) {
- if tx == nil {
- tx = s.dao.DB
- }
- if err := tx.Table(_configTableName).Where("pid = ? and status = ?", id, _valid).Find(&panels).Error; err != nil {
- log.Error("HasDiscount %v, Err %v", id, err)
- return
- }
- nowTime := time.Now().Unix()
- for _, panel := range panels {
- if int64(panel.Stime) < nowTime && nowTime < int64(panel.Etime) {
- hasDiscount = true
- price = panel.Price
- return
- }
- }
- return
- }
- // checkDisCountTime check discount time conflict
- func checkDisCountTime(discounts []model.TvPriceConfig, panel *model.TvPriceConfig) (flag bool) {
- var (
- startTime = panel.Stime
- endTime = panel.Etime
- )
- for _, discount := range discounts {
- // do not compare with self
- if panel.ID != discount.ID {
- if discount.Stime < startTime && startTime < discount.Etime {
- return false
- }
- if discount.Stime < endTime && endTime < discount.Etime {
- return false
- }
- if discount.Stime > startTime && endTime > discount.Etime {
- return false
- }
- }
- }
- return true
- }
- // checkRemotePanel check YST panel
- func (s *Service) checkRemotePanel(c context.Context) {
- var (
- panels []*model.TvPriceConfigListResp
- )
- if err := s.dao.DB.Table(_configTableName).Order(_orderField).Find(&panels).Error; err != nil {
- log.Error("CheckRemotePanel Err %v", err)
- return
- }
- res, _ := s.getRemotePanels(c)
- remotePanels := res.Product
- panelMap := make(map[string]*model.TvPriceConfigListResp, len(panels))
- remotePaneMap := make(map[string]model.Product, len(remotePanels))
- for i := 0; i < len(panels); i++ {
- panelMap[panels[i].ProductID] = panels[i]
- }
- for i := 0; i < len(remotePanels); i++ {
- remotePaneMap[remotePanels[i].ID] = remotePanels[i]
- }
- for i := 0; i < len(panels); i++ {
- rp, exists := remotePaneMap[panels[i].ProductID]
- if exists {
- s.compareFiled(rp, panels[i])
- } else {
- log.Error("Our panel not exists in YST, panel id is (%v)", panels[i].ProductID)
- }
- }
- for i := 0; i < len(remotePanels); i++ {
- p, exists := panelMap[remotePanels[i].ID]
- if exists {
- s.compareFiled(remotePanels[i], p)
- } else {
- log.Error("YST panel not exists in our db, panel id is (%v)", remotePanels[i].ID)
- }
- }
- }
- // getRemotePanels get YST panel
- func (s *Service) getRemotePanels(c context.Context) (res *model.RemotePanel, err error) {
- var (
- req *http.Request
- )
- res = &model.RemotePanel{}
- params := map[string]string{
- "vod_type": s.c.YSTParam.QueryPanelType,
- "source": s.c.YSTParam.Source,
- }
- reqBody, _ := json.Marshal(params)
- getRemotePanelUrl := s.c.URLConf.GetRemotePanelUrl
- if req, err = http.NewRequest(http.MethodPost, getRemotePanelUrl, bytes.NewReader(reqBody)); err != nil {
- log.Error("MerakNotify NewRequest Err %v, Url %v", err, getRemotePanelUrl)
- return
- }
- req.Header.Set("Content-Type", "application/json; charset=utf-8")
- if err = s.client.Do(c, req, &res); err != nil {
- log.Error("MergeUpInfo http req failed ,err:%v", err)
- return
- }
- return
- }
- // compareFiled compare our panel field with YST
- func (s *Service) compareFiled(remotePanel model.Product, panel *model.TvPriceConfigListResp) {
- rpid := remotePanel.ID
- prodiuctId := panel.ProductID
- if rpid != prodiuctId {
- log.Error("PanelInfo id different, Remote panel prodiuctId is (%v), Our panel prodiuctId is (%v)", rpid, prodiuctId)
- }
- if remotePanel.Price != panel.Price {
- log.Error("PanelInfo price different, Remote panel prodiuctId is (%v), Our panel prodiuctId is (%v)", rpid, prodiuctId)
- }
- if remotePanel.Contract != strconv.Itoa(int(panel.SubType)) {
- log.Error("PanelInfo subType different, Remote panel prodiuctId is (%v), Our panel prodiuctId is (%v)", rpid, prodiuctId)
- }
- if remotePanel.SuitType != panel.SuitType {
- log.Error("PanelInfo suitType different, Remote panel id is (%v), Our panel id is (%v)", rpid, prodiuctId)
- }
- if remotePanel.ProductDuration != strconv.FormatInt(panel.Month*31, 10) {
- log.Error("PanelInfo months different, Remote panel prodiuctId is (%v), Our panel prodiuctId is (%v)", rpid, prodiuctId)
- }
- if remotePanel.Title != panel.ProductName {
- log.Error("PanelInfo productName different, Remote panel prodiuctId is (%v), Our panel id prodiuctId (%v)", rpid, prodiuctId)
- }
- if panel.PID != 0 {
- parentPanel, err := s.dao.GetById(panel.PID)
- if err != nil {
- log.Error("PanelInfo (%v) error(%v)", parentPanel, err)
- }
- if remotePanel.ComboPkgID != parentPanel.ProductID {
- log.Error("PanelInfo pid different, Remote panel prodiuctId is (%v), Our panel prodiuctId is (%v)", rpid, prodiuctId)
- }
- }
- }
- // syncPanels send our panel to YST
- func (s *Service) syncPanels(c context.Context, opType string, panel *model.TvPriceConfig) (err error) {
- var (
- req *http.Request
- res struct {
- Result string `json:"result"`
- Message string `json:"message"`
- }
- params struct {
- OpType string `json:"optype"`
- Source string `json:"source"`
- Product model.Product `json:"product"`
- }
- )
- params.OpType = opType
- params.Source = s.c.YSTParam.Source
- params.Product.ID = panel.ProductID
- params.Product.VodType = s.c.YSTParam.InsertPanelType
- params.Product.Title = panel.ProductName
- params.Product.ProductDuration = strconv.FormatInt(31*panel.Month, 10)
- params.Product.Description = panel.Remark
- params.Product.Contract = strconv.Itoa(int(panel.SubType))
- if panel.PID != 0 {
- parentPanel, _ := s.dao.GetById(panel.PID)
- if parentPanel != nil {
- params.Product.ComboPkgID = parentPanel.ProductID
- params.Product.ComboDes = parentPanel.Remark
- } else {
- log.Error("Prarent PanelInfo not found, pid =(%v)", panel.PID)
- err = ecode.NothingFound
- return err
- }
- }
- params.Product.Price = panel.Price
- params.Product.SuitType = panel.SuitType
- reqBody, _ := json.Marshal(params)
- SyncPanelUrl := s.c.URLConf.SyncPanelUrl
- if req, err = http.NewRequest(http.MethodPost, SyncPanelUrl, bytes.NewReader(reqBody)); err != nil {
- log.Error("MerakNotify NewRequest Err %v, Url %v", err, SyncPanelUrl)
- return err
- }
- req.Header.Set("Content-Type", "application/json; charset=utf-8")
- if err = s.client.Do(c, req, &res); err != nil {
- log.Error("MergeUpInfo http req failed ,err:%v", err)
- return err
- }
- if res.Result != "SUCCESS" {
- err = ecode.TvVipProdSyncErr
- log.Info("Sync panel To YST Fail,err:%v", res.Message)
- return err
- }
- return
- }
- func (s *Service) hasOnlineUpgradeVipProduct() (flag bool, err error) {
- var (
- panels []*model.TvPriceConfig
- )
- if err = s.dao.DB.Table(_configTableName).Where("suit_type = ? and status = ? and pid = ?", _vip, _valid, _noPid).Find(&panels).Error; err != nil {
- log.Error("GetValidUpgradeVipProduct Err %v", err)
- return
- }
- flag = !(len(panels) == 0)
- return
- }
- func (s *Service) copyParentExtraField(panel *model.TvPriceConfig) {
- parentPanel, _ := s.dao.GetById(panel.PID)
- if parentPanel != nil {
- panel.SuitType = parentPanel.SuitType
- panel.SubType = parentPanel.SubType
- panel.Selected = parentPanel.Selected
- panel.Superscript = parentPanel.Superscript
- panel.Month = parentPanel.Month
- }
- }
|