package mod

import (
	"errors"

	"../log"
	"../nt"
	pb "../protos"
	"../utils"
	//"fmt"
	"strconv"
	"time"

	//"github.com/coheneye/go-simplejson"
	"github.com/go-redis/redis"
	"go.uber.org/zap"
)

var (
	ErrRedisHGetFailed  = errors.New("maybe execute hget failed.")
	ErrRedisHSetFailed  = errors.New("execute hset failed.")
	ErrRedisHIncrFailed = errors.New("hincr failed")
	ErrRedisZAddFailed  = errors.New("execute zadd failed.")
	ErrRedisZRemFailed  = errors.New("execute zrem failed")
)

func Exists(key string) bool {
	rs, err := nt.Rdb.Exists(key).Result()
	return err == nil && rs > 0
}

func SHGet(key, field string) (string, error) {
	ret, err := nt.Rdb.HGet(key, field).Result()
	if err == redis.Nil {
		return "", nil
	}
	return ret, err
}

// 从 redis 中取得用户信息 user:<guid>
func GetUserinfoFromRedis(guid uint64) (*pb.User, error) {
	rs, err := nt.Rdb.HMGet(KUserInfo(guid), []string{
		"account", //0
		"nickname",
		"password",
		"icon",
		"token",
		"balance", // 5
		"bank",
		"freezed",
		"area",
		"ip",
		"vip", // 10
		"channel",
		"qq",
		"wechat",
		"bets",
		"recharged", //15
		"withdrawed",
		"bankPass",
		"phone",
		"status",
		"name", //20
		"alipay",
		"regameinfo",
		"email",
		"birthday",
		"bindPhoneBonus"}...).Result()
	if nil != err || rs[0] == nil {
		log.Debug("redis.HMGet", zap.Uint64("guid", guid))
		return nil, ErrRedisHGetFailed
	}

	userinfo := &pb.User{
		Guid:           guid,
		Account:        utils.If_to_string(rs[0], ""),
		Nickname:       utils.If_to_string(rs[1], ""),
		Icon:           utils.If_to_int32(rs[3], 0),
		Token:          utils.If_to_string(rs[4], ""),
		Balance:        utils.If_to_int64(rs[5], 0),
		Bank:           utils.If_to_int64(rs[6], 0),
		Freezed:        utils.If_to_int64(rs[7], 0),
		Area:           utils.If_to_string(rs[8], ""),
		Ip:             utils.If_to_string(rs[9], ""),
		Vip:            utils.If_to_int32(rs[10], 0),
		Qq:             utils.If_to_string(rs[12], ""),
		Wechat:         utils.If_to_string(rs[13], ""),
		Bets:           utils.If_to_int64(rs[14], 0),
		Recharged:      utils.If_to_int64(rs[15], 0),
		Withdrawed:     utils.If_to_int64(rs[16], 0),
		BankPass:       utils.If_to_string(rs[17], ""),
		Phone:          utils.If_to_string(rs[18], ""),
		Status:         utils.If_to_int32(rs[19], 0),
		Name:           utils.If_to_string(rs[20], ""),
		Alipay:         utils.If_to_string(rs[21], ""),
		Regameinfo:     utils.If_to_string(rs[22], ""),
		Email:          utils.If_to_string(rs[23], ""),
		Birthday:       utils.If_to_string(rs[24], ""),
		BindPhoneBonus: utils.If_to_int64(rs[25], 0),
	}
	return userinfo, nil
}

// 第一次登录的用户需要保存用户信息。
func UpdateUserinfoToRedis(guid uint64, fields map[string]interface{}) error {
	_, err := nt.Rdb.HMSet(KUserInfo(guid), fields).Result()
	if nil != err {
		log.Error("save userinfo", zap.Uint64("guid", guid), zap.Error(err))
	}
	return err
}

func AddUserBalance(guid uint64, deltaBalance int64) (int64, error) {
	return nt.Rdb.HIncrBy(KUserInfo(guid), "balance", deltaBalance).Result()
}

func AddUserRecharged(guid uint64, delta int64) (int64, error) {
	return nt.Rdb.HIncrBy(KUserInfo(guid), "recharged", delta).Result()
}

func AddUserWithDraw(guid uint64, delta int64) (int64, error) {
	return nt.Rdb.HIncrBy(KUserInfo(guid), "withdrawed", delta).Result()
}

