anniversary.go 6.33 KB
package cp_m

import (
	"fmt"
	"git.hilo.cn/hilo-common/domain"
	"git.hilo.cn/hilo-common/resource/mysql"
	"github.com/bluele/gcache"
	"hilo-user/_const/enum/cp_e"
	"hilo-user/domain/model/res_m"
	"hilo-user/domain/model/user_m"
	"time"
)

// CpAnniversary  cp纪念日
type CpAnniversary struct {
	mysql.Entity
	Type           cp_e.AnniversaryItemType
	CpId           mysql.ID
	UserId1        mysql.ID
	UserId2        mysql.ID
	Content        string
	Timestamp      int64
	IsRemind       bool
	LastRemindTime int64
	Sort           int
	MsgId          uint
}

// 初始化6个cp纪念日
// 1)我们在一起;2)XXX的生日;3)XXX的生日;4)第一次说我爱你;5)第一次亲吻;6)结婚纪念日
func InitCpAnniversary(model *domain.Model, cp CpRelation, lang string) error {
	users, err := user_m.GetUserMapByIds(model, []uint64{cp.UserId1, cp.UserId2})
	if err != nil {
		return err
	}
	if err := AddCpAnniversary(model, cp_e.AnniversaryItemTypeNormal, cp, GetTranslate(259, lang), time.Now().Unix(), true, 100, 259); err != nil {
		return err
	}
	if err := AddCpAnniversary(model, cp_e.AnniversaryItemTypeBirthday1, cp, fmt.Sprintf(GetTranslate(260, lang), users[cp.UserId1].Nick), 0, true, 0, 260); err != nil {
		return err
	}
	if err := AddCpAnniversary(model, cp_e.AnniversaryItemTypeBirthday2, cp, fmt.Sprintf(GetTranslate(260, lang), users[cp.UserId2].Nick), 0, true, 0, 260); err != nil {
		return err
	}
	if err := AddCpAnniversary(model, cp_e.AnniversaryItemTypeNormal, cp, GetTranslate(261, lang), 0, true, 0, 261); err != nil {
		return err
	}
	if err := AddCpAnniversary(model, cp_e.AnniversaryItemTypeNormal, cp, GetTranslate(262, lang), 0, true, 0, 262); err != nil {
		return err
	}
	if err := AddCpAnniversary(model, cp_e.AnniversaryItemTypeAnniversary, cp, GetTranslate(263, lang), 0, true, 0, 263); err != nil {
		return err
	}
	return nil
}

var translateCache = gcache.New(1000).LRU().Build()

func GetTranslate(msgId uint, lang string) string {
	key := fmt.Sprintf("%v-%v", msgId, lang)
	if data, err := translateCache.Get(key); err == nil {
		return data.(string)
	}
	if resMul, _ := res_m.GetResMultiTextBy(mysql.Db, msgId, lang); resMul != nil {
		_ = translateCache.SetWithExpire(key, resMul.Content, time.Hour)
		return resMul.Content
	}
	return "default"
}

// 添加cp纪念日
func AddCpAnniversary(model *domain.Model, Type cp_e.AnniversaryItemType, cp CpRelation, content string, ts int64, isRemind bool, sort int, msgId uint) error {
	return model.DB().Model(CpAnniversary{}).Create(&CpAnniversary{
		CpId:           cp.Id,
		Type:           Type,
		UserId1:        cp.UserId1,
		UserId2:        cp.UserId2,
		Content:        content,
		Timestamp:      ts,
		IsRemind:       isRemind,
		LastRemindTime: 0,
		Sort:           sort,
		MsgId:          msgId,
	}).Error
}

// 更新cp纪念日
func UpdateCpAnniversary(model *domain.Model, id mysql.ID, content string, ts int64, isRemind bool) error {
	updates := map[string]interface{}{
		"content":   content,
		"timestamp": ts,
		"is_remind": isRemind,
	}
	return model.DB().Model(CpAnniversary{}).Where("id = ?", id).Updates(updates).Error
}

func DelCpAnniversary(model *domain.Model, id mysql.ID) error {
	return model.DB().Model(CpAnniversary{}).Where("id = ? ", id).Delete(&CpAnniversary{}).Error
}

