package controllers import ( "encoding/json" "server/models" "server/services" "strings" "time" "github.com/beego/beego/v2/client/orm" beego "github.com/beego/beego/v2/server/web" ) // 用于签名的密钥 var jwtSecret = []byte("yunzer_jwt_secret_key") // AuthController 处理认证相关请求 type AuthController struct { beego.Controller } // Login 处理登录请求 func (c *AuthController) Login() { var username, password, tenantName string // 优先尝试从URL参数获取 username = c.GetString("username") password = c.GetString("password") tenantName = c.GetString("tenant_name") // 如果URL参数为空,尝试从JSON请求体获取 if username == "" || password == "" || tenantName == "" { var loginData struct { Username string `json:"username"` Password string `json:"password"` TenantName string `json:"tenant_name"` } err := json.Unmarshal(c.Ctx.Input.RequestBody, &loginData) if err != nil { c.Data["json"] = map[string]interface{}{ "code": 1, "message": "请求参数格式错误", "data": nil, } c.ServeJSON() return } username = loginData.Username password = loginData.Password tenantName = loginData.TenantName } // 验证参数 if tenantName == "" { c.Data["json"] = map[string]interface{}{ "code": 1, "message": "租户名称不能为空", "data": nil, } c.ServeJSON() return } // 验证用户(先检查用户表,找不到再检查员工表) user, employee, err := services.ValidateUser(username, password, tenantName) if err != nil { // 登录失败 c.Data["json"] = map[string]interface{}{ "code": 1, "message": err.Error(), } } else { var tokenString string var userId int var usernameForToken string var tenantId int var userInfo map[string]interface{} // 判断是用户登录还是员工登录 if user != nil { // 用户登录 userId = user.Id usernameForToken = user.Username tenantId = user.TenantId userInfo = map[string]interface{}{ "id": user.Id, "username": user.Username, "email": user.Email, "avatar": user.Avatar, "nickname": user.Nickname, "tenant_id": user.TenantId, "role": user.Role, // 角色ID "type": "user", // 标识是用户登录 } } else if employee != nil { // 员工登录 userId = employee.Id usernameForToken = employee.EmployeeNo tenantId = employee.TenantId userInfo = map[string]interface{}{ "id": employee.Id, "username": employee.EmployeeNo, "name": employee.Name, "email": employee.Email, "phone": employee.Phone, "tenant_id": employee.TenantId, "department_id": employee.DepartmentId, "position_id": employee.PositionId, "role": employee.Role, // 角色ID "type": "employee", // 标识是员工登录 } } else { c.Data["json"] = map[string]interface{}{ "code": 1, "message": "登录验证失败", } c.ServeJSON() return } // 使用models包中的GenerateToken函数生成token tokenString, err = models.GenerateToken(userId, usernameForToken, tenantId) if err != nil { c.Data["json"] = map[string]interface{}{ "code": 1, "message": "生成token失败", "data": nil, } } else { // 登录成功,写当前时间到last_login_time,获取IP写入last_login_ip,并增加login_count loginTime := time.Now() // 获取客户端IP地址 clientIP := c.Ctx.Input.IP() // 优先从X-Forwarded-For获取真实IP(适用于代理环境) forwardedFor := c.Ctx.Input.Header("X-Forwarded-For") if forwardedFor != "" { // X-Forwarded-For可能包含多个IP,取第一个 ips := strings.Split(forwardedFor, ",") if len(ips) > 0 { ip := strings.TrimSpace(ips[0]) // 过滤掉本地地址 if ip != "" && ip != "::1" && ip != "127.0.0.1" && !strings.HasPrefix(ip, "192.168.") && !strings.HasPrefix(ip, "10.") && !strings.HasPrefix(ip, "172.16.") { clientIP = ip } else if ip != "" { clientIP = ip } } } // 如果X-Forwarded-For没有有效IP,尝试从X-Real-IP获取 if clientIP == "" || clientIP == "::1" || clientIP == "127.0.0.1" { realIP := c.Ctx.Input.Header("X-Real-IP") if realIP != "" { ip := strings.TrimSpace(realIP) if ip != "::1" && ip != "127.0.0.1" { clientIP = ip } } } // 如果获取到的是IPv6的localhost,转换为IPv4格式显示 if clientIP == "::1" { clientIP = "127.0.0.1" } // 如果仍然没有获取到IP,使用默认值 if clientIP == "" { clientIP = "unknown" } o := orm.NewOrm() // 更新登录信息 if user != nil { // 更新用户表 _, _ = o.Raw("UPDATE yz_users SET last_login_time = ?, last_login_ip = ?, login_count = IFNULL(login_count,0)+1 WHERE id = ?", loginTime, clientIP, user.Id).Exec() } else if employee != nil { // 更新员工表(如果员工表有last_login_time和last_login_ip字段) // 注意:如果员工表没有这些字段,需要先添加字段 _, _ = o.Raw("UPDATE yz_tenant_employees SET last_login_time = ?, last_login_ip = ? WHERE id = ?", loginTime, clientIP, employee.Id).Exec() } c.Data["json"] = map[string]interface{}{ "code": 0, "message": "登录成功", "data": map[string]interface{}{ "accessToken": tokenString, "token": tokenString, // 兼容性 "user": userInfo, }, } } } c.ServeJSON() } // Logout 处理登出请求 func (c *AuthController) Logout() { // 在实际应用中,这里需要处理JWT或Session的清除 c.Data["json"] = map[string]interface{}{ "success": true, "message": "登出成功", } c.ServeJSON() }