313 lines
9.2 KiB
Go
313 lines
9.2 KiB
Go
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"
|
||
"time"
|
||
)
|
||
|
||
type ArticleService struct{}
|
||
|
||
func (ArticleService) CreateArticle(req article.Article) (err error) {
|
||
err = global.GVA_DB.Create(&req).Error
|
||
return
|
||
}
|
||
|
||
func (ArticleService) DeleteArticle(ids request.DeleteIds) (err error) {
|
||
err = global.GVA_DB.Delete(&article.Article{}, "id in ?", ids.Ids).Error
|
||
return
|
||
}
|
||
|
||
func (ArticleService) UpdateArticle(req article.Article) (err error) {
|
||
err = global.GVA_DB.Model(&article.Article{}).Where("id = ?", req.ID).Updates(&req).Error
|
||
return
|
||
}
|
||
|
||
func (ArticleService) GetArticle(id string) (article article.Article, err error) {
|
||
err = global.GVA_DB.Where("id = ?", id).First(&article).Error
|
||
return
|
||
}
|
||
|
||
func (ArticleService) GetArticleList(pageInfo request.GetList) (list []article.Article, total int64, err error) {
|
||
limit := pageInfo.PageSize
|
||
offset := pageInfo.PageSize * (pageInfo.Page - 1)
|
||
// 创建db
|
||
db := global.GVA_DB.Model(&article.Article{})
|
||
|
||
if pageInfo.Title != "" {
|
||
db = db.Where("title LIKE ?", "%"+pageInfo.Title+"%")
|
||
}
|
||
if pageInfo.CategoryId != 0 {
|
||
db = db.Where("category_id = ?", pageInfo.CategoryId)
|
||
}
|
||
if pageInfo.TeacherId != 0 {
|
||
db = db.Where("teacher_id = ?", pageInfo.TeacherId)
|
||
}
|
||
|
||
err = db.Count(&total).Error
|
||
if err != nil {
|
||
return
|
||
}
|
||
err = db.Limit(limit).Offset(offset).Order("created_at desc").Find(&list).Error
|
||
return
|
||
}
|
||
|
||
func (s ArticleService) APPGetArticleList(pageInfo request.GetList) (list []vo.ArticleListVo, total int64, err error) {
|
||
limit := pageInfo.PageSize
|
||
offset := pageInfo.PageSize * (pageInfo.Page - 1)
|
||
|
||
db := global.GVA_DB.Model(&article.Article{}).Where("status = 1") // 只查询已发布的文章
|
||
|
||
// 优化:先构建所有筛选条件再查询总数和数据
|
||
if pageInfo.Title != "" {
|
||
db = db.Where("title LIKE ?", "%"+pageInfo.Title+"%")
|
||
}
|
||
if pageInfo.CategoryId != 0 {
|
||
db = db.Where("category_id = ?", pageInfo.CategoryId)
|
||
}
|
||
if pageInfo.TeacherId != 0 {
|
||
db = db.Where("teacher_id = ?", pageInfo.TeacherId)
|
||
}
|
||
if pageInfo.Keyword != "" {
|
||
db = db.Where("title LIKE ? OR article.desc LIKE ? OR teacher_name LIKE ?", "%"+pageInfo.Keyword+"%", "%"+pageInfo.Keyword+"%", "%"+pageInfo.Keyword+"%")
|
||
}
|
||
|
||
// 先查总数
|
||
err = db.Count(&total).Error
|
||
if err != nil {
|
||
return
|
||
}
|
||
|
||
// 批量查出teacher_id
|
||
err = db.Limit(limit).Offset(offset).Omit("teacher_avatar").Order("created_at desc").Find(&list).Error
|
||
if err != nil {
|
||
return
|
||
}
|
||
|
||
// 优化:批量查询讲师头像,避免N+1查询
|
||
teacherIds := make([]int, 0, len(list))
|
||
for _, a := range list {
|
||
teacherIds = append(teacherIds, a.TeacherId)
|
||
}
|
||
avatars := make(map[int]string)
|
||
if len(teacherIds) > 0 {
|
||
type avatarResult struct {
|
||
ID int
|
||
Avatar string
|
||
}
|
||
var results []avatarResult
|
||
global.GVA_DB.Table("app_user").Select("id, avatar").Where("id IN ?", teacherIds).Find(&results)
|
||
for _, r := range results {
|
||
avatars[r.ID] = r.Avatar
|
||
}
|
||
}
|
||
for i, a := range list {
|
||
list[i].TeacherAvatar = avatars[a.TeacherId]
|
||
}
|
||
|
||
return
|
||
}
|
||
|
||
func (s ArticleService) APPGetArticle(id string, userId int) (article *vo.ArticleVo, err error) {
|
||
err = global.GVA_DB.Table("article").Where("id = ?", id).First(&article).Error
|
||
if err != nil {
|
||
global.GVA_LOG.Error("获取文章失败", zap.Error(err))
|
||
return
|
||
}
|
||
article.IsBuy = 1
|
||
|
||
global.GVA_DB.Table("app_user").Select("avatar").Where("id = ?", article.TeacherId).Scan(&article.TeacherAvatar)
|
||
|
||
// 判断是否免费
|
||
if article.IsFree == 0 {
|
||
// 如果不是免费文章,判断用户是否购买过
|
||
var count int64
|
||
err = global.GVA_DB.Model(&app.Order{}).Where("article_id = ? AND user_id = ? AND status = 2", id, userId).Count(&count).Error
|
||
if err != nil {
|
||
global.GVA_LOG.Error("查询用户购买记录失败", zap.Error(err))
|
||
return nil, err
|
||
}
|
||
|
||
// 如果count = 0 或者 TeacherId 不等于 userId,表示用户没有购买过该文章
|
||
if count == 0 && article.TeacherId != userId {
|
||
|
||
// 判断用户是否已经包月该讲师和是否是讲师本人
|
||
if userId != 0 && userId != article.TeacherId {
|
||
var userTeacherVip []app.UserTeacherVip
|
||
err = global.GVA_DB.Model(&app.UserTeacherVip{}).Where("teacher_id = ? AND user_id = ? AND is_expire = 1", article.TeacherId, userId).Find(&userTeacherVip).Count(&count).Error
|
||
if err != nil {
|
||
global.GVA_LOG.Error("查询用户包月记录失败", zap.Error(err))
|
||
return nil, err
|
||
}
|
||
|
||
for _, vip := range userTeacherVip {
|
||
// 获取包月的信息 判断文章是否在包月范围内
|
||
var teacherVipInfo app.TeacherVip
|
||
err = global.GVA_DB.Model(&app.TeacherVip{}).Where("id = ?", vip.TeacherVipId).First(&teacherVipInfo).Error
|
||
if err != nil {
|
||
global.GVA_LOG.Error("查询讲师包月信息失败", zap.Error(err))
|
||
return nil, err
|
||
}
|
||
|
||
// 用户包月了,判断文章是否在包月范围内
|
||
if count != 0 {
|
||
if teacherVipInfo.CategoryId == article.CategoryId {
|
||
return
|
||
}
|
||
}
|
||
}
|
||
// 用户没有购买过,隐藏Content
|
||
article.Content = ""
|
||
article.IsBuy = 0 // 设置为未购买
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
return
|
||
}
|
||
|
||
// AppPush app端推送文章
|
||
func (s ArticleService) AppPush(req article.Article) (err error) {
|
||
req.Status = 2 // 默认状态为待审核
|
||
if req.ID != 0 {
|
||
err = global.GVA_DB.Model(&article.Article{}).Where("id = ?", req.ID).Updates(&req).Error
|
||
} else {
|
||
err = global.GVA_DB.Create(&req).Error
|
||
}
|
||
if err != nil {
|
||
global.GVA_LOG.Error("推送文章失败", zap.Error(err))
|
||
return err
|
||
}
|
||
return nil
|
||
}
|
||
|
||
func (s ArticleService) GetMyArticleList(req request.GetList) (list []article.Article, total int64, err error) {
|
||
|
||
limit := req.PageSize
|
||
offset := req.PageSize * (req.Page - 1)
|
||
|
||
db := global.GVA_DB.Model(&article.Article{}).Where("teacher_id = ?", req.TeacherId)
|
||
if req.Title != "" {
|
||
db = db.Where("title LIKE ?", "%"+req.Title+"%")
|
||
}
|
||
|
||
if req.CategoryId != 0 {
|
||
db = db.Where("category_id = ?", req.CategoryId)
|
||
}
|
||
|
||
if req.Status != 0 {
|
||
db = db.Where("status = ?", req.Status)
|
||
}
|
||
|
||
err = db.Count(&total).Error
|
||
if err != nil {
|
||
return nil, 0, err
|
||
}
|
||
err = db.Limit(limit).Offset(offset).Find(&list).Error
|
||
return list, total, err
|
||
}
|
||
|
||
func (s ArticleService) GetBuyList(p request.GetList) (articles []article.Article, total int64, err error) {
|
||
buyIds := make([]int, 0)
|
||
// 获取用户购买的文章ID列表
|
||
err = global.GVA_DB.Model(&app.Order{}).Where("user_id = ? AND status = 2", p.UserId).Select("article_id").Find(&buyIds).Error
|
||
if err != nil {
|
||
global.GVA_LOG.Error("查询用户购买记录失败", zap.Error(err))
|
||
return nil, 0, err
|
||
}
|
||
|
||
if len(buyIds) == 0 {
|
||
// 如果没有购买记录,直接返回空列表
|
||
return []article.Article{}, 0, nil
|
||
}
|
||
|
||
db := global.GVA_DB.Model(&article.Article{}).Where("id IN ?", buyIds)
|
||
if p.Title != "" {
|
||
db = db.Where("title LIKE ?", "%"+p.Title+"%")
|
||
}
|
||
|
||
err = db.Count(&total).Error
|
||
if err != nil {
|
||
global.GVA_LOG.Error("查询购买文章总数失败", zap.Error(err))
|
||
return nil, 0, err
|
||
}
|
||
|
||
err = db.Limit(p.PageSize).Offset(p.PageSize * (p.Page - 1)).Find(&articles).Error
|
||
if err != nil {
|
||
global.GVA_LOG.Error("查询购买文章列表失败", zap.Error(err))
|
||
return nil, 0, err
|
||
}
|
||
return articles, total, nil
|
||
}
|
||
|
||
func (s ArticleService) AppDelete(id string) error {
|
||
err := global.GVA_DB.Delete(&article.Article{}, "id = ?", id).Error
|
||
if err != nil {
|
||
global.GVA_LOG.Error("删除文章失败", zap.Error(err))
|
||
return err
|
||
}
|
||
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>"
|
||
|
||
// 将 p.PublishTime转为time.time类型
|
||
loc, _ := time.LoadLocation("Asia/Shanghai")
|
||
publishTime, _ := time.ParseInLocation("2006-01-02 15:04:05", p.PublishTime, loc)
|
||
|
||
articles = append(articles, article.Article{
|
||
Title: teacher.NickName + "--" + 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),
|
||
PublishTime: &publishTime,
|
||
})
|
||
}
|
||
|
||
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]
|
||
}
|