// 根据用户id获取所有纪念日
func GetAllCpAnniversary(model *domain.Model, userId mysql.ID, lang string) []CpAnniversary {
	var res []CpAnniversary
	relation, exists := GetCpRelation(model, userId)
	if !exists {
		return res
	}
	if err := model.DB().Model(CpAnniversary{}).Where("cp_id = ?", relation.Id).Order("`sort` DESC,updated_time DESC,id ASC").Find(&res).Error; err != nil {
		model.Log.Errorf("GetAllCpAnniversary fail:%v", err)
	}
	var userIds = []mysql.ID{relation.UserId1, relation.UserId2}
	users, _ := user_m.GetUserMapByIds(model, userIds)
	for i, v := range res {
		if v.CreatedTime.Equal(v.UpdatedTime) && v.MsgId > 0 {
			if v.Type == cp_e.AnniversaryItemTypeBirthday1 {
				res[i].Content = fmt.Sprintf(GetTranslate(v.MsgId, lang), users[relation.UserId1].Nick)
			} else if v.Type == cp_e.AnniversaryItemTypeBirthday2 {
				res[i].Content = fmt.Sprintf(GetTranslate(v.MsgId, lang), users[relation.UserId2].Nick)
			} else {
				res[i].Content = GetTranslate(v.MsgId, lang)
			}
		}
	}
	return res
}

// 获取所有需要提醒的纪念日
func GetNeedRemindCpAnniversary(model *domain.Model) []CpAnniversary {
	var rows, res []CpAnniversary
	if err := model.DB().Model(CpAnniversary{}).
		Where("`timestamp` > 0").
		Where("`timestamp` < ?", time.Now().Unix()).
		Where("is_remind = 1").
		Where("last_remind_time < ?", time.Now().AddDate(-1, 0, 0).Unix()). // 一年前提醒过
		Find(&rows).Error; err != nil {
		model.Log.Errorf("GetNeedRemindCpAnniversary fail:%v", err)
	}
	now := time.Now().Unix()
	for i, v := range rows {
		ts := CalcNextAnniversary(v.Timestamp, time.Local)
		if now > ts {
			res = append(res, rows[i])
		}
	}
	return res
}

// 获取cp当天需要提醒的纪念日
func GetUserTodayCpAnniversary(model *domain.Model, cpId mysql.ID, tz *time.Location) []CpAnniversary {
	var rows, res []CpAnniversary
	if err := model.DB().Model(CpAnniversary{}).
		Where("`timestamp` > 0").
		Where("`timestamp` < ?", time.Now().Unix()).
		Where("is_remind = 1").
		Where("cp_id = ?", cpId).
		Find(&rows).Error; err != nil {
		model.Log.Errorf("GetUserTodayCpAnniversary fail:%v", err)
	}
	now := time.Now().Unix()
	for i, v := range rows {
		ts := CalcNextAnniversary(v.Timestamp, tz)
		if now > ts {
			res = append(res, rows[i])
		}
	}
	return res
}

func UpdateCpAnniversaryReminded(model *domain.Model, id mysql.ID) error {
	return model.DB().Model(CpAnniversary{}).Where("id = ?", id).Update("last_remind_time", time.Now().Unix()).Error
}

// 计算下一个纪念日
func CalcNextAnniversary(timestamp int64, tz *time.Location) int64 {
	if tz == nil {
		tz = time.Local
	}
	now := time.Now()
	birthday := time.Unix(timestamp, 0)
	// 计算今年的生日日期
	thisYearBirthday := time.Date(now.Year(), birthday.Month(), birthday.Day(), 0, 0, 0, 0, tz)

	// 如果今年的生日还未到,则生日日期为今年的生日日期;否则为明年的生日日期
	var next time.Time
	if thisYearBirthday.After(now) || now.Sub(thisYearBirthday).Seconds() < 86400 {
		next = thisYearBirthday
	} else {
		next = thisYearBirthday.AddDate(1, 0, 0)
	}

	// 计算时间戳
	nextTimestamp := next.Unix()
	return nextTimestamp
}