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

news2025/4/19 2:46:21

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。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Centos7安装Jenkins脚本一键部署

公司原先Jenkins二进制安装&#xff0c;自己闲来无事在测试主机优化了一下&#xff0c;一键部署&#xff0c;jenkins2.426版本jdk11版本 #!/bin/bashjenkins_file"jenkins-2.426.3-1.1.noarch.rpm"# 更新软件包列表 echo "更新软件包列表..." sudo yum up…

【WPF】Prism学习(五)

Prism Commands 1.错误处理&#xff08;Error Handling&#xff09; Prism 9 为所有的命令&#xff08;包含AsyncDelegateCommand&#xff09;提供了更好的错误处理。 避免用try/catch包装每一个方法根据不同遇到的异常类型来提供特定的逻辑处理可以在多个命令之间共享错误处…

Ubuntu 18.04 配置sources.list源文件(无法安全地用该源进行更新,所以默认禁用该源)

如果你 sudo apt update 时出现诸如 无法安全地用该源进行更新&#xff0c;所以默认禁用该源 的错误&#xff0c;那就换换源吧&#xff0c;链接&#xff1a; https://mirror.tuna.tsinghua.edu.cn/help/ubuntu/ 注意版本&#xff1a; 修改源文件&#xff1a; sudo nano /etc…

C++ —— 剑斩旧我 破茧成蝶—C++11

江河入海&#xff0c;知识涌动&#xff0c;这是我参与江海计划的第2篇。 目录 1. C11的发展历史 2. 列表初始化 2.1 C98传统的{} 2.2 C11中的{} 2.3 C11中的std::initializer_list 3. 右值引用和移动语义 3.1 左值和右值 3.2 左值引用和右值引用 3.3 引用延长生命周期…

04 - Clickhouse-21.7.3.14-2单机版安装

目录 一、准备工作 1、确定防火墙处于关闭状态 2、CentOS 取消打开文件数限制 3、安装依赖 4、CentOS取消SELINUX 二、单机安装 2.1、下载安装 2.2、安装这4个rpm包 2.3、修改配置文件 2.4、启动服务 2.5、关闭开机自启 2.6、使用Client连接server 一、准备工作 1…

STM32设计学生宿舍监测控制系统-分享

目录 前言 一、本设计主要实现哪些很“开门”功能&#xff1f; 二、电路设计原理图 电路图采用Altium Designer进行设计&#xff1a; 三、实物设计图 四、程序源代码设计 五、获取资料内容 前言 本项目旨在利用STM32单片机为核心&#xff0c;结合传感器技术、无线通信技…

macOS 的目录结构

文章目录 根目录 (/)常见目录及其用途示例目录结构注意事项根目录 (/)主要目录及其含义其他目录总结 macOS 的目录结构无论是在 Intel 架构还是 ARM 架构的 Mac 电脑上都是相同的。macOS 的目录结构遵循 Unix 和 BSD 的传统&#xff0c;具有许多标准目录。以下是一些主要目录及…

日常ctf

15&#xff0c; [MoeCTF 2021]Web安全入门指北—小饼干 直接改就行了 16&#xff0c; [MoeCTF 2021]2048 传入参数就获取到flag了 /flag.php?score500000000 17&#xff0c; [SWPUCTF 2022 新生赛]funny_web 账户密码是 NSS 2122693401 登录进去查看源码 考intval缺陷&…

【java】java入门

盘符名称冒号---------盘符切换 dir---------------查看当前路径下的内容 cd目录--------进入单级目录 cd..----------回退到上一级目录 cd \----------回退到盘符目录 cls----------清屏 exit 为什么要配环境变量&#xff1f; 在任意的目录下都可以打开指定的软件。把软件的路…

网络安全检测技术

一&#xff0c;网络安全漏洞 安全威胁是指所有能够对计算机网络信息系统的网络服务和网络信息的机密性&#xff0c;可用性和完整性产生阻碍&#xff0c;破坏或中断的各种因素。安全威胁可分为人为安全威胁和非人为安全威胁两大类。 1&#xff0c;网络安全漏洞威胁 漏洞分析的…

【大数据学习 | flume】flume的概述与组件的介绍

1. flume概述 Flume是cloudera(CDH版本的hadoop) 开发的一个分布式、可靠、高可用的海量日志收集系统。它将各个服务器中的数据收集起来并送到指定的地方去&#xff0c;比如说送到HDFS、Hbase&#xff0c;简单来说flume就是收集日志的。 Flume两个版本区别&#xff1a; ​ 1&…

如何高效实现汤臣倍健营销云数据集成到SQLServer

新版订单同步-&#xff08;Life-Space&#xff09;江油泰熙&#xff1a;汤臣倍健营销云数据集成到SQL Server 在企业信息化建设中&#xff0c;数据的高效集成和管理是提升业务运营效率的关键。本文将分享一个实际案例——如何通过新版订单同步方案&#xff0c;将汤臣倍健营销云…

Ubuntu22.04安装CH343驱动并创建udev规则

驱动说明 Linux系统提供CH34*系列 USB UART 设备配合使用的默认 CDC-ACM 驱动程序。驱动程序文件名为CDC-ACM。CDC-ACM 驱动程序控制特定设备的能力有限。此通用驱动程序不了解特定设备协议。因此&#xff0c;设备制造商可以创建能够访问设备特定功能集&#xff08;例如硬件流…

2.8 群辉 黑群晖 意味断电 抱歉,您所指定的页面不存在。

实验室组装的黑群晖施工时不小心被意味断电&#xff0c;然后出现了如下图&#xff1a; 对于7.1.1的系统来说&#xff0c;这个是由于libsynopkg.so.1和libsynoshare.so.7这两个文件出问题所致。 因此&#xff0c;解决方法也比较简单就是把好的文件恢复到/lib文件夹下即可。 这…

Flutter:key的作用原理(LocalKey ,GlobalKey)

第一段代码实现的内容&#xff1a;创建了3个块&#xff0c;随机3个颜色&#xff0c;每次点击按钮时&#xff0c;把第一个块删除 import dart:math; import package:flutter/material.dart; import package:flutter_one/demo.dart;void main() {runApp(const App()); }class App…

服务器上部署并启动 Go 语言框架 **GoZero** 的项目

要在服务器上部署并启动 Go 语言框架 **GoZero** 的项目&#xff0c;下面是一步步的操作指南&#xff1a; ### 1. 安装 Go 语言环境 首先&#xff0c;确保你的服务器上已安装 Go 语言。如果还没有安装&#xff0c;可以通过以下步骤进行安装&#xff1a; #### 1.1 安装 Go 语…

如何去掉el-input 中 type=“number“两侧的上下按键

<el-input v-model.trim"row.length" type"number" min"0" placeholder""></el-input> // 如何去掉el-input-number两侧的上下按键 ::v-deep input::-webkit-outer-spin-button, ::v-deep input::-webkit-inner-spin-butt…

前端注册代码

代码 <template><el-card class"register" style"max-width: 480px ; background-color: aliceblue;"><template #header><div class"card-header"><span>注册</span></div></template><el…

Node.js | Yarn下载安装与环境配置

一、安装Node.js Yarn 是 Node.js 下的包管理工具&#xff0c;因此想要使用 Yarn 就必须先下载 Node.js。 推荐参考&#xff1a;Node.js | npm下载安装及环境配置教程 二、Yarn安装 打开cmd&#xff0c;输入以下命令&#xff1a; npm install -g yarn检查是否安装成功&…

Golang | Leetcode Golang题解之第564题寻找最近的回文数

题目&#xff1a; 题解&#xff1a; func nearestPalindromic(n string) string {m : len(n)candidates : []int{int(math.Pow10(m-1)) - 1, int(math.Pow10(m)) 1}selfPrefix, _ : strconv.Atoi(n[:(m1)/2])for _, x : range []int{selfPrefix - 1, selfPrefix, selfPrefix …