🎨 新增批量上传文章功能
This commit is contained in:
@@ -8,6 +8,7 @@ import (
|
|||||||
"git.echol.cn/loser/lckt/utils/user_jwt"
|
"git.echol.cn/loser/lckt/utils/user_jwt"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ArticleApi struct{}
|
type ArticleApi struct{}
|
||||||
@@ -90,6 +91,26 @@ func (ArticleApi) ById(ctx *gin.Context) {
|
|||||||
r.OkWithData(article, ctx)
|
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) {
|
func (ArticleApi) APPGetList(ctx *gin.Context) {
|
||||||
var p request.GetList
|
var p request.GetList
|
||||||
if err := ctx.ShouldBind(&p); err != nil {
|
if err := ctx.ShouldBind(&p); err != nil {
|
||||||
|
@@ -15,3 +15,15 @@ type GetList struct {
|
|||||||
type DeleteIds struct {
|
type DeleteIds struct {
|
||||||
Ids []int `json:"ids" form:"ids" binding:"required"`
|
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"` // 是否免费
|
||||||
|
}
|
||||||
|
@@ -14,11 +14,12 @@ func (s *ArticleRouter) InitBotRouter(Router *gin.RouterGroup, PublicRouter *gin
|
|||||||
articleRouterWithoutAuth := PublicRouter.Group("article")
|
articleRouterWithoutAuth := PublicRouter.Group("article")
|
||||||
appRouter := AppRouter.Group("article")
|
appRouter := AppRouter.Group("article")
|
||||||
{
|
{
|
||||||
articleRouter.POST("", artApi.Create) // 新建文章
|
articleRouter.POST("", artApi.Create) // 新建文章
|
||||||
articleRouter.DELETE("", artApi.Delete) // 批量删除文章
|
articleRouter.DELETE("", artApi.Delete) // 批量删除文章
|
||||||
articleRouter.PUT("", artApi.Update) // 更新文章
|
articleRouter.PUT("", artApi.Update) // 更新文章
|
||||||
articleRouter.GET("list", artApi.List) // 获取文章列表
|
articleRouter.GET("list", artApi.List) // 获取文章列表
|
||||||
articleRouter.GET("", artApi.ById) // 文章开放接口
|
articleRouter.GET("", artApi.ById) // 文章开放接口
|
||||||
|
articleRouter.POST("bulk", artApi.BulkUpload) // 批量新建文章
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
articleRouterWithoutRecord.GET(":id", artApi.ById) // 根据ID获取文章
|
articleRouterWithoutRecord.GET(":id", artApi.ById) // 根据ID获取文章
|
||||||
|
@@ -1,12 +1,15 @@
|
|||||||
package article
|
package article
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"git.echol.cn/loser/lckt/global"
|
"git.echol.cn/loser/lckt/global"
|
||||||
"git.echol.cn/loser/lckt/model/app"
|
"git.echol.cn/loser/lckt/model/app"
|
||||||
"git.echol.cn/loser/lckt/model/article"
|
"git.echol.cn/loser/lckt/model/article"
|
||||||
"git.echol.cn/loser/lckt/model/article/request"
|
"git.echol.cn/loser/lckt/model/article/request"
|
||||||
"git.echol.cn/loser/lckt/model/article/vo"
|
"git.echol.cn/loser/lckt/model/article/vo"
|
||||||
|
"git.echol.cn/loser/lckt/model/user"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ArticleService struct{}
|
type ArticleService struct{}
|
||||||
@@ -200,3 +203,52 @@ func (s ArticleService) AppDelete(id string) error {
|
|||||||
}
|
}
|
||||||
return nil
|
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 := "<p><img src=" + a + " alt=\"" + a + "\" data-href=\"\" style=\"width: 100%;height: auto;\"/></p>"
|
||||||
|
|
||||||
|
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]
|
||||||
|
}
|
||||||
|
@@ -101,6 +101,9 @@ func (e *FileUploadAndDownloadService) UploadFile(header *multipart.FileHeader,
|
|||||||
if classId == 2 {
|
if classId == 2 {
|
||||||
header.Filename = utils.GenerateRandomString(12) + "_" + strconv.FormatInt(time.Now().Unix(), 10) + "." + s[len(s)-1]
|
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)
|
filePath, key, uploadErr := oss.UploadFile(header)
|
||||||
if uploadErr != nil {
|
if uploadErr != nil {
|
||||||
return file, uploadErr
|
return file, uploadErr
|
||||||
|
Reference in New Issue
Block a user