A:增加“资料库”;增加模型注入
This commit is contained in:
1 parent
b8dc199cff
commit
592b01a89b
10 files changed
+250
-68
No files matched your search
@@ -0,0 +1,16 @@
|
|||||||
|
package container
|
||||||
|
|
||||||
|
import "rear/internal/repositories"
|
||||||
|
|
||||||
|
type Container struct {
|
||||||
|
LibraryRepo *repositories.LibraryRepository
|
||||||
|
UserRepo *repositories.UserService
|
||||||
|
// 其他服务...
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewContainer() *Container {
|
||||||
|
return &Container{
|
||||||
|
LibraryRepo: repositories.NewLibraryRepository(),
|
||||||
|
UserRepo: repositories.NewUserService(),
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,123 @@
|
|||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"rear/internal/container"
|
||||||
|
"rear/internal/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Handler struct {
|
||||||
|
container *container.Container
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewLibraryHandler(container *container.Container) *Handler {
|
||||||
|
return &Handler{container: container}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetLibrary 获取存储哭
|
||||||
|
func (h *Handler) GetLibrary(c *gin.Context) {
|
||||||
|
libraries, err := h.container.LibraryRepo.GetAllLibrary()
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Failed to get all libraries: %v", err)
|
||||||
|
c.JSON(http.StatusInternalServerError, model.Response{
|
||||||
|
Code: http.StatusInternalServerError,
|
||||||
|
Message: "Internal server error",
|
||||||
|
Data: nil,
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("Total libraries: %d", len(libraries))
|
||||||
|
c.JSON(http.StatusOK, model.Response{
|
||||||
|
Code: http.StatusOK,
|
||||||
|
Message: "Success",
|
||||||
|
Data: libraries,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *Handler) AddLibrary(c *gin.Context) {
|
||||||
|
var path string
|
||||||
|
if err := c.ShouldBindJSON(&path); err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, model.Response{
|
||||||
|
Code: http.StatusBadRequest,
|
||||||
|
Message: "Invalid request body",
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
library := &model.LibraryTable{
|
||||||
|
ImgPath: path,
|
||||||
|
IsEnable: true,
|
||||||
|
}
|
||||||
|
err := h.container.LibraryRepo.AddLibrary(library)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusOK, model.Response{
|
||||||
|
Code: http.StatusInternalServerError,
|
||||||
|
Message: err.Error(),
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, model.Response{
|
||||||
|
Code: http.StatusOK,
|
||||||
|
Message: "Success",
|
||||||
|
Data: nil,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
func (h *Handler) UpdateLibrary(c *gin.Context) {
|
||||||
|
var path string
|
||||||
|
if err := c.ShouldBindJSON(&path); err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, model.Response{
|
||||||
|
Code: http.StatusBadRequest,
|
||||||
|
Message: "Invalid request body",
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
library := &model.LibraryTable{
|
||||||
|
ImgPath: path,
|
||||||
|
IsEnable: true,
|
||||||
|
}
|
||||||
|
err := h.container.LibraryRepo.AddLibrary(library)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusOK, model.Response{
|
||||||
|
Code: http.StatusInternalServerError,
|
||||||
|
Message: err.Error(),
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, model.Response{
|
||||||
|
Code: http.StatusOK,
|
||||||
|
Message: "Success",
|
||||||
|
Data: nil,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
func (h *Handler) DeleteLibrary(c *gin.Context) {
|
||||||
|
var path string
|
||||||
|
if err := c.ShouldBindJSON(&path); err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, model.Response{
|
||||||
|
Code: http.StatusBadRequest,
|
||||||
|
Message: "Invalid request body",
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
library := &model.LibraryTable{
|
||||||
|
ImgPath: path,
|
||||||
|
IsEnable: true,
|
||||||
|
}
|
||||||
|
err := h.container.LibraryRepo.AddLibrary(library)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusOK, model.Response{
|
||||||
|
Code: http.StatusInternalServerError,
|
||||||
|
Message: err.Error(),
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, model.Response{
|
||||||
|
Code: http.StatusOK,
|
||||||
|
Message: "Success",
|
||||||
|
Data: nil,
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -7,9 +7,9 @@ import (
|
|||||||
|
|
||||||
// BaseModel 基础模型,包含通用字段
|
// BaseModel 基础模型,包含通用字段
|
||||||
type BaseModel struct {
|
type BaseModel struct {
|
||||||
ID uint `gorm:"primaryKey" json:"id"`
|
ID uint `gorm:"primaryKey" json:"id"`
|
||||||
CreatedAt time.Time `json:"created_at"`
|
CreatedAt time.Time `json:"created_at"`
|
||||||
UpdatedAt time.Time `json:"updated_at"`
|
UpdatedAt time.Time `json:"updated_at"`
|
||||||
|
// 软删除 【查询时会检测删除时间】
|
||||||
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
|
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
|
||||||
IsDeleted bool `json:"is_deleted"`
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
type LibraryTable struct {
|
||||||
|
BaseModel
|
||||||
|
// 照片存储库路径
|
||||||
|
ImgPath string `gorm:"not null;size:255" json:"imgPath"`
|
||||||
|
// 是否开启
|
||||||
|
IsEnable bool `gorm:"default:false;" json:"isEnable"`
|
||||||
|
}
|
||||||
@@ -1,29 +1,11 @@
|
|||||||
package model
|
package model
|
||||||
|
|
||||||
import "gorm.io/gorm"
|
|
||||||
|
|
||||||
type User struct {
|
type User struct {
|
||||||
BaseModel
|
BaseModel
|
||||||
Username string `gorm:"uniqueIndex;not null;size:50" json:"username"`
|
Username string `gorm:"uniqueIndex;not null;size:50" json:"username"`
|
||||||
Email string `gorm:"uniqueIndex;not null;size:100" json:"email"`
|
Email string `gorm:"uniqueIndex;not null;size:100" json:"email"`
|
||||||
|
// json:"-" - 序列化时忽略此字段(密码不会出现在JSON中)
|
||||||
Password string `gorm:"not null;size:255" json:"-"`
|
Password string `gorm:"not null;size:255" json:"-"`
|
||||||
Age int `gorm:"default:0" json:"age"`
|
Age int `gorm:"default:0" json:"age"`
|
||||||
Status int `gorm:"default:1;comment:1-active,0-inactive" json:"status"`
|
Status int `gorm:"default:1;comment:1-active,0-inactive" json:"status"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// TableName 指定表名
|
|
||||||
func (User) GetTableName() string {
|
|
||||||
return "users"
|
|
||||||
}
|
|
||||||
|
|
||||||
// BeforeCreate GORM钩子,创建前执行
|
|
||||||
func (u *User) BeforeCreate(tx *gorm.DB) error {
|
|
||||||
// 这里可以添加创建前的逻辑,比如密码加密
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// AfterCreate GORM钩子,创建后执行
|
|
||||||
func (u *User) AfterCreate(tx *gorm.DB) error {
|
|
||||||
// 这里可以添加创建后的逻辑
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@@ -18,6 +18,7 @@ type BaseService struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var baseService = &BaseService{
|
var baseService = &BaseService{
|
||||||
|
// 缓冲队列
|
||||||
writeQueue: make(chan WriteOperation, 1000),
|
writeQueue: make(chan WriteOperation, 1000),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -31,8 +32,8 @@ func InitBaseService() {
|
|||||||
// 处理写操作的协程
|
// 处理写操作的协程
|
||||||
func (s *BaseService) processWriteOperations() {
|
func (s *BaseService) processWriteOperations() {
|
||||||
for op := range s.writeQueue {
|
for op := range s.writeQueue {
|
||||||
err := op.Execute()
|
err := op.Execute() // 串行执行每个写操作
|
||||||
op.Response <- err
|
op.Response <- err // 将结果返回给调用者
|
||||||
close(op.Response)
|
close(op.Response)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -50,8 +51,8 @@ func ExecuteWrite(fn func() error) error {
|
|||||||
Response: make(chan error, 1),
|
Response: make(chan error, 1),
|
||||||
}
|
}
|
||||||
|
|
||||||
baseService.writeQueue <- op
|
baseService.writeQueue <- op // 将操作放入队列
|
||||||
return <-op.Response
|
return <-op.Response // 等待执行结果
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExecuteRead 执行读操作(可以并发)
|
// ExecuteRead 执行读操作(可以并发)
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
package repositories
|
||||||
|
|
||||||
|
import (
|
||||||
|
"rear/internal/db"
|
||||||
|
"rear/internal/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
type LibraryRepository struct{}
|
||||||
|
|
||||||
|
func NewLibraryRepository() *LibraryRepository {
|
||||||
|
return &LibraryRepository{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *LibraryRepository) AddLibrary(lib *model.LibraryTable) error {
|
||||||
|
var result model.LibraryTable
|
||||||
|
|
||||||
|
err := db.GetDB().Where("imgPath = ?", lib.ImgPath).FirstOrCreate(&result, lib).Error
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return ExecuteWrite(func() error {
|
||||||
|
// 如果找到了已存在的记录,更新 IsEnable
|
||||||
|
if result.ID != 0 && result.ImgPath == lib.ImgPath {
|
||||||
|
return db.GetDB().Model(&result).Update("isEnable", true).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
//return ExecuteWrite(func() error {
|
||||||
|
// return db.GetDB().Create(lib).Error
|
||||||
|
//})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *LibraryRepository) DeleteLibrary(imgPath string) error {
|
||||||
|
return ExecuteWrite(func() error {
|
||||||
|
return db.GetDB().Where("imgPath = ?", imgPath).Delete(&model.LibraryTable{}).Error
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *LibraryRepository) UpdateLibrary(oldImgPath string, newImgPath string) error {
|
||||||
|
return ExecuteWrite(func() error {
|
||||||
|
return db.GetDB().Where("imgPath = ?", oldImgPath).
|
||||||
|
Updates(&model.LibraryTable{ImgPath: newImgPath}).Error
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *LibraryRepository) GetAllLibrary() ([]model.LibraryTable, error) {
|
||||||
|
var library []model.LibraryTable
|
||||||
|
err := ExecuteRead(func() error {
|
||||||
|
return db.GetDB().Find(&library).Error
|
||||||
|
})
|
||||||
|
|
||||||
|
return library, err
|
||||||
|
}
|
||||||
@@ -30,6 +30,24 @@ func (s *UserService) UpdateUser(id uint, updates map[string]interface{}) error
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Model() 方法的作用
|
||||||
|
1. 指定操作的表和模型
|
||||||
|
2. 表名推断
|
||||||
|
|
||||||
|
✅ 正确写法1:使用 Model()
|
||||||
|
goreturn db.GetDB().Model(&model.User{}).
|
||||||
|
Where("id = ?", id).
|
||||||
|
Update("name", name).Error
|
||||||
|
✅ 正确写法2:直接使用结构体实例
|
||||||
|
goreturn db.GetDB().Where("id = ?", id).
|
||||||
|
Updates(&model.User{Name: name}).Error
|
||||||
|
✅ 正确写法3:使用 Table() 指定表名
|
||||||
|
goreturn db.GetDB().Table("users").
|
||||||
|
Where("id = ?", id).
|
||||||
|
Update("name", name).Error
|
||||||
|
*/
|
||||||
|
|
||||||
// 更新用户名称(写操作)
|
// 更新用户名称(写操作)
|
||||||
func (s *UserService) UpdateUserName(id uint, name string) error {
|
func (s *UserService) UpdateUserName(id uint, name string) error {
|
||||||
return ExecuteWrite(func() error {
|
return ExecuteWrite(func() error {
|
||||||
|
|||||||
@@ -2,17 +2,21 @@ package router
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"rear/internal/container"
|
||||||
"rear/internal/handler"
|
"rear/internal/handler"
|
||||||
)
|
)
|
||||||
|
|
||||||
// 设置路由
|
// SetupRoutes 设置路由
|
||||||
func SetupRoutes(r *gin.Engine) {
|
func SetupRoutes(r *gin.Engine, contain *container.Container) {
|
||||||
// 默认访问
|
// 默认访问
|
||||||
r.GET("/", handler.BasicResponse)
|
r.GET("/", handler.BasicResponse)
|
||||||
|
|
||||||
// 健康检查
|
// 健康检查
|
||||||
r.GET("/health", handler.HealthCheck)
|
r.GET("/health", handler.HealthCheck)
|
||||||
|
|
||||||
|
// 资料库处理
|
||||||
|
libraryHandler := handler.NewLibraryHandler(contain)
|
||||||
|
|
||||||
// API版本组
|
// API版本组
|
||||||
v1 := r.Group("/api/v1")
|
v1 := r.Group("/api/v1")
|
||||||
{
|
{
|
||||||
@@ -25,5 +29,13 @@ func SetupRoutes(r *gin.Engine) {
|
|||||||
users.PUT("/:id", handler.UpdateUser)
|
users.PUT("/:id", handler.UpdateUser)
|
||||||
users.DELETE("/:id", handler.DeleteUser)
|
users.DELETE("/:id", handler.DeleteUser)
|
||||||
}
|
}
|
||||||
|
// 存储库相关
|
||||||
|
library := v1.Group("/library")
|
||||||
|
{
|
||||||
|
library.GET("", libraryHandler.GetLibrary)
|
||||||
|
library.POST("", libraryHandler.AddLibrary)
|
||||||
|
library.PUT("/:path", libraryHandler.UpdateLibrary)
|
||||||
|
library.DELETE("/:path", libraryHandler.DeleteLibrary)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+6
-39
@@ -11,8 +11,8 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"rear/internal/config"
|
"rear/internal/config"
|
||||||
|
"rear/internal/container"
|
||||||
"rear/internal/db"
|
"rear/internal/db"
|
||||||
"rear/internal/model"
|
|
||||||
"rear/internal/repositories"
|
"rear/internal/repositories"
|
||||||
"rear/internal/router"
|
"rear/internal/router"
|
||||||
"rear/internal/service"
|
"rear/internal/service"
|
||||||
@@ -38,55 +38,22 @@ func main() {
|
|||||||
if err := db.AutoMigrate(); err != nil {
|
if err := db.AutoMigrate(); err != nil {
|
||||||
log.Fatal("Failed to migrate database:", err)
|
log.Fatal("Failed to migrate database:", err)
|
||||||
}
|
}
|
||||||
|
// 初始化容器【数据库存储容器】
|
||||||
|
newContainer := container.NewContainer()
|
||||||
|
|
||||||
// 初始化基础服务(启动写操作处理协程)
|
// 初始化基础服务(启动写操作处理协程)
|
||||||
repositories.InitBaseService()
|
repositories.InitBaseService()
|
||||||
|
|
||||||
// 使用示例
|
|
||||||
userService := repositories.NewUserService()
|
|
||||||
|
|
||||||
// 创建用户
|
|
||||||
user := &model.User{
|
|
||||||
Email: "john@example.com",
|
|
||||||
Username: "John Doe",
|
|
||||||
Age: 25,
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := userService.CreateUser(user); err != nil {
|
|
||||||
log.Printf("Failed to create user: %v", err)
|
|
||||||
} else {
|
|
||||||
log.Printf("User created successfully: %+v", user)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 更新用户名称
|
|
||||||
if err := userService.UpdateUserName(user.ID, "John Smith"); err != nil {
|
|
||||||
log.Printf("Failed to update user name: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查询用户(可以并发执行)
|
|
||||||
if foundUser, err := userService.GetUserByID(user.ID); err != nil {
|
|
||||||
log.Printf("Failed to get user: %v", err)
|
|
||||||
} else if foundUser != nil {
|
|
||||||
log.Printf("Found user: %+v", foundUser)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取所有用户
|
|
||||||
if users, err := userService.GetAllUsers(); err != nil {
|
|
||||||
log.Printf("Failed to get all users: %v", err)
|
|
||||||
} else {
|
|
||||||
log.Printf("Total users: %d", len(users))
|
|
||||||
}
|
|
||||||
|
|
||||||
//if err := initDatabase(); err != nil {
|
//if err := initDatabase(); err != nil {
|
||||||
// logger.Fatalf("Failed to initialize database: %v", err)
|
// logger.Fatalf("Failed to initialize database: %v", err)
|
||||||
//}
|
//}
|
||||||
// 依赖注入
|
// 依赖注入
|
||||||
|
|
||||||
// 启动 http
|
// 启动 http
|
||||||
startHttp()
|
startHttp(newContainer)
|
||||||
}
|
}
|
||||||
|
|
||||||
func startHttp() {
|
func startHttp(con *container.Container) {
|
||||||
// 配置加载
|
// 配置加载
|
||||||
netConfig := config.InitConfig()
|
netConfig := config.InitConfig()
|
||||||
// 设置Gin模式
|
// 设置Gin模式
|
||||||
@@ -114,7 +81,7 @@ func startHttp() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 设置路由
|
// 设置路由
|
||||||
router.SetupRoutes(r)
|
router.SetupRoutes(r, con)
|
||||||
|
|
||||||
// 创建HTTP服务器
|
// 创建HTTP服务器
|
||||||
srv := &http.Server{
|
srv := &http.Server{
|
||||||
|
|||||||
Reference in new issue
Block a user