Skip to content

1. 初始化目录结构

给 AI 提问: 我要做一个待办事项的应用。用 GO 写。请在当前文件目录下完善整个项目目录结构,并写好相关代码。

我来帮你创建一个基于 Go 的待办事项应用。我们将使用 Gin 框架作为 Web 服务器,GORM 作为 ORM,SQLite 作为数据库。

首先创建项目目录结构:

bash
mkdir d:\works\RD\todo-list\config
mkdir d:\works\RD\todo-list\controllers
mkdir d:\works\RD\todo-list\models
mkdir d:\works\RD\todo-list\routes
mkdir d:\works\RD\todo-list\services

然后初始化 Go 模块:

bash
cd d:\works\RD\todo-list
go mod init todo-list

现在让我们创建必要的文件和代码:

1. 主程序入口:

go
// :d:\works\RD\todo-list\main.go
package main

import (
	"log"
	"todo-list/config"
	"todo-list/routes"
)

func main() {
	// 初始化数据库
	db, err := config.InitDB()
	if err != nil {
		log.Fatal("数据库初始化失败:", err)
	}

	// 确保在main函数结束时关闭数据库连接
	sqlDB, err := db.DB()
	if err != nil {
		log.Fatal("获取数据库实例失败:", err)
	}
	defer sqlDB.Close()

	// 初始化路由
	r := routes.SetupRouter()

	// 启动服务器
	r.Run(":8080")
}

2. 数据库配置:

go
// :d:\works\RD\todo-list\config\database.go
package config

import (
	"todo-list/models"
	"gorm.io/driver/sqlite"
	"gorm.io/gorm"
)

func InitDB() (*gorm.DB, error) {
	db, err := gorm.Open(sqlite.Open("todo.db"), &gorm.Config{})
	if err != nil {
		return nil, err
	}

	// 自动迁移数据库结构
	err = db.AutoMigrate(&models.Todo{})
	if err != nil {
		return nil, err
	}

	return db, nil
}

3. 模型定义:

go
// :d:\works\RD\todo-list\models\todo.go
package models

import (
	"gorm.io/gorm"
	"time"
)

type Todo struct {
	gorm.Model
	Title       string    `json:"title"`
	Description string    `json:"description"`
	DueDate     time.Time `json:"due_date"`
	Completed   bool      `json:"completed"`
}

4. 控制器:

go
// :d:\works\RD\todo-list\controllers\todo_controller.go
package controllers

import (
	"github.com/gin-gonic/gin"
	"net/http"
	"todo-list/models"
	"gorm.io/gorm"
)

type TodoController struct {
	DB *gorm.DB
}

func NewTodoController(db *gorm.DB) *TodoController {
	return &TodoController{DB: db}
}

// 创建待办事项
func (tc *TodoController) Create(c *gin.Context) {
	var todo models.Todo
	if err := c.ShouldBindJSON(&todo); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	if err := tc.DB.Create(&todo).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "创建待办事项失败"})
		return
	}

	c.JSON(http.StatusOK, todo)
}

// 获取所有待办事项
func (tc *TodoController) GetAll(c *gin.Context) {
	var todos []models.Todo
	if err := tc.DB.Find(&todos).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "获取待办事项失败"})
		return
	}

	c.JSON(http.StatusOK, todos)
}

// 获取单个待办事项
func (tc *TodoController) GetOne(c *gin.Context) {
	id := c.Param("id")
	var todo models.Todo

	if err := tc.DB.First(&todo, id).Error; err != nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "待办事项不存在"})
		return
	}

	c.JSON(http.StatusOK, todo)
}

// 更新待办事项
func (tc *TodoController) Update(c *gin.Context) {
	id := c.Param("id")
	var todo models.Todo

	if err := tc.DB.First(&todo, id).Error; err != nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "待办事项不存在"})
		return
	}

	if err := c.ShouldBindJSON(&todo); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	if err := tc.DB.Save(&todo).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "更新待办事项失败"})
		return
	}

	c.JSON(http.StatusOK, todo)
}

// 删除待办事项
func (tc *TodoController) Delete(c *gin.Context) {
	id := c.Param("id")
	var todo models.Todo

	if err := tc.DB.First(&todo, id).Error; err != nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "待办事项不存在"})
		return
	}

	if err := tc.DB.Delete(&todo).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "删除待办事项失败"})
		return
	}

	c.JSON(http.StatusOK, gin.H{"message": "删除成功"})
}

5. 路由配置:

go
// :d:\works\RD\todo-list\routes\routes.go
package routes

import (
	"github.com/gin-gonic/gin"
	"todo-list/controllers"
	"todo-list/config"
)

func SetupRouter() *gin.Engine {
	r := gin.Default()

	// 获取数据库实例
	db, _ := config.InitDB()
	todoController := controllers.NewTodoController(db)

	// 设置路由
	v1 := r.Group("/api/v1")
	{
		todos := v1.Group("/todos")
		{
			todos.POST("/", todoController.Create)
			todos.GET("/", todoController.GetAll)
			todos.GET("/:id", todoController.GetOne)
			todos.PUT("/:id", todoController.Update)
			todos.DELETE("/:id", todoController.Delete)
		}
	}

	return r
}

最后,安装必要的依赖:

bash
cd d:\works\RD\todo-list
go get -u github.com/gin-gonic/gin
go get -u gorm.io/gorm
go get -u gorm.io/driver/sqlite

这个待办事项应用提供了以下功能:

  1. 创建待办事项
  2. 获取所有待办事项
  3. 获取单个待办事项
  4. 更新待办事项
  5. 删除待办事项

API 端点:

  • POST /api/v1/todos - 创建待办事项
  • GET /api/v1/todos - 获取所有待办事项
  • GET /api/v1/todos/:id - 获取单个待办事项
  • PUT /api/v1/todos/:id - 更新待办事项
  • DELETE /api/v1/todos/:id - 删除待办事项

运行应用

bash
cd d:\works\RD\todo-list
go run main.go

报错(详情见下文)

An image

服务器将在 http://localhost:8080 启动。你可以使用 Postman 或其他 API 测试工具来测试这些端点。