func GetUserAttrs(guid uint64, fields ...string) ([]interface{}, error) {
	return nt.Rdb.HMGet(KUserInfo(guid), fields...).Result()
}

func GetUserAttr(guid uint64, field string) (string, error) {
	return SHGet(KUserInfo(guid), field)
}

func AddUserBank(guid uint64, deltaBank int64) (int64, error) {
	return nt.Rdb.HIncrBy(KUserInfo(guid), "bank", deltaBank).Result()
}

// 更新用户 token, 从登录服务器返回后刷新
func UpdateUserToken(guid uint64, token string) {
	_, err := nt.Rdb.HSet(KUserInfo(guid), "token", token).Result()
	if nil != err {
		log.Error("save userinfo", zap.Uint64("guid", guid), zap.Error(err))
	}
}

func GetUserPassword(guid uint64) string {
	password, _ := SHGet(KUserInfo(guid), "password")
	return password
}

func UpdateUserPassword(guid uint64, password string) error {
	_, err := nt.Rdb.HSet(KUserInfo(guid), "password", password).Result()
	return err
}

func UpdateUserAttr(guid uint64, field string, value interface{}) error {
	_, err := nt.Rdb.HSet(KUserInfo(guid), field, value).Result()
	return err
}

//////////////////////////////////////////// game channel addr-config //////////////////////////////////////////
// 获取所有 channel 配置
//func GetChannels() ([]*pb.GameItemEntry, error) {
//	pjs, err := nt.Rdb.Get(KTConfChannels).Result()
//	if err != nil {
//		return nil, err
//	}
//	js, err := simplejson.NewJson([]byte(pjs))
//	if err != nil {
//		return nil, err
//	}
//
//	items := js.Get("params")
//	arr, err := items.Array()
//	if err != nil {
//		return nil, err
//	}
//	sz := len(arr)
//
//	var games []*pb.GameItemEntry
//	var bGame bool
//	for i := 0; i < sz; i++ {
//		item := &pb.GameItemEntry{}
//
//		item.ParentId = items.GetIndex(i).Get("lobby_id").MustInt64()
//		item.Name = items.GetIndex(i).Get("name").MustString()
//		item.Id = items.GetIndex(i).Get("channel_id").MustInt64()
//		item.Enabled = int32(items.GetIndex(i).Get("is_start").MustInt64())
//		item.Order = int32(items.GetIndex(i).Get("order").MustInt64())
//		item.Icon = items.GetIndex(i).Get("big_icon").MustString()
//		item.IconSize = int32(items.GetIndex(i).Get("big_icon_size").MustInt64())
//		item.ThumbNorm = items.GetIndex(i).Get("normal_icon").MustString()
//		item.ThumbHl = items.GetIndex(i).Get("click_icon").MustString()
//		bGame = items.GetIndex(i).Get("is_game").MustBool()
//		if bGame {
//			item.IsGame = 1
//		}
//
//		games = append(games, item)
//	}
//	return games, nil
//}
//
//func GetGames() ([]*pb.GameItemEntry, error) {
//	pjs, err := nt.Rdb.Get(KTConfGames).Result()
//	if err != nil {
//		return nil, err
//	}
//	js, err := simplejson.NewJson([]byte(pjs))
//	if err != nil {
//		return nil, err
//	}
//
//	items := js.Get("params")
//	arr, err := items.Array()
//	if err != nil {
//		return nil, err
//	}
//	sz := len(arr)
//
//	var games []*pb.GameItemEntry
//	var bGame bool
//	for i := 0; i < sz; i++ {
//		item := &pb.GameItemEntry{}
//
//		item.ParentId = items.GetIndex(i).Get("channel_id").MustInt64()
//		item.Name = items.GetIndex(i).Get("name").MustString()
//		item.Id = items.GetIndex(i).Get("game_id").MustInt64()
//		item.Enabled = int32(items.GetIndex(i).Get("is_start").MustInt64())
//		item.Order = int32(items.GetIndex(i).Get("order").MustInt64())
//		item.Icon = items.GetIndex(i).Get("icon").MustString()
//		item.IconSize = int32(items.GetIndex(i).Get("icon_size").MustInt64())
//		item.GameMaker = items.GetIndex(i).Get("channel").MustInt64()
//		gameParamArr := items.GetIndex(i).Get("game_param").MustArray()
//
//		for n := 0; n < len(gameParamArr); n++ {
//			str, _ := gameParamArr[n].(string)
//			item.GameParam = append(item.GameParam, str)
//		}
//		bGame = items.GetIndex(i).Get("is_game").MustBool()
//		if bGame {
//			item.IsGame = 1
//		} else {
//			item.IsGame = 0
//		}
//		games = append(games, item)
//	}
//	return games, nil
//}

