yunzer_go/server/services/articles.go
2026-01-07 08:43:14 +08:00

492 lines
12 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package services
import (
"fmt"
"server/models"
"strconv"
"strings"
"time"
"github.com/beego/beego/v2/client/orm"
)
// GetArticlesList 获取文章列表
func GetArticlesList(tenant_id int, user_id int, page, pageSize int, keyword string, cate int, status int8) ([]*models.Articles, int64, error) {
o := orm.NewOrm()
qs := o.QueryTable(new(models.Articles))
// 过滤已删除的文章
qs = qs.Filter("delete_time__isnull", true)
// 关键词搜索
if keyword != "" {
cond := orm.NewCondition()
cond1 := cond.Or("title__icontains", keyword).Or("content__icontains", keyword).Or("desc__icontains", keyword)
qs = qs.SetCond(cond1)
}
// 分类筛选
if cate > 0 {
qs = qs.Filter("cate", cate)
}
// 状态筛选
if status >= 0 {
qs = qs.Filter("status", status)
}
// 获取总数
total, err := qs.Count()
if err != nil {
return nil, 0, err
}
// 分页查询
if page <= 0 {
page = 1
}
if pageSize <= 0 {
pageSize = 10
}
offset := (page - 1) * pageSize
var articles []*models.Articles
_, err = qs.OrderBy("-create_time").Limit(pageSize, offset).All(&articles)
return articles, total, err
}
// GetArticleById 根据ID获取文章
func GetArticleById(id int) (*models.Articles, error) {
o := orm.NewOrm()
article := &models.Articles{Id: id}
err := o.Read(article)
if err != nil {
return nil, err
}
// 检查是否已删除
if article.DeleteTime != nil {
return nil, nil // 返回nil表示文章不存在或已删除
}
return article, nil
}
// CreateArticle 创建文章
func CreateArticle(article *models.Articles) (*models.Articles, error) {
o := orm.NewOrm()
id, err := o.Insert(article)
if err != nil {
return nil, err
}
// 获取创建后的文章
article.Id = int(id)
return article, nil
}
// UpdateArticle 更新文章
func UpdateArticle(article *models.Articles) error {
o := orm.NewOrm()
_, err := o.Update(article, "title", "cate", "image", "desc", "author", "content", "publisher", "publishdate", "sort", "status", "is_trans", "transurl", "push", "update_time")
return err
}
// DeleteArticle 删除文章(软删除)
func DeleteArticle(id int) error {
o := orm.NewOrm()
// 获取文章
article := &models.Articles{Id: id}
err := o.Read(article)
if err != nil {
return err
}
// 设置删除时间
now := time.Now()
article.DeleteTime = &now
_, err = o.Update(article, "delete_time")
return err
}
// UpdateArticleStatus 更新文章状态
func UpdateArticleStatus(id int, status int8) error {
o := orm.NewOrm()
article := &models.Articles{Id: id}
err := o.Read(article)
if err != nil {
return err
}
article.Status = status
now := time.Now()
article.UpdateTime = &now
_, err = o.Update(article, "status", "update_time")
return err
}
// IncrementArticleViews 增加文章浏览量
func IncrementArticleViews(id int) error {
o := orm.NewOrm()
article := &models.Articles{Id: id}
err := o.Read(article)
if err != nil {
return err
}
article.Views++
now := time.Now()
article.UpdateTime = &now
_, err = o.Update(article, "views", "update_time")
return err
}
// IncrementArticleLikes 增加文章点赞量
func IncrementArticleLikes(id int) error {
o := orm.NewOrm()
article := &models.Articles{Id: id}
err := o.Read(article)
if err != nil {
return err
}
article.Likes++
now := time.Now()
article.UpdateTime = &now
_, err = o.Update(article, "likes", "update_time")
return err
}
// GetPublishedArticles 获取已发布的文章列表(用于前台展示)
func GetPublishedArticles(page, pageSize int, cate int) ([]*models.Articles, int64, error) {
return GetArticlesList(0, 0, page, pageSize, "", cate, 2) // status=2 表示已发布tenant_id=0, user_id=0
}
// GetArticleStats 获取文章统计信息
func GetArticleStats() (map[string]int64, error) {
o := orm.NewOrm()
stats := make(map[string]int64)
// 总文章数
total, err := o.QueryTable(new(models.Articles)).Filter("delete_time__isnull", true).Count()
if err != nil {
return nil, err
}
stats["total"] = total
// 草稿数
draft, err := o.QueryTable(new(models.Articles)).Filter("delete_time__isnull", true).Filter("status", 0).Count()
if err != nil {
return nil, err
}
stats["draft"] = draft
// 待审核数
pending, err := o.QueryTable(new(models.Articles)).Filter("delete_time__isnull", true).Filter("status", 1).Count()
if err != nil {
return nil, err
}
stats["pending"] = pending
// 已发布数
published, err := o.QueryTable(new(models.Articles)).Filter("delete_time__isnull", true).Filter("status", 2).Count()
if err != nil {
return nil, err
}
stats["published"] = published
// 隐藏数
hidden, err := o.QueryTable(new(models.Articles)).Filter("delete_time__isnull", true).Filter("status", 3).Count()
if err != nil {
return nil, err
}
stats["hidden"] = hidden
return stats, nil
}
// GetArticleCategories 获取文章分类列表
func GetArticleCategories(tenantId int, page, pageSize int, keyword string, status *int8) ([]*models.DictItem, int, error) {
// 首先确保文章分类字典类型存在,如果不存在则创建并添加默认分类
err := ensureDefaultArticleCategories(tenantId)
if err != nil {
return nil, 0, err
}
// 调用字典服务获取文章分类(使用字典编码 "article_category"
// 注意这里传入true表示包含禁用的项目然后我们在业务层进行状态过滤
categories, err := GetDictItemsByCode("article_category", tenantId, true)
if err != nil {
return nil, 0, err
}
// 过滤状态
var filteredCategories []*models.DictItem
if status != nil {
for _, category := range categories {
if category.Status == *status {
filteredCategories = append(filteredCategories, category)
}
}
} else {
filteredCategories = categories
}
// 过滤关键词
if keyword != "" {
var keywordFiltered []*models.DictItem
for _, category := range filteredCategories {
if strings.Contains(category.DictLabel, keyword) {
keywordFiltered = append(keywordFiltered, category)
}
}
filteredCategories = keywordFiltered
}
// 分页处理
total := len(filteredCategories)
start := (page - 1) * pageSize
end := start + pageSize
if start > total {
start = total
}
if end > total {
end = total
}
if start >= end {
return []*models.DictItem{}, total, nil
}
return filteredCategories[start:end], total, nil
}
// GetArticleCategoryById 根据ID获取文章分类详情
func GetArticleCategoryById(id int) (*models.DictItem, error) {
return GetDictItemById(id)
}
// CreateArticleCategory 创建文章分类
func CreateArticleCategory(tenantId, userId int, label, value string, status int8, sort int, color, icon, remark string) (int64, error) {
// 先获取或创建文章分类字典类型
dictType, err := getOrCreateArticleCategoryDictType(tenantId, userId)
if err != nil {
return 0, err
}
// 构建字典项对象
var dictItem models.DictItem
dictItem.DictTypeId = dictType.Id
dictItem.DictLabel = label
dictItem.DictValue = value
dictItem.Status = status
dictItem.Sort = sort
dictItem.Color = color
dictItem.Icon = icon
dictItem.Remark = remark
dictItem.CreateBy = strconv.Itoa(userId)
dictItem.UpdateBy = strconv.Itoa(userId)
// 调用字典服务创建分类
return AddDictItem(&dictItem)
}
// UpdateArticleCategory 更新文章分类
func UpdateArticleCategory(id, userId int, label, value string, status int8, sort int, color, icon, remark string) error {
// 获取现有分类
existingCategory, err := GetDictItemById(id)
if err != nil {
return err
}
if existingCategory == nil {
return fmt.Errorf("分类不存在")
}
// 构建更新对象
var dictItem models.DictItem
dictItem.Id = id
dictItem.DictTypeId = existingCategory.DictTypeId
dictItem.DictLabel = label
dictItem.DictValue = value
dictItem.Status = status
dictItem.Sort = sort
dictItem.Color = color
dictItem.Icon = icon
dictItem.Remark = remark
dictItem.UpdateBy = strconv.Itoa(userId)
// 调用字典服务更新分类
return UpdateDictItem(&dictItem)
}
// DeleteArticleCategory 删除文章分类
func DeleteArticleCategory(id int) error {
// 检查是否有文章使用此分类
o := orm.NewOrm()
var count int
err := o.Raw("SELECT COUNT(*) FROM yz_articles WHERE cate = ? AND delete_time IS NULL", id).QueryRow(&count)
if err == nil && count > 0 {
return fmt.Errorf("该分类下存在文章,无法删除")
}
// 调用字典服务删除分类
return DeleteDictItem(id)
}
// UpdateArticleCategoryStatus 更新文章分类状态
func UpdateArticleCategoryStatus(id int, status int8) error {
// 获取现有分类
category, err := GetDictItemById(id)
if err != nil {
return err
}
if category == nil {
return fmt.Errorf("分类不存在")
}
// 更新状态
category.Status = status
category.UpdateTime = time.Now()
// 调用字典服务更新分类
return UpdateDictItem(category)
}
// ensureDefaultArticleCategories 确保文章分类字典类型和默认分类项存在
func ensureDefaultArticleCategories(tenantId int) error {
o := orm.NewOrm()
// 检查文章分类字典类型是否存在
dictType := &models.DictType{}
err := o.Raw("SELECT * FROM sys_dict_type WHERE dict_code = ? AND tenant_id = ? AND is_deleted = 0",
"article_category", tenantId).QueryRow(dictType)
if err != nil {
// 字典类型不存在,创建它
dictType = &models.DictType{
TenantId: tenantId,
DictCode: "article_category",
DictName: "文章分类",
ParentId: 0,
Status: 1,
IsGlobal: 0,
Sort: 0,
Remark: "文章分类字典",
CreateBy: "system",
UpdateBy: "system",
IsDeleted: 0,
CreateTime: time.Now(),
UpdateTime: time.Now(),
}
_, err = o.Insert(dictType)
if err != nil {
return err
}
}
// 检查是否已有分类项,如果没有则创建默认分类
var count int
err = o.Raw("SELECT COUNT(*) FROM sys_dict_item WHERE dict_type_id = ? AND is_deleted = 0", dictType.Id).QueryRow(&count)
if err != nil {
return err
}
if count == 0 {
// 创建默认分类项
defaultCategories := []struct {
label string
value string
sort int
color string
remark string
}{
{"技术分享", "tech", 1, "#409EFF", "技术相关文章"},
{"行业资讯", "news", 2, "#67C23A", "行业新闻资讯"},
{"教程指南", "tutorial", 3, "#E6A23C", "使用教程和指南"},
{"公告通知", "announcement", 4, "#F56C6C", "重要公告通知"},
{"其他", "other", 5, "#909399", "其他类型文章"},
}
for _, cat := range defaultCategories {
dictItem := &models.DictItem{
DictTypeId: dictType.Id,
DictLabel: cat.label,
DictValue: cat.value,
ParentId: 0,
Status: 1,
Sort: cat.sort,
Color: cat.color,
Remark: cat.remark,
CreateBy: "system",
UpdateBy: "system",
IsDeleted: 0,
CreateTime: time.Now(),
UpdateTime: time.Now(),
}
_, err = o.Insert(dictItem)
if err != nil {
return err
}
}
}
return nil
}
// getOrCreateArticleCategoryDictType 获取或创建文章分类字典类型
func getOrCreateArticleCategoryDictType(tenantId int, userId int) (*models.DictType, error) {
o := orm.NewOrm()
// 尝试获取现有的文章分类字典类型
dictType := &models.DictType{}
err := o.Raw("SELECT * FROM sys_dict_type WHERE dict_code = ? AND tenant_id = ? AND is_deleted = 0",
"article_category", tenantId).QueryRow(dictType)
if err == nil {
// 已存在,直接返回
return dictType, nil
}
// 不存在,创建新的字典类型
dictType = &models.DictType{
TenantId: tenantId,
DictCode: "article_category",
DictName: "文章分类",
ParentId: 0,
Status: 1,
IsGlobal: 0,
Sort: 0,
Remark: "文章分类字典",
CreateBy: strconv.Itoa(userId),
UpdateBy: strconv.Itoa(userId),
IsDeleted: 0,
CreateTime: time.Now(),
UpdateTime: time.Now(),
}
_, err = o.Insert(dictType)
if err != nil {
return nil, err
}
return dictType, nil
}