0


【AI图像生成网站&Golang】项目架构

AI图像生成网站

目录

一、项目介绍

二、雪花算法

三、JWT认证与令牌桶算法

四、项目架构

五、图床上传与图像生成API搭建

六、项目测试与调试(等待更新)


四、项目架构

本项目的后端基于Golang和Gin框架开发,主要包括的模块有:

  1. backend/
  2. ├── controller // 路由控制器
  3. ├── dao // 数据访问模块
  4. ├── mysql // MySQL 数据库操作
  5. └── api // 调用第三方 API 的模块
  6. ├── logic // 核心业务逻辑
  7. ├── models // 数据结构定义
  8. ├── pkg // 工具包(JWT、Snowflake 等)
  9. └── router // 路由定义
  • controller: 负责处理 HTTP 请求并将请求数据传递给逻辑层,控制器层作为入口,将不同的请求指向相应的业务逻辑。
  • dao/mysql: 负责数据库操作,封装了数据查询和持久化逻辑,便于管理数据库交互。
  • logic: 业务逻辑层,实现具体的业务功能,比如用户的登录注册和相关的账号管理。
  • model: 用于定义数据模型与表结构,是项目中数据对象的核心描述。

以用户登录功能为例,从前端请求到后端处理的完整调用流程如下:

在这里插入图片描述

1. 前端发送请求

Vue.js 前端会通过表单收集用户输入的

  1. username

  1. password

,并调用后端登录 API(如

  1. POST /api/login

)。请求中会包含 JSON 格式的用户凭证。

2. 路由层解析请求

后端的路由通过

  1. controller

文件夹中定义的控制器来接收前端的 HTTP 请求。例如:

  1. v1.POST("/login", controller.LoginHandler)

3.控制器层处理请求

控制器负责将请求转发到逻辑层,并对输入参数进行基本的校验:

  1. // LoginHandler 登录业务funcLoginHandler(c *gin.Context){// 1、获取请求参数及参数校验var u *models.LoginForm
  2. if err := c.ShouldBindJSON(&u); err !=nil{// 请求参数有误,直接返回响应
  3. zap.L().Error("Login with invalid param", zap.Error(err))// 判断err是不是 validator.ValidationErrors类型的errors
  4. errs, ok := err.(validator.ValidationErrors)if!ok {// 非validator.ValidationErrors类型错误直接返回ResponseError(c, CodeInvalidParams)// 请求参数错误return}// validator.ValidationErrors类型错误则进行翻译ResponseErrorWithMsg(c, CodeInvalidParams,removeTopStruct(errs.Translate(trans)))return}// 2、业务逻辑处理——登录
  5. user, err := logic.Login(u)if err !=nil{
  6. zap.L().Error("logic.Login failed", zap.String("username", u.UserName), zap.Error(err))if err.Error()== mysql.ErrorUserNotExit {ResponseError(c, CodeUserNotExist)return}ResponseError(c, CodeInvalidParams)return}// 3、返回响应ResponseSuccess(c, gin.H{"user_id": fmt.Sprintf("%d", user.UserID),//js识别的最大值:id值大于1<<53-1 int64: i<<63-1"user_name": user.UserName,"access_token": user.AccessToken,"refresh_token": user.RefreshToken,"avatarImageUrl": user.Avatar,"gender": user.Gender,})}

这里使用了

  1. models.LoginForm

来解析和校验前端传递的 JSON 数据。

  1. // LoginForm 登录请求参数type LoginForm struct{
  2. UserName string`json:"username" binding:"required"`
  3. Password string`json:"password" binding:"required"`}

4. 逻辑层处理核心业务逻辑

  1. logic

文件夹中封装了核心的业务逻辑,例如验证用户凭证、生成令牌等:

  1. funcLogin(username, password string)(string,error){
  2. user =&models.User{
  3. UserName: p.UserName,
  4. Password: p.Password,}if err := mysql.Login(user); err !=nil{returnnil, err
  5. }// 生成JWT
  6. accessToken, refreshToken, err := jwt.GenToken(user.UserID, user.UserName)if err !=nil{return}
  7. user.AccessToken = accessToken
  8. user.RefreshToken = refreshToken
  9. return}

5. 数据访问层与数据库交互

  1. dao/mysql

中的方法负责与数据库交互,如查询用户信息:

  1. // Login 登录业务funcLogin(user *models.User)(err error){
  2. originPassword := user.Password // 记录一下原始密码(用户登录的密码)
  3. sqlStr :="select user_id, username, password,avatar,gender from user where username = ?"
  4. err = db.Get(user, sqlStr, user.UserName)// 查询数据库出错if err !=nil&& err != sql.ErrNoRows {return err
  5. }// 用户不存在if err == sql.ErrNoRows {return errors.New(ErrorUserNotExit)}// 生成加密密码与查询到的密码比较
  6. password :=encryptPassword([]byte(originPassword))if user.Password != password {return errors.New(ErrorPasswordWrong)}returnnil}

