using CampusErrand.Data; using CampusErrand.Models; using CampusErrand.Models.Dtos; using CampusErrand.Services; using CampusErrand.Helpers; using Microsoft.EntityFrameworkCore; namespace CampusErrand.Endpoints; public static class AuthEndpoints { public static void MapAuthEndpoints(this WebApplication app) { // 微信手机号登录接口 app.MapPost("/api/auth/login", async ( WeChatLoginRequest request, IWeChatService weChatService, JwtService jwtService, AppDbContext db) => { // 1. 调用微信 code2Session 获取 session_key 和 openid var sessionResult = await weChatService.Code2SessionAsync(request.Code); if (!sessionResult.Success) { return Results.BadRequest(new { code = 400, message = sessionResult.ErrorMessage }); } // 2. 使用 session_key 解密手机号 string phoneNumber; try { phoneNumber = weChatService.DecryptPhoneNumber( sessionResult.SessionKey!, request.EncryptedData, request.Iv); } catch (Exception) { return Results.BadRequest(new { code = 400, message = "手机号解密失败" }); } // 3. 根据手机号查找或创建用户 var user = await db.Users.FirstOrDefaultAsync(u => u.Phone == phoneNumber); if (user == null) { user = new User { Uid = await BusinessHelpers.GenerateUniqueUid(db), OpenId = sessionResult.OpenId!, Phone = phoneNumber, Nickname = $"用户{phoneNumber[^4..]}", CreatedAt = DateTime.UtcNow }; db.Users.Add(user); await db.SaveChangesAsync(); } else if (string.IsNullOrEmpty(user.OpenId) && !string.IsNullOrEmpty(sessionResult.OpenId)) { // 更新 OpenId(如果之前为空) user.OpenId = sessionResult.OpenId; await db.SaveChangesAsync(); } // 4. 生成 JWT 返回 var token = jwtService.GenerateToken(user.Id, user.Role.ToString()); return Results.Ok(new LoginResponse { Token = token, UserInfo = new UserInfo { Id = user.Id, Uid = user.Uid, Phone = user.Phone, Nickname = user.Nickname, AvatarUrl = user.AvatarUrl, Role = user.Role.ToString() } }); }); // 微信快捷登录(仅需 code,通过 openid 注册/登录) app.MapPost("/api/auth/wx-login", async ( WxLoginRequest request, IWeChatService weChatService, JwtService jwtService, AppDbContext db) => { // 1. 调用微信 code2Session 获取 openid Console.WriteLine($"[wx-login] 收到 code: {request.Code}"); var sessionResult = await weChatService.Code2SessionAsync(request.Code); if (!sessionResult.Success) { return Results.BadRequest(new { code = 400, message = sessionResult.ErrorMessage }); } // 2. 根据 openid 查找或创建用户 var openId = sessionResult.OpenId!; var user = await db.Users.FirstOrDefaultAsync(u => u.OpenId == openId); if (user == null) { // 自动注册,手机号暂时留空 var randomSuffix = Random.Shared.Next(1000, 9999).ToString(); user = new User { Uid = await BusinessHelpers.GenerateUniqueUid(db), OpenId = openId, Phone = "", Nickname = $"微信用户{randomSuffix}", CreatedAt = DateTime.UtcNow }; db.Users.Add(user); await db.SaveChangesAsync(); } // 3. 生成 JWT 返回 var token = jwtService.GenerateToken(user.Id, user.Role.ToString()); return Results.Ok(new LoginResponse { Token = token, UserInfo = new UserInfo { Id = user.Id, Uid = user.Uid, Phone = user.Phone, Nickname = user.Nickname, AvatarUrl = user.AvatarUrl, Role = user.Role.ToString() } }); }); // 受保护的测试端点(用于验证认证和授权) app.MapGet("/api/protected", () => Results.Ok("ok")) .RequireAuthorization(); // 更新用户信息(昵称、头像) app.MapPut("/api/user/profile", async (UpdateProfileRequest request, HttpContext httpContext, AppDbContext db) => { var userIdClaim = httpContext.User.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier); if (userIdClaim == null) return Results.Unauthorized(); var userId = int.Parse(userIdClaim.Value); var user = await db.Users.FindAsync(userId); if (user == null) return Results.NotFound(new { code = 404, message = "用户不存在" }); if (!string.IsNullOrWhiteSpace(request.Nickname)) user.Nickname = request.Nickname.Trim(); if (!string.IsNullOrWhiteSpace(request.AvatarUrl)) user.AvatarUrl = request.AvatarUrl.Trim(); await db.SaveChangesAsync(); return Results.Ok(new UserInfo { Id = user.Id, Uid = user.Uid, Phone = user.Phone, Nickname = user.Nickname, AvatarUrl = user.AvatarUrl, Role = user.Role.ToString() }); }).RequireAuthorization(); // 管理员账号密码登录接口 app.MapPost("/api/admin/auth/login", async ( AdminLoginRequest request, JwtService jwtService, AppDbContext db, IConfiguration configuration) => { // 从配置读取管理员凭据 var adminUsername = configuration["Admin:Username"] ?? "admin"; var adminPassword = configuration["Admin:Password"] ?? "admin123"; if (request.Username != adminUsername || request.Password != adminPassword) { return Results.BadRequest(new { code = 400, message = "账号或密码错误" }); } // 查找或创建管理员用户 var admin = await db.Users.FirstOrDefaultAsync(u => u.Role == UserRole.Admin); if (admin == null) { admin = new User { OpenId = "admin", Phone = "admin", Nickname = "管理员", Role = UserRole.Admin, CreatedAt = DateTime.UtcNow }; db.Users.Add(admin); await db.SaveChangesAsync(); } var token = jwtService.GenerateToken(admin.Id, admin.Role.ToString()); return Results.Ok(new { token }); }); } }