分解
This commit is contained in:
		
							
								
								
									
										26
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								README.md
									
									
									
									
									
								
							@@ -44,6 +44,21 @@ WS     | /api/{name}/{item_id}          | Websocket 連接對象
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
對象模型:
 | 
					對象模型:
 | 
				
			||||||
 | 
					```go
 | 
				
			||||||
 | 
					type Model struct {
 | 
				
			||||||
 | 
						ID           int      `json:"id"`
 | 
				
			||||||
 | 
						Name         string   `json:"name"`
 | 
				
			||||||
 | 
						Type         string   `json:"type"`          // (lora|ckp|hyper|ti)
 | 
				
			||||||
 | 
						TriggerWords string   `json:"trigger_words"` // 觸發詞
 | 
				
			||||||
 | 
						BaseModel    string   `json:"base_model"`    // (SD1.5|SD2)
 | 
				
			||||||
 | 
						ModelPath    string   `json:"model_path"`    // 模型路徑
 | 
				
			||||||
 | 
						Status       string   `json:"status"`        // (waiting|running|success|error)
 | 
				
			||||||
 | 
						Progress     int      `json:"progress"`      // (0-100)
 | 
				
			||||||
 | 
						Tags         []string `json:"tags"`
 | 
				
			||||||
 | 
						CreatedAt    string   `json:"created_at"`
 | 
				
			||||||
 | 
						UpdatedAt    string   `json:"updated_at"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
```javascript
 | 
					```javascript
 | 
				
			||||||
//// TODO
 | 
					//// TODO
 | 
				
			||||||
////训练专属模型模块
 | 
					////训练专属模型模块
 | 
				
			||||||
