/// <summary>
        /// 尝试创建用户,并发送注册邮件到用户邮箱
        /// </summary>
        /// <param name="registerUser"></param>
        /// <param name="roleType"></param>
        /// <returns></returns>
        private async Task <ValueTuple <bool, MoUserInfo> > TryCreateUser(MoUserInfoSimple registerUser, RoleType roleType)
        {
            if (registerUser == null)
            {
                throw new ArgumentNullException(nameof(registerUser));
            }

            // 因为我们要考虑到已经入库了但邮箱还未激活的用户(也就是还未完成全部注册流程的用户)可能会重复注册,所以我这里改成这样子
            User user = _uf.UserRepository.GetFirstOrDefault(x => x.Email.Equals(registerUser.UserName, StringComparison.OrdinalIgnoreCase));

            if (user == null)
            {
                using (var trans = _uf.BeginTransaction())
                {
                    try
                    {
                        user = await _uf.UserRepository.CreateUserAsync(registerUser);

                        //_uf.SaveChanges();
                        var role = await _uf.RoleRepository.GetOrAddAsync(roleType);

                        //_uf.SaveChanges();
                        var userToRole = new UserToRole
                        {
                            UserId = user.Id,
                            RoleId = role.Id
                        };

                        await _uf.UserToRoleRepository.InsertAsync(userToRole);

                        await _uf.SaveChangesAsync();

                        trans.Commit();
                    }
                    catch (Exception ex)
                    {
                        trans.Rollback();
                        this.MsgBox("注册用户失败");
                        return(false, null);
                    }
                }
            }

            var userInfo = new MoUserInfo
            {
                Id         = user.Id,
                UserStatus = (int)user.UserStatus,
                Email      = user.Email,
                HeadPhoto  = user.HeadPhoto,
                UserName   = user.UserName,
                Roles      = roleType.ToString()
            };

            HttpContext.AddUserInfo(userInfo);
            this.MsgBox("注册用户成功,请查看您的邮箱,确认激活!");
            return(true, userInfo);
        }
        public async Task <IActionResult> Login(MoLoginUser loginUser)
        {
            if (ModelState.IsValid == false || loginUser == null)
            {
                this.MsgBox("验证失败,请重试!");
                return(View());
            }

            User user;

            user = await _uf.UserRepository.GetUser(loginUser.UserName, loginUser.UserPwd);

            if (user == null)
            {
                this.MsgBox("账号或密码错误!");
                return(View(typeof(MoLoginUser), loginUser));
            }
            else if (user.UserStatus == UserStatus.未登录)
            {
                this.MsgBox("该账号已被禁用,或许你可以尝试重新注册一个账号!");
                return(View());
            }

            user.UserStatus = (int)UserStatus.启用;
            _uf.UserRepository.Update(user);

            var userToRole = _uf.UserToRoleRepository.GetAll(x => x.UserId == user.Id);
            await _uf.SaveChangesAsync();

            var userInfo = new MoUserInfo
            {
                Id         = user.Id,
                UserName   = user.UserName,
                Email      = user.Email,
                HeadPhoto  = user.HeadPhoto,
                UserStatus = (int)user.UserStatus,
                Roles      = userToRole.Any(x => x.Role.RoleName.Equals(RoleType.SuperAdmin.ToString(),
                                                                        StringComparison.OrdinalIgnoreCase)) ? RoleType.SuperAdmin.ToString() :
                             userToRole.Any(x => x.Role.RoleName.Equals(RoleType.Admin.ToString(), StringComparison.OrdinalIgnoreCase)) ?
                             RoleType.Admin.ToString() : RoleType.User.ToString()
            };

            HttpContext.AddUserInfo(userInfo);

            if (String.IsNullOrWhiteSpace(loginUser.ReturnUrl))
            {
                return(Redirect("http://localhost:17758/home/index"));
            }
            else
            {
                return(Redirect(loginUser.ReturnUrl));
            }
        }
        public async Task <IActionResult> ActiveEmail(string expire, string token, string email)
        {
            email = email.Trim();
            if (String.IsNullOrWhiteSpace(expire) ||
                String.IsNullOrWhiteSpace(token) ||
                String.IsNullOrWhiteSpace(email))
            {
                return(Redirect("http://*****:*****@"^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$").IsMatch(email) == false)
            {
                return(RedirectToAction("home", "error", new Dictionary <string, object> {
                    { "msg", "邮箱格式不合法,请仔细甄别您的邮箱是否正确" }
                }));
            }
            else if (!long.TryParse(expire, out var longNum))
            {
                return(RedirectToAction("home", "error", new Dictionary <string, object> {
                    { "msg", "无效的请求" }
                }));
            }
            else if (longNum < DateTime.Now.Ticks)
            {
                return(RedirectToAction("home", "error", new Dictionary <string, object> {
                    { "msg", "请求已过期,请重新请求发送激活邮箱" }
                }));
            }

            var user = await _uf.UserRepository.GetAsync(x => x.UserName == email);

            if (user == null)
            {
                return(RedirectToAction("home", "error", new Dictionary <string, object> {
                    { "msg", "不存在该邮箱指定的账号" }
                }));
            }
            else if (user.UserStatus == (int)UserStatus.启用)
            {
                return(RedirectToAction("home", "index"));
            }

            var key = $"activeEmail{email}";

            user.Email      = email;
            user.UserStatus = (int)UserStatus.启用;
            _uf.UserRepository.Update(user);
            await _uf.SaveChangesAsync();

            var userInfo = new MoUserInfo
            {
                Id         = user.Id,
                UserName   = user.UserName,
                UserStatus = (int)user.UserStatus,
                Email      = user.Email,
                HeadPhoto  = user.HeadPhoto,
                Roles      = RoleType.User.ToString()
            };

            HttpContext.AddUserInfo(userInfo);
            return(RedirectToAction("home", "index"));
        }
        public async Task <IActionResult> ConfirmSettingEmail(string expire, string token, string email)
        {
            if (string.IsNullOrWhiteSpace(expire) || string.IsNullOrWhiteSpace(token) || string.IsNullOrWhiteSpace(email) || !email.Contains("@"))
            {
                return(RedirectToAction("home", "error", new Dictionary <string, object>()
                {
                    { "msg", "无效的请求" }
                }));
            }

            if (!long.TryParse(expire, out var expireNum))
            {
                return(RedirectToAction("home", "error", new Dictionary <string, object>()
                {
                    { "msg", "无效的请求" }
                }));
            }

            if (DateTime.Now.Ticks > expireNum)
            {
                return(RedirectToAction("home", "error", new Dictionary <string, object>()
                {
                    { "msg", "请求已过期,请重新申请!" }
                }));
            }

            var compareToken = CryptHelper.GetMd5Value($"{expire}-{email}");

            if (!token.Equals(compareToken))
            {
                return(RedirectToAction("home", "error", new Dictionary <string, object>()
                {
                    { "msg", "验证失败,请重新操作" }
                }));
            }

            if (!HttpContext.TryGetUserInfo(out var userInfo))
            {
                return(RedirectToAction("home", "error", new Dictionary <string, object>()
                {
                    { "msg", "登录已过期,请重新登录" }
                }));
            }

            // 处理
            var user = await _uf.UserRepository.GetFirstOrDefaultAsync(x => x.Id == userInfo.Id && x.UserStatus == (int)UserStatus.启用);

            if (user == null)
            {
                return(RedirectToAction("home", "error", new Dictionary <string, object>()
                {
                    { "msg", "绑定失败,请重新操作" }
                }));
            }

            user.Email = email;
            _uf.UserRepository.Update(user);

            var result = await _uf.SaveChangesAsync();

            if (result > 0)
            {
                this.MsgBox("绑定邮箱成功!");
                userInfo.Email = email;
                //如果是登陆状态,需要更新session
                HttpContext.DeleteUserInfo();
                HttpContext.AddUserInfo(userInfo);
            }
            else
            {
                this.MsgBox("绑定失败,请稍重试!");
            }

            return(RedirectToAction("UserCenter", "Index"));
        }
        public async Task <IActionResult> ModifyUser(MoUserInfoEntire userInfoEntire)
        {
            HttpContext.TryGetUserInfo(out var userInfo);
            ViewData["HeadPhoto"] = userInfo.HeadPhoto;
            ViewData["Role"]      = userInfo.Roles.ToLower();

            if (userInfoEntire == null || userInfoEntire.Id <= 0)
            {
                this.MsgBox("修改失败,请稍后重试");
                return(View(userInfoEntire));
            }
            else if (String.IsNullOrEmpty(userInfoEntire.UserName))
            {
                this.MsgBox("昵称不能为空");
                return(View(userInfoEntire));
            }

            if (!Regex.IsMatch(userInfoEntire.Email, @"^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$"))
            {
                this.MsgBox("非法邮箱,请重新输入");
            }

            if (!String.IsNullOrWhiteSpace(userInfoEntire.Tel) &&
                !Regex.IsMatch(userInfoEntire.Tel, "^(13|15|18)[0-9]{9}$"))
            {
                this.MsgBox("非法手机号码,请重新输入");
            }

            try
            {
                var user = await _uf.UserRepository.GetByIdAsync(userInfoEntire.Id);

                if (user == null)
                {
                    this.MsgBox("修改失败,请稍后重试");
                    return(View(userInfoEntire));
                }

                user.RealName  = userInfoEntire.RealName;
                user.UserName  = userInfoEntire.UserName;
                user.Tel       = userInfoEntire.Tel;
                user.Sex       = userInfoEntire.Sex;
                user.Introduce = userInfoEntire.Introduce;

                _uf.UserRepository.Update(user);

                var result = await _uf.SaveChangesAsync();

                userInfo.UserName = userInfoEntire.UserName;
                HttpContext.DeleteUserInfo();
                HttpContext.AddUserInfo(userInfo);

                this.MsgBox("修改成功!");
            }
            catch (Exception ex)
            {
                this.MsgBox("修改失败,请稍后重试!");
                _logger.LogError(userInfoEntire.Id, "更新用户信息操作失败");
                _uf.SaveChanges();
            }

            return(View(userInfoEntire));
        }
        public async Task <IActionResult> UpHeadPhoto(int id)
        {
            HttpContext.TryGetUserInfo(out var userInfo);
            ViewData["Role"] = userInfo.Roles.ToLower();
            var file = HttpRequest.Form.Files.Where(x =>
                                                    x.Name == "myHeadPhoto" &&
                                                    x.ContentType.Contains("image"))
                       .SingleOrDefault();

            if (file == null)
            {
                this.MsgBox("请选择上传的头像图片!");
                return(View(userInfo));
            }


            var maxSize = 1024 * 1024 * 4; // 图片大小不超过4M

            if (file.Length > maxSize)
            {
                this.MsgBox("头像图片不能大于4M");
                return(View(userInfo));
            }

            var directory     = RootConfiguration.Root + Path.DirectorySeparatorChar + _mapSetting.UpHeadPhotoPath;
            var directoryInfo = new DirectoryInfo(directory);

            directoryInfo.DeleteAll(userInfo.Email);

            var fileExtend  = file.FileName.Substring(file.FileName.LastIndexOf('.'));
            var fileNewName = $"{userInfo.Email}-{DateTime.Now.ToString("yyyyMMddHHssfff")}{fileExtend}";
            var path        = Path.Combine(directory, fileNewName);

            using (var stream = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write))
            {
                await file.CopyToAsync(stream); // 读取上传的图片并保存
            }

            // 更新数据
            var viewPath = $"{_mapSetting.ViewHeadPhotoPath}/{fileNewName}";

            using (var trans = _uf.BeginTransaction())
            {
                try
                {
                    var user = await _uf.UserRepository.GetByIdAsync(userInfo.Id);

                    if (user == null)
                    {
                        this.MsgBox("上传失败,请稍后重试!");
                        return(View(userInfo));
                    }
                    user.HeadPhoto = $"../../wwwroot{viewPath}";
                    _uf.UserRepository.Update(user);
                    var result = await _uf.SaveChangesAsync();

                    if (result > 0)
                    {
                        userInfo.HeadPhoto = user.HeadPhoto;

                        HttpContext.DeleteUserInfo();
                        HttpContext.AddUserInfo(userInfo);

                        this.MsgBox("上传成功!");
                        trans.Commit();
                    }
                    else
                    {
                        this.MsgBox("上传失败,请稍后再试!");
                        trans.Rollback();
                    }
                }
                catch (Exception ex)
                {
                    this.MsgBox("上传失败,请稍后再试!");
                    trans.Rollback();
                    _logger.LogError(userInfo.Id, "上传头像操作失败");
                    _uf.SaveChanges();
                    trans.Commit();
                }
            }

            return(View(userInfo));
        }