using Alipay.EasySDK.Kernel;

using CloudGaming.Code.Account.Contract;
using CloudGaming.Code.Contract;
using CloudGaming.Code.DataAccess;
using CloudGaming.Code.Sms;
using CloudGaming.DtoModel.Account;
using CloudGaming.DtoModel.Account.Login;
using CloudGaming.DtoModel.Account.User;
using CloudGaming.DtoModel.Account.UserDiamondConsume;

using HuanMeng.DotNetCore.JwtInfrastructure;
using HuanMeng.DotNetCore.Redis;
using HuanMeng.DotNetCore.Utility;

using Microsoft.EntityFrameworkCore.Metadata.Internal;

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

using Org.BouncyCastle.Utilities.Encoders;

using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;

namespace CloudGaming.Code.Account
{
    /// <summary>
    /// 账号操作
    /// </summary>
    public class AccountBLL : CloudGamingBase
    {
        public AccountBLL(IServiceProvider serviceProvider) : base(serviceProvider)
        {

        }

        /// <summary>
        /// 发送手机号码
        /// </summary>
        /// <param name="PhoneNumber"></param>
        /// <returns></returns>
        public async Task<bool> SendPhoneNumber(string PhoneNumber)
        {
            if (!PhoneNumberValidator.IsPhoneNumber(PhoneNumber))
            {
                throw MessageBox.Show(ResponseCode.PhoneNumberException, "手机号格式错误");
            }
            var day = int.Parse(DateTime.Now.ToString("yyyyMMdd"));
            var smsCount = await Dao.DaoExt.Context.T_Sms_Log.Where(it => it.SendTimeDay == day && it.PhoneNumber == PhoneNumber).CountAsync();
            if (smsCount >= 5)
            {
                throw MessageBox.Show(ResponseCode.PhoneNumberMaxException, "当日发送以达到上限");
            }
            var phoneNumberCache = RedisCache.StringGetAsync($"App:sms:{PhoneNumber}");
            var verificationCode = new Random().Next(1000, 9999).ToString();
            var sms = AppConfig.AliyunConfig.GetPhoneNumberVerificationService();
            bool isSend = false;
            string exMsg = "";
            try
            {
                isSend = await sms.SendVerificationCodeAsync(PhoneNumber, verificationCode);
            }
            catch (Exception ex)
            {

                exMsg = ex.Message;
                if (exMsg.Length > 200)
                {
                    exMsg = exMsg.Substring(0, 200);
                }
            }
            if (isSend)
            {
                await RedisCache.StringSetAsync($"App:sms:{PhoneNumber}", verificationCode, TimeSpan.FromMinutes(5));
            }

            T_Sms_Log t_Sms_Log = new T_Sms_Log()
            {
                VerificationCode = verificationCode,
                ErrorMessage = exMsg,
                PhoneNumber = PhoneNumber,
                SendStatus = isSend ? 1 : 0,
                SendTime = DateTime.Now,
                SendTimeDay = day
            };
            Dao.DaoExt.Context.T_Sms_Log.Add(t_Sms_Log);
            await Dao.DaoExt.Context.SaveChangesAsync();
            if (!isSend)
            {
                throw MessageBox.ErrorShow("发送失败");
            }
            return isSend;
        }

