Commit b4d52c16 authored by hujiebin's avatar hujiebin

Merge branch 'feature/jackpot' into 'master'

Feature/jackpot

See merge request !1
parents 5a78e911 1c33ff36
swag: swag:
swag init swag init
proto:
protoc --go_out=./ --go-grpc_out=. ./protocol/*.proto
\ No newline at end of file
package diamond_e
import "hilo-user/resource/mysql"
type StatusAccount = mysql.Type
const (
Normal StatusAccount = 1
//冻结,只是限制减少,不限制增加
Frozen StatusAccount = 2
)
type OperateType = mysql.Type
const (
//注册
/* REGISTER OperateType = 1
//建立融云会话
SessionPay OperateType = 2
//购买钻石
BuyDiamond OperateType = 3
//发送礼物
SendGift OperateType = 4
//接受礼物
ReceiveGift OperateType = 5
//匹配条件
MatchCondition OperateType = 6*/
SendGift OperateType = 1 //发送礼物
MatchCondition OperateType = 2 //匹配条件
SessionPay OperateType = 3 //建立融云会话
BuyDiamond OperateType = 4 //购买钻石
ReceiveGift OperateType = 5 //接受礼物
REGISTER OperateType = 6 //注册
MgrSend OperateType = 8 //平台赠送
VideoCost OperateType = 9 //1对1视频花费
MgrReduce OperateType = 10 //平台扣除
ActivityBillboard OperateType = 11 //活动榜单奖励
ExchangeBean OperateType = 12 //钻石兑换豆子
ActivityGroupBillboard OperateType = 13 //活动榜单奖励
DailyInAppVip OperateType = 14 //每日登陆领取钻石(VIP)
GroupIMMass OperateType = 15 //群中IM群发
DailyInAppCommon OperateType = 16 //每日登陆领取钻石(普通用户)
GroupSupportAdmin OperateType = 17 //群组支持(利益分配者)
GroupSupportMgr OperateType = 18 //群主支持(助手)
MgrBillDiamond OperateType = 19 //管理人单据送钻石
Headwear OperateType = 20 //送头饰扣费
Property OperateType = 21 //送坐骑扣费
LuckyWheelJoin OperateType = 22 //参与转盘扣费
LuckyWheelCancel OperateType = 23 //转盘取消
LuckyWheelWin OperateType = 24 //转盘奖励
LuckWheelGroupOwer OperateType = 25 //转盘群主抽成
DealerTransfer OperateType = 26 //币商转账
GroupCustomTheme OperateType = 27 //购买群组自定义主题
RocketAward OperateType = 28 //火箭奖励
LuckyboxBuy OperateType = 29 //幸运盒子购买
LuckyboxAward OperateType = 30 //幸运盒子奖励
PrivateGift OperateType = 31 // 私聊送礼物
PrivateGiftReturn OperateType = 32 // 私聊送礼物退款
ActivityTriggerAward OperateType = 33 //活动触发奖励
VideoTradeUnionGift OperateType = 34 // 视频送礼物
VideoTradeUnionGiftReturn OperateType = 35 // 视频送礼物退款
GlobalBroadcast OperateType = 36 //全球发布消息
TaskAward OperateType = 37 //任务奖励
FruitMachineAward OperateType = 38 // 水果机奖励
FruitMachineBet OperateType = 39 // 水果机投注
Noble OperateType = 40 //购买/赠送贵族
FruitTycoonAward OperateType = 41 // 水果大亨奖励
Checkout OperateType = 42 //checkout购买
LuckyboxCycle OperateType = 43 //幸运盒子回收奖励
ActivityRechargeFirst OperateType = 44 //首次充值奖励
NewUserInvite OperateType = 45 // 新用户奖励活动
GeneralActivity OperateType = 46 // 一般性活动奖励
PowerSupportOwner OperateType = 47 // 势力支持(势力主)
PowerSupportAssistant OperateType = 48 // 势力支持(助手)
VideoMinute OperateType = 49 //1对1视频(分钟扣费)
MatchMinute OperateType = 50 //匹配视频(第一分钟扣费)
VideoMinuteBack OperateType = 51 //1对1视频(分钟扣费,返回)
VideoMinuteTotal OperateType = 52 //1对1视频(分钟扣费,返回)
GroupActivity OperateType = 53 //创建群组活动
GroupActivityReward OperateType = 54 //群组活动奖励
PayerMax OperateType = 55 //payerMax/茄子支付购买
BuyPinkDiamond OperateType = 56 //购买粉钻
VideoCostPink OperateType = 57 //1对1视频送礼(粉钻)
MatchMinutePink OperateType = 58 //匹配视频(第一分钟扣费)(粉钻)
VideoMinuteTotalPink OperateType = 59 //1对1视频(分钟扣费,返回)(粉钻)
SendPinkGift OperateType = 60 //送粉钻礼物 ---占位---暂不开放 数据库配置表中暂未配置
MatchMinuteGiftPink OperateType = 61 //匹配视频送礼(粉钻)
MatchMinuteGiftPinkTime OperateType = 62 //匹配视频加时送礼(粉钻)
JoinGroupCost OperateType = 63 //加入群组扣费
JoinGroupAdd OperateType = 64 //加入群组,群主得黄钻
GameJoin OperateType = 65 //加入游戏扣费
GameAward OperateType = 66 //游戏结算奖励
GameRefund OperateType = 67 //游戏退费
)
const (
DiamondYellow mysql.Type = 1
DiamondPink mysql.Type = 2
)
package user_e
type ReportType string
type GameType int
type GameOpt int
type GameStatus uint8
type GamerStatus uint8
type GamerPlayerStatus uint8
type GameMode = int
const (
ReportTypeGameStart ReportType = "user_start" // 战斗开始通知
ReportTypeGameSettle ReportType = "user_settle" // 战斗结算通知
GameAutoMatchYes = 1 // 游戏自动匹配
GameAutoMatchNo = 0 // 游戏非自动匹配
GameTypeLudo GameType = 1 // ludo
GameTypeUno GameType = 2 // uno
GameModeQuick GameMode = 0
GameModeClassic GameMode = 1
GameOptCreate GameOpt = 0 // 创建游戏
GameOptJoin GameOpt = 1 // 加入游戏,自动准备
GameOptExit GameOpt = 2 // 退出游戏
GameOptClose GameOpt = 3 // 创建者关闭游戏
//GameOptReady GameOpt = 2 // 准备游戏
//GameOptCancelReady GameOpt = 3 // 取消准备游戏
GameStatusNoStart GameStatus = 0 // 未开始
GameStatusGaming GameStatus = 1 // 游戏中
GameStatusEnd GameStatus = 2 // 游戏结束
GamerStatusUnready GamerStatus = 0 // 未开始
GamerStatusGaming GamerStatus = 1 // 游戏中
GamerStatusEnd GamerStatus = 2 // 游戏结束
GamerExit GamerStatus = 3 // 自己退出游戏
GamerClose GamerStatus = 4 // 创建者关闭游戏
//GamerStatusReady GamerStatus = 1 // 准备
//GamerExit GamerStatus = 4 // 自己退出游戏
MgIdLudo = "1468180338417074177"
MgIdUno = "1472142559912517633"
)
package groupPower_e
import "hilo-user/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
)
// 国家势力日志操作类型
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 "hilo-user/resource/mysql"
// 信令消息(不显示公屏工,不记入消息历史,不影响未读数)
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 //房间-用户群组身份变化
GroupGameInfoLudo TypeSignalMsg = 200 // 房间-游戏信息-ludo
GroupGameSettleLudo TypeSignalMsg = 201 // 房间-游戏结算信息-ludo
GroupGameInfoUno TypeSignalMsg = 202 // 房间-游戏信息-uno
GroupGameSettleUno TypeSignalMsg = 203 // 房间-游戏结算信息-uno
)
// 群组麦位数量类型
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
//
)
// 公屏消息
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 // 用户进入房间
GameLudoPubMsg TypePublicScreenMsg = 101 // Ludo游戏公屏
GameUnoPubMsg TypePublicScreenMsg = 102 // uno游戏公屏
)
package headwear_e
import "git.hilo.cn/hilo-common/resource/mysql"
type UserHeadwearUsing = mysql.Type
const (
YesUsing UserHeadwearUsing = 1
NoUsing UserHeadwearUsing = 0
)
type UserHeadwearLogOrginType = mysql.Type
const (
Mgr UserHeadwearLogOrginType = 1
//购买,或者别人购买
Send UserHeadwearLogOrginType = 2
Activity UserHeadwearLogOrginType = 3
Rocket UserHeadwearLogOrginType = 4
//活动阀值自动触发奖励
ActivityTrigger UserHeadwearLogOrginType = 5
//首次充值奖励
ActivityRechargeFirst UserHeadwearLogOrginType = 6
//别人赠送
Give UserHeadwearLogOrginType = 7
GeneralActivity UserHeadwearLogOrginType = 8
)
type UserHeadwearLogType mysql.Type
const (
AddSecond UserHeadwearLogType = 1
UpdateEndTime UserHeadwearLogType = 2
Del UserHeadwearLogType = 3
)
package match_e
import "hilo-user/resource/mysql"
/****************************/
type MatchDetailDataChange mysql.NumAll
const (
AddDataChange MatchDetailDataChange = 1
ReduceDataChange MatchDetailDataChange = 2
ZeroDataChange MatchDetailDataChange = 0
)
/******元素分数***************/
/*type EnumCountType mysql.Type
const (
PriorityEnumCountType EnumCountType = 1
ExcellentEnumCountType EnumCountType = 2
RelationEnumCountType EnumCountType = 3
)*/
/*const (
//接收到礼物的数量
ReceiveGiftNumCountType EnumCountType = 1
//接收到礼物的频率
ReceiveGiftFCountType EnumCountType = 2
//被举报
BeReportCountType EnumCountType = 3
//被拉黑
BeBlackCountType EnumCountType = 4
//支付次数
PayCountType EnumCountType = 5
//被喜欢的次数
LikeMeType EnumCountType = 6
//新用户
NewUserType EnumCountType = 7
//连续被拒
AgainRefuse EnumCountType = 8
//每天新登陆用户
DailyUserType EnumCountType = 9
//活跃等级
ActiveGrade EnumCountType = 10
//连续同性
AgainSameSex EnumCountType = 11
//匹配推送次数
MatchSuccessNum EnumCountType = 12
//匹配推送接受次数
MatchConfirmNum EnumCountType = 13
//接通率
MatchConfirmRate EnumCountType = 14
//免费加时
MatchFreeTimeNum EnumCountType = 15
//礼物加时
MatchGiftTimeNum EnumCountType = 16
//加时率
MatchAddTimeRate EnumCountType = 17
//工会成员
TradeUnion EnumCountType = 18
//匹配拒绝
RelationMatchRefuse EnumCountType = 19
//匹配用户
RelationMatchUser EnumCountType = 20
)*/
// 优先度排序
type PriorityUserFormOriginType mysql.Type
const (
//钻石余额
PriorityDiamond PriorityUserFormOriginType = 1
//首充
PriorityFirstCharge PriorityUserFormOriginType = 2
//财富等级
PriorityWealthGrade PriorityUserFormOriginType = 3
//被举报
PriorityBeReport PriorityUserFormOriginType = 4
//被拉黑
PriorityBeBlack PriorityUserFormOriginType = 5
//近期充值
PriorityRecentlyPay PriorityUserFormOriginType = 6
//新用户
PriorityNewUserType PriorityUserFormOriginType = 7
//连续被拒
PriorityAgainRefuse PriorityUserFormOriginType = 8
//每天新登陆用户
PriorityDailyUserType PriorityUserFormOriginType = 9
//活跃等级
PriorityActiveGrade PriorityUserFormOriginType = 10
//工会
PriorityTradeUnion PriorityUserFormOriginType = 11
//多次匹配到同性
PriorityAgainSameSex PriorityUserFormOriginType = 12
)
var PriorityMap = map[PriorityUserFormOriginType]string{
PriorityDiamond: "钻石余额",
PriorityFirstCharge: "首充",
PriorityWealthGrade: "财富等级",
PriorityBeReport: "被举报",
PriorityBeBlack: "被拉黑",
PriorityRecentlyPay: "近期充值",
PriorityNewUserType: "新用户",
PriorityAgainRefuse: "连续被拒",
PriorityDailyUserType: "每天新登陆用户",
PriorityActiveGrade: "活跃等级",
PriorityTradeUnion: "工会",
PriorityAgainSameSex: "连续同性",
}
// 质量排序
type ExcellentUserFormOriginType mysql.Type
const (
//被喜欢的次数
ExcellentLikeMe ExcellentUserFormOriginType = 1
//接收礼物数量
ExcellentReceiveGiftNumChange ExcellentUserFormOriginType = 2
//接收礼物次数
ExcellentReceiveGiftFChange ExcellentUserFormOriginType = 3
//被投诉次数
ExcellentBeReport ExcellentUserFormOriginType = 4
//被拉黑的次数
ExcellentBeBlack ExcellentUserFormOriginType = 5
//魅力等级
ExcellentCharmGrade ExcellentUserFormOriginType = 6
//被付费建立融云会话
ExcellentSessionCreate ExcellentUserFormOriginType = 7
//接通率
ExcellentMatchConfirmRate ExcellentUserFormOriginType = 8
//加时率(视频通话加时次数(免费加时成功 + 礼物加时成功)/视频通话次数(匹配成功的次数))
ExcellentAddTimeRate ExcellentUserFormOriginType = 9
//工会成员
ExcellentTradeUnion ExcellentUserFormOriginType = 10
//匹配成功次数
ExcellentMatchSuccessNum ExcellentUserFormOriginType = 11
//匹配确认次数
ExcellentMatchConfirmNum ExcellentUserFormOriginType = 12
//匹配免费加时的次数
ExcellentMatchFreeTimeNum ExcellentUserFormOriginType = 13
//匹配礼物加时次数
ExcellentMatchGiftTimeNum ExcellentUserFormOriginType = 14
)
var ExcellentMap = map[ExcellentUserFormOriginType]string{
ExcellentLikeMe: "喜欢我",
ExcellentReceiveGiftNumChange: "接收礼物数量",
ExcellentReceiveGiftFChange: "接收礼物次数",
ExcellentBeReport: "被投诉次数",
ExcellentBeBlack: "被拉黑次数",
ExcellentCharmGrade: "魅力等级",
ExcellentSessionCreate: "被付费建立融云会话",
ExcellentMatchConfirmRate: "接通率",
ExcellentAddTimeRate: "加时率",
ExcellentTradeUnion: "工会成员",
ExcellentMatchSuccessNum: "匹配成功次数",
ExcellentMatchConfirmNum: "匹配确认次数",
ExcellentMatchFreeTimeNum: "匹配免费加时次数",
ExcellentMatchGiftTimeNum: "匹配礼物加时次数",
}
// 关系排序
type RelationUserFormOriginType mysql.Type
const (
//喜欢的用户
RelationUserLike RelationUserFormOriginType = 1
//匹配拒绝用户
RelationMatchRefuse RelationUserFormOriginType = 2
//匹配过的用户
RelationMatchUser RelationUserFormOriginType = 3
//付费发送过消息但没进行过视频聊天
RelationSessionNoMatchConfirm RelationUserFormOriginType = 4
//上一次匹配的用户
RelationMatchUserLastTime RelationUserFormOriginType = 5
)
var RelationMap = map[RelationUserFormOriginType]string{
RelationUserLike: "喜欢的用户",
RelationMatchRefuse: "匹配被拒绝",
RelationMatchUser: "匹配上的用户",
RelationSessionNoMatchConfirm: "付费发送过消息但没进行过视频聊天",
RelationMatchUserLastTime: "上一次匹配的用户",
}
/******匹配确认***********************************/
type MatchConfirmStatus mysql.Type
const (
Success MatchConfirmStatus = 1
Fail MatchConfirmStatus = 2
Temp MatchConfirmStatus = 3
)
type MatchConfirmUserAcceptRefuse mysql.Type
const (
AcceptMatchConfirmUser MatchConfirmUserAcceptRefuse = 1
RefuseMatchConfirmUser MatchConfirmUserAcceptRefuse = 2
)
type MatchCharmUserScoreDetailType = mysql.Type
const (
GiftReceiveCharmType MatchCharmUserScoreDetailType = 1
GiftReceiveVipCharmType MatchCharmUserScoreDetailType = 2
)
type MatchWealthUserScoreDetailType = mysql.Type
const (
GiftReceiveWealthType MatchWealthUserScoreDetailType = 1
GiftReceiveVipWealthType MatchWealthUserScoreDetailType = 2
)
package msg_e
import "git.hilo.cn/hilo-common/resource/mysql"
//消息发送类型,消息接收者是谁 1:通知 2:官网 3:被喜欢通知 (注意:MsgReceiveType 同 MsgUserRecordType 不是树形关系s)
//MsgReceive 结构体服务
type MsgReceiveType = mysql.Type
const (
//小助手的通知
UserMsgReceiveType MsgReceiveType = 1
//系统的通知
SysMsgReceiveType MsgReceiveType = 2
//喜欢消息
LikeMeReceiveType MsgReceiveType = 3
//工会用户通知
TradeUnionReceiveType MsgReceiveType = 4
//用户召回
UserRecall MsgReceiveType = 5
//video请求
VideoSend MsgReceiveType = 6
//访问
VisitReceiveType MsgReceiveType = 7
//拉黑
BlockReceiveType MsgReceiveType = 8
//短信验证码
SmsCode MsgReceiveType = 9
)
//跳转类型 0:无调整 1:网页跳转 2:app跳转 3:跳转到钻石 4:跳转到背包
type ActionType = uint16
const (
NonActionType ActionType = 0
WebActionType ActionType = 1
AppActionType ActionType = 2
)
//消息记录类型(设计的不好,应该是根据消息样式类型设计,而不是业务类型,渣渣)
type MsgUserRecordType = mysql.Type
const (
//新用户
//NewUserType MsgUserRecordType = 1
//举报
ReportType MsgUserRecordType = 2
//喜欢我
//LikeMeType MsgUserRecordType = 3
//重置图片
ResetAvatarType MsgUserRecordType = 4
//
//喜欢我
LikeMeType MsgUserRecordType = 5
//访问
VisitType MsgUserRecordType = 6
//新匹配记录
MatchHistoryType MsgUserRecordType = 7
//互相喜欢
LikeEachType MsgUserRecordType = 8
//你获得s%钻石的礼物收益!
DiamondIncome MsgUserRecordType = 9
//榜单结果
ActivityBillboardResult MsgUserRecordType = 10
//榜单钻石收益
ActivityBillboardDiamond MsgUserRecordType = 11
//榜单坐骑收益
ActivityBillboardProperty MsgUserRecordType = 12
//通过收礼物获得豆子
ActivityBeanProperty MsgUserRecordType = 13
//管理人送钻石
MgrSendDiamondProperty MsgUserRecordType = 14
//群组榜单钻石收益
ActivityGroupBillboardDiamond MsgUserRecordType = 15
//群组榜单坐骑收益
ActivityGroupBillboardProperty MsgUserRecordType = 16
//群组支持收益
GroupSupport MsgUserRecordType = 17
//群组支持提醒结果
GroupSupportResult MsgUserRecordType = 18
//管理人送座驾
MgrSendProperty MsgUserRecordType = 19
//送道具(座驾,头饰都属于道具)
AddProps MsgUserRecordType = 20
//MISS活动获胜
ActivityBillboardBeLikeResult = 21
//CP活动获胜
ActivityBillboardCpResult = 22
//加入势力主
GroupPowerUserJoin = 23
//离开势力主
GroupPowerUserLeave = 24
//贵族
AddNoble = 25
//日充值活动通知
ActivityTriggerDayPay = 26
//也门活动通知
ActivityTriggerYemen = 27
//月充值活动通知
ActivityTriggerMonthPay = 28
FruitTycoonAward = 29 // 水果大亨获奖
LuckyboxRecycle = 30 //幸运盒子回收
HlTemp1 = 31 //产品黄蕾,2022/06/29 临时要求发给某人的小助手消息
HLTemp2 = 32 //问卷调查
NewUserInviteAuditPassed = 33 // 新用户奖励活动审核通过
NewUserInviteAuditFailed = 34 // 新用户奖励活动审核不通过
NewUserInviterAward = 35 // 新用户奖励活动邀请成功数达标
PowerSupportSalary = 36 // 势力扶持工资领取 提醒
CountryStarOrdinaryAward = 37 // 国家之星瓜分奖提醒
GroupActivityRewardMsg = 38 // 群组活动钻石奖励提醒
TemplateActAwardMsg = 39 // 通用模板活动奖励提醒
TemplateSmsCode = 40 // 通用模板活动奖励提醒
)
type MsgSysUserType = mysql.Type
const (
//系统消息
SysType MsgSysUserType = 1
//小助手消息
AssistantType MsgSysUserType = 2
)
//resMsgTransalte 中 msg_type 同 type, msg_type是属于一级类型 type属于二级类型。 msg_type 对应MsgReceiveType type:部分对应MsgUserRecordType MsgUserRecordType(应该是小助手的类型)
type MsgSysRecordType = mysql.Type
const (
//这个值木有意义,
SysMsgSysRecordType1 MsgSysRecordType = 1
SysMsgSysRecordType2 MsgSysRecordType = 2
)
package msg_e
// 公屏消息
type TypePublicScreenMsg uint8
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 // 用户进入房间
)
package property_e
import "git.hilo.cn/hilo-common/resource/mysql"
type UserPropertyUsing = mysql.Type
const (
YesUsing UserPropertyUsing = 1
NoUsing UserPropertyUsing = 0
)
type UserPropertyLogOrginType = mysql.Type
const (
//活动奖励
ActivityBillboardReward UserPropertyLogOrginType = 1
//
Operational UserPropertyLogOrginType = 2
//群组活动
ActivityGroupBillboardReward UserPropertyLogOrginType = 3
//赠送
Send UserPropertyLogOrginType = 4
//火箭游戏
Rocket UserPropertyLogOrginType = 5
//活动阀值触发奖励
ActivityBillboardTrigger UserPropertyLogOrginType = 6
//首次充值奖励
ActivityRechargeFirst UserPropertyLogOrginType = 7
Give UserPropertyLogOrginType = 8
GeneralActivity UserPropertyLogOrginType = 9 // 一般性活动
)
type UserPropertyLogType mysql.Type
const (
AddSecond UserPropertyLogType = 1
UpdateEndTime UserPropertyLogType = 2
Del UserPropertyLogType = 3
)
type PropertyType = uint16
const (
TypeNoble PropertyType = 1
TypeMedal PropertyType = 2
TypeHeaddress PropertyType = 3
TypeRide PropertyType = 4
)
package res_e package res_e
import "hilo-user/resource/mysql" import "git.hilo.cn/hilo-common/resource/mysql"
type MsgIdType = uint type MsgIdType = uint
const ( const (
DEFAULT_LANG = "en" DEFAULT_LANG = "en"
MSG_ID_GAME_CREATE MsgIdType = 1001
MSG_ID_GAME_JOIN MsgIdType = 1002
) )
type ResMedalType = mysql.Type type ResMedalType = mysql.Type
...@@ -55,3 +52,9 @@ const ( ...@@ -55,3 +52,9 @@ const (
type ResNameplateType = mysql.Type type ResNameplateType = mysql.Type
type ResNameplateObtainType = mysql.Type type ResNameplateObtainType = mysql.Type
type ResNameplateScope = mysql.Type type ResNameplateScope = mysql.Type
type ResUserBag = mysql.Type
const (
ResUserBagGift ResUserBag = 1 // 背包道具-礼物
)
package user_e package user_e
import "hilo-user/resource/mysql" import "git.hilo.cn/hilo-common/resource/mysql"
type ThirdPartyType = mysql.Type type ThirdPartyType = mysql.Type
......
package _const
const (
TRACEID = "traceId"
USERID = "userId"
EXTERNAL_ID = "externalId"
CODE = "code"
NICK = "nick"
AVATAR = "avatar"
COUNTRY = "country"
EXTERNALID1 = "externalId1"
EXTERNALID2 = "externalId2"
MGRID = "mgrId"
DEVICETYPE = "deviceType"
DEVICEVERSION = "deviceVersion"
APP_VERSION = "appVersion"
ACTION_RESULt = "actionResult"
URL = "url"
METHOD = "method"
IMEI = "imei"
LANGUAGE = "language"
)
package user_k
import (
"fmt"
)
const (
GameAdd = "user:add:%s"
GameLock = "user:lock:%s"
)
func GetGameAddKey(txGroupId string) string {
return fmt.Sprintf(GameAdd, txGroupId)
}
package robot_k
import "fmt"
const (
RobotGroupCd = "robot:group:cd:%s"
)
// 机器人上群cd
func GetRobotGroupCdKey(txGroupId string) string {
return fmt.Sprintf(RobotGroupCd, txGroupId)
}
...@@ -2,8 +2,8 @@ package user_k ...@@ -2,8 +2,8 @@ package user_k
import ( import (
"fmt" "fmt"
"git.hilo.cn/hilo-common/resource/mysql"
"hilo-user/_const/redis_key" "hilo-user/_const/redis_key"
"hilo-user/resource/mysql"
) )
const ( const (
......
package _const
import (
"encoding/json"
"fmt"
"hilo-user/mylogrus"
"hilo-user/resource/config"
"net"
"runtime/debug"
"strings"
"time"
)
const DEFAULT_LANG = "en"
const DATETIME_FORMAT = "2006-01-02 15:04:05"
const DATE_FORMAT = "2006-01-02"
const DefaultAvatarMan = "hilo/manager/ea48b62d54a24a709de3c38702c89995.png"
func GetZeroTime(t time.Time) time.Time {
return time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, 0, t.Location())
}
// 取最近的一个星期n
func GetLastDayOfWeek(t time.Time, n time.Weekday) time.Time {
weekDay := t.Weekday()
// 校正日期
if weekDay < n {
weekDay = 7 - n + weekDay
} else {
weekDay = weekDay - n
}
return t.AddDate(0, 0, -(int(weekDay)))
}
// 补全url,区分处理oss和aws两种情况
func MakeFullUrl(url string) string {
if strings.HasPrefix(url, config.GetConfigOss().OSS_CDN) || strings.HasPrefix(url, config.GetConfigAws().AWS_CDN) {
return url
} else if strings.HasPrefix(url, "nextvideo/") {
return config.GetConfigOss().OSS_CDN + url
} else if strings.HasPrefix(url, config.GetConfigAws().AWS_DIR) {
return config.GetConfigAws().AWS_CDN + url
} else {
return url
}
}
// 去除slice中的重复元素
func UniqueSliceUInt64(sliceIn []uint64) []uint64 {
sliceOut := make([]uint64, 0, len(sliceIn))
m := make(map[uint64]struct{}, len(sliceIn))
for _, i := range sliceIn {
if _, ok := m[i]; !ok {
m[i] = struct{}{}
sliceOut = append(sliceOut, i)
}
}
return sliceOut
}
func ToString(s interface{}) (string, error) {
b, err := json.Marshal(s)
if err != nil {
return "", nil
}
return string(b), nil
}
func SliceToMapUInt64(s []uint64) map[uint64]struct{} {
m := make(map[uint64]struct{}, len(s))
for _, i := range s {
m[i] = struct{}{}
}
return m
}
func GetClientIp() (string, error) {
addrs, err := net.InterfaceAddrs()
if err != nil {
return "", err
}
for _, address := range addrs {
// 检查ip地址判断是否回环地址
if ipNet, ok := address.(*net.IPNet); ok && ipNet.IP.IsGlobalUnicast() {
//if ipNet, ok := address.(*net.IPNet); ok && !ipNet.IP.IsLoopback() {
if ipNet.IP.To4() != nil {
return ipNet.IP.String(), nil
}
}
}
return "", fmt.Errorf("can not find the client ip address")
}
func CheckGoPanic() {
if r := recover(); r != nil {
//打印错误堆栈信息
mylogrus.MyLog.Errorf("ACTION PANIC: %v, stack: %v", r, string(debug.Stack()))
}
}
package user_cv
import (
"git.hilo.cn/hilo-common/resource/mysql"
)
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"` // 有效天数
}
package user_cv
import "git.hilo.cn/hilo-common/resource/mysql"
type MGetUserLevelData map[mysql.ID]CvUserLevel
type CvUserLevel struct {
UserId mysql.ID `json:"userId"` // 用户id
WealthUserGrade uint32 `json:"wealthUserGrade"` //财富等级
CharmUserGrade uint32 `json:"charmUserGrade"` //魅力等级
}
...@@ -2,7 +2,7 @@ package cache ...@@ -2,7 +2,7 @@ package cache
import ( import (
"encoding/json" "encoding/json"
"hilo-user/domain" "git.hilo.cn/hilo-common/domain"
"math/rand" "math/rand"
"time" "time"
) )
......
package user_c package user_c
import ( import (
"git.hilo.cn/hilo-common/domain"
"git.hilo.cn/hilo-common/resource/mysql"
redisV8 "github.com/go-redis/redis/v8" redisV8 "github.com/go-redis/redis/v8"
"github.com/jinzhu/copier" "github.com/jinzhu/copier"
"hilo-user/_const/redis_key/user_k" "hilo-user/_const/redis_key/user_k"
"hilo-user/domain"
"hilo-user/domain/cache" "hilo-user/domain/cache"
"hilo-user/domain/model/user_m" "hilo-user/domain/model/user_m"
"hilo-user/myerr" "hilo-user/myerr"
"hilo-user/myerr/bizerr" "hilo-user/myerr/bizerr"
"hilo-user/resource/mysql"
) )
// 获取用户简要信息 // 获取用户简要信息
......
package domain
import (
"github.com/go-redis/redis/v8"
"gorm.io/gorm"
"hilo-user/mycontext"
)
type CtxAndDb struct {
Db *gorm.DB
*mycontext.MyContext
Redis *redis.Client
}
package domain
//异步执行的接口
type AsyncEvent interface {
AsyncDo(model *Model, eventData interface{}, n int) error
AsyncSize() int
AsyncNoTxDo(model *Model, eventData interface{}, n int) error
AsyncNoTxSize() int
}
package event package event
import "hilo-user/domain" import "git.hilo.cn/hilo-common/domain"
// 程序内部事件 // 程序内部事件
type Base struct { type Base struct {
......
package user_ev
import (
"hilo-user/_const"
"hilo-user/domain"
"hilo-user/domain/event"
"hilo-user/resource/mysql"
)
//注册监听
var userEditEvent = new(event.Base)
/**
注册事件
*/
type GameEditEvent struct {
GameId mysql.ID `json:"userId"` // 游戏id
TxGroupId mysql.Str `json:"txGroupId"` // 群组id
}
//添加领域事件,在每个领域模型中init中添加,因为这是静态业务,非动态的。
func AddGameEditEventSync(callback func(model *domain.Model, event interface{}) error) {
userEditEvent.SyncList = append(userEditEvent.SyncList, callback)
}
//加入到异步操作中
func AddGameEditEventAsync(callback func(model *domain.Model, event interface{}) error) {
userEditEvent.AsyncList = append(userEditEvent.AsyncList, callback)
}
//领域事件发布
func PublishGameEditEvent(model *domain.Model, event interface{}) error {
//执行同步的领域事件
for _, callback := range userEditEvent.SyncList {
if err := callback(model, event); err != nil {
return err
}
}
// 执行异步的领域事件
if len(userEditEvent.AsyncList) > 0 {
go func() {
defer _const.CheckGoPanic()
for _, callback := range userEditEvent.AsyncList {
// 异步事件需要用新model,主要是db
var newModel = domain.CreateModelContext(model.MyContext)
if err := callback(newModel, event); err != nil {
model.Log.Errorf("userEditEvent aysnc fail:%v", err)
}
}
}()
}
return nil
}
package user_ev
import (
"hilo-user/_const"
"hilo-user/_const/enum/user_e"
"hilo-user/domain"
"hilo-user/domain/event"
"hilo-user/resource/mysql"
)
//注册监听
var reportGameInfoEvent = new(event.Base)
/**
注册事件
*/
type ReportGameInfoEvent struct {
UserId mysql.ID `json:"uid"` // 用户id,请求get_user_info 接口返回uid参数
ReportType user_e.ReportType `json:"report_type"` // 上报类型 user_start|user_settle
GameStartObject *GameStartObject `json:"user_start_object"` // user_start对应结构体
GameSettleObject *GameSettleObject `json:"user_settle_object"` // user_settle对应结构体
}
type GameStartObject struct {
MgId uint64 `json:"mg_id"` // 游戏id
MgIdStr string `json:"mg_id_str"` // 小游戏id数值型兼容字段(nodejs服务请使用当前字段)
RoomId string `json:"room_id"` // 接入方房间id
GameMode int32 `json:"user_mode"` // 游戏模式,设定游戏的一些功能(参与游戏的人数,出手时间,特定的玩法)
GameRoundId string `json:"user_round_id"` // 本局游戏的id (重复上报,使用该字段去重)
BattleStartAt int32 `json:"battle_start_at"` // 战斗开始时间(秒)
Players []PlayerObject `json:"players"` // player_object 数组
ReportGameInfoExtras string `json:"report_user_info_extras"` // 游戏上报信息扩展参数(透传),取值范围:长度不超过1024字节,超过则截断
ReportGameInfoKey string `json:"report_user_info_key"` // 游戏上报信息扩展参数(透传),取值范围:长度不超过64字节,超过则截断。接入方服务端可以根据这个字段来查询一局游戏的数据
}
type PlayerObject struct {
Uid string `json:"uid"` // 接入方uid,机器人为空字符
IsAi int32 `json:"is_ai"` // 0:普通用户,1:机器人
}
type GameSettleObject struct {
MgId uint64 `json:"mg_id"` // 游戏id
MgIdStr string `json:"mg_id_str"` // 小游戏id数值型兼容字段(nodejs服务请使用当前字段)
RoomId string `json:"room_id"` // 接入方房间id
GameMode int32 `json:"user_mode"` // 游戏模式
GameRoundId string `json:"user_round_id"` // 本局游戏的id (重复上报,使用该字段去重)
BattleStartAt uint32 `json:"battle_start_at"` // 战斗开始时间(秒)
BattleEndAt uint32 `json:"battle_end_at"` // 战斗结束时间(秒)
BattleDuration int32 `json:"battle_duration"` // 战斗总时间(秒)
Results []PlayerResultObject `json:"results"` // player_result_object 数组
ReportGameInfoExtras string `json:"report_user_info_extras"` // 游戏上报信息扩展参数(透传),取值范围:长度不超过1024字节,超过则截断
ReportGameInfoKey string `json:"report_user_info_key"` // 游戏上报信息扩展参数(透传),取值范围:长度不超过64字节,超过则截断。接入方服务端可以根据这个字段来查询一局游戏的数据
}
type PlayerResultObject struct {
Uid string `json:"uid"` // 接入方uid,机器人为空字符
Rank int32 `json:"rank"` // 排名从1开始,平局排名相同
IsEscaped int32 `json:"is_escaped"` // 0:正常,1:逃跑
IsAi int32 `json:"is_ai"` // 0:普通用户,1:机器人
Role int32 `json:"role"` // 0:表示没有角色信息,玩家在游戏中的角色 游戏role 说明
Score int32 `json:"score"` // 玩家当前局得到的分数
IsWin int32 `json:"is_win"` // 结果 0:表示没有信息,1:输,2:赢,3:平局
Award int32 `json:"award"` // 奖励
Extras string `json:"extras"` // 扩展参数扩展说明
IsManaged int32 `json:"is_managed"` // 是否托管 0:未托管 1:托管
Diamond int64 `json:"diamond"` // 钻石收益,有可能负数,后期计算
LudoExtras *LudoExtras
}
type LudoExtras struct {
Color int `json:"color"`
Steps int `json:"steps"`
}
//添加领域事件,在每个领域模型中init中添加,因为这是静态业务,非动态的。
func AddReportGameInfoEventSync(callback func(model *domain.Model, event interface{}) error) {
reportGameInfoEvent.SyncList = append(reportGameInfoEvent.SyncList, callback)
}
//加入到异步操作中
func AddReportGameInfoEventAsync(callback func(model *domain.Model, event interface{}) error) {
reportGameInfoEvent.AsyncList = append(reportGameInfoEvent.AsyncList, callback)
}
//领域事件发布
func PublishReportGameInfoEvent(model *domain.Model, event interface{}) error {
//执行同步的领域事件
for _, callback := range reportGameInfoEvent.SyncList {
if err := callback(model, event); err != nil {
return err
}
}
// 执行异步的领域事件
if len(reportGameInfoEvent.AsyncList) > 0 {
go func() {
defer _const.CheckGoPanic()
for _, callback := range reportGameInfoEvent.AsyncList {
// 异步事件需要用新model,主要是db
var newModel = domain.CreateModelContext(model.MyContext)
if err := callback(newModel, event); err != nil {
model.Log.Errorf("ReportGameInfoEvent aysnc fail:%v", err)
}
}
}()
}
return nil
}
package group_ev
import (
"hilo-user/_const"
"hilo-user/domain"
"hilo-user/domain/event"
"hilo-user/myerr"
"hilo-user/resource/mysql"
)
var groupInListen = new(event.Base)
// 进房事件
type GroupInEvent struct {
GroupId string // imGroupId
UserId mysql.ID
ExternalId string
Nick string
Avatar string
IsMember bool //是否永久成员
IsVip bool
NobleLevel uint16
}
func AddGroupInEventSync(callback func(model *domain.Model, event interface{}) error) {
groupInListen.SyncList = append(groupInListen.SyncList, callback)
}
func AddGroupInEventAsync(callback func(model *domain.Model, event interface{}) error) {
groupInListen.AsyncList = append(groupInListen.AsyncList, callback)
}
func PublishGroupInEvent(model *domain.Model, event interface{}) error {
// 执行同步的领域事件
for _, callback := range groupInListen.SyncList {
if err := callback(model, event); err != nil {
return myerr.WrapErr(err)
}
}
// 执行异步的领域事件
if len(groupInListen.AsyncList) > 0 {
go func() {
defer _const.CheckGoPanic()
for _, callback := range groupInListen.AsyncList {
// 异步事件需要用新model,主要是db
var newModel = domain.CreateModelContext(model.MyContext)
if err := callback(newModel, event); err != nil {
model.Log.Errorf("GroupInEvent aysnc fail:%v", err)
}
}
}()
}
return nil
}
package group_ev
import (
"hilo-user/_const"
"hilo-user/domain"
"hilo-user/domain/event"
"hilo-user/myerr"
"hilo-user/resource/mysql"
)
var groupLeaveListen = new(event.Base)
// 离房事件
type GroupLeaveEvent struct {
GroupId string
UserId mysql.ID
ExternalId string
}
func AddGroupLeaveEventSync(callback func(model *domain.Model, event interface{}) error) {
groupLeaveListen.SyncList = append(groupLeaveListen.SyncList, callback)
}
func AddGroupLeaveEventAsync(callback func(model *domain.Model, event interface{}) error) {
groupLeaveListen.AsyncList = append(groupLeaveListen.AsyncList, callback)
}
func PublishGroupLeaveEvent(model *domain.Model, event interface{}) error {
// 执行同步的领域事件
for _, callback := range groupLeaveListen.SyncList {
if err := callback(model, event); err != nil {
return myerr.WrapErr(err)
}
}
// 执行异步的领域事件
if len(groupLeaveListen.AsyncList) > 0 {
go func() {
defer _const.CheckGoPanic()
for _, callback := range groupLeaveListen.AsyncList {
// 异步事件需要用新model,主要是db
var newModel = domain.CreateModelContext(model.MyContext)
if err := callback(newModel, event); err != nil {
model.Log.Errorf("GroupInEvent aysnc fail:%v", err)
}
}
}()
}
return nil
}
package domain
import (
"gorm.io/gorm"
"hilo-user/mycontext"
"hilo-user/resource/mysql"
"hilo-user/resource/redisCli"
)
type Model struct {
*CtxAndDb `gorm:"-"`
}
func CreateModel(ctxAndDb *CtxAndDb) *Model {
return &Model{CtxAndDb: ctxAndDb}
}
func CreateModelContext(myContext *mycontext.MyContext) *Model {
return &Model{
CtxAndDb: &CtxAndDb{
Db: mysql.Db,
MyContext: myContext,
Redis: redisCli.GetRedis(),
},
}
}
func CreateModelNil() *Model {
return &Model{
CtxAndDb: &CtxAndDb{
Db: mysql.Db,
MyContext: mycontext.CreateMyContext(nil),
Redis: redisCli.GetRedis(),
},
}
}
func (m *Model) DB() *gorm.DB {
return m.Db.WithContext(m)
}
// 包装事务
// 注意:需要使用新的model
func (m *Model) Transaction(f func(*Model) error) error {
// 公用context
// 新的db
txModel := CreateModelContext(m.MyContext)
txModel.Db = m.Db.Begin().WithContext(m)
err := f(txModel)
if err != nil {
txModel.Db.Rollback()
return err
}
return txModel.Db.Commit().Error
}
package bag_m
import (
"git.hilo.cn/hilo-common/domain"
"git.hilo.cn/hilo-common/resource/mysql"
"gorm.io/gorm/clause"
"hilo-user/_const/enum/res_e"
"time"
)
type UserBag struct {
mysql.Entity
UserId mysql.ID
ResType mysql.Type // 资源类型 1:礼物
ResId mysql.ID
Count mysql.Num
EndTime time.Time
}
type UserBagDetail struct {
mysql.Entity
UserId mysql.ID
BagId mysql.ID
ResType mysql.Type // 资源类型 1:礼物
ResId mysql.ID
Count mysql.Num
AddReduce mysql.AddReduce
BefNum mysql.Num
AftNum mysql.Num
Remark mysql.Str
}
// 获取用户有效的背包
// param userId 用户id
// param resType 背包类型 1:礼物
// condition
// 1.获取end_time未到期的
// 2.数量大于0的
func GetUserValidUserBag(model *domain.Model, userId mysql.ID, resType res_e.ResUserBag) ([]*UserBag, error) {
var res []*UserBag
if err := model.DB().Model(UserBag{}).
Where("end_time > ?", time.Now()).
Where("count > 0").
Where("res_type = ?", resType).
Where("user_id = ?", userId).
Order("id").Find(&res).Error; err != nil {
return nil, err
}
return res, nil
}
// 获取指定背包
func GetUserBag(model *domain.Model, bagId mysql.ID) (*UserBag, error) {
res := new(UserBag)
if err := model.DB().Model(UserBag{}).
Where("id = ?", bagId).First(res).Error; err != nil {
return nil, err
}
return res, nil
}
// 增加用户背包
// param userId 用户id
// param resType 道具类型
// param resId 道具id
// param count 增加数量
// param day 增加天数
// condition:
// 0.事务操作
// 1.背包表
// 2.明细表
// return bagId
func AddUserBag(model *domain.Model, userId mysql.ID, resType mysql.Type, resId mysql.ID, count mysql.Num, day int, reason string) (mysql.ID, error) {
var bagId mysql.ID
err := model.Transaction(func(model *domain.Model) error {
// 1.背包表
endTime := time.Now().AddDate(0, 0, day)
userBag := &UserBag{
UserId: userId,
ResType: resType,
ResId: resId,
Count: count,
EndTime: endTime,
}
if err := model.DB().Clauses(clause.OnConflict{
Columns: []clause.Column{{Name: "user_id"}, {Name: "res_type"}, {Name: "res_id"}, {Name: "end_time"}},
DoUpdates: clause.AssignmentColumns([]string{"count"}),
}).Create(userBag).Error; err != nil {
return err
}
bagId = userBag.ID // 自增id
// 2.明细表
userBagDetail := &UserBagDetail{
UserId: userId,
BagId: userBag.ID,
ResType: resType,
ResId: resId,
Count: count,
AddReduce: mysql.ADD,
BefNum: 0, // 加背包的统一为0
AftNum: count, // 加背包统一为count,因为每次加几乎不可能是一样的
Remark: reason,
}
if err := model.DB().Create(userBagDetail).Error; err != nil {
return err
}
return nil
})
return bagId, err
}
...@@ -3,11 +3,11 @@ package common ...@@ -3,11 +3,11 @@ package common
import ( import (
"context" "context"
"encoding/json" "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/_const/redis_key"
"hilo-user/myerr" "hilo-user/myerr"
"hilo-user/mylogrus"
"hilo-user/resource/mysql"
"hilo-user/resource/redisCli"
"time" "time"
) )
......
package diamond_m
import (
"hilo-user/_const/enum/diamond_e"
"hilo-user/domain"
"hilo-user/myerr"
"hilo-user/myerr/bizerr"
"hilo-user/resource/mysql"
"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:"-"`
}
//账号操作配置
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: diamond_e.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.Model(&DiamondAccountDetail{}).Where(&DiamondAccountDetail{
UserId: diamondAccount.UserId,
OperateType: operateType,
}).Count(&count)
if count >= int64(diamondOperateSet.FrequencyNum) {
return nil, bizerr.DiamondFrequency
}
}
} 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.Model(&DiamondAccountDetail{}).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 diamond_account_detail 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(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(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
}
package diamond_m
import (
"hilo-user/_const/enum/diamond_e"
"hilo-user/domain"
"hilo-user/myerr/bizerr"
"hilo-user/resource/mysql"
)
func CheckEnoughDiamondFrozen(model *domain.Model, userId mysql.ID, diamondNum mysql.Num) (*DiamondAccount, error) {
diamondAccount, err := GetDiamondAccountByUserId(model, userId)
if err != nil {
return nil, err
}
if diamondAccount.DiamondNum < diamondNum {
return nil, bizerr.DiamondNoEnough
}
if diamondAccount.Status == diamond_e.Frozen {
return nil, bizerr.DiamondAccountFrozen
}
return diamondAccount, nil
}
package diamond_m
import (
"gorm.io/gorm"
"hilo-user/domain/model"
"hilo-user/myerr"
"hilo-user/mylogrus"
"hilo-user/resource/mysql"
"strconv"
)
func (diamondAccountDetail *DiamondAccountDetail) Persistent() error {
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 {
mylogrus.MyLog.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)
}
//改变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 diamond_m
import "time"
func getZeroTime(t time.Time) time.Time {
return time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, 0, t.Location())
}
package event_m
import (
"gorm.io/gorm"
"hilo-user/domain"
"hilo-user/resource/mysql"
"time"
)
// 进房事件消息
type EventGroupIn struct {
mysql.Entity
*domain.Model `gorm:"-"`
Proto mysql.Type
Payload []byte
Mark mysql.YesNo
}
// 偏移值
type EventGroupInOffset struct {
mysql.Entity
*domain.Model `gorm:"-"`
MarkOffset mysql.ID
}
// 获取当前偏移值
func Offset(model *domain.Model) (*EventGroupInOffset, error) {
offset := new(EventGroupInOffset)
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 FetchEventGroupIn(model *domain.Model, limit int) ([]*EventGroupIn, *EventGroupInOffset, error) {
offset, err := Offset(model)
if err != nil {
return nil, nil, err
}
var events []*EventGroupIn
if err := model.Db.WithContext(model).Model(EventGroupIn{}).
Where("id > ?", offset.MarkOffset).
Order("id asc").Limit(limit).Find(&events).Error; err != nil {
model.Log.Errorf("FetchEventGroupIn fail:%v", err)
return nil, nil, err
}
return events, offset, nil
}
// 标记已完成
func (p *EventGroupIn) MarkDone() error {
p.Mark = mysql.YES
return p.Db.WithContext(p.Model).Model(EventGroupIn{}).Where("id = ?", p.ID).Update("mark", p.Mark).Limit(1).Error
}
// 查询过去1小时-5分钟前未mark的事件
// 用来补偿
// 记得加limit
func FetchUnMarkEvents(model *domain.Model, limit int) ([]*EventGroupIn, 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 []*EventGroupIn
if err := model.Db.WithContext(model).Model(EventGroupIn{}).
Where("mark = ?", 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 *EventGroupIn) error {
return model.Db.WithContext(model).Create(event).Error
}
package event_m
import (
"gorm.io/gorm"
"hilo-user/domain"
"hilo-user/resource/mysql"
"time"
)
// 离房事件消息
type EventGroupLeave struct {
mysql.Entity
*domain.Model `gorm:"-"`
Proto mysql.Type
Payload []byte
Mark mysql.YesNo
}
// 偏移值
type EventGroupLeaveOffset struct {
mysql.Entity
*domain.Model `gorm:"-"`
MarkOffset mysql.ID
}
// 获取当前偏移值
func GroupLeaveOffset(model *domain.Model) (*EventGroupLeaveOffset, error) {
offset := new(EventGroupLeaveOffset)
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 FetchEventGroupLeave(model *domain.Model, limit int) ([]*EventGroupLeave, *EventGroupLeaveOffset, error) {
offset, err := GroupLeaveOffset(model)
if err != nil {
return nil, nil, err
}
var events []*EventGroupLeave
if err := model.Db.WithContext(model).Model(EventGroupLeave{}).
Where("id > ?", offset.MarkOffset).
Order("id asc").Limit(limit).Find(&events).Error; err != nil {
model.Log.Errorf("FetchEventGroupLeave fail:%v", err)
return nil, nil, err
}
return events, offset, nil
}
// 标记已完成
func (p *EventGroupLeave) MarkDone() error {
p.Mark = mysql.YES
return p.Db.WithContext(p.Model).Model(EventGroupLeave{}).Where("id = ?", p.ID).Update("mark", p.Mark).Limit(1).Error
}
// 查询过去1小时-5分钟前未mark的事件
// 用来补偿
// 记得加limit
func FetchGroupLeaveUnMarkEvents(model *domain.Model, limit int) ([]*EventGroupLeave, error) {
offset, err := GroupLeaveOffset(model)
if err != nil {
return nil, err
}
t := time.Now().Add(-time.Minute * 5)
lt := t.Add(-time.Hour)
var events []*EventGroupLeave
if err := model.Db.WithContext(model).Model(EventGroupLeave{}).
Where("mark = ?", 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 AddGroupLeaveUnMarkEvent(model *domain.Model, event *EventGroupLeave) error {
return model.Db.WithContext(model).Create(event).Error
}
package event_m
import "hilo-user/domain/model"
func (p *EventGroupInOffset) Persistence() error {
return model.Persistent(p.Db, p)
}
func (p *EventGroupLeaveOffset) Persistence() error {
return model.Persistent(p.Db, p)
}
This diff is collapsed.
package user_m
import (
"hilo-user/_const/enum/user_e"
"hilo-user/domain"
"hilo-user/resource/mysql"
"sort"
"time"
)
type StartGamePlayer struct {
TxGroupId mysql.Str // 房间id
GameId mysql.ID // 游戏id
MgId mysql.Str // 游戏sdk id
UserId mysql.ID // 用户id
CreatedTime time.Time // 加入游戏时间
}
// 获取可以开始的游戏
// condition
// 1. 游戏还没开始
// 2. 游戏人数大于等于2个
// 3. 第二个加入的人距离现在已经超过15秒
func GetCanStartGames(model *domain.Model) []GameInfo {
// 1. 游戏还没开始
sql := "SELECT g.tx_group_id,p.user_id,g.mg_id,p.user_id,p.created_time FROM `user_info` g,`user_player` p where p.user_id = g.id AND g.`status` = ?;"
var startGamePlayers []StartGamePlayer
if err := model.DB().Raw(sql, user_e.GameStatusNoStart).Find(&startGamePlayers).Error; err != nil {
model.Log.Errorf("GetCanStartGames fail,sql:%v,err:%v", sql, err)
return nil
}
// userId -> userPlayer
var startGamePlayersMap = make(map[mysql.ID][]StartGamePlayer)
for i, p := range startGamePlayers {
startGamePlayersMap[p.GameId] = append(startGamePlayersMap[p.GameId], startGamePlayers[i])
}
var res []GameInfo
for userId, players := range startGamePlayersMap {
// 2. 游戏人数大于等于2个
if len(players) < 2 {
continue
}
model.Log.Infof("startGamePlayer,userId:%v,player:%+v", userId, players)
// 3. 第二个加入的人距离现在已经超过15秒
sort.Slice(players, func(i, j int) bool {
return players[i].CreatedTime.Before(players[j].CreatedTime)
})
// 客户端15秒,服务端延迟1秒
if time.Now().Sub(players[1].CreatedTime).Seconds() >= 16 {
res = append(res, GameInfo{
Id: userId,
MgId: players[1].MgId,
TxGroupId: players[1].TxGroupId,
})
}
}
return res
}
This diff is collapsed.
package user_m
import (
"hilo-user/_const/enum/robot_e"
"hilo-user/_const/enum/user_e"
"hilo-user/domain"
"hilo-user/domain/cache/robot_c"
"hilo-user/resource/mysql"
"math/rand"
"time"
)
// 游戏结构体
type GameTiny struct {
GameUid mysql.ID
GameType user_e.GameType
GroupId string
MgId int64
Diamond int64
NeedRobots int // 需要机器人数量
Status user_e.GameStatus // 游戏进行状态,1:进行中、0:结束, 心跳实时刷新
UpdatedTime time.Time
}
// 获取需要机器人的游戏
func GetNeedRobotGames(model *domain.Model) ([]GameTiny, error) {
var resGames []GameTiny
// 获取准备开始的游戏
var users []GameTiny
sql := "SELECT user.id as user_uid,user.user_type,user.tx_group_id as group_id,mg_id,user.diamond,user.`status`,user.updated_time FROM user_info user,group_info g " +
"WHERE user.tx_group_id = g.tx_group_id AND user. STATUS = 0 AND user.auto_match = 1 AND user.battle_start_at = 0 AND g.`password` = '' AND g.tourist_mic = 1"
if err := model.DB().Raw(sql).Find(&users).Error; err != nil {
return nil, err
}
now := time.Now()
for _, user := range users {
// 使用user.UpdatedTime(非CreatedTime)去判断8秒,兼容编辑游戏的情况
if now.Sub(user.UpdatedTime).Seconds() <= 8 {
continue
}
// user players
var players []GamePlayer
if err := model.DB().Model(GamePlayer{}).
Where("user_id = ?", user.GameUid).Find(&players).Error; err == nil {
// 没有玩家,属于异常的user
if len(players) <= 0 {
model.Log.Errorf("GetNeedRobotGames no player exits,user:%v,players:%v", user, players)
continue
}
// 玩家大于2个就不需要机器人
if len(players) > 1 {
continue
}
// 机器人进群cd中
if robot_c.IsGroupInCd(model, user.GroupId) {
model.Log.Warnf("IsGroupInCd in cd,user:%v", user)
continue
}
var needRobots = 1 // 一个机器人
resGames = append(resGames, GameTiny{
GameUid: user.GameUid,
GroupId: user.GroupId,
MgId: user.MgId,
NeedRobots: needRobots,
Status: user.Status,
GameType: user.GameType,
Diamond: user.Diamond,
})
} else if err != nil {
model.Log.Errorf("GamePlayer fail:%v", err.Error())
}
}
return resGames, nil
}
// 获取正在使用中的机器人
func GetUsingRobots(model *domain.Model) ([]*GameRobot, error) {
var robots []*GameRobot
if err := model.DB().Model(GameRobot{}).Where("state = ?", robot_e.RobotStateUsing).Find(&robots).Error; err != nil {
return nil, err
}
return robots, nil
}
// 获取房间中的机器人
func GetRoomRobots(model *domain.Model, txGroupId mysql.Str) ([]*GameRobot, error) {
var robots []*GameRobot
if err := model.DB().Model(GameRobot{}).Where("group_id = ?", txGroupId).Find(&robots).Error; err != nil {
return nil, err
}
return robots, nil
}
// 获取异常的robot
// state = 0,但是状态没清空
func GetAbnormalRobots(model *domain.Model) ([]*GameRobot, error) {
var robots []*GameRobot
if err := model.DB().Model(GameRobot{}).Where("state = ? AND op_step != 0", robot_e.RobotStateIdle).Find(&robots).Error; err != nil {
return nil, err
}
return robots, nil
}
// 获取闲置中的机器人
// 并且设置为使用中
func GetSetIdleGameRobots(model *domain.Model, num int) ([]*GameRobot, error) {
if num <= 0 {
model.Log.Warnf("GetSetIdleGameRobots no need robot:%v", num)
return nil, nil
}
var robots []*GameRobot
var canUseRobots []*GameRobot
err := model.Transaction(func(txModel *domain.Model) error {
if err := txModel.Db.WithContext(txModel).Model(GameRobot{}).Where("state = ?", robot_e.RobotStateIdle).Limit(1000).Find(&robots).Error; err != nil {
return err
}
// 打乱1000个空闲的机器人
rand.Shuffle(len(robots), func(i, j int) {
robots[i], robots[j] = robots[j], robots[i]
})
for i, robot := range robots {
// 增加cd逻辑,60秒机器人不复用
if time.Now().Sub(robot.LastUseTime).Seconds() < 60 {
model.Log.Warnf("robot cannot frequency use:%v", robot)
continue
}
if err := robot.MarkUsing(txModel); err != nil {
return err
}
canUseRobots = append(canUseRobots, robots[i])
num--
if num <= 0 {
break
}
}
return nil
})
if err != nil {
model.Log.Errorf("GetIdleGameRobots fail:%v", err)
return nil, err
}
return canUseRobots, nil
}
// 游戏ai启动
func AddAi(model *domain.Model, robots []*GameRobot) {
for _, robot := range robots {
robot.Run() // 一个机器人一个协程
}
}
package groupPower_m
import (
"gorm.io/gorm"
"hilo-user/_const/enum/groupPower_e"
"hilo-user/domain"
"hilo-user/domain/model/group_m"
"hilo-user/myerr"
"hilo-user/resource/mysql"
)
type GroupPower struct {
mysql.Entity
*domain.Model `gorm:"-"`
GroupUid mysql.Str
Name mysql.Str
Status groupPower_e.GroupPowerStatus
}
type GroupPowerUser struct {
mysql.Entity
*domain.Model `gorm:"-"`
GroupPowerId mysql.ID
UserId mysql.ID
Role groupPower_e.GroupPowerUserRole
}
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
}
//获取用户所在的国家势力信息,不存在则为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
}
// 查询用户加入的国家势力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
}
package group_m
import (
"context"
"encoding/json"
redisV8 "github.com/go-redis/redis/v8"
"gorm.io/gorm"
"hilo-user/common"
"hilo-user/common/rediskey"
"hilo-user/domain"
"hilo-user/myerr"
"hilo-user/myerr/bizerr"
"hilo-user/resource/mysql"
"hilo-user/resource/redisCli"
)
type GroupRoles struct {
mysql.Entity
UserId uint64
ImGroupId string
Role common.GroupRoleType
}
func (this *GroupInfo) TableName() string {
return "group_info"
}
//发言,注意(发言是在麦位上)
type MicUser struct {
model *domain.Model
//群组uuid
GroupUuid string
//麦位
I int
//麦中的人
ExternalId string
//
UserId uint64
//静音 true:静音,false:没有静音
Forbid bool
//上麦的的时间戳
Timestamp int64
}
//记录麦位上有谁。用于
type UserInMic struct {
//群组uuid
GroupUuid string
//麦位
I int
//userId
UserId uint64
}
// 查询用户在IM群组中的角色
func GetRoleInGroup(model *domain.Model, userId uint64, imGroupId string) (uint16, error) {
r := GroupRoles{}
err := model.Db.Where(&GroupRoles{
UserId: userId,
ImGroupId: imGroupId}).First(&r).Error
if err != nil {
if err != gorm.ErrRecordNotFound {
return 0, err
} else {
return 0, nil
}
}
return r.Role, nil
}
func GetByTxGroupId(model *domain.Model, txGroupId string) (*GroupInfo, error) {
if len(txGroupId) <= 0 {
return nil, bizerr.GroupNotFound
}
res := new(GroupInfo)
err := model.Db.Where(&GroupInfo{TxGroupId: txGroupId}).First(&res).Error
if err != nil {
if err == gorm.ErrRecordNotFound {
return nil, myerr.WrapErr(bizerr.GroupNotFound)
} else {
return nil, myerr.WrapErr(err)
}
}
return res, nil
}
//获取用户在哪个麦位上。没有不在麦上,则是nil
func GetMicUserByExternalId(model *domain.Model, externalId string) (*MicUser, error) {
if str, err := redisCli.GetRedis().Get(context.Background(), rediskey.GetPrefixGroupUserInMic(externalId)).Result(); err != nil {
if err != redisV8.Nil {
return nil, myerr.WrapErr(err)
} else {
return nil, nil
}
} else {
if userInMic, err := strToUserInMic(str); err != nil {
return nil, err
} else {
return GetMicUser(model, userInMic.GroupUuid, userInMic.I)
}
}
}
//麦位上没人,返回nil
func GetMicUser(model *domain.Model, groupUuid string, i int) (*MicUser, error) {
if i < 1 || i > 30 {
return nil, myerr.NewSysErrorF("麦序不对,不在范围值内 i:%v", i)
}
str, err := redisCli.GetRedis().Get(context.Background(), rediskey.GetPrefixGroupMicUser(groupUuid, i)).Result()
if err != nil {
if err == redisV8.Nil {
return nil, nil
} else {
return nil, myerr.WrapErr(err)
}
}
var micUser MicUser
err = json.Unmarshal([]byte(str), &micUser)
if err != nil {
return nil, err
}
return &MicUser{
model: model,
GroupUuid: groupUuid,
I: i,
ExternalId: micUser.ExternalId,
UserId: micUser.UserId,
Forbid: micUser.Forbid,
Timestamp: micUser.Timestamp,
}, nil
}
func strToUserInMic(str string) (UserInMic, error) {
userInMic := UserInMic{}
if err := json.Unmarshal([]byte(str), &userInMic); err != nil {
return UserInMic{}, myerr.WrapErr(err)
}
return userInMic, nil
}
package group_m
import (
"gorm.io/gorm"
"hilo-user/_const/enum/group_e"
"hilo-user/domain"
"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 GetGroupInfoByOwner(model *domain.Model, userId uint64) (*GroupInfo, error) {
if userId <= 0 {
return nil, bizerr.GroupNotFound
}
r := GroupInfo{}
err := model.Db.Where(&GroupInfo{Owner: userId}).First(&r).Error
if err != nil {
if err == gorm.ErrRecordNotFound {
return nil, nil
} else {
return nil, err
}
}
return &r, nil
}
package group_m
import (
"hilo-user/domain"
"hilo-user/myerr/bizerr"
)
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
}
package group_m
import (
"encoding/json"
"hilo-user/_const/enum/group_e"
"hilo-user/domain"
"hilo-user/domain/model/noble_m"
"hilo-user/domain/model/user_m"
"hilo-user/rpc"
)
// 信令消息
type GroupSystemMsg struct {
MsgId group_e.TypeSignalMsg `json:"msgId"`
Source string `json:"source"`
Target string `json:"target"`
Content string `json:"content"`
}
type HiloUserInfo struct {
WealthGrade uint32 `json:"wealthGrade"`
CharmGrade uint32 `json:"charmGrade"`
IsVip bool `json:"isVip"`
IsPretty bool `json:"isPretty"`
Medals []uint32 `json:"medals"`
PowerName string `json:"powerName"` // 用户加入的国家势力的绑定群组的名称
NobleLevel uint16 `json:"nobleLevel"`
SvipLevel int `json:"svipLevel"`
}
var GetGroupPowerNameByUserId func(model *domain.Model, userId uint64) (uint64, string, error)
//不用返回错误
func GetHiloUserInfo(model *domain.Model, extId string) string {
user, err := user_m.GetUserByExtId(model, extId)
if err != nil {
model.Log.Errorf("extId:%v, err:%+v", extId, err)
return ""
}
wealthGrade, _, err := user_m.GetWealthGrade(model, user.ID)
if err != nil {
model.Log.Errorf("extId:%v, err:%v", extId, err)
return ""
}
charmGrade, _, err := user_m.GetCharmGrade(model, user.ID)
if err != nil {
model.Log.Errorf("extId:%v, err:%v", extId, err)
return ""
}
isVip, _, err := user_m.IsVip(user.ID)
if err != nil {
model.Log.Errorf("extId:%v, err:%v", extId, err)
return ""
}
//
isPretty := user.IsPrettyCode()
//
medals, err := user_m.GetUserMedalMerge(model.Log, model.Db, user.ID)
if err != nil {
model.Log.Errorf("extId:%v, err:%v", extId, err)
return ""
}
_, powerName, err := GetGroupPowerNameByUserId(model, user.ID)
if err != nil {
model.Log.Errorf("extId:%v, err:%v", extId, err)
return ""
}
nobleLevel, err := noble_m.GetNobleLevel(model.Db, user.ID)
if err != nil {
model.Log.Errorf("extId:%v, err:%v", extId, err)
return ""
}
svip, _ := rpc.GetUserSvip(model, user.ID)
hilo := HiloUserInfo{
WealthGrade: wealthGrade,
CharmGrade: charmGrade,
IsVip: isVip,
IsPretty: isPretty,
Medals: medals,
PowerName: powerName,
NobleLevel: nobleLevel,
SvipLevel: svip.SvipLevel,
}
buf, err := json.Marshal(hilo)
if err != nil {
model.Log.Errorf("hilo:%+v, err:%v", hilo, err)
}
return string(buf)
}
package msg_m
import (
"git.hilo.cn/hilo-common/domain"
"git.hilo.cn/hilo-common/resource/mysql"
"gorm.io/gorm"
"hilo-user/myerr"
)
func GetMsgSysRecordInit(model *domain.Model, t uint32, msgSysId uint64) *MsgSysRecord {
return &MsgSysRecord{
Model: model,
Type: t,
Status: mysql.EXIST,
MsgSysId: msgSysId,
}
}
func GetMsgSysRecord(model *domain.Model, msgSysId uint64) (*MsgSysRecord, error) {
msgSysRecord := MsgSysRecord{}
if err := model.Db.Model(&MsgSysRecord{}).Where(&MsgSysRecord{
MsgSysId: msgSysId,
}).First(&msgSysRecord).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, nil
} else {
return nil, myerr.WrapErr(err)
}
} else {
msgSysRecord.Model = model
return &msgSysRecord, nil
}
}
package msg_m
import (
"git.hilo.cn/hilo-common/domain"
"git.hilo.cn/hilo-common/resource/mysql"
"git.hilo.cn/hilo-common/sdk/emas"
"git.hilo.cn/hilo-common/utils"
"hilo-user/_const/enum/msg_e"
)
type MsgUserRecord struct {
mysql.Entity
*domain.Model `gorm:"-"`
UserId mysql.ID
Type msg_e.MsgUserRecordType
Nick mysql.Str
NickUserId mysql.ID //用户的别名
DiamondIncome mysql.Str
DayNum mysql.Str //多少天
PropertyUrl mysql.Str //道具地址
BeanNum mysql.Str //多少豆子
GroupCode mysql.Str //群组code
}
type MsgSysRecord struct {
mysql.Entity
*domain.Model `gorm:"-"`
//Type msg_m.MsgSysRecordType
Type uint32
Status mysql.LogicDel
MsgSysId mysql.ID
}
//系统消息,用户最后已读的位置
type MsgSysUser struct {
mysql.Entity
*domain.Model `gorm:"-"`
Type msg_e.MsgSysUserType
UserId mysql.ID
MsgSysLastId mysql.ID
}
//删除
func (msgSysRecord *MsgSysRecord) Del() *MsgSysRecord {
msgSysRecord.Status = mysql.DEL
return msgSysRecord
}
type MsgReceive struct {
Type msg_e.MsgReceiveType `json:"type"`
//Timestamp mysql.Timestamp `json:"timestamp"`
}
func NewUserRecord(model *domain.Model, userId mysql.ID, t msg_e.MsgUserRecordType, nick mysql.Str, nickUserId mysql.ID, diamondIncome mysql.Str, dayNum mysql.Str, propertyUrl mysql.Str, beanNum mysql.Str, groupCode mysql.Str) *MsgUserRecord {
return &MsgUserRecord{
Model: model,
UserId: userId,
Type: t,
Nick: nick,
NickUserId: nickUserId,
DiamondIncome: diamondIncome,
DayNum: dayNum,
PropertyUrl: propertyUrl,
BeanNum: beanNum,
GroupCode: groupCode,
}
}
// 发给小助手的消息, 不需要抛出错误
func SendEmasMsgAssistant(model *domain.Model, externalId string, deviceType string) error {
str, _ := utils.ToString(MsgReceive{
Type: msg_e.UserMsgReceiveType,
})
err := emas.SendMsg(externalId, deviceType, str)
if err != nil {
model.Log.Errorf("emas.SendMsg err:%v", err)
}
return nil
}
package msg_m
import (
"hilo-user/domain/model"
"hilo-user/myerr"
)
func (msgUserRecord *MsgUserRecord) Persistent() error {
if err := model.Persistent(msgUserRecord.Db, msgUserRecord); err != nil {
return myerr.WrapErr(err)
}
return nil
}
func (msgSysRecord *MsgSysRecord) Persistent() error {
if err := model.Persistent(msgSysRecord.Db, msgSysRecord); err != nil {
return myerr.WrapErr(err)
}
return nil
}
func (msgSysUser *MsgSysUser) Persistent() error {
return model.Persistent(msgSysUser.Db, msgSysUser)
}
\ No newline at end of file
package noble_m
import (
"gorm.io/gorm"
"time"
)
const RENEWAL_LIMIT_DAY = 7
type ResNoble struct {
Level uint16
PurchasePrice uint32
RenewalPrice uint32
Duration uint16
PicUrl string
DailyGold uint
RideId uint64 // 赠送的座驾ID
HeaddressId uint64 // 赠送的头饰ID
}
func GetAllConfig(db *gorm.DB) ([]ResNoble, error) {
rows := make([]ResNoble, 0)
err := db.Find(&rows).Error
if err != nil {
return nil, err
}
return rows, nil
}
func GetAllConfigMap(db *gorm.DB) (map[uint16]ResNoble, error) {
rows, err := GetAllConfig(db)
if err != nil {
return nil, err
}
result := make(map[uint16]ResNoble, 0)
for _, i := range rows {
result[i.Level] = i
}
return result, nil
}
func GetConfigByLevel(db *gorm.DB, level uint16) (ResNoble, error) {
r := ResNoble{}
if err := db.Model(&ResNoble{}).First(&r, level).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return r, nil
} else {
return r, err
}
}
return r, nil
}
// 根据过期时间推算价格
func CalcPrice(cfg ResNoble, endTime time.Time) uint32 {
now := time.Now()
price := cfg.RenewalPrice
if now.After(endTime.AddDate(0, 0, RENEWAL_LIMIT_DAY)) {
price = cfg.PurchasePrice
}
return price
}
package noble_m
import (
"git.hilo.cn/hilo-common/resource/mysql"
"gorm.io/gorm"
"time"
)
const (
SRC_APP = 1 // APP
SRC_OPERATION = 2 // 管理后台发放
SRC_H5 = 3 // H5页面
SRC_ACTIVITY = 4 // 活动奖励
RECHARGE_FIRST = 5 // 首次充值
)
type UserNobleLog struct {
mysql.Entity
SenderId uint64
ReceiverId uint64
Level uint16
Money uint32
SrcType uint16
OldEndTime time.Time
NewEndTime time.Time
}
func (ubl *UserNobleLog) Create(db *gorm.DB) error {
return db.Create(ubl).Error
}
package noble_m package noble_m
import ( import (
"git.hilo.cn/hilo-common/resource/mysql"
"gorm.io/gorm" "gorm.io/gorm"
"hilo-user/resource/mysql"
"time" "time"
) )
...@@ -52,22 +52,6 @@ func (ub *UserNoble) Delete(db *gorm.DB) error { ...@@ -52,22 +52,6 @@ func (ub *UserNoble) Delete(db *gorm.DB) error {
return db.Where(ub).Delete(&UserNoble{}).Error return db.Where(ub).Delete(&UserNoble{}).Error
} }
// 查询用户未过期的贵族
func (ub *UserNoble) batchGet(db *gorm.DB, userIds []uint64) (map[uint64][]UserNoble, error) {
rows := make([]UserNoble, 0)
if err := db.Model(ub).Where("end_time>=NOW() AND user_id IN ?", userIds).Order("level DESC").Find(&rows).Error; err != nil {
return nil, err
}
result := make(map[uint64][]UserNoble, 0)
for _, i := range rows {
if _, ok := result[i.UserId]; !ok {
result[i.UserId] = make([]UserNoble, 0)
}
result[i.UserId] = append(result[i.UserId], i)
}
return result, nil
}
func FindActiveNoble(db *gorm.DB, userId uint64) (*UserNoble, error) { func FindActiveNoble(db *gorm.DB, userId uint64) (*UserNoble, error) {
ub := UserNoble{ ub := UserNoble{
UserId: userId, UserId: userId,
...@@ -93,3 +77,50 @@ func GetNobleLevel(db *gorm.DB, userId uint64) (uint16, error) { ...@@ -93,3 +77,50 @@ func GetNobleLevel(db *gorm.DB, userId uint64) (uint16, error) {
return noble.Level, nil return noble.Level, nil
} }
} }
func BatchGetNobleLevel(db *gorm.DB, userIds []uint64) (map[uint64]uint16, error) {
m, err := BatchGetActiveNoble(db, userIds)
if err != nil {
return nil, err
}
result := make(map[uint64]uint16, 0)
for _, i := range userIds {
result[i] = m[i].Level
}
return result, nil
}
func BatchGetActiveNoble(db *gorm.DB, userIds []uint64) (map[uint64]UserNoble, error) {
ub := UserNoble{}
records, err := ub.batchGet(db, userIds)
if err != nil {
return nil, err
}
result := make(map[uint64]UserNoble, 0)
for _, i := range userIds {
if len(records[i]) > 0 {
result[i] = records[i][0]
} else {
result[i] = UserNoble{}
}
}
return result, nil
}
// 查询用户未过期的贵族
func (ub *UserNoble) batchGet(db *gorm.DB, userIds []uint64) (map[uint64][]UserNoble, error) {
rows := make([]UserNoble, 0)
if err := db.Model(ub).Where("end_time>=NOW() AND user_id IN ?", userIds).Order("level DESC").Find(&rows).Error; err != nil {
return nil, err
}
result := make(map[uint64][]UserNoble, 0)
for _, i := range rows {
if _, ok := result[i.UserId]; !ok {
result[i.UserId] = make([]UserNoble, 0)
}
result[i.UserId] = append(result[i.UserId], i)
}
return result, nil
}
...@@ -2,10 +2,10 @@ package model ...@@ -2,10 +2,10 @@ package model
import ( import (
"fmt" "fmt"
"git.hilo.cn/hilo-common/resource/mysql"
"gorm.io/gorm" "gorm.io/gorm"
"gorm.io/gorm/clause" "gorm.io/gorm/clause"
"hilo-user/myerr" "hilo-user/myerr"
"hilo-user/resource/mysql"
"time" "time"
) )
......
package res_m package res_m
import ( import (
"git.hilo.cn/hilo-common/domain"
"git.hilo.cn/hilo-common/resource/mysql"
"gorm.io/gorm" "gorm.io/gorm"
"hilo-user/_const/enum/res_e" "hilo-user/_const/enum/res_e"
"hilo-user/domain"
"hilo-user/myerr" "hilo-user/myerr"
"hilo-user/resource/mysql"
) )
type ResCountry struct { type ResCountry struct {
......
package res_m
import (
"git.hilo.cn/hilo-common/domain"
"git.hilo.cn/hilo-common/resource/mysql"
)
type ResGift struct {
mysql.Entity
Name mysql.Str
IconUrl mysql.Str
SvagUrl mysql.Str
MusicUrl mysql.Str
Column uint16
DiamondNum mysql.Num
BeanNum mysql.Num
ReceiveDiamondNum mysql.Num
Second mysql.Num // obsolete
N mysql.Num
GroupBroadcast bool
Cp bool
Together bool
Status mysql.UserYesNo
GiftType mysql.Type
}
// 获取所有有效的礼物
func FindValidResGiftsMap(model *domain.Model) (map[mysql.ID]ResGift, error) {
res := make(map[mysql.ID]ResGift, 0)
rows := make([]ResGift, 0)
if err := model.DB().Model(ResGift{}).Where("status = ?", mysql.USER).Find(&rows).Error; err != nil {
return nil, err
}
for i, v := range rows {
res[v.ID] = rows[i]
}
return res, nil
}
// 获取礼物
func FindResGift(model *domain.Model, giftId mysql.ID) (*ResGift, error) {
res := new(ResGift)
if err := model.DB().Model(ResGift{}).Where("id = ?", giftId).First(res).Error; err != nil {
return nil, err
}
return res, nil
}
package res_m
import (
"git.hilo.cn/hilo-common/domain"
"git.hilo.cn/hilo-common/resource/mysql"
"gorm.io/gorm"
"hilo-user/myerr"
)
type ResHeadwear struct {
mysql.Entity
*domain.Model `gorm:"-"`
Name mysql.Str
PicUrl mysql.Str
EffectUrl mysql.Str
}
//矛盾,项目负责人(产品不接受 商品 同上架分开两个数据结构的模式),又在页面上要求头饰同价格在一起展示,修改。
//目前违背了,ResHeadwearDiamond 作为资源数据,不允许修改的特点。后果在于,对账错误。
type ResHeadwearDiamond struct {
mysql.Entity
*domain.Model `gorm:"-"`
ResHeadwearId mysql.ID
DiamondNum mysql.Num
Second mysql.Num
Status mysql.UserYesNo
}
func InitResHeadwearDiamond(model *domain.Model, resHeadwearId mysql.ID, diamondNum mysql.Num, second mysql.Num) *ResHeadwearDiamond {
return &ResHeadwearDiamond{
Model: model,
ResHeadwearId: resHeadwearId,
DiamondNum: diamondNum,
Second: second,
Status: mysql.NOUSER,
}
}
func GetResHeadwearDiamondByHeadwearIdOrNil(model *domain.Model, resHeadwearId mysql.ID) (*ResHeadwearDiamond, error) {
resHeadwearDiamond := ResHeadwearDiamond{}
if err := model.Db.Model(&ResHeadwearDiamond{}).Where(&ResHeadwearDiamond{
ResHeadwearId: resHeadwearId,
}).First(&resHeadwearDiamond).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, nil
} else {
return nil, myerr.WrapErr(err)
}
}
resHeadwearDiamond.Model = model
return &resHeadwearDiamond, nil
}
func (resHeadwearDiamond *ResHeadwearDiamond) SetDiamondNum(diamondNum uint32) *ResHeadwearDiamond {
resHeadwearDiamond.DiamondNum = diamondNum
return resHeadwearDiamond
}
func (resHeadwearDiamond *ResHeadwearDiamond) SetSecond(second uint32) *ResHeadwearDiamond {
resHeadwearDiamond.Second = second
return resHeadwearDiamond
}
//设置成未使用
func (resHeadwearDiamond *ResHeadwearDiamond) SetUser() *ResHeadwearDiamond {
resHeadwearDiamond.Status = mysql.USER
return resHeadwearDiamond
}
//设置成未使用
func (resHeadwearDiamond *ResHeadwearDiamond) SetNoUser() *ResHeadwearDiamond {
resHeadwearDiamond.Status = mysql.NOUSER
return resHeadwearDiamond
}
//id获取头饰,不存在则抛异常
func GetHeadwearById(model *domain.Model, id mysql.ID) (*ResHeadwear, error) {
resHeadwear := ResHeadwear{}
if err := model.Db.Model(&ResHeadwear{}).First(&resHeadwear, id).Error; err != nil {
return nil, myerr.WrapErr(err)
} else {
resHeadwear.Model = model
return &resHeadwear, nil
}
}
//初始化头饰,
func InitHeadwear(model *domain.Model, name string, picUrl string, effectUrl string) *ResHeadwear {
return &ResHeadwear{
Model: model,
Name: name,
PicUrl: picUrl,
EffectUrl: effectUrl,
}
}
//修改头饰
func (resHeadwear *ResHeadwear) EditName(name string) *ResHeadwear {
resHeadwear.Name = name
return resHeadwear
}
func (resHeadwear *ResHeadwear) EditPicUrl(picUrl string) *ResHeadwear {
resHeadwear.PicUrl = picUrl
return resHeadwear
}
func (resHeadwear *ResHeadwear) EditEffectUrl(effectUrl string) *ResHeadwear {
resHeadwear.EffectUrl = effectUrl
return resHeadwear
}
func CheckHeadwearValidById(model *domain.Model, id mysql.ID) (bool, error) {
resHeadwear := ResHeadwear{}
if err := model.Db.Model(&ResHeadwear{}).First(&resHeadwear, id).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return false, nil
} else {
return false, myerr.WrapErr(err)
}
} else {
return true, nil
}
}
package res_m package res_m
import ( import (
"git.hilo.cn/hilo-common/resource/mysql"
"gorm.io/gorm" "gorm.io/gorm"
"hilo-user/_const/enum/res_e" "hilo-user/_const/enum/res_e"
"hilo-user/resource/mysql"
) )
type ResMedal struct { type ResMedal struct {
......
package res_m package res_m
import ( import (
"git.hilo.cn/hilo-common/resource/mysql"
"hilo-user/_const/enum/res_e" "hilo-user/_const/enum/res_e"
"hilo-user/resource/mysql"
) )
type ResNameplate struct { type ResNameplate struct {
......
package res_m package res_m
import ( import (
"git.hilo.cn/hilo-common/resource/mysql"
"gorm.io/gorm" "gorm.io/gorm"
"hilo-user/_const/enum/res_e" "hilo-user/_const/enum/res_e"
"hilo-user/myerr" "hilo-user/myerr"
"hilo-user/resource/mysql"
) )
type ResMultiText struct { type ResMultiText struct {
......
package user_m
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/res_m"
"hilo-user/myerr"
"strconv"
"time"
)
//用户头饰
type UserHeadwear struct {
mysql.Entity
*domain.Model `gorm:"-"`
UserId mysql.ID
HeadwearId mysql.ID
EndTime time.Time
Using headwear_e.UserHeadwearUsing
}
//获取用户头饰,不存在则新建
func GetUserHeadwearOrInit(model *domain.Model, userId mysql.ID, headwearId mysql.ID) (*UserHeadwear, error) {
//检查headwearId是否存在/有效
if flag, err := res_m.CheckHeadwearValidById(model, headwearId); err != nil {
return nil, err
} else {
if flag == false {
return nil, myerr.NewSysError("headwearId: " + strconv.FormatUint(headwearId, 10) + " 无效")
}
}
userHeadwear := UserHeadwear{}
if err := model.Db.Model(&UserHeadwear{}).Where(&UserHeadwear{
UserId: userId,
HeadwearId: headwearId,
}).First(&userHeadwear).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return &UserHeadwear{
Model: model,
UserId: userId,
HeadwearId: headwearId,
EndTime: time.Now(),
}, nil
} else {
return nil, myerr.WrapErr(err)
}
}
userHeadwear.Model = model
return &userHeadwear, nil
}
//设置为使用中
func (userHeadwear *UserHeadwear) SetUsing() (*UserHeadwear, error) {
if err := resetAllUserHeadwearNoUsing(userHeadwear.Model, userHeadwear.UserId); err != nil {
return nil, err
}
userHeadwear.Using = headwear_e.YesUsing
return userHeadwear, nil
}
//增加结束时间
func (userHeadwear *UserHeadwear) AddEndTime(t headwear_e.UserHeadwearLogOrginType, second uint32, operateUserId mysql.ID) (*UserHeadwear, mysql.ID, error) {
logId, err := addUserHeadwearLog(userHeadwear.Model, userHeadwear.UserId, userHeadwear.HeadwearId, t, headwear_e.AddSecond, &second, nil, operateUserId)
if err != nil {
return nil, 0, myerr.WrapErr(err)
}
//if err := resetAllUserHeadwearNoUsing(userHeadwear.Model, userHeadwear.UserId); err != nil {
// return nil, logId, err
//}
nowTime := time.Now()
if userHeadwear.EndTime.After(nowTime) {
nowTime = userHeadwear.EndTime
}
userHeadwear.EndTime = nowTime.Add(time.Duration(second) * time.Second)
return userHeadwear, logId, nil
}
//删除
func (userHeadwear *UserHeadwear) MgrDel(mgrId mysql.ID) (*UserHeadwear, mysql.ID, error) {
logId, err := addUserHeadwearLog(userHeadwear.Model, userHeadwear.UserId, userHeadwear.HeadwearId, headwear_e.Mgr, headwear_e.Del, nil, nil, mgrId)
if err != nil {
return nil, 0, myerr.WrapErr(err)
}
userHeadwear.SetDel()
return userHeadwear, logId, nil
}
//重置所有的座驾均为不使用状态
func resetAllUserHeadwearNoUsing(model *domain.Model, userId mysql.ID) error {
if err := model.Db.Model(&UserHeadwear{}).Where(&UserHeadwear{
UserId: userId,
}).UpdateColumn("using", headwear_e.NoUsing).Error; err != nil {
return myerr.WrapErr(err)
}
return nil
}
//用户装饰日志
type UserHeadwearLog struct {
mysql.Entity
UserId mysql.ID
OperateUserId mysql.ID
HeadwearId mysql.ID
OriginType headwear_e.UserHeadwearLogOrginType
Type headwear_e.UserHeadwearLogType
AddSecond *mysql.Num
UpdateEndTime *time.Time
}
//增加修改日志
func addUserHeadwearLog(model *domain.Model, userId mysql.ID, headwearId mysql.ID, originType headwear_e.UserHeadwearLogOrginType, t headwear_e.UserHeadwearLogType, addSecond *uint32, UpdateEndTime *time.Time, operateUserId mysql.ID) (mysql.ID, error) {
userHeadwearLog := UserHeadwearLog{
UserId: userId,
OperateUserId: operateUserId,
HeadwearId: headwearId,
OriginType: originType,
Type: t,
AddSecond: addSecond,
UpdateEndTime: UpdateEndTime,
}
if err := model.Db.Create(&userHeadwearLog).Error; err != nil {
return 0, myerr.WrapErr(err)
}
return userHeadwearLog.ID, nil
}
func GetUserHeadwearUsing(model *domain.Model, userId mysql.ID) (*UserHeadwear, error) {
userHeadwear := UserHeadwear{}
if err := model.Db.Model(&UserHeadwear{}).Where(&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)
}
}
userHeadwear.Model = model
return &userHeadwear, nil
}
package user_m package user_m
import ( import (
"gorm.io/gorm" "git.hilo.cn/hilo-common/domain"
"hilo-user/_const/enum/match_e" "git.hilo.cn/hilo-common/resource/mysql"
"hilo-user/domain"
"hilo-user/myerr"
"hilo-user/resource/mysql"
) )
/** /**
...@@ -19,54 +16,15 @@ type MatchCharmUserScore struct { ...@@ -19,54 +16,15 @@ type MatchCharmUserScore struct {
Grade mysql.Num Grade mysql.Num
} }
//获取魅力等级 // 批量获取魅力等级
func GetCharmGrade(model *domain.Model, userId mysql.ID) (uint32, uint32, error) { func MGetCharmGrade(model *domain.Model, userIds []mysql.ID) (map[mysql.ID]mysql.Num, error) {
var charmUserScore MatchCharmUserScore res := make(map[mysql.ID]mysql.Num)
if err := model.Db.Model(&MatchCharmUserScore{}).Where(&MatchCharmUserScore{ var charmUserScore []*MatchCharmUserScore
UserId: userId, if err := model.Db.Model(&MatchCharmUserScore{}).Where("user_id in ?", userIds).Find(&charmUserScore).Error; err != nil {
}).First(&charmUserScore).Error; err != nil { return res, err
if err == gorm.ErrRecordNotFound {
return 0, 0, nil
} else {
return 0, 0, myerr.WrapErr(err)
} }
for _, r := range charmUserScore {
res[r.UserId] = r.Grade
} }
return charmUserScore.Grade, charmUserScore.Score, nil return res, nil
}
type MatchCharmUserScoreDetail struct {
mysql.Entity
MatchCharmUserScoreId mysql.ID
UserId mysql.ID
BeforeScore mysql.Num
Score mysql.Num
AfterScore mysql.Num
Type match_e.MatchCharmUserScoreDetailType
OrginId mysql.ID
}
func addMatchCharmUserScoreDetail(model *domain.Model, matchCharmUserScoreId mysql.ID, userId mysql.ID, beforeScore mysql.Num, score mysql.Num, t match_e.MatchCharmUserScoreDetailType, orginId mysql.ID) error {
if err := model.Db.Save(&MatchCharmUserScoreDetail{
MatchCharmUserScoreId: matchCharmUserScoreId,
UserId: userId,
BeforeScore: beforeScore,
Score: score,
AfterScore: beforeScore + score,
Type: t,
OrginId: orginId,
}).Error; err != nil {
return myerr.WrapErr(err)
}
return nil
}
/**
* 获取的分数同等级关系
**/
type MatchCharmSetScoreGrade struct {
mysql.Entity
*domain.Model `gorm:"-"`
MinNum mysql.Num
MaxNum mysql.Num
Grade mysql.Num
} }
package user_m package user_m
import ( import (
"gorm.io/gorm" "git.hilo.cn/hilo-common/domain"
"hilo-user/_const/enum/match_e" "git.hilo.cn/hilo-common/resource/mysql"
"hilo-user/domain"
"hilo-user/myerr"
"hilo-user/resource/mysql"
) )
/** /**
...@@ -19,52 +16,15 @@ type MatchWealthUserScore struct { ...@@ -19,52 +16,15 @@ type MatchWealthUserScore struct {
Grade mysql.Num Grade mysql.Num
} }
/** // 批量获取财富等级
* 获取的分数同等级关系 func MGetWealthGrade(model *domain.Model, userIds []mysql.ID) (map[mysql.ID]mysql.Num, error) {
**/ res := make(map[mysql.ID]mysql.Num)
type MatchWealthSetScoreGrade struct { var wealthUserScore []*MatchWealthUserScore
mysql.Entity if err := model.Db.Model(&MatchWealthUserScore{}).Where("user_id in ?", userIds).Find(&wealthUserScore).Error; err != nil {
*domain.Model `gorm:"-"` return res, err
MinNum mysql.Num
MaxNum mysql.Num
Grade mysql.Num
}
type MatchWealthUserScoreDetail struct {
mysql.Entity
MatchWealthUserScoreId mysql.ID
UserId mysql.ID
BeforeScore mysql.Num
Score mysql.Num
AfterScore mysql.Num
Type match_e.MatchWealthUserScoreDetailType
OrginId mysql.ID
}
func addMatchWealthUserScoreDetail(model *domain.Model, matchWealthUserScoreId mysql.ID, userId mysql.ID, beforeScore mysql.Num, score mysql.Num, t match_e.MatchWealthUserScoreDetailType, orginId mysql.ID) error {
if err := model.Db.Save(&MatchWealthUserScoreDetail{
MatchWealthUserScoreId: matchWealthUserScoreId,
UserId: userId,
BeforeScore: beforeScore,
Score: score,
AfterScore: beforeScore + score,
Type: t,
OrginId: orginId,
}).Error; err != nil {
return myerr.WrapErr(err)
}
return nil
}
//获取财富等级
func GetWealthGrade(model *domain.Model, userId mysql.ID) (uint32, uint32, error) {
var wealthUserScore MatchWealthUserScore
if err := model.Db.Model(&MatchWealthUserScore{}).Where(&MatchWealthUserScore{UserId: userId}).First(&wealthUserScore).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return 0, 0, nil
} else {
return 0, 0, myerr.WrapErr(err)
} }
for _, r := range wealthUserScore {
res[r.UserId] = r.Grade
} }
return wealthUserScore.Grade, wealthUserScore.Score, nil return res, nil
} }
package user_m package user_m
import ( import (
"git.hilo.cn/hilo-common/domain"
"git.hilo.cn/hilo-common/resource/mysql"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"gorm.io/gorm" "gorm.io/gorm"
"hilo-user/domain"
"hilo-user/domain/model/common" "hilo-user/domain/model/common"
"hilo-user/domain/model/res_m" "hilo-user/domain/model/res_m"
"hilo-user/resource/mysql"
"time" "time"
) )
......
package user_m package user_m
import ( import (
"hilo-user/domain" "git.hilo.cn/hilo-common/domain"
"hilo-user/resource/mysql" "git.hilo.cn/hilo-common/resource/mysql"
"time" "time"
) )
......
package user_m
import (
"git.hilo.cn/hilo-common/domain"
"git.hilo.cn/hilo-common/resource/mysql"
"gorm.io/gorm"
"hilo-user/_const/enum/property_e"
"hilo-user/myerr"
"time"
)
//用户道具
type UserProperty struct {
mysql.Entity
*domain.Model `gorm:"-"`
UserId mysql.ID
PropertyId mysql.ID
EndTime time.Time
Using property_e.UserPropertyUsing
}
func GetUserPropertyOrInit(model *domain.Model, userId mysql.ID, propertyId mysql.ID) (*UserProperty, error) {
userProperty := UserProperty{}
if err := model.Db.Model(&UserProperty{}).Where(&UserProperty{
UserId: userId,
PropertyId: propertyId,
}).First(&userProperty).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return &UserProperty{
Model: model,
UserId: userId,
PropertyId: propertyId,
EndTime: time.Now(),
}, nil
} else {
return nil, myerr.WrapErr(err)
}
}
userProperty.Model = model
return &userProperty, nil
}
//设置为使用中
func (userProperty *UserProperty) SetUsing() (*UserProperty, error) {
if err := ResetAllUserPropertyNoUsing(userProperty.Model, userProperty.UserId); err != nil {
return nil, err
}
userProperty.Using = property_e.YesUsing
return userProperty, nil
}
//增加结束时间
func (userProperty *UserProperty) AddEndTime(t property_e.UserPropertyLogOrginType, second uint32, operateUserId mysql.ID) (*UserProperty, mysql.ID, error) {
logId, err := addUserPropertyLog(userProperty.Model, userProperty.UserId, userProperty.PropertyId, t, property_e.AddSecond, &second, nil, operateUserId)
if err != nil {
return nil, 0, myerr.WrapErr(err)
}
//if err := ResetAllUserPropertyNoUsing(userProperty.Model, userProperty.UserId); err != nil {
// return nil, logId, err
//}
nowTime := time.Now()
if userProperty.EndTime.After(nowTime) {
nowTime = userProperty.EndTime
}
userProperty.EndTime = nowTime.Add(time.Duration(second) * time.Second)
return userProperty, logId, nil
}
//重置所有的座驾均为不使用状态
func ResetAllUserPropertyNoUsing(model *domain.Model, userId mysql.ID) error {
if err := model.Db.Model(&UserProperty{}).Where(&UserProperty{
UserId: userId,
}).UpdateColumn("using", property_e.NoUsing).Error; err != nil {
return myerr.WrapErr(err)
}
return nil
}
//增加修改日志
func addUserPropertyLog(model *domain.Model, userId mysql.ID, propertyId mysql.ID, originType property_e.UserPropertyLogOrginType, t property_e.UserPropertyLogType, addSecond *uint32, UpdateEndTime *time.Time, operateUserId mysql.ID) (mysql.ID, error) {
userPropertyLog := UserPropertyLog{
UserId: userId,
OperateUserId: operateUserId,
PropertyId: propertyId,
OriginType: originType,
Type: t,
AddSecond: addSecond,
UpdateEndTime: UpdateEndTime,
}
if err := model.Db.Create(&userPropertyLog).Error; err != nil {
return 0, myerr.WrapErr(err)
}
return userPropertyLog.ID, nil
}
func RemoveUserProperty(model *domain.Model, userId mysql.ID, propertyId mysql.ID) error {
return model.Db.Where("user_id = ? AND property_id = ?", userId, propertyId).Delete(&UserProperty{}).Error
}
//用户道具日志
type UserPropertyLog struct {
mysql.Entity
*domain.Model `gorm:"-"`
UserId mysql.ID
OperateUserId mysql.ID
PropertyId mysql.ID
OriginType property_e.UserPropertyLogOrginType
Type property_e.UserPropertyLogType
AddSecond *mysql.Num
UpdateEndTime *time.Time
}
\ No newline at end of file
package user_m package user_m
import "hilo-user/domain/model"
func (userHeadwear *UserHeadwear) Persistent() error {
return model.Persistent(userHeadwear.Db, userHeadwear)
}
func (userProperty *UserProperty) Persistent() error {
return model.Persistent(userProperty.Db, userProperty)
}
func (userPropertyLog *UserPropertyLog) Persistent() error {
return model.Persistent(userPropertyLog.Db, userPropertyLog)
}
package user_m package user_m
import ( import (
"git.hilo.cn/hilo-common/domain"
"git.hilo.cn/hilo-common/resource/mysql"
"hilo-user/_const/enum/user_e" "hilo-user/_const/enum/user_e"
"hilo-user/domain"
"hilo-user/myerr" "hilo-user/myerr"
"hilo-user/myerr/bizerr" "hilo-user/myerr/bizerr"
"hilo-user/resource/mysql"
) )
//用户信息 //用户信息
......
package user_m package user_m
import ( import (
"git.hilo.cn/hilo-common/domain"
"git.hilo.cn/hilo-common/resource/mysql"
"gorm.io/gorm" "gorm.io/gorm"
"hilo-user/_const/enum/user_e" "hilo-user/_const/enum/user_e"
"hilo-user/domain"
"hilo-user/resource/mysql"
"time" "time"
) )
......
package headwear_s
import (
"git.hilo.cn/hilo-common/domain"
"git.hilo.cn/hilo-common/mycontext"
"git.hilo.cn/hilo-common/resource/mysql"
"hilo-user/_const/enum/headwear_e"
"hilo-user/domain/model/user_m"
"hilo-user/myerr"
"hilo-user/myerr/bizerr"
"time"
)
type HeadwearService struct {
svc *domain.Service
}
func NewHeadwearService(myContext *mycontext.MyContext) *HeadwearService {
svc := domain.CreateService(myContext)
return &HeadwearService{svc}
}
// 下发头饰
func (s *HeadwearService) SendHeadwear(receiverUserId mysql.ID, headdressId mysql.ID, days int) error {
var model = domain.CreateModelContext(s.svc.MyContext)
// 头饰增加
receiveHeadwearDuration := uint32(days) * 3600 * 24
if headdressId <= 0 {
return bizerr.InvalidParameter
}
userHeadwear, err := user_m.GetUserHeadwearOrInit(model, receiverUserId, headdressId)
if err != nil {
return err
}
nowTime := time.Now()
if userHeadwear.EndTime.After(nowTime) {
nowTime = userHeadwear.EndTime
}
userHeadwear.EndTime = nowTime.Add(time.Duration(receiveHeadwearDuration) * time.Second)
if err := userHeadwear.Persistent(); err != nil {
return err
}
//日志错误,并不事务回调
if _, err = addUserHeadwearLog(model, receiverUserId, headdressId, headwear_e.ActivityTrigger, headwear_e.AddSecond, &receiveHeadwearDuration, nil, 0); err != nil {
model.Log.Error(err)
}
return err
}
//增加修改日志
func addUserHeadwearLog(model *domain.Model, userId mysql.ID, headwearId mysql.ID, originType headwear_e.UserHeadwearLogOrginType, t headwear_e.UserHeadwearLogType, addSecond *uint32, UpdateEndTime *time.Time, operateUserId mysql.ID) (mysql.ID, error) {
userHeadwearLog := user_m.UserHeadwearLog{
UserId: userId,
OperateUserId: operateUserId,
HeadwearId: headwearId,
OriginType: originType,
Type: t,
AddSecond: addSecond,
UpdateEndTime: UpdateEndTime,
}
if err := model.Db.Create(&userHeadwearLog).Error; err != nil {
return 0, myerr.WrapErr(err)
}
return userHeadwearLog.ID, nil
}
package noble_s
import (
"git.hilo.cn/hilo-common/domain"
"git.hilo.cn/hilo-common/mycontext"
"git.hilo.cn/hilo-common/resource/mysql"
"hilo-user/_const/enum/headwear_e"
"hilo-user/_const/enum/msg_e"
"hilo-user/_const/enum/property_e"
"hilo-user/domain/model/msg_m"
"hilo-user/domain/model/noble_m"
"hilo-user/domain/model/user_m"
"hilo-user/myerr"
"hilo-user/myerr/bizerr"
"strconv"
"time"
)
type NobleService struct {
svc *domain.Service
}
func NewNobleService(myContext *mycontext.MyContext) *NobleService {
svc := domain.CreateService(myContext)
return &NobleService{svc}
}
// 下发贵族
func (s *NobleService) SendNoble(receiverUserId mysql.ID, level uint16, days int) error {
model := domain.CreateModelContext(s.svc.MyContext)
if level <= 0 {
return bizerr.InvalidParameter
}
cfg, err := noble_m.GetConfigByLevel(model.Db, level)
if err != nil {
return err
}
if cfg.PurchasePrice <= 0 || cfg.RenewalPrice <= 0 {
return bizerr.InvalidParameter
}
n := noble_m.UserNoble{UserId: receiverUserId, Level: level}
records, err := n.FindAll(model.Db)
if err != nil {
return err
}
if len(records) > 1 {
// DB表结构决定了不可能发生
return bizerr.IncorrectState
}
if len(records) <= 0 {
// 新增贵族
endTime := time.Now().AddDate(0, 0, int(days))
n = noble_m.UserNoble{UserId: receiverUserId, Level: level, EndTime: endTime}
err = n.Create(model.Db)
if err != nil {
return err
}
nbl := noble_m.UserNobleLog{
SenderId: 0,
ReceiverId: receiverUserId,
Level: level,
Money: 0,
SrcType: noble_m.SRC_APP,
NewEndTime: endTime,
}
err = nbl.Create(model.Db)
if err != nil {
return err
}
} else {
// 延长贵族
n = records[0]
now := time.Now()
endTime := n.EndTime.AddDate(0, 0, int(days))
if now.After(n.EndTime) {
endTime = now.AddDate(0, 0, int(days))
}
nn := noble_m.UserNoble{
Entity: mysql.Entity{ID: n.ID, UpdatedTime: n.UpdatedTime},
}
af, err := nn.UpdateEndTime(model.Db, endTime)
if err != nil {
return err
}
if af <= 0 {
return bizerr.TransactionFailed
}
nbl := noble_m.UserNobleLog{
SenderId: 0,
ReceiverId: receiverUserId,
Level: level,
Money: 0,
SrcType: noble_m.SRC_APP,
OldEndTime: n.EndTime,
NewEndTime: endTime,
}
err = nbl.Create(model.Db)
if err != nil {
return err
}
}
// 头饰增加
receiveHeadwearDuration := uint32(days) * 3600 * 24
if cfg.HeaddressId != 0 {
userHeadwear, err := user_m.GetUserHeadwearOrInit(model, receiverUserId, cfg.HeaddressId)
if err != nil {
return err
}
nowTime := time.Now()
if userHeadwear.EndTime.After(nowTime) {
nowTime = userHeadwear.EndTime
}
userHeadwear.EndTime = nowTime.Add(time.Duration(receiveHeadwearDuration) * time.Second)
if err := userHeadwear.Persistent(); err != nil {
return err
}
//日志错误,并不事务回调
if _, err := addUserHeadwearLog(model, receiverUserId, cfg.HeaddressId, headwear_e.ActivityTrigger, headwear_e.AddSecond, &receiveHeadwearDuration, nil, 0); err != nil {
model.Log.Error(err)
}
}
// 增加座驾
receivePropertyDuration := uint32(days) * 3600 * 24
if cfg.RideId != 0 {
userProperty, err := user_m.GetUserPropertyOrInit(model, receiverUserId, cfg.RideId)
if err != nil {
return err
}
nowTime := time.Now()
if userProperty.EndTime.After(nowTime) {
nowTime = userProperty.EndTime
}
userProperty.EndTime = nowTime.Add(time.Duration(receivePropertyDuration) * time.Second)
if err := userProperty.Persistent(); err != nil {
return err
}
//日志错误,并不事务回调
if err := (&user_m.UserPropertyLog{
Model: model,
UserId: receiverUserId,
PropertyId: cfg.RideId,
OriginType: property_e.ActivityBillboardTrigger,
Type: property_e.AddSecond,
AddSecond: &receivePropertyDuration,
UpdateEndTime: nil,
}).Persistent(); err != nil {
model.Log.Error(err)
}
}
// 推送
user, err := user_m.GetUser(model, receiverUserId)
if err != nil {
return err
}
nobleDuration := days * 3600 * 24
if err := msg_m.NewUserRecord(model, user.ID, msg_e.AddNoble, user.Nick, user.ID, "", strconv.Itoa(int(nobleDuration)/(24*3600)), "", "", "").Persistent(); err != nil {
return err
}
msg_m.SendEmasMsgAssistant(model, user.ExternalId, user.DeviceType)
return nil
}
//增加修改日志
func addUserHeadwearLog(model *domain.Model, userId mysql.ID, headwearId mysql.ID, originType headwear_e.UserHeadwearLogOrginType, t headwear_e.UserHeadwearLogType, addSecond *uint32, UpdateEndTime *time.Time, operateUserId mysql.ID) (mysql.ID, error) {
userHeadwearLog := user_m.UserHeadwearLog{
UserId: userId,
OperateUserId: operateUserId,
HeadwearId: headwearId,
OriginType: originType,
Type: t,
AddSecond: addSecond,
UpdateEndTime: UpdateEndTime,
}
if err := model.Db.Create(&userHeadwearLog).Error; err != nil {
return 0, myerr.WrapErr(err)
}
return userHeadwearLog.ID, nil
}
package ride_s
import (
"git.hilo.cn/hilo-common/domain"
"git.hilo.cn/hilo-common/mycontext"
"git.hilo.cn/hilo-common/resource/mysql"
"hilo-user/_const/enum/property_e"
"hilo-user/domain/model/user_m"
"time"
)
type RideService struct {
svc *domain.Service
}
func NewRideService(myContext *mycontext.MyContext) *RideService {
svc := domain.CreateService(myContext)
return &RideService{svc}
}
// 下发座驾
func (s *RideService) SendRide(receiverUserId mysql.ID, rideId mysql.ID, days int) error {
model := domain.CreateModelContext(s.svc.MyContext)
// 增加座驾
receivePropertyDuration := uint32(days) * 3600 * 24
userProperty, err := user_m.GetUserPropertyOrInit(model, receiverUserId, rideId)
if err != nil {
return err
}
nowTime := time.Now()
if userProperty.EndTime.After(nowTime) {
nowTime = userProperty.EndTime
}
userProperty.EndTime = nowTime.Add(time.Duration(receivePropertyDuration) * time.Second)
if err := userProperty.Persistent(); err != nil {
return err
}
//日志错误,并不事务回调
if err := (&user_m.UserPropertyLog{
Model: model,
UserId: receiverUserId,
PropertyId: rideId,
OriginType: property_e.ActivityBillboardTrigger,
Type: property_e.AddSecond,
AddSecond: &receivePropertyDuration,
UpdateEndTime: nil,
}).Persistent(); err != nil {
model.Log.Error(err)
}
return nil
}
package service
import (
"hilo-user/domain"
"hilo-user/mycontext"
"hilo-user/resource/mysql"
"hilo-user/resource/redisCli"
"runtime/debug"
)
type Service struct {
*domain.CtxAndDb
}
func (service *Service) getMyContext() *mycontext.MyContext {
return service.MyContext
}
/**
* 创建服务
* @param
* @return
**/
func CreateService(myContext *mycontext.MyContext) *Service {
if myContext == nil {
return &Service{CtxAndDb: &domain.CtxAndDb{
Db: mysql.Db,
MyContext: mycontext.CreateMyContext(nil),
Redis: redisCli.GetRedis(),
}}
} else {
return &Service{CtxAndDb: &domain.CtxAndDb{
Db: mysql.Db,
MyContext: myContext,
Redis: redisCli.GetRedis(),
}}
}
}
//事务钩子回调,遇到错误,异常则回调,写service都需要钩子回调
func (service *Service) Transactional(callback func() error) error {
//异常回调
defer func() {
if err := recover(); err != nil {
service.Log.Errorf("doTransactional SYSTEM ACTION PANIC: %v, stack: %v", err, string(debug.Stack()))
service.Db.Rollback()
//为了防止给controller层造成数据错误,继续抛恐慌
panic(err)
}
}()
service.CtxAndDb.Db = mysql.Db.Begin()
err := callback()
if err != nil {
service.Db.Rollback()
return err
}
//提交
return service.Db.Commit().Error
}
...@@ -2,6 +2,8 @@ module hilo-user ...@@ -2,6 +2,8 @@ module hilo-user
go 1.17 go 1.17
replace git.hilo.cn/hilo-common => ../hilo-common
require ( require (
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751
github.com/dgrijalva/jwt-go v3.2.0+incompatible github.com/dgrijalva/jwt-go v3.2.0+incompatible
...@@ -25,9 +27,11 @@ require ( ...@@ -25,9 +27,11 @@ require (
) )
require ( require (
git.hilo.cn/hilo-common v0.0.0-00010101000000-000000000000 // indirect
github.com/KyleBanks/depth v1.2.1 // indirect github.com/KyleBanks/depth v1.2.1 // indirect
github.com/PuerkitoBio/purell v1.1.1 // indirect github.com/PuerkitoBio/purell v1.1.1 // indirect
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
github.com/aliyun/alibaba-cloud-sdk-go v1.61.1274 // indirect
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da // indirect github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da // indirect
github.com/cespare/xxhash/v2 v2.1.2 // indirect github.com/cespare/xxhash/v2 v2.1.2 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
...@@ -40,15 +44,17 @@ require ( ...@@ -40,15 +44,17 @@ require (
github.com/go-playground/locales v0.13.0 // indirect github.com/go-playground/locales v0.13.0 // indirect
github.com/go-playground/universal-translator v0.17.0 // indirect github.com/go-playground/universal-translator v0.17.0 // indirect
github.com/go-playground/validator/v10 v10.2.0 // indirect github.com/go-playground/validator/v10 v10.2.0 // indirect
github.com/golang/protobuf v1.3.3 // indirect github.com/golang/protobuf v1.5.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.1 // indirect github.com/hashicorp/go-cleanhttp v0.5.1 // indirect
github.com/hashicorp/go-hclog v0.12.0 // indirect github.com/hashicorp/go-hclog v0.12.0 // indirect
github.com/hashicorp/go-immutable-radix v1.0.0 // indirect github.com/hashicorp/go-immutable-radix v1.0.0 // indirect
github.com/hashicorp/go-rootcerts v1.0.2 // indirect github.com/hashicorp/go-rootcerts v1.0.2 // indirect
github.com/hashicorp/go-version v1.6.0 // indirect
github.com/hashicorp/golang-lru v0.5.0 // indirect github.com/hashicorp/golang-lru v0.5.0 // indirect
github.com/hashicorp/serf v0.9.3 // indirect github.com/hashicorp/serf v0.9.3 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect github.com/jinzhu/now v1.1.5 // indirect
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af // indirect
github.com/jonboulle/clockwork v0.3.0 // indirect github.com/jonboulle/clockwork v0.3.0 // indirect
github.com/json-iterator/go v1.1.9 // indirect github.com/json-iterator/go v1.1.9 // indirect
github.com/leodido/go-urn v1.2.0 // indirect github.com/leodido/go-urn v1.2.0 // indirect
...@@ -62,8 +68,9 @@ require ( ...@@ -62,8 +68,9 @@ require (
github.com/modern-go/reflect2 v1.0.1 // indirect github.com/modern-go/reflect2 v1.0.1 // indirect
github.com/ugorji/go/codec v1.1.7 // indirect github.com/ugorji/go/codec v1.1.7 // indirect
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 // indirect golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 // indirect
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e // indirect golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 // indirect
golang.org/x/text v0.3.6 // indirect golang.org/x/text v0.3.6 // indirect
golang.org/x/tools v0.0.0-20190907020128-2ca718005c18 // indirect golang.org/x/tools v0.0.0-20190907020128-2ca718005c18 // indirect
google.golang.org/protobuf v1.28.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect
) )
This diff is collapsed.
...@@ -2,18 +2,20 @@ package main ...@@ -2,18 +2,20 @@ package main
import ( import (
"fmt" "fmt"
"hilo-user/resource/consul" "git.hilo.cn/hilo-common/resource/consul"
"hilo-user/route" "hilo-user/route"
) )
const ( const (
PORT = 9040 PORT = 9040
RegisterName = "hiloUser"
RegisterTag = "用户中心"
) )
func main() { func main() {
//cron.Init() // 开启定时任务 //cron.Init() // 开启定时任务
//event_s.EventInit() // 注册事件(内部事件+mysql拟kafka) //event_s.EventInit() // 注册事件(内部事件+mysql拟kafka)
r := route.InitRouter() // 注册路由 r := route.InitRouter() // 注册路由
consul.RegisterToConsul(PORT) // 服务注册 consul.RegisterToConsul(PORT, RegisterName, RegisterTag) // 服务注册
r.Run(fmt.Sprintf(":%d", PORT)) // 启动服务 r.Run(fmt.Sprintf(":%d", PORT)) // 启动服务
} }
package mycontext
import (
"context"
uuid "github.com/satori/go.uuid"
"github.com/sirupsen/logrus"
"hilo-user/_const"
"hilo-user/mylogrus"
"strconv"
"strings"
)
/**
* 主要是完成日志打印
* @param
* @return
**/
type MyContext struct {
context.Context
Log *logrus.Entry
Cxt map[string]interface{}
}
func CreateMyContextWith(traceId interface{}) *MyContext {
cxt := map[string]interface{}{}
cxt[_const.TRACEID] = traceId
return CreateMyContext(cxt)
}
func CreateMyContext(ctx map[string]interface{}) *MyContext {
var traceId string
if traceIdTemp, ok := ctx[_const.TRACEID]; ok {
traceId, ok = traceIdTemp.(string)
} else {
traceId = strings.Replace(uuid.NewV4().String(), "-", "", -1)
}
var userId string
if userIdTemp, ok := ctx[_const.USERID]; ok {
userId = strconv.FormatUint(userIdTemp.(uint64), 10)
}
var deviceTypeStr string
if deviceTypeTemp, ok := ctx[_const.DEVICETYPE]; ok {
deviceTypeStr, ok = deviceTypeTemp.(string)
}
var sAppVersion string
if appVersionTmp, ok := ctx[_const.APP_VERSION]; ok {
sAppVersion, ok = appVersionTmp.(string)
}
var url string
if urlTmp, ok := ctx[_const.URL]; ok {
url, ok = urlTmp.(string)
}
var method string
if methodTmp, ok := ctx[_const.METHOD]; ok {
method, ok = methodTmp.(string)
}
_ctx := context.WithValue(context.Background(), "traceId", traceId)
_ctx = context.WithValue(_ctx, "userId", userId)
return &MyContext{
Context: _ctx,
Log: CreateContextLog(userId, traceId, deviceTypeStr, sAppVersion, url, method),
Cxt: ctx,
}
}
/**
* 创建上下文的日志
**/
func CreateContextLog(userId string, traceId string, deviceType string, deviceVersion string, url string, method string) *logrus.Entry {
return mylogrus.MyLog.WithFields(logrus.Fields{
_const.USERID: userId,
_const.TRACEID: traceId,
_const.DEVICETYPE: deviceType,
_const.APP_VERSION: deviceVersion,
_const.URL: url,
_const.METHOD: method,
})
}
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.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment