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

AI图像生成网站

目录

一、项目介绍

二、雪花算法

三、JWT认证与令牌桶算法

四、项目架构

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

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


四、项目架构

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

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

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

在这里插入图片描述

1. 前端发送请求

Vue.js 前端会通过表单收集用户输入的 usernamepassword,并调用后端登录 API(如 POST /api/login)。请求中会包含 JSON 格式的用户凭证。

2. 路由层解析请求

后端的路由通过 controller 文件夹中定义的控制器来接收前端的 HTTP 请求。例如:

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

3.控制器层处理请求

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


// LoginHandler 登录业务
func LoginHandler(c *gin.Context) {
	// 1、获取请求参数及参数校验
	var u *models.LoginForm
	if err := c.ShouldBindJSON(&u); err != nil {
		// 请求参数有误,直接返回响应
		zap.L().Error("Login with invalid param", zap.Error(err))
		// 判断err是不是 validator.ValidationErrors类型的errors
		errs, ok := err.(validator.ValidationErrors)
		if !ok {
			// 非validator.ValidationErrors类型错误直接返回
			ResponseError(c, CodeInvalidParams) // 请求参数错误
			return
		}
		// validator.ValidationErrors类型错误则进行翻译
		ResponseErrorWithMsg(c, CodeInvalidParams, removeTopStruct(errs.Translate(trans)))
		return
	}

	// 2、业务逻辑处理——登录
	user, err := logic.Login(u)
	if err != nil {
		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,
	})
}

这里使用了 models.LoginForm 来解析和校验前端传递的 JSON 数据。

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

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

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

func Login(username, password string) (string, error) {
    user = &models.User{
		UserName: p.UserName,
		Password: p.Password,
	}
	if err := mysql.Login(user); err != nil {
		return nil, err
	}
	// 生成JWT
	accessToken, refreshToken, err := jwt.GenToken(user.UserID, user.UserName)
	if err != nil {
		return
	}
	user.AccessToken = accessToken
	user.RefreshToken = refreshToken
	return
}

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

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

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

6. 返回响应

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

// 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 数据的序列化和反序列化的字段名,如:

	UserID uint64 `json:"user_id,string"`

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

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

	Avatar string `db:"avatar"`

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

(3) 多标签结合

字段可以同时使用 jsondb 标签,分别处理 JSON 和数据库交互需求,如:

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

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

2. 自定义 UnmarshalJSON 方法

        在前端提交到后端的字段中,某些字段(usernamepassword)可能是某个业务逻辑的必须项,而Golang 的默认 JSON 反序列化无法验证字段是否缺失和符合项目要求,这种情况下,我们可以通过自定义UnmarshalJSON 方法来解决这个问题。

实现细节
定义一个嵌套的 required 临时结构体,声明必需字段:

required := struct {
    Avatar   string `json:"avatar" db:"avatar"`
    UserName string `json:"username" db:"username"`
    Password string `json:"password" db:"password"`
    Email    string `json:"email" db:"email"`
    Gender   int    `json:"gender" db:"gender"`
}{}

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

err = json.Unmarshal(data, &required)

验证必填字段是否存在:

if len(required.UserName) == 0 {
    err = errors.New("缺少必填字段username")
} else if len(required.Password) == 0 {
    err = errors.New("缺少必填字段password")
}

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

  u.Avatar = required.Avatar
  u.UserName = required.UserName

3. binding 标签

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

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

其中,binding:"required" 表示字段为必填项。 如果前端未提供 username,请求会被 Gin 自动拒绝,返回 400 Bad Request。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/917999.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

翼鸥教育:从OceanBase V3.1.4 到 V4.2.1,8套核心集群升级实践

引言&#xff1a;自2021年起&#xff0c;翼鸥教育便开始应用OceanBase社区版&#xff0c;两年间&#xff0c;先后部署了总计12套生产集群&#xff0c;其中核心集群占比超过四分之三&#xff0c;所承载的数据量已突破30TB。自2022年10月&#xff0c;OceanBase 社区发布了4.2.x 版…

ESP32-S3模组上跑通esp32-camera(19)