// 保存渠道信息到 redis
// 当前渠道对应客户端二级菜单
// redis key: conf:chans
// @jt: json text
func SaveChannels(jt string) error {
	_, err := nt.Rdb.Set(KTConfChannels, jt, 0).Result()
	return err
}

// 保存游戏信息到 redis
func SaveGames(jt string) error {
	s, err := nt.Rdb.Set(KTConfGames, jt, 0).Result()
	if nil != err {
		log.Error("save_games", zap.String("return", s), zap.Error(err))
	}
	return err
}

// @jt: json text
func SaveClientAddrConfig(jt string) error {
	s, err := nt.Rdb.Set(KTConfClientAddrs, jt, 0).Result()
	if nil != err {
		log.Error("save client addrs", zap.String("return", s), zap.Error(err))
	}
	return err
}

func GetClientAddrConfig() (string, error) {
	return nt.Rdb.Get(KTConfClientAddrs).Result()
}

// 设置跑马灯
func SaveMarquees(id, typ int64, jt string) error {
	field := strconv.FormatInt(id, 10)
	_, err := nt.Rdb.HSet(KHConfMarquees, field, jt).Result()
	return err
}

// 得到跑马灯配置
func GetMarquee() (map[string]string, error) {
	return nt.Rdb.HGetAll(KHConfMarquees).Result()
}

func RemoveMarquee(ids ...int64) error {
	var sids []string
	for _, id := range ids {
		sids = append(sids, strconv.FormatInt(id, 10))
	}
	_, err := nt.Rdb.HDel(KHConfMarquees, sids...).Result()
	return err
}

// 系统公告
func SaveNotices(id, typ int64, jt string) error {
	field := strconv.FormatInt(id, 10)
	_, err := nt.Rdb.HSet(KHConfNotices, field, jt).Result()
	return err
}

func GetNotices() (map[string]string, error) {
	return nt.Rdb.HGetAll(KHConfNotices).Result()
}

func RemoveNotices(ids ...int64) error {
	var sids []string
	for _, id := range ids {
		sids = append(sids, strconv.FormatInt(id, 10))
	}
	_, err := nt.Rdb.HDel(KHConfNotices, sids...).Result()
	return err
}

///////////////////////////////////////////////////// user status /////////////////////////////////
// 保存玩家连接信息，从哪个 agent 连接过来的
func SaveUserAgent(guid uint64, agentId uint64) {
	_, err := nt.Rdb.EvalSha(Scripts["user_agent_update"].Sha, []string{}, guid, agentId).Result()
	if nil != err {
		log.Error("SaveUserAgent", zap.Uint64("guid", guid), zap.Error(err))
	}
}

func GetUserAgent(guid uint64) (uint64, error) {
	v, _ := SHGet(KHMapUserAgent, strconv.FormatUint(guid, 10))
	return strconv.ParseUint(v, 10, 64)
}

// 在 map:user_agent 和 map:agent_user:* 中同时删除 guid
// 对应用户下线
func RemoveUserAgent(guid uint64, agentId uint64) {
	_, err := nt.Rdb.EvalSha(Scripts["user_agent_remove"].Sha, []string{}, guid, agentId).Result()
	if nil != err {
		log.Error("RemoveUserAgent", zap.Uint64("guid", guid), zap.Error(err))
	}
}

// 在 map:user_agent 中 删除所有 agentId 的用户
func TryRemoveUsersOfAgent(agentId uint64) {
	mp, err := nt.Rdb.HGetAll(KHMapUserAgent).Result()
	if err != nil {
		return
	}
	s_agentId := strconv.FormatUint(agentId, 10)
	for sguid, sagent := range mp {
		if sagent == s_agentId {
			nt.Rdb.HDel(KHMapUserAgent, sguid)
		}
	}
}

// 获取 agentId 上的所有用户 guid
func GetAgentUsers(agentId uint64) ([]uint64, error) {
	m, err := nt.Rdb.HGetAll(KMapAgentUser(agentId)).Result()
	if nil != err {
		return nil, err
	}
	var rt []uint64
	for k, _ := range m {
		guid, err := strconv.ParseUint(k, 10, 64)
		if err != nil {
			continue
		}
		rt = append(rt, guid)
	}
	return rt, nil
}

