// Controllers/AdminController.cs
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.EntityFrameworkCore;
using UserManagementSystem.Web.Data;
using UserManagementSystem.Web.Models;
using UserManagementSystem.Web.Models.ViewModel;
using UserManagementSystem.Web.Services;
namespace UserManagementSystem.Web.Controllers;
[Authorize(Roles = "Admin")]
public class AdminController : Controller
{
private readonly UserManager<ApplicationUser> _userManager;
private readonly ILogger<AdminController> _logger;
private readonly ApplicationDbContext _context; // ✅ 必须注入
public AdminController(UserManager<ApplicationUser> userManager, ILogger<AdminController> logger,ApplicationDbContext context)
{
_userManager = userManager;
_logger = logger;
_context = context;
}
// GET: /Admin/Users
public async Task<IActionResult> Users(string search, int page = 1, int pageSize = 10)
{
var query = _userManager.Users.AsQueryable();
if (!string.IsNullOrWhiteSpace(search))
{
search = search.Trim();
query = query.Where(u => u.UserName.Contains(search) ||
u.Email.Contains(search) ||
u.RealName.Contains(search));
}
var total = await query.CountAsync();
var users = await query
.Skip((page - 1) * pageSize)
.Take(pageSize)
.ToListAsync();
// ✅ 新增:获取每个用户的角色,并映射为显示名
var userRolesList = new List<(string UserId, List<string> DisplayNames)>();
foreach (var user in users)
{
var roles = await _userManager.GetRolesAsync(user);
var displayNames = roles.Select(r => GetDisplayNameForRole(r)).ToList();
userRolesList.Add((user.Id, displayNames));
}
ViewBag.Search = search;
ViewBag.CurrentPage = page;
ViewBag.PageSize = pageSize;
ViewBag.TotalPages = (int)Math.Ceiling(total / (double)pageSize);
ViewBag.UserRoles = userRolesList.ToDictionary(x => x.UserId, x => x.DisplayNames); // 存入 ViewBag
return View(users);
}
// GET: /Admin/CreateUser
public IActionResult CreateUser()
{
return View();
}
// POST: /Admin/CreateUser
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> CreateUser(CreateUserViewModel model)
{
if (!ModelState.IsValid)
{
return View(model);
}
var user = new ApplicationUser
{
UserName = model.Email,
Email = model.Email,
EmailConfirmed = true,
RealName = model.Email.Split('@')[0], // 默认使用邮箱前缀作为真实姓名
CmbId = 0, // 默认村庄
IsActive = true
};
var result = await _userManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
TempData["Success"] = $"用户 {user.Email} 创建成功。";
return RedirectToAction(nameof(Users));
}
foreach (var error in result.Errors)
{
ModelState.AddModelError("", error.Description);
}
return View(model);
}
// GET: /Admin/EditUser/{id}
public async Task<IActionResult> EditUser(string id)
{
var user = await _userManager.FindByIdAsync(id);
if (user == null) return NotFound();
// 获取用户当前角色
var userRoles = await _userManager.GetRolesAsync(user);
var model = new EditUserViewModel
{
Id = user.Id,
UserName = user.UserName!,
RealName = user.RealName ?? "",
Email = user.Email!,
PhoneNumber = user.PhoneNumber ?? "",
CmbId = user.CmbId,
IsActive = user.IsActive,
SelectedRoles = userRoles.ToList()
};
// ✅ 加载村庄选项
model.AvailableVillages = await _context.Cmbs
.Select(c => new SelectListItem
{
Value = c.Id.ToString(),
Text = c.Name
})
.OrderBy(x => x.Text)
.ToListAsync();
model.AvailableVillages.Insert(0, new SelectListItem
{
Value = "",
Text = "-- 请选择村庄 --"
});
// ✅ 加载所有角色用于下拉多选
var allRoles = await _context.Roles.Select(r => r.Name).ToListAsync();
model.AvailableRoles = allRoles.Select(roleName => new SelectListItem
{
Value = roleName,
Text = GetDisplayNameForRole(roleName),
Selected = userRoles.Contains(roleName)
}).ToList();
return View(model);
}
// Controllers/AdminController.cs
private string GetDisplayNameForRole(string role)
{
return role switch
{
"Admin" => "系统管理员",
"User" => "普通用户",
"Editor" => "内容编辑员",
"Moderator" => "信息导入员",
_ => char.ToUpper(role[0]) + role.Substring(1) // 首字母大写兜底
};
}
// POST: /Admin/EditUser
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> EditUser(EditUserViewModel model)
{
if (!ModelState.IsValid)
{
// 需要重新填充 AvailableRoles 和 AvailableVillages
await PopulateDropdowns(model);
return View(model);
}
var user = await _userManager.FindByIdAsync(model.Id);
if (user == null) return NotFound();
// 防止编辑关键账户
if (user.Email == "admin@example.com")
{
TempData["Error"] = "无法编辑系统管理员账户。";
return RedirectToAction(nameof(Users));
}
// 更新用户基本信息
user.UserName = model.UserName;
user.RealName = model.RealName;
user.Email = model.Email;
user.PhoneNumber = model.PhoneNumber;
user.CmbId = model.CmbId ?? 1;
user.IsActive = model.IsActive;
var result = await _userManager.UpdateAsync(user);
if (!result.Succeeded)
{
foreach (var error in result.Errors)
ModelState.AddModelError("", error.Description);
await PopulateDropdowns(model);
return View(model);
}
// ✅ 处理角色更新
var oldRoles = await _userManager.GetRolesAsync(user);
var newRoles = model.SelectedRoles ?? new List<string>();
// 移除不再拥有的角色
var rolesToRemove = oldRoles.Except(newRoles).ToList();
if (rolesToRemove.Any())
{
var removeResult = await _userManager.RemoveFromRolesAsync(user, rolesToRemove);
if (!removeResult.Succeeded)
{
AddErrors(removeResult);
}
}
// 添加新增的角色
var rolesToAdd = newRoles.Except(oldRoles).ToList();
if (rolesToAdd.Any())
{
var addResult = await _userManager.AddToRolesAsync(user, rolesToAdd);
if (!addResult.Succeeded)
{
AddErrors(addResult);
}
}
TempData["Success"] = $"用户信息及角色已更新:{user.Email}";
return RedirectToAction(nameof(Users));
}
// 辅助方法:填充下拉项(避免重复代码)
private async Task PopulateDropdowns(EditUserViewModel model)
{
model.AvailableVillages = await _context.Cmbs
.Select(c => new SelectListItem { Value = c.Id.ToString(), Text = c.Name })
.OrderBy(x => x.Text)
.ToListAsync();
model.AvailableVillages.Insert(0, new SelectListItem { Value = "", Text = "-- 请选择村庄 --" });
var allRoles = await _context.Roles.Select(r => r.Name).ToListAsync();
model.AvailableRoles = allRoles.Select(role => new SelectListItem
{
Value = role,
Text = GetDisplayNameForRole(role),
Selected = model.SelectedRoles?.Contains(role) ?? false
}).ToList();
}
// 辅助方法:添加错误到 ModelState
private void AddErrors(IdentityResult result)
{
foreach (var error in result.Errors)
{
ModelState.AddModelError("", error.Description);
}
}
// GET: /Admin/ResetPassword/{id}
[HttpGet]
public async Task<IActionResult> ResetPassword(string id)
{
var user = await _userManager.FindByIdAsync(id);
if (user == null) return NotFound();
// 1. 生成密码重置 Token(安全令牌)
var token = await _userManager.GeneratePasswordResetTokenAsync(user);
// 2. 生成强密码
string newPassword = PasswordGenerator.GenerateRandomPassword(12);
// 3. 使用 ResetPassword 直接重置(无需移除旧密码)
var result = await _userManager.ResetPasswordAsync(user, token, newPassword);
if (!result.Succeeded)
{
foreach (var error in result.Errors)
{
ModelState.AddModelError("", $"密码重置失败: {error.Description}");
}
return View(new ResetPasswordViewModel
{
UserId = user.Id,
UserName = user.UserName,
GeneratedPassword = null
});
}
// 4. 刷新用户安全戳(强制所有旧 Token 失效)
await _userManager.UpdateSecurityStampAsync(user);
// 5. 成功 → 显示新密码
var model = new ResetPasswordViewModel
{
UserId = user.Id,
UserName = user.UserName,
GeneratedPassword = newPassword
};
return View(model);
}
// POST: /Admin/ResetPassword
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> ResetPassword(ResetPasswordViewModel model)
{
// 1. 验证模型
if (string.IsNullOrEmpty(model.NewPassword) || model.NewPassword != model.ConfirmPassword)
{
ModelState.AddModelError("", "密码为空或两次输入不一致。");
goto ReloadUser;
}
// 2. 查找用户(只查一次)
var appUser = await _userManager.FindByIdAsync(model.UserId);
if (appUser == null)
{
TempData["ErrorMessage"] = "用户不存在。";
return RedirectToAction(nameof(Users));
}
// 3. 执行密码重置
var token = await _userManager.GeneratePasswordResetTokenAsync(appUser);
var result = await _userManager.ResetPasswordAsync(appUser, token, model.NewPassword);
if (result.Succeeded)
{
await _userManager.UpdateSecurityStampAsync(appUser);
_logger.LogInformation("管理员重置了用户 {UserId} ({Email}) 的密码。", appUser.Id, appUser.Email);
TempData["SuccessMessage"] = $"密码已成功重置为:{model.NewPassword}";
return RedirectToAction(nameof(Users));
}
// 4. 如果失败,添加错误信息
foreach (var error in result.Errors)
{
ModelState.AddModelError("", $"密码重置失败: {error.Description}");
}
ReloadUser:
// 只有失败时才需要重新加载用户名
if (string.IsNullOrEmpty(model.UserName))
{
var userToLoad = await _userManager.FindByIdAsync(model.UserId);
if (userToLoad != null)
{
model.UserName = userToLoad.UserName;
}
}
return View(model);
}
// POST: /Admin/DeleteUser/{id}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteUser(string id)
{
var user = await _userManager.FindByIdAsync(id);
if (user == null || user.Email == "admin@example.com")
{
TempData["Error"] = "无法删除此用户。";
return RedirectToAction(nameof(Users));
}
var result = await _userManager.DeleteAsync(user);
if (result.Succeeded)
{
TempData["Success"] = $"用户 {user.Email} 已被删除。";
}
else
{
TempData["Error"] = "删除失败:" + string.Join(", ", result.Errors.Select(e => e.Description));
}
return RedirectToAction(nameof(Users));
}
}
这是我的admincontroller.cs,和// Controllers/AccountController.cs
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using UserManagementSystem.Web.Data;
using UserManagementSystem.Web.Models;
using UserManagementSystem.Web.Models.ViewModel;
public class AccountController : Controller
{
private readonly UserManager<ApplicationUser> _userManager;
private readonly ApplicationDbContext _context;
public AccountController(UserManager<ApplicationUser> userManager, ApplicationDbContext context)
{
_userManager = userManager;
_context = context;
}
[HttpGet]
public IActionResult Register()
{
var model = new RegisterViewModel
{
Cmbs = _context.Cmbs.OrderBy(c => c.SortOrder).ToList()
};
return View(model);
}
[HttpPost]
public async Task<IActionResult> Register(RegisterViewModel model)
{
if (!ModelState.IsValid) return View(model);
var user = new ApplicationUser
{
UserName = model.Email,
Email = model.Email,
RealName = model.RealName,
CmbId = model.CmbId,
IsVip = model.IsVip,
IsActive = true
};
var result = await _userManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
TempData["Success"] = "注册成功!";
return RedirectToAction("Users", "Admin");
}
//foreach (var error in result.Errors)
// ModelState.AddModelError("", error.Description);
foreach (var error in result.Errors)
{
string zhError = error.Code switch
{
"DuplicateUserName" => $"用户名 '{model.Email}' 已被占用。",
"InvalidUserName" => "用户名格式无效,请使用有效的邮箱地址。",
"PasswordTooShort" => "密码太短,至少需要 6 位字符。",
"PasswordRequiresDigit" => "密码必须包含至少一个数字(0-9)。",
"PasswordRequiresLower" => "密码必须包含至少一个小写字母(a-z)。",
"PasswordRequiresUpper" => "密码必须包含至少一个大写字母(A-Z)。",
"PasswordRequiresNonAlphanumeric" => "密码必须包含至少一个特殊字符(如 !@#$%^&*)。",
_ => $"注册失败:{error.Description}"
};
ModelState.AddModelError(string.Empty, zhError);
}
model.Cmbs = _context.Cmbs.OrderBy(c => c.SortOrder).ToList();
return View(model);
}
}
accountcontroller.cs
要求增加角色管理功能