接前一篇文章&#xff1a;ESP32-S3模组上跑通esp32-camera&#xff08;18&#xff09; 本文内容参考&#xff1a; esp32-camera入门&#xff08;基于ESP-IDF&#xff09;_esp32 camera-CSDN博客 OV5640手册解读-CSDN博客 ESP32_CAM CameraWebServer例程源码解析笔记&#xf…

vmWare虚拟环境centos7安装Hadoop 伪分布式实践

背景&#xff1a;近期在研发大数据中台&#xff0c;需要研究Hadoop hive 的各种特性&#xff0c;需要搭建一个Hadoop的虚拟环境&#xff0c;本来想着使用dock &#xff0c;但突然发现docker 公共仓库的镜像 被XX 了&#xff0c;无奈重新使用vm 搭建虚拟机。 大概经历了6个小时完…

ARM(安谋) China处理器

0 Preface/Foreword 0.1 参考博客 Cortex-M23/M33与STAR-MC1星辰处理器 ARM China&#xff0c;2018年4月established&#xff0c;独立运行。 1 处理器类型 1.1 周易AIPU 1.2 STAR-MC1&#xff08;星辰处理器&#xff09; STAT-MC1&#xff0c;主要为满足AIOT应用性能、功…

c++--------《set 和 map》

c--------《set 和 map》 1 set系列的使⽤1.1 set类的介绍1.2 set的构造和迭代器1.3 set重要接口 2 实现样例2.1: insert和迭代器遍历使⽤样例&#xff1a;2.2: find和erase使⽤样例&#xff1a; 练习3.map系列的使用3.1 map类的介绍3.1.1 pair类型介绍 3.2 map的数据修改3.3mu…

MySQL面试之底层架构与库表设计

华子目录 mysql的底层架构客户端连接服务端连接的本质&#xff0c;连接用完会立马丢弃吗解析器和优化器的作用sql执行前会发生什么客户端的连接池和服务端的连接池数据库的三范式 mysql的底层架构 客户端连接服务端 连接的本质&#xff0c;连接用完会立马丢弃吗 解析器和优化器…

vscode vite+vue3项目启动调试

1、经常我们在普通的项目中&#xff0c;如果算法并不复杂&#xff0c;那么基本上console.log就可以搞定&#xff0c;当然也可以直接alert&#xff0c;打包的时候如果不去掉&#xff0c;还会在发版中上接弹出&#xff0c;给你个惊喜。 2、碰到了有些算法过程比较复杂的情况下&a…

详解八大排序(一)------(插入排序,选择排序,冒泡排序,希尔排序)

文章目录 前言1.插入排序&#xff08;InsertSort&#xff09;1.1 核心思路1.2 实现代码 2.选择排序&#xff08;SelectSort&#xff09;2.1 核心思路2.2 实现代码 3.冒泡排序&#xff08;BubbleSort&#xff09;3.1 核心思路3.2 实现代码 4.希尔排序&#xff08;ShellSort&…

IPv6 NDP 记录

NDP&#xff08;Neighbor Discovery Protocol&#xff0c;邻居发现协议&#xff09; 是 IPv6 的一个关键协议&#xff0c;它组合了 IPv4 中的 ARP、ICMP 路由器发现和 ICMP 重定向等协议&#xff0c;并对它们作出了改进。该协议使用 ICMPv6 协议实现&#xff0c;作为 IPv6 的基…

【包教包会】CocosCreator3.x框架——带翻页特效的场景切换

一、效果演示 二、如何获取 1、https://gitee.com/szrpf/TurnPage 2、解压&#xff0c;导入cocos creator&#xff08;版本3.8.2&#xff09;&#xff0c;可以直接运行Demo演示 三、算法思路 1、单场景 页面预制体 通过loadScene来切换页面&#xff0c;无法实现页面特效。…

拉取docker镜像应急方法

发现许多docker hub镜像网址速度也慢得发指啦&#xff0c;如果想速度快点&#xff0c;可以考虑买个按量计费的公有云服务器&#xff0c;用他们的内网镜像&#xff0c;然后再导出&#xff0c;然后传到本地。 开通服务器 可以考虑个开通最低配的&#xff0c;这里我用的是腾讯的…