// 删除 key map:agent_user:* ，用于服务下线
func ClearAgentUsers(agentId uint64) error {
	_, err := nt.Rdb.Del(KMapAgentUser(agentId)).Result()
	return err
}

// 保存玩家所在的服务器实例信息
// v1: 保存玩家当前在玩什么游戏， guid - gameId
func SaveUserLogic(guid uint64, gameId int64) error {
	_, err := nt.Rdb.EvalSha(Scripts["user_logic_update"].Sha, []string{}, guid, gameId).Result()
	return err
}

func GetUserLogic(guid uint64) (int64, error) {
	val, err := nt.Rdb.HGet(KHMapUserLogic, strconv.FormatUint(guid, 10)).Result()
	if err != nil {
		return 0, err
	}
	ival, err := strconv.ParseInt(val, 10, 64)
	if err != nil {
		log.Debug("GetUserLogic strconv.ParseInt err",zap.Any("val",val),zap.Any("ival",ival))
		return 0, err
	}
	if !utils.ValidGameId(ival) {
		return 0, utils.ErrEmptyString
	}
	return ival, nil
}

func RemoveUserLogic(guid uint64, gameId int64) error {
	_, err := nt.Rdb.EvalSha(Scripts["user_logic_remove"].Sha, []string{}, guid, gameId).Result()
	return err
}

func GetLogicUsers(logicId uint64) ([]uint64, error) {
	m, err := nt.Rdb.HGetAll(KMapLogicUser(logicId)).Result()
	if nil != err {
		return nil, err
	}
	var rt []uint64
	for k, _ := range m {
		guid, err := strconv.ParseUint(k, 10, 64)
		if err != nil {
			continue
		}
		rt = append(rt, guid)
	}
	return rt, nil
}

func ClearLogicUsers(logicId uint64) error {
	_, err := nt.Rdb.Del(KMapLogicUser(logicId)).Result()
	return err
}

// 获得玩家所在大厅或游戏服务器(id)
func GetAllUserPlace() (map[string]string, map[string]string) {
	agents, _ := nt.Rdb.HGetAll(KHMapUserAgent).Result()
	logics, _ := nt.Rdb.HGetAll(KHMapUserLogic).Result()
	return agents, logics
}

//  玩家私信 sorted set
func AddPrivateMail(guid uint64, id int64, js string) error {
	_, err := nt.Rdb.ZAdd(KUserMails(guid), &redis.Z{Score: float64(id), Member: js}).Result()
	if err != nil {
		return ErrRedisZAddFailed
	}
	return err
}

func GetPrivateMails(guid uint64) ([]string, error) {
	return nt.Rdb.ZRangeByScore(KUserMails(guid), &redis.ZRangeBy{Min: "-inf", Max: "+inf"}).Result()
}

func GetPrivateMailNum(guid uint64) (int64, error) {
	return nt.Rdb.ZCard(KUserMails(guid)).Result()
}

func RemovePrivateMailById(guid uint64, id int64) error {
	sid := strconv.FormatInt(id, 10)
	r, err := nt.Rdb.ZRemRangeByScore(KUserMails(guid), sid, sid).Result()
	if r != 1 {
		return ErrRedisZRemFailed
	}
	return err
}

///////////////////////////////////////// wallet //////////////////////////
// 本函数只需要在第一次保存用户信息的时候调用
func SaveMapAccountGuid(account string, guid uint64) error {
	_, err := nt.Rdb.HSet(KHMapAccountGuid, account, strconv.FormatUint(guid, 10)).Result()
	return err
}

// 获得 account 映射的 guid
func GetGuidbyAccount(account string) (uint64, error) {
	sguid, err := SHGet(KHMapAccountGuid, account)
	if nil != err {
		return 0, err
	}
	return strconv.ParseUint(sguid, 10, 64)
}

// 获得流水单号状态
// 如果交易成功，状态为交易的金币数量
// 如果交易回滚，状态为 0.00
// 回滚失败的流水，保存在回滚记录
func GetSerialStatus(ticketId int64, serial string, agentName string) (string, error) {
	return SHGet(KTradeStatus(agentName, ticketId), serial)
}

//通过流水号拿到注单号
func GetTicketIdBySerial(serial string, agentName string) (string, error) {
	return SHGet(KTradeTicketMap(agentName), serial)
}

