492 lines
12 KiB
Go
492 lines
12 KiB
Go
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
|
||
}
|