@@ -94,17 +109,6 @@ WS     | /api/{name}/{item_id}          | Websocket 連接對象
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Model 模型對象
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    id: 'xxxxx',     // 模型ID
 | 
					 | 
				
			||||||
    name: 'xxx',     // 模型名稱
 | 
					 | 
				
			||||||
    type: '',        // 模型類型(RoLa|SD2|SD1.5)
 | 
					 | 
				
			||||||
    status: 'xxx',   // 模型狀態(waiting|running|success|error)
 | 
					 | 
				
			||||||
    progress: 100,   // 訓練進度(0~100)
 | 
					 | 
				
			||||||
    createdAt: '',   // 創建時間
 | 
					 | 
				
			||||||
    updatedAt: '',   // 更新時間
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Task 任務對象
 | 
					// Task 任務對象
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    id: 'xxxxx',     // 任務ID
 | 
					    id: 'xxxxx',     // 任務ID
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -36,6 +36,9 @@ func init() {
 | 
				
			|||||||
		CREATE TABLE IF NOT EXISTS models(
 | 
							CREATE TABLE IF NOT EXISTS models(
 | 
				
			||||||
			id INTEGER PRIMARY KEY AUTOINCREMENT,
 | 
								id INTEGER PRIMARY KEY AUTOINCREMENT,
 | 
				
			||||||
			name TEXT,
 | 
								name TEXT,
 | 
				
			||||||
 | 
								type TEXT,
 | 
				
			||||||
 | 
								status TEXT,
 | 
				
			||||||
 | 
								progress INTEGER,
 | 
				
			||||||
			created_at TEXT,
 | 
								created_at TEXT,
 | 
				
			||||||
			updated_at TEXT
 | 
								updated_at TEXT
 | 
				
			||||||
		);
 | 
							);
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										349
									
								
								main.go
									
									
									
									
									
								
							
							
						
						
									
										349
									
								
								main.go
									
									
									
									
									
								
							@@ -8,6 +8,7 @@ import (
 | 
				
			|||||||
	"net/http"
 | 
						"net/http"
 | 
				
			||||||
	"runtime"
 | 
						"runtime"
 | 
				
			||||||
	"strconv"
 | 
						"strconv"
 | 
				
			||||||
 | 
						"text/template"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"main/models"
 | 
						"main/models"
 | 
				
			||||||
@@ -15,130 +16,244 @@ import (
 | 
				
			|||||||
	"github.com/gorilla/mux"
 | 
						"github.com/gorilla/mux"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func CreateObject(w http.ResponseWriter, r *http.Request) {
 | 
					 | 
				
			||||||
	defer LogComponent(time.Now().UnixNano(), r) // 最后打印日志
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// 從body中獲取收到的JSON數據
 | 
					 | 
				
			||||||
	body, err := ioutil.ReadAll(r.Body)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		log.Println(err)
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	defer r.Body.Close()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// 將JSON數據轉換成目標對象
 | 
					 | 
				
			||||||
	object := models.GetObject(mux.Vars(r)["name"], 0)
 | 
					 | 
				
			||||||
	if err = json.Unmarshal(body, object); err != nil {
 | 
					 | 
				
			||||||
		log.Println(err)
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// 將對象存入數據庫
 | 
					 | 
				
			||||||
	err = object.Create()
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		log.Println(err)
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// 返回結果
 | 
					 | 
				
			||||||
	w.Header().Set("Content-Type", "application/json; charset=utf-8")
 | 
					 | 
				
			||||||
	w.Write(object.ToJSON())
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func GetObjetc(w http.ResponseWriter, r *http.Request) {
 | 
					 | 
				
			||||||
	defer LogComponent(time.Now().UnixNano(), r) // 最后打印日志
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// 獲取對象
 | 
					 | 
				
			||||||
	object := models.GetObject(mux.Vars(r)["name"], ParamInt(mux.Vars(r)["id"], 0))
 | 
					 | 
				
			||||||
	err := object.Get()
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		log.Println(err)
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// 返回結果
 | 
					 | 
				
			||||||
	w.Header().Set("Content-Type", "application/json; charset=utf-8")
 | 
					 | 
				
			||||||
	w.Write(object.ToJSON())
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func UpdateObject(w http.ResponseWriter, r *http.Request) {
 | 
					 | 
				
			||||||
	defer LogComponent(time.Now().UnixNano(), r) // 最后打印日志
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// 從body中獲取收到的JSON數據
 | 
					 | 
				
			||||||
	body, err := ioutil.ReadAll(r.Body)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		log.Println(err)
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	defer r.Body.Close()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// 將JSON數據轉換成目標對象
 | 
					 | 
				
			||||||
	object := models.GetObject(mux.Vars(r)["name"], ParamInt(mux.Vars(r)["id"], 0))
 | 
					 | 
				
			||||||
	if err = json.Unmarshal(body, object); err != nil {
 | 
					 | 
				
			||||||
		log.Println(err)
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// 更新對象
 | 
					 | 
				
			||||||
	err = object.Update()
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		log.Println(err)
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// 返回結果
 | 
					 | 
				
			||||||
	w.Header().Set("Content-Type", "application/json; charset=utf-8")
 | 
					 | 
				
			||||||
	w.Write(object.ToJSON())
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func DeleteObject(w http.ResponseWriter, r *http.Request) {
 | 
					 | 
				
			||||||
	defer LogComponent(time.Now().UnixNano(), r) // 最后打印日志
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// 刪除對象
 | 
					 | 
				
			||||||
	object := models.GetObject(mux.Vars(r)["name"], ParamInt(mux.Vars(r)["id"], 0))
 | 
					 | 
				
			||||||
	err := object.Delete()
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		log.Println(err)
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// 返回結果
 | 
					 | 
				
			||||||
	w.Header().Set("Content-Type", "application/json; charset=utf-8")
 | 
					 | 
				
			||||||
	w.Write(object.ToJSON())
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func GetObjects(w http.ResponseWriter, r *http.Request) {
 | 
					 | 
				
			||||||
	defer LogComponent(time.Now().UnixNano(), r) // 最后打印日志
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	var listview models.ListView
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// 獲取查詢參數: page, pageSize
 | 
					 | 
				
			||||||
	name := mux.Vars(r)["name"]
 | 
					 | 
				
			||||||
	page := ParamInt(r.URL.Query().Get("page"), 1)
 | 
					 | 
				
			||||||
	pagesize := ParamInt(r.URL.Query().Get("pageSize"), 10)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// 獲取對象列表
 | 
					 | 
				
			||||||
	listview.Read(name, page, pagesize)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// 返回結果
 | 
					 | 
				
			||||||
	w.Header().Set("Content-Type", "application/json; charset=utf-8")
 | 
					 | 
				
			||||||
	w.Write(listview.ToJSON())
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func main() {
 | 
					func main() {
 | 
				
			||||||
	runtime.GOMAXPROCS(runtime.NumCPU())
 | 
						runtime.GOMAXPROCS(runtime.NumCPU())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	r := mux.NewRouter()
 | 
						r := mux.NewRouter()
 | 
				
			||||||
	r.HandleFunc("/api/{name}", GetObjects).Methods("GET")
 | 
						r.Use(middleware)
 | 
				
			||||||
	r.HandleFunc("/api/{name}", CreateObject).Methods("POST")
 | 
						r.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
 | 
				
			||||||
	r.HandleFunc("/api/{name}/{id}", GetObjetc).Methods("GET")
 | 
							t, _ := template.ParseFiles("templates/index.html")
 | 
				
			||||||
	r.HandleFunc("/api/{name}/{id}", UpdateObject).Methods("PATCH")
 | 
							t.Execute(w, nil)
 | 
				
			||||||
	r.HandleFunc("/api/{name}/{id}", DeleteObject).Methods("DELETE")
 | 
						})
 | 
				
			||||||
 | 
						r.HandleFunc("/api/models", models_get).Methods("GET")
 | 
				
			||||||
 | 
						r.HandleFunc("/api/models", models_post).Methods("POST")
 | 
				
			||||||
 | 
						r.HandleFunc("/api/models/{id}", models_item_get).Methods("GET")
 | 
				
			||||||
 | 
						r.HandleFunc("/api/models/{id}", models_item_patch).Methods("PATCH")
 | 
				
			||||||
 | 
						r.HandleFunc("/api/models/{id}", models_item_delete).Methods("DELETE")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						r.HandleFunc("/api/images", images_get).Methods("GET")
 | 
				
			||||||
 | 
						r.HandleFunc("/api/images", images_post).Methods("POST")
 | 
				
			||||||
 | 
						r.HandleFunc("/api/images/{id}", images_item_get).Methods("GET")
 | 
				
			||||||
 | 
						r.HandleFunc("/api/images/{id}", images_item_patch).Methods("PATCH")
 | 
				
			||||||
 | 
						r.HandleFunc("/api/images/{id}", images_item_delete).Methods("DELETE")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						r.HandleFunc("/api/tasks", tasks_get).Methods("GET")
 | 
				
			||||||
 | 
						r.HandleFunc("/api/tasks", tasks_post).Methods("POST")
 | 
				
			||||||
 | 
						r.HandleFunc("/api/tasks/{id}", tasks_item_get).Methods("GET")
 | 
				
			||||||
 | 
						r.HandleFunc("/api/tasks/{id}", tasks_item_patch).Methods("PATCH")
 | 
				
			||||||
 | 
						r.HandleFunc("/api/tasks/{id}", tasks_item_delete).Methods("DELETE")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	log.Println("Web Server is running on http://localhost:8080")
 | 
						log.Println("Web Server is running on http://localhost:8080")
 | 
				
			||||||
	http.ListenAndServe(":8080", r)
 | 
						http.ListenAndServe(":8080", r)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func models_get(w http.ResponseWriter, r *http.Request) {
 | 
				
			||||||
 | 
						var listview models.ListView
 | 
				
			||||||
 | 
						listview.Page = ParamInt(r.URL.Query().Get("page"), 1)
 | 
				
			||||||
 | 
						listview.PageSize = ParamInt(r.URL.Query().Get("pageSize"), 10)
 | 
				
			||||||
 | 
						listview.List = models.QueryModels(listview.Page, listview.PageSize)
 | 
				
			||||||
 | 
						fmt.Println(listview.List)
 | 
				
			||||||
 | 
						listview.Total = models.CountModels()
 | 
				
			||||||
 | 
						listview.Next = listview.Page*listview.PageSize < listview.Total
 | 
				
			||||||
 | 
						w.Header().Set("Content-Type", "application/json; charset=utf-8")
 | 
				
			||||||
 | 
						w.Write(listview.ToJSON())
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func models_post(w http.ResponseWriter, r *http.Request) {
 | 
				
			||||||
 | 
						var model models.Model
 | 
				
			||||||
 | 
						body, err := ioutil.ReadAll(r.Body)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer r.Body.Close()
 | 
				
			||||||
 | 
						if err = json.Unmarshal(body, &model); err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						model.Create()
 | 
				
			||||||
 | 
						w.Header().Set("Content-Type", "application/json; charset=utf-8")
 | 
				
			||||||
 | 
						w.Write(ToJSON(model))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func models_item_get(w http.ResponseWriter, r *http.Request) {
 | 
				
			||||||
 | 
						model := models.Model{ID: ParamInt(mux.Vars(r)["id"], 0)}
 | 
				
			||||||
 | 
						model.Get()
 | 
				
			||||||
 | 
						w.Header().Set("Content-Type", "application/json; charset=utf-8")
 | 
				
			||||||
 | 
						w.Write(ToJSON(model))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func models_item_patch(w http.ResponseWriter, r *http.Request) {
 | 
				
			||||||
 | 
						model := models.Model{}
 | 
				
			||||||
 | 
						body, err := ioutil.ReadAll(r.Body)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer r.Body.Close()
 | 
				
			||||||
 | 
						if err = json.Unmarshal(body, &model); err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						model.ID = ParamInt(mux.Vars(r)["id"], 0)
 | 
				
			||||||
 | 
						model.Update()
 | 
				
			||||||
 | 
						w.Header().Set("Content-Type", "application/json; charset=utf-8")
 | 
				
			||||||
 | 
						w.Write(ToJSON(model))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func models_item_delete(w http.ResponseWriter, r *http.Request) {
 | 
				
			||||||
 | 
						model := models.Model{ID: ParamInt(mux.Vars(r)["id"], 0)}
 | 
				
			||||||
 | 
						model.Delete()
 | 
				
			||||||
 | 
						w.Header().Set("Content-Type", "application/json; charset=utf-8")
 | 
				
			||||||
 | 
						w.Write(ToJSON(model))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func images_get(w http.ResponseWriter, r *http.Request) {
 | 
				
			||||||
 | 
						var listview models.ListView
 | 
				
			||||||
 | 
						listview.Page = ParamInt(r.URL.Query().Get("page"), 1)
 | 
				
			||||||
 | 
						listview.PageSize = ParamInt(r.URL.Query().Get("pageSize"), 10)
 | 
				
			||||||
 | 
						listview.List = models.QueryImages(listview.Page, listview.PageSize)
 | 
				
			||||||
 | 
						listview.Total = models.CountImages()
 | 
				
			||||||
 | 
						listview.Next = listview.Page*listview.PageSize < listview.Total
 | 
				
			||||||
 | 
						w.Header().Set("Content-Type", "application/json; charset=utf-8")
 | 
				
			||||||
 | 
						w.Write(ToJSON(listview))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func images_post(w http.ResponseWriter, r *http.Request) {
 | 
				
			||||||
 | 
						var image models.Image
 | 
				
			||||||
 | 
						body, err := ioutil.ReadAll(r.Body)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer r.Body.Close()
 | 
				
			||||||
 | 
						if err = json.Unmarshal(body, &image); err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						image.Create()
 | 
				
			||||||
 | 
						w.Header().Set("Content-Type", "application/json; charset=utf-8")
 | 
				
			||||||
 | 
						w.Write(ToJSON(image))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func images_item_get(w http.ResponseWriter, r *http.Request) {
 | 
				
			||||||
 | 
						image := models.Image{ID: ParamInt(mux.Vars(r)["id"], 0)}
 | 
				
			||||||
 | 
						image.Get()
 | 
				
			||||||
 | 
						w.Header().Set("Content-Type", "application/json; charset=utf-8")
 | 
				
			||||||
 | 
						w.Write(ToJSON(image))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func images_item_patch(w http.ResponseWriter, r *http.Request) {
 | 
				
			||||||
 | 
						image := models.Image{}
 | 
				
			||||||
 | 
						body, err := ioutil.ReadAll(r.Body)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer r.Body.Close()
 | 
				
			||||||
 | 
						if err = json.Unmarshal(body, &image); err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						image.ID = ParamInt(mux.Vars(r)["id"], 0)
 | 
				
			||||||
 | 
						image.Update()
 | 
				
			||||||
 | 
						w.Header().Set("Content-Type", "application/json; charset=utf-8")
 | 
				
			||||||
 | 
						w.Write(ToJSON(image))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func images_item_delete(w http.ResponseWriter, r *http.Request) {
 | 
				
			||||||
 | 
						image := models.Image{ID: ParamInt(mux.Vars(r)["id"], 0)}
 | 
				
			||||||
 | 
						image.Delete()
 | 
				
			||||||
 | 
						w.Header().Set("Content-Type", "application/json; charset=utf-8")
 | 
				
			||||||
 | 
						w.Write(ToJSON(image))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func tasks_get(w http.ResponseWriter, r *http.Request) {
 | 
				
			||||||
 | 
						var listview models.ListView
 | 
				
			||||||
 | 
						listview.Page = ParamInt(r.URL.Query().Get("page"), 1)
 | 
				
			||||||
 | 
						listview.PageSize = ParamInt(r.URL.Query().Get("pageSize"), 10)
 | 
				
			||||||
 | 
						listview.List = models.QueryTasks(listview.Page, listview.PageSize)
 | 
				
			||||||
 | 
						listview.Total = models.CountTasks()
 | 
				
			||||||
 | 
						listview.Next = listview.Page*listview.PageSize < listview.Total
 | 
				
			||||||
 | 
						w.Header().Set("Content-Type", "application/json; charset=utf-8")
 | 
				
			||||||
 | 
						w.Write(ToJSON(listview))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func tasks_post(w http.ResponseWriter, r *http.Request) {
 | 
				
			||||||
 | 
						var task models.Task
 | 
				
			||||||
 | 
						body, err := ioutil.ReadAll(r.Body)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer r.Body.Close()
 | 
				
			||||||
 | 
						if err = json.Unmarshal(body, &task); err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						task.Create()
 | 
				
			||||||
 | 
						w.Header().Set("Content-Type", "application/json; charset=utf-8")
 | 
				
			||||||
 | 
						w.Write(ToJSON(task))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func tasks_item_get(w http.ResponseWriter, r *http.Request) {
 | 
				
			||||||
 | 
						task := models.Task{ID: ParamInt(mux.Vars(r)["id"], 0)}
 | 
				
			||||||
 | 
						task.Get()
 | 
				
			||||||
 | 
						w.Header().Set("Content-Type", "application/json; charset=utf-8")
 | 
				
			||||||
 | 
						w.Write(ToJSON(task))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func tasks_item_patch(w http.ResponseWriter, r *http.Request) {
 | 
				
			||||||
 | 
						task := models.Task{}
 | 
				
			||||||
 | 
						body, err := ioutil.ReadAll(r.Body)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer r.Body.Close()
 | 
				
			||||||
 | 
						if err = json.Unmarshal(body, &task); err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						task.ID = ParamInt(mux.Vars(r)["id"], 0)
 | 
				
			||||||
 | 
						task.Update()
 | 
				
			||||||
 | 
						w.Header().Set("Content-Type", "application/json; charset=utf-8")
 | 
				
			||||||
 | 
						w.Write(ToJSON(task))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func tasks_item_delete(w http.ResponseWriter, r *http.Request) {
 | 
				
			||||||
 | 
						task := models.Task{ID: ParamInt(mux.Vars(r)["id"], 0)}
 | 
				
			||||||
 | 
						task.Delete()
 | 
				
			||||||
 | 
						w.Header().Set("Content-Type", "application/json; charset=utf-8")
 | 
				
			||||||
 | 
						w.Write(ToJSON(task))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 中間件, 通用
 | 
				
			||||||
 | 
					func middleware(next http.Handler) http.Handler {
 | 
				
			||||||
 | 
						return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 | 
				
			||||||
 | 
							defer LogComponent(time.Now().UnixNano(), r) // 最后打印日志
 | 
				
			||||||
 | 
							// 處理跨域請求
 | 
				
			||||||
 | 
							w.Header().Set("Access-Control-Allow-Origin", "*")
 | 
				
			||||||
 | 
							w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization, X-Requested-With")
 | 
				
			||||||
 | 
							w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, PATCH, DELETE, OPTIONS")
 | 
				
			||||||
 | 
							// 處理OPTIONS請求
 | 
				
			||||||
 | 
							if r.Method == "OPTIONS" {
 | 
				
			||||||
 | 
								w.WriteHeader(http.StatusOK)
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							next.ServeHTTP(w, r)
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func ToJSON(object interface{}) []byte {
 | 
				
			||||||
 | 
						json, err := json.MarshalIndent(object, "", "  ")
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return []byte{}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return json
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func LogComponent(startTime int64, r *http.Request) {
 | 
					func LogComponent(startTime int64, r *http.Request) {
 | 
				
			||||||
	ms := (time.Now().UnixNano() - startTime) / 1000000
 | 
						ms := (time.Now().UnixNano() - startTime) / 1000000
 | 
				
			||||||
	color := "\033[1;32m%d\033[0m"
 | 
						color := "\033[1;32m%d\033[0m"
 | 
				
			||||||
@@ -162,11 +277,11 @@ func LogComponent(startTime int64, r *http.Request) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 獲取查詢參數(int 類型)
 | 
					// 獲取查詢參數(int 類型)
 | 
				
			||||||
func ParamInt(value string, defaultValue int64) int64 {
 | 
					func ParamInt(value string, defaultValue int) int {
 | 
				
			||||||
	if value == "" {
 | 
						if value == "" {
 | 
				
			||||||
		return defaultValue
 | 
							return defaultValue
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	result, err := strconv.ParseInt(value, 10, 64)
 | 
						result, err := strconv.Atoi(value)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return defaultValue
 | 
							return defaultValue
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										136
									
								
								models/Image.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										136
									
								
								models/Image.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,136 @@
 | 
				
			|||||||
 | 
					package models
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"log"
 | 
				
			||||||
 | 
						"main/configs"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Image struct {
 | 
				
			||||||
 | 
						ID        int    `json:"id"`
 | 
				
			||||||
 | 
						Name      string `json:"name"`
 | 
				
			||||||
 | 
						CreatedAt string `json:"created_at"`
 | 
				
			||||||
 | 
						UpdatedAt string `json:"updated_at"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (image *Image) Create() error {
 | 
				
			||||||
 | 
						db, err := configs.GetDB()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer db.Close()
 | 
				
			||||||
 | 
						stmt, err := db.Prepare("INSERT INTO images(name, created_at, updated_at) values(?, ?, ?)")
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer stmt.Close()
 | 
				
			||||||
 | 
						result, err := stmt.Exec(image.Name, image.CreatedAt, image.UpdatedAt)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						id, err := result.LastInsertId()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						image.ID = int(id)
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (image *Image) Delete() error {
 | 
				
			||||||
 | 
						db, err := configs.GetDB()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer db.Close()
 | 
				
			||||||
 | 
						stmt, err := db.Prepare("DELETE FROM images WHERE id = ?")
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer stmt.Close()
 | 
				
			||||||
 | 
						_, err = stmt.Exec(image.ID)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (image *Image) Update() error {
 | 
				
			||||||
 | 
						db, err := configs.GetDB()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer db.Close()
 | 
				
			||||||
 | 
						stmt, err := db.Prepare("UPDATE images SET name = ?, updated_at = ? WHERE id = ?")
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer stmt.Close()
 | 
				
			||||||
 | 
						_, err = stmt.Exec(image.Name, image.UpdatedAt, image.ID)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (image *Image) Get() error {
 | 
				
			||||||
 | 
						db, err := configs.GetDB()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer db.Close()
 | 
				
			||||||
 | 
						err = db.QueryRow("SELECT id, name, created_at, updated_at FROM images WHERE id = ?", image.ID).Scan(&image.ID, &image.Name, &image.CreatedAt, &image.UpdatedAt)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func QueryImages(page int, pagesize int) (images []interface{}) {
 | 
				
			||||||
 | 
						db, err := configs.GetDB()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer db.Close()
 | 
				
			||||||
 | 
						rows, err := db.Query("SELECT id, name, created_at, updated_at FROM images LIMIT ?, ?", (page-1)*pagesize, pagesize)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer rows.Close()
 | 
				
			||||||
 | 
						for rows.Next() {
 | 
				
			||||||
 | 
							image := Image{}
 | 
				
			||||||
 | 
							err := rows.Scan(&image.ID, &image.Name, &image.CreatedAt, &image.UpdatedAt)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								log.Println(err)
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							images = append(images, image)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func CountImages() (count int) {
 | 
				
			||||||
 | 
						db, err := configs.GetDB()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer db.Close()
 | 
				
			||||||
 | 
						err = db.QueryRow("SELECT COUNT(*) FROM images").Scan(&count)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -3,14 +3,13 @@ package models
 | 
				
			|||||||
import (
 | 
					import (
 | 
				
			||||||
	"encoding/json"
 | 
						"encoding/json"
 | 
				
			||||||
	"log"
 | 
						"log"
 | 
				
			||||||
	"main/configs"
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type ListView struct {
 | 
					type ListView struct {
 | 
				
			||||||
	Code     int64         `json:"code"`
 | 
						Code     int           `json:"code"`
 | 
				
			||||||
	Page     int64         `json:"page"`
 | 
						Page     int           `json:"page"`
 | 
				
			||||||
	PageSize int64         `json:"page_size"`
 | 
						PageSize int           `json:"page_size"`
 | 
				
			||||||
	Total    int64         `json:"total"`
 | 
						Total    int           `json:"total"`
 | 
				
			||||||
	Next     bool          `json:"next"`
 | 
						Next     bool          `json:"next"`
 | 
				
			||||||
	List     []interface{} `json:"list"`
 | 
						List     []interface{} `json:"list"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -32,292 +31,72 @@ func (listview *ListView) ToJSON() []byte {
 | 
				
			|||||||
	return b
 | 
						return b
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 查詢數據(分頁, 每頁數量, 排序, 條件, 關聯, 獲取總數)
 | 
					//// 查詢數據(分頁, 每頁數量, 排序, 條件, 關聯, 獲取總數)
 | 
				
			||||||
func (listview *ListView) Read(name string, page int64, page_size int64) error {
 | 
					//func (listview *ListView) Read(name string, page int64, page_size int64) error {
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
	// 獲取數據庫連接
 | 
					//	// 獲取數據庫連接
 | 
				
			||||||
	db, err := configs.GetDB()
 | 
					//	db, err := configs.GetDB()
 | 
				
			||||||
	if err != nil {
 | 
					//	if err != nil {
 | 
				
			||||||
		log.Println(err)
 | 
					//		log.Println(err)
 | 
				
			||||||
		return err
 | 
					//		return err
 | 
				
			||||||
	}
 | 
					//	}
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
	// 獲取總數
 | 
					//	// 獲取總數
 | 
				
			||||||
	var total int64
 | 
					//	var total int64
 | 
				
			||||||
	err = db.QueryRow("SELECT COUNT(*) FROM " + name).Scan(&total)
 | 
					//	err = db.QueryRow("SELECT COUNT(*) FROM " + name).Scan(&total)
 | 
				
			||||||
	if err != nil {
 | 
					//	if err != nil {
 | 
				
			||||||
		log.Println(err)
 | 
					//		log.Println(err)
 | 
				
			||||||
		return err
 | 
					//		return err
 | 
				
			||||||
	}
 | 
					//	}
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
	// 獲取數據
 | 
					//	// 獲取數據
 | 
				
			||||||
	rows, err := db.Query("SELECT * FROM "+name+" LIMIT ?, ?", (page-1)*page_size, page_size)
 | 
					//	rows, err := db.Query("SELECT * FROM "+name+" LIMIT ?, ?", (page-1)*page_size, page_size)
 | 
				
			||||||
	if err != nil {
 | 
					//	if err != nil {
 | 
				
			||||||
		log.Println(err)
 | 
					//		log.Println(err)
 | 
				
			||||||
		return err
 | 
					//		return err
 | 
				
			||||||
	}
 | 
					//	}
 | 
				
			||||||
	defer rows.Close()
 | 
					//	defer rows.Close()
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
	// 將數據轉換成對象
 | 
					//	// 將數據轉換成對象
 | 
				
			||||||
	switch name {
 | 
					//	switch name {
 | 
				
			||||||
	case "images":
 | 
					//	case "images":
 | 
				
			||||||
		for rows.Next() {
 | 
					//		for rows.Next() {
 | 
				
			||||||
			var image Image
 | 
					//			var image Image
 | 
				
			||||||
			err = rows.Scan(&image.ID, &image.Name, &image.CreatedAt, &image.UpdatedAt)
 | 
					//			err = rows.Scan(&image.ID, &image.Name, &image.CreatedAt, &image.UpdatedAt)
 | 
				
			||||||
			if err != nil {
 | 
					//			if err != nil {
 | 
				
			||||||
				log.Println(err)
 | 
					//				log.Println(err)
 | 
				
			||||||
				return err
 | 
					//				return err
 | 
				
			||||||
			}
 | 
					//			}
 | 
				
			||||||
			listview.List = append(listview.List, image)
 | 
					//			listview.List = append(listview.List, image)
 | 
				
			||||||
		}
 | 
					//		}
 | 
				
			||||||
	case "models":
 | 
					//	case "models":
 | 
				
			||||||
		for rows.Next() {
 | 
					//		for rows.Next() {
 | 
				
			||||||
			var model Model
 | 
					//			var model Model
 | 
				
			||||||
			err = rows.Scan(&model.ID, &model.Name, &model.CreatedAt, &model.UpdatedAt)
 | 
					//			err = rows.Scan(&model.ID, &model.Name, &model.CreatedAt, &model.UpdatedAt)
 | 
				
			||||||
			if err != nil {
 | 
					//			if err != nil {
 | 
				
			||||||
				log.Println(err)
 | 
					//				log.Println(err)
 | 
				
			||||||
				return err
 | 
					//				return err
 | 
				
			||||||
			}
 | 
					//			}
 | 
				
			||||||
			listview.List = append(listview.List, model)
 | 
					//			listview.List = append(listview.List, model)
 | 
				
			||||||
		}
 | 
					//		}
 | 
				
			||||||
	default:
 | 
					//	default:
 | 
				
			||||||
		for rows.Next() {
 | 
					//		for rows.Next() {
 | 
				
			||||||
			var object Object
 | 
					//			var object Object
 | 
				
			||||||
			err = rows.Scan(&object.ID, &object.Name, &object.CreatedAt, &object.UpdatedAt)
 | 
					//			err = rows.Scan(&object.ID, &object.Name, &object.CreatedAt, &object.UpdatedAt)
 | 
				
			||||||
			if err != nil {
 | 
					//			if err != nil {
 | 
				
			||||||
				log.Println(err)
 | 
					//				log.Println(err)
 | 
				
			||||||
				return err
 | 
					//				return err
 | 
				
			||||||
			}
 | 
					//			}
 | 
				
			||||||
			listview.List = append(listview.List, object)
 | 
					//			listview.List = append(listview.List, object)
 | 
				
			||||||
		}
 | 
					//		}
 | 
				
			||||||
	}
 | 
					//	}
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
	// 設置返回值
 | 
					//	// 設置返回值
 | 
				
			||||||
	listview.Code = 0
 | 
					//	listview.Code = 0
 | 
				
			||||||
	listview.Page = page
 | 
					//	listview.Page = page
 | 
				
			||||||
	listview.PageSize = page_size
 | 
					//	listview.PageSize = page_size
 | 
				
			||||||
	listview.Total = total
 | 
					//	listview.Total = total
 | 
				
			||||||
	listview.Next = total > page*page_size
 | 
					//	listview.Next = total > page*page_size
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
	return nil
 | 
					//	return nil
 | 
				
			||||||
}
 | 
					//}
 | 
				
			||||||
 | 
					 | 
				
			||||||
type Object struct {
 | 
					 | 
				
			||||||
	ID        int64  `json:"id"`
 | 
					 | 
				
			||||||
	Name      string `json:"name"`
 | 
					 | 
				
			||||||
	CreatedAt string `json:"created_at"`
 | 
					 | 
				
			||||||
	UpdatedAt string `json:"updated_at"`
 | 
					 | 
				
			||||||
	tablename string
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type Image struct {
 | 
					 | 
				
			||||||
	Object
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type Model struct {
 | 
					 | 
				
			||||||
	Object
 | 
					 | 
				
			||||||
	Type string `json:"type"`
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type Tag struct {
 | 
					 | 
				
			||||||
	Object
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type User struct {
 | 
					 | 
				
			||||||
	Object
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type Task struct {
 | 
					 | 
				
			||||||
	Object
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type ObjectInterface interface {
 | 
					 | 
				
			||||||
	Create() error
 | 
					 | 
				
			||||||
	Delete() error
 | 
					 | 
				
			||||||
	Update() error
 | 
					 | 
				
			||||||
	Get() error
 | 
					 | 
				
			||||||
	GetAll() ([]Object, error)
 | 
					 | 
				
			||||||
	GetPage(page int64, page_size int64) (ListView, error)
 | 
					 | 
				
			||||||
	ToJSON() []byte
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// 按照名稱返回響應的對象類型
 | 
					 | 
				
			||||||
func GetObject(name string, id int64) ObjectInterface {
 | 
					 | 
				
			||||||
	switch name {
 | 
					 | 
				
			||||||
	case "images":
 | 
					 | 
				
			||||||
		return &Image{
 | 
					 | 
				
			||||||
			Object{tablename: name, ID: id},
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		return &Object{tablename: name, ID: id}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// 創建對象
 | 
					 | 
				
			||||||
func (d *Object) Create() error {
 | 
					 | 
				
			||||||
	db, err := configs.GetDB()
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		log.Println(err)
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	stmt, err := db.Prepare("INSERT INTO " + d.tablename + "(name, created_at, updated_at) values(?, ?, ?)")
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		log.Println(err)
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	defer stmt.Close()
 | 
					 | 
				
			||||||
	result, err := stmt.Exec(d.Name, d.CreatedAt, d.UpdatedAt)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		log.Println(err)
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	id, err := result.LastInsertId()
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	d.ID = id
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// 刪除對象
 | 
					 | 
				
			||||||
func (d *Object) Delete() error {
 | 
					 | 
				
			||||||
	db, err := configs.GetDB()
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		log.Println(err)
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	stmt, err := db.Prepare("DELETE FROM " + d.tablename + " WHERE id = ?")
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		log.Println(err)
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	defer stmt.Close()
 | 
					 | 
				
			||||||
	_, err = stmt.Exec(d.ID)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		log.Println(err)
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// 更新對象
 | 
					 | 
				
			||||||
func (d *Object) Update() error {
 | 
					 | 
				
			||||||
	db, err := configs.GetDB()
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		log.Println(err)
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	stmt, err := db.Prepare("UPDATE " + d.tablename + " SET name = ?, updated_at = ? WHERE id = ?")
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		log.Println(err)
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	defer stmt.Close()
 | 
					 | 
				
			||||||
	_, err = stmt.Exec(d.Name, d.UpdatedAt, d.ID)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		log.Println(err)
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// 獲取對象
 | 
					 | 
				
			||||||
func (d *Object) Get() error {
 | 
					 | 
				
			||||||
	db, err := configs.GetDB()
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		log.Println(err)
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	stmt, err := db.Prepare("SELECT * FROM " + d.tablename + " WHERE id = ?")
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		log.Println(err)
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	defer stmt.Close()
 | 
					 | 
				
			||||||
	row := stmt.QueryRow(d.ID)
 | 
					 | 
				
			||||||
	err = row.Scan(&d.ID, &d.Name, &d.CreatedAt, &d.UpdatedAt)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		log.Println(err)
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// 獲取所有對象
 | 
					 | 
				
			||||||
func (d *Object) GetAll() ([]Object, error) {
 | 
					 | 
				
			||||||
	db, err := configs.GetDB()
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		log.Println(err)
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	stmt, err := db.Prepare("SELECT * FROM " + d.tablename)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		log.Println(err)
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	defer stmt.Close()
 | 
					 | 
				
			||||||
	rows, err := stmt.Query()
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		log.Println(err)
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	defer rows.Close()
 | 
					 | 
				
			||||||
	var list []Object
 | 
					 | 
				
			||||||
	for rows.Next() {
 | 
					 | 
				
			||||||
		var item Object
 | 
					 | 
				
			||||||
		err = rows.Scan(&item.ID, &item.Name, &item.CreatedAt, &item.UpdatedAt)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			log.Println(err)
 | 
					 | 
				
			||||||
			return nil, err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		list = append(list, item)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return list, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// 獲取分頁對象
 | 
					 | 
				
			||||||
func (d *Object) GetPage(page int64, page_size int64) (ListView, error) {
 | 
					 | 
				
			||||||
	db, err := configs.GetDB()
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		log.Println(err)
 | 
					 | 
				
			||||||
		return ListView{}, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	stmt, err := db.Prepare("SELECT * FROM " + d.tablename + " LIMIT ?, ?")
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		log.Println(err)
 | 
					 | 
				
			||||||
		return ListView{}, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	defer stmt.Close()
 | 
					 | 
				
			||||||
	rows, err := stmt.Query((page-1)*page_size, page_size)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		log.Println(err)
 | 
					 | 
				
			||||||
		return ListView{}, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	defer rows.Close()
 | 
					 | 
				
			||||||
	var list []interface{}
 | 
					 | 
				
			||||||
	for rows.Next() {
 | 
					 | 
				
			||||||
		var item Object
 | 
					 | 
				
			||||||
		err = rows.Scan(&item.ID, &item.Name, &item.CreatedAt, &item.UpdatedAt)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			log.Println(err)
 | 
					 | 
				
			||||||
			return ListView{}, err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		list = append(list, item)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	var listview ListView
 | 
					 | 
				
			||||||
	listview.Code = 0
 | 
					 | 
				
			||||||
	listview.Page = page
 | 
					 | 
				
			||||||
	listview.PageSize = page_size
 | 
					 | 
				
			||||||
	listview.List = list
 | 
					 | 
				
			||||||
	return listview, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// 轉換為格式化的JSON
 | 
					 | 
				
			||||||
func (d *Object) ToJSON() []byte {
 | 
					 | 
				
			||||||
	b, err := json.MarshalIndent(d, "", "  ")
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		log.Println(err)
 | 
					 | 
				
			||||||
		return nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return b
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										144
									
								
								models/Model.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										144
									
								
								models/Model.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,144 @@
 | 
				
			|||||||
 | 
					package models
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"log"
 | 
				
			||||||
 | 
						"main/configs"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Model struct {
 | 
				
			||||||
 | 
						ID           int      `json:"id"`
 | 
				
			||||||
 | 
						Name         string   `json:"name"`
 | 
				
			||||||
 | 
						Type         string   `json:"type"`          // (lora|ckp|hyper|ti)
 | 
				
			||||||
 | 
						TriggerWords string   `json:"trigger_words"` // 觸發詞
 | 
				
			||||||
 | 
						BaseModel    string   `json:"base_model"`    // (SD1.5|SD2)
 | 
				
			||||||
 | 
						ModelPath    string   `json:"model_path"`    // 模型路徑
 | 
				
			||||||
 | 
						Status       string   `json:"status"`        // (waiting|running|success|error)
 | 
				
			||||||
 | 
						Progress     int      `json:"progress"`      // (0-100)
 | 
				
			||||||
 | 
						Tags         []string `json:"tags"`
 | 
				
			||||||
 | 
						CreatedAt    string   `json:"created_at"`
 | 
				
			||||||
 | 
						UpdatedAt    string   `json:"updated_at"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (model *Model) Create() error {
 | 
				
			||||||
 | 
						db, err := configs.GetDB()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer db.Close()
 | 
				
			||||||
 | 
						stmt, err := db.Prepare("INSERT INTO models(name, type, created_at, updated_at) values(?, ?, ?, ?)")
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer stmt.Close()
 | 
				
			||||||
 | 
						result, err := stmt.Exec(model.Name, model.Type, model.CreatedAt, model.UpdatedAt)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						id, err := result.LastInsertId()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						model.ID = int(id)
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (model *Model) Delete() error {
 | 
				
			||||||
 | 
						db, err := configs.GetDB()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer db.Close()
 | 
				
			||||||
 | 
						stmt, err := db.Prepare("DELETE FROM models WHERE id = ?")
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer stmt.Close()
 | 
				
			||||||
 | 
						_, err = stmt.Exec(model.ID)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (model *Model) Update() error {
 | 
				
			||||||
 | 
						db, err := configs.GetDB()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer db.Close()
 | 
				
			||||||
 | 
						stmt, err := db.Prepare("UPDATE models SET name = ?, type = ?, updated_at = ? WHERE id = ?")
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer stmt.Close()
 | 
				
			||||||
 | 
						_, err = stmt.Exec(model.Name, model.Type, model.UpdatedAt, model.ID)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (model *Model) Get() error {
 | 
				
			||||||
 | 
						db, err := configs.GetDB()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer db.Close()
 | 
				
			||||||
 | 
						err = db.QueryRow("SELECT * FROM models WHERE id = ?", model.ID).Scan(&model.ID, &model.Name, &model.Type, &model.CreatedAt, &model.UpdatedAt)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func QueryModels(page int, pagesize int) (models []interface{}) {
 | 
				
			||||||
 | 
						db, err := configs.GetDB()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer db.Close()
 | 
				
			||||||
 | 
						rows, err := db.Query("SELECT * FROM models LIMIT ?, ?", (page-1)*pagesize, pagesize)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer rows.Close()
 | 
				
			||||||
 | 
						for rows.Next() {
 | 
				
			||||||
 | 
							var model Model
 | 
				
			||||||
 | 
							err = rows.Scan(&model.ID, &model.Name, &model.Type, &model.CreatedAt, &model.UpdatedAt)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								log.Println(err)
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							models = append(models, model)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func CountModels() (count int) {
 | 
				
			||||||
 | 
						db, err := configs.GetDB()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer db.Close()
 | 
				
			||||||
 | 
						err = db.QueryRow("SELECT COUNT(*) FROM models").Scan(&count)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										141
									
								
								models/Tag.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										141
									
								
								models/Tag.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,141 @@
 | 
				
			|||||||
 | 
					package models
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"log"
 | 
				
			||||||
 | 
						"main/configs"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Tag struct {
 | 
				
			||||||
 | 
						ID        int    `json:"id"`
 | 
				
			||||||
 | 
						Name      string `json:"name"`
 | 
				
			||||||
 | 
						CreatedAt string `json:"created_at"`
 | 
				
			||||||
 | 
						UpdatedAt string `json:"updated_at"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (tag *Tag) Create() error {
 | 
				
			||||||
 | 
						db, err := configs.GetDB()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer db.Close()
 | 
				
			||||||
 | 
						stmt, err := db.Prepare("INSERT INTO tags(name, created_at, updated_at) values(?, ?, ?)")
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer stmt.Close()
 | 
				
			||||||
 | 
						result, err := stmt.Exec(tag.Name, tag.CreatedAt, tag.UpdatedAt)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						id, err := result.LastInsertId()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						tag.ID = int(id)
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (tag *Tag) Delete() error {
 | 
				
			||||||
 | 
						db, err := configs.GetDB()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer db.Close()
 | 
				
			||||||
 | 
						stmt, err := db.Prepare("DELETE FROM tags WHERE id = ?")
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer stmt.Close()
 | 
				
			||||||
 | 
						_, err = stmt.Exec(tag.ID)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (tag *Tag) Update() error {
 | 
				
			||||||
 | 
						db, err := configs.GetDB()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer db.Close()
 | 
				
			||||||
 | 
						stmt, err := db.Prepare("UPDATE tags SET name = ?, updated_at = ? WHERE id = ?")
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer stmt.Close()
 | 
				
			||||||
 | 
						_, err = stmt.Exec(tag.Name, tag.UpdatedAt, tag.ID)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func GetTags() ([]Tag, error) {
 | 
				
			||||||
 | 
						db, err := configs.GetDB()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer db.Close()
 | 
				
			||||||
 | 
						rows, err := db.Query("SELECT * FROM tags")
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer rows.Close()
 | 
				
			||||||
 | 
						var tags []Tag
 | 
				
			||||||
 | 
						for rows.Next() {
 | 
				
			||||||
 | 
							var tag Tag
 | 
				
			||||||
 | 
							err := rows.Scan(&tag.ID, &tag.Name, &tag.CreatedAt, &tag.UpdatedAt)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								log.Println(err)
 | 
				
			||||||
 | 
								return nil, err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							tags = append(tags, tag)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return tags, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func GetTag(id int) (*Tag, error) {
 | 
				
			||||||
 | 
						db, err := configs.GetDB()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer db.Close()
 | 
				
			||||||
 | 
						row := db.QueryRow("SELECT * FROM tags WHERE id = ?", id)
 | 
				
			||||||
 | 
						var tag Tag
 | 
				
			||||||
 | 
						err = row.Scan(&tag.ID, &tag.Name, &tag.CreatedAt, &tag.UpdatedAt)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return &tag, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func GetTagByName(name string) (*Tag, error) {
 | 
				
			||||||
 | 
						db, err := configs.GetDB()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer db.Close()
 | 
				
			||||||
 | 
						row := db.QueryRow("SELECT * FROM tags WHERE name = ?", name)
 | 
				
			||||||
 | 
						var tag Tag
 | 
				
			||||||
 | 
						err = row.Scan(&tag.ID, &tag.Name, &tag.CreatedAt, &tag.UpdatedAt)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return &tag, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										137
									
								
								models/Task.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										137
									
								
								models/Task.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,137 @@
 | 
				
			|||||||
 | 
					package models
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"log"
 | 
				
			||||||
 | 
						"main/configs"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Task struct {
 | 
				
			||||||
 | 
						ID        int    `json:"id"`
 | 
				
			||||||
 | 
						Name      string `json:"name"`
 | 
				
			||||||
 | 
						Type      string `json:"type"`
 | 
				
			||||||
 | 
						CreatedAt string `json:"created_at"`
 | 
				
			||||||
 | 
						UpdatedAt string `json:"updated_at"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (task *Task) Create() error {
 | 
				
			||||||
 | 
						db, err := configs.GetDB()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer db.Close()
 | 
				
			||||||
 | 
						stmt, err := db.Prepare("INSERT INTO tasks(name, type, created_at, updated_at) values(?, ?, ?, ?)")
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer stmt.Close()
 | 
				
			||||||
 | 
						result, err := stmt.Exec(task.Name, task.Type, task.CreatedAt, task.UpdatedAt)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						id, err := result.LastInsertId()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						task.ID = int(id)
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (task *Task) Delete() error {
 | 
				
			||||||
 | 
						db, err := configs.GetDB()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer db.Close()
 | 
				
			||||||
 | 
						stmt, err := db.Prepare("DELETE FROM tasks WHERE id = ?")
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer stmt.Close()
 | 
				
			||||||
 | 
						_, err = stmt.Exec(task.ID)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (task *Task) Update() error {
 | 
				
			||||||
 | 
						db, err := configs.GetDB()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer db.Close()
 | 
				
			||||||
 | 
						stmt, err := db.Prepare("UPDATE tasks SET name = ?, type = ?, updated_at = ? WHERE id = ?")
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer stmt.Close()
 | 
				
			||||||
 | 
						_, err = stmt.Exec(task.Name, task.Type, task.UpdatedAt, task.ID)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (task *Task) Get() error {
 | 
				
			||||||
 | 
						db, err := configs.GetDB()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer db.Close()
 | 
				
			||||||
 | 
						err = db.QueryRow("SELECT name, type, created_at, updated_at FROM tasks WHERE id = ?", task.ID).Scan(&task.Name, &task.Type, &task.CreatedAt, &task.UpdatedAt)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func QueryTasks(page int, pagesize int) (tasks []interface{}) {
 | 
				
			||||||
 | 
						db, err := configs.GetDB()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer db.Close()
 | 
				
			||||||
 | 
						rows, err := db.Query("SELECT id, name, type, created_at, updated_at FROM tasks LIMIT ?, ?", (page-1)*pagesize, pagesize)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer rows.Close()
 | 
				
			||||||
 | 
						for rows.Next() {
 | 
				
			||||||
 | 
							task := Task{}
 | 
				
			||||||
 | 
							err := rows.Scan(&task.ID, &task.Name, &task.Type, &task.CreatedAt, &task.UpdatedAt)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								log.Println(err)
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							tasks = append(tasks, task)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func CountTasks() (count int) {
 | 
				
			||||||
 | 
						db, err := configs.GetDB()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer db.Close()
 | 
				
			||||||
 | 
						err = db.QueryRow("SELECT COUNT(*) FROM tasks").Scan(&count)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										138
									
								
								models/User.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										138
									
								
								models/User.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,138 @@
 | 
				
			|||||||
 | 
					package models
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"log"
 | 
				
			||||||
 | 
						"main/configs"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type User struct {
 | 
				
			||||||
 | 
						ID        int    `json:"id"`
 | 
				
			||||||
 | 
						Name      string `json:"name"`
 | 
				
			||||||
 | 
						Email     string `json:"email"`
 | 
				
			||||||
 | 
						CreatedAt string `json:"created_at"`
 | 
				
			||||||
 | 
						UpdatedAt string `json:"updated_at"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (user *User) Create() error {
 | 
				
			||||||
 | 
						db, err := configs.GetDB()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer db.Close()
 | 
				
			||||||
 | 
						stmt, err := db.Prepare("INSERT INTO users(name, email, created_at, updated_at) values(?, ?, ?, ?)")
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer stmt.Close()
 | 
				
			||||||
 | 
						result, err := stmt.Exec(user.Name, user.Email, user.CreatedAt, user.UpdatedAt)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						id, err := result.LastInsertId()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						user.ID = int(id)
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (user *User) Delete() error {
 | 
				
			||||||
 | 
						db, err := configs.GetDB()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer db.Close()
 | 
				
			||||||
 | 
						stmt, err := db.Prepare("DELETE FROM users WHERE id = ?")
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer stmt.Close()
 | 
				
			||||||
 | 
						_, err = stmt.Exec(user.ID)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (user *User) Update() error {
 | 
				
			||||||
 | 
						db, err := configs.GetDB()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer db.Close()
 | 
				
			||||||
 | 
						stmt, err := db.Prepare("UPDATE users SET name = ?, email = ?, updated_at = ? WHERE id = ?")
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer stmt.Close()
 | 
				
			||||||
 | 
						_, err = stmt.Exec(user.Name, user.Email, user.UpdatedAt, user.ID)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (user *User) Get() error {
 | 
				
			||||||
 | 
						db, err := configs.GetDB()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer db.Close()
 | 
				
			||||||
 | 
						err = db.QueryRow("SELECT name, email, created_at, updated_at FROM users WHERE id = ?", user.ID).Scan(&user.Name, &user.Email, &user.CreatedAt, &user.UpdatedAt)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (user *User) GetAll() ([]User, error) {
 | 
				
			||||||
 | 
						db, err := configs.GetDB()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer db.Close()
 | 
				
			||||||
 | 
						rows, err := db.Query("SELECT id, name, email, created_at, updated_at FROM users")
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer rows.Close()
 | 
				
			||||||
 | 
						var users []User
 | 
				
			||||||
 | 
						for rows.Next() {
 | 
				
			||||||
 | 
							var user User
 | 
				
			||||||
 | 
							err := rows.Scan(&user.ID, &user.Name, &user.Email, &user.CreatedAt, &user.UpdatedAt)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								log.Println(err)
 | 
				
			||||||
 | 
								return nil, err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							users = append(users, user)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return users, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (user *User) GetByEmail() error {
 | 
				
			||||||
 | 
						db, err := configs.GetDB()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer db.Close()
 | 
				
			||||||
 | 
						err = db.QueryRow("SELECT id, name, email, created_at, updated_at FROM users WHERE email = ?", user.Email).Scan(&user.ID, &user.Name, &user.Email, &user.CreatedAt, &user.UpdatedAt)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										26
									
								
								templates/index.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								templates/index.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,26 @@
 | 
				
			|||||||
 | 
					<!DOCTYPE html>
 | 
				
			||||||
 | 
					<html lang="en">
 | 
				
			||||||
 | 
					<head>
 | 
				
			||||||
 | 
					    <meta charset="UTF-8">
 | 
				
			||||||
 | 
					    <title>Home</title>
 | 
				
			||||||
 | 
					</head>
 | 
				
			||||||
 | 
					<body>
 | 
				
			||||||
 | 
					    <h1>Home</h1>
 | 
				
			||||||
 | 
					    <p>Hi, {{ .Name }}!</p>
 | 
				
			||||||
 | 
					    <!-- 列出所有API路徑 -->
 | 
				
			||||||
 | 
					    <ul>
 | 
				
			||||||
 | 
					        <li><a href="/api/models">/api/models</a></li>
 | 
				
			||||||
 | 
					        <li><a href="/api/images">/api/images</a></li>
 | 
				
			||||||
 | 
					        <li><a href="/api/users">/api/users</a></li>
 | 
				
			||||||
 | 
					        <li><a href="/api/tasks">/api/tasks</a></li>
 | 
				
			||||||
 | 
					        <li><a href="/api/tags">/api/tags</a></li>
 | 
				
			||||||
 | 
					    </ul>
 | 
				
			||||||
 | 
					    <ul>
 | 
				
			||||||
 | 
					        <li><a href="/api/models/1">/api/models/1</a></li>
 | 
				
			||||||
 | 
					        <li><a href="/api/images/1">/api/images/1</a></li>
 | 
				
			||||||
 | 
					        <li><a href="/api/users/1">/api/users/1</a></li>
 | 
				
			||||||
 | 
					        <li><a href="/api/tasks/1">/api/tasks/1</a></li>
 | 
				
			||||||
 | 
					        <li><a href="/api/tags/1">/api/tags/1</a></li>
 | 
				
			||||||
 | 
					    </ul>
 | 
				
			||||||
 | 
					</body>
 | 
				
			||||||
 | 
					</html>
 | 
				
			||||||
		Reference in New Issue
	
	Block a user