// 更新流水单号状态
func UpdateSerialSuc(ticketId int64, serial string, agentName string, val interface{}) error {
	suc, err := nt.Rdb.HSet(KTradeStatus(agentName, ticketId), serial, val).Result()
	if !suc {
		return ErrRedisHSetFailed
	}
	return err
}

func GetAllSerialStatus(ticketId int64, agentName string) (map[string]string, error) {
	return nt.Rdb.HGetAll(KTradeStatus(agentName, ticketId)).Result()
}

func GetAllFaildKeys(agentName string) ([]string, error) {
	return nt.Rdb.Keys(KTradeFailedKey(agentName)).Result()
}

func GetAllFaildStatus(key string) (map[string]string, error) {
	return nt.Rdb.HGetAll(key).Result()
}

///////////// 交易失败
// 更新流水单号状态
func UpdateTradeFailed(ticketId int64, serial string, agentName string, val interface{}) error {
	suc, err := nt.Rdb.HSet(KTradeFailed(agentName, ticketId), serial, val).Result()
	if !suc {
		return ErrRedisHSetFailed
	}
	succ, err := nt.Rdb.HSet(KTradeTicketMap(agentName), serial, strconv.FormatInt(ticketId, 10)).Result()
	if !succ {
		return ErrRedisHSetFailed
	}
	return err
}

func GetTradeFailed(ticketId int64, serial string, agentName string) (string, error) {
	return SHGet(KTradeFailed(agentName, ticketId), serial)
}

func RemTradeFailed(ticketId int64, serial string, agentName string) error {
	_, err := nt.Rdb.HDel(KTradeFailed(agentName, ticketId), serial).Result()
	return err
}

////////////////// 交易回滚
func AddRollbackFailed(ticketId int64, serial string) error {
	return nil
}

/////////////////////////////////////////////////// bind phone ///////////////////////////////////////////
// 建立由 phone 到 guid 的绑定
func SetupPhoneGuid(phone string, guid uint64) {
	_, err := nt.Rdb.HSet(KHMapPhoneGuid, phone, guid).Result()
	if nil != err {
		log.Warn("phone_guid", zap.String("phone", phone), zap.Uint64("guid", guid), zap.Error(err))
	}
}

// 根据手机号查询绑定的 guid
func GetGuidByPhone(phone string) (uint64, error) {
	s, err := SHGet(KHMapPhoneGuid, phone)
	if err != nil {
		return 0, err
	}
	guid, err := strconv.ParseUint(s, 10, 64)
	if nil != err {
		return 0, err
	}
	return guid, nil
}

// 缓存验证码，默认 90 秒
func CacheVerifiCode(guid uint64, phone string, code string) error {
	_, err := nt.Rdb.Set(KUserVerifiCode(guid, phone), code, 90*time.Second).Result()
	if nil != err {
		log.Error("CacheVerifiCode", zap.Uint64("guid", guid), zap.String("phone", phone),
			zap.String("code", code))
	}
	return err
}

func GetVerifiCode(guid uint64, phone string) (string, error) {
	return nt.Rdb.Get(KUserVerifiCode(guid, phone)).Result()
}

func ClearVerifiCode(guid uint64, phone string) {
	_ = nt.Rdb.Del(KUserVerifiCode(guid, phone))
}

// 活动
func UpdateActivity(jst []byte) error {
	_, err := nt.Rdb.HSet(KHConfActivities, "def", jst).Result()
	return err
}

func GetActivities() (string, error) {
	return SHGet(KHConfActivities, "def")
}

func RemActivity() error {
	_, err := nt.Rdb.HDel(KHConfActivities, "def").Result()
	return err
}

//夺宝电子
//dbdz通过交易序号查找下注结算信息
func GetDBDZTransferId(agentName string, transferid string) (string, error) {
	return SHGet(KDBDZTransferIdKey(agentName), transferid)
}

//dbdz交易失败(平台系统错误)暂存
func UpdateDbdzTradeFailed(agentName string, transferId string, val interface{}) error {
	suc, err := nt.Rdb.HSet(KDBDZTradeFailed(agentName), transferId, val).Result()
	if !suc {
		return ErrRedisHSetFailed
	}
	return err
}

//dbdz下注失败 取消下注
func SaveBetFaildTrade(agentName string, transferId string, val interface{}) error {
	suc, err := nt.Rdb.HSet(KDBDZBetFaild(agentName), transferId, val).Result()
	if !suc {
		return ErrRedisHSetFailed
	}
	return err
}