        /// <summary>
        /// 登录接口
        /// </summary>
        /// <returns></returns>
        public async Task<AccountLogInResponse> LoginAsync()
        {
            this.HttpContextAccessor.HttpContext.Request.Body.Position = 0;
            var json = await new StreamReader(this.HttpContextAccessor.HttpContext.Request.Body).ReadToEndAsync();
            //this.HttpContextAccessor.HttpContext.Request.Headers.GetAuthorization();
            //if (string.IsNullOrEmpty(json))
            //{
            //    throw MessageBox.Show(ResponseCode.NullOrEmpty, "登录方式不合格");
            //}

            var account = AccountExtend.GetUserAccount(json, this);
            if (account == null)
            {
                throw MessageBox.Show(ResponseCode.NullOrEmpty, "未找到登录方式");
            }

            var userId = await account.LoginAsync();
            bool isNew = false;
            if (userId == 0)
            {
                isNew = true;
            }
            var ip = this.HttpContextAccessor.HttpContext.GetClientIpAddress();
            //登录或者注册用户
            var user = await RegisterOrUpdateUserAsync(userId, account, ip);
            //注册用户详细信息
            var userData = await EnsureUserDataExistsAsync(user.Id, account);
            //用户货币
            var userCurrency = await EnsureUserCurrencyExistsAsync(user.Id);
            if (userCurrency == null)
            {
                userCurrency = new List<T_User_Currency>();
            }
            var userCurrencyDic = userCurrency.ToDictionary(it => (UserCurrencyType)it.CurrencyType);
            var userPlayGameTime = await Dao.DaoPhone.Context.T_User_PlayGameTime.Where(it => it.UserId == userId).SumAsync(it => (int?)it.PlayTime);
            //创建用户缓存
            await AccountExtend.LogUserInfoCahceAsync(RedisCache, user, userData, userCurrencyDic, userPlayGameTime ?? 0);

            //创建jwt登录
            var jwt = GenerateJwtToken(user);
            var accountLogIn = new AccountLogInResponse
            {
                NickName = user.NickName,
                Token = jwt.AccessToken,
                UserId = user.Id,
            };
            //获取登录的设备
            var (deviceList, currentDevice) = await ManageUserDevicesAsync(user, account, jwt.AccessToken);
            // 管理设备和Redis缓存
            await ManageDeviceCacheAsync(user.Id, currentDevice.TokenMd5, deviceList);
            var createTimeDay = int.Parse(DateTime.Now.ToString("yyyyMMdd"));
            var createTimeHour = int.Parse(DateTime.Now.ToString("yyyyMMddHH"));
            T_User_Login_Log login_Log = new T_User_Login_Log()
            {
                Channel = this.AppRequestInfo.Channel,
                CreateTime = DateTime.Now,
                CreateTimeDay = createTimeDay,
                CreateTimeHour = createTimeHour,
                AppVersion = this.AppRequestInfo.Version,
                Ip = ip,
                IsNew = isNew,
                LoginType = account.LastLoginType,
                PlatformType = this.AppRequestInfo.Platform,
                UserId = user.Id,
            };
            await Dao.DaoExt.Context.AddAsync(login_Log);
            var isUserLogDay = await Dao.DaoExt.Context.T_User_LoginDay_Log.AnyAsync(it => it.UserId == user.Id && it.CreateTimeDay == createTimeDay);
            if (!isUserLogDay)
            {
                var logInDay = 1;
                if (!isNew)
                {
                    var oldCreateTimeDay = int.Parse(DateTime.Now.AddDays(-1).ToString("yyyyMMdd"));
                    var oldUserLog = await Dao.DaoExt.Context.T_User_LoginDay_Log.FirstOrDefaultAsync(it => it.UserId == user.Id && it.CreateTimeDay == oldCreateTimeDay);
                    if (oldUserLog != null)
                    {
                        logInDay = oldUserLog.LogInDay++;
                    }
                }

                T_User_LoginDay_Log user_LoginDay_Log = new T_User_LoginDay_Log()
                {
                    Channel = this.AppRequestInfo.Channel,
                    CreateTime = DateTime.Now,
                    CreateTimeDay = createTimeDay,
                    CreateTimeHour = createTimeHour,
                    AppVersion = this.AppRequestInfo.Version,
                    Ip = ip,
                    IsNew = isNew,
                    LogInDay = logInDay,
                    PlatformType = this.AppRequestInfo.Platform,
                    UserId = user.Id,
                };
                await Dao.DaoExt.Context.AddAsync(user_LoginDay_Log);
            }
            await Dao.DaoExt.Context.SaveChangesAsync();

            return accountLogIn;
        }
        #region 注册用户

