123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526 |
- 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
- }
|