6. 返回响应

数据流逐步返回到控制器,最终通过 JSON 格式的响应返回给前端。

  1. // 3、返回响应ResponseSuccess(c, gin.H{"user_id": fmt.Sprintf("%d", user.UserID),//js识别的最大值:id值大于1<<53-1 int64: i<<63-1"user_name": user.UserName,"access_token": user.AccessToken,"refresh_token": user.RefreshToken,"avatarImageUrl": user.Avatar,"gender": user.Gender,})

一些项目中的model建立技巧

1. 字段标签

(1)json 标签
指定 JSON 数据的序列化和反序列化的字段名,如:

  1. UserID uint64`json:"user_id,string"`
  1. json:"user_id,string"

表示 JSON 中的

  1. user_id

字段是字符串格式,但在程序中使用 uint64 类型。适用于后端接收到的数字 ID 被前端以字符串形式传递的场景,避免因类型不匹配导致解析失败。

(2) db 标签
用于指定数据库中表字段的映射,如:

  1. Avatar string`db:"avatar"`

可以避免数据库字段名与代码字段名不一致引发问题。

(3) 多标签结合

字段可以同时使用

  1. json

  1. db

标签,分别处理 JSON 和数据库交互需求,如:

  1. Email string`json:"email" db:"email"`

这样做可以使同一字段同时适配 JSON 序列化和数据库映射,代码更加清晰统一。

2. 自定义

  1. UnmarshalJSON

方法

  1. 在前端提交到后端的字段中,某些字段(
  1. username

  1. password

)可能是某个业务逻辑的必须项,而Golang 的默认 JSON 反序列化无法验证字段是否缺失和符合项目要求,这种情况下,我们可以通过自定义

  1. UnmarshalJSON

方法来解决这个问题。

实现细节
定义一个嵌套的

  1. required

临时结构体,声明必需字段:

  1. required :=struct{
  2. Avatar string`json:"avatar" db:"avatar"`
  3. UserName string`json:"username" db:"username"`
  4. Password string`json:"password" db:"password"`
  5. Email string`json:"email" db:"email"`
  6. Gender int`json:"gender" db:"gender"`}{}

然后通过 json.Unmarshal 解析 JSON 数据:

  1. err = json.Unmarshal(data,&required)

验证必填字段是否存在:

  1. iflen(required.UserName)==0{
  2. err = errors.New("缺少必填字段username")}elseiflen(required.Password)==0{
  3. err = errors.New("缺少必填字段password")}

如果校验通过,将值赋给 User 结构体:

  1. u.Avatar = required.Avatar
  2. u.UserName = required.UserName

3.

  1. binding

标签

  1. binding

标签是 Gin 框架提供的参数校验机制,使用方法如下:

  1. UserName string`json:"username" binding:"required"`

其中,

  1. binding:"required"

表示字段为必填项。 如果前端未提供

  1. username

,请求会被 Gin 自动拒绝,返回 400 Bad Request。


本文转载自: https://blog.csdn.net/qq_42638506/article/details/143831157
版权归原作者 ahhhhaaaa- 所有, 如有侵权,请联系我们删除。

“【AI图像生成网站&Golang】项目架构”的评论:

还没有评论