        /// <summary>
        /// 设备Redis缓存管理方法
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="currentTokenMd5"></param>
        /// <param name="deviceList"></param>
        /// <returns></returns>
        private async Task ManageDeviceCacheAsync(int userId, string currentTokenMd5, List<T_User_Token> deviceList)
        {

            // 获取用户当前所有的登录缓存key
            var existingKeys = await RedisServerCache.ScanKeysAsync($"user:login:{userId}:*");

            if (existingKeys != null && existingKeys.Count > 0)
            {
                // 查找和移除不在当前设备列表中的旧设备
                var activeKeys = deviceList.Select(dev => $"user:login:{userId}:{dev.TokenMd5}").ToHashSet();

                foreach (var key in existingKeys)
                {
                    if (!activeKeys.Contains(key))
                    {
                        // 将无效设备状态标记为过期
                        await RedisCache.StringSetAsync(key, "0", TimeSpan.FromMinutes(10));
                    }
                }
            }
            // 构建当前设备的Redis key
            var currentDeviceKey = $"user:login:{userId}:{currentTokenMd5}";
            // 创建当前设备的缓存记录
            await RedisCache.StringSetAsync(currentDeviceKey, "1", TimeSpan.FromHours(1));
        }

        /// <summary>
        /// 注册新用户或更新现有用户信息
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="account"></param>
        /// <param name="ip"></param>
        /// <returns></returns>
        private async Task<T_User> RegisterOrUpdateUserAsync(int userId, IUserAccount account, string ip)
        {
            var user = userId > 0
               ? await Dao.DaoUser.Context.T_User.FirstOrDefaultAsync(it => it.Id == userId)
               : null;
            if (user == null)
            {
                user = new T_User
                {
                    CreatedAt = DateTime.Now,
                    LastLoginAt = DateTime.Now,
                    UpdatedAt = DateTime.Now,
                    IsTest = false,
                    LastLoginType = account.LastLoginType,
                    RegisterType = account.LastLoginType,
                    State = 0,
                    UserIconUrl = AppConfig.UserConfig.UserIconUrl,
                    NickName = $"{AppConfig.UserConfig.NickName}{new Random().Next(1000, 9999)}",
                    Ip = ip,
                    UserRealNameStatus = 0,
                };
                await Dao.DaoUser.Context.T_User.AddAsync(user);
                await Dao.DaoUser.Context.SaveChangesAsync();
                await account.CreateLoginAsync(user);
            }

            user.LastLoginAt = DateTime.Now;
            user.UpdatedAt = DateTime.Now;
            user.Ip = ip;
            await Dao.DaoUser.Context.SaveChangesAsync();

            return user;
        }

        // 确保用户数据存在
        private async Task<T_User_Data> EnsureUserDataExistsAsync(int userId, IUserAccount account)
        {
            var userData = await Dao.DaoUser.Context.T_User_Data.FirstOrDefaultAsync(it => it.UserId == userId);
            if (userData == null)
            {
                userData = new T_User_Data
                {
                    CreateAt = DateTime.Now,
                    UpdateAt = DateTime.Now,
                    PhoneNum = account.GetUserDataProperty(UserDataPropertyEnum.PhoneNum),
                    UserId = userId,
                    Email = account.GetUserDataProperty(UserDataPropertyEnum.Email),
                    DeviceNumber = account.DeviceNumber
                };
                await Dao.DaoUser.Context.T_User_Data.AddAsync(userData);
                await Dao.DaoUser.Context.SaveChangesAsync();
            }
            return userData;
        }
        // 确保用户数据存在
        private async Task<List<T_User_Currency>> EnsureUserCurrencyExistsAsync(int userId)
        {
            var userCurrencys = await Dao.DaoUser.Context.T_User_Currency.Where(it => it.UserId == userId).ToListAsync();
            if (userCurrencys == null || userCurrencys.Count == 0)
            {
                userCurrencys ??= new List<T_User_Currency>();
                var userCurrency = new T_User_Currency
                {
                    CreateAt = DateTime.Now,
                    CurrencyMoney = 0,
                    CurrencyName = UserCurrencyType.钻石.ToString(),
                    CurrencyType = (int)UserCurrencyType.钻石,
                    UpdateAt = DateTime.Now,
                    UserId = userId
                };
                await Dao.DaoUser.Context.T_User_Currency.AddAsync(userCurrency);
                await Dao.DaoUser.Context.SaveChangesAsync();
                userCurrencys.Add(userCurrency);
            }
            return userCurrencys;
        }