Cyberchef配合Wireshark提取并解析HTTP/TLS流量数据包中的文件

本文将介绍一种手动的轻量级的方式&#xff0c;还原HTTP/TLS协议中传输的文件&#xff0c;为流量数据包中的文件分析提供帮助。 如果捕获的数据包中存在非文本类文件&#xff0c;例如png,jpg等图片文件&#xff0c;或者word&#xff0c;Excel等office文件异或是其他类型的二进…

Stable diffusion详细讲解

&#x1f33a;系列文章推荐&#x1f33a; 扩散模型系列文章正在持续的更新&#xff0c;更新节奏如下&#xff0c;先更新SD模型讲解&#xff0c;再更新相关的微调方法文章&#xff0c;敬请期待&#xff01;&#xff01;&#xff01;&#xff08;本文及其之前的文章均已更新&…

机器学习-37-对ML的思考之机器学习发展的三个阶段和驱动AI发展三驾马车的由来

文章目录 1 引言2 机器学习发展的三个阶段2.1 萌芽期(20世纪50年代)2.1.1 达特茅斯会议(人工智能诞生)2.1.2 机器学习名称的由来2.2 知识期(20世纪80年代)2.2.1 知识瓶颈问题2.2.2 机器学习顶级会议ICML2.2.3 Machine Learning创刊2.2.4 神经网络规则抽取2.3 算法期(20世纪90年…

SpringCloud篇(服务网关 - GateWay)

目录 一、简介 二、为什么需要网关 二、gateway快速入门 1. 创建gateway服务&#xff0c;引入依赖 2. 编写启动类 3. 编写基础配置和路由规则 4. 重启测试 5. 网关路由的流程图 6. 总结 三、断言工厂 四、过滤器工厂 1. 路由过滤器的种类 2. 请求头过滤器 3. 默认…

代码段数据段的划分

DPL DPL存储在段描述符中&#xff0c;规定访问该段的权限级别(Descriptor Privilege Level) CPL CPL是当前进程的权限级别(Current Privilege Level)&#xff0c;是当前正在指向的代码段所在段的成绩&#xff0c;也就是CS段的DPL RPL RPL说明的是进程对段访问的请求权限(Re…

HTML5+CSS前端开发【保姆级教学】+前端介绍和软件安装

学习了基础编程刚刚开始学习计算机的程序员&#xff0c;你是否会这样的想法:前端和后端是什么呢&#xff1f;如果你是刚上大学的大一大二基础小白&#xff0c;但是身边的卷王同学已经超前知道之后要从事前后端开发了&#xff0c;并且在学习各种框架的课程&#xff0c;Aahhahah,…

【Rabbitmq篇】RabbitMQ⾼级特性----消息确认

目录 前言&#xff1a; 一.消息确认机制 • ⾃动确认 • ⼿动确认 手动确认方法又分为三种&#xff1a; 二. 代码实现&#xff08;spring环境&#xff09; 配置相关信息&#xff1a; 1&#xff09;. AcknowledgeMode.NONE 2 &#xff09;AcknowledgeMode.AUTO 3&…

QT入门之下载、工程创建、学习方法

1.QT下载链接 因为我的是下载在LINUX上面&#xff0c;所以这里提供LINUX平台下的下载方式&#xff1a; wget http://download.qt.io/archive/qt/5.12/5.12.9/qt-opensource-linux-x64-5.12.9.run 赋予可执行权限&#xff0c;加上 sudo 权限进入安装&#xff0c;这样会安装在…

初识Linux—— 基本指令(上)

前言 Linux简述 ​ Linux是一种开源、自由、类UNIX的操作系统&#xff0c;由著名的芬兰程序员林纳斯托瓦兹&#xff08;Linus Torvalds&#xff09;于1991年首次发布。Linux的内核在GNU通用公共许可证&#xff08;GPL&#xff09;下发布&#xff0c;这意味着任何人都可以自由…