You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
526 lines
16 KiB
526 lines
16 KiB
package dao |
|
|
|
import ( |
|
"context" |
|
|
|
"encoding/json" |
|
"fmt" |
|
item "go-common/app/service/openplatform/ticket-item/api/grpc/v1" |
|
"go-common/app/service/openplatform/ticket-item/model" |
|
"go-common/library/ecode" |
|
"go-common/library/log" |
|
"go-common/library/time" |
|
"strconv" |
|
"strings" |
|
xtime "time" |
|
|
|
"github.com/jinzhu/gorm" |
|
) |
|
|
|
// DelBannerInfo 删除缓存所需banner信息 |
|
type DelBannerInfo struct { |
|
Order int32 |
|
Position int32 |
|
SubPosition int32 |
|
DistrictIDs []string |
|
} |
|
|
|
// AddBanner 添加新投放 |
|
func (d *Dao) AddBanner(c context.Context, info *item.BannerEditRequest) (bannerID int64, verID uint64, err error) { |
|
// 开启事务 |
|
tx := d.db.Begin() |
|
|
|
//创建banner信息 |
|
banner := model.Banner{ |
|
PubStart: time.Time(info.PubStart), |
|
PubEnd: time.Time(info.PubEnd), |
|
Name: info.Name, |
|
Pic: info.Pic, |
|
URL: info.Url, |
|
From: info.From, |
|
TargetUser: info.TargetUser, |
|
} |
|
|
|
if err = tx.Create(&banner).Error; err != nil { |
|
log.Error("创建banner失败:%s", err) |
|
tx.Rollback() |
|
return 0, 0, err |
|
} |
|
bannerID = banner.ID |
|
if bannerID == 0 { |
|
log.Error("bannerID为0") |
|
tx.Rollback() |
|
return 0, 0, err |
|
} |
|
|
|
var mainInfo []byte |
|
mainInfo, err = json.Marshal(info) |
|
if err != nil { |
|
log.Error("jsonMarshal版本详情失败:%s", err) |
|
tx.Rollback() |
|
return bannerID, 0, err |
|
} |
|
|
|
//生成新审核版本ver,verExt |
|
str := fmt.Sprintf("%d%d%.2d", info.Position, info.SubPosition, info.Order) |
|
forInt, _ := strconv.ParseInt(str, 10, 64) |
|
verInfo := model.Version{ |
|
Type: model.VerTypeBanner, |
|
Status: info.OpType, |
|
ItemName: info.Name, |
|
TargetItem: bannerID, |
|
AutoPub: 1, // 自动上架 |
|
PubStart: time.Time(info.PubStart), |
|
PubEnd: time.Time(info.PubEnd), |
|
For: forInt, |
|
} |
|
err = d.AddVersion(c, tx, &verInfo, &model.VersionExt{ |
|
Type: model.VerTypeBanner, |
|
MainInfo: string(mainInfo), |
|
}) |
|
if err != nil { |
|
log.Error("创建banner版本失败: %s", err) |
|
return 0, verInfo.VerID, ecode.TicketAddVersionFailed |
|
} |
|
if verInfo.VerID == 0 { |
|
log.Error("创建后获取verID为0") |
|
return 0, verInfo.VerID, ecode.TicketAddVersionFailed |
|
} |
|
|
|
// 提交事务 |
|
tx.Commit() |
|
return bannerID, verInfo.VerID, nil |
|
} |
|
|
|
// EditBanner 编辑投放 |
|
func (d *Dao) EditBanner(c context.Context, info *item.BannerEditRequest) (err error) { |
|
// 开启事务 |
|
tx := d.db.Begin() |
|
|
|
var mainInfo []byte |
|
mainInfo, err = json.Marshal(info) |
|
if err != nil { |
|
log.Error("jsonMarshal版本详情失败:%s", err) |
|
tx.Rollback() |
|
return err |
|
} |
|
|
|
//更新审核版本ver,verExt |
|
str := fmt.Sprintf("%d%d%.2d", info.Position, info.SubPosition, info.Order) |
|
forInt, _ := strconv.ParseInt(str, 10, 64) |
|
if err = tx.Model(&model.Version{}).Where("ver_id = ?", info.VerId).Updates( |
|
map[string]interface{}{ |
|
"item_name": info.Name, |
|
"status": info.OpType, |
|
"pub_start": time.Time(info.PubStart), |
|
"pub_end": time.Time(info.PubEnd), |
|
"for": forInt, |
|
}).Error; err != nil { |
|
log.Error("更新banner版本失败:%s", err) |
|
tx.Rollback() |
|
return err |
|
} |
|
if err = tx.Model(&model.VersionExt{}).Where("ver_id = ?", info.VerId).Updates( |
|
map[string]interface{}{ |
|
"main_info": mainInfo, |
|
}).Error; err != nil { |
|
log.Error("更新banner版本详情失败:%s", err) |
|
tx.Rollback() |
|
return err |
|
} |
|
|
|
// 提交事务 |
|
tx.Commit() |
|
return nil |
|
} |
|
|
|
// PassOrPublishBanner 审核通过或上架banner版本 |
|
func (d *Dao) PassOrPublishBanner(c context.Context, verID uint64) (err error) { |
|
|
|
//获取版本信息 |
|
verInfo, verExtInfo, getErr := d.GetVersion(c, verID, true) |
|
if getErr != nil { |
|
return getErr |
|
} |
|
|
|
//解析mainInfo |
|
var decodedMainInfo item.BannerEditRequest |
|
err = json.Unmarshal([]byte(verExtInfo.MainInfo), &decodedMainInfo) |
|
if err != nil { |
|
return err |
|
} |
|
bannerID := verInfo.TargetItem |
|
tx := d.db.Begin() |
|
|
|
//如果存在审核通过/进行中版本 删除版本 |
|
var bannerVersions []model.Version |
|
if err = tx.Where("target_item = ? and status in (?) and ver_id != ? and deleted_at='0000-00-00 00:00:00'", |
|
bannerID, []int32{model.VerStatusReadyForSale, model.VerStatusOnShelf}, verID).Find(&bannerVersions).Error; err != nil { |
|
log.Error("获取banner所有审核通过/已上架版本失败:%s", err) |
|
tx.Rollback() |
|
return err |
|
} |
|
|
|
var delCacheInfos []DelBannerInfo |
|
var verIDs []uint64 |
|
var delPosition int32 |
|
var delSubPosition int32 |
|
var delOrder int32 |
|
var delDistrictIDs []string |
|
for _, v := range bannerVersions { |
|
//获取该版本详情 删除对应bannerDistrict信息 |
|
if delPosition, delSubPosition, delOrder, delDistrictIDs, err = d.DelBannerDistrictByVerID(c, tx, v.VerID, bannerID); err != nil { |
|
return |
|
} |
|
delCacheInfos = append(delCacheInfos, DelBannerInfo{ |
|
Order: delOrder, |
|
Position: delPosition, |
|
SubPosition: delSubPosition, |
|
DistrictIDs: delDistrictIDs, |
|
}) |
|
verIDs = append(verIDs, v.VerID) |
|
} |
|
if verIDs != nil { |
|
if err = tx.Exec("UPDATE version SET deleted_at=? WHERE ver_id in (?)", xtime.Now().Format("2006-01-02 15:04:05"), verIDs).Error; err != nil { |
|
log.Error("删除banner版本失败:%s", err) |
|
tx.Rollback() |
|
return err |
|
} |
|
if err = tx.Exec("UPDATE version_ext SET deleted_at=? WHERE ver_id in (?)", xtime.Now().Format("2006-01-02 15:04:05"), verIDs).Error; err != nil { |
|
log.Error("删除banner ext版本失败:%s", err) |
|
tx.Rollback() |
|
return err |
|
} |
|
} |
|
|
|
//如果达到投放开始时间 还要更新bannerDistrict并直接上架 |
|
var newVerStatus int32 |
|
var newBannerStatus int32 |
|
var districtIDs []string |
|
if decodedMainInfo.PubStart <= xtime.Now().Unix() { |
|
districtIDs = strings.Split(decodedMainInfo.Location, ",") |
|
for _, districtID := range districtIDs { |
|
newDistrictID, _ := strconv.ParseInt(districtID, 10, 64) |
|
if err = d.CreateOrUpdateBannerDistrict(c, tx, model.BannerDistrict{ |
|
BannerID: bannerID, |
|
Position: decodedMainInfo.Position, |
|
SubPosition: decodedMainInfo.SubPosition, |
|
Order: decodedMainInfo.Order, |
|
DistrictID: newDistrictID, |
|
}); err != nil { |
|
return err |
|
} |
|
} |
|
newVerStatus = model.VerStatusOnShelf |
|
newBannerStatus = 1 |
|
} else { |
|
newVerStatus = model.VerStatusReadyForSale |
|
newBannerStatus = 0 |
|
} |
|
|
|
//更新banner表 |
|
if err = tx.Model(&model.Banner{}).Where("id = ?", bannerID).Updates( |
|
map[string]interface{}{ |
|
"pub_start": time.Time(decodedMainInfo.PubStart), |
|
"pub_end": time.Time(decodedMainInfo.PubEnd), |
|
"name": decodedMainInfo.Name, |
|
"pic": decodedMainInfo.Pic, |
|
"url": decodedMainInfo.Url, |
|
"from": decodedMainInfo.From, |
|
"status": newBannerStatus, |
|
"target_user": decodedMainInfo.TargetUser, |
|
}).Error; err != nil { |
|
log.Error("更新banner失败:%s", err) |
|
tx.Rollback() |
|
return err |
|
} |
|
|
|
//更新version状态为审核通过(待上架)或已上架 |
|
if err = tx.Model(&model.Version{}).Where("ver_id = ?", verID).Updates( |
|
map[string]interface{}{ |
|
"status": newVerStatus, |
|
}).Error; err != nil { |
|
log.Error("更新banner审核版本失败:%s", err) |
|
tx.Rollback() |
|
return err |
|
} |
|
|
|
tx.Commit() |
|
//如果新状态是上架状态 删除相关缓存 |
|
if newVerStatus == model.VerStatusOnShelf { |
|
_, err = d.DelBannerCache(c, decodedMainInfo.Position, decodedMainInfo.SubPosition, decodedMainInfo.Order, districtIDs, bannerID) |
|
if err != nil { |
|
return |
|
} |
|
for _, v := range delCacheInfos { |
|
_, err = d.DelBannerCache(c, v.Position, v.SubPosition, v.Order, v.DistrictIDs, 0) |
|
if err != nil { |
|
return |
|
} |
|
} |
|
|
|
} |
|
|
|
return |
|
} |
|
|
|
// DelBannerCache 删除banner相关缓存 |
|
func (d *Dao) DelBannerCache(c context.Context, position int32, subPosition int32, order int32, districtIDs []string, bannerID int64) (res bool, err error) { |
|
var ( |
|
keys []interface{} |
|
) |
|
|
|
conn := d.redis.Get(c) |
|
defer func() { |
|
conn.Flush() |
|
conn.Close() |
|
}() |
|
|
|
for _, districtID := range districtIDs { |
|
// DEL bannerList |
|
keys = append(keys, keyBannerList(order, districtID, position, subPosition)) |
|
} |
|
//删除bannerInfo缓存 |
|
if bannerID != 0 { |
|
keys = append(keys, keyBannerInfo(bannerID)) |
|
} |
|
|
|
log.Info("DEL %v", keys) |
|
//DEL bannerList |
|
if err = conn.Send("DEL", keys...); err != nil { |
|
log.Error("DEL %v, error(%v)", keys, err) |
|
} |
|
if err != nil { |
|
return false, err |
|
} |
|
return true, err |
|
} |
|
|
|
//DelBannerDistrictByVerID 删除版本详情内对应的关系表信息 |
|
func (d *Dao) DelBannerDistrictByVerID(c context.Context, tx *gorm.DB, verID uint64, bannerID int64) (position int32, subPosition int32, order int32, districtIDs []string, err error) { |
|
var verExtInfo model.VersionExt |
|
var delDecodedInfo item.BannerEditRequest |
|
//获取该版本详情 删除对应bannerDistrict信息 |
|
if err = tx.Where("ver_id = ?", verID).First(&verExtInfo).Error; err != nil { |
|
log.Error("获取需要删除版本详情失败:%s", err) |
|
tx.Rollback() |
|
return 0, 0, 0, nil, err |
|
} |
|
//解析mainInfo |
|
err = json.Unmarshal([]byte(verExtInfo.MainInfo), &delDecodedInfo) |
|
if err != nil { |
|
tx.Rollback() |
|
return 0, 0, 0, nil, err |
|
} |
|
|
|
districtIDs = strings.Split(delDecodedInfo.Location, ",") |
|
for _, districtID := range districtIDs { |
|
if err = tx.Exec("UPDATE banner_district SET is_deleted=1 WHERE banner_id = ? and district_id = ? and position = ? and sub_position = ? and `order` = ?", |
|
bannerID, districtID, delDecodedInfo.Position, delDecodedInfo.SubPosition, delDecodedInfo.Order).Error; err != nil { |
|
log.Error("删除bannerDistrict失败:%s", err) |
|
tx.Rollback() |
|
return 0, 0, 0, nil, err |
|
} |
|
} |
|
return delDecodedInfo.Position, delDecodedInfo.SubPosition, delDecodedInfo.Order, districtIDs, err |
|
} |
|
|
|
// CreateOrUpdateBannerDistrict 更新或新建bannerDistrict关系记录 |
|
func (d *Dao) CreateOrUpdateBannerDistrict(c context.Context, tx *gorm.DB, info model.BannerDistrict) (err error) { |
|
var bannerDist model.BannerDistrict |
|
log.Info("bannerDist:%v", info) |
|
err = tx.Where("district_id = ? and position = ? and sub_position = ? and `order` = ?", |
|
info.DistrictID, info.Position, info.SubPosition, info.Order).First(&bannerDist).Error |
|
//除去没查找到记录的报错 其他直接抛错 |
|
if err != nil && err != ecode.NothingFound { |
|
log.Error("获取banner dist信息失败:%s", err) |
|
tx.Rollback() |
|
return |
|
} |
|
|
|
if bannerDist.ID != 0 { |
|
//update |
|
log.Info("update bannerDistrict") |
|
if err = tx.Exec("UPDATE banner_district SET banner_id=?,is_deleted=0 WHERE district_id = ? and position = ? and sub_position = ? and `order` = ?", |
|
info.BannerID, info.DistrictID, info.Position, info.SubPosition, info.Order).Error; err != nil { |
|
log.Error("更新bannerDistrict失败:%s", err) |
|
tx.Rollback() |
|
return err |
|
} |
|
} else { |
|
//create |
|
log.Info("insert bannerDistrict") |
|
if err = tx.Create(&model.BannerDistrict{ |
|
BannerID: info.BannerID, |
|
Position: info.Position, |
|
SubPosition: info.SubPosition, |
|
Order: info.Order, |
|
DistrictID: info.DistrictID, |
|
}).Error; err != nil { |
|
log.Error("创建bannerDistrict失败:%s", err) |
|
tx.Rollback() |
|
return err |
|
} |
|
} |
|
return nil |
|
} |
|
|
|
// DeleteBanner 删除banner |
|
func (d *Dao) DeleteBanner(c context.Context, verID uint64) (err error) { |
|
tx := d.db.Begin() |
|
if err = tx.Exec("UPDATE version SET deleted_at=? WHERE ver_id = ?", xtime.Now().Format("2006-01-02 15:04:05"), verID).Error; err != nil { |
|
tx.Rollback() |
|
log.Error("删除banner版本失败:%s", err) |
|
return err |
|
} |
|
if err = tx.Exec("UPDATE version_ext SET deleted_at=? WHERE ver_id=?", xtime.Now().Format("2006-01-02 15:04:05"), verID).Error; err != nil { |
|
tx.Rollback() |
|
log.Error("删除banner ext版本失败:%s", err) |
|
return err |
|
} |
|
tx.Commit() |
|
return |
|
} |
|
|
|
// UnpublishBannerManual 手动取消激活banner |
|
func (d *Dao) UnpublishBannerManual(c context.Context, verID uint64) (err error) { |
|
//取消激活banner |
|
//获取版本信息 |
|
tx := d.db.Begin() |
|
verInfo, _, getErr := d.GetVersion(c, verID, true) |
|
if getErr != nil { |
|
return getErr |
|
} |
|
bannerID := verInfo.TargetItem |
|
if err = tx.Exec("UPDATE banner SET status = 0 WHERE id = ?", bannerID).Error; err != nil { |
|
tx.Rollback() |
|
log.Error("更新banner未激活状态失败:%s", err) |
|
return err |
|
} |
|
|
|
//更新版本为草稿状态 |
|
if err = tx.Exec("UPDATE version SET status = ? WHERE ver_id = ?", model.VerStatusNotReviewed, verID).Error; err != nil { |
|
tx.Rollback() |
|
log.Error("更新banner版本为草稿状态失败:%s", err) |
|
return err |
|
} |
|
|
|
//删除此版本bannerDistrict信息 |
|
var delPosition int32 |
|
var delSubPosition int32 |
|
var delOrder int32 |
|
var delDistrictIDs []string |
|
if delPosition, delSubPosition, delOrder, delDistrictIDs, err = d.DelBannerDistrictByVerID(c, tx, verID, bannerID); err != nil { |
|
return |
|
} |
|
|
|
//如果存在除这个版本以外同个投放id的版本 删除版本 |
|
var bannerVersions []model.Version |
|
if err = tx.Where("target_item = ? and ver_id != ? and deleted_at='0000-00-00 00:00:00'", |
|
bannerID, verID).Find(&bannerVersions).Error; err != nil { |
|
log.Error("获取banner所有其他版本失败:%s", err) |
|
tx.Rollback() |
|
return err |
|
} |
|
|
|
var verIDs []uint64 |
|
for _, v := range bannerVersions { |
|
//获取该版本详情 删除对应bannerDistrict信息 |
|
_, _, _, _, err = d.DelBannerDistrictByVerID(c, tx, v.VerID, bannerID) |
|
if err != nil { |
|
return |
|
} |
|
verIDs = append(verIDs, v.VerID) |
|
} |
|
if verIDs != nil { |
|
if err = tx.Exec("UPDATE version SET deleted_at=? WHERE ver_id in (?)", xtime.Now().Format("2006-01-02 15:04:05"), verIDs).Error; err != nil { |
|
log.Error("删除banner版本失败:%s", err) |
|
tx.Rollback() |
|
return err |
|
} |
|
if err = tx.Exec("UPDATE version_ext SET deleted_at=? WHERE ver_id in (?)", xtime.Now().Format("2006-01-02 15:04:05"), verIDs).Error; err != nil { |
|
log.Error("删除banner ext版本失败:%s", err) |
|
tx.Rollback() |
|
return err |
|
} |
|
} |
|
tx.Commit() |
|
|
|
//删除下架相关缓存 |
|
_, err = d.DelBannerCache(c, delPosition, delSubPosition, delOrder, delDistrictIDs, bannerID) |
|
|
|
return |
|
} |
|
|
|
// UnpublishBannerForced 已过期自动下架操作 |
|
func (d *Dao) UnpublishBannerForced(c context.Context, verID uint64) (err error) { |
|
//获取版本信息 |
|
tx := d.db.Begin() |
|
verInfo, _, getErr := d.GetVersion(c, verID, true) |
|
if getErr != nil { |
|
return getErr |
|
} |
|
//取消激活banner |
|
bannerID := verInfo.TargetItem |
|
if err = tx.Exec("UPDATE banner SET status = 0 WHERE id = ?", bannerID).Error; err != nil { |
|
tx.Rollback() |
|
log.Error("更新banner未激活状态失败:%s", err) |
|
return err |
|
} |
|
//删除bannerDistrict信息 |
|
var delPosition int32 |
|
var delSubPosition int32 |
|
var delOrder int32 |
|
var delDistrictIDs []string |
|
if delPosition, delSubPosition, delOrder, delDistrictIDs, err = d.DelBannerDistrictByVerID(c, tx, verID, bannerID); err != nil { |
|
return |
|
} |
|
|
|
//更新版本为强制下架状态 |
|
if err = tx.Exec("UPDATE version SET status = ? WHERE ver_id = ?", model.VerStatusOffShelfForced, verID).Error; err != nil { |
|
tx.Rollback() |
|
log.Error("更新banner版本为强制下架状态失败:%s", err) |
|
return err |
|
} |
|
tx.Commit() |
|
//删除下架相关缓存 |
|
_, err = d.DelBannerCache(c, delPosition, delSubPosition, delOrder, delDistrictIDs, bannerID) |
|
|
|
return |
|
} |
|
|
|
// CgBannerStatus 更改banner版本状态 |
|
func (d *Dao) CgBannerStatus(c context.Context, info *item.VersionStatusRequest) (err error) { |
|
|
|
switch info.OpType { |
|
case 0: |
|
//手动取消激活操作 |
|
err = d.UnpublishBannerManual(c, info.VerId) |
|
case 1: |
|
//提交审核操作 |
|
err = d.db.Exec("UPDATE version SET status = ? WHERE ver_id = ?", model.VerStatusReadyForReview, info.VerId).Error |
|
if err != nil { |
|
return err |
|
} |
|
//提交审核时 记入versionLog |
|
err = d.AddVersionLog(c, &model.VersionLog{ |
|
VerID: info.VerId, |
|
Type: 2, //用户操作记录 |
|
Log: "提交审核", |
|
Uname: info.Uname, |
|
}) |
|
case 2: |
|
//删除操作 |
|
err = d.DeleteBanner(c, info.VerId) |
|
case 3: |
|
//上架操作 |
|
err = d.PassOrPublishBanner(c, info.VerId) |
|
case 4: |
|
//已过期自动下架操作 |
|
err = d.UnpublishBannerForced(c, info.VerId) |
|
default: |
|
return ecode.NothingFound |
|
} |
|
|
|
return |
|
}
|
|
|