        // 生成JWT令牌
        private JwtAuthResult GenerateJwtToken(T_User user)
        {
            var claims = new[]
            {
        new Claim("NickName", user.NickName),
        new Claim("UserId", user.Id.ToString()),
    };
            return JwtAuthManager.GenerateTokens(user.NickName, claims, DateTime.Now);
        }

        // 管理用户设备
        private async Task<(List<T_User_Token>, T_User_Token)> ManageUserDevicesAsync(T_User user, IUserAccount account, string accessToken)
        {
            var currentTime = DateTime.Now;
            var dev = string.IsNullOrEmpty(account.DeviceNumber)
                ? MD5Encryption.ComputeMD5Hash($"{user.Id}:{account.LastLoginType}")
                : account.DeviceNumber;

            var userLoginList = await Dao.DaoUser.Context.T_User_Token
                .Where(it => it.UserId == user.Id)
                .OrderBy(it => it.LastLoginAt)
                .ToListAsync();

            // 删除多余的设备记录
            if (userLoginList.Count > AppConfig.UserConfig.MaxDeviceCount)
            {
                var excessDevices = userLoginList.Take(userLoginList.Count - AppConfig.UserConfig.MaxDeviceCount).ToList();
                Dao.DaoUser.Context.T_User_Token.RemoveRange(excessDevices);
                await Dao.DaoUser.Context.SaveChangesAsync();
            }

            var existingDevice = userLoginList.FirstOrDefault(it => it.DeviceNumber == dev);

            if (existingDevice == null)
            {
                if (userLoginList.Count == AppConfig.UserConfig.MaxDeviceCount)
                {
                    // 替换最早登录的设备
                    existingDevice = userLoginList.First();
                    UpdateDeviceToken(existingDevice, dev, accessToken, currentTime);
                }
                else
                {
                    // 新增设备记录
                    existingDevice = new T_User_Token
                    {
                        CreateAt = currentTime,
                        ExpiresAt = currentTime.AddDays(5),
                        LastLoginAt = currentTime,
                        Token = accessToken,
                        UserId = user.Id,
                        DeviceNumber = dev,
                        TokenMd5 = MD5Encryption.ComputeMD5Hash(accessToken)
                    };
                    await Dao.DaoUser.Context.T_User_Token.AddAsync(existingDevice);
                    userLoginList.Add(existingDevice);
                }
            }
            else
            {
                // 更新现有设备信息
                UpdateDeviceToken(existingDevice, dev, accessToken, currentTime);
            }

            await Dao.DaoUser.Context.SaveChangesAsync();
            return (userLoginList, existingDevice);
        }

        // 更新设备令牌信息
        private void UpdateDeviceToken(T_User_Token device, string deviceNumber, string accessToken, DateTime currentTime)
        {
            device.DeviceNumber = deviceNumber;
            device.TokenMd5 = MD5Encryption.ComputeMD5Hash(accessToken);
            device.LastLoginAt = currentTime;
            device.ExpiresAt = currentTime.AddDays(5);
            device.Token = accessToken;
        }


        #endregion
        /// <summary>
        /// 获取用户信息
        /// </summary>
        /// <returns></returns>
        public async Task<UserInfoDto> GetUserInfo()
        {
            var userId = _UserId;
            if (userId == 0)
            {
                throw MessageBox.Show(ResponseCode.NotFoundRecord, "未找到用户");
            }
            UserInfoCache? userInfo = await GetUserInfoCache();
            UserInfoDto userInfoDto = Mapper.Map<UserInfoDto>(userInfo);
            if (!string.IsNullOrEmpty(userInfoDto.UserName))
            {
                userInfoDto.UserName = userInfoDto.UserName.Length <= 2
                    ? userInfoDto.UserName.Substring(0, 1) + "*"
                    : userInfoDto.UserName.Substring(0, 1) + "*" + userInfoDto.UserName.Substring(userInfoDto.UserName.Length - 1);
            }
            // 将用户身份证号设置成 "前四位*后四位"
            if (!string.IsNullOrEmpty(userInfoDto.IdCard) && userInfoDto.IdCard.Length >= 8)
            {
                userInfoDto.IdCard = userInfoDto.IdCard.Substring(0, 4) + "*********" + userInfoDto.IdCard.Substring(userInfoDto.IdCard.Length - 4);
            }
            //var userPlayGameTime = await Dao.DaoPhone.Context.T_User_PlayGameTime.Where(it => it.UserId == _UserId).SumAsync(it => (int?)it.PlayTime);
            //userInfoDto.UserPlayGameTime = userPlayGameTime ?? 0;
            return userInfoDto;
        }

