using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.IdentityModel.Tokens; using MySql.Data.MySqlClient; using System; using System.Data; using System.IdentityModel.Tokens.Jwt; using System.Security.Claims; using System.Text; using System.Threading.Tasks; using System.Net.Http; using System.Text.Json; namespace WxCheckMvc.Controllers { [Route("api/[controller]/[action]")] [ApiController] public class LoginController : ControllerBase { private readonly MySqlConnection _connection; private readonly IHttpClientFactory _httpClientFactory; public IConfiguration? configuration { get; set; } public LoginController(MySqlConnection connection, IHttpClientFactory httpClientFactory, IConfiguration? configuration) { _connection = connection; _httpClientFactory = httpClientFactory; this.configuration = configuration; } // 获取微信小程序OpenID private async Task GetWxOpenIdAsync(string code) { try { var appId = configuration["WeChat:AppId"]; var appSecret = configuration["WeChat:AppSecret"]; if (string.IsNullOrEmpty(appId) || string.IsNullOrEmpty(appSecret)) { throw new Exception("微信小程序配置缺失"); } var httpClient = _httpClientFactory.CreateClient(); var url = $"https://api.weixin.qq.com/sns/jscode2session?appid={appId}&secret={appSecret}&js_code={code}&grant_type=authorization_code"; var response = await httpClient.GetAsync(url); response.EnsureSuccessStatusCode(); var responseContent = await response.Content.ReadAsStringAsync(); var jsonDocument = JsonDocument.Parse(responseContent); if (jsonDocument.RootElement.TryGetProperty("openid", out var openidElement)) { return openidElement.GetString(); } else { // 如果有错误信息,抛出异常 if (jsonDocument.RootElement.TryGetProperty("errcode", out var errcodeElement) && jsonDocument.RootElement.TryGetProperty("errmsg", out var errmsgElement)) { throw new Exception($"获取OpenID失败: {errcodeElement.GetInt32()} - {errmsgElement.GetString()}"); } throw new Exception("获取OpenID失败: 响应中未包含openid"); } } catch (Exception ex) { throw new Exception($"获取微信OpenID时发生错误: {ex.Message}"); } } private string GetToken(string entity) { string TokenString; var claims = new Claim[] { new Claim(ClaimTypes.NameIdentifier, Guid.NewGuid().ToString()), new Claim(ClaimTypes.Name, entity) }; var secretByte = Encoding.UTF8.GetBytes(configuration["JwT:SecretKey"]); var signingKey = new SymmetricSecurityKey(secretByte); var a = SecurityAlgorithms.HmacSha256; var signingCredentials = new SigningCredentials(signingKey, a); var token = new JwtSecurityToken( issuer: configuration["JwT:Issuer"], audience: configuration["JwT:Audience"],//接收 claims: claims,//存放的用户信息 notBefore: DateTime.UtcNow,//发布时间 expires: DateTime.UtcNow.AddMonths(12), signingCredentials: signingCredentials //有效期设置为1天signingCredentials //数字名 ); TokenString = new JwtSecurityTokenHandler().WriteToken(token); return TokenString; } // 用户注册接口 [HttpPost] public async Task Register([FromBody] RegisterRequest request) { try { if (_connection.State != ConnectionState.Open) { await _connection.OpenAsync(); } // 检查用户是否存在 UserResponse user = null; using (MySqlCommand checkCmd = new MySqlCommand("SELECT Id, UserName, UserKey, WeChatName, PhoneNumber, AvatarUrl, FirstLoginTime, IsDisabled, CreateTime, UpdateTime FROM xcx_users WHERE UserKey = @UserKey", _connection)) { checkCmd.Parameters.AddWithValue("@UserKey", request.UserKey); using (var reader = await checkCmd.ExecuteReaderAsync()) { if (await reader.ReadAsync()) { user = new UserResponse { Id = reader.GetInt64(0), UserName = reader.IsDBNull(1) ? "" : reader.GetString(1), UserKey = reader.GetString(2), WeChatName = reader.IsDBNull(3) ? "" : reader.GetString(3), PhoneNumber = reader.IsDBNull(4) ? "" : reader.GetString(4), AvatarUrl = reader.IsDBNull(5) ? "" : reader.GetString(5), FirstLoginTime = reader.GetDateTime(6), IsDisabled = reader.GetBoolean(7), CreateTime = reader.GetDateTime(8), UpdateTime = reader.GetDateTime(9) }; } } } if (user == null) { return NotFound(new { success = false, message = "用户不存在" }); } // 更新用户信息 using (MySqlCommand cmd = new MySqlCommand("UPDATE xcx_users SET UserName = @UserName, WeChatName = @WeChatName, PhoneNumber = @PhoneNumber, AvatarUrl = @AvatarUrl, UpdateTime = NOW() WHERE UserKey = @UserKey", _connection)) { cmd.Parameters.AddWithValue("@UserName", request.UserName ?? (object)DBNull.Value); cmd.Parameters.AddWithValue("@WeChatName", request.WeChatName ?? ""); cmd.Parameters.AddWithValue("@PhoneNumber", request.PhoneNumber ?? ""); cmd.Parameters.AddWithValue("@AvatarUrl", request.AvatarUrl ?? (object)DBNull.Value); cmd.Parameters.AddWithValue("@UserKey", request.UserKey); await cmd.ExecuteNonQueryAsync(); } // 获取更新后的用户信息 UserResponse updatedUser = null; using (MySqlCommand cmd = new MySqlCommand("SELECT Id, UserName, UserKey, WeChatName, PhoneNumber, AvatarUrl, FirstLoginTime, IsDisabled, CreateTime, UpdateTime FROM xcx_users WHERE UserKey = @UserKey", _connection)) { cmd.Parameters.AddWithValue("@UserKey", request.UserKey); using (var reader = await cmd.ExecuteReaderAsync()) { if (await reader.ReadAsync()) { updatedUser = new UserResponse { Id = reader.GetInt64(0), UserName = reader.IsDBNull(1) ? "" : reader.GetString(1), UserKey = reader.GetString(2), WeChatName = reader.IsDBNull(3) ? "" : reader.GetString(3), PhoneNumber = reader.IsDBNull(4) ? "" : reader.GetString(4), AvatarUrl = reader.IsDBNull(5) ? "" : reader.GetString(5), FirstLoginTime = reader.GetDateTime(6), IsDisabled = reader.GetBoolean(7), CreateTime = reader.GetDateTime(8), UpdateTime = reader.GetDateTime(9), Token = GetToken(request.UserKey) }; } } } return Ok(new { success = true, data = updatedUser }); } catch (Exception ex) { return StatusCode(500, new { success = false, message = "更新用户信息失败", error = ex.Message }); } finally { if (_connection.State == ConnectionState.Open) { await _connection.CloseAsync(); } } } // 用户登录接口 [HttpPost] public async Task Login([FromBody] LoginRequest request) { try { string openId; try { openId = await GetWxOpenIdAsync(request.Code); } catch (Exception ex) { return BadRequest(new { success = false, message = "获取微信OpenID失败", error = ex.Message }); } if (_connection.State != ConnectionState.Open) { await _connection.OpenAsync(); } UserResponse user = null; // 检查用户是否存在 using (MySqlCommand checkCmd = new MySqlCommand("SELECT COUNT(1) FROM xcx_users WHERE UserKey = @UserKey", _connection)) { checkCmd.Parameters.AddWithValue("@UserKey", openId); int count = Convert.ToInt32(await checkCmd.ExecuteScalarAsync()); // 如果用户不存在,则注册新用户 if (count == 0) { using (MySqlCommand insertCmd = new MySqlCommand("INSERT INTO xcx_users (UserKey, FirstLoginTime, IsDisabled, CreateTime, UpdateTime) VALUES (@UserKey, @FirstLoginTime, @IsDisabled, NOW(), NOW())", _connection)) { insertCmd.Parameters.AddWithValue("@UserKey", openId); insertCmd.Parameters.AddWithValue("@FirstLoginTime", DateTime.Now); insertCmd.Parameters.AddWithValue("@IsDisabled", 0); // 默认启用 await insertCmd.ExecuteNonQueryAsync(); } } } // 获取用户信息 using (MySqlCommand cmd = new MySqlCommand("SELECT Id, UserName, UserKey, WeChatName, PhoneNumber, AvatarUrl, FirstLoginTime, IsDisabled, CreateTime, UpdateTime FROM xcx_users WHERE UserKey = @UserKey", _connection)) { cmd.Parameters.AddWithValue("@UserKey", openId); using (var reader = await cmd.ExecuteReaderAsync()) { if (await reader.ReadAsync()) { user = new UserResponse { Id = reader.GetInt64(0), UserName = reader.IsDBNull(1) ? "" : reader.GetString(1), UserKey = reader.GetString(2), WeChatName = reader.IsDBNull(3) ? "" : reader.GetString(3), PhoneNumber = reader.IsDBNull(4) ? "" : reader.GetString(4), AvatarUrl = reader.IsDBNull(5) ? "" : reader.GetString(5), FirstLoginTime = reader.GetDateTime(6), IsDisabled = reader.GetBoolean(7), CreateTime = reader.GetDateTime(8), UpdateTime = reader.GetDateTime(9), Token = GetToken(openId) }; } } } if (user == null) { return NotFound(new { success = false, message = "用户不存在" }); } if (user.IsDisabled) { return Ok(new { success = false, message = "用户已被禁用" }); } return Ok(new { success = true, data = user }); } catch (Exception ex) { return StatusCode(500, new { success = false, message = "登录失败", error = ex.Message }); } finally { if (_connection.State == ConnectionState.Open) { await _connection.CloseAsync(); } } } } // 请求和响应模型 public class RegisterRequest { public string UserName { get; set; } public string UserKey { get; set; } // 改为直接传入UserKey public string WeChatName { get; set; } public string PhoneNumber { get; set; } public string AvatarUrl { get; set; } } public class LoginRequest { public string Code { get; set; } } public class UserResponse { public long Id { get; set; } public string UserName { get; set; } public string UserKey { get; set; } public string WeChatName { get; set; } public string PhoneNumber { get; set; } public string AvatarUrl { get; set; } public DateTime FirstLoginTime { get; set; } public bool IsDisabled { get; set; } public DateTime CreateTime { get; set; } public DateTime UpdateTime { get; set; } public string Token { get; set; } } }