Просмотр исходного кода

Channel API done without verification

JustSong 2 лет назад
Родитель
Сommit
6164829239
5 измененных файлов с 107 добавлено и 116 удалено
  1. 12 0
      common/constants.go
  2. 61 80
      controller/channel.go
  3. 26 27
      model/channel.go
  4. 8 6
      router/api-router.go
  5. 0 3
      router/web-router.go

+ 12 - 0
common/constants.go

@@ -83,3 +83,15 @@ const (
 	UserStatusEnabled  = 1 // don't use 0, 0 is the default value!
 	UserStatusDisabled = 2 // also don't use 0
 )
+
+const (
+	ChannelStatusUnknown  = 0
+	ChannelStatusEnabled  = 1 // don't use 0, 0 is the default value!
+	ChannelStatusDisabled = 2 // also don't use 0
+)
+
+const (
+	ChannelTypeUnknown = 0
+	ChannelTypeOpenAI  = 1
+	ChannelTypeAPI2D   = 2
+)

+ 61 - 80
controller/channel.go

@@ -1,15 +1,11 @@
 package controller
 
 import (
-	"fmt"
 	"github.com/gin-gonic/gin"
 	"net/http"
 	"one-api/common"
 	"one-api/model"
-	"path/filepath"
 	"strconv"
-	"strings"
-	"time"
 )
 
 func GetAllChannels(c *gin.Context) {
@@ -17,7 +13,7 @@ func GetAllChannels(c *gin.Context) {
 	if p < 0 {
 		p = 0
 	}
-	files, err := model.GetAllChannels(p*common.ItemsPerPage, common.ItemsPerPage)
+	channels, err := model.GetAllChannels(p*common.ItemsPerPage, common.ItemsPerPage)
 	if err != nil {
 		c.JSON(http.StatusOK, gin.H{
 			"success": false,
@@ -28,14 +24,14 @@ func GetAllChannels(c *gin.Context) {
 	c.JSON(http.StatusOK, gin.H{
 		"success": true,
 		"message": "",
-		"data":    files,
+		"data":    channels,
 	})
 	return
 }
 
 func SearchChannels(c *gin.Context) {
 	keyword := c.Query("keyword")
-	files, err := model.SearchChannels(keyword)
+	channels, err := model.SearchChannels(keyword)
 	if err != nil {
 		c.JSON(http.StatusOK, gin.H{
 			"success": false,
@@ -46,13 +42,13 @@ func SearchChannels(c *gin.Context) {
 	c.JSON(http.StatusOK, gin.H{
 		"success": true,
 		"message": "",
-		"data":    files,
+		"data":    channels,
 	})
 	return
 }
 
-func UploadFile(c *gin.Context) {
-	form, err := c.MultipartForm()
+func GetChannel(c *gin.Context) {
+	id, err := strconv.Atoi(c.Param("id"))
 	if err != nil {
 		c.JSON(http.StatusOK, gin.H{
 			"success": false,
@@ -60,101 +56,86 @@ func UploadFile(c *gin.Context) {
 		})
 		return
 	}
-	uploadPath := common.UploadPath
-	description := c.PostForm("description")
-	if description == "" {
-		description = "无描述信息"
-	}
-	uploader := c.GetString("username")
-	if uploader == "" {
-		uploader = "访客用户"
-	}
-	uploaderId := c.GetInt("id")
-	currentTime := time.Now().Format("2006-01-02 15:04:05")
-	files := form.File["file"]
-	for _, file := range files {
-		filename := filepath.Base(file.Filename)
-		ext := filepath.Ext(filename)
-		link := common.GetUUID() + ext
-		savePath := filepath.Join(uploadPath, link) // both parts are checked, so this path should be safe to use
-		if err := c.SaveUploadedFile(file, savePath); err != nil {
-			c.JSON(http.StatusOK, gin.H{
-				"success": false,
-				"message": err.Error(),
-			})
-			return
-		}
-		// save to database
-		fileObj := &model.Channel{
-			Description: description,
-			Uploader:    uploader,
-			UploadTime:  currentTime,
-			UploaderId:  uploaderId,
-			Link:        link,
-			Filename:    filename,
-		}
-		err = fileObj.Insert()
-		if err != nil {
-			_ = fmt.Errorf(err.Error())
-		}
+	channel, err := model.GetChannelById(id)
+	if err != nil {
+		c.JSON(http.StatusOK, gin.H{
+			"success": false,
+			"message": err.Error(),
+		})
+		return
 	}
 	c.JSON(http.StatusOK, gin.H{
 		"success": true,
 		"message": "",
+		"data":    channel,
 	})
 	return
 }
 
-func DeleteFile(c *gin.Context) {
-	fileIdStr := c.Param("id")
-	fileId, err := strconv.Atoi(fileIdStr)
-	if err != nil || fileId == 0 {
-		c.JSON(http.StatusBadRequest, gin.H{
+func AddChannel(c *gin.Context) {
+	channel := model.Channel{}
+	err := c.ShouldBindJSON(&channel)
+	if err != nil {
+		c.JSON(http.StatusOK, gin.H{
 			"success": false,
-			"message": "无效的参数",
+			"message": err.Error(),
 		})
 		return
 	}
-
-	fileObj := &model.Channel{
-		Id: fileId,
-	}
-	model.DB.Where("id = ?", fileId).First(&fileObj)
-	if fileObj.Link == "" {
+	err = channel.Insert()
+	if err != nil {
 		c.JSON(http.StatusOK, gin.H{
 			"success": false,
-			"message": "文件不存在!",
+			"message": err.Error(),
 		})
 		return
 	}
-	err = fileObj.Delete()
+	c.JSON(http.StatusOK, gin.H{
+		"success": true,
+		"message": "",
+	})
+	return
+}
+
+func DeleteChannel(c *gin.Context) {
+	id, _ := strconv.Atoi(c.Param("id"))
+	channel := model.Channel{Id: id}
+	err := channel.Delete()
 	if err != nil {
 		c.JSON(http.StatusOK, gin.H{
-			"success": true,
+			"success": false,
 			"message": err.Error(),
 		})
 		return
-	} else {
-		message := "文件删除成功"
-		c.JSON(http.StatusOK, gin.H{
-			"success": true,
-			"message": message,
-		})
 	}
-
+	c.JSON(http.StatusOK, gin.H{
+		"success": true,
+		"message": "",
+	})
+	return
 }
 
-func DownloadFile(c *gin.Context) {
-	path := c.Param("file")
-	fullPath := filepath.Join(common.UploadPath, path)
-	if !strings.HasPrefix(fullPath, common.UploadPath) {
-		// We may being attacked!
-		c.Status(403)
+func UpdateChannel(c *gin.Context) {
+	channel := model.Channel{}
+	err := c.ShouldBindJSON(&channel)
+	if err != nil {
+		c.JSON(http.StatusOK, gin.H{
+			"success": false,
+			"message": err.Error(),
+		})
 		return
 	}
-	c.File(fullPath)
-	// Update download counter
-	go func() {
-		model.UpdateDownloadCounter(path)
-	}()
+	err = channel.Update()
+	if err != nil {
+		c.JSON(http.StatusOK, gin.H{
+			"success": false,
+			"message": err.Error(),
+		})
+		return
+	}
+	c.JSON(http.StatusOK, gin.H{
+		"success": true,
+		"message": "",
+	})
+	return
 }

+ 26 - 27
model/channel.go

@@ -2,50 +2,49 @@ package model
 
 import (
 	_ "gorm.io/driver/sqlite"
-	"gorm.io/gorm"
-	"one-api/common"
-	"os"
-	"path"
 )
 
 type Channel struct {
-	Id              int    `json:"id"`
-	Filename        string `json:"filename" gorm:"index"`
-	Description     string `json:"description"`
-	Uploader        string `json:"uploader"  gorm:"index"`
-	UploaderId      int    `json:"uploader_id"  gorm:"index"`
-	Link            string `json:"link" gorm:"unique;index"`
-	UploadTime      string `json:"upload_time"`
-	DownloadCounter int    `json:"download_counter"`
+	Id     int    `json:"id"`
+	Type   int    `json:"type" gorm:"default:0"`
+	Key    string `json:"key"`
+	Status int    `json:"status" gorm:"default:1"`
 }
 
 func GetAllChannels(startIdx int, num int) ([]*Channel, error) {
-	var files []*Channel
+	var channels []*Channel
 	var err error
-	err = DB.Order("id desc").Limit(num).Offset(startIdx).Find(&files).Error
-	return files, err
+	err = DB.Order("id desc").Limit(num).Offset(startIdx).Find(&channels).Error
+	return channels, err
 }
 
-func SearchChannels(keyword string) (files []*Channel, err error) {
-	err = DB.Select([]string{"id", "filename", "description", "uploader", "uploader_id", "link", "upload_time", "download_counter"}).Where(
-		"filename LIKE ? or uploader LIKE ? or uploader_id = ?", keyword+"%", keyword+"%", keyword).Find(&files).Error
-	return files, err
+func SearchChannels(keyword string) (channels []*Channel, err error) {
+	err = DB.Select([]string{"id", "key"}, keyword, keyword).Find(&channels).Error
+	return channels, err
 }
 
-func (file *Channel) Insert() error {
+func GetChannelById(id int) (*Channel, error) {
+	channel := Channel{Id: id}
+	var err error = nil
+	err = DB.Select([]string{"id", "type"}).First(&channel, "id = ?", id).Error
+	return &channel, err
+}
+
+func (channel *Channel) Insert() error {
 	var err error
-	err = DB.Create(file).Error
+	err = DB.Create(channel).Error
 	return err
 }
 
-// Delete Make sure link is valid! Because we will use os.Remove to delete it!
-func (file *Channel) Delete() error {
+func (channel *Channel) Update() error {
 	var err error
-	err = DB.Delete(file).Error
-	err = os.Remove(path.Join(common.UploadPath, file.Link))
+	err = DB.Model(channel).Updates(channel).Error
 	return err
 }
 
-func UpdateDownloadCounter(link string) {
-	DB.Model(&Channel{}).Where("link = ?", link).UpdateColumn("download_counter", gorm.Expr("download_counter + 1"))
+// Delete Make sure link is valid! Because we will use os.Remove to delete it!
+func (channel *Channel) Delete() error {
+	var err error
+	err = DB.Delete(channel).Error
+	return err
 }

+ 8 - 6
router/api-router.go

@@ -54,13 +54,15 @@ func SetApiRouter(router *gin.Engine) {
 			optionRoute.GET("/", controller.GetOptions)
 			optionRoute.PUT("/", controller.UpdateOption)
 		}
-		fileRoute := apiRouter.Group("/file")
-		fileRoute.Use(middleware.AdminAuth())
+		channelRoute := apiRouter.Group("/channel")
+		channelRoute.Use(middleware.AdminAuth())
 		{
-			fileRoute.GET("/", controller.GetAllChannels)
-			fileRoute.GET("/search", controller.SearchChannels)
-			fileRoute.POST("/", middleware.UploadRateLimit(), controller.UploadFile)
-			fileRoute.DELETE("/:id", controller.DeleteFile)
+			channelRoute.GET("/", controller.GetAllChannels)
+			channelRoute.GET("/search", controller.SearchChannels)
+			channelRoute.GET("/:id", controller.GetChannel)
+			channelRoute.POST("/", controller.AddChannel)
+			channelRoute.PUT("/", controller.UpdateChannel)
+			channelRoute.DELETE("/:id", controller.DeleteChannel)
 		}
 	}
 }

+ 0 - 3
router/web-router.go

@@ -6,14 +6,11 @@ import (
 	"github.com/gin-gonic/gin"
 	"net/http"
 	"one-api/common"
-	"one-api/controller"
 	"one-api/middleware"
 )
 
 func setWebRouter(router *gin.Engine, buildFS embed.FS, indexPage []byte) {
 	router.Use(middleware.GlobalWebRateLimit())
-	fileDownloadRoute := router.Group("/")
-	fileDownloadRoute.GET("/upload/:file", middleware.DownloadRateLimit(), controller.DownloadFile)
 	router.Use(middleware.Cache())
 	router.Use(static.Serve("/", common.EmbedFolder(buildFS, "web/build")))
 	router.NoRoute(func(c *gin.Context) {