        #region 实名认证
        /// <summary>
        /// 实名认证
        /// </summary>
        /// <returns></returns>
        public async Task<BaseResponse<bool>> RealAuthentication(string userName, string idCard, string deviceNumber)
        {
            // 参数校验
            ValidateParameters(userName, idCard);

            // 检查用户信息和状态
            CheckUserRealNameStatus(userName, idCard);

            // 获取用户
            var user = await Dao.DaoUser.Context.T_User.FirstOrDefaultAsync(it => it.Id == _UserId);
            if (user == null)
            {
                throw CreateException(ResponseCode.NotFoundRecord, "用户不存在");
            }

            // 实名认证接口验证
            var idCardVerify = this.GetIdCardVerify();
            var (isv, msg) = await idCardVerify.IdCardVerify(userName, idCard);
            if (!isv)
            {
                await LogRealAuthenticationFailure(userName, idCard, deviceNumber, msg);
                throw CreateException(ResponseCode.NotFoundRecord, "身份证号错误");
            }

            // 更新用户实名认证状态
            UpdateUserRealNameStatus(user, userName, idCard);

            // 发放实名认证奖励
            var rewardMessage = await GrantRewardsIfEligible(deviceNumber);

            // 保存日志
            await LogRealAuthenticationSuccess(userName, idCard, deviceNumber, rewardMessage);

            // 更新缓存
            await UpdateUserCache(userName, idCard);

            return new BaseResponse<bool>(0, $"认证成功！{rewardMessage}") { }; ;
        }

        /// <summary>
        /// 校验参数
        /// </summary>
        private void ValidateParameters(string userName, string idCard)
        {
            if (string.IsNullOrEmpty(userName))
            {
                throw CreateException(ResponseCode.ParamError, "用户名为空");
            }
            if (string.IsNullOrEmpty(idCard) || !OtherExtensions.ValidateIDCard(idCard))
            {
                throw CreateException(ResponseCode.ParamError, "身份证号错误");
            }

        }

        /// <summary>
        /// 检查用户实名认证状态
        /// </summary>
        private void CheckUserRealNameStatus(string userName, string idCard)
        {
            //判断用户是否实名认证过,并且不等于未成年人
            if (UserInfo.IsRealName && !UserInfo.IsJuveniles)
            {
                throw MessageBox.Show(0, "此账号已实名认证成功，无需重复实名");
            }
            if (UserInfo.RealNameDateTimeLast != null && DateTime.Now.Subtract((UserInfo.RealNameDateTimeLast ?? DateTime.MinValue)).TotalSeconds < 10)
            {
                throw MessageBox.Show(ResponseCode.Error, "两次绑定身份证号时间间隔太短，请稍后再绑定~");
            }
            if (UserInfo.IdCard == idCard && UserInfo.UserName == userName)
            {
                throw MessageBox.Show(0, "此账号已实名认证成功，无需重复验证");
            }
            if (UserInfo.RealAuthentCount > 10)
            {
                throw MessageBox.Show(0, "此账号今日实名认证次数已到达上限");
            }
        }

        /// <summary>
        /// 更新用户实名认证状态
        /// </summary>
        private void UpdateUserRealNameStatus(T_User user, string userName, string idCard)
        {
            var (isValid, age, _, _) = OtherExtensions.GetIDCardBirthdayAgeSex(idCard);
            user.UserName = userName;
            user.IDCard = idCard;

            if (isValid)
            {
                UserInfo.IsJuveniles = age < 18;
                user.UserRealNameStatus = UserInfo.IsJuveniles ? 2 : 1;
            }

            UserInfo.IsRealName = true;
            UserInfo.RealNameDateTimeLast = DateTime.Now;
            UserInfo.RealAuthentCount++;
        }