//回滚交易失败的下注
func RemDBDZTradeFailed(agentName string, transferId string) error {
	_, err := nt.Rdb.HDel(KDBDZTradeFailed(agentName), transferId).Result()
	return err
}

///////////////// VIP section

func VipGetBonus(guid uint64) (int64, error) {
	s, err := SHGet(KHVipBonus, strconv.FormatUint(guid, 10))
	if nil != err {
		return 0, err
	}
	r, err := utils.StrToInt64(s)
	if nil != err {
		return 0, err
	}
	return r, nil
}

func VipUpdateBonus(guid uint64, delta int64) error {
	_, err := nt.Rdb.HSet(KHVipBonus, strconv.FormatUint(guid, 10), delta).Result()
	return err
}

func VipGetWeekly(guid uint64) (int64, error) {
	s, err := SHGet(KHVipWeekly, strconv.FormatUint(guid, 10))
	if nil != err {
		return 0, err
	}
	r, err := utils.StrToInt64(s)
	if nil != err {
		return 0, err
	}
	return r, nil
}

func VipUpdateWeekly(guid uint64, when int64) error {
	_, err := nt.Rdb.HSet(KHVipWeekly, strconv.FormatUint(guid, 10), when).Result()
	return err
}

func VipGetMonthly(guid uint64) (int64, error) {
	s, err := SHGet(KHVipMonthly, strconv.FormatUint(guid, 10))
	if nil != err {
		return 0, err
	}
	r, err := utils.StrToInt64(s)
	if nil != err {
		return 0, err
	}
	return r, nil
}

func VipUpdateMonthly(guid uint64, when int64) error {
	_, err := nt.Rdb.HSet(KHVipMonthly, strconv.FormatUint(guid, 10), when).Result()
	return err
}

// 延时下分任务
func UpdateCronJob(guid string, jst []byte) error {
	_, err := nt.Rdb.HSet(KHMapGuidCronJob, guid, jst).Result()
	return err
}

func GetCronJob(guid string) (string, error) {
	return SHGet(KHMapGuidCronJob, guid)
}

func RemCronJob(guid string) error {
	_, err := nt.Rdb.HDel(KHMapGuidCronJob, guid).Result()
	return err
}

func GetAllCronJob() (map[string]string, error) {
	return nt.Rdb.HGetAll(KHMapGuidCronJob).Result()
}

func UpdateKickoff(guid uint64) error {
	_, err := nt.Rdb.HSet(KHKickoffs, strconv.FormatUint(guid, 10), time.Now().Unix()).Result()
	return err
}

func GetKickoff(guid uint64) (int64, error) {
	stime, err := SHGet(KHKickoffs, strconv.FormatUint(guid, 10))
	if err != nil {
		return 0, err
	}
	tm, err := utils.StrToInt64(stime)
	if err != nil {
		return 0, err
	}
	return tm, nil
}

func RemKickoff(guid uint64) error {
	_, err := nt.Rdb.HDel(KHKickoffs, strconv.FormatUint(guid, 10)).Result()
	return err
}

// 游戏任务
func UpdateGameTask(guid_key string, value []byte) error {
	_, err := nt.Rdb.HSet(KHMapGuidTask, guid_key, value).Result()
	return err
}

func GetGameTask(guid_key string) (string, error) {
	return SHGet(KHMapGuidTask, guid_key)
}

//获取游戏任务配置
func GetGameTaskConf() (string, error) {
	return nt.Rdb.Get(KHConfGameTask).Result()
}

//记录玩家近期游戏
func UpdateGameHistory(guid string, jst []byte) error {
	_, err := nt.Rdb.HSet(KHMAPGuidGHistory, guid, jst).Result()
	return err
}

func GetGameHistory(guid string) (string, error) {
	return SHGet(KHMAPGuidGHistory, guid)
}

func RemGameHistory(guid string) error {
	_, err := nt.Rdb.HDel(KHMAPGuidGHistory, guid).Result()
	return err
}

//记录红包
func UpdateRedEnvelope(data []byte, exp time.Duration) error {
	_, err := nt.Rdb.Set(KHRedEnvelope, data, exp).Result()
	return err
}

func GetRedEnvelope() (string, error) {
	str,err := nt.Rdb.Get(KHRedEnvelope).Result()
	if err != nil && err != redis.Nil{
		return "",err
	}

	return str, nil
}

func RemRedEnvelop() error{
	_,err := nt.Rdb.Del(KHRedEnvelope).Result()
	return err
}