// Code generated by hertz generator. package user import ( "acquaintances/biz/dal/mysql" "acquaintances/biz/model" user "acquaintances/biz/model/user" "acquaintances/biz/utils" "context" "fmt" "github.com/cloudwego/hertz/pkg/app" "github.com/cloudwego/hertz/pkg/common/hlog" "github.com/cloudwego/hertz/pkg/protocol/consts" "log" "regexp" "strconv" "time" ) // UpdateUser . // @router /v1/user/update/ [PUT] func UpdateUser(ctx context.Context, c *app.RequestContext) { var err error var req user.UpdateUserRequest err = c.BindAndValidate(&req) if err != nil { c.JSON(consts.StatusBadRequest, err.Error()) return } if err = mysql.UpdatesUser(&req); err != nil { hlog.Error(err.Error()) c.JSON(consts.StatusInternalServerError, &user.CreateUserResponse{Code: user.Code_DBErr, Msg: err.Error()}) return } resp := new(user.UpdateUserResponse) c.JSON(consts.StatusOK, resp) } // DeleteUser . // @router /v1/user/delete/ [delete] func DeleteUser(ctx context.Context, c *app.RequestContext) { var err error var req user.DeleteUserRequest err = c.BindAndValidate(&req) if err != nil { c.JSON(consts.StatusBadRequest, err.Error()) return } if err = mysql.DeleteUser(req.UserID); err != nil { c.JSON(consts.StatusInternalServerError, err.Error()) return } resp := new(user.DeleteUserResponse) c.JSON(consts.StatusOK, resp) } // QueryUser . // @router /v1/user/[GET] func InfoUser(ctx context.Context, c *app.RequestContext) { var err error var req user.InfoUserRequest err = c.BindAndValidate(&req) if err != nil { c.JSON(consts.StatusBadRequest, err.Error()) return } hlog.Infof("InfoUser(%+v)", req) data, err := mysql.InfoUser(req.UserID) if err != nil { c.JSON(consts.StatusInternalServerError, err.Error()) return } resData := new(user.UserInfoReq) resData.UserName = data.UserName resData.Gender = data.Gender resData.Age = int64(data.Age) resData.Introduce = data.Introduce resData.AvatarImageURL = data.AvatarImageURL if data.Birthday != nil { resData.Birthday = data.Birthday.String() } resData.Area = int64(data.Area) resData.Mobile = data.Mobile resData.Email = data.UserEmail resData.Alias = data.Alias resData.Address = data.Address resData.UserID = data.UserID resp := new(user.QueryUserResponse) resp.UserInfo = resData c.JSON(consts.StatusOK, resp) } // CreateUser . // @router /v1/user/create/ [POST] func CreateUser(ctx context.Context, c *app.RequestContext) { var err error var req user.CreateUserRequest err = c.BindAndValidate(&req) if err != nil { c.JSON(consts.StatusBadRequest, err.Error()) return } userId, err := utils.GetID() if err != nil { c.JSON(consts.StatusInternalServerError, err.Error()) return } if err = mysql.CreateUser([]*model.User{ { UserID: strconv.FormatInt(userId, 10), UserName: req.Name, Gender: req.Gender, Age: uint8(req.Age), Mobile: req.Mobile, Area: uint8(req.Area), UserPassword: req.UserPassword, }, }); err != nil { c.JSON(consts.StatusInternalServerError, &user.CreateUserResponse{Code: user.Code_DBErr, Msg: err.Error()}) return } resp := new(user.CreateUserResponse) c.JSON(consts.StatusOK, resp) } // FindUser . // @router /v1/user/find/ [GET] func FindUser(ctx context.Context, c *app.RequestContext) { var err error var req user.FindUserRequest err = c.BindAndValidate(&req) if err != nil { c.String(consts.StatusBadRequest, err.Error()) return } data, err := mysql.FindUser(&req.Keyword) if err != nil { c.JSON(consts.StatusInternalServerError, err.Error()) return } resp := new(user.FindUserResponse) resp.UserInfo = data c.JSON(consts.StatusOK, resp) } // LoginUser . // @router /v1/user/login/ [POST] func LoginUser(ctx context.Context, c *app.RequestContext) { var err error var req user.LoginUserRequest err = c.BindAndValidate(&req) if err != nil { c.JSON(consts.StatusBadRequest, err.Error()) return } data, err := mysql.CheckLogin(req.UserName, req.Password, c.ClientIP()) if err != nil { c.JSON(consts.StatusBadRequest, err.Error()) return } resp := new(user.LoginUserResponse) resData := new(user.UserInfoReq) resData.UserName = data.UserName resData.Gender = data.Gender resData.Age = int64(data.Age) resData.Introduce = data.Introduce resData.AvatarImageURL = data.AvatarImageURL if data.Birthday != nil { resData.Birthday = data.Birthday.String() } resData.Area = int64(data.Area) resData.Mobile = data.Mobile resData.Email = data.UserEmail resData.Alias = data.Alias resData.Address = data.Address resData.UserID = data.UserID resp.UserInfo = resData c.JSON(consts.StatusOK, resp) } // SmsUser 处理用户短信请求(注册、登录等场景的验证码发送) // @router /v1/user/sms/ [POST] func SmsUser(ctx context.Context, c *app.RequestContext) { var err error var req user.SmsRequest err = c.BindAndValidate(&req) if err != nil { c.String(consts.StatusBadRequest, err.Error()) return } // 验证手机号格式 if !utils.IsValidPhone(req.Phone) { c.String(consts.StatusBadRequest, "无效的手机号格式") return } // 生成6位数字验证码 code := utils.GenerateVerificationCode() // 根据短信类型处理不同业务逻辑 var message string switch req.Type { case model.SmsRegister: // 注册场景:检查手机号是否已注册 exists, err := mysql.CheckPhone(req.Phone) if err != nil { c.String(consts.StatusInternalServerError, "查询用户信息失败") return } if exists { c.String(consts.StatusBadRequest, "该手机号已注册") return } message = fmt.Sprintf("您的注册验证码是:%s,有效期5分钟。", code) case model.SmsLongin: // 登录场景:可以不需要检查手机号是否存在 message = fmt.Sprintf("您的登录验证码是:%s,有效期5分钟。", code) default: c.String(consts.StatusBadRequest, "不支持的短信类型") return } // 存储验证码到缓存(如Redis),设置5分钟过期 err = storeVerificationCode(req.Phone, req.Type, code, 5*time.Minute) if err != nil { c.String(consts.StatusInternalServerError, "存储验证码失败") return } // 调用短信发送服务 err = utils.SendSms(req.Phone, message) if err != nil { // 发送失败时删除已存储的验证码 deleteVerificationCode(req.Phone, req.Type) c.String(consts.StatusInternalServerError, "发送短信失败:"+err.Error()) return } resp := &user.SmsResponse{ Msg: "验证码已发送", } c.JSON(consts.StatusOK, resp) } func storeVerificationCode(phone, typ, code string, expiration time.Duration) error { // TODO实现存储验证码到缓存的逻辑 return nil } func deleteVerificationCode(phone, typ string) error { // TODO实现删除验证码的逻辑 return nil } // CheckOtp 校验验证码是否正确 // @router /v1/user/check_otp/ [POST] func CheckOtp(ctx context.Context, c *app.RequestContext) { var err error var req user.CheckOtpRequest err = c.BindAndValidate(&req) if err != nil { c.String(consts.StatusBadRequest, err.Error()) return } // 验证手机号格式 if !utils.IsValidPhone(req.Phone) { c.String(consts.StatusBadRequest, "无效的手机号格式") return } // 验证验证码格式(通常是6位数字) //if !isValidOtp(req.Otp) { // c.String(consts.StatusBadRequest, "验证码格式不正确") // return //} // 验证验证码类型 if !isValidOtpType(req.Type) { c.String(consts.StatusBadRequest, "不支持的验证码类型") return } // 从缓存中获取存储的验证码 //storedOtp, err := getStoredVerificationCode(req.Phone, req.Type) //if err != nil { // c.String(consts.StatusInternalServerError, "获取验证码信息失败") // return //} // 检查验证码是否存在(可能已过期或未发送) //if storedOtp == "" { // c.String(consts.StatusBadRequest, "验证码不存在或已过期") // return //} // 验证验证码是否匹配 //if req.Otp != storedOtp { // resp := &user.CheckOtpResponse{ // Code: consts.StatusBadRequest, // Msg: "验证码不正确", // } // c.JSON(consts.StatusOK, resp) // return //} // 验证码验证成功后,根据类型执行不同业务逻辑 switch req.Type { case model.SmsRegister: case model.SmsLongin: } // 验证成功后删除已使用的验证码,防止重复使用 err = deleteVerificationCode(req.Phone, req.Type) if err != nil { // 这里只记录警告,不影响主流程 log.Printf("删除验证码失败: %v, 手机号: %s, 类型: %s", err, req.Phone, req.Type) } resp := &user.CheckOtpResponse{ Msg: "验证码验证成功", } c.JSON(consts.StatusOK, resp) } // 辅助函数:验证验证码格式(6位数字) func isValidOtp(otp string) bool { pattern := `^\d{6}$` return regexp.MustCompile(pattern).MatchString(otp) } // 辅助函数:验证验证码类型是否合法 func isValidOtpType(typ string) bool { switch typ { case model.SmsRegister, model.SmsLongin: return true default: return false } } // 以下是需要根据实际项目实现的函数 func getStoredVerificationCode(phone, typ string) (string, error) { // 从缓存中获取验证码的逻辑 // 例如: return redisClient.Get(ctx, getOtpCacheKey(phone, typ)).Result() return "", nil }