        /// <summary>
        /// 发放实名认证奖励
        /// </summary>
        private async Task<string> GrantRewardsIfEligible(string deviceNumber)
        {
            if (string.IsNullOrEmpty(deviceNumber))
            {
                deviceNumber = UserInfo.DeviceNumber;
            }

            var hasUserReward = await Dao.DaoUser.Context.T_User_LimitActionLog
                .AnyAsync(it => it.UserId == _UserId && it.ActionType == (int)UserActionTypeEnum.ActionType.实名认证);

            if (hasUserReward)
            {
                return "用户已经领取过奖励，不再发放奖励";
            }

            var hasDeviceReward = await Dao.DaoUser.Context.T_User_LimitActionLog
                .AnyAsync(it => it.DeviceNumber == deviceNumber && it.ActionType == (int)UserActionTypeEnum.ActionType.实名认证);

            if (!hasDeviceReward)
            {
                var limitActionLog = new T_User_LimitActionLog
                {
                    CreateTime = DateTime.Now,
                    CreateTimeDay = int.Parse(DateTime.Now.ToString("yyyyMMdd")),
                    ActionType = (int)UserActionTypeEnum.ActionType.实名认证,
                    DeviceNumber = deviceNumber,
                    UserId = _UserId,
                    Ip = HttpContextAccessor.HttpContext.GetClientIpAddress()
                };
                await this.UserConsumeDiamondMoneyAsync(UserCurrencyType.钻石, 10, "实名认证赠送");
                await this.SendUserMessageAsync("实名认证赠送", $"实名认证成功!您已获得钻石*{10}");

                await Dao.DaoUser.Context.T_User_LimitActionLog.AddAsync(limitActionLog);
                await Dao.DaoUser.Context.SaveChangesAsync();
                return "奖励已经发送，钻石*10";
            }

            return "用户设备号重复，不发放奖励";
        }

        /// <summary>
        /// 记录实名认证失败日志
        /// </summary>
        private async Task LogRealAuthenticationFailure(string userName, string idCard, string deviceNumber, string msg)
        {
            if (msg.Length > 100)
            {
                msg = msg.Substring(0, 100);
            }
            var log = new T_User_RealAuthentication_Log
            {
                CreateTime = DateTime.Now,
                DeviceNumber = deviceNumber,
                IdCard = idCard,
                UserId = _UserId,
                UserName = userName,
                IsRewards = false,
                RealResults = msg,
                Message = "认证失败"
            };

            await Dao.DaoExt.Context.T_User_RealAuthentication_Log.AddAsync(log);
            await Dao.DaoExt.Context.SaveChangesAsync();
            UserInfo.RealNameDateTimeLast = DateTime.Now;
            UserInfo.RealAuthentCount++;
            await this.SaveUserInfoCacheChangesAsync();
        }

        /// <summary>
        /// 记录实名认证成功日志
        /// </summary>
        private async Task LogRealAuthenticationSuccess(string userName, string idCard, string deviceNumber, string message)
        {
            var log = new T_User_RealAuthentication_Log
            {
                CreateTime = DateTime.Now,
                DeviceNumber = deviceNumber,
                IdCard = idCard,
                UserId = _UserId,
                UserName = userName,
                IsRewards = message.Contains("奖励已经发送"),
                RealResults = "认证成功",
                Message = message
            };

            await Dao.DaoExt.Context.T_User_RealAuthentication_Log.AddAsync(log);
            await Dao.DaoExt.Context.SaveChangesAsync();
        }

        /// <summary>
        /// 更新用户缓存
        /// </summary>
        private async Task UpdateUserCache(string userName, string idCard)
        {
            UserInfo.UserName = userName;
            UserInfo.IdCard = idCard;
            UserInfo.IsRealName = true;
            UserInfo.RealNameDateTimeLast = DateTime.Now;
            UserInfo.RealAuthentCount++;
            await this.SaveUserInfoCacheChangesAsync();
        }

        #endregion

