...
 
Commits (90)
package country_e
import "git.hilo.cn/hilo-common/resource/mysql"
// 国家角色
type CountryMgrRole mysql.Type
const (
// 国家管理员
CountryMgrManager CountryMgrRole = 1
// 国家助理
CountryMgrAssistant CountryMgrRole = 2
)
// 角色权限
type ManagerPrivilegeItem mysql.Type
const (
// 重置用户头像
ManagerPrivilegeItemResetAvatar ManagerPrivilegeItem = 1
// 重置群组头像
ManagerPrivilegeItemResetFaceUrl ManagerPrivilegeItem = 2
// 删除广播
ManagerPrivilegeItemDeleteGlobalBroadcast ManagerPrivilegeItem = 3
)
package cp_e
type CpAchievement int
const (
CpAchievementLevel CpAchievement = 1 // 等级
CpAchievementVisitors CpAchievement = 2 // 空间访问人数
CpAchievementMonthRank CpAchievement = 3 // 月榜最高
CpAchievementWeekRank CpAchievement = 4 // 周榜最高
CpAchievementDayRank CpAchievement = 5 // 日榜最高
)
package cp_e
type AnniversaryItemType int
const (
AnniversaryItemTypeNormal AnniversaryItemType = 0 // 普通类型
AnniversaryItemTypeAvatar AnniversaryItemType = 1 // 头像类型
AnniversaryItemTypeBirthday1 AnniversaryItemType = 2 // user1的生日
AnniversaryItemTypeBirthday2 AnniversaryItemType = 3 // user2的生日
AnniversaryItemTypeAnniversary AnniversaryItemType = 4 // 纪念日
)
package cp_e
import "git.hilo.cn/hilo-common/resource/mysql"
type CpInviteStatus mysql.Type
type CpCancelStatus mysql.Type
const (
//新用户
CpRelationInviteDiamond = 7777
//1.未接受2.已接受3.拒接导致退费4.过期导致退费
CpInvite CpInviteStatus = 1
CpInviteAccept CpInviteStatus = 2
CpInviteRefuse CpInviteStatus = 3
CpInviteExpired CpInviteStatus = 4
//1.未处理2.发起者已撤销3.对方已确认4.到期自动确认
CpCancel CpCancelStatus = 1
CpCancelRevoke CpCancelStatus = 2
CpCancelAccept CpCancelStatus = 3
CpCancelAcceptAuto CpCancelStatus = 4
CpConfessionGiftId = 3481 // cp礼物id
CpMaleHeadwearId = 2551 // cp绑定成功后赠送的头饰-男
CpFemaleHeadwearId = 2561 // cp绑定成功后赠送的头饰-女
)
package cp_e
import "git.hilo.cn/hilo-common/resource/mysql"
const (
EffectDays = 30 // 30天有效期
CpHeadwearId = 2571
)
type CpLevel int
const (
CpLevel0 CpLevel = 0 // 无称号
CpLevel1 CpLevel = 1 // 恋爱CP
CpLevel2 CpLevel = 2 // 甜蜜CP
CpLevel3 CpLevel = 3 // 忠诚CP
CpLevel4 CpLevel = 4 // 炽热CP
CpLevel5 CpLevel = 5 // 荣耀CP
CpLevelMax = CpLevel5
)
var (
// cp等级积分
CpLevelPoints = map[CpLevel]mysql.Num{
CpLevel0: 0,
CpLevel1: 200000,
CpLevel2: 800000,
CpLevel3: 1000000,
CpLevel4: 3000000,
CpLevel5: 10000000,
}
// cp等级icon // todo ui
CpLevelIcon = map[CpLevel]string{
CpLevel0: "icon0.png",
CpLevel1: "icon1.png",
CpLevel2: "icon2.png",
CpLevel3: "icon3.png",
CpLevel4: "icon4.png",
CpLevel5: "icon5.png",
}
// cp等级称号
CpLevelTitle = map[CpLevel]uint{
CpLevel1: 252,
CpLevel2: 253,
CpLevel3: 254,
CpLevel4: 255,
CpLevel5: 256,
}
// cp特权名称
CpPrivilegeNameMsgId = map[CpPrivilege]uint{
CpPrivilegeSpace: 234,
CpPrivilegeBanner: 235,
CpPrivilegeMedal: 236,
CpPrivilegeCert: 237,
CpPrivilegeRoomEffect: 238,
CpPrivilegeHeadwear: 239,
CpPrivilegeActiveProfile: 240,
CpPrivilegeMicEffect: 241,
}
// cp特权描述
CpPrivilegeDescMsgId = map[CpPrivilege]uint{
CpPrivilegeSpace: 264,
CpPrivilegeBanner: 265,
CpPrivilegeMedal: 266,
CpPrivilegeCert: 267,
CpPrivilegeRoomEffect: 268,
CpPrivilegeHeadwear: 269,
CpPrivilegeActiveProfile: 270,
CpPrivilegeMicEffect: 271,
}
// cp特权icon
CpPrivilegeIcon = map[CpPrivilege]map[CpLevel]string{
CpPrivilegeSpace: {CpLevel0: "https://image.whoisamy.shop/hilo/resource/cp/cp_p_space.png", CpLevel1: "https://image.whoisamy.shop/hilo/resource/cp/cp_p_space.png", CpLevel2: "https://image.whoisamy.shop/hilo/resource/cp/cp_p_space.png", CpLevel3: "https://image.whoisamy.shop/hilo/resource/cp/cp_p_space.png", CpLevel4: "https://image.whoisamy.shop/hilo/resource/cp/cp_p_space.png", CpLevel5: "https://image.whoisamy.shop/hilo/resource/cp/cp_p_space.png"},
CpPrivilegeBanner: {CpLevel1: "https://image.whoisamy.shop/hilo/resource/cp/cp_p_banner1.png", CpLevel2: "https://image.whoisamy.shop/hilo/resource/cp/cp_p_banner2.png", CpLevel3: "https://image.whoisamy.shop/hilo/resource/cp/cp_p_banner3.png", CpLevel4: "https://image.whoisamy.shop/hilo/resource/cp/cp_p_banner4.png", CpLevel5: "https://image.whoisamy.shop/hilo/resource/cp/cp_p_banner5.png"},
CpPrivilegeMedal: {CpLevel1: "https://image.whoisamy.shop/hilo/resource/cp/cp_p_medal1.png", CpLevel2: "https://image.whoisamy.shop/hilo/resource/cp/cp_p_medal2.png", CpLevel3: "https://image.whoisamy.shop/hilo/resource/cp/cp_p_medal3.png", CpLevel4: "https://image.whoisamy.shop/hilo/resource/cp/cp_p_medal4.png", CpLevel5: "https://image.whoisamy.shop/hilo/resource/cp/cp_p_medal5.png"},
CpPrivilegeCert: {CpLevel0: "https://image.whoisamy.shop/hilo/resource/cp/cp_p_cert0.png", CpLevel1: "https://image.whoisamy.shop/hilo/resource/cp/cp_p_cert1.png", CpLevel2: "https://image.whoisamy.shop/hilo/resource/cp/cp_p_cert2.png", CpLevel3: "https://image.whoisamy.shop/hilo/resource/cp/cp_p_cert3.png", CpLevel4: "https://image.whoisamy.shop/hilo/resource/cp/cp_p_cert4.png", CpLevel5: "https://image.whoisamy.shop/hilo/resource/cp/cp_p_cert5.png"},
CpPrivilegeRoomEffect: {CpLevel2: "https://image.whoisamy.shop/hilo/resource/cp/cp_p_enter2.png", CpLevel3: "https://image.whoisamy.shop/hilo/resource/cp/cp_p_enter3.png", CpLevel4: "https://image.whoisamy.shop/hilo/resource/cp/cp_p_enter4.png", CpLevel5: "https://image.whoisamy.shop/hilo/resource/cp/cp_p_enter5.png"},
CpPrivilegeHeadwear: {CpLevel3: "https://image.whoisamy.shop/hilo/resource/cp/cp_p_headwear.png", CpLevel4: "https://image.whoisamy.shop/hilo/resource/cp/cp_p_headwear.png", CpLevel5: "https://image.whoisamy.shop/hilo/resource/cp/cp_p_headwear.png"},
CpPrivilegeActiveProfile: {CpLevel4: "https://image.whoisamy.shop/hilo/resource/cp/cp_p_profile.png", CpLevel5: "https://image.whoisamy.shop/hilo/resource/cp/cp_p_profile.png"},
CpPrivilegeMicEffect: {CpLevel5: "https://image.whoisamy.shop/hilo/resource/cp/cp_p_mic.png"},
}
)
type CpPrivilege int
const (
CpPrivilegeSpace CpPrivilege = 1 // 空间
CpPrivilegeBanner CpPrivilege = 2 // 横幅
CpPrivilegeMedal CpPrivilege = 3 // 等级勋章
CpPrivilegeCert CpPrivilege = 4 // 证书
CpPrivilegeRoomEffect CpPrivilege = 5 // 进场特效
CpPrivilegeHeadwear CpPrivilege = 6 // 头像头饰
CpPrivilegeActiveProfile CpPrivilege = 7 // 动态资料卡
CpPrivilegeMicEffect CpPrivilege = 8 // 麦位特效
)
package gift_e
import "git.hilo.cn/hilo-common/resource/mysql"
type GiftOperateSceneType mysql.Type
const (
//匹配声网中场景
MatchVedioSceneType GiftOperateSceneType = 1
// 私聊
PriveChatSceneType GiftOperateSceneType = 2
//1对1视频
VideoSceneType GiftOperateSceneType = 3
//群组
GroupSceneType GiftOperateSceneType = 4
)
type ResGiftAvatarType = mysql.Type
const (
SendGiftCpGiftAvatarType ResGiftAvatarType = 1 //周CP
MonthlyWealthGiftAvatarType ResGiftAvatarType = 2 //月冠财富榜
MonthlyCharmGiftAvatarType ResGiftAvatarType = 3 //月冠魅力榜
MonthlyPayGiftAvatarType ResGiftAvatarType = 4 //月冠充值榜
WeekStarGiftAvatarType ResGiftAvatarType = 5 //周星榜
CountryStarGiftAvatarType ResGiftAvatarType = 6 // 国家之星
)
type GiftPrivateRecordType = mysql.Type
const (
PrivateRecord GiftPrivateRecordType = 1
VideoTradeUnion GiftPrivateRecordType = 2
PrivateRecordBag GiftPrivateRecordType = 3
)
type GiftColumnType = uint16
const (
GiftColumnGift GiftColumnType = 1 // 礼物
GiftColumnRomance GiftColumnType = 2 // 浪漫
GiftColumnCountry GiftColumnType = 3 // 国家
GiftColumnCustom GiftColumnType = 4 // 定制
)
type GiftTagType = uint16
const (
GiftTagMedal GiftTagType = 1 // 勋章礼物
GiftTagWeeklyStar GiftTagType = 2 // 周星礼物
)
type GiftEntryType = uint16
const (
GiftEntryWeeklyStar GiftEntryType = 1 // 周星活动入口
GiftEntryWeeklyCp GiftEntryType = 2 // 周CP活动入口
GiftEntryMedal GiftEntryType = 3 // 勋章激活动入口
GiftEntryCountryStar GiftEntryType = 4 // 国家之星活动入口
)
package groupPower_e
import "git.hilo.cn/hilo-common/resource/mysql"
//国家势力状态
type GroupPowerStatus = mysql.Type
const (
//上架
GroupPowerUserHas GroupPowerStatus = 1
//未上架
GroupPowerUserNo GroupPowerStatus = 2
//解散
GroupPowerDissolve GroupPowerStatus = 3
)
//国家势力用户角色
type GroupPowerUserRole = mysql.Type
const (
// 普通用户
GroupPowerUserRoleUser GroupPowerUserRole = 1
// 势力主
GroupPowerUserRoleMgr GroupPowerUserRole = 2
// 管理员
GroupPowerUserRoleAdmin GroupPowerUserRole = 3
)
//国家势力日志操作类型
type GroupPowerUserLogType = mysql.Type
const (
//加入
GroupPowerUserLogTypeUserJoin GroupPowerUserLogType = 1
//用户自己离开
GroupPowerUserLogTypeUserLeave GroupPowerUserLogType = 2
//运营平台赋予管理者
GroupPowerUserLogTypeOwerJoin GroupPowerUserLogType = 3
//管理人让用户离开
GroupPowerUserLogTypeMgrLeave GroupPowerUserLogType = 4
//管理人解散
GroupPowerUserLogDissolve GroupPowerUserLogType = 5
)
type GroupPowerDiamondLogType = mysql.Type
const (
//群组原因加入
GroupPowerDiamondLogTypeByGroup GroupPowerDiamondLogType = 1
//群主原因加入
GroupPowerDiamondLogTypeByGroupOwer GroupPowerDiamondLogType = 2
)
type PowerSupportAwardState = uint
const (
PowerSuppportNo PowerSupportAwardState = 0 // 未达到要求
PowerSuppportAwarded PowerSupportAwardState = 1 // 已经领取
PowerSuppportWaiting PowerSupportAwardState = 2 // 待领取
)
package group_e
import "git.hilo.cn/hilo-common/resource/mysql"
type MsgStatusGroupUser = mysql.Type
const (
//正常: 灰点+震动
NormalMsgStatusGroupUser MsgStatusGroupUser = 0
//静音:灰点
MuteMsgStatusGroupUser MsgStatusGroupUser = 1
//免打扰:什么也没有
DoNotDisturbMsgStatusGroupUser MsgStatusGroupUser = 2
OverseaRoom = 1
LocalRoom = 2
)
// 公屏消息
type TypePublicScreenMsg = mysql.Type
const (
UserJoinPublicScreenMsg TypePublicScreenMsg = 1 // 加入群组
UserKickPublicScreenMsg TypePublicScreenMsg = 2 // 踢出房间
UserBannedPublicScreenMsg TypePublicScreenMsg = 3 // 拉黑用户
RoleAssignedPublicScreenMsg TypePublicScreenMsg = 4 // 添加角色
RoleRemovedPublicScreenMsg TypePublicScreenMsg = 5 // 移除角色
ClientSendMsgLocal TypePublicScreenMsg = 6 // 客户端占用
RollDiceMsg TypePublicScreenMsg = 7 // 掷骰子结果
GroupGiftMsg TypePublicScreenMsg = 8 //全服礼物
GroupSupportH5 TypePublicScreenMsg = 9 //群组支持H5
JumpMessage TypePublicScreenMsg = 10 // 可跳转的公屏消息
RocketAwardMsg TypePublicScreenMsg = 11 // 火箭获奖消息
LockyboxAwardMsg TypePublicScreenMsg = 12 // 幸运盒子公屏中奖
FruitMachineAwardMsg TypePublicScreenMsg = 13 // 水果机中奖
EnterRoomMsg TypePublicScreenMsg = 14 // 用户进入房间
)
// 信令消息(不显示公屏工,不记入消息历史,不影响未读数)
type TypeSignalMsg = mysql.Type
const (
GroupEditProfileSignal TypeSignalMsg = 1
GroupRoleChangeSignal TypeSignalMsg = 2
GroupMicChangeSignal TypeSignalMsg = 3 //保留
GroupMsgBannedSignal TypeSignalMsg = 4
GroupMemberRemoveSignal TypeSignalMsg = 5
GroupGiftSignal TypeSignalMsg = 6 //礼物
GroupMicInSignal TypeSignalMsg = 7
GroupMicOutSignal TypeSignalMsg = 8
GroupMicLockSignal TypeSignalMsg = 9
GroupMicUnLockSignal TypeSignalMsg = 10
GroupMicSpeechOpenSignal TypeSignalMsg = 11
GroupMicSpeechCloseSignal TypeSignalMsg = 12
GroupKickOut TypeSignalMsg = 13 //保留
GroupSocketMicOutSignal TypeSignalMsg = 14 //保留
GroupInviteMicInSignal TypeSignalMsg = 15 //邀请上麦保留
GroupInSignal TypeSignalMsg = 16 //进入房间,进房特效
GroupMicEmoji TypeSignalMsg = 17 //麦上表情
GroupLuckyWheel TypeSignalMsg = 18 //转盘的通知信令
GroupOutSignal TypeSignalMsg = 19 //离开房间
GroupRocketState TypeSignalMsg = 20 //火箭状态变化
GroupOnlineUser TypeSignalMsg = 21 //房间在线用户信息
GroupMicChange TypeSignalMsg = 22 //房间麦位上的变量
GroupMemberInvite TypeSignalMsg = 23 //房间-邀请用户成为会员
GroupRoleChange TypeSignalMsg = 24 //房间-用户群组身份变化
GroupClearScreen TypeSignalMsg = 25 //房间-清理公屏
GroupRoomGiftSignal TypeSignalMsg = 26 //全房间送礼物
)
//群组麦位数量类型
type GroupMicNumType = mysql.Type
const (
OneMicNumType GroupMicNumType = 5
TwoMicNumType GroupMicNumType = 10
ThreeMicNumType GroupMicNumType = 3
FourMicNumType GroupMicNumType = 4
SixMicNumType GroupMicNumType = 6
SevenMicNumType GroupMicNumType = 7
EightMicNumType GroupMicNumType = 8
NineMicNumType GroupMicNumType = 9
ElevenMicNumType GroupMicNumType = 11
TwelveMicNumType GroupMicNumType = 12
ThirteenMicNumType GroupMicNumType = 13
FourteenMicNumType GroupMicNumType = 14
FifteenMicNumType GroupMicNumType = 15
SixteenMicNumType GroupMicNumType = 16
SeventeenMicNumType GroupMicNumType = 17
EighteenMicNumType GroupMicNumType = 18
NineteenMicNumType GroupMicNumType = 19
TwentyMicNumType GroupMicNumType = 20
//5个麦位
FiveMicNumType GroupMicNumType = 1
//10个麦位
TenMicNumType GroupMicNumType = 2
//
SUPPORT_LEVEL_BOUNDARY_HOUR = 0
SUPPORT_LEVEL_PERIOD_DAY = 7
)
......@@ -5,55 +5,16 @@ import "git.hilo.cn/hilo-common/resource/mysql"
type MsgIdType = uint
const (
DEFAULT_LANG = "en"
DefaultLang = "en"
)
type ResMedalType = mysql.Type
const (
Wealth ResMedalType = 1
Charm ResMedalType = 2
LoveForAll ResMedalType = 3
StartForAll ResMedalType = 4
MoonForAll ResMedalType = 5
MarryMe ResMedalType = 6
RoomRocket ResMedalType = 7
Actity ResMedalType = 8
FruitKing ResMedalType = 9
BoxKing ResMedalType = 10
Helicopter ResMedalType = 11
Roadster ResMedalType = 12
Watermelon ResMedalType = 13
Kiss ResMedalType = 14
Love ResMedalType = 15
Chick ResMedalType = 16
SportsCar ResMedalType = 17
Rocket ResMedalType = 18
Tower ResMedalType = 19
Eagle ResMedalType = 20
Lion ResMedalType = 21
Vacation ResMedalType = 22
RomanticNight ResMedalType = 23
SweetCouple ResMedalType = 24
Castle ResMedalType = 25
WeddingCar ResMedalType = 26
VideoChat ResMedalType = 27
)
type ResMedalScope = mysql.Type
const (
//私有,只能时管理人发放
Private ResMedalScope = 1
//公有,自己获取
Public ResMedalScope = 2
)
type ResNameplateType = mysql.Type
type ResNameplateObtainType = mysql.Type
type ResNameplateScope = mysql.Type
type ResUserBag = mysql.Type
type ResPropertyAvatarType = mysql.Type
const (
ResUserBagGift ResUserBag = 1 // 背包道具-礼物
......
package user_e
import "git.hilo.cn/hilo-common/resource/mysql"
import (
"git.hilo.cn/hilo-common/resource/mysql"
)
type ThirdPartyType = mysql.Type
......@@ -12,6 +14,17 @@ const (
WeChat ThirdPartyType = 5
)
type CountType mysql.Type
const (
//我喜欢的数量
CountTypeLike CountType = 1
//我拉黑的数量
CountTypeBlock CountType = 2
//我被喜欢的次数
CountTypeLikeMe CountType = 3
)
type UserStatus mysql.Type
const (
......@@ -24,8 +37,33 @@ const (
type UserVipType = mysql.Type
const (
//
UserMan = 1
//
UserWomen = 2
//购买
UserVipTypeBuy UserVipType = 1
//赠送
UserVipTypeGive UserVipType = 2
)
type UserLikeOperateType = mysql.Type
const (
//增加喜欢
LikeAdd UserLikeOperateType = 1
//取消喜欢
LikeCancel UserLikeOperateType = 2
)
type UserLikeSceneType = mysql.Type
const (
Match UserLikeSceneType = 1
Video UserLikeSceneType = 2
)
type InteractionType = mysql.Type
const (
InteractPrivateGift InteractionType = 1
InteractVideo InteractionType = 2
)
package group_k
//在房间的人
const groupRoomLiving = "group_room_living"
func GetPrefixGroupRoomLiving() string {
return groupRoomLiving
}
......@@ -4,6 +4,8 @@ import (
"fmt"
"git.hilo.cn/hilo-common/resource/mysql"
"hilo-user/_const/redis_key"
"strconv"
"strings"
)
const (
......@@ -28,3 +30,9 @@ func GetExternalIdToUidKey(externalId mysql.Str) string {
func GetCodeToUidKey(code mysql.Str) string {
return redis_key.ReplaceKey(UserCodeToUIdStr, code)
}
const syncTimHiloLock = "sync_tim_hilo_{userId}"
func GetKeySyncTimHilo(userId uint64) string {
return strings.Replace(syncTimHiloLock, "{userId}", strconv.FormatUint(userId, 10), -1)
}
package cp_cron
import (
"git.hilo.cn/hilo-common/_const/enum/msg_e"
"git.hilo.cn/hilo-common/domain"
"git.hilo.cn/hilo-common/resource/config"
"github.com/robfig/cron"
"hilo-user/domain/model/cp_m"
"hilo-user/domain/model/msg_m"
"hilo-user/domain/model/user_m"
)
// 纪念日
type CpAnniversaryNoticeMsg struct {
Identifier string `json:"identifier"`
Content string `json:"content"`
Timestamp int64 `json:"timestamp"`
}
func CpAnniversaryNotice() {
c := cron.New()
// 1小时操作一次
spec := "0 0 */1 * * ?"
if !config.AppIsRelease() {
// 测服1分钟
spec = "0 * * * * ?"
}
_ = c.AddFunc(spec, func() {
var model = domain.CreateModelNil()
anniversary := cp_m.GetNeedRemindCpAnniversary(model)
if len(anniversary) <= 0 {
return
}
var userIds []uint64
for _, v := range anniversary {
userIds = append(userIds, v.UserId1)
userIds = append(userIds, v.UserId2)
}
users, err := user_m.GetUserMapByIds(model, userIds)
if err != nil {
model.Log.Errorf("GetUserMapByIds fail:%v", err)
}
for _, v := range anniversary {
content1 := cp_m.GetTranslate(285, users[v.UserId1].Language)
content2 := cp_m.GetTranslate(285, users[v.UserId2].Language)
record1 := msg_m.NewUserRecord(model, v.UserId1, msg_e.CpAnniversaryNotice, content1, 0, "", "", "", "", "")
record2 := msg_m.NewUserRecord(model, v.UserId2, msg_e.CpAnniversaryNotice, content2, 0, "", "", "", "", "")
err1, err2 := record1.Persistent(), record2.Persistent()
if err1 != nil || err2 != nil {
model.Log.Errorf("NewUserRecord fail:%v-%v", err1, err2)
return
}
//if err := tencentyun.BatchSendCustomMsg(model, 1, users[0].ExternalId, []string{users[1].ExternalId}, string(data), "cp纪念日"); err != nil {
// model.Log.Errorf("BatchSendCustomMsg fail:%v", err)
//}
//if err := tencentyun.BatchSendCustomMsg(model, 1, users[1].ExternalId, []string{users[0].ExternalId}, string(data), "cp纪念日"); err != nil {
// model.Log.Errorf("BatchSendCustomMsg fail:%v", err)
//}
if err := cp_m.UpdateCpAnniversaryReminded(model, v.ID); err != nil {
model.Log.Errorf("UpdateCpAnniversaryReminded fail:%v", err)
}
}
})
c.Start()
}
package cp_cron
import (
"git.hilo.cn/hilo-common/domain"
"git.hilo.cn/hilo-common/resource/config"
"github.com/robfig/cron"
"hilo-user/domain/model/cp_m"
)
func ClearCpExpire() {
c := cron.New()
spec := "0 0 */1 * * ?"
if !config.AppIsRelease() {
spec = "0 * * * * ?"
}
// 1小时清理一次
_ = c.AddFunc(spec, func() {
var model = domain.CreateModelNil()
if err := cp_m.ClearExpireCpPoints(model); err != nil {
model.Log.Errorf("ClearExpireCpPoints fail:%v", err)
}
})
c.Start()
}
package cp_cron
import (
"git.hilo.cn/hilo-common/_const/enum/diamond_e"
"git.hilo.cn/hilo-common/domain"
"git.hilo.cn/hilo-common/mylogrus"
"git.hilo.cn/hilo-common/resource/config"
"git.hilo.cn/hilo-common/utils"
"github.com/robfig/cron"
"hilo-user/_const/enum/cp_e"
"hilo-user/domain/model/cp_m"
"hilo-user/domain/model/diamond_m"
"time"
)
// cp邀请、解除到期结算
func CpInviteCancelInit() {
if !config.IsMaster() {
return
}
mylogrus.MyLog.Infof("CpInviteCancelInit")
// 每2min监测一次
c := cron.New()
spec := "0 */2 * * * *"
if !config.AppIsRelease() {
spec = "0 */1 * * * ?" // 测服每1分钟
}
_ = c.AddFunc(spec, func() {
defer utils.CheckGoPanic()
model := domain.CreateModelNil()
// 获取超过24小时没被处理的cp邀请
inviteList, err := cp_m.GetCpInviteByTime(model, time.Now().AddDate(0, 0, -1))
if err != nil {
model.Log.Errorf("CpInviteCancelInit err:%v", err)
return
}
for _, v := range inviteList {
model := domain.CreateModelContext(model.MyContext)
model.Log.Infof("CpInviteCancelInit invite:%+v", v)
err = model.Transaction(func(model *domain.Model) error {
// 更新邀请记录
err = cp_m.UpdateStatusCpInvite(model, v.Id, cp_e.CpInviteExpired)
if err != nil {
model.Log.Errorf("CpInviteCancelInit Id:%d, err:%v", v.Id, err)
return err
}
// 退费
err = diamond_m.ChangeDiamondAccountDetail(model, diamond_e.CpInviteRefund, v.Id, v.UserId, v.DiamondNum)
if err != nil {
model.Log.Errorf("CpInviteCancelInit Id:%d, err:%v", v.Id, err)
return err
}
return nil
})
if err != nil {
model.Log.Errorf("CpInviteCancelInit invite:%+v, err:%v", v, err)
continue
}
time.Sleep(time.Millisecond * 10)
}
// 获取超过24小时没被处理的cp解除申请
cancelList, err := cp_m.GetCpCancelByTime(model, time.Now().AddDate(0, 0, -1))
if err != nil {
model.Log.Errorf("CpInviteCancelInit err:%v", err)
return
}
for _, v := range cancelList {
model := domain.CreateModelContext(model.MyContext)
model.Log.Infof("CpInviteCancelInit cancel:%+v", v)
err = model.Transaction(func(model *domain.Model) error {
// 更新解除记录
err = cp_m.UpdateStatusCpCancel(model, v.Id, cp_e.CpCancelAcceptAuto)
if err != nil {
model.Log.Errorf("CpInviteCancelInit Id:%d, err:%v", v.Id, err)
return err
}
// 删除cp关系表的记录
err = cp_m.DelCpRelation(model, v.UserId, v.RecUserId)
if err != nil {
model.Log.Errorf("CpInviteCancelInit Id:%d, err:%v", v.Id, err)
return err
}
return nil
})
if err != nil {
model.Log.Errorf("CpInviteCancelInit cancel:%+v, err:%v", v, err)
continue
}
time.Sleep(time.Millisecond * 10)
}
})
c.Start()
}
package cron
import (
"git.hilo.cn/hilo-common/resource/config"
"hilo-user/cron/cp_cron"
"hilo-user/cron/gift_cron"
"hilo-user/cron/user_cron"
)
func Init() {
user_cron.SyncGiftRecommendUsers() // 同步送礼推荐用户,多进程都需要执行
if !config.IsMaster() {
return
}
//gift_cron.SendGiftEventInit() // 礼物消息
//gift_cron.GiftRemark() // 礼物消息补偿
gift_cron.SendGiftEvent() // 送礼事件
cp_cron.ClearCpExpire() // 清理过期cp
cp_cron.CpAnniversaryNotice() // cp纪念日
cp_cron.CpInviteCancelInit() // cp邀请、解除到期结算
}
package gift_cron
import (
"git.hilo.cn/hilo-common/domain"
"git.hilo.cn/hilo-common/resource/config"
"github.com/robfig/cron"
"hilo-user/domain/model/event_m"
)
// 补偿检查mark=2
func GiftRemark() {
c := cron.New()
// 每5分钟
spec := "0 */5 * * * ?"
if !config.AppIsRelease() {
spec = "0 * * * * ?" // 测服1分钟
}
_ = c.AddFunc(spec, func() {
var model = domain.CreateModelNil()
unmarks, err := event_m.FetchUnMarkEvents(model, 10)
if err != nil {
model.Log.Errorf("FetchUnMarkEvents fail:%v", err)
return
}
for _, unmark := range unmarks {
model.Log.Infof("FetchUnMarkEvent start:%v", unmark.ID)
// 重新入库
if err := event_m.AddUnMarkEvent(model, &event_m.EventGiftSend{
Proto: unmark.Proto,
Payload: unmark.Payload,
MarkHiloGroup: unmark.MarkHiloGroup,
MarkHiloUser: unmark.MarkHiloUser,
Mark: unmark.Mark, // 不能影响别的服务的mark状态
}); err != nil {
model.Log.Errorf("FetchUnMarkEvent add unmark fail:%v", err)
continue
}
// 旧的标记已处理
unmark.Model = model
if err := unmark.MarkDone(); err != nil {
model.Log.Errorf("FetchUnMarkEvent mark fail:%v", err)
}
model.Log.Infof("FetchUnMarkEvent success:%v", unmark.ID)
}
})
c.Start()
}
package gift_cron
import (
"git.hilo.cn/hilo-common/mycontext"
"git.hilo.cn/hilo-common/mylogrus"
"hilo-user/domain/service/event_s"
"time"
)
// 送礼事件
func SendGiftEventInit() {
mylogrus.MyLog.Infof("SendGiftEventInit")
go func() {
ticker := time.NewTicker(time.Millisecond * 500)
defer ticker.Stop()
for {
select {
case <-ticker.C:
//start := time.Now()
myCtx := mycontext.CreateMyContext(nil)
// 消费送礼事件
if err := event_s.NewGiftSendEventService(myCtx).Consume(); err != nil {
myCtx.Log.Errorf("eventServcie consume fail:%v", err)
} else {
//myCtx.Log.Infof("eventServcie consume success,cost:%v", time.Now().Sub(start))
}
}
}
}()
}
package gift_cron
import (
"git.hilo.cn/hilo-common/domain"
"github.com/jinzhu/now"
"hilo-user/_const/enum/cp_e"
"hilo-user/domain/cache/gift_c"
"hilo-user/domain/event/gift_ev"
"hilo-user/domain/model/cp_m"
"time"
)
// 送礼事件
func SendGiftEvent() {
//if !config.IsMaster() {
// return
//}
go func() {
for true {
model := domain.CreateModelNil()
if sendGiftEvent := gift_c.BLPopQueueSendGift(model); sendGiftEvent != nil {
cpGiftEvent(model, sendGiftEvent) // cp送礼
}
}
}()
}
// 送礼增加cp等级
// 送礼增加cp排行榜
func cpGiftEvent(model *domain.Model, sendGiftEvent *gift_ev.SendGiftEvent) {
// 只处理cp礼物
if !sendGiftEvent.ResGift.Cp {
return
}
for _, receiverUid := range sendGiftEvent.ReceiveUserIds {
diamonds := sendGiftEvent.GiftN * sendGiftEvent.ResGift.DiamondNum
// 有cp关系
if cpRelation, exits := cp_m.GetCpRelationPair(model, sendGiftEvent.SendUserId, receiverUid); exits {
if err := cp_m.AddCpLevelPoints(model, cpRelation, diamonds, sendGiftEvent.SceneType, sendGiftEvent.SceneUid); err != nil {
model.Log.Errorf("AddCpLevelPoints fail:%v", err)
}
if err := cp_m.AddCpDayRank(model, cpRelation, diamonds); err != nil {
model.Log.Errorf("AddCpDayRank fail:%v", err)
}
// 检查最新的等级
if cpLevel := cp_m.GetCpLevel(model, cpRelation.Id); cpLevel.CpId >= 0 {
points := cpLevel.Points + cp_e.CpLevelPoints[cpLevel.Level]
if err := cp_m.UpdateCpAchievement(model, cpLevel.CpId, cpRelation.UserId1, cpRelation.UserId2, cp_e.CpAchievementLevel, points); err != nil {
model.Log.Errorf("UpdateCpAchievement fail:%v", err)
}
}
// 检查最高的分数
for _, queryType := range []string{"day", "week", "month"} {
var beginDate, endDate string
var cpAchievementType cp_e.CpAchievement
switch queryType {
case "day":
beginDate, endDate = time.Now().Format("2006-01-02"), time.Now().Format("2006-01-02")
cpAchievementType = cp_e.CpAchievementDayRank
case "week":
beginDate = now.BeginningOfWeek().Format("2006-01-02")
endDate = now.EndOfWeek().Format("2006-01-02")
cpAchievementType = cp_e.CpAchievementWeekRank
case "month":
beginDate = now.BeginningOfMonth().Format("2006-01-02")
endDate = now.EndOfMonth().Format("2006-01-02")
cpAchievementType = cp_e.CpAchievementMonthRank
}
if data := cp_m.GetCpDayRank(model, beginDate, endDate, cpRelation.Id); data.Score > 0 {
if err := cp_m.UpdateCpAchievement(model, cpRelation.Id, cpRelation.UserId1, cpRelation.UserId2, cpAchievementType, data.Score); err != nil {
model.Log.Errorf("UpdateCpAchievement fail:%v", err)
}
}
}
// 检查最新日周月榜单
return // 业务场景允许提前break(cp是唯一的)
}
}
}
package user_cron
import (
"git.hilo.cn/hilo-common/domain"
"github.com/robfig/cron"
"hilo-user/domain/model/recommend_m"
)
// 定期同步礼物推荐用户
func SyncGiftRecommendUsers() {
go recommend_m.SyncPastTop50SendGiftUsers(domain.CreateModelNil()) // 启动先同步一次
c := cron.New()
spec := "0 */5 * * * ?"
_ = c.AddFunc(spec, func() {
var model = domain.CreateModelNil()
recommend_m.SyncPastTop50SendGiftUsers(model)
})
c.Start()
}
package cp_cv
import (
"hilo-user/_const/enum/cp_e"
"hilo-user/cv/user_cv"
)
// cp信息
type CvCpBase struct {
UserInfo user_cv.UserTiny `json:"userInfo"` // 用户信息
CpUserInfo user_cv.UserTiny `json:"cpUserInfo,omitempty"` // cp用户信息
}
type CvCpAnniversary struct {
Type cp_e.AnniversaryItemType `json:"type"` // 列表类型 0:普通 1:头像
CpInfo *CvCpBase `json:"cpInfo,omitempty"` // cp信息,type=1(头像)时候用到
Id uint64 `json:"id"` // 记录id
Content string `json:"content"` // 纪念日内容
OriginTimestamp int64 `json:"originTimestamp"` // 纪念日的时间
Timestamp int64 `json:"timestamp"` // 下次纪念日时间戳
IsRemind bool `json:"isRemind"` // 是否提醒
CanDel bool `json:"canDel"` // 能否删除
IsTop bool `json:"isTop"` // 是否置顶
}
package cp_cv
import (
"hilo-user/_const/enum/cp_e"
"hilo-user/cv/user_cv"
)
// cp信息
type CvCp struct {
CpUserInfo *user_cv.CvUserBase `json:"cpUserInfo"` // cp用户信息
CpLevel CvCpLevel `json:"cpLevel"` // cp等级
MyPrivilegeList []CvPrivilege `json:"myPrivilegeList"` // 等级特权
CreatedUnix int64 `json:"createdUnix"` // cp创建时间
CpDays int `json:"cpDays"` // cp天数
}
// cp关系
type CvCpRelation struct {
CpId uint64 `json:"cpId"`
UserId uint64 `json:"userId"`
CpUserId uint64 `json:"cpUserId"`
CpUserAvatar string `json:"cpUserAvatar,omitempty"`
}
// cp进场特效信息
type CvCpEntryEffect struct {
CpLevel cp_e.CpLevel `json:"cpLevel"`
CpUserAvatar string `json:"cpUserAvatar"`
CpEntryEffect bool `json:"cpEntryEffect"`
}
package cp_cv
type CheckCpRelationRes struct {
Diamond uint32 `json:"diamond"`
Msg string `json:"msg"`
}
type CheckCpImRes struct {
}
package cp_cv
import (
"hilo-user/_const/enum/cp_e"
"hilo-user/cv/user_cv"
)
type CvCpRank struct {
CpId uint64 `json:"cpId"` // cpId
User1 *user_cv.CvUserLittle `json:"user1"` // user1
User2 *user_cv.CvUserLittle `json:"user2,omitempty"` // user2
Score uint32 `json:"score"` // 分值
CpLevel CvCpLevel `json:"cpLevel"` // cp等级
Ranking string `json:"ranking"` // 排名
}
type CvCpAchievement struct {
CpId uint64 `json:"cpId"` // cpId
User1 *user_cv.UserTiny `json:"user1"` // user1
User2 *user_cv.UserTiny `json:"user2"` // user2
CpLevel cp_e.CpLevel `json:"cpLevel"` // cpLevel
Type cp_e.CpAchievement `json:"type"` // 成就类型 1:等级 2:空间访问人数 3:月榜最高 4:周榜最高 5:日榜最高
TypeDesc string `json:"typeDesc"` // 成就类型翻译
Score uint32 `json:"score"` // 分值
TimeUnix int64 `json:"timeUnix"` // 达成成就时间戳
}
type CpTops struct {
Day []CvCpRank `json:"day"`
Week []CvCpRank `json:"week"`
}
package cp_cv
import (
"fmt"
"git.hilo.cn/hilo-common/resource/mysql"
"github.com/bluele/gcache"
"hilo-user/_const/enum/cp_e"
"hilo-user/cv/user_cv"
"hilo-user/domain/model/res_m"
"time"
)
// cp信息
type CvCpInfo struct {
UserInfo *user_cv.UserTiny `json:"userInfo"` // 用户信息
CpUserInfo *user_cv.UserTiny `json:"cpUserInfo,omitempty"` // cp用户信息
CreatedUnix int64 `json:"createdUnix"` // cp创建时间
CpDays int `json:"cpDays"` // cp天数
VisitTimes int64 `json:"visitTimes"` // 空间访问量
ApplyToUnbind bool `json:"applyToUnbind"` // 是否申请撤销cp
}
// cp等级
type CvCpLevel struct {
Level cp_e.CpLevel `json:"level"` // 等级 0:无称号 1:恋爱CP 2:甜蜜CP 3:忠诚CP 4:炽热CP 5:荣耀CP
Points uint32 `json:"points"` // CP值
StartPoints uint32 `json:"startPoints,omitempty"` // 上个等级所需CP值
EndPoints uint32 `json:"endPoints,omitempty"` // 下个等级所需CP值
ExpireAtUnix int64 `json:"expireAtUnix,omitempty"` // 有效期,时间戳
SettlementDate string `json:"settlementDate"` // 等级过期时间
MaxLevel cp_e.CpLevel `json:"maxLevel"` // cp最大的等级
Title string `json:"title,omitempty"` // 称号翻译
}
// 资源等级
type CvResLevel struct {
Level cp_e.CpLevel `json:"level"` // 等级
Icon string `json:"icon"` // 等级icon图
StartPoints uint32 `json:"startPoints"` // 上个等级所需CP值
EndPoints uint32 `json:"endPoints,omitempty"` // 下个等级所需CP值
}
// 特权信息
type CvPrivilege struct {
Type cp_e.CpPrivilege `json:"type"` // 特权id 1:空间 2:横幅 3:等级勋章 4:证书 5:进场特效 6:头像头饰 7:动态资料卡 8:麦位特效
NameMsgId uint `json:"-"` // 名称-翻译id
Name string `json:"name"` // 名称
DescMsgId uint `json:"-"` // 描述-翻译id
Desc string `json:"desc"`
Icon string `json:"icon"` // 图标
CanSwitch bool `json:"canSwitch"` // 能否开关
UserSwitch bool `json:"userSwitch"` // 用户开关
LevelList []cp_e.CpLevel `json:"levelList"` // 特权->level的反向索引
}
// cp空间页
type CvSpace struct {
CpInfo CvCpInfo `json:"cpInfo"` // cp信息
CpLevel CvCpLevel `json:"cpLevel"` // cp等级
ResLevelList []CvResLevel `json:"resLevelList"` // 资源等级列表,无称号/恋爱CP/甜蜜CP/忠诚CP/炽热CP/荣耀CP
PrivilegeList [][]CvPrivilege `json:"privilegeList"` // 等级特权
CpAnniversary []CvCpAnniversary `json:"cpAnniversary"` // 提醒的纪念日
}
var CvResLevelList = []CvResLevel{
{cp_e.CpLevel0, cp_e.CpLevelIcon[cp_e.CpLevel0], cp_e.CpLevelPoints[cp_e.CpLevel0], cp_e.CpLevelPoints[cp_e.CpLevel1]},
{cp_e.CpLevel1, cp_e.CpLevelIcon[cp_e.CpLevel1], cp_e.CpLevelPoints[cp_e.CpLevel1], cp_e.CpLevelPoints[cp_e.CpLevel2]},
{cp_e.CpLevel2, cp_e.CpLevelIcon[cp_e.CpLevel2], cp_e.CpLevelPoints[cp_e.CpLevel2], cp_e.CpLevelPoints[cp_e.CpLevel3]},
{cp_e.CpLevel3, cp_e.CpLevelIcon[cp_e.CpLevel3], cp_e.CpLevelPoints[cp_e.CpLevel3], cp_e.CpLevelPoints[cp_e.CpLevel4]},
{cp_e.CpLevel4, cp_e.CpLevelIcon[cp_e.CpLevel4], cp_e.CpLevelPoints[cp_e.CpLevel4], cp_e.CpLevelPoints[cp_e.CpLevel5]},
{cp_e.CpLevel5, cp_e.CpLevelIcon[cp_e.CpLevel5], cp_e.CpLevelPoints[cp_e.CpLevel5], cp_e.CpLevelPoints[cp_e.CpLevelMax]},
}
var (
CvPrivilege1 = CvPrivilege{cp_e.CpPrivilegeSpace, cp_e.CpPrivilegeNameMsgId[cp_e.CpPrivilegeSpace], "", cp_e.CpPrivilegeDescMsgId[cp_e.CpPrivilegeSpace], "", "", false, false, CpPrivilegeLevelList[cp_e.CpPrivilegeSpace]}
CvPrivilege2 = CvPrivilege{cp_e.CpPrivilegeBanner, cp_e.CpPrivilegeNameMsgId[cp_e.CpPrivilegeBanner], "", cp_e.CpPrivilegeDescMsgId[cp_e.CpPrivilegeBanner], "", "", false, false, CpPrivilegeLevelList[cp_e.CpPrivilegeBanner]}
CvPrivilege3 = CvPrivilege{cp_e.CpPrivilegeMedal, cp_e.CpPrivilegeNameMsgId[cp_e.CpPrivilegeMedal], "", cp_e.CpPrivilegeDescMsgId[cp_e.CpPrivilegeMedal], "", "", false, false, CpPrivilegeLevelList[cp_e.CpPrivilegeMedal]}
CvPrivilege4 = CvPrivilege{cp_e.CpPrivilegeCert, cp_e.CpPrivilegeNameMsgId[cp_e.CpPrivilegeCert], "", cp_e.CpPrivilegeDescMsgId[cp_e.CpPrivilegeCert], "", "", false, false, CpPrivilegeLevelList[cp_e.CpPrivilegeCert]}
CvPrivilege5 = CvPrivilege{cp_e.CpPrivilegeRoomEffect, cp_e.CpPrivilegeNameMsgId[cp_e.CpPrivilegeRoomEffect], "", cp_e.CpPrivilegeDescMsgId[cp_e.CpPrivilegeRoomEffect], "", "", true, false, CpPrivilegeLevelList[cp_e.CpPrivilegeRoomEffect]}
CvPrivilege6 = CvPrivilege{cp_e.CpPrivilegeHeadwear, cp_e.CpPrivilegeNameMsgId[cp_e.CpPrivilegeHeadwear], "", cp_e.CpPrivilegeDescMsgId[cp_e.CpPrivilegeHeadwear], "", "", false, false, CpPrivilegeLevelList[cp_e.CpPrivilegeHeadwear]}
CvPrivilege7 = CvPrivilege{cp_e.CpPrivilegeActiveProfile, cp_e.CpPrivilegeNameMsgId[cp_e.CpPrivilegeActiveProfile], "", cp_e.CpPrivilegeDescMsgId[cp_e.CpPrivilegeActiveProfile], "", "", true, false, CpPrivilegeLevelList[cp_e.CpPrivilegeActiveProfile]}
CvPrivilege8 = CvPrivilege{cp_e.CpPrivilegeMicEffect, cp_e.CpPrivilegeNameMsgId[cp_e.CpPrivilegeMicEffect], "", cp_e.CpPrivilegeDescMsgId[cp_e.CpPrivilegeMicEffect], "", "", false, false, CpPrivilegeLevelList[cp_e.CpPrivilegeMicEffect]}
)
var CpLevelPrivilegeList = map[cp_e.CpLevel][]CvPrivilege{
cp_e.CpLevel0: {CvPrivilege1, CvPrivilege4},
cp_e.CpLevel1: {CvPrivilege1, CvPrivilege2, CvPrivilege3, CvPrivilege4},
cp_e.CpLevel2: {CvPrivilege1, CvPrivilege2, CvPrivilege3, CvPrivilege4, CvPrivilege5},
cp_e.CpLevel3: {CvPrivilege1, CvPrivilege2, CvPrivilege3, CvPrivilege4, CvPrivilege5, CvPrivilege6},
cp_e.CpLevel4: {CvPrivilege1, CvPrivilege2, CvPrivilege3, CvPrivilege4, CvPrivilege5, CvPrivilege6, CvPrivilege7},
cp_e.CpLevel5: {CvPrivilege1, CvPrivilege2, CvPrivilege3, CvPrivilege4, CvPrivilege5, CvPrivilege6, CvPrivilege7, CvPrivilege8},
}
var CpPrivilegeLevelList = map[cp_e.CpPrivilege][]cp_e.CpLevel{
cp_e.CpPrivilegeSpace: {cp_e.CpLevel0, cp_e.CpLevel1, cp_e.CpLevel2, cp_e.CpLevel3, cp_e.CpLevel4, cp_e.CpLevel5},
cp_e.CpPrivilegeBanner: {cp_e.CpLevel1, cp_e.CpLevel2, cp_e.CpLevel3, cp_e.CpLevel4, cp_e.CpLevel5},
cp_e.CpPrivilegeMedal: {cp_e.CpLevel1, cp_e.CpLevel2, cp_e.CpLevel3, cp_e.CpLevel4, cp_e.CpLevel5},
cp_e.CpPrivilegeCert: {cp_e.CpLevel1, cp_e.CpLevel2, cp_e.CpLevel3, cp_e.CpLevel4, cp_e.CpLevel5},
cp_e.CpPrivilegeRoomEffect: {cp_e.CpLevel2, cp_e.CpLevel3, cp_e.CpLevel4, cp_e.CpLevel5},
cp_e.CpPrivilegeHeadwear: {cp_e.CpLevel3, cp_e.CpLevel4, cp_e.CpLevel5},
cp_e.CpPrivilegeActiveProfile: {cp_e.CpLevel4, cp_e.CpLevel5},
cp_e.CpPrivilegeMicEffect: {cp_e.CpLevel5},
}
func CopyCpLevelPrivilegeList(Level cp_e.CpLevel, lang string) []CvPrivilege {
privileges := make([]CvPrivilege, len(CpLevelPrivilegeList[Level]))
copy(privileges, CpLevelPrivilegeList[Level])
for i, v := range privileges {
privileges[i].Name = GetTranslate(v.NameMsgId, lang)
privileges[i].Desc = GetTranslate(v.DescMsgId, lang)
privileges[i].Icon = cp_e.CpPrivilegeIcon[v.Type][Level]
}
return privileges
}
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"
}
package headwear_cv
import (
"git.hilo.cn/hilo-common/domain"
"git.hilo.cn/hilo-common/resource/mysql"
"gorm.io/gorm"
"hilo-user/_const/enum/headwear_e"
"hilo-user/domain/model/cp_m"
"hilo-user/domain/model/res_m"
"hilo-user/domain/model/user_m"
"hilo-user/myerr"
"strconv"
"time"
)
type CvHeadwear struct {
Id uint64 `json:"id"`
Using bool `json:"using"`
PicUrl mysql.Str `json:"picUrl"`
EffectUrl mysql.Str `json:"effectUrl"`
ReverseEffectUrl mysql.Str `json:"reverseEffectUrl"`
TimeLeft int64 `json:"timeLeft"` // 离到期还有多少秒(过期则是负数)
HeadwearIcon string `json:"headwearIcon"`
}
type CvHeadwearDiamond struct {
Id uint64 `json:"id"`
PicUrl string `json:"picUrl"`
EffectUrl string `json:"effectUrl"`
DiamondNum uint32 `json:"diamondNum"`
Second uint32 `json:"second"`
Days string `json:"days"`
}
func GetCvHeadwearDiamond(pageSize int, pageIndex int) ([]CvHeadwearDiamond, error) {
headwearDiamonds := []CvHeadwearDiamond{}
if err := mysql.Db.Raw("SELECT d.id, r.pic_url, r.effect_url, d.`second`, d.diamond_num from res_headwear r, res_headwear_diamond d where r.id = d.res_headwear_id and d.`status` = ? ORDER BY d.diamond_num asc LIMIT ?, ?", mysql.USER, (pageIndex-1)*pageSize, pageSize).Scan(&headwearDiamonds).Error; err != nil {
return nil, myerr.WrapErr(err)
}
for i, _ := range headwearDiamonds {
headwearDiamonds[i].Days = strconv.FormatUint(uint64(headwearDiamonds[i].Second/(24*60*60)), 10)
}
return headwearDiamonds, nil
}
func GetHeadwearList(db *gorm.DB, userId uint64) ([]CvHeadwear, error) {
rows := make([]user_m.UserHeadwear, 0)
if err := db.Where(&user_m.UserHeadwear{
UserId: userId,
}).Where("end_time >= ?", time.Now()).Order("`using` DESC, updated_time DESC").Find(&rows).Error; err != nil {
return nil, err
}
resHwMap, err := res_m.GetResHeadwearMap(db)
if err != nil {
return nil, myerr.WrapErr(err)
}
result := make([]CvHeadwear, 0)
now := time.Now()
hasUsing := false
for _, i := range rows {
// TODO: 没过期并且有设置using的,才算是,因为写入方不维护using状态的更新
isUsing := i.Using == headwear_e.YesUsing && i.EndTime.After(now)
result = append(result, CvHeadwear{
Id: i.HeadwearId,
PicUrl: resHwMap[i.HeadwearId].PicUrl,
EffectUrl: resHwMap[i.HeadwearId].EffectUrl,
ReverseEffectUrl: resHwMap[i.HeadwearId].ReverseEffectUrl,
Using: isUsing,
TimeLeft: i.EndTime.Unix() - now.Unix(),
})
if isUsing {
hasUsing = true
}
}
// 如果没有一个using,则找第一个没过期的充当
if !hasUsing {
for i, e := range result {
if e.TimeLeft > 0 {
result[i].Using = true
break
}
}
}
return result, nil
}
func GetCvHeadwear(userId uint64) (*CvHeadwear, error) {
userHeadwear := user_m.UserHeadwear{}
if err := mysql.Db.Model(&user_m.UserHeadwear{}).Where(&user_m.UserHeadwear{
UserId: userId,
}).Where("end_time >= ?", time.Now()).Order("`using` DESC, updated_time DESC").First(&userHeadwear).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, nil
} else {
return nil, myerr.WrapErr(err)
}
}
resHeadwear := res_m.ResHeadwear{}
if err := mysql.Db.Model(&res_m.ResHeadwear{}).First(&resHeadwear, userHeadwear.HeadwearId).Error; err != nil {
return nil, myerr.WrapErr(err)
}
return &CvHeadwear{
Id: userHeadwear.HeadwearId,
PicUrl: resHeadwear.PicUrl,
EffectUrl: resHeadwear.EffectUrl,
ReverseEffectUrl: resHeadwear.ReverseEffectUrl,
Using: userHeadwear.Using == headwear_e.YesUsing,
}, nil
}
func BatchGetCvHeadwears(userIds []uint64) (map[uint64]CvHeadwear, error) {
if len(userIds) == 0 {
return map[uint64]CvHeadwear{}, nil
}
rows := make([]user_m.UserHeadwear, 0)
//asc 进行覆盖,保证了updated_time 最大的是最后的输出
if err := mysql.Db.Where("user_id IN ?", userIds).Where("end_time >= ?", time.Now()).
Order("`using` ASC, updated_time ASC").Find(&rows).Error; err != nil {
return nil, err
}
//
resHeadwearIds := make([]uint64, 0, len(rows))
for i, _ := range rows {
resHeadwearIds = append(resHeadwearIds, rows[i].HeadwearId)
}
//获取头饰资源,然后转换成map结构
resHeadwearMap := map[uint64]res_m.ResHeadwear{}
resHeadwears := []res_m.ResHeadwear{}
if err := mysql.Db.Where("id IN ?", resHeadwearIds).Find(&resHeadwears).Error; err != nil {
return nil, err
}
for i, _ := range resHeadwears {
resHeadwearMap[resHeadwears[i].ID] = resHeadwears[i]
}
// cp 相关
var model = domain.CreateModelNil()
cpRelations := cp_m.MGetCpRelation(model, userIds)
var m = make(map[uint64]cp_m.CpRelation)
var cpUserIds []uint64
for i, v := range cpRelations {
m[v.UserId1] = cpRelations[i]
m[v.UserId2] = cpRelations[i]
cpUserIds = append(cpUserIds, v.UserId1)
cpUserIds = append(cpUserIds, v.UserId2)
}
users, _ := user_m.GetUserMapByIds(model, cpUserIds)
var response = make(map[uint64]string)
for _, uid := range userIds {
if cpRelation, ok := m[uid]; ok {
cpUserId := cpRelation.UserId2
if cpUserId == uid {
cpUserId = cpRelation.UserId1
}
response[uid] = users[cpUserId].Avatar
}
}
result := make(map[uint64]CvHeadwear, 0)
for _, r := range rows {
headwear, flag := resHeadwearMap[r.HeadwearId]
if flag {
result[r.UserId] = CvHeadwear{
Id: headwear.ID,
PicUrl: headwear.PicUrl,
EffectUrl: headwear.EffectUrl,
ReverseEffectUrl: headwear.ReverseEffectUrl,
Using: r.Using == headwear_e.YesUsing,
HeadwearIcon: response[r.UserId],
}
}
}
return result, nil
}
package invite_cv
import "git.hilo.cn/hilo-common/resource/mysql"
type CvUserLevel struct {
UserId mysql.ID `json:"userId"` // 用户id
WealthUserGrade uint32 `json:"wealthUserGrade"` // 财富等级
CharmUserGrade uint32 `json:"charmUserGrade"` // 魅力等级
ActiveUserGrade uint32 `json:"activeUserGrade"` // 活跃等级
NobleLevel uint16 `json:"nobleLevel"` // 贵族等级
}
type InviteApplyRes struct {
List []*InviteApply `json:"list"`
NumList []*InviteApplyNumRes `json:"numList"`
MyCode string `json:"myCode"`
}
type InviteApply struct {
NewUserCode string `json:"newUserCode"`
Platform string `json:"platform"`
Recharge string `json:"recharge"`
UserCode string `json:"userCode"`
CreateUnix int64 `json:"createUnix"`
Level string `json:"level"`
Status uint8 `json:"status"` // 状态0.未审核1.已通过2.已拒绝
Avatar string `json:"avatar"`
ExternalId string `json:"externalId"`
Reason int `json:"reason"` // 1.已申请2.待审核3.已通过4.已拒绝"
Country string `json:"country"`
PlatformId string `json:"platformId"`
}
type InviteApplyNumRes struct {
Type int `json:"type"` // 1.已申请2.待审核3.已通过4.已拒绝"
Num int `json:"num"`
}
type AgentPeriod struct {
Week []AgentPeriodWeek `json:"week"`
}
type AgentPeriodWeek struct {
StartDate string `json:"startDate"`
EndDate string `json:"endDate"`
}
package medal_cv
import (
"git.hilo.cn/hilo-common/resource/mysql"
"gorm.io/gorm"
"hilo-user/domain/model/res_m"
"sort"
)
type CvMedal struct {
Id uint32 `json:"id"`
PicUrl mysql.Str `json:"picUrl"`
EffectUrl mysql.Str `json:"effectUrl"`
}
type ReturnGroupMedal struct {
PicUrl string `json:"picUrl"`
SvgaUrl string `json:"svgaUrl"`
}
type PicElement struct {
PicUrl string `json:"picUrl"`
SvgaUrl string `json:"svgaUrl"`
}
func GetMedalInfoMap(db *gorm.DB, medals map[uint64][]uint32) (map[uint64][]uint32, map[uint64][]CvMedal, error) {
resMedals, err := res_m.MedalGetAllMap(db)
if err != nil {
return nil, nil, err
}
medalIds := make(map[uint64][]uint32)
medalMap := make(map[uint64][]CvMedal, 0)
// 只选择合法的勋章
for u, i := range medals {
medalIds[u] = make([]uint32, 0)
medalMap[u] = make([]CvMedal, 0)
for _, j := range i {
if e, ok := resMedals[j]; ok {
medalIds[u] = append(medalIds[u], j)
medalMap[u] = append(medalMap[u], CvMedal{
Id: j,
PicUrl: e.PicUrl,
EffectUrl: e.SvgaUrl,
})
}
}
// 按照勋章排序
sort.Slice(medalIds[u], func(i, j int) bool {
return resMedals[medalIds[u][i]].Sort < resMedals[medalIds[u][j]].Sort
})
sort.Slice(medalMap[u], func(i, j int) bool {
return resMedals[medalMap[u][i].Id].Sort < resMedals[medalMap[u][j].Id].Sort
})
}
return medalIds, medalMap, nil
}
package noble_cv
import (
"git.hilo.cn/hilo-common/resource/mysql"
"gorm.io/gorm"
"hilo-user/domain/model/noble_m"
"hilo-user/myerr"
"time"
)
type NobleConfig struct {
Level uint16 `json:"level"` // 贵族等级
PurchasePrice uint32 `json:"purchasePrice"` // 购买价格
RenewalPrice uint32 `json:"renewalPrice"` // 续费价格
Duration uint16 `json:"duration"` // 有效期(天)
PicUrl string `json:"picUrl"` // 大图url
DailyGold uint `json:"dailyGold"` // 每日登录领取的金币
RideId uint64 `json:"rideId"` // 赠送的勋章ID
HeaddressId uint64 `json:"headdressId"` // 赠送的头饰ID
Privileges []int `json:"privileges"` // 权益列表
}
type NobleInfo struct {
Level uint16 `json:"level"` // 等级
EndTime int64 `json:"endTime"` // 截止时间
RemainTime int64 `json:"remainTime"` // 还有多久(秒)过期,可以是负数
Price uint32 `json:"price"` // 购买或续费价格
}
type CvNoble struct {
Level uint16 `json:"level"`
EndTime int64 `json:"endTime"`
}
func GetCvNoble(userId uint64) (CvNoble, error) {
userNoble := noble_m.UserNoble{}
if err := mysql.Db.Model(&noble_m.UserNoble{}).Where(&noble_m.UserNoble{
UserId: userId,
}).Where("end_time > ?", time.Now()).Order("level desc").First(&userNoble).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return CvNoble{
Level: 0,
EndTime: 0,
}, nil
} else {
return CvNoble{
Level: 0,
EndTime: 0,
}, myerr.WrapErr(err)
}
} else {
return CvNoble{
Level: userNoble.Level,
EndTime: userNoble.EndTime.Unix(),
}, nil
}
}
func GetCvNobles(userIds []uint64) (map[uint64]CvNoble, error) {
if len(userIds) == 0 {
return map[uint64]CvNoble{}, nil
}
var userNobles []noble_m.UserNoble
if err := mysql.Db.Model(&noble_m.UserNoble{}).Where("user_id in (?)", userIds).Where("end_time > ?", time.Now()).Order("level asc").Find(&userNobles).Error; err != nil {
return nil, err
}
userNobleMap := map[uint64]noble_m.UserNoble{}
for i, _ := range userNobles {
userNobleMap[userNobles[i].UserId] = userNobles[i]
}
result := map[uint64]CvNoble{}
for _, r := range userIds {
userNoble, flag := userNobleMap[r]
if flag {
result[r] = CvNoble{
Level: userNoble.Level,
EndTime: userNoble.EndTime.Unix(),
}
} else {
result[r] = CvNoble{
Level: 0,
EndTime: 0,
}
}
}
return result, nil
}
package property_cv
import (
"git.hilo.cn/hilo-common/resource/mysql"
"gorm.io/gorm"
"hilo-user/_const/enum/headwear_e"
"hilo-user/domain/model/res_m"
"hilo-user/domain/model/user_m"
"hilo-user/myerr"
"strconv"
"time"
)
type CvProperty struct {
Id uint64 `json:"id"`
PicUrl mysql.Str `json:"picUrl"`
EffectUrl mysql.Str `json:"effectUrl"`
Using bool `json:"using"`
TimeLeft int64 `json:"timeLeft"` // 离到期还有多少秒(过期则是负数)
SenderAvatar string `json:"senderAvatar"`
ReceiverAvatar string `json:"receiverAvatar"`
}
type CvPropertyDiamond struct {
Id uint64 `json:"id"`
PicUrl string `json:"picUrl"`
EffectUrl string `json:"effectUrl"`
DiamondNum uint32 `json:"diamondNum"`
Second uint32 `json:"second"`
Days string `json:"days"`
}
func GetCvPropertyDiamond(pageSize int, pageIndex int) ([]CvPropertyDiamond, error) {
propertyDiamonds := []CvPropertyDiamond{}
if err := mysql.Db.Raw("select d.id, r.pic_url, r.effect_url, d.`second`, d.diamond_num from res_property r, res_property_diamond d where r.id = d.res_property_id and d.`status` = ? ORDER BY d.diamond_num ASC LIMIT ?, ?", mysql.USER, (pageIndex-1)*pageSize, pageSize).Scan(&propertyDiamonds).Error; err != nil {
return nil, myerr.WrapErr(err)
}
for i, _ := range propertyDiamonds {
propertyDiamonds[i].Days = strconv.FormatUint(uint64(propertyDiamonds[i].Second/(24*60*60)), 10)
}
return propertyDiamonds, nil
}
func GetPropertyById(resPropertyId mysql.ID) (CvProperty, error) {
resProperty := res_m.ResProperty{}
if err := mysql.Db.Model(&res_m.ResProperty{}).First(&resProperty, resPropertyId).Error; err != nil {
return CvProperty{}, err
}
//获取座驾头像
propertieAvatarMap, err := (&res_m.ResPropertyAvatar{}).GetAll(mysql.Db)
if err != nil {
return CvProperty{}, err
}
userIds := []uint64{}
for _, value := range propertieAvatarMap {
if value.SendUserId > 0 {
userIds = append(userIds, value.SendUserId)
}
if value.ReceiverUserId > 0 {
userIds = append(userIds, value.ReceiverUserId)
}
}
//获取用户信息
users := []user_m.User{}
if err := mysql.Db.Model(&user_m.User{}).Where("id in (?)", userIds).Find(&users).Error; err != nil {
return CvProperty{}, myerr.WrapErr(err)
}
userAvatarMap := map[mysql.ID]string{}
for _, r := range users {
userAvatarMap[r.ID] = r.Avatar
}
var senderAvatar string = ""
var receiverAvatar string = ""
if propertieAvatar, flag := propertieAvatarMap[resProperty.ID]; flag {
if propertieAvatar.SendUserId > 0 {
if avatar, flag := userAvatarMap[propertieAvatar.SendUserId]; flag {
senderAvatar = avatar
}
}
if propertieAvatar.ReceiverUserId > 0 {
if avatar, flag := userAvatarMap[propertieAvatar.ReceiverUserId]; flag {
receiverAvatar = avatar
}
}
}
return CvProperty{
Id: resProperty.ID,
PicUrl: resProperty.PicUrl,
EffectUrl: resProperty.EffectUrl,
SenderAvatar: senderAvatar,
ReceiverAvatar: receiverAvatar,
}, nil
}
func GetPropertyAll(db *gorm.DB, area int) (map[uint64]CvProperty, error) {
rp := res_m.ResProperty{}
properties, err := rp.GetAll(mysql.Db)
if err != nil {
return nil, err
}
//获取座驾头像
propertieAvatarMap, err := (&res_m.ResPropertyAvatar{Area: area}).GetAll(mysql.Db)
userIds := []uint64{}
for _, value := range propertieAvatarMap {
if value.SendUserId > 0 {
userIds = append(userIds, value.SendUserId)
}
if value.ReceiverUserId > 0 {
userIds = append(userIds, value.ReceiverUserId)
}
}
//获取用户信息
users := []user_m.User{}
if err := db.Model(&user_m.User{}).Where("id in (?)", userIds).Find(&users).Error; err != nil {
return nil, myerr.WrapErr(err)
}
userAvatarMap := map[mysql.ID]string{}
for _, r := range users {
userAvatarMap[r.ID] = r.Avatar
}
result := map[uint64]CvProperty{}
for _, r := range properties {
var senderAvatar string = ""
var receiverAvatar string = ""
if propertieAvatar, flag := propertieAvatarMap[r.ID]; flag {
if propertieAvatar.SendUserId > 0 {
if avatar, flag := userAvatarMap[propertieAvatar.SendUserId]; flag {
senderAvatar = avatar
}
}
if propertieAvatar.ReceiverUserId > 0 {
if avatar, flag := userAvatarMap[propertieAvatar.ReceiverUserId]; flag {
receiverAvatar = avatar
}
}
}
result[r.ID] = CvProperty{
Id: r.ID,
PicUrl: r.PicUrl,
EffectUrl: r.EffectUrl,
SenderAvatar: senderAvatar,
ReceiverAvatar: receiverAvatar,
}
}
return result, nil
}
func GetPropertyList(db *gorm.DB, userId uint64) ([]CvProperty, error) {
rows := make([]user_m.UserProperty, 0)
if err := db.Where(&user_m.UserProperty{
UserId: userId,
}).Order("`using` DESC, updated_time DESC").Find(&rows).Error; err != nil {
return nil, err
}
rp := res_m.ResProperty{}
properties, err := rp.GetAll(mysql.Db)
if err != nil {
return nil, err
}
//获取座驾头像
propertieAvatarMap, err := (&res_m.ResPropertyAvatar{}).GetAll(mysql.Db)
userIds := []uint64{}
for _, value := range propertieAvatarMap {
if value.SendUserId > 0 {
userIds = append(userIds, value.SendUserId)
}
if value.ReceiverUserId > 0 {
userIds = append(userIds, value.ReceiverUserId)
}
}
//获取用户信息
users := []user_m.User{}
if err := db.Model(&user_m.User{}).Where("id in (?)", userIds).Find(&users).Error; err != nil {
return nil, myerr.WrapErr(err)
}
userAvatarMap := map[mysql.ID]string{}
for _, r := range users {
userAvatarMap[r.ID] = r.Avatar
}
result := make([]CvProperty, 0)
now := time.Now()
hasUsing := false
for _, i := range rows {
// TODO: 没过期并且有设置using的,才算是,因为写入方不维护using状态的更新
isUsing := i.Using == headwear_e.YesUsing && i.EndTime.After(now)
var senderAvatar string = ""
var receiverAvatar string = ""
if propertieAvatar, flag := propertieAvatarMap[i.PropertyId]; flag {
if propertieAvatar.SendUserId > 0 {
if avatar, flag := userAvatarMap[propertieAvatar.SendUserId]; flag {
senderAvatar = avatar
}
}
if propertieAvatar.ReceiverUserId > 0 {
if avatar, flag := userAvatarMap[propertieAvatar.ReceiverUserId]; flag {
receiverAvatar = avatar
}
}
}
result = append(result, CvProperty{
Id: i.PropertyId,
PicUrl: properties[i.PropertyId].PicUrl,
EffectUrl: properties[i.PropertyId].EffectUrl,
Using: isUsing,
TimeLeft: i.EndTime.Unix() - now.Unix(),
SenderAvatar: senderAvatar,
ReceiverAvatar: receiverAvatar,
})
if isUsing {
hasUsing = true
}
}
// 如果没有一个using,则找第一个没过期的充当
if !hasUsing {
for i, e := range result {
if e.TimeLeft > 0 {
result[i].Using = true
break
}
}
}
return result, nil
}
type PropertyExt struct {
Id uint64
PicUrl mysql.Str
EffectUrl mysql.Str
Using bool
TimeLeft int64 // 离到期还有多少秒(过期则是负数)
SenderAvatar string
ReceiverAvatar string
}
func GetExtendedProperty(db *gorm.DB) (map[uint64]PropertyExt, error) {
rp := res_m.ResProperty{}
properties, err := rp.GetAll(mysql.Db)
if err != nil {
return nil, err
}
//获取座驾头像
propertieAvatarMap, err := (&res_m.ResPropertyAvatar{}).GetAll(mysql.Db)
userIds := []uint64{}
for _, value := range propertieAvatarMap {
if value.SendUserId > 0 {
userIds = append(userIds, value.SendUserId)
}
if value.ReceiverUserId > 0 {
userIds = append(userIds, value.ReceiverUserId)
}
}
//获取用户信息
users := []user_m.User{}
if err := db.Model(&user_m.User{}).Where("id in (?)", userIds).Find(&users).Error; err != nil {
return nil, myerr.WrapErr(err)
}
userAvatarMap := map[mysql.ID]string{}
for _, r := range users {
userAvatarMap[r.ID] = r.Avatar
}
result := map[uint64]PropertyExt{}
for _, r := range properties {
var senderAvatar string = ""
var receiverAvatar string = ""
if propertieAvatar, flag := propertieAvatarMap[r.ID]; flag {
if propertieAvatar.SendUserId > 0 {
if avatar, flag := userAvatarMap[propertieAvatar.SendUserId]; flag {
senderAvatar = avatar
}
}
if propertieAvatar.ReceiverUserId > 0 {
if avatar, flag := userAvatarMap[propertieAvatar.ReceiverUserId]; flag {
receiverAvatar = avatar
}
}
}
result[r.ID] = PropertyExt{
Id: r.ID,
PicUrl: r.PicUrl,
EffectUrl: r.EffectUrl,
SenderAvatar: senderAvatar,
ReceiverAvatar: receiverAvatar,
}
}
return result, nil
}
......@@ -5,14 +5,23 @@ import (
)
type UserBag struct {
BagId mysql.ID `json:"bagId"` // 背包id
ResType mysql.Type `json:"resType"` // 道具类型 1:礼物道具
ResId mysql.ID `json:"resId"` // 道具资源id
GiftId mysql.ID `json:"giftId"` // 道具的礼物id
Name string `json:"name"` // 资源名称
DiamondNum mysql.Num `json:"diamondNum"` // 钻石数量
IconUrl string `json:"iconUrl"` // icon url
SvgaUrl string `json:"svgaUrl"` // svga url
Count mysql.Num `json:"count"` // 拥有数量
RemainDays int `json:"remainDays"` // 有效天数
BagId mysql.ID `json:"bagId"` // 背包id
ResType mysql.Type `json:"resType"` // 道具类型 1:礼物道具
ResId mysql.ID `json:"resId"` // 道具资源id
GiftId mysql.ID `json:"giftId"` // 道具的礼物id
Name string `json:"name"` // 资源名称
DiamondNum mysql.Num `json:"diamondNum"` // 钻石数量
IconUrl string `json:"iconUrl"` // icon url
SvgaUrl string `json:"svgaUrl"` // svga url
Count mysql.Num `json:"count"` // 拥有数量
RemainDays int `json:"remainDays"` // 有效天数
TextStyleList []*TextStyle `json:"textStyleList"` // 文本样式
HasGiftText bool `json:"hasGiftText"` // 是否有礼物文字
}
type TextStyle struct {
TextColor string `json:"textColor"` //文本颜色
TextSize float32 `json:"textSize"` //文本字体大小
IsBold bool `json:"isBold"` //是否加粗
TextKey string `json:"textKey"` //替换svga 对象里面的key
}
This diff is collapsed.
package user_cv
import (
"git.hilo.cn/hilo-common/resource/mysql"
"hilo-user/cv/headwear_cv"
"hilo-user/cv/medal_cv"
"hilo-user/cv/property_cv"
"time"
)
//空字符串转成nil
func StrNil(msg string) *string {
if msg == "" {
return nil
}
return &msg
}
func TypeToUint8(t *mysql.Type) *uint8 {
if *t == 0 {
return nil
} else {
return (*uint8)(t)
}
}
func BirthdayToUint64(birthday *mysql.Timestamp) *uint64 {
if *birthday == 0 {
return nil
}
return (*uint64)(birthday)
}
func NumToUint32(num *mysql.Num) *uint32 {
return (*uint32)(num)
}
func TimeToUint64(t *time.Time) *uint64 {
a := uint64(t.Unix())
return &a
}
func StrToString(str *mysql.Str) *string {
return (*string)(str)
}
func IndexToUint16(i *mysql.Index) *uint16 {
return (*uint16)(i)
}
func IdToUint64(id *mysql.ID) *uint64 {
return (*uint64)(id)
}
func IsInStringList(str string, list []string) bool {
for _, v := range list {
if str == v {
return true
}
}
return false
}
func IfLogoutStr(condition bool, trueVal, falseVal string) string {
if condition {
return trueVal
}
return falseVal
}
func IfLogoutNick(condition bool, code string, nick string) string {
if condition {
return "Hilo No." + code
}
return nick
}
func IfLogout(logoutTime int64) bool {
return logoutTime > 0 && time.Now().Unix() > logoutTime
}
func IfLogoutMedals(condition bool, trueVal, falseVal []uint32) []uint32 {
if condition {
return trueVal
}
return falseVal
}
func IfLogoutMedalInfo(condition bool, trueVal, falseVal []medal_cv.CvMedal) []medal_cv.CvMedal {
if condition {
return trueVal
}
return falseVal
}
func IfLogoutRide(condition bool, trueVal, falseVal property_cv.CvProperty) property_cv.CvProperty {
if condition {
return trueVal
}
return falseVal
}
func IfLogoutHeadwear(condition bool, trueVal, falseVal *headwear_cv.CvHeadwear) *headwear_cv.CvHeadwear {
if condition {
return trueVal
}
return falseVal
}
......@@ -11,6 +11,8 @@ MYSQL_DB=hilo_code
[REDIS]
REDIS_HOST=47.244.34.27:6379
REDIS_PASSWORD=8QZ9JD1zLvPR3yHf
REDIS_CLUSTER_HOST=47.244.34.27:6379
REDIS_CLUSTER_PASSWORD=8QZ9JD1zLvPR3yHf
[JWT]
SECRET=hilo1632
ISSUER_API=hiloApi
......
package gift_c
import (
"encoding/json"
"git.hilo.cn/hilo-common/domain"
"github.com/go-redis/redis/v8"
"hilo-user/domain/event/gift_ev"
"time"
)
const EventSendGiftHiloUserQueue = "send:gift:queue:hilo_user"
// redis pop event sendGift
func BLPopQueueSendGift(model *domain.Model) *gift_ev.SendGiftEvent {
var res *gift_ev.SendGiftEvent
queue := EventSendGiftHiloUserQueue
strs, err := model.RedisCluster.BLPop(model, time.Second, queue).Result()
if err != nil {
if err != redis.Nil {
model.Log.Errorf("BLPopQueueSendGift fail:%v", err)
}
return nil
}
if len(strs) >= 2 {
content := strs[1]
res = new(gift_ev.SendGiftEvent)
if err := json.Unmarshal([]byte(content), res); err != nil {
model.Log.Errorf("BLPopQueueSendGift json fail:%v", err)
return nil
}
return res
}
return nil
}
......@@ -27,7 +27,7 @@ func SetJSON(model *domain.Model, key string, obj interface{}) (err error) {
if err != nil {
return err
}
return model.Redis.Set(model.Context, key, value, DEFAULT_TTL).Err()
return model.RedisCluster.Set(model.Context, key, value, DEFAULT_TTL).Err()
}
// 获取redis中json结构体
......@@ -37,7 +37,7 @@ func GetJSON(model *domain.Model, key string, obj interface{}) (err error) {
defer func() {
model.Log.Infof("GetJson key:%v,value:%s,obj:%v,err:%v", key, value, obj, err)
}()
value, err = model.Redis.Get(model.Context, key).Bytes()
value, err = model.RedisCluster.Get(model.Context, key).Bytes()
if err != nil {
// may redisV2.Nil
return
......@@ -59,7 +59,7 @@ func TryLock(model *domain.Model, key string, acquireTimeout, expireTimeout time
if time.Now().After(deadline) {
return false
}
flag, err := model.Redis.SetNX(model, key, "1", expireTimeout).Result()
flag, err := model.RedisCluster.SetNX(model, key, "1", expireTimeout).Result()
if err != nil || !flag {
time.Sleep(time.Millisecond * 10)
} else {
......@@ -70,5 +70,5 @@ func TryLock(model *domain.Model, key string, acquireTimeout, expireTimeout time
// 解锁
func UnLock(model *domain.Model, key string) {
model.Redis.Del(model, key)
model.RedisCluster.Del(model, key)
}
package user_c
import (
"git.hilo.cn/hilo-common/_const/common"
"git.hilo.cn/hilo-common/domain"
"git.hilo.cn/hilo-common/resource/mysql"
"git.hilo.cn/hilo-common/utils"
redisV8 "github.com/go-redis/redis/v8"
"github.com/jinzhu/copier"
"hilo-user/_const/redis_key/user_k"
......@@ -10,6 +12,7 @@ import (
"hilo-user/domain/model/user_m"
"hilo-user/myerr"
"hilo-user/myerr/bizerr"
"time"
)
// 获取用户简要信息
......@@ -50,7 +53,7 @@ func ToUserId(model *domain.Model, externalId mysql.Str) (mysql.ID, error) {
if externalId == "" {
return 0, myerr.NewSysError("externalId 不能为空")
}
userId, err := model.Redis.Get(model.Context, user_k.GetExternalIdToUidKey(externalId)).Int64()
userId, err := model.RedisCluster.Get(model.Context, user_k.GetExternalIdToUidKey(externalId)).Int64()
if err != nil && err != redisV8.Nil {
return 0, err
}
......@@ -73,7 +76,7 @@ func ToUserIdByCode(model *domain.Model, code mysql.Str) (mysql.ID, error) {
if code == "" {
return 0, myerr.NewSysError("code 不能为空")
}
userId, err := model.Redis.Get(model.Context, user_k.GetCodeToUidKey(code)).Int64()
userId, err := model.RedisCluster.Get(model.Context, user_k.GetCodeToUidKey(code)).Int64()
if err != nil && err != redisV8.Nil {
return 0, err
}
......@@ -96,16 +99,17 @@ func ToUserIdByCode(model *domain.Model, code mysql.Str) (mysql.ID, error) {
// 顺手缓存code->userId
// param user: 已经在上层获取的db User结构
func cacheUserTiny(model *domain.Model, user *user_m.User) error {
userTiny := new(user_m.UserTiny)
if err := copier.Copy(userTiny, user); err != nil {
return err
}
userTiny := ToUserTinyBy(user)
//userTiny := new(user_m.UserTiny)
//if err := copier.Copy(userTiny, user); err != nil {
// return err
//}
// cache externalId->userId
if err := model.Redis.SetEX(model.Context, user_k.GetExternalIdToUidKey(user.ExternalId), user.ID, cache.GetDefaultTTL()).Err(); err != nil {
if err := model.RedisCluster.SetEX(model.Context, user_k.GetExternalIdToUidKey(user.ExternalId), user.ID, cache.GetDefaultTTL()).Err(); err != nil {
return err
}
// cache code->userId
if err := model.Redis.SetEX(model.Context, user_k.GetCodeToUidKey(user.Code), user.ID, cache.GetDefaultTTL()).Err(); err != nil {
if err := model.RedisCluster.SetEX(model.Context, user_k.GetCodeToUidKey(user.Code), user.ID, cache.GetDefaultTTL()).Err(); err != nil {
return err
}
if err := cache.SetJSON(model, user_k.GetUserTinyKey(user.ID), userTiny); err != nil {
......@@ -113,3 +117,89 @@ func cacheUserTiny(model *domain.Model, user *user_m.User) error {
}
return nil
}
// 获取用户简要信息
// param userIds 用户id列表
func GetUserTinyMap(model *domain.Model, userIds []mysql.ID, isDefAvatar bool) (map[mysql.ID]*user_m.UserTiny, error) {
redisNoIds := make([]mysql.ID, 0)
res := make(map[mysql.ID]*user_m.UserTiny)
for _, id := range userIds {
userTiny := new(user_m.UserTiny)
key := user_k.GetUserTinyKey(id)
err := cache.GetJSON(model, key, userTiny)
if err != nil && err != redisV8.Nil {
return nil, err
}
if err == redisV8.Nil {
redisNoIds = append(redisNoIds, id)
} else if userTiny.ID > 0 {
res[id] = userTiny
}
}
// 从db中读
users, err := user_m.GetUsers(model, redisNoIds)
if err != nil {
return nil, err
}
for _, u := range users {
userTiny := ToUserTinyBy(u)
err = cacheUserTiny(model, u)
if err != nil {
return nil, err
}
res[userTiny.ID] = userTiny
}
if isDefAvatar {
for _, v := range res {
if len(v.Avatar) <= 0 {
if v.Sex == mysql.MAN {
v.Avatar = utils.MakeFullUrl(common.DefaultAvatarMan)
} else if v.Sex == mysql.WOMAN {
v.Avatar = utils.MakeFullUrl(common.DefaultAvatarWoman)
}
}
}
}
return res, nil
}
func ToUserTinyBy(user *user_m.User) *user_m.UserTiny {
return &user_m.UserTiny{
ID: user.ID,
Avatar: IfLogoutStr(IfLogout(user.LogoutTime), "", user.Avatar),
ExternalId: user.ExternalId,
Nick: IfLogoutNick(IfLogout(user.LogoutTime), user.Code, user.Nick),
Sex: user.Sex,
Code: user.Code,
Country: user.Country,
CountryIcon: user.CountryIcon,
IsPrettyCode: user.IsPrettyCode(),
IsLogout: IfLogout(user.LogoutTime),
Birthday: BirthdayToUint64(&user.Birthday),
}
}
func IfLogout(logoutTime int64) bool {
return logoutTime > 0 && time.Now().Unix() > logoutTime
}
func BirthdayToUint64(birthday *mysql.Timestamp) *uint64 {
if *birthday == 0 {
return nil
}
return (*uint64)(birthday)
}
func IfLogoutStr(condition bool, trueVal, falseVal string) string {
if condition {
return trueVal
}
return falseVal
}
func IfLogoutNick(condition bool, code string, nick string) string {
if condition {
return "Hilo No." + code
}
return nick
}
package cp_ev
import (
"git.hilo.cn/hilo-common/domain"
"git.hilo.cn/hilo-common/resource/mysql"
)
//注册监听
var spaceVisitListen = new(domain.EventBase)
type SpaceVisitEvent struct {
UserId mysql.ID
CpId mysql.ID
UserId1, UserId2 mysql.ID
}
//添加领域事件,在每个领域模型中init中添加,因为这是静态业务,非动态的。
func AddCpSpaceVisitSync(callback func(model *domain.Model, event interface{}) error) {
domain.AddEventSync(spaceVisitListen, callback)
}
//加入到异步操作中
func AddCpSpaceVisitAsync(callback func(model *domain.Model, event interface{}) error) {
domain.AddEventAsync(spaceVisitListen, callback)
}
//领域事件发布
func PublishCpSpaceVisit(model *domain.Model, event interface{}) error {
return domain.PublishEvent(spaceVisitListen, model, event)
}
package gift_ev
import (
"git.hilo.cn/hilo-common/domain"
"git.hilo.cn/hilo-common/resource/mysql"
"hilo-user/_const/enum/gift_e"
)
var sendGiftListen = new(domain.EventBase)
// 送礼事件
type SendGiftEvent struct {
SendUserId mysql.ID
ReceiveUserIds []mysql.ID
ResGift EventResGift
GiftOperateIds []mysql.ID
GiftN mysql.Num
SceneType gift_e.GiftOperateSceneType
SceneUid mysql.Str
NoDiamondConsume bool // 不要消费钻石
TotalConsume uint64 // 房间的总消费额
}
type EventResGift struct {
ID mysql.ID
Name mysql.Str
IconUrl mysql.Str
SvgaUrl mysql.Str
MusicUrl mysql.Str
DiamondNum mysql.Num
BeanNum mysql.Num
ReceiveDiamondNum mysql.Num
Second mysql.Num
N mysql.Num
GroupBroadcast bool
Cp bool
Together bool
Status mysql.UserYesNo
GiftType mysql.Type
}
func AddSendGiftEventSync(callback func(model *domain.Model, event interface{}) error) {
domain.AddEventSync(sendGiftListen, callback)
}
func AddSendGiftEventAsync(callback func(model *domain.Model, event interface{}) error) {
domain.AddEventAsync(sendGiftListen, callback)
}
func PublishSendGiftEvent(model *domain.Model, event interface{}) error {
return domain.PublishEvent(sendGiftListen, model, event)
}
package common
import (
"context"
"encoding/json"
"git.hilo.cn/hilo-common/mylogrus"
"git.hilo.cn/hilo-common/resource/mysql"
"git.hilo.cn/hilo-common/resource/redisCli"
"hilo-user/_const/redis_key"
"hilo-user/myerr"
"github.com/bluele/gcache"
"time"
)
func GetUserMedalMergeCache(userId mysql.ID) ([]uint32, error) {
bData, err := GetCache(redis_key.GetUserMedalMerge(userId))
if err != nil {
return nil, myerr.WrapErr(err)
}
res := make([]uint32, 0)
err = json.Unmarshal(bData, &res)
if err != nil {
return nil, myerr.WrapErr(err)
}
return res, nil
}
// 改成lru
var userMedalMergeLru = gcache.New(10000).LRU().Build()
func GetCache(key string) ([]byte, error) {
data, err := redisCli.GetRedis().Get(context.Background(), key).Bytes()
if err != nil {
return nil, err
}
return data, nil
}
func SetCache(key string, data interface{}, expire time.Duration) error {
jData, err := json.Marshal(data)
if err != nil {
return err
}
err = redisCli.GetRedis().Set(context.Background(), key, jData, expire).Err()
if err != nil {
mylogrus.MyLog.Errorf("SetCache key:%s, data:%v, err:%s", key, data, err)
return err
func GetUserMedalMergeCache(userId mysql.ID) ([]uint32, error) {
if data, err := userMedalMergeLru.Get(userId); err == nil {
return data.([]uint32), nil
}
return nil
return nil, nil
}
func SetUserMedalMergeCache(userId mysql.ID, data []uint32) error {
err := SetCache(redis_key.GetUserMedalMerge(userId), data, time.Hour*2)
if err != nil {
mylogrus.MyLog.Errorf("SetUserMedalMerge err:%s", err)
return myerr.WrapErr(err)
}
return nil
func SetUserMedalMergeCache(userId mysql.ID, data []uint32) {
_ = userMedalMergeLru.SetWithExpire(userId, data, time.Minute*15)
}
package country_m
import (
"git.hilo.cn/hilo-common/domain"
"git.hilo.cn/hilo-common/resource/mysql"
"gorm.io/gorm"
"hilo-user/_const/enum/country_e"
"hilo-user/myerr"
)
type CountryMgrUser struct {
mysql.Entity
Country string
UserId mysql.ID
Role country_e.CountryMgrRole
}
// 获取国家管理人员
func GetCountryMgr(model *domain.Model, userId mysql.ID) (*CountryMgrUser, error) {
cmu := new(CountryMgrUser)
if err := model.Db.WithContext(model.MyContext.Context).Where("user_id = ?", userId).First(&cmu).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, nil
} else {
return nil, myerr.WrapErr(err)
}
}
return cmu, nil
}
// 更新国家管理人员
func (cmu *CountryMgrUser) UpdateCountryMgr(userId mysql.ID, role country_e.CountryMgrRole, country string) *CountryMgrUser {
cmu.UserId, cmu.Role, cmu.Country = userId, role, country
return cmu
}
// 删除国家管理人员
func (cmu *CountryMgrUser) DeleteCountryMgr() {
cmu.SetDel()
}
package cp_m
import (
"git.hilo.cn/hilo-common/domain"
"git.hilo.cn/hilo-common/resource/mysql"
"gorm.io/gorm"
"hilo-user/_const/enum/cp_e"
"time"
)
type CpAchievement struct {
CpId mysql.ID
UserId1 mysql.ID
UserId2 mysql.ID
Type cp_e.CpAchievement
Score mysql.Num
CreatedTime time.Time `gorm:"->"`
UpdatedTime time.Time `gorm:"->"`
}
// 更新cp成就
// 单进程操作,先create,后update
func UpdateCpAchievement(model *domain.Model, cpId, userId1, userId2 mysql.ID, Type cp_e.CpAchievement, score mysql.Num) error {
var cpAchievement CpAchievement
if err := model.DB().Model(CpAchievement{}).Where("cp_id = ? AND `type` = ?", cpId, Type).First(&cpAchievement).Error; err != nil {
if err != gorm.ErrRecordNotFound {
model.Log.Errorf("UpdateCpAchievement fail:%v", err)
return err
}
// gorm.ErrRecordNotFound
cpAchievement = CpAchievement{
CpId: cpId,
UserId1: userId1,
UserId2: userId2,
Type: Type,
Score: score,
}
return model.DB().Model(CpAchievement{}).Create(&cpAchievement).Error
}
// update if less than
return model.DB().Model(CpAchievement{}).Where("cp_id = ? AND `type` = ?", cpId, Type).Where("score < ?", score).UpdateColumn("score", score).Error
}
// 获取cp成就
func GetCpAchievements(model *domain.Model) []CpAchievement {
var achievements []CpAchievement
subQuery := model.DB().Table("cp_achievement a").Joins("JOIN cp_relation r ON a.cp_id = r.id").Select("type,MAX(score) AS max_score").Group("type")
if err := model.DB().Model(CpAchievement{}).Joins("INNER JOIN cp_relation r ON cp_id = r.id").Where("(type, score) IN (?)", subQuery).Order("type ASC").Find(&achievements).Error; err != nil {
model.Log.Errorf("GetAchievements fail:%v", err)
}
return achievements
}
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
}
This diff is collapsed.
This diff is collapsed.
package cp_m
import (
"git.hilo.cn/hilo-common/domain"
"git.hilo.cn/hilo-common/resource/mysql"
"gorm.io/gorm"
"hilo-user/myerr"
)
type StatusCp = mysql.Type
const (
Connect StatusCp = 1
Disconnect StatusCp = 2
)
type OldCp struct {
mysql.Entity
//必须保证userId1 > userId2
UserId1 mysql.ID
UserId2 mysql.ID
Score mysql.Num
DayScore mysql.Num
PeriodDay mysql.Str
WeekScore mysql.Num
PeriodWeek mysql.Str
MonthScore mysql.Num
PeriodMonth mysql.Str
Status StatusCp
//中断时长
DisconnectSecond int64
}
func (OldCp) TableName() string {
return "cp"
}
// 获取旧的绑定中的cp
func GetOldConnectCp(model *domain.Model, tmpUserId1 mysql.ID, tmpUserId2 mysql.ID) (*OldCp, error) {
userId1 := tmpUserId1
userId2 := tmpUserId2
if tmpUserId1 < tmpUserId2 {
userId1 = tmpUserId2
userId2 = tmpUserId1
}
cp := OldCp{}
if err := model.Db.Where(&OldCp{
UserId1: userId1,
UserId2: userId2,
Status: Connect,
}).First(&cp).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, nil
} else {
return nil, myerr.WrapErr(err)
}
}
return &cp, nil
}
package cp_m
import (
"git.hilo.cn/hilo-common/domain"
"git.hilo.cn/hilo-common/resource/mysql"
"gorm.io/gorm"
"hilo-user/_const/enum/cp_e"
)
// svip特权
type CpPrivilege struct {
mysql.Entity
UserId mysql.ID
Type cp_e.CpPrivilege
OpenClose mysql.OpenClose
}
// 开关用于svip特权
func OpenCLoseUserSvipPrivilege(model *domain.Model, userId mysql.ID, Type cp_e.CpPrivilege, openClose mysql.OpenClose) error {
var pri CpPrivilege
if err := model.DB().Model(CpPrivilege{}).Where("user_id = ? AND `type` = ?", userId, Type).
First(&pri).Error; err != nil {
if err != gorm.ErrRecordNotFound {
return err
}
// record not found
return model.DB().Create(&CpPrivilege{
UserId: userId,
Type: Type,
OpenClose: openClose,
}).Error
}
// update
return model.DB().Model(CpPrivilege{}).Where("user_id = ? AND `type` = ?", userId, Type).
UpdateColumn("open_close", openClose).Error
}
// 批量获取用户svip特权开关
// map userId->type->open
func MGetUserSvipPrivilege(model *domain.Model, userIds []mysql.ID) (map[mysql.ID]map[cp_e.CpPrivilege]bool, error) {
res := make(map[mysql.ID]map[cp_e.CpPrivilege]bool)
var privileges []CpPrivilege
if err := model.DB().Model(CpPrivilege{}).Where("user_id in ? AND open_close = ?", userIds, mysql.OPEN).Find(&privileges).Error; err != nil {
return res, err
}
for _, v := range privileges {
if data, ok := res[v.UserId]; ok {
data[v.Type] = true
} else {
res[v.UserId] = make(map[cp_e.CpPrivilege]bool)
res[v.UserId][v.Type] = true
}
}
return res, nil
}
package cp_m
import (
"git.hilo.cn/hilo-common/domain"
"git.hilo.cn/hilo-common/resource/mysql"
"gorm.io/gorm"
"gorm.io/gorm/clause"
"time"
)
type CpDayRank struct {
Date string
CpId mysql.ID
UserId1 mysql.ID
UserId2 mysql.ID
Score mysql.Num
CreatedTime time.Time `gorm:"->"`
UpdatedTime time.Time `gorm:"->"`
}
// 增加cp排行榜-天
func AddCpDayRank(model *domain.Model, cpRelation CpRelation, score mysql.Num) (err error) {
date := time.Now().Format("2006-01-02")
rank := &CpDayRank{
Date: date,
CpId: cpRelation.Id,
UserId1: cpRelation.UserId1,
UserId2: cpRelation.UserId2,
Score: score,
}
if err = model.DB().Model(CpDayRank{}).Clauses(clause.OnConflict{Columns: []clause.Column{{Name: "date"}, {Name: "cp_id"}},
DoUpdates: clause.Assignments(map[string]interface{}{
"score": gorm.Expr("score + ?", rank.Score)})}).Create(rank).Error; err != nil {
model.Log.Errorf("AddCpDayRank fail:%v", err)
return err
}
return nil
}
// 分页获取cp排行榜
func PageCpDayRank(model *domain.Model, beginDate, endDate string, offset, limit int) []CpDayRank {
var ranks []CpDayRank
if err := model.DB().Table("cp_day_rank r").Joins("INNER JOIN cp_relation c ON c.id = r.cp_id").
Where("r.date BETWEEN ? AND ?", beginDate, endDate).
Where("cp_id not in (1581, 12651, 5171, 9191, 39131, 28801, 181, 35221)").
Group("cp_id").Select("cp_id,r.user_id1,r.user_id2,SUM(r.score) score").
Order("score DESC").Offset(offset).Limit(limit).Find(&ranks).Error; err != nil {
model.Log.Errorf("PageCpDayRank fail:%v", err)
}
return ranks
}
// 获取指定cp排行榜
func GetCpDayRank(model *domain.Model, beginDate, endDate string, cpId mysql.ID) CpDayRank {
var rank CpDayRank
if err := model.DB().Table("cp_day_rank").
Where("date BETWEEN ? AND ?", beginDate, endDate).Where("cp_id = ?", cpId).Select("cp_id,user_id1,user_id2,SUM(score) score").
First(&rank).Error; err != nil {
model.Log.Errorf("GetCpDayRank fail:%v", err)
}
return rank
}
// 获取Cp历史分数
func SumCpPoints(model *domain.Model, cpId mysql.ID) mysql.Num {
var score CpDayRank
if err := model.DB().Model(CpDayRank{}).Where("cp_id = ?", cpId).Select("SUM(score) score").Scan(&score).Error; err != nil {
model.Log.Errorf("SumCpPoints fail:%v", err)
}
return score.Score
}
package cp_m
import (
"git.hilo.cn/hilo-common/domain"
"hilo-user/domain/model"
)
func (p *CpLevel) Persistence(m *domain.Model) error {
return model.Persistent(m.DB(), p)
}
package cp_m
import (
"git.hilo.cn/hilo-common/domain"
"git.hilo.cn/hilo-common/resource/mysql"
"gorm.io/gorm"
"gorm.io/gorm/clause"
"time"
)
type CpVisitor struct {
CpId mysql.ID
UserId1 mysql.ID
UserId2 mysql.ID
Visitor mysql.ID
Times mysql.Num
CreatedTime time.Time `gorm:"->"`
UpdatedTime time.Time `gorm:"->"`
}
// 添加cp空间访问量
func AddCpSpaceVisitor(model *domain.Model, cpId, userId1, userId2, visitor mysql.ID) error {
vis := &CpVisitor{
CpId: cpId,
UserId1: userId1,
UserId2: userId2,
Visitor: visitor,
Times: 1,
}
if err := model.DB().Model(CpVisitor{}).Clauses(clause.OnConflict{Columns: []clause.Column{{Name: "cp_id"}, {Name: "visitor"}},
DoUpdates: clause.Assignments(map[string]interface{}{
"times": gorm.Expr("times + ?", 1)})}).Create(vis).Error; err != nil {
model.Log.Errorf("AddCpSpaceVisitor fail:%v", err)
return err
}
return nil
}
// 获取cp空间访问人数
func CountCpSpaceVisitors(model *domain.Model, cpId mysql.ID) int64 {
var cnt int64
if err := model.DB().Model(CpVisitor{}).Where("cp_id = ?", cpId).Count(&cnt).Error; err != nil {
model.Log.Errorf("CountCpSpaceVisitors fail:%v", err)
}
return cnt
}
package diamond_m
import (
"fmt"
"git.hilo.cn/hilo-common/_const/enum/diamond_e"
"git.hilo.cn/hilo-common/domain"
"git.hilo.cn/hilo-common/resource/mysql"
"git.hilo.cn/hilo-common/utils"
"hilo-user/myerr"
"hilo-user/myerr/bizerr"
"strconv"
"time"
)
type DiamondAccount struct {
mysql.Entity
*domain.Model `gorm:"-"`
UserId mysql.ID
DiamondNum mysql.Num
PinkDiamondNum mysql.Num
Status diamond_e.StatusAccount
}
//账号详情
type DiamondAccountDetail struct {
mysql.Entity
*domain.Model `gorm:"-"`
UserId mysql.ID
DiamondAccountId mysql.ID
OperateId mysql.ID
OperateType diamond_e.OperateType
OriginId mysql.ID
AddReduce mysql.AddReduce
Num mysql.Num
Remark mysql.Str
BefNum mysql.Num
AftNum mysql.Num
diamondAccount *DiamondAccount `gorm:"-"`
}
func (DiamondAccountDetail) TableName() string {
month := time.Now().Format("200601")
return fmt.Sprintf("diamond_account_detail_%s", month)
}
// 粉钻详情
type DiamondPinkAccountDetail struct {
mysql.Entity
*domain.Model `gorm:"-"`
UserId mysql.ID
DiamondAccountId mysql.ID
OperateId mysql.ID
OperateType diamond_e.OperateType
OriginId mysql.ID
AddReduce mysql.AddReduce
Num mysql.Num
Remark mysql.Str
BefNum mysql.Num
AftNum mysql.Num
diamondAccount *DiamondAccount `gorm:"-"`
}
//账号操作配置
type DiamondOperateSet struct {
mysql.Entity
*domain.Model `gorm:"-"`
DiamondNum mysql.NumAll
FrequencyNum mysql.NumAll
FrequencyDay mysql.NumAll
DiamondMaxNum mysql.NumAll
AddReduce mysql.AddReduce
Type diamond_e.OperateType
Name mysql.Str
Status mysql.UserYesNo
DiamondType diamond_e.OperateType
}
//通过userId获取帐号
func GetDiamondAccountByUserId(model *domain.Model, userId mysql.ID) (*DiamondAccount, error) {
var diamondAccount DiamondAccount
if err := model.Db.WithContext(model).Where(&DiamondAccount{
UserId: userId,
}).First(&diamondAccount).Error; err != nil {
return nil, myerr.WrapErr(err)
}
diamondAccount.Model = model
return &diamondAccount, nil
}
//匹配条件扣费
func (diamondAccount *DiamondAccount) ChangeDiamondAccountDetail(operateType diamond_e.OperateType, originId mysql.ID, diamondNum mysql.Num) (*DiamondAccountDetail, error) {
return diamondAccount.addDiamondAccountDetail(operateType, originId, diamondNum)
}
//钻石操作记录,
func (diamondAccount *DiamondAccount) addDiamondAccountDetail(operateType diamond_e.OperateType, originId mysql.ID, diamondNum mysql.Num) (*DiamondAccountDetail, error) {
var diamondOperateSet DiamondOperateSet
var err error
if err = diamondAccount.Db.Where(&DiamondOperateSet{
Type: operateType,
Status: mysql.USER,
DiamondType: mysql.DiamondYellow,
}).First(&diamondOperateSet).Error; err != nil {
return nil, myerr.WrapErr(err)
}
//判断是增加,账号是否被冻结
if diamondAccount.Status == diamond_e.Frozen && diamondOperateSet.AddReduce == mysql.REDUCE {
return nil, bizerr.DiamondAccountFrozen
}
//无限,检查次数
var count int64
if diamondOperateSet.FrequencyDay == -1 {
if diamondOperateSet.FrequencyNum != -1 {
diamondAccount.DB().Table(DiamondAccountDetail{}.TableName()).Where(&DiamondAccountDetail{
UserId: diamondAccount.UserId,
OperateType: operateType,
}).Count(&count)
if count >= int64(diamondOperateSet.FrequencyNum) {
return nil, bizerr.DiamondFrequency
//return nil, myerr.NewSysError("钻石操作次数多大, userId:" + mysql.IdToStr(diamondAccount.UserId) + " diamondOperateSetId" + mysql.IdToStr(diamondOperateSet.ID))
}
}
} else if diamondOperateSet.FrequencyDay == 1 {
beginTime, err := time.ParseInLocation("2006-01-02", time.Now().Format("2006-01-02"), time.Local)
if err != nil {
return nil, myerr.WrapErr(err)
}
//一天的次数
diamondAccount.DB().Table(DiamondAccountDetail{}.TableName()).Where(&DiamondAccountDetail{
UserId: diamondAccount.UserId,
OperateType: operateType,
}).Where("created_time >= ? ", beginTime).Count(&count)
if count >= int64(diamondOperateSet.FrequencyNum) {
return nil, bizerr.DiamondFrequency
}
//终极拦截,利用
diamondAccount.SetCheckUpdateCondition(" EXISTS (SELECT * from (SELECT COUNT(1) as n from " + DiamondAccountDetail{}.TableName() + " d where d.user_id = " + strconv.FormatUint(diamondAccount.UserId, 10) + " and d.operate_type = " + strconv.FormatUint(uint64(operateType), 10) + " and d.created_time >= from_unixtime(" + strconv.FormatInt(utils.GetZeroTime(time.Now()).Unix(), 10) + ")) t where t.n < " + strconv.Itoa(diamondOperateSet.FrequencyNum) + " )")
}
//-1,代表值无效,由参数给与
var upateDiamondNum mysql.Num
if diamondOperateSet.DiamondNum == -1 {
upateDiamondNum = diamondNum
} else {
upateDiamondNum = mysql.Num(diamondOperateSet.DiamondNum)
}
var afterNum mysql.Num
if diamondOperateSet.AddReduce == mysql.ADD {
afterNum = diamondAccount.DiamondNum + upateDiamondNum
} else if diamondOperateSet.AddReduce == mysql.REDUCE {
if diamondAccount.DiamondNum < upateDiamondNum {
return nil, bizerr.DiamondNoEnough
}
afterNum = diamondAccount.DiamondNum - upateDiamondNum
} else {
return nil, myerr.NewSysError("AddReduce 值错误:" + mysql.TypeToString(mysql.Type(diamondOperateSet.AddReduce)))
}
diamondAccountDetail := &DiamondAccountDetail{
Model: diamondAccount.Model,
UserId: diamondAccount.UserId,
DiamondAccountId: diamondAccount.ID,
OperateId: diamondOperateSet.ID,
OperateType: diamondOperateSet.Type,
OriginId: originId,
AddReduce: diamondOperateSet.AddReduce,
Num: upateDiamondNum,
Remark: diamondOperateSet.Name,
BefNum: diamondAccount.DiamondNum,
AftNum: afterNum,
diamondAccount: diamondAccount,
}
return diamondAccountDetail, err
}
// 此方法必须要在事务里面调用
func ChangeDiamondAccountDetail(model *domain.Model, operateType diamond_e.OperateType, originId mysql.ID, userId mysql.ID, diamondNum mysql.Num) error {
diamondAccount, err := GetDiamondAccountByUserId(model, userId)
if err != nil {
model.Log.Errorf("ChangeDiamondAccountDetail operateType:%v, originId:%v, userId:%v, diamondNum:%v, err:%v", operateType, originId, userId, diamondNum, err)
return err
}
diamondAccountDetail, err := diamondAccount.ChangeDiamondAccountDetail(operateType, originId, diamondNum)
if err != nil {
model.Log.Errorf("ChangeDiamondAccountDetail operateType:%v, originId:%v, userId:%v, diamondNum:%v, err:%v", operateType, originId, userId, diamondNum, err)
return err
}
if err := diamondAccountDetail.PersistentNoInTransactional(); err != nil {
model.Log.Errorf("ChangeDiamondAccountDetail operateType:%v, originId:%v, userId:%v, diamondNum:%v, err:%v", operateType, originId, userId, diamondNum, err)
return err
}
return nil
}
package diamond_m
import (
"git.hilo.cn/hilo-common/resource/mysql"
"gorm.io/gorm"
"hilo-user/myerr"
"strconv"
)
func (diamondAccountDetail *DiamondAccountDetail) PersistentNoInTransactional() error {
//fixme: 这里有点奇怪, diamondAccount持久化动作在diamondAccountDetail持久化之后,RowsAffected 就一定是0
txDiamondAccount := diamondAccountDetail.Db.Model(diamondAccountDetail.diamondAccount)
if diamondAccountDetail.diamondAccount.CheckUpdateCondition() {
txDiamondAccount = txDiamondAccount.Where(diamondAccountDetail.diamondAccount.GetUpdateCondition())
}
if diamondAccountDetail.AddReduce == mysql.ADD {
//增加
txDiamondAccount.UpdateColumn("diamond_num", gorm.Expr("diamond_num + ?", diamondAccountDetail.Num))
} else if diamondAccountDetail.AddReduce == mysql.REDUCE {
//减少,保证不能扣成负数
txDiamondAccount.Where("diamond_num >= ?", diamondAccountDetail.Num).UpdateColumn("diamond_num", gorm.Expr("diamond_num - ?", diamondAccountDetail.Num))
} else {
myerr.NewSysError("addReduce 枚举错误 value:" + mysql.TypeToString(mysql.Type(diamondAccountDetail.AddReduce)))
}
if err := txDiamondAccount.Error; err != nil {
return myerr.WrapErr(err)
}
if txDiamondAccount.RowsAffected == 0 {
diamondAccountDetail.Log.Errorf("gorm condition update.RowsAffected = 0,AddReduce:%v", diamondAccountDetail.AddReduce)
return myerr.NewWaring("gorm condition update.RowsAffected = 0")
}
//持久化diamondAccountDetail
//if err := model.Persistent(diamondAccountDetail.Db, diamondAccountDetail); err != nil {
// return myerr.WrapErr(err)
//}
if err := diamondAccountDetail.DB().Table(diamondAccountDetail.TableName()).Save(diamondAccountDetail).Error; err != nil {
return myerr.WrapErr(err)
}
//改变diamondAccount值
if diamondAccountDetail.diamondAccount == nil {
return myerr.NewSysError("持久化错误, 模型:DiamondAccountDetail 中没有diamondAccount, DiamondAccountDetail.Id =" + strconv.Itoa(int(diamondAccountDetail.ID)))
}
var newDiamondAccount DiamondAccount
if err := diamondAccountDetail.Db.First(&newDiamondAccount, diamondAccountDetail.diamondAccount.ID).Error; err != nil {
return myerr.WrapErr(err)
}
if newDiamondAccount.DiamondNum < 0 {
return myerr.NewSysError("diamond_account表中,diamond_num 不能小于0, diamondAccount.id = " + strconv.Itoa(int(newDiamondAccount.ID)))
}
return nil
}
package event_m
import "hilo-user/domain/model"
func (p *EventGiftSendOffsetHiloUser) Persistence() error {
return model.Persistent(p.Db, p)
}
func (p *EventGiftSend) Persistence() error {
return model.Persistent(p.Db, p)
}
package event_m
import (
"git.hilo.cn/hilo-common/domain"
"git.hilo.cn/hilo-common/resource/mysql"
"github.com/pkg/errors"
"gorm.io/gorm"
"time"
)
// 送礼事件消息
type EventGiftSend struct {
mysql.Entity
*domain.Model `gorm:"-"`
Proto mysql.Type
Payload []byte
Mark mysql.YesNo
MarkHiloGroup mysql.YesNo
MarkHiloUser mysql.YesNo
}
func (EventGiftSend) TableName() string {
return "event_gift_send"
}
// 偏移值
type EventGiftSendOffsetHiloUser struct {
mysql.Entity
*domain.Model `gorm:"-"`
MarkOffset mysql.ID
}
// 获取当前偏移值
func Offset(model *domain.Model) (*EventGiftSendOffsetHiloUser, error) {
offset := new(EventGiftSendOffsetHiloUser)
if err := model.Db.WithContext(model).First(offset).Error; err != nil {
if err != gorm.ErrRecordNotFound {
model.Log.Errorf("Offset fail:%v", err)
return nil, err
}
// gorm.ErrRecordNotFound
}
offset.Model = model
return offset, nil
}
// 批量获取送礼
func FetchEventGiftSend(model *domain.Model, limit int) ([]*EventGiftSend, *EventGiftSendOffsetHiloUser, error) {
offset, err := Offset(model)
if err != nil {
return nil, nil, err
}
var events []*EventGiftSend
if err := model.Db.WithContext(model).Model(EventGiftSend{}).
Where("id > ?", offset.MarkOffset).
Order("id asc").Limit(limit).Find(&events).Error; err != nil {
model.Log.Errorf("FetchEventGiftSend fail:%v", err)
return nil, nil, err
}
return events, offset, nil
}
// 标记已完成
func (p *EventGiftSend) MarkDone() error {
p.MarkHiloUser = mysql.YES
result := p.Db.WithContext(p.Model).Model(EventGiftSend{}).Where("id = ?", p.ID).Update("mark_hilo_user", p.MarkHiloUser).Limit(1)
if result.Error != nil {
return result.Error
}
if result.RowsAffected <= 0 {
p.Model.Log.Errorf("MarkDone row affeced 0")
return errors.New("row affect 0")
}
return nil
}
// 查询过去1小时-5分钟前未mark的事件
// 用来补偿
// 记得加limit
func FetchUnMarkEvents(model *domain.Model, limit int) ([]*EventGiftSend, error) {
offset, err := Offset(model)
if err != nil {
return nil, err
}
t := time.Now().Add(-time.Minute * 5)
lt := t.Add(-time.Hour)
var events []*EventGiftSend
if err := model.Db.WithContext(model).Model(EventGiftSend{}).
Where("mark_hilo_user = ?", mysql.NO).
Where("id <= ?", offset.MarkOffset).
Where("created_time < ?", t).
Where("created_time > ?", lt).
Order("id asc").Limit(limit).Find(&events).Error; err != nil {
model.Log.Errorf("FetchUnMarkEvents fail:%v", err)
return nil, err
}
return events, nil
}
// 补偿加上unmark的event
func AddUnMarkEvent(model *domain.Model, event *EventGiftSend) error {
return model.Db.WithContext(model).Create(event).Error
}
package groupPower_m
import (
"git.hilo.cn/hilo-common/domain"
"git.hilo.cn/hilo-common/resource/mysql"
"gorm.io/gorm"
"hilo-user/_const/enum/groupPower_e"
"hilo-user/domain/model/group_m"
"hilo-user/myerr"
)
type GroupPowerUser struct {
mysql.Entity
*domain.Model `gorm:"-"`
GroupPowerId mysql.ID
UserId mysql.ID
Role groupPower_e.GroupPowerUserRole
}
type GroupPower struct {
mysql.Entity
*domain.Model `gorm:"-"`
GroupUid mysql.Str
Name mysql.Str
Status groupPower_e.GroupPowerStatus
}
// 查询用户加入的国家势力ID及名称(势力绑定的群组的名称)
func GetUserGroupPower(model *domain.Model, userId uint64) (uint64, string, error) {
gpu, err := GetGroupPowerUserOrNil(model, userId)
if err != nil {
return 0, "", err
}
if gpu == nil || gpu.GroupPowerId == 0 {
return 0, "", nil
}
gp, err := GetGroupPowerOrErr(model, gpu.GroupPowerId)
if err != nil {
return 0, "", err
}
powerName := ""
if gp != nil && len(gp.GroupUid) > 0 {
gi, err := group_m.GetGroupInfo(model, gp.GroupUid)
if err != nil {
return 0, "", err
}
if gi != nil {
// 只要前15个字
s := []rune(gi.Name)
if len(s) <= 15 {
powerName = string(s)
} else {
powerName = string(s[0:15])
}
}
}
return gpu.GroupPowerId, powerName, nil
}
//获取用户所在的国家势力信息,不存在则为nil
func GetGroupPowerUserOrNil(model *domain.Model, userId mysql.ID) (*GroupPowerUser, error) {
groupPowerUser := GroupPowerUser{}
if err := model.Db.Where(&GroupPowerUser{
UserId: userId,
}).First(&groupPowerUser).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, nil
} else {
return nil, myerr.WrapErr(err)
}
}
groupPowerUser.Model = model
return &groupPowerUser, nil
}
func GetGroupPowerOrErr(model *domain.Model, id uint64) (*GroupPower, error) {
groupPower := GroupPower{}
if err := model.Db.Model(&GroupPower{}).First(&groupPower, id).Error; err != nil {
return nil, myerr.WrapErr(err)
}
groupPower.Model = model
return &groupPower, nil
}
package group_m
import (
"git.hilo.cn/hilo-common/domain"
"gorm.io/gorm"
"hilo-user/_const/enum/group_e"
"hilo-user/myerr/bizerr"
"time"
)
type GroupInfo struct {
Id int64
ImGroupId string
TxGroupId string
Type uint16
Code string
OriginCode string
Owner uint64
Name string
Introduction string
Notification string
FaceUrl string
Country string
ChannelId string
Password string
EntryLevel uint32 // obsolete
MicOn bool
LoadHistory bool
ThemeId int16
MicNumType group_e.GroupMicNumType
TouristMic uint8 // 游客是否能上麦1是2否
TouristSendMsg uint8 // 游客是否能发消息1是2否
TouristSendPic uint8 // 游客是否能发图片1是2否
MemberFee uint64 // 加入会员需要黄钻数
CreatedTime time.Time `gorm:"->"`
UpdatedTime time.Time `gorm:"->"`
}
func GetGroupInfo(model *domain.Model, groupId string) (*GroupInfo, error) {
if len(groupId) <= 0 {
return nil, bizerr.GroupNotFound
}
r := GroupInfo{}
err := model.Db.Where(&GroupInfo{ImGroupId: groupId}).First(&r).Error
if err != nil {
if err == gorm.ErrRecordNotFound {
return nil, nil
} else {
return nil, err
}
}
return &r, nil
}
func FindGroupByOwner(model *domain.Model, ownerId uint64) ([]GroupInfo, error) {
rows := make([]GroupInfo, 0)
err := model.Db.Where(&GroupInfo{Owner: ownerId}).Find(&rows).Error
if err != nil {
return nil, err
}
return rows, nil
}
func ToTxGroupId(model *domain.Model, imGroupId string) (string, error) {
if len(imGroupId) <= 0 {
return "", nil
}
gi, err := GetGroupInfo(model, imGroupId)
if err != nil {
return "", err
}
if gi == nil {
return "", bizerr.GroupNotFound
}
return gi.TxGroupId, nil
}
func ToTxGroupIdMap(model *domain.Model, imGroupIds []string) (map[string]string, error) {
var res = make(map[string]string)
var rows []GroupInfo
if err := model.DB().Model(GroupInfo{}).Where("im_group_id in ?", imGroupIds).Find(&rows).Error; err != nil {
return res, err
}
for _, v := range rows {
res[v.ImGroupId] = v.TxGroupId
}
return res, nil
}
func ToImGroupId(model *domain.Model, txGroupId string) (string, error) {
if len(txGroupId) <= 0 {
return "", nil
}
gi, err := GetInfoByTxGroupId(model, txGroupId)
if err != nil {
return "", err
}
if gi == nil {
return "", bizerr.GroupNotFound
}
return gi.ImGroupId, nil
}
func GetInfoByTxGroupId(model *domain.Model, txGroupId string) (*GroupInfo, error) {
if len(txGroupId) <= 0 {
return nil, bizerr.GroupNotFound
}
r := GroupInfo{}
err := model.Db.Where(&GroupInfo{TxGroupId: txGroupId}).First(&r).Error
if err != nil {
if err == gorm.ErrRecordNotFound {
return nil, nil
} else {
return nil, err
}
}
return &r, nil
}
package group_m
import (
"git.hilo.cn/hilo-common/_const/common"
"git.hilo.cn/hilo-common/domain"
"git.hilo.cn/hilo-common/resource/mysql"
"gorm.io/gorm"
)
type GroupRoles struct {
mysql.Entity
UserId uint64
ImGroupId string
Role common.GroupRoleType
}
type GroupMember struct {
GroupId string
UserId uint64
}
func (gm *GroupMember) Find(db *gorm.DB) ([]GroupMember, error) {
rows := make([]GroupMember, 0)
if err := db.Where(gm).Order("created_time DESC").Find(&rows).Error; err != nil {
return nil, err
}
return rows, nil
}
func GetGroupRoleById(model *domain.Model, imGroupId string, userId uint64) (role common.GroupRoleType, err error) {
role = common.GROUP_VISITOR
roles, _, err := GetRolesInGroup(model, imGroupId)
if err != nil {
return
}
for u, r := range roles {
if u == userId {
role = r
return
}
}
isGroupMember, err := IsGroupMember(model.Db, imGroupId, userId)
if err != nil {
return
}
if isGroupMember {
role = common.GROUP_MEMBER
}
return
}
// 查询群组中所有有角色的成员,由级别高到低、创建时间由早到晚排列
func GetRolesInGroup(model *domain.Model, groupId string) (map[uint64]uint16, []uint64, error) {
data := make([]GroupRoles, 0)
err := model.Db.Where(&GroupRoles{ImGroupId: groupId}).Order("role DESC, created_time").Find(&data).Error
if err != nil {
return nil, nil, err
}
result := make(map[uint64]uint16, 0)
orders := make([]uint64, 0)
for _, i := range data {
orders = append(orders, i.UserId)
result[i.UserId] = i.Role
}
return result, orders, nil
}
func IsGroupMember(db *gorm.DB, groupId string, userId uint64) (bool, error) {
gm := GroupMember{
GroupId: groupId,
UserId: userId,
}
rows, err := gm.Find(db)
if err != nil {
return false, err
}
return len(rows) > 0, nil
}
package group_m
import (
"git.hilo.cn/hilo-common/domain"
"git.hilo.cn/hilo-common/mylogrus"
"git.hilo.cn/hilo-common/resource/mysql"
"hilo-user/_const/redis_key/group_k"
"hilo-user/myerr"
"strconv"
"strings"
"time"
)
// 3天
const expireMinute = 60 * 60 * 24 * 3
//获取在房间的用户 返回值:map,key:userId, value:groupUuid
func RoomLivingUserIdFilter(model *domain.Model, userIds []mysql.ID) (map[mysql.ID]string, error) {
userIdSet := map[mysql.ID]struct{}{}
for i, _ := range userIds {
userIdSet[userIds[i]] = struct{}{}
}
key := group_k.GetPrefixGroupRoomLiving()
if err := ClearExpired(model, key, expireMinute); err != nil {
return nil, myerr.WrapErr(err)
}
groupUserIdstrs, err := model.RedisCluster.ZRange(model, key, 0, -1).Result()
if err != nil {
return nil, myerr.WrapErr(err)
}
resultUserSet := map[mysql.ID]string{}
for i, _ := range groupUserIdstrs {
tempGroupUid, userId := analysisMemberStr(groupUserIdstrs[i])
if _, flag := userIdSet[userId]; flag {
resultUserSet[userId] = tempGroupUid
}
}
return resultUserSet, nil
}
func ClearExpired(model *domain.Model, key string, expireSec int64) error {
return model.RedisCluster.ZRemRangeByScore(model, key,
"0", strconv.FormatInt(time.Now().Unix()-expireSec, 10)).Err()
}
func analysisMemberStr(memberStr string) (string, uint64) {
strs := strings.Split(memberStr, "_")
groupUid := strs[0]
userId, err := strconv.ParseUint(strs[1], 10, 64)
if err != nil {
mylogrus.MyLog.Errorf("analysisMemberStr memberStr:%v err:%+v", memberStr, err)
}
return groupUid, userId
}
package invite_m
import (
"git.hilo.cn/hilo-common/domain"
"git.hilo.cn/hilo-common/resource/mysql"
"git.hilo.cn/hilo-common/utils"
"gorm.io/gorm"
"time"
)
type InviteApply struct {
Id uint64 `json:"id"`
UserId uint64 `json:"user_id"`
NewUserId uint64 `json:"new_user_id"`
Platform string `json:"platform"`
PlatformId string `json:"platform_id"`
RechargeInfo string `json:"recharge_info"`
Status uint8 `json:"status"` // 状态0.未审核1.已通过2.已拒绝
VideoUrl string `json:"video_url"`
Level string `json:"level"`
CreatedTime time.Time `json:"created_time"`
Reason int `json:"reason"` // 1.已申请2.待审核3.已通过4.已拒绝"
SubUserId uint64 `json:"sub_user_id"` // 提交人
}
func CreateInviteApply(model *domain.Model, userId, newUserId, subUserId uint64, platform, platformId, recharge, videoUrl string) error {
err := model.DB().Create(&InviteApply{
UserId: userId, NewUserId: newUserId, Platform: platform, PlatformId: platformId, RechargeInfo: recharge, VideoUrl: videoUrl,
CreatedTime: time.Now(), SubUserId: subUserId}).Error
if err != nil {
model.Log.Errorf("CreateInviteApply err:%v", err)
return err
}
return nil
}
func GetApplyList(model *domain.Model, subUserId uint64, userIds []uint64, pageIndex, pageSize, gType int, beginTime,
endTime time.Time) ([]*InviteApply, int64, error) {
db := model.DB().Model(InviteApply{}).Where("user_id in (?) or sub_user_id = ?", userIds, subUserId).Where("created_time >= ? and created_time <= ?", beginTime, endTime)
switch gType { // 1.已申请2.待审核3.已通过4.已拒绝
case 2:
db = db.Where("`status` = ?", 0)
case 3:
db = db.Where("`status` = ?", 1)
case 4:
db = db.Where("`status` = ?", 2)
}
res := make([]*InviteApply, 0)
var count int64
err := db.Order("id desc").Offset((pageIndex - 1) * pageSize).Find(&res).Limit(-1).Offset(-1).Count(&count).Error
if err != nil {
model.Log.Errorf("GetApplyList err:%v", err)
return nil, 0, err
}
return res, count, nil
}
// 检查被邀请人是否存在
func IsInInviteApply(model *domain.Model, userId mysql.ID) (bool, error) {
var apply InviteApply
if err := model.Db.Model(InviteApply{}).Where("new_user_id = ?", userId).First(&apply).Error; err != nil {
if err != gorm.ErrRecordNotFound {
return false, err
}
return false, nil
}
// err == nil, record exists
return true, nil
}
// 检查被邀请人是否存在
func GetInviteApplyNumByType(model *domain.Model, gType int, beginTime, endTime time.Time, userIds []uint64, subUserId uint64) (int, error) {
var count int64
db := model.Db.Model(InviteApply{}).Where("user_id in (?) or sub_user_id = ?", userIds, subUserId).Where("created_time >= ? and created_time <= ?", beginTime, endTime)
switch gType { // 1.已申请2.待审核3.已通过4.已拒绝
case 2:
db = db.Where("`status` = ?", 0)
case 3:
db = db.Where("`status` = ?", 1)
case 4:
db = db.Where("`status` = ?", 2)
}
if err := db.Count(&count).Error; err != nil {
return 0, err
}
return int(count), nil
}
// 今日已提交次数
func TodayInviteApplyCount(model *domain.Model, userId mysql.ID) (int64, error) {
start, end := utils.DayStartEnd(time.Now())
var count int64
if err := model.Db.Model(InviteApply{}).
Where("user_id = ?", userId).
Where("created_time >= ? and created_time <= ?", start.Format(utils.DATETIME_FORMAT), end.Format(utils.DATETIME_FORMAT)).
Count(&count).Error; err != nil {
return 0, err
}
// err == nil, record exists
return count, nil
}
package promotion_m
import "git.hilo.cn/hilo-common/resource/mysql"
// 推广员
type PromotionAgent struct {
mysql.Entity
ManagerId mysql.ID
AgentId mysql.ID
}
// 邀请关系
type PromotionInvite struct {
mysql.Entity
ManagerId mysql.ID
AgentId mysql.ID
Invitee mysql.ID
Platform string
PlatformId string
Reason string
InviteDate string
}
// 邀请关系日志
type PromotionInviteLog struct {
mysql.Entity
AgentId mysql.ID
Invitee mysql.ID
AddReduce mysql.AddReduce
}
This diff is collapsed.
This diff is collapsed.
......@@ -191,7 +191,7 @@ func GetLangeByCountry(db *gorm.DB, country mysql.Str) (string, error) {
if err == nil {
return r.Lang, nil
} else if err == gorm.ErrRecordNotFound {
return res_e.DEFAULT_LANG, nil
return res_e.DefaultLang, nil
} else {
return "", myerr.WrapErr(err)
}
......
......@@ -22,6 +22,7 @@ type ResGift struct {
Together bool
Status mysql.UserYesNo
GiftType mysql.Type
HasGiftText bool
}
// 获取所有的礼物
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.