diff --git a/api/v1/article/article.go b/api/v1/article/article.go index e7c53e9..0a42059 100644 --- a/api/v1/article/article.go +++ b/api/v1/article/article.go @@ -8,6 +8,7 @@ import ( "git.echol.cn/loser/lckt/utils/user_jwt" "github.com/gin-gonic/gin" "go.uber.org/zap" + "strings" ) type ArticleApi struct{} @@ -90,6 +91,26 @@ func (ArticleApi) ById(ctx *gin.Context) { r.OkWithData(article, ctx) } +// BulkUpload 批量上传文章 +func (ArticleApi) BulkUpload(ctx *gin.Context) { + var p request.BulkUpload + if err := ctx.ShouldBind(&p); err != nil { + r.FailWithMessage(err.Error(), ctx) + global.GVA_LOG.Error("参数有误!", zap.Error(err)) + return + } + err := articleService.BulkUpload(p) + if err != nil { + global.GVA_LOG.Error("批量上传失败!", zap.Error(err)) + // 只要返回部分失败的文件列表 删除前面的"部分文件上传失败: "即可 + r.FailWithDetailed(strings.TrimPrefix(err.Error(), "部分文件上传失败: "), "部分文件上传失败:"+strings.TrimPrefix(err.Error(), "部分文件上传失败: "), ctx) + return + } + r.OkWithMessage("批量上传成功", ctx) +} + +// ===================================== APP 端接口 ============================ + func (ArticleApi) APPGetList(ctx *gin.Context) { var p request.GetList if err := ctx.ShouldBind(&p); err != nil { diff --git a/model/article/request/article.go b/model/article/request/article.go index 1d2c7b6..79b0eb1 100644 --- a/model/article/request/article.go +++ b/model/article/request/article.go @@ -15,3 +15,15 @@ type GetList struct { type DeleteIds struct { Ids []int `json:"ids" form:"ids" binding:"required"` } + +type BulkUpload struct { + Files []string `json:"files" form:"files" binding:"required"` + Title string `json:"title" form:"title" binding:"required"` + Desc string `json:"desc" form:"desc" binding:"required"` + Price float64 `json:"price" form:"price" binding:"required"` // 价格,单位分 + // 分类ID + CategoryId int `json:"categoryId" form:"categoryId" binding:"required"` // 分类ID + // 发布时间 + PublishTime string `json:"publishTime" form:"publishTime"` // 发布时间 + IsFree *int `json:"isFree" form:"isFree"` // 是否免费 +} diff --git a/router/article/article.go b/router/article/article.go index 1d22da3..7740431 100644 --- a/router/article/article.go +++ b/router/article/article.go @@ -14,11 +14,12 @@ func (s *ArticleRouter) InitBotRouter(Router *gin.RouterGroup, PublicRouter *gin articleRouterWithoutAuth := PublicRouter.Group("article") appRouter := AppRouter.Group("article") { - articleRouter.POST("", artApi.Create) // 新建文章 - articleRouter.DELETE("", artApi.Delete) // 批量删除文章 - articleRouter.PUT("", artApi.Update) // 更新文章 - articleRouter.GET("list", artApi.List) // 获取文章列表 - articleRouter.GET("", artApi.ById) // 文章开放接口 + articleRouter.POST("", artApi.Create) // 新建文章 + articleRouter.DELETE("", artApi.Delete) // 批量删除文章 + articleRouter.PUT("", artApi.Update) // 更新文章 + articleRouter.GET("list", artApi.List) // 获取文章列表 + articleRouter.GET("", artApi.ById) // 文章开放接口 + articleRouter.POST("bulk", artApi.BulkUpload) // 批量新建文章 } { articleRouterWithoutRecord.GET(":id", artApi.ById) // 根据ID获取文章 diff --git a/service/article/article.go b/service/article/article.go index 3de4174..f26595b 100644 --- a/service/article/article.go +++ b/service/article/article.go @@ -1,12 +1,15 @@ package article import ( + "fmt" "git.echol.cn/loser/lckt/global" "git.echol.cn/loser/lckt/model/app" "git.echol.cn/loser/lckt/model/article" "git.echol.cn/loser/lckt/model/article/request" "git.echol.cn/loser/lckt/model/article/vo" + "git.echol.cn/loser/lckt/model/user" "go.uber.org/zap" + "strings" ) type ArticleService struct{} @@ -200,3 +203,52 @@ func (s ArticleService) AppDelete(id string) error { } return nil } + +func (s ArticleService) BulkUpload(p request.BulkUpload) (err error) { + var articles []article.Article + var failedFiles []string + + for _, a := range p.Files { + teacher := user.User{} + if dbErr := global.GVA_DB.Model(&teacher).Where("nick_name = ?", getTeacherName(a)).First(&teacher).Error; dbErr != nil { + global.GVA_LOG.Error("获取讲师信息失败", zap.Error(dbErr)) + failedFiles = append(failedFiles, a) + continue + } + content := "

\""

" + + articles = append(articles, article.Article{ + Title: p.Title, + Desc: p.Desc, + CategoryId: p.CategoryId, + TeacherId: int(teacher.ID), + TeacherName: teacher.NickName, + CoverImg: teacher.Avatar, + Content: content, + IsFree: p.IsFree, + Price: int64(p.Price), + }) + } + + if len(articles) > 0 { + if dbErr := global.GVA_DB.Create(&articles).Error; dbErr != nil { + global.GVA_LOG.Error("批量上传文章失败", zap.Error(dbErr)) + return dbErr + } + } + + if len(failedFiles) > 0 { + global.GVA_LOG.Error("部分文件上传失败", zap.Strings("failedFiles", failedFiles)) + return fmt.Errorf("部分文件上传失败: %v", failedFiles) + } + return nil +} + +func getTeacherName(url string) string { + lastSlash := strings.LastIndex(url, "/") + underscore := strings.Index(url[lastSlash+1:], "_") + if lastSlash == -1 || underscore == -1 { + return "" + } + return url[lastSlash+1 : lastSlash+1+underscore] +} diff --git a/service/example/exa_file_upload_download.go b/service/example/exa_file_upload_download.go index 405e253..b73800c 100644 --- a/service/example/exa_file_upload_download.go +++ b/service/example/exa_file_upload_download.go @@ -101,6 +101,9 @@ func (e *FileUploadAndDownloadService) UploadFile(header *multipart.FileHeader, if classId == 2 { header.Filename = utils.GenerateRandomString(12) + "_" + strconv.FormatInt(time.Now().Unix(), 10) + "." + s[len(s)-1] } + if classId == 3 { + header.Filename = s[0] + "_" + utils.GenerateRandomString(12) + "_" + strconv.FormatInt(time.Now().Unix(), 10) + "." + s[len(s)-1] + } filePath, key, uploadErr := oss.UploadFile(header) if uploadErr != nil { return file, uploadErr