        /// <summary>
        /// 资产收入、支出
        /// </summary>
        /// <param name="ConsumeType">0支出，收入</param>
        /// <returns></returns>
        public async Task<List<UserDiamondConsumeDto>> GetUserDiamondConsumeList(int ConsumeType)
        {
            if (_UserId == 0)
            {
                return new List<UserDiamondConsumeDto>();
            }
            List<UserDiamondConsumeDto> userDiamondConsumeDtos = new List<UserDiamondConsumeDto>();
            var list = await Dao.DaoUser.Context.T_User_DiamondList.Where(it => it.UserId == _UserId && it.CurrencyType == (int)UserCurrencyType.钻石 && it.ConsumeType == ConsumeType).OrderByDescending(it => it.UpdateAt).Take(200).ToListAsync();
            list?.ForEach(it =>
            {
                UserDiamondConsumeDto userDiamondConsumeDto = new UserDiamondConsumeDto()
                {
                    Title = it.Title,

                };
                if (ConsumeType == (int)UserCurrencyConsumeType.收入)
                {
                    userDiamondConsumeDto.ConsumeDetails = $"+{it.Consume.ToString("0.##")}{((UserCurrencyType)it.CurrencyType).ToString()}";
                    userDiamondConsumeDto.DatePrompt = $"{it.CreateAt.ToString("yyyy-MM-dd HH:mm:ss")}";
                }
                else
                {
                    userDiamondConsumeDto.ConsumeDetails = $"-{it.Consume.ToString("0.##")}{((UserCurrencyType)it.CurrencyType).ToString()}";
                    userDiamondConsumeDto.DatePrompt = $"{it.CreateAt.ToString("yyyy-MM-dd HH:mm:ss")} 至 {it.UpdateAt.ToString("yyyy-MM-dd HH:mm:ss")}";
                }
                userDiamondConsumeDtos.Add(userDiamondConsumeDto);
            });
            return userDiamondConsumeDtos;
        }


        /// <summary>
        /// 修改用户昵称
        /// </summary>
        /// <param name="nickName"></param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public async Task<BaseResponse<bool>> UpdateUserNickName(string nickName)
        {

            var user = await Dao.DaoUser.Context.T_User.FirstOrDefaultAsync(it => it.Id == _UserId);
            if (user == null)
            {
                throw new Exception("用户不存在");
            }
            user.NickName = nickName;
            var userPhone = await Dao.DaoUser.Context.T_User_Phone_Account.FirstOrDefaultAsync(it => it.UserId == _UserId);
            if (userPhone != null)
            {
                userPhone.NikeName = nickName;
            }
            await Dao.DaoUser.Context.SaveChangesAsync();
            this.UserInfo.NickName = nickName;
            await this.SaveUserInfoCacheChangesAsync();
            return new BaseResponse<bool>(ResponseCode.Success, "", true);
        }


        /// <summary>
        /// 退出App
        /// </summary>
        /// <returns></returns>
        public async Task ExitApp()
        {
            if (_UserId == 0)
            {
                return;
            }
            //redis
            var userInfo = await AccountExtend.GetUserInfoOrNull(_UserId, this);
            if (userInfo != null)
            {
                await userInfo.DeleteUserInfoCache(this);
            }
        }
        /// <summary>
        /// 账号注销
        /// </summary>
        /// <returns></returns>
        public async Task AccountLogOff()
        {
            if (_UserId == 0)
            {
                return;
            }
            //redis
            //用户信息
            var user = await Dao.DaoUser.Context.T_User.FirstOrDefaultAsync(it => it.Id == _UserId);
            if (user != null)
            {
                user.State = 1;
            }
            //用户手机号登录表
            var userData = await Dao.DaoUser.Context.T_User_Phone_Account.FirstOrDefaultAsync(it => it.UserId == _UserId);
            if (userData != null)
            {
                userData.IsLogout = true;
            }
            await Dao.DaoUser.Context.SaveChangesAsync();
            var userInfo = await AccountExtend.GetUserInfoOrNull(_UserId, this);
            if (userInfo != null)
            {
                await userInfo.DeleteUserInfoCache(this);
            }
        }
    }
}
