feat: import services and standardize Go 1.26.5
This commit is contained in:
56
apps/base/cms/internal/config/config.go
Normal file
56
apps/base/cms/internal/config/config.go
Normal file
@@ -0,0 +1,56 @@
|
||||
// Package config 提供CMS服务的配置管理功能
|
||||
// 负责加载和验证服务配置参数,包括数据库、缓存、微服务等配置
|
||||
package config
|
||||
|
||||
import (
|
||||
"net"
|
||||
|
||||
"git.apinb.com/bsm-sdk/core/conf"
|
||||
"git.apinb.com/bsm-sdk/core/crypto/encipher"
|
||||
"git.apinb.com/bsm-sdk/core/env"
|
||||
)
|
||||
|
||||
var (
|
||||
// Spec 全局配置实例,包含所有服务配置参数
|
||||
Spec SrvConfig
|
||||
)
|
||||
|
||||
// SrvConfig CMS服务配置结构体
|
||||
// 继承基础配置,并扩展数据库、微服务、网关等特定配置
|
||||
type SrvConfig struct {
|
||||
conf.Base `yaml:",inline"` // 基础配置(服务名、端口、缓存等)
|
||||
Databases *conf.DBConf `yaml:"Databases"` // 数据库配置
|
||||
MicroService *conf.MicroServiceConf `yaml:"MicroService"` // 微服务配置
|
||||
Rpc map[string]conf.RpcConf `yaml:"Rpc"` // RPC服务配置
|
||||
Gateway *conf.GatewayConf `yaml:"Gateway"` // HTTP网关配置
|
||||
Apm *conf.ApmConf `yaml:"APM"` // APM监控配置
|
||||
Etcd *conf.EtcdConf `yaml:"Etcd"` // Etcd配置
|
||||
}
|
||||
|
||||
// New 初始化配置
|
||||
// 根据服务标识符加载配置文件,验证配置参数的有效性
|
||||
// 参数:
|
||||
// - srvKey: 服务标识符,用于确定配置文件路径
|
||||
func New(srvKey string) {
|
||||
// 加载配置文件,将配置数据解析到Spec结构体中
|
||||
conf.New(srvKey, &Spec)
|
||||
|
||||
// 验证和修正端口配置,如果端口不合法则分配随机端口
|
||||
Spec.Port = conf.CheckPort(Spec.Port)
|
||||
|
||||
// 验证和修正IP地址配置,确保IP地址有效
|
||||
Spec.BindIP = conf.CheckIP(Spec.BindIP)
|
||||
|
||||
// 组合IP和端口,生成完整的服务地址
|
||||
Spec.Addr = net.JoinHostPort(Spec.BindIP, Spec.Port)
|
||||
|
||||
// 验证关键配置项不能为空
|
||||
// 服务名称和缓存配置是必需的
|
||||
conf.NotNil(Spec.Service, Spec.Cache)
|
||||
|
||||
// 初始化JWT加密密钥,用于身份验证
|
||||
encipher.New(env.Runtime.JwtSecretKey)
|
||||
|
||||
// 打印服务启动信息,包括监听地址
|
||||
conf.PrintInfo(Spec.Addr)
|
||||
}
|
||||
47
apps/base/cms/internal/impl/impl.go
Normal file
47
apps/base/cms/internal/impl/impl.go
Normal file
@@ -0,0 +1,47 @@
|
||||
// Package impl 提供CMS服务的实现层
|
||||
// 负责初始化和管理各种外部服务的连接,包括数据库、缓存、etcd等
|
||||
package impl
|
||||
|
||||
import (
|
||||
"git.apinb.com/bsm-apps/cms/internal/config"
|
||||
"git.apinb.com/bsm-sdk/core/cache/redis"
|
||||
"git.apinb.com/bsm-sdk/core/with"
|
||||
cache "github.com/patrickmn/go-cache"
|
||||
clientv3 "go.etcd.io/etcd/client/v3"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
var (
|
||||
// RedisService Redis缓存服务客户端
|
||||
// 用于存储临时数据和缓存热点数据
|
||||
RedisService *redis.RedisClient
|
||||
|
||||
// EtcdService Etcd客户端
|
||||
// 用于服务发现和配置管理
|
||||
EtcdService *clientv3.Client
|
||||
|
||||
// DBService 数据库服务连接
|
||||
// 用于数据持久化存储
|
||||
DBService *gorm.DB
|
||||
|
||||
// MemoryService 内存缓存服务
|
||||
// 用于存储频繁访问的数据,提供最快的访问速度
|
||||
MemoryService *cache.Cache
|
||||
)
|
||||
|
||||
// NewImpl 初始化实现层
|
||||
// 建立与各种外部服务的连接,包括内存缓存、Redis、数据库和Etcd
|
||||
// 这些连接将在整个服务生命周期中使用
|
||||
func NewImpl() {
|
||||
// 初始化内存缓存服务,用于存储热点数据
|
||||
MemoryService = with.Memory(nil)
|
||||
|
||||
// 初始化Redis缓存服务,用于分布式缓存
|
||||
RedisService = with.RedisCache(config.Spec.Cache)
|
||||
|
||||
// 初始化数据库连接,用于数据持久化
|
||||
DBService = with.Databases(config.Spec.Databases, nil)
|
||||
|
||||
// 初始化Etcd客户端,用于服务发现和配置管理
|
||||
EtcdService = with.Etcd(config.Spec.Etcd)
|
||||
}
|
||||
66
apps/base/cms/internal/logic/category/create.go
Normal file
66
apps/base/cms/internal/logic/category/create.go
Normal file
@@ -0,0 +1,66 @@
|
||||
// Package category 提供分类相关的业务逻辑处理
|
||||
// 包括分类的创建、修改、删除、查询等功能
|
||||
package category
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"git.apinb.com/bsm-apps/cms/internal/impl"
|
||||
"git.apinb.com/bsm-apps/cms/internal/models"
|
||||
pb "git.apinb.com/bsm-apps/cms/pb"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
"git.apinb.com/bsm-sdk/core/service"
|
||||
"git.apinb.com/bsm-sdk/core/utils"
|
||||
"git.apinb.com/bsm-sdk/core/vars"
|
||||
)
|
||||
|
||||
// Create 创建新分类
|
||||
// 验证用户身份和分类数据,创建分类记录
|
||||
// 参数:
|
||||
// - ctx: 请求上下文,包含用户身份信息
|
||||
// - in: 分类数据,包含标题、父级ID、介绍等
|
||||
//
|
||||
// 返回:
|
||||
// - reply: 操作结果,包含分类ID和时间戳
|
||||
// - err: 错误信息
|
||||
func Create(ctx context.Context, in *pb.CategoryItem) (reply *pb.StatusReply, err error) {
|
||||
// 解析请求上下文,验证用户身份
|
||||
_, err = service.ParseMetaCtx(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 验证分类标题不能为空且长度不超过255字符
|
||||
if in.GetSiteIdentity() == "" || in.GetTitle() == "" || len(in.GetTitle()) > 255 {
|
||||
return nil, errcode.ErrInvalidArgument
|
||||
}
|
||||
|
||||
// 构建分类数据模型
|
||||
data := models.CmsCategory{
|
||||
SiteIdentity: in.GetSiteIdentity(),
|
||||
ParentId: uint(in.GetParentId()), // 父级分类ID,0表示顶级分类
|
||||
CategoryKey: in.GetCategoryKey(), // 分类键值,用于URL等
|
||||
Title: in.GetTitle(), // 分类标题
|
||||
CoverPath: in.GetCoverPath(), // 分类封面图片路径
|
||||
Intro: in.GetIntro(), // 分类介绍
|
||||
}
|
||||
|
||||
// 生成分类唯一标识
|
||||
data.Identity = utils.UUID()
|
||||
|
||||
// 保存分类数据到数据库
|
||||
if err := impl.DBService.Model(&models.CmsCategory{}).Create(&data).Error; err != nil {
|
||||
printer.Error(err.Error())
|
||||
return nil, errcode.ErrDB
|
||||
}
|
||||
|
||||
// 返回成功响应
|
||||
return &pb.StatusReply{
|
||||
Code: 0,
|
||||
Message: vars.OK,
|
||||
Details: data.Identity,
|
||||
Timeseq: time.Now().UnixMilli(),
|
||||
}, nil
|
||||
}
|
||||
33
apps/base/cms/internal/logic/category/delete.go
Normal file
33
apps/base/cms/internal/logic/category/delete.go
Normal file
@@ -0,0 +1,33 @@
|
||||
package category
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"git.apinb.com/bsm-apps/cms/internal/models"
|
||||
pb "git.apinb.com/bsm-apps/cms/pb"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
"git.apinb.com/bsm-sdk/core/service"
|
||||
)
|
||||
|
||||
// 删除分类
|
||||
func Delete(ctx context.Context, in *pb.DeleteCategoryRequest) (reply *pb.StatusReply, err error) {
|
||||
_, err = service.ParseMetaCtx(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if in.GetIdentity() == "" || len(in.GetIdentity()) > 255 {
|
||||
return nil, errcode.ErrInvalidArgument
|
||||
}
|
||||
if err := models.DeleteCategory(in.GetIdentity()); err != nil {
|
||||
printer.Error(err.Error())
|
||||
return nil, err
|
||||
}
|
||||
return &pb.StatusReply{
|
||||
Code: 0,
|
||||
Message: "OK",
|
||||
Timeseq: time.Now().Unix(),
|
||||
}, nil
|
||||
|
||||
}
|
||||
59
apps/base/cms/internal/logic/category/fetch.go
Normal file
59
apps/base/cms/internal/logic/category/fetch.go
Normal file
@@ -0,0 +1,59 @@
|
||||
package category
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"git.apinb.com/bsm-apps/cms/internal/impl"
|
||||
"git.apinb.com/bsm-apps/cms/internal/models"
|
||||
pb "git.apinb.com/bsm-apps/cms/pb"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
)
|
||||
|
||||
// 分类列表
|
||||
func Fetch(ctx context.Context, in *pb.IdentRequest) (reply *pb.CategoryListReply, err error) {
|
||||
// list, cnt, err := logic.CategoryList()
|
||||
var (
|
||||
cnt int64 = 0
|
||||
list []models.CmsCategory
|
||||
)
|
||||
tx := impl.DBService.Debug().Model(&models.CmsCategory{})
|
||||
fmt.Println("in = ", in)
|
||||
if in.GetId() != 0 {
|
||||
tx = tx.Where("parent_id = ?", in.GetId())
|
||||
} else {
|
||||
tx = tx.Where("parent_id = 0")
|
||||
}
|
||||
err = tx.Order("created_at desc").Preload("Children").Count(&cnt).Find(&list).Error
|
||||
if err != nil {
|
||||
return nil, errcode.ErrDB
|
||||
}
|
||||
|
||||
out := &pb.CategoryListReply{
|
||||
Count: cnt,
|
||||
Data: fetchCategory(list),
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func fetchCategory(list []models.CmsCategory) (in []*pb.CategoryItem) {
|
||||
for _, v := range list {
|
||||
item := &pb.CategoryItem{
|
||||
Id: int64(v.ID),
|
||||
Identity: v.Identity,
|
||||
ParentId: int64(v.ParentId),
|
||||
CategoryKey: v.CategoryKey,
|
||||
Title: v.Title,
|
||||
CoverPath: v.CoverPath,
|
||||
Intro: v.Intro,
|
||||
CreatedAt: v.CreatedAt.Format("2006-01-02 15:04:05"),
|
||||
UpdatedAt: v.UpdatedAt.Format("2006-01-02 15:04:05"),
|
||||
Child: make([]*pb.CategoryItem, 0, len(v.Children)),
|
||||
}
|
||||
if len(v.Children) > 0 {
|
||||
item.Child = fetchCategory(v.Children)
|
||||
}
|
||||
in = append(in, item)
|
||||
}
|
||||
return in
|
||||
}
|
||||
44
apps/base/cms/internal/logic/category/modify.go
Normal file
44
apps/base/cms/internal/logic/category/modify.go
Normal file
@@ -0,0 +1,44 @@
|
||||
package category
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"git.apinb.com/bsm-apps/cms/internal/impl"
|
||||
"git.apinb.com/bsm-apps/cms/internal/models"
|
||||
pb "git.apinb.com/bsm-apps/cms/pb"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
"git.apinb.com/bsm-sdk/core/types"
|
||||
)
|
||||
|
||||
// 修改分类
|
||||
func Modify(ctx context.Context, in *pb.ModifyCategoryRequest) (reply *pb.StatusReply, err error) {
|
||||
if in.GetSiteIdentity() == "" || in.GetIdentity() == "" || len(in.GetIdentity()) > 255 {
|
||||
return nil, errcode.ErrInvalidArgument
|
||||
}
|
||||
if in.GetTitle() == "" || len(in.GetTitle()) > 255 {
|
||||
return nil, errcode.ErrInvalidArgument
|
||||
}
|
||||
|
||||
data := &models.CmsCategory{
|
||||
SiteIdentity: in.SiteIdentity,
|
||||
ParentId: uint(in.GetParentId()),
|
||||
CategoryKey: in.GetCategoryKey(),
|
||||
Title: in.GetTitle(),
|
||||
CoverPath: in.GetCoverPath(),
|
||||
Intro: in.GetIntro(),
|
||||
Std_Identity: types.Std_Identity{Identity: in.Identity},
|
||||
}
|
||||
if err := impl.DBService.Where("identity = ?", data.Identity).Updates(data).Error; err != nil {
|
||||
printer.Error(err.Error())
|
||||
return nil, errcode.ErrDB
|
||||
}
|
||||
|
||||
return &pb.StatusReply{
|
||||
Code: 0,
|
||||
Message: "OK",
|
||||
Timeseq: time.Now().Unix(),
|
||||
}, nil
|
||||
|
||||
}
|
||||
129
apps/base/cms/internal/logic/pages/create.go
Normal file
129
apps/base/cms/internal/logic/pages/create.go
Normal file
@@ -0,0 +1,129 @@
|
||||
// Package pages 提供页面相关的业务逻辑处理
|
||||
// 包括页面的创建、修改、删除、查询等功能
|
||||
package pages
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"git.apinb.com/bsm-apps/cms/internal/impl"
|
||||
"git.apinb.com/bsm-apps/cms/internal/models"
|
||||
"git.apinb.com/bsm-apps/cms/internal/utils"
|
||||
pb "git.apinb.com/bsm-apps/cms/pb"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/service"
|
||||
"git.apinb.com/bsm-sdk/core/types"
|
||||
sdkUtils "git.apinb.com/bsm-sdk/core/utils"
|
||||
"git.apinb.com/bsm-sdk/core/vars"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// Create 创建新页面
|
||||
// 验证用户身份和页面数据,创建页面记录并关联标签、附件等信息
|
||||
// 参数:
|
||||
// - ctx: 请求上下文,包含用户身份信息
|
||||
// - in: 页面数据,包含标题、内容、标签等
|
||||
//
|
||||
// 返回:
|
||||
// - reply: 操作结果,包含页面ID和时间戳
|
||||
// - err: 错误信息
|
||||
func Create(ctx context.Context, in *pb.PagesItem) (reply *pb.StatusReply, err error) {
|
||||
// 解析请求上下文,验证用户身份
|
||||
_, err = service.ParseMetaCtx(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 验证必填字段
|
||||
if in.GetSiteIdentity() == "" || in.GetTitle() == "" || in.GetContent() == "" || in.GetKey() == "" {
|
||||
return nil, errcode.ErrInvalidArgument
|
||||
}
|
||||
|
||||
// 构建页面数据模型
|
||||
var data = &models.CmsPages{
|
||||
SiteIdentity: in.SiteIdentity,
|
||||
Title: in.Title,
|
||||
Key: utils.FormatKey(in.Key), // 格式化页面键值,确保唯一性
|
||||
Description: in.Description,
|
||||
CoverPath: in.CoverPath,
|
||||
Content: in.Content,
|
||||
HasAccessory: in.HasAccessory,
|
||||
AccessoryIdentityArray: in.AccessoryIdentityArray,
|
||||
TagsIdentityArray: in.TagsIdentityArray,
|
||||
}
|
||||
|
||||
// 生成页面唯一标识
|
||||
data.Identity = sdkUtils.UUID()
|
||||
|
||||
// 保存页面数据,包括关联的标签、附件信息
|
||||
err = AddPostPages(data, in.AccessoryData, in.TagsIdentityArray)
|
||||
if err != nil {
|
||||
return nil, errcode.ErrDB
|
||||
}
|
||||
|
||||
// 返回成功响应
|
||||
return &pb.StatusReply{
|
||||
Code: 0,
|
||||
Message: vars.OK,
|
||||
Details: data.Identity,
|
||||
Timeseq: time.Now().UnixMilli(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// AddPostPages 添加页面及其关联数据
|
||||
// 使用事务确保数据一致性,同时创建页面、标签关联和附件信息
|
||||
// 参数:
|
||||
// - pages: 页面数据模型
|
||||
// - accessory: 附件数据列表
|
||||
// - tags: 标签标识列表
|
||||
//
|
||||
// 返回:
|
||||
// - err: 错误信息
|
||||
func AddPostPages(pages *models.CmsPages, accessory []*pb.AccessoryItem, tags []string) (err error) {
|
||||
var (
|
||||
accessoryPage = make([]models.CmsAccessory, 0) // 页面附件数据
|
||||
TagsPage = make([]models.CmsRelateTags, 0) // 页面标签关联数据
|
||||
)
|
||||
|
||||
// 构建标签关联数据
|
||||
for _, val := range tags {
|
||||
TagsPage = append(TagsPage, models.CmsRelateTags{
|
||||
Identity: sdkUtils.ULID(),
|
||||
PagesIdentity: pages.Identity,
|
||||
TagsIdentity: val,
|
||||
})
|
||||
}
|
||||
|
||||
// 使用事务确保数据一致性
|
||||
return impl.DBService.Transaction(func(tx *gorm.DB) error {
|
||||
// 创建页面记录
|
||||
if err = tx.Create(pages).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 创建附件关联记录
|
||||
if len(accessory) != 0 {
|
||||
for _, v := range accessory {
|
||||
accessoryPage = append(accessoryPage, models.CmsAccessory{
|
||||
Std_Identity: types.Std_Identity{Identity: sdkUtils.UUID()},
|
||||
PagesId: pages.ID,
|
||||
PagesIdentity: pages.Identity,
|
||||
FilePath: v.FilePath,
|
||||
Title: v.Title,
|
||||
})
|
||||
}
|
||||
if err := tx.Create(&accessoryPage).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// 创建标签关联记录
|
||||
if len(tags) != 0 {
|
||||
if err := tx.Create(&TagsPage).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
52
apps/base/cms/internal/logic/pages/delete.go
Normal file
52
apps/base/cms/internal/logic/pages/delete.go
Normal file
@@ -0,0 +1,52 @@
|
||||
package pages
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"git.apinb.com/bsm-apps/cms/internal/impl"
|
||||
"git.apinb.com/bsm-apps/cms/internal/models"
|
||||
pb "git.apinb.com/bsm-apps/cms/pb"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/service"
|
||||
"git.apinb.com/bsm-sdk/core/vars"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// 删除文章
|
||||
func Delete(ctx context.Context, in *pb.IdentRequest) (reply *pb.StatusReply, err error) {
|
||||
// parse authorization meta.
|
||||
_, err = service.ParseMetaCtx(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if in.Identity == "" {
|
||||
return nil, errcode.ErrInvalidArgument
|
||||
}
|
||||
err = DeletePages(in.Identity)
|
||||
if err != nil {
|
||||
return nil, errcode.ErrDB
|
||||
}
|
||||
return &pb.StatusReply{
|
||||
Code: 0,
|
||||
Message: vars.OK,
|
||||
Timeseq: time.Now().UnixMilli(),
|
||||
}, nil
|
||||
|
||||
}
|
||||
|
||||
func DeletePages(identity string) (err error) {
|
||||
return impl.DBService.Transaction(func(tx *gorm.DB) error {
|
||||
if err = tx.Where("identity = ?", identity).Delete(&models.CmsPages{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if err = tx.Where("pages_identity = ?", identity).Delete(&models.CmsRelateTags{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if err = tx.Where("pages_identity = ?", identity).Delete(&models.CmsAccessory{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
17
apps/base/cms/internal/logic/pages/ext.go
Normal file
17
apps/base/cms/internal/logic/pages/ext.go
Normal file
@@ -0,0 +1,17 @@
|
||||
package pages
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func fmtKey(in string) string {
|
||||
in = strings.ToLower(in)
|
||||
in = strings.TrimSpace(in)
|
||||
|
||||
re := regexp.MustCompile(`\s+`)
|
||||
in = re.ReplaceAllString(in, " ")
|
||||
in = strings.ReplaceAll(in, " ", "-")
|
||||
|
||||
return in
|
||||
}
|
||||
103
apps/base/cms/internal/logic/pages/fetch.go
Normal file
103
apps/base/cms/internal/logic/pages/fetch.go
Normal file
@@ -0,0 +1,103 @@
|
||||
package pages
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"git.apinb.com/bsm-apps/cms/internal/impl"
|
||||
"git.apinb.com/bsm-apps/cms/internal/models"
|
||||
pb "git.apinb.com/bsm-apps/cms/pb"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
)
|
||||
|
||||
// 文章列表
|
||||
func Fetch(ctx context.Context, in *pb.PagesListRequest) (reply *pb.PagesListReply, err error) {
|
||||
if in.GetPage() < 1 {
|
||||
in.Page = 1
|
||||
}
|
||||
if in.GetSize() < 10 {
|
||||
in.Size = 10
|
||||
}
|
||||
if in.GetSize() > 50 {
|
||||
in.Size = 50
|
||||
}
|
||||
list, cnt, err := PagesList(in.Page, in.Size, in.Keyword, int64(in.Type))
|
||||
if err != nil {
|
||||
printer.Error(err.Error())
|
||||
return nil, errcode.ErrDB
|
||||
}
|
||||
var res = pb.PagesListReply{
|
||||
Count: cnt,
|
||||
Data: make([]*pb.PagesItem, 0),
|
||||
}
|
||||
for _, val := range list {
|
||||
var (
|
||||
accessoryData = make([]*pb.AccessoryItem, 0)
|
||||
accessories = make([]string, 0)
|
||||
|
||||
TagsData = make([]*pb.TagsItem, 0)
|
||||
tagsIdentityArray = make([]string, 0)
|
||||
)
|
||||
for _, accessory := range val.Accessories {
|
||||
accessoryData = append(accessoryData, &pb.AccessoryItem{
|
||||
Identity: accessory.Identity,
|
||||
Title: accessory.Title,
|
||||
FilePath: accessory.FilePath,
|
||||
CreatedAt: accessory.CreatedAt.Format(time.DateTime),
|
||||
})
|
||||
accessories = append(accessories, accessory.Identity)
|
||||
}
|
||||
|
||||
for _, tags := range val.Tags {
|
||||
TagsData = append(TagsData, &pb.TagsItem{
|
||||
Id: int64(tags.Tags.ID),
|
||||
Identity: tags.TagsIdentity,
|
||||
Title: tags.Tags.Title,
|
||||
Intro: tags.Tags.Intro,
|
||||
CoverPath: tags.Tags.CoverPath,
|
||||
CreatedAt: tags.Tags.CreatedAt.Format(time.DateTime),
|
||||
})
|
||||
tagsIdentityArray = append(tagsIdentityArray, tags.TagsIdentity)
|
||||
}
|
||||
|
||||
res.Data = append(res.Data, &pb.PagesItem{
|
||||
Identity: val.Identity,
|
||||
Title: val.Title,
|
||||
CoverPath: val.CoverPath,
|
||||
Content: val.Content,
|
||||
Hits: val.Hits,
|
||||
HasAccessory: val.HasAccessory,
|
||||
CreatedAt: val.CreatedAt.Format(time.DateTime),
|
||||
UpdatedAt: val.UpdatedAt.Format(time.DateTime),
|
||||
Description: val.Description,
|
||||
PostType: val.Type,
|
||||
Key: val.Key,
|
||||
AccessoryData: accessoryData,
|
||||
AccessoryIdentityArray: accessories,
|
||||
TagsData: TagsData,
|
||||
TagsIdentityArray: tagsIdentityArray,
|
||||
})
|
||||
}
|
||||
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
func PagesList(page, size int64, keyword string, userType int64) (list []*models.CmsPages, cnt int64, err error) {
|
||||
|
||||
tx := impl.DBService.Model(&models.CmsPages{})
|
||||
|
||||
if keyword != "" {
|
||||
tx = tx.Where("Cms_pages.title like ?", "%"+keyword+"%")
|
||||
}
|
||||
|
||||
if userType != 0 {
|
||||
tx = tx.Where("Cms_pages.type = ?", userType)
|
||||
}
|
||||
|
||||
if err = tx.Count(&cnt).Order("Cms_pages.created_at desc").Limit(int(size)).Offset(int((page - 1) * size)).Error; err != nil {
|
||||
return nil, 0, errcode.ErrDB
|
||||
}
|
||||
err = tx.Preload("Accessories").Preload("Tags.Tags").Find(&list).Error
|
||||
return
|
||||
}
|
||||
81
apps/base/cms/internal/logic/pages/get_by_identity.go
Normal file
81
apps/base/cms/internal/logic/pages/get_by_identity.go
Normal file
@@ -0,0 +1,81 @@
|
||||
package pages
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"git.apinb.com/bsm-apps/cms/internal/impl"
|
||||
"git.apinb.com/bsm-apps/cms/internal/models"
|
||||
pb "git.apinb.com/bsm-apps/cms/pb"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// 获取文章详情 By Identity
|
||||
func GetByIdentity(ctx context.Context, in *pb.GetPagesRequest) (reply *pb.PagesItem, err error) {
|
||||
if in.GetIdentity() == "" {
|
||||
return nil, errcode.ErrInvalidArgument
|
||||
}
|
||||
|
||||
data, err := GetPages("Cms_pages.identity", in.Identity)
|
||||
if err != nil {
|
||||
printer.Error(err.Error())
|
||||
return nil, errcode.ErrDB
|
||||
}
|
||||
var res = &pb.PagesItem{}
|
||||
if data != nil {
|
||||
res.Identity = data.Identity
|
||||
res.Title = data.Title
|
||||
res.CoverPath = data.CoverPath
|
||||
res.Content = data.Content
|
||||
res.Hits = data.Hits
|
||||
res.HasAccessory = data.HasAccessory
|
||||
res.CreatedAt = data.CreatedAt.String()
|
||||
res.UpdatedAt = data.UpdatedAt.String()
|
||||
res.Description = data.Description
|
||||
res.PostType = data.Type
|
||||
}
|
||||
for _, val := range data.Accessories {
|
||||
res.AccessoryData = append(res.AccessoryData, &pb.AccessoryItem{
|
||||
Identity: val.Identity,
|
||||
Title: val.Title,
|
||||
FilePath: val.FilePath,
|
||||
CreatedAt: val.CreatedAt.Format(time.DateTime),
|
||||
})
|
||||
}
|
||||
for _, val := range data.Accessories {
|
||||
res.AccessoryIdentityArray = append(res.AccessoryIdentityArray, val.Identity)
|
||||
}
|
||||
|
||||
for _, val := range data.Tags {
|
||||
res.TagsData = append(res.TagsData, &pb.TagsItem{
|
||||
Id: int64(val.ID),
|
||||
Identity: val.Tags.Identity,
|
||||
Title: val.Tags.Title,
|
||||
Intro: val.Tags.Intro,
|
||||
CoverPath: val.Tags.CoverPath,
|
||||
CreatedAt: val.Tags.CreatedAt.Format(time.DateTime),
|
||||
})
|
||||
}
|
||||
for _, val := range data.Tags {
|
||||
res.TagsIdentityArray = append(res.TagsIdentityArray, val.Identity)
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func GetPages(key, val string) (*models.CmsPages, error) {
|
||||
var pages = models.CmsPages{}
|
||||
//// 使用事务确保操作
|
||||
// 查询帖子并更新点击量
|
||||
err := impl.DBService.Model(&models.CmsPages{}).Debug().Preload("Accessories").Preload("Tags.Tags").
|
||||
Where(key+" = ?", val).First(&pages).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := impl.DBService.Model(&models.CmsPages{}).Where("key = ?", val).
|
||||
UpdateColumn("hits", gorm.Expr("hits + 1")).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &pages, err
|
||||
}
|
||||
63
apps/base/cms/internal/logic/pages/get_by_key.go
Normal file
63
apps/base/cms/internal/logic/pages/get_by_key.go
Normal file
@@ -0,0 +1,63 @@
|
||||
package pages
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
pb "git.apinb.com/bsm-apps/cms/pb"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
)
|
||||
|
||||
// 获取文章详情 By Key
|
||||
func GetByKey(ctx context.Context, in *pb.GetPagesByKeyRequest) (reply *pb.PagesItem, err error) {
|
||||
if in.GetKey() == "" {
|
||||
return nil, errcode.ErrInvalidArgument
|
||||
}
|
||||
|
||||
data, err := GetPages("key", in.Key)
|
||||
if err != nil {
|
||||
printer.Error(err.Error())
|
||||
return nil, errcode.ErrDB
|
||||
}
|
||||
|
||||
var res = &pb.PagesItem{}
|
||||
if data != nil {
|
||||
res.Identity = data.Identity
|
||||
res.Title = data.Title
|
||||
res.CoverPath = data.CoverPath
|
||||
res.Content = data.Content
|
||||
res.Hits = data.Hits
|
||||
res.HasAccessory = data.HasAccessory
|
||||
res.CreatedAt = data.CreatedAt.String()
|
||||
res.UpdatedAt = data.UpdatedAt.String()
|
||||
res.Description = data.Description
|
||||
res.PostType = data.Type
|
||||
}
|
||||
for _, val := range data.Accessories {
|
||||
res.AccessoryData = append(res.AccessoryData, &pb.AccessoryItem{
|
||||
Identity: val.Identity,
|
||||
Title: val.Title,
|
||||
FilePath: val.FilePath,
|
||||
CreatedAt: val.CreatedAt.Format(time.DateTime),
|
||||
})
|
||||
}
|
||||
for _, val := range data.Accessories {
|
||||
res.AccessoryIdentityArray = append(res.AccessoryIdentityArray, val.Identity)
|
||||
}
|
||||
|
||||
for _, val := range data.Tags {
|
||||
res.TagsData = append(res.TagsData, &pb.TagsItem{
|
||||
Id: int64(val.ID),
|
||||
Identity: val.Tags.Identity,
|
||||
Title: val.Tags.Title,
|
||||
Intro: val.Tags.Intro,
|
||||
CoverPath: val.Tags.CoverPath,
|
||||
CreatedAt: val.Tags.CreatedAt.Format(time.DateTime),
|
||||
})
|
||||
}
|
||||
for _, val := range data.Tags {
|
||||
res.TagsIdentityArray = append(res.TagsIdentityArray, val.Identity)
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
102
apps/base/cms/internal/logic/pages/modify.go
Normal file
102
apps/base/cms/internal/logic/pages/modify.go
Normal file
@@ -0,0 +1,102 @@
|
||||
package pages
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"git.apinb.com/bsm-apps/cms/internal/impl"
|
||||
"git.apinb.com/bsm-apps/cms/internal/models"
|
||||
pb "git.apinb.com/bsm-apps/cms/pb"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/service"
|
||||
"git.apinb.com/bsm-sdk/core/types"
|
||||
"git.apinb.com/bsm-sdk/core/utils"
|
||||
"git.apinb.com/bsm-sdk/core/vars"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// 修改文章
|
||||
func Modify(ctx context.Context, in *pb.PagesItem) (reply *pb.StatusReply, err error) {
|
||||
// parse authorization meta.
|
||||
_, err = service.ParseMetaCtx(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// TODO: valid code
|
||||
if in.GetSiteIdentity() == "" || in.GetIdentity() == "" {
|
||||
return nil, errcode.ErrInvalidArgument
|
||||
}
|
||||
var data = &models.CmsPages{
|
||||
SiteIdentity: in.SiteIdentity,
|
||||
Title: in.Title,
|
||||
Key: in.Key,
|
||||
Description: in.Description,
|
||||
CoverPath: in.CoverPath,
|
||||
Content: in.Content,
|
||||
HasAccessory: in.HasAccessory,
|
||||
AccessoryIdentityArray: in.AccessoryIdentityArray,
|
||||
TagsIdentityArray: in.TagsIdentityArray,
|
||||
}
|
||||
err = ModifyPages(in.Identity, data, in.AccessoryData, in.TagsIdentityArray)
|
||||
if err != nil {
|
||||
return nil, errcode.ErrDB
|
||||
}
|
||||
// TODO: add your logic code & delete this line.
|
||||
|
||||
return &pb.StatusReply{
|
||||
Code: 0,
|
||||
Message: vars.OK,
|
||||
Timeseq: time.Now().UnixMilli(),
|
||||
}, nil
|
||||
|
||||
}
|
||||
|
||||
func ModifyPages(identity string, pages *models.CmsPages, accessory []*pb.AccessoryItem, tags []string) (err error) {
|
||||
var (
|
||||
accessoryPath = make([]models.CmsAccessory, 0)
|
||||
tagsData = make([]models.CmsRelateTags, 0)
|
||||
)
|
||||
|
||||
for _, val := range tags {
|
||||
tagsData = append(tagsData, models.CmsRelateTags{
|
||||
Identity: utils.ULID(),
|
||||
PagesIdentity: identity,
|
||||
TagsIdentity: val,
|
||||
})
|
||||
}
|
||||
for _, v := range accessory {
|
||||
accessoryPath = append(accessoryPath, models.CmsAccessory{
|
||||
Std_Identity: types.Std_Identity{Identity: utils.UUID()},
|
||||
PagesId: pages.ID,
|
||||
PagesIdentity: identity,
|
||||
FilePath: v.FilePath,
|
||||
})
|
||||
}
|
||||
return impl.DBService.Transaction(func(tx *gorm.DB) error {
|
||||
if err = tx.Where("identity = ?", identity).Updates(pages).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
// 删除旧的附件、分类和标签关联
|
||||
if err := tx.Where("pages_identity = ?", identity).Delete(&models.CmsAccessory{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := tx.Where("pages_identity = ?", identity).Delete(&models.CmsRelateTags{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
// 创建新的标签关联
|
||||
if len(tags) != 0 {
|
||||
if err := tx.Create(&tagsData).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
// 创建新的附件关联
|
||||
if len(accessory) != 0 {
|
||||
if err := tx.Create(&accessoryPath).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
51
apps/base/cms/internal/logic/post/add_comment.go
Normal file
51
apps/base/cms/internal/logic/post/add_comment.go
Normal file
@@ -0,0 +1,51 @@
|
||||
package post
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"git.apinb.com/bsm-apps/cms/internal/impl"
|
||||
"git.apinb.com/bsm-apps/cms/internal/models"
|
||||
pb "git.apinb.com/bsm-apps/cms/pb"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
"git.apinb.com/bsm-sdk/core/service"
|
||||
"git.apinb.com/bsm-sdk/core/types"
|
||||
"git.apinb.com/bsm-sdk/core/utils"
|
||||
"git.apinb.com/bsm-sdk/core/vars"
|
||||
)
|
||||
|
||||
// 发布评论
|
||||
func AddComment(ctx context.Context, in *pb.CommentItem) (*pb.StatusReply, error) {
|
||||
auth, err := service.ParseMetaCtx(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var data = models.CmsComment{
|
||||
Std_Identity: types.Std_Identity{Identity: utils.ULID()},
|
||||
PostIdentity: in.PostIdentity,
|
||||
OwnerIdentity: auth.Identity,
|
||||
Role: auth.Role,
|
||||
ParentId: uint(in.ParentId),
|
||||
ReplyIdentity: in.ReplyIdentity,
|
||||
Cms: in.Cms,
|
||||
}
|
||||
authName := map[string]any{}
|
||||
err = impl.DBService.Table("mall_staff").Take(&authName, "identity=?", auth.Identity).Error
|
||||
if err != nil {
|
||||
printer.Error(err.Error())
|
||||
return nil, errcode.ErrDB
|
||||
}
|
||||
data.OwnerName = authName["name"].(string)
|
||||
err = models.AddComment(&data, auth.Identity)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &pb.StatusReply{
|
||||
Code: 0,
|
||||
Message: vars.OK,
|
||||
Details: data.Identity,
|
||||
Timeseq: time.Now().Unix(),
|
||||
}, nil
|
||||
}
|
||||
80
apps/base/cms/internal/logic/post/comment_list.go
Normal file
80
apps/base/cms/internal/logic/post/comment_list.go
Normal file
@@ -0,0 +1,80 @@
|
||||
package post
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"git.apinb.com/bsm-apps/cms/internal/impl"
|
||||
"git.apinb.com/bsm-apps/cms/internal/models"
|
||||
pb "git.apinb.com/bsm-apps/cms/pb"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
)
|
||||
|
||||
// 评论列表
|
||||
func CommentList(ctx context.Context, in *pb.CommentListRequest) (*pb.CommentListResponse, error) {
|
||||
var (
|
||||
page = in.GetPage()
|
||||
size = in.GetSize()
|
||||
postIdentity = in.GetPostIdentity()
|
||||
list = make([]models.CmsComment, 0)
|
||||
cnt int64 = 0
|
||||
)
|
||||
// _, err := service.ParseMetaCtx(ctx, nil)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
|
||||
if in.GetPostIdentity() == "" {
|
||||
fmt.Println("err = ", in.GetPostIdentity())
|
||||
return nil, errcode.ErrInvalidArgument
|
||||
}
|
||||
|
||||
if in.GetPage() < 1 {
|
||||
in.Page = 1
|
||||
}
|
||||
if in.GetSize() < 10 {
|
||||
in.Size = 10
|
||||
}
|
||||
if in.GetSize() > 50 {
|
||||
in.Size = 50
|
||||
}
|
||||
// list, cnt, err := logic.CommentList(in.Page, in.Size, in.PostIdentity)
|
||||
if err := impl.DBService.Model(&models.CmsComment{}).Debug().Where("post_identity = ?", postIdentity).
|
||||
Order("created_at desc").Preload("Children").Count(&cnt).
|
||||
Limit(int(size)).Offset(int((page - 1) * size)).Find(&list).Error; err != nil {
|
||||
printer.Error(err.Error())
|
||||
return nil, errcode.ErrDB
|
||||
}
|
||||
return &pb.CommentListResponse{
|
||||
List: GetCommentList(list),
|
||||
Count: cnt,
|
||||
}, nil
|
||||
}
|
||||
func GetCommentList(list []models.CmsComment) (res []*pb.CommentItem) {
|
||||
for _, val := range list {
|
||||
var comment = &pb.CommentItem{
|
||||
Identity: val.Identity,
|
||||
PostIdentity: val.PostIdentity,
|
||||
OwnerName: val.OwnerName,
|
||||
OwnerIdentity: val.OwnerIdentity,
|
||||
Role: val.Role,
|
||||
ParentId: int64(val.ParentId),
|
||||
Cms: val.Cms,
|
||||
ReplyIdentity: val.ReplyIdentity,
|
||||
CreatedAt: val.CreatedAt.Format(time.DateTime),
|
||||
UpdatedAt: val.UpdatedAt.Format(time.DateTime),
|
||||
LikeHits: val.LikeHits,
|
||||
UnlikeHits: val.UnlikeHits,
|
||||
CommentHits: val.CommentHits,
|
||||
}
|
||||
|
||||
if len(val.Children) != 0 {
|
||||
comment.List = GetCommentList(val.Children)
|
||||
}
|
||||
res = append(res, comment)
|
||||
|
||||
}
|
||||
return res
|
||||
}
|
||||
74
apps/base/cms/internal/logic/post/create.go
Normal file
74
apps/base/cms/internal/logic/post/create.go
Normal file
@@ -0,0 +1,74 @@
|
||||
// Package post 提供文章相关的业务逻辑处理
|
||||
// 包括文章的创建、修改、删除、查询等功能
|
||||
package post
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"git.apinb.com/bsm-apps/cms/internal/models"
|
||||
"git.apinb.com/bsm-apps/cms/internal/utils"
|
||||
pb "git.apinb.com/bsm-apps/cms/pb"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/service"
|
||||
sdkUtils "git.apinb.com/bsm-sdk/core/utils"
|
||||
"git.apinb.com/bsm-sdk/core/vars"
|
||||
)
|
||||
|
||||
// Create 创建新文章
|
||||
// 验证用户身份和文章数据,创建文章记录并关联分类、标签、附件等信息
|
||||
// 参数:
|
||||
// - ctx: 请求上下文,包含用户身份信息
|
||||
// - in: 文章数据,包含标题、内容、分类、标签等
|
||||
//
|
||||
// 返回:
|
||||
// - reply: 操作结果,包含文章ID和时间戳
|
||||
// - err: 错误信息
|
||||
func Create(ctx context.Context, in *pb.PostItem) (reply *pb.StatusReply, err error) {
|
||||
// 解析请求上下文,获取用户身份信息
|
||||
authCtx, err := service.ParseMetaCtx(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 验证必填字段
|
||||
if in.GetSiteIdentity() == "" || in.GetTitle() == "" || in.GetContent() == "" || in.GetKey() == "" {
|
||||
return nil, errcode.ErrInvalidArgument
|
||||
}
|
||||
|
||||
// 构建文章数据模型
|
||||
var data = &models.CmsPost{
|
||||
SiteIdentity: in.SiteIdentity,
|
||||
Title: in.Title,
|
||||
Hash: utils.FormatKey(in.Key), // 格式化文章键值,确保唯一性
|
||||
Description: in.Description,
|
||||
CoverPath: in.CoverPath,
|
||||
Author: in.Author,
|
||||
AuthorIdentity: authCtx.Identity, // 设置作者身份标识
|
||||
Content: in.Content,
|
||||
TargetUrl: in.TargetUrl,
|
||||
SourceUrl: in.SourceUrl,
|
||||
HasAccessory: in.HasAccessory,
|
||||
Types: in.PostType,
|
||||
AccessoryIdentityArray: in.AccessoryIdentityArray,
|
||||
CategoryIdentityArray: in.CategoryIdentityArray,
|
||||
TagsIdentityArray: in.TagsIdentityArray,
|
||||
}
|
||||
|
||||
// 生成文章唯一标识
|
||||
data.Identity = sdkUtils.UUID()
|
||||
|
||||
// 保存文章数据,包括关联的分类、标签、附件信息
|
||||
err = models.AddPost(data, in.AccessoryData, in.CategoryIdentityArray, in.TagsIdentityArray)
|
||||
if err != nil {
|
||||
return nil, errcode.ErrDB
|
||||
}
|
||||
|
||||
// 返回成功响应
|
||||
return &pb.StatusReply{
|
||||
Code: 0,
|
||||
Message: vars.OK,
|
||||
Details: data.Identity,
|
||||
Timeseq: time.Now().Unix(),
|
||||
}, nil
|
||||
}
|
||||
40
apps/base/cms/internal/logic/post/delete.go
Normal file
40
apps/base/cms/internal/logic/post/delete.go
Normal file
@@ -0,0 +1,40 @@
|
||||
package post
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"git.apinb.com/bsm-apps/cms/internal/models"
|
||||
pb "git.apinb.com/bsm-apps/cms/pb"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/service"
|
||||
)
|
||||
|
||||
// 删除文章
|
||||
func Delete(ctx context.Context, in *pb.IdentRequest) (reply *pb.StatusReply, err error) {
|
||||
// parse authorization meta.
|
||||
_, err = service.ParseMetaCtx(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// valildate request id,identity.
|
||||
if in.Id == 0 && in.Identity == "" {
|
||||
return nil, errcode.ErrInvalidArgument
|
||||
}
|
||||
|
||||
if in.GetIdentity() == "" {
|
||||
return nil, errcode.ErrInvalidArgument
|
||||
}
|
||||
err = models.DeletePost(in.Identity, "") // Todo:
|
||||
if err != nil {
|
||||
return nil, errcode.ErrDB
|
||||
}
|
||||
|
||||
return &pb.StatusReply{
|
||||
Code: 0,
|
||||
Message: "OK",
|
||||
Timeseq: time.Now().Unix(),
|
||||
}, nil
|
||||
|
||||
}
|
||||
30
apps/base/cms/internal/logic/post/delete_comment.go
Normal file
30
apps/base/cms/internal/logic/post/delete_comment.go
Normal file
@@ -0,0 +1,30 @@
|
||||
package post
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/service"
|
||||
|
||||
"git.apinb.com/bsm-apps/cms/internal/models"
|
||||
pb "git.apinb.com/bsm-apps/cms/pb"
|
||||
)
|
||||
|
||||
// DeleteComment 删除评论
|
||||
func DeleteComment(ctx context.Context, in *pb.DeleteCommentRequest) (*pb.StatusReply, error) {
|
||||
_, err := service.ParseMetaCtx(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if in.GetIdentity() == "" {
|
||||
return nil, errcode.ErrInvalidArgument
|
||||
}
|
||||
err = models.DeleteComment(in.Identity)
|
||||
if err != nil {
|
||||
fmt.Println()
|
||||
return nil, errcode.ErrDB
|
||||
}
|
||||
return &pb.StatusReply{}, nil
|
||||
}
|
||||
30
apps/base/cms/internal/logic/post/desc_comment_like.go
Normal file
30
apps/base/cms/internal/logic/post/desc_comment_like.go
Normal file
@@ -0,0 +1,30 @@
|
||||
package post
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/service"
|
||||
|
||||
"git.apinb.com/bsm-apps/cms/internal/models"
|
||||
pb "git.apinb.com/bsm-apps/cms/pb"
|
||||
)
|
||||
|
||||
// DescCommentLike 减少评论点赞数
|
||||
func DescCommentLike(ctx context.Context, in *pb.CommentOpIdentityRequest) (*pb.StatusReply, error) {
|
||||
_, err := service.ParseMetaCtx(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if in.GetCommentIdentity() == "" || in.GetOpIdentity() == "" {
|
||||
return nil, errcode.ErrInvalidArgument
|
||||
}
|
||||
|
||||
err = models.IncrOrDescCommentField(in.CommentIdentity, "like_hits", true)
|
||||
if err != nil {
|
||||
return nil, errcode.ErrDB
|
||||
}
|
||||
|
||||
return &pb.StatusReply{}, nil
|
||||
}
|
||||
30
apps/base/cms/internal/logic/post/desc_comment_unlike.go
Normal file
30
apps/base/cms/internal/logic/post/desc_comment_unlike.go
Normal file
@@ -0,0 +1,30 @@
|
||||
package post
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/service"
|
||||
|
||||
"git.apinb.com/bsm-apps/cms/internal/models"
|
||||
pb "git.apinb.com/bsm-apps/cms/pb"
|
||||
)
|
||||
|
||||
// DescCommentUnlike 减少评论踩
|
||||
func DescCommentUnlike(ctx context.Context, in *pb.CommentOpIdentityRequest) (*pb.StatusReply, error) {
|
||||
_, err := service.ParseMetaCtx(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if in.GetCommentIdentity() == "" || in.GetOpIdentity() == "" {
|
||||
return nil, errcode.ErrInvalidArgument
|
||||
}
|
||||
|
||||
err = models.IncrOrDescCommentField(in.CommentIdentity, "unlike_hits", true)
|
||||
if err != nil {
|
||||
return nil, errcode.ErrDB
|
||||
}
|
||||
|
||||
return &pb.StatusReply{}, nil
|
||||
}
|
||||
31
apps/base/cms/internal/logic/post/desc_post_like.go
Normal file
31
apps/base/cms/internal/logic/post/desc_post_like.go
Normal file
@@ -0,0 +1,31 @@
|
||||
package post
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"git.apinb.com/bsm-apps/cms/internal/models"
|
||||
pb "git.apinb.com/bsm-apps/cms/pb"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
"git.apinb.com/bsm-sdk/core/service"
|
||||
)
|
||||
|
||||
// DescPostLike 处理帖子的点赞减少操作
|
||||
func DescPostLike(ctx context.Context, in *pb.PostOpIdentityRequest) (*pb.StatusReply, error) {
|
||||
_, err := service.ParseMetaCtx(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if in.GetOpIdentity() == "" || in.GetPostIdentity() == "" {
|
||||
return nil, errcode.ErrInvalidArgument
|
||||
}
|
||||
|
||||
err = models.IncrOrDescPostField(in.PostIdentity, "like_hits", true)
|
||||
if err != nil {
|
||||
printer.Error(err.Error())
|
||||
return nil, errcode.ErrDB
|
||||
}
|
||||
|
||||
return &pb.StatusReply{}, nil
|
||||
}
|
||||
31
apps/base/cms/internal/logic/post/desc_post_unlike.go
Normal file
31
apps/base/cms/internal/logic/post/desc_post_unlike.go
Normal file
@@ -0,0 +1,31 @@
|
||||
package post
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"git.apinb.com/bsm-apps/cms/internal/models"
|
||||
pb "git.apinb.com/bsm-apps/cms/pb"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
"git.apinb.com/bsm-sdk/core/service"
|
||||
)
|
||||
|
||||
// DescPostUnlike 处理用户取消点赞帖子的操作
|
||||
func DescPostUnlike(ctx context.Context, in *pb.PostOpIdentityRequest) (*pb.StatusReply, error) {
|
||||
_, err := service.ParseMetaCtx(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if in.GetOpIdentity() == "" || in.GetPostIdentity() == "" {
|
||||
return nil, errcode.ErrInvalidArgument
|
||||
}
|
||||
|
||||
err = models.IncrOrDescPostField(in.PostIdentity, "unlike_hits", true)
|
||||
if err != nil {
|
||||
printer.Error(err.Error())
|
||||
return nil, errcode.ErrDB
|
||||
}
|
||||
|
||||
return &pb.StatusReply{}, nil
|
||||
}
|
||||
17
apps/base/cms/internal/logic/post/ext.go
Normal file
17
apps/base/cms/internal/logic/post/ext.go
Normal file
@@ -0,0 +1,17 @@
|
||||
package post
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func fmtKey(in string) string {
|
||||
in = strings.ToLower(in)
|
||||
in = strings.TrimSpace(in)
|
||||
|
||||
re := regexp.MustCompile(`\s+`)
|
||||
in = re.ReplaceAllString(in, " ")
|
||||
in = strings.ReplaceAll(in, " ", "-")
|
||||
|
||||
return in
|
||||
}
|
||||
107
apps/base/cms/internal/logic/post/fetch.go
Normal file
107
apps/base/cms/internal/logic/post/fetch.go
Normal file
@@ -0,0 +1,107 @@
|
||||
package post
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"git.apinb.com/bsm-apps/cms/internal/models"
|
||||
pb "git.apinb.com/bsm-apps/cms/pb"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
)
|
||||
|
||||
// 文章列表
|
||||
func Fetch(ctx context.Context, in *pb.PostListRequest) (reply *pb.PostListReply, err error) {
|
||||
if in.GetPage() <= 0 {
|
||||
in.Page = 1
|
||||
}
|
||||
if in.GetSize() <= 0 {
|
||||
in.Size = 10
|
||||
}
|
||||
if in.GetSize() > 50 {
|
||||
in.Size = 50
|
||||
}
|
||||
list, cnt, err := models.PostList(in.Page, in.Size, in.CategoryIdentity, in.Keyword, int64(in.Type))
|
||||
if err != nil {
|
||||
printer.Error(err.Error())
|
||||
return nil, errcode.ErrDB
|
||||
}
|
||||
var res = pb.PostListReply{
|
||||
Count: cnt,
|
||||
Data: make([]*pb.PostItem, 0),
|
||||
}
|
||||
for _, val := range list {
|
||||
var (
|
||||
accessoryData = make([]*pb.AccessoryItem, 0)
|
||||
accessories = make([]string, 0)
|
||||
|
||||
categoryData = make([]*pb.CategoryItem, 0)
|
||||
categories = make([]string, 0)
|
||||
|
||||
TagsData = make([]*pb.TagsItem, 0)
|
||||
tagsIdentityArray = make([]string, 0)
|
||||
)
|
||||
for _, accessory := range val.Accessories {
|
||||
accessoryData = append(accessoryData, &pb.AccessoryItem{
|
||||
Identity: accessory.Identity,
|
||||
Title: accessory.Title,
|
||||
FilePath: accessory.FilePath,
|
||||
})
|
||||
accessories = append(accessories, accessory.Identity)
|
||||
}
|
||||
for _, category := range val.Categories {
|
||||
categoryData = append(categoryData, &pb.CategoryItem{
|
||||
Id: int64(category.Category.ID),
|
||||
Identity: category.Category.Identity,
|
||||
ParentId: int64(category.Category.ParentId),
|
||||
Title: category.Category.Title,
|
||||
CoverPath: category.Category.CoverPath,
|
||||
Intro: category.Category.Intro,
|
||||
})
|
||||
categories = append(categories, category.CategoryIdentity)
|
||||
}
|
||||
for _, tags := range val.Tags {
|
||||
TagsData = append(TagsData, &pb.TagsItem{
|
||||
Id: int64(tags.Tags.ID),
|
||||
Identity: tags.TagsIdentity,
|
||||
Title: tags.Tags.Title,
|
||||
Intro: tags.Tags.Intro,
|
||||
CoverPath: tags.Tags.CoverPath,
|
||||
})
|
||||
tagsIdentityArray = append(tagsIdentityArray, tags.TagsIdentity)
|
||||
}
|
||||
|
||||
res.Data = append(res.Data, &pb.PostItem{
|
||||
Identity: val.Identity,
|
||||
OwnerId: int64(val.OwnerID),
|
||||
OwnerIdentity: val.OwnerIdentity,
|
||||
Title: val.Title,
|
||||
CoverPath: val.CoverPath,
|
||||
Author: val.Author,
|
||||
AuthorIdentity: val.AuthorIdentity,
|
||||
Content: val.Content,
|
||||
TargetUrl: val.TargetUrl,
|
||||
SourceUrl: val.SourceUrl,
|
||||
Hits: val.Hits,
|
||||
HasAccessory: val.HasAccessory,
|
||||
CreatedAt: val.CreatedAt.Format(time.DateTime),
|
||||
UpdatedAt: val.UpdatedAt.Format(time.DateTime),
|
||||
Description: val.Description,
|
||||
LikeHits: val.LikeHits,
|
||||
UnlikeHits: val.UnlikeHits,
|
||||
CommentHits: val.CommentHits,
|
||||
PostType: val.Types,
|
||||
Key: val.Hash,
|
||||
Hash: val.Hash,
|
||||
AccessoryData: accessoryData,
|
||||
AccessoryIdentityArray: accessories,
|
||||
CategoryData: categoryData,
|
||||
CategoryIdentityArray: categories,
|
||||
TagsData: TagsData,
|
||||
TagsIdentityArray: tagsIdentityArray,
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
return &res, nil
|
||||
}
|
||||
82
apps/base/cms/internal/logic/post/get_by_identity.go
Normal file
82
apps/base/cms/internal/logic/post/get_by_identity.go
Normal file
@@ -0,0 +1,82 @@
|
||||
package post
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"git.apinb.com/bsm-apps/cms/internal/models"
|
||||
pb "git.apinb.com/bsm-apps/cms/pb"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
)
|
||||
|
||||
// 获取文章详情 By Identity
|
||||
func GetByIdentity(ctx context.Context, in *pb.GetPostRequest) (reply *pb.PostItem, err error) {
|
||||
if in.GetIdentity() == "" {
|
||||
return nil, errcode.ErrInvalidArgument
|
||||
}
|
||||
|
||||
data, err := models.GetPost("identity", in.Identity)
|
||||
if err != nil {
|
||||
printer.Error(err.Error())
|
||||
return nil, errcode.ErrDB
|
||||
}
|
||||
|
||||
var res = &pb.PostItem{}
|
||||
if data != nil {
|
||||
res.Identity = data.Identity
|
||||
res.OwnerId = int64(data.OwnerID)
|
||||
res.OwnerIdentity = data.OwnerIdentity
|
||||
res.Title = data.Title
|
||||
res.CoverPath = data.CoverPath
|
||||
res.Author = data.Author
|
||||
res.AuthorIdentity = data.AuthorIdentity
|
||||
res.Content = data.Content
|
||||
res.TargetUrl = data.TargetUrl
|
||||
res.SourceUrl = data.SourceUrl
|
||||
res.Hits = data.Hits
|
||||
res.HasAccessory = data.HasAccessory
|
||||
res.CreatedAt = data.CreatedAt.String()
|
||||
res.UpdatedAt = data.UpdatedAt.String()
|
||||
res.Description = data.Description
|
||||
res.LikeHits = data.LikeHits
|
||||
res.UnlikeHits = data.UnlikeHits
|
||||
res.CommentHits = data.CommentHits
|
||||
res.PostType = data.Types
|
||||
res.Key = data.Hash
|
||||
res.Hash = data.Hash
|
||||
res.Lang = data.Lang
|
||||
res.SourceOrigin = data.SourceOrigin
|
||||
res.Rights = data.Rights
|
||||
res.ExtendUrl = data.ExtendUrl
|
||||
res.ExtendData = data.ExtendData
|
||||
res.ExtendImg = data.ExtendImg
|
||||
res.ExtendDesc = data.ExtendDesc
|
||||
res.Published = data.Published.Format(time.DateTime)
|
||||
}
|
||||
for _, val := range data.Accessories {
|
||||
res.AccessoryData = append(res.AccessoryData, &pb.AccessoryItem{
|
||||
Identity: val.Identity,
|
||||
Title: val.Title,
|
||||
FilePath: val.FilePath,
|
||||
CreatedAt: val.CreatedAt.Format(time.DateTime),
|
||||
})
|
||||
}
|
||||
for _, val := range data.Accessories {
|
||||
res.AccessoryIdentityArray = append(res.AccessoryIdentityArray, val.Identity)
|
||||
}
|
||||
for _, val := range data.Tags {
|
||||
res.TagsData = append(res.TagsData, &pb.TagsItem{
|
||||
Id: int64(val.ID),
|
||||
Identity: val.Tags.Identity,
|
||||
Title: val.Tags.Title,
|
||||
Intro: val.Tags.Intro,
|
||||
CoverPath: val.Tags.CoverPath,
|
||||
CreatedAt: val.Tags.CreatedAt.Format(time.DateTime),
|
||||
})
|
||||
}
|
||||
for _, val := range data.Tags {
|
||||
res.TagsIdentityArray = append(res.TagsIdentityArray, val.Tags.Identity)
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
50
apps/base/cms/internal/logic/post/get_by_key.go
Normal file
50
apps/base/cms/internal/logic/post/get_by_key.go
Normal file
@@ -0,0 +1,50 @@
|
||||
package post
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"git.apinb.com/bsm-apps/cms/internal/models"
|
||||
"git.apinb.com/bsm-apps/cms/internal/utils"
|
||||
pb "git.apinb.com/bsm-apps/cms/pb"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
)
|
||||
|
||||
// 获取文章详情 By Key
|
||||
func GetByKey(ctx context.Context, in *pb.GetPostByKeyRequest) (reply *pb.PostItem, err error) {
|
||||
if in.GetKey() == "" {
|
||||
return nil, errcode.ErrInvalidArgument
|
||||
}
|
||||
|
||||
data, err := models.GetPost("hash", utils.FormatKey(in.Key))
|
||||
if err != nil {
|
||||
printer.Error(err.Error())
|
||||
return nil, errcode.ErrDB
|
||||
}
|
||||
|
||||
var res = &pb.PostItem{}
|
||||
if data != nil {
|
||||
res.Identity = data.Identity
|
||||
res.OwnerId = int64(data.OwnerID)
|
||||
res.OwnerIdentity = data.OwnerIdentity
|
||||
res.Title = data.Title
|
||||
res.CoverPath = data.CoverPath
|
||||
res.Author = data.Author
|
||||
res.AuthorIdentity = data.AuthorIdentity
|
||||
res.Content = data.Content
|
||||
res.TargetUrl = data.TargetUrl
|
||||
res.SourceUrl = data.SourceUrl
|
||||
res.Hits = data.Hits
|
||||
res.HasAccessory = data.HasAccessory
|
||||
res.CreatedAt = data.CreatedAt.String()
|
||||
res.UpdatedAt = data.UpdatedAt.String()
|
||||
res.Description = data.Description
|
||||
res.LikeHits = data.LikeHits
|
||||
res.UnlikeHits = data.UnlikeHits
|
||||
res.CommentHits = data.CommentHits
|
||||
res.PostType = data.Types
|
||||
res.Key = data.Hash
|
||||
res.Hash = data.Hash
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
41
apps/base/cms/internal/logic/post/incr_comment_like.go
Normal file
41
apps/base/cms/internal/logic/post/incr_comment_like.go
Normal file
@@ -0,0 +1,41 @@
|
||||
package post
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"git.apinb.com/bsm-apps/cms/internal/impl"
|
||||
"git.apinb.com/bsm-apps/cms/internal/models"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/service"
|
||||
"git.apinb.com/bsm-sdk/core/utils"
|
||||
|
||||
pb "git.apinb.com/bsm-apps/cms/pb"
|
||||
)
|
||||
|
||||
// IncrCommentLike 评论点赞处理
|
||||
func IncrCommentLike(ctx context.Context, in *pb.CommentOpIdentityRequest) (*pb.StatusReply, error) {
|
||||
_, err := service.ParseMetaCtx(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var (
|
||||
cnt int64 = 0
|
||||
)
|
||||
|
||||
if in.GetCommentIdentity() == "" {
|
||||
return nil, errcode.ErrInvalidArgument
|
||||
}
|
||||
|
||||
err = models.IncrOrDescCommentField(in.CommentIdentity, "like_hits", false)
|
||||
if err != nil {
|
||||
return nil, errcode.ErrDB
|
||||
}
|
||||
if err := impl.DBService.Model(&models.CmsComment{}).Where("identity = ?", in.CommentIdentity).
|
||||
Pluck("like_hits", &cnt).Error; err != nil {
|
||||
return nil, errcode.ErrDB
|
||||
}
|
||||
|
||||
return &pb.StatusReply{
|
||||
Details: utils.Int642String(cnt),
|
||||
}, nil
|
||||
}
|
||||
36
apps/base/cms/internal/logic/post/incr_comment_unlike.go
Normal file
36
apps/base/cms/internal/logic/post/incr_comment_unlike.go
Normal file
@@ -0,0 +1,36 @@
|
||||
package post
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"git.apinb.com/bsm-apps/cms/internal/impl"
|
||||
"git.apinb.com/bsm-apps/cms/internal/models"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/service"
|
||||
"git.apinb.com/bsm-sdk/core/utils"
|
||||
|
||||
pb "git.apinb.com/bsm-apps/cms/pb"
|
||||
)
|
||||
|
||||
// 评论点踩处理
|
||||
func IncrCommentUnlike(ctx context.Context, in *pb.CommentOpIdentityRequest) (*pb.StatusReply, error) {
|
||||
_, err := service.ParseMetaCtx(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var cnt int64
|
||||
if in.GetCommentIdentity() == "" {
|
||||
return nil, errcode.ErrInvalidArgument
|
||||
}
|
||||
err = models.IncrOrDescCommentField(in.CommentIdentity, "unlike_hits", false)
|
||||
if err != nil {
|
||||
return nil, errcode.ErrDB
|
||||
}
|
||||
if err := impl.DBService.Model(&models.CmsComment{}).Where("identity = ?", in.CommentIdentity).
|
||||
Pluck("unlike_hits", &cnt).Error; err != nil {
|
||||
return nil, errcode.ErrDB
|
||||
}
|
||||
return &pb.StatusReply{
|
||||
Details: utils.Int642String(cnt),
|
||||
}, nil
|
||||
}
|
||||
50
apps/base/cms/internal/logic/post/incr_post_like.go
Normal file
50
apps/base/cms/internal/logic/post/incr_post_like.go
Normal file
@@ -0,0 +1,50 @@
|
||||
// Package post 提供文章相关的业务逻辑处理
|
||||
// 包括文章的创建、修改、删除、查询、点赞等功能
|
||||
package post
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"git.apinb.com/bsm-apps/cms/internal/models"
|
||||
pb "git.apinb.com/bsm-apps/cms/pb"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
"git.apinb.com/bsm-sdk/core/service"
|
||||
)
|
||||
|
||||
// IncrPostLike 增加文章点赞数
|
||||
// 验证用户身份后,增加指定文章的点赞计数
|
||||
// 参数:
|
||||
// - ctx: 请求上下文,包含用户身份信息
|
||||
// - in: 操作请求,包含操作ID和文章ID
|
||||
//
|
||||
// 返回:
|
||||
// - *pb.StatusReply: 操作结果
|
||||
// - error: 错误信息
|
||||
func IncrPostLike(ctx context.Context, in *pb.PostOpIdentityRequest) (*pb.StatusReply, error) {
|
||||
// 解析请求上下文,验证用户身份
|
||||
_, err := service.ParseMetaCtx(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 验证必填参数
|
||||
if in.GetOpIdentity() == "" || in.GetPostIdentity() == "" {
|
||||
return nil, errcode.ErrInvalidArgument
|
||||
}
|
||||
|
||||
// 增加文章点赞数
|
||||
err = models.IncrOrDescPostField(in.PostIdentity, "like_hits", false)
|
||||
if err != nil {
|
||||
printer.Error(err.Error())
|
||||
return nil, errcode.ErrDB
|
||||
}
|
||||
|
||||
// 返回成功响应
|
||||
return &pb.StatusReply{
|
||||
Code: 0,
|
||||
Message: "OK",
|
||||
Timeseq: time.Now().Unix(),
|
||||
}, nil
|
||||
}
|
||||
29
apps/base/cms/internal/logic/post/incr_post_unlike.go
Normal file
29
apps/base/cms/internal/logic/post/incr_post_unlike.go
Normal file
@@ -0,0 +1,29 @@
|
||||
package post
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"git.apinb.com/bsm-apps/cms/internal/models"
|
||||
pb "git.apinb.com/bsm-apps/cms/pb"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
"git.apinb.com/bsm-sdk/core/service"
|
||||
)
|
||||
|
||||
// 文章点踩处理
|
||||
func IncrPostUnlike(ctx context.Context, in *pb.PostOpIdentityRequest) (*pb.StatusReply, error) {
|
||||
_, err := service.ParseMetaCtx(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if in.GetOpIdentity() == "" || in.GetPostIdentity() == "" {
|
||||
return nil, errcode.ErrInvalidArgument
|
||||
}
|
||||
err = models.IncrOrDescPostField(in.PostIdentity, "unlike_hits", false)
|
||||
if err != nil {
|
||||
printer.Error(err.Error())
|
||||
return nil, errcode.ErrDB
|
||||
}
|
||||
return &pb.StatusReply{}, nil
|
||||
}
|
||||
54
apps/base/cms/internal/logic/post/modify.go
Normal file
54
apps/base/cms/internal/logic/post/modify.go
Normal file
@@ -0,0 +1,54 @@
|
||||
package post
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"git.apinb.com/bsm-apps/cms/internal/models"
|
||||
"git.apinb.com/bsm-apps/cms/internal/utils"
|
||||
pb "git.apinb.com/bsm-apps/cms/pb"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/service"
|
||||
)
|
||||
|
||||
// 修改文章
|
||||
func Modify(ctx context.Context, in *pb.PostItem) (reply *pb.StatusReply, err error) {
|
||||
_, err = service.ParseMetaCtx(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if in.GetSiteIdentity() == "" || in.GetIdentity() == "" {
|
||||
return nil, errcode.ErrInvalidArgument
|
||||
}
|
||||
var data = &models.CmsPost{
|
||||
SiteIdentity: in.SiteIdentity,
|
||||
Title: in.Title,
|
||||
Description: in.Description,
|
||||
CoverPath: in.CoverPath,
|
||||
Author: in.Author,
|
||||
Content: in.Content,
|
||||
TargetUrl: in.TargetUrl,
|
||||
SourceUrl: in.SourceUrl,
|
||||
HasAccessory: in.HasAccessory,
|
||||
Types: in.PostType,
|
||||
Hash: utils.FormatKey(in.Key),
|
||||
Lang: in.Lang,
|
||||
SourceOrigin: in.SourceOrigin,
|
||||
Rights: in.Rights,
|
||||
ExtendUrl: in.ExtendUrl,
|
||||
ExtendData: in.ExtendData,
|
||||
ExtendImg: in.ExtendImg,
|
||||
ExtendDesc: in.ExtendDesc,
|
||||
}
|
||||
err = models.ModifyPost(in.Identity, data, in.AccessoryIdentityArray, in.CategoryIdentityArray, in.TagsIdentityArray)
|
||||
if err != nil {
|
||||
return nil, errcode.ErrDB
|
||||
}
|
||||
|
||||
return &pb.StatusReply{
|
||||
Code: 0,
|
||||
Message: "OK",
|
||||
Timeseq: time.Now().Unix(),
|
||||
}, nil
|
||||
|
||||
}
|
||||
37
apps/base/cms/internal/logic/post/modify_comment.go
Normal file
37
apps/base/cms/internal/logic/post/modify_comment.go
Normal file
@@ -0,0 +1,37 @@
|
||||
package post
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"git.apinb.com/bsm-apps/cms/internal/impl"
|
||||
"git.apinb.com/bsm-apps/cms/internal/models"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/service"
|
||||
"git.apinb.com/bsm-sdk/core/types"
|
||||
|
||||
pb "git.apinb.com/bsm-apps/cms/pb"
|
||||
)
|
||||
|
||||
// 修改评论
|
||||
func ModifyComment(ctx context.Context, in *pb.CommentItem) (*pb.StatusReply, error) {
|
||||
_, err := service.ParseMetaCtx(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if in.GetIdentity() == "" {
|
||||
return nil, errcode.ErrInvalidArgument
|
||||
}
|
||||
|
||||
var data = models.CmsComment{
|
||||
Std_Identity: types.Std_Identity{Identity: in.Identity},
|
||||
PostIdentity: in.PostIdentity,
|
||||
ParentId: uint(in.ParentId),
|
||||
ReplyIdentity: in.ReplyIdentity,
|
||||
Cms: in.Cms,
|
||||
}
|
||||
// err = logic.ModifyComment(&data)
|
||||
if err := impl.DBService.Where("identity = ?", data.Identity).Updates(data).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &pb.StatusReply{}, nil
|
||||
}
|
||||
74
apps/base/cms/internal/logic/post/search.go
Normal file
74
apps/base/cms/internal/logic/post/search.go
Normal file
@@ -0,0 +1,74 @@
|
||||
package post
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"git.apinb.com/bsm-apps/cms/internal/impl"
|
||||
"git.apinb.com/bsm-apps/cms/internal/models"
|
||||
pb "git.apinb.com/bsm-apps/cms/pb"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
)
|
||||
|
||||
// 搜索文章
|
||||
func Search(ctx context.Context, in *pb.SearchRequest) (reply *pb.PostListReply, err error) {
|
||||
if in.GetKeyword() == "" {
|
||||
return nil, errcode.ErrInvalidArgument
|
||||
}
|
||||
|
||||
var (
|
||||
cnt int64 = 0
|
||||
pageNo int64 = in.GetPageNo()
|
||||
pageSize int64 = in.GetPageSize()
|
||||
offset int64 = (pageNo - 1) * pageSize
|
||||
)
|
||||
|
||||
// vlidate request page_no,page_size.
|
||||
if pageNo < 1 {
|
||||
pageNo = 1
|
||||
offset = 0
|
||||
}
|
||||
if pageSize < 50 {
|
||||
pageSize = 50
|
||||
offset = (pageNo - 1) * pageSize
|
||||
}
|
||||
|
||||
var data []*models.CmsPost
|
||||
tx := impl.DBService.Model(&models.CmsPost{}).Where("title like ? or Cms like ?", "%"+in.Keyword+"%", "%"+in.Keyword+"%")
|
||||
if err := tx.Count(&cnt).Offset(int(offset)).Limit(int(pageSize)).Find(&data).Error; err != nil {
|
||||
printer.Error(err.Error())
|
||||
return nil, errcode.ErrDB
|
||||
}
|
||||
|
||||
replyData := make([]*pb.PostItem, len(data))
|
||||
for _, val := range data {
|
||||
replyData = append(replyData, &pb.PostItem{
|
||||
Identity: val.Identity,
|
||||
OwnerId: int64(val.OwnerID),
|
||||
OwnerIdentity: val.OwnerIdentity,
|
||||
Title: val.Title,
|
||||
CoverPath: val.CoverPath,
|
||||
Author: val.Author,
|
||||
AuthorIdentity: val.AuthorIdentity,
|
||||
Content: val.Content,
|
||||
TargetUrl: val.TargetUrl,
|
||||
SourceUrl: val.SourceUrl,
|
||||
Hits: val.Hits,
|
||||
HasAccessory: val.HasAccessory,
|
||||
CreatedAt: val.CreatedAt.String(),
|
||||
UpdatedAt: val.UpdatedAt.String(),
|
||||
Description: val.Description,
|
||||
LikeHits: val.LikeHits,
|
||||
UnlikeHits: val.UnlikeHits,
|
||||
CommentHits: val.CommentHits,
|
||||
PostType: val.Types,
|
||||
Key: val.Hash,
|
||||
Hash: val.Hash,
|
||||
})
|
||||
}
|
||||
|
||||
return &pb.PostListReply{
|
||||
Count: cnt,
|
||||
Data: replyData,
|
||||
}, nil
|
||||
}
|
||||
29
apps/base/cms/internal/logic/site/create.go
Normal file
29
apps/base/cms/internal/logic/site/create.go
Normal file
@@ -0,0 +1,29 @@
|
||||
package site
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
pb "git.apinb.com/bsm-apps/cms/pb"
|
||||
"git.apinb.com/bsm-sdk/core/service"
|
||||
"git.apinb.com/bsm-sdk/core/vars"
|
||||
"time"
|
||||
)
|
||||
|
||||
// 添加站点
|
||||
func Create(ctx context.Context, in *pb.SiteItem) (reply *pb.StatusReply, err error) {
|
||||
// parse authorization meta.
|
||||
_, err = service.ParseMetaCtx(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// TODO: valid code
|
||||
|
||||
// TODO: add your logic code & delete this line.
|
||||
|
||||
return &pb.StatusReply{
|
||||
Details: vars.OK,
|
||||
Timeseq: time.Now().UnixMilli(),
|
||||
}, nil
|
||||
|
||||
}
|
||||
34
apps/base/cms/internal/logic/site/delete.go
Normal file
34
apps/base/cms/internal/logic/site/delete.go
Normal file
@@ -0,0 +1,34 @@
|
||||
package site
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"time"
|
||||
|
||||
pb "git.apinb.com/bsm-apps/cms/pb"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/service"
|
||||
"git.apinb.com/bsm-sdk/core/vars"
|
||||
)
|
||||
|
||||
// 删除站点
|
||||
func Delete(ctx context.Context, in *pb.IdentRequest) (reply *pb.StatusReply, err error) {
|
||||
// parse authorization meta.
|
||||
_, err = service.ParseMetaCtx(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// valildate request id,identity.
|
||||
if in.Id == 0 && in.Identity == "" {
|
||||
return nil, errcode.ErrInvalidArgument
|
||||
}
|
||||
|
||||
// TODO: add your logic code & delete this line.
|
||||
|
||||
return &pb.StatusReply{
|
||||
Details: vars.OK,
|
||||
Timeseq: time.Now().UnixMilli(),
|
||||
}, nil
|
||||
|
||||
}
|
||||
23
apps/base/cms/internal/logic/site/fetch.go
Normal file
23
apps/base/cms/internal/logic/site/fetch.go
Normal file
@@ -0,0 +1,23 @@
|
||||
package site
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
pb "git.apinb.com/bsm-apps/cms/pb"
|
||||
"git.apinb.com/bsm-sdk/core/service"
|
||||
)
|
||||
|
||||
// 站点列表
|
||||
func Fetch(ctx context.Context, in *pb.Empty) (reply *pb.SiteListReply, err error) {
|
||||
// parse authorization meta.
|
||||
_, err = service.ParseMetaCtx(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// TODO: valid code
|
||||
|
||||
// TODO: add your logic code & delete this line.
|
||||
|
||||
return
|
||||
}
|
||||
27
apps/base/cms/internal/logic/site/get.go
Normal file
27
apps/base/cms/internal/logic/site/get.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package site
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
pb "git.apinb.com/bsm-apps/cms/pb"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/service"
|
||||
)
|
||||
|
||||
// 站点详情
|
||||
func Get(ctx context.Context, in *pb.IdentRequest) (reply *pb.SiteItem, err error) {
|
||||
// parse authorization meta.
|
||||
_, err = service.ParseMetaCtx(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// valildate request id,identity.
|
||||
if in.Id == 0 && in.Identity == "" {
|
||||
return nil, errcode.ErrInvalidArgument
|
||||
}
|
||||
|
||||
// TODO: add your logic code & delete this line.
|
||||
|
||||
return
|
||||
}
|
||||
30
apps/base/cms/internal/logic/site/modify.go
Normal file
30
apps/base/cms/internal/logic/site/modify.go
Normal file
@@ -0,0 +1,30 @@
|
||||
package site
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"time"
|
||||
|
||||
pb "git.apinb.com/bsm-apps/cms/pb"
|
||||
"git.apinb.com/bsm-sdk/core/service"
|
||||
"git.apinb.com/bsm-sdk/core/vars"
|
||||
)
|
||||
|
||||
// 修改站点
|
||||
func Modify(ctx context.Context, in *pb.SiteItem) (reply *pb.StatusReply, err error) {
|
||||
// parse authorization meta.
|
||||
_, err = service.ParseMetaCtx(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// TODO: valid code
|
||||
|
||||
// TODO: add your logic code & delete this line.
|
||||
|
||||
return &pb.StatusReply{
|
||||
Details: vars.OK,
|
||||
Timeseq: time.Now().UnixMilli(),
|
||||
}, nil
|
||||
|
||||
}
|
||||
50
apps/base/cms/internal/logic/tags/create.go
Normal file
50
apps/base/cms/internal/logic/tags/create.go
Normal file
@@ -0,0 +1,50 @@
|
||||
package tags
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"git.apinb.com/bsm-apps/cms/internal/impl"
|
||||
"git.apinb.com/bsm-apps/cms/internal/models"
|
||||
pb "git.apinb.com/bsm-apps/cms/pb"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/service"
|
||||
"git.apinb.com/bsm-sdk/core/types"
|
||||
"git.apinb.com/bsm-sdk/core/utils"
|
||||
"git.apinb.com/bsm-sdk/core/vars"
|
||||
)
|
||||
|
||||
// 创建标签
|
||||
func Create(ctx context.Context, in *pb.TagsItem) (reply *pb.StatusReply, err error) {
|
||||
var cnt int64 = 0
|
||||
_, err = service.ParseMetaCtx(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if in.GetTitle() == "" || in.GetCoverPath() == "" || in.GetIntro() == "" {
|
||||
return nil, errcode.ErrInvalidArgument
|
||||
}
|
||||
if err := impl.DBService.Model(&models.CmsTags{}).Where("title = ?", in.Title).First(&models.CmsTags{}).Error; err == nil {
|
||||
return nil, errcode.ErrDB
|
||||
}
|
||||
if cnt > 0 {
|
||||
return nil, errcode.ErrAlreadyExists
|
||||
}
|
||||
var data = &models.CmsTags{
|
||||
Std_Identity: types.Std_Identity{Identity: utils.UUID()},
|
||||
Title: in.Title,
|
||||
CoverPath: in.CoverPath,
|
||||
Intro: in.Intro,
|
||||
}
|
||||
if err := impl.DBService.Model(&models.CmsTags{}).Create(data).Error; err != nil {
|
||||
return nil, errcode.ErrDB
|
||||
}
|
||||
return &pb.StatusReply{
|
||||
Code: 0,
|
||||
Message: vars.OK,
|
||||
Details: data.Identity,
|
||||
Timeseq: time.Now().Unix(),
|
||||
}, nil
|
||||
|
||||
}
|
||||
34
apps/base/cms/internal/logic/tags/delete.go
Normal file
34
apps/base/cms/internal/logic/tags/delete.go
Normal file
@@ -0,0 +1,34 @@
|
||||
package tags
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"git.apinb.com/bsm-apps/cms/internal/impl"
|
||||
"git.apinb.com/bsm-apps/cms/internal/models"
|
||||
pb "git.apinb.com/bsm-apps/cms/pb"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/service"
|
||||
)
|
||||
|
||||
// 删除标签
|
||||
func Delete(ctx context.Context, in *pb.IdentRequest) (reply *pb.StatusReply, err error) {
|
||||
_, err = service.ParseMetaCtx(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if in.GetIdentity() == "" {
|
||||
return nil, errcode.ErrInvalidArgument
|
||||
}
|
||||
if err := impl.DBService.Where("identity = ?", in.GetIdentity()).Delete(&models.CmsTags{}).Error; err != nil {
|
||||
return nil, errcode.ErrDB
|
||||
}
|
||||
|
||||
return &pb.StatusReply{
|
||||
Code: 0,
|
||||
Message: "OK",
|
||||
Timeseq: time.Now().Unix(),
|
||||
}, nil
|
||||
|
||||
}
|
||||
39
apps/base/cms/internal/logic/tags/fetch.go
Normal file
39
apps/base/cms/internal/logic/tags/fetch.go
Normal file
@@ -0,0 +1,39 @@
|
||||
package tags
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"git.apinb.com/bsm-apps/cms/internal/impl"
|
||||
"git.apinb.com/bsm-apps/cms/internal/models"
|
||||
pb "git.apinb.com/bsm-apps/cms/pb"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
)
|
||||
|
||||
// 标签列表
|
||||
func Fetch(ctx context.Context, in *pb.IdentRequest) (reply *pb.TagsListReply, err error) {
|
||||
|
||||
var (
|
||||
tags = make([]*models.CmsTags, 0)
|
||||
cnt int64 = 0
|
||||
)
|
||||
if err := impl.DBService.Model(&models.CmsTags{}).Order("created_at desc").Count(&cnt).Find(&tags).Error; err != nil {
|
||||
fmt.Println("err = ", err)
|
||||
return nil, errcode.ErrDB
|
||||
}
|
||||
|
||||
var res = &pb.TagsListReply{
|
||||
Count: cnt,
|
||||
Data: make([]*pb.TagsItem, 0, len(tags)),
|
||||
}
|
||||
for _, v := range tags {
|
||||
res.Data = append(res.Data, &pb.TagsItem{
|
||||
Id: int64(v.ID),
|
||||
Identity: v.Identity,
|
||||
Title: v.Title,
|
||||
Intro: v.Intro,
|
||||
CoverPath: v.CoverPath,
|
||||
})
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
45
apps/base/cms/internal/logic/tags/modify.go
Normal file
45
apps/base/cms/internal/logic/tags/modify.go
Normal file
@@ -0,0 +1,45 @@
|
||||
package tags
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"git.apinb.com/bsm-apps/cms/internal/impl"
|
||||
"git.apinb.com/bsm-apps/cms/internal/models"
|
||||
pb "git.apinb.com/bsm-apps/cms/pb"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/service"
|
||||
"git.apinb.com/bsm-sdk/core/types"
|
||||
)
|
||||
|
||||
// 修改标签
|
||||
func Modify(ctx context.Context, in *pb.TagsItem) (reply *pb.StatusReply, err error) {
|
||||
_, err = service.ParseMetaCtx(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if in.GetTitle() == "" || in.GetCoverPath() == "" || in.GetIntro() == "" {
|
||||
return nil, errcode.ErrInvalidArgument
|
||||
}
|
||||
|
||||
var tagsData = &models.CmsTags{
|
||||
Title: in.Title,
|
||||
CoverPath: in.CoverPath,
|
||||
Intro: in.Intro,
|
||||
Std_Identity: types.Std_Identity{Identity: in.Identity},
|
||||
}
|
||||
|
||||
// err = logic.ModifyTags(tagsData)
|
||||
|
||||
if err := impl.DBService.Where("identity = ?", tagsData.Identity).Updates(tagsData).Error; err != nil {
|
||||
return nil, errcode.ErrDB
|
||||
}
|
||||
|
||||
return &pb.StatusReply{
|
||||
Code: 0,
|
||||
Message: "OK",
|
||||
Timeseq: time.Now().Unix(),
|
||||
}, nil
|
||||
|
||||
}
|
||||
28
apps/base/cms/internal/models/cms_accessory.go
Normal file
28
apps/base/cms/internal/models/cms_accessory.go
Normal file
@@ -0,0 +1,28 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"git.apinb.com/bsm-sdk/core/database"
|
||||
"git.apinb.com/bsm-sdk/core/types"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// CmsAccessory 文章附件表
|
||||
type CmsAccessory struct {
|
||||
gorm.Model
|
||||
types.Std_Identity
|
||||
PostId uint `gorm:"column:post_id;not null" json:"post_id"` // 关联文章id
|
||||
PostIdentity string `gorm:"column:post_identity;type:varchar(36);index;" json:"post_identity"` // 关联文章标识
|
||||
PagesId uint `gorm:"column:pages_id;not null" json:"pages_id"` // 关联文章页面id
|
||||
PagesIdentity string `gorm:"column:pages_identity;type:varchar(36);index;" json:"pages_identity"` // 关联文章页面标识
|
||||
Title string `gorm:"column:title;type:varchar(255);default:''" json:"title"` // 附件标题
|
||||
FilePath string `gorm:"column:file_path;type:varchar(500);not null" json:"file_path"` // 附件文件地址
|
||||
}
|
||||
|
||||
func init() {
|
||||
database.MigrateTables = append(database.MigrateTables, &CmsAccessory{})
|
||||
}
|
||||
|
||||
// TableName .CmsAccessory 分类表
|
||||
func (c *CmsAccessory) TableName() string {
|
||||
return "cms_accessory" // 对应数据库表名
|
||||
}
|
||||
44
apps/base/cms/internal/models/cms_category.go
Normal file
44
apps/base/cms/internal/models/cms_category.go
Normal file
@@ -0,0 +1,44 @@
|
||||
/**
|
||||
* CMS分类数据模型
|
||||
* @Author: david.yan@qq.com
|
||||
* @Date: 2021-11-29 15:16:26
|
||||
* @LastEditors: david.yan@qq.com
|
||||
* @LastEditTime: 2021-11-30 17:40:50
|
||||
* @Description: 定义分类相关的数据结构和数据库映射,支持层级分类
|
||||
*/
|
||||
package models
|
||||
|
||||
import (
|
||||
"git.apinb.com/bsm-sdk/core/database"
|
||||
"git.apinb.com/bsm-sdk/core/types"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// CmsCategory CMS分类数据模型
|
||||
// 支持层级分类结构,每个分类可以有父分类和子分类
|
||||
type CmsCategory struct {
|
||||
gorm.Model // GORM基础模型(ID、CreatedAt、UpdatedAt、DeletedAt)
|
||||
types.Std_Identity // 标准身份标识字段
|
||||
SiteIdentity string `gorm:"column:site_identity;type:varchar(36);index;" json:"site_identity"`
|
||||
|
||||
// 分类基本信息
|
||||
CategoryKey string `gorm:"column:category_key;type:varchar(255);not null;uniqueIndex;" json:"category_key"` // 分类唯一键值
|
||||
Title string `gorm:"column:title;type:varchar(255);not null" json:"title"` // 分类标题
|
||||
CoverPath string `gorm:"column:cover_path;type:varchar(255);default:''" json:"cover_path"` // 分类封面图片路径
|
||||
Intro string `gorm:"column:intro;type:text;default:''" json:"intro"` // 分类介绍/描述
|
||||
|
||||
// 层级关系
|
||||
ParentId uint `gorm:"column:parent_id;index;" json:"parent_id"` // 父级分类ID,0表示顶级分类
|
||||
Children []CmsCategory `gorm:"foreignkey:ParentId;references:ID"` // 子分类列表
|
||||
}
|
||||
|
||||
// init 初始化函数,将模型注册到数据库迁移表
|
||||
func init() {
|
||||
database.MigrateTables = append(database.MigrateTables, &CmsCategory{})
|
||||
}
|
||||
|
||||
// TableName 指定数据库表名
|
||||
// 返回: 数据库表名
|
||||
func (c *CmsCategory) TableName() string {
|
||||
return "cms_category"
|
||||
}
|
||||
42
apps/base/cms/internal/models/cms_comment.go
Normal file
42
apps/base/cms/internal/models/cms_comment.go
Normal file
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
* @Author: david.yan@qq.com
|
||||
* @Date: 2021-11-29 15:16:26
|
||||
* @LastEditors: david.yan@qq.com
|
||||
* @LastEditTime: 2021-12-08 15:48:55
|
||||
* @FilePath: /src/git.buka.tv/Cms/internal/models/comment.go
|
||||
*/
|
||||
package models
|
||||
|
||||
import (
|
||||
"git.apinb.com/bsm-sdk/core/database"
|
||||
"git.apinb.com/bsm-sdk/core/types"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// 内容评论
|
||||
type CmsComment struct {
|
||||
gorm.Model
|
||||
types.Std_Identity
|
||||
PostIdentity string `gorm:"column:post_identity;type:varchar(36);index;" json:"post_identity"` // 关联的帖子身份标识符
|
||||
OwnerName string `gorm:"column:owner_name;type:varchar(255);index;" json:"owner_name"` // 作者名称
|
||||
OwnerIdentity string `gorm:"column:owner_identity;type:varchar(36);index;" json:"owner_identity"` // 作者身份标识符
|
||||
Role string `gorm:"column:role;type:varchar(255);index;" json:"role"` // 角色
|
||||
ParentId uint `gorm:"column:parent_id;index;" json:"parent_id"` // 关联的父级评论id
|
||||
ReplyIdentity string `gorm:"column:reply_identity;type:varchar(36);index;" json:"reply_identity"` // 被回复的评论的身份标识符
|
||||
Cms string `gorm:"column:Cms;type:text;default:'';" json:"Cms"` // 评论内容
|
||||
Hits int64 `gorm:"column:hits;default:0" json:"hits"` // 点击量
|
||||
LikeHits int64 `gorm:"column:like_hits;default:0" json:"like_hits"` // 点赞量
|
||||
UnlikeHits int64 `gorm:"column:unlike_hits;default:0" json:"unlike_hits"` // 踩赞量
|
||||
CommentHits int64 `gorm:"column:comment_hits;default:0" json:"comment_hits"` // 评论量
|
||||
|
||||
Children []CmsComment `gorm:"foreignkey:parent_id;references:ID"` // 子评论
|
||||
}
|
||||
|
||||
func init() {
|
||||
database.MigrateTables = append(database.MigrateTables, &CmsComment{})
|
||||
}
|
||||
|
||||
// TableName .CmsComment 内容评论表
|
||||
func (table *CmsComment) TableName() string {
|
||||
return "cms_comment" // 对应数据库表名
|
||||
}
|
||||
42
apps/base/cms/internal/models/cms_pages.go
Normal file
42
apps/base/cms/internal/models/cms_pages.go
Normal file
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
* @Author: david.yan@qq.com
|
||||
* @Date: 2021-11-29 15:16:26
|
||||
* @LastEditors: david.yan@qq.com
|
||||
* @LastEditTime: 2021-12-08 15:59:00
|
||||
* @FilePath: /src/git.buka.tv/Cms/internal/models/post.go
|
||||
*/
|
||||
package models
|
||||
|
||||
import (
|
||||
"git.apinb.com/bsm-sdk/core/database"
|
||||
"git.apinb.com/bsm-sdk/core/types"
|
||||
)
|
||||
|
||||
// CmsPost 单页文章
|
||||
type CmsPages struct {
|
||||
types.Std_IICUDS
|
||||
SiteIdentity string `gorm:"column:site_identity;type:varchar(36);index;" json:"site_identity"`
|
||||
|
||||
Title string `gorm:"column:title;type:varchar(255);default:'';" json:"title"` // 标题
|
||||
Key string `gorm:"column:key;type:varchar(255);uniqueIndex;" json:"key"` // 内容KEY,唯一,无空格
|
||||
Description string `gorm:"column:description;type:varchar(255);default:'';" json:"description"` // 描述
|
||||
CoverPath string `gorm:"column:cover_path;type:varchar(255);default:'';" json:"cover_path"` // 封面
|
||||
Content string `gorm:"column:content;type:text;default:'';" json:"content"` // 内容
|
||||
HasAccessory bool `gorm:"column:has_accessory;type:bool;default:false" json:"has_accessory"` // 是否有附件
|
||||
Type int32 `gorm:"column:type;default:0" json:"type"` // 类型
|
||||
Hits int64 `gorm:"column:hits;default:0" json:"hits"` // 点击量
|
||||
|
||||
AccessoryIdentityArray []string `gorm:"-" json:"accessory_identity_array"` // 附件标识
|
||||
Accessories []*CmsAccessory `gorm:"foreignkey:PagesIdentity ;references:Identity"` // 附件
|
||||
Tags []*CmsRelateTags `gorm:"foreignkey:PagesIdentity;references:Identity"` // 标签
|
||||
TagsIdentityArray []string `gorm:"-" json:"tags_identity_array"` // 标签标识
|
||||
}
|
||||
|
||||
func init() {
|
||||
database.MigrateTables = append(database.MigrateTables, &CmsPages{})
|
||||
}
|
||||
|
||||
// TableName .CmsPages 单页文章表
|
||||
func (table *CmsPages) TableName() string {
|
||||
return "cms_pages" // 对应数据库表名
|
||||
}
|
||||
80
apps/base/cms/internal/models/cms_post.go
Normal file
80
apps/base/cms/internal/models/cms_post.go
Normal file
@@ -0,0 +1,80 @@
|
||||
/**
|
||||
* CMS文章数据模型
|
||||
* @Author: david.yan@qq.com
|
||||
* @Date: 2021-11-29 15:16:26
|
||||
* @LastEditors: david.yan@qq.com
|
||||
* @LastEditTime: 2021-12-08 15:59:00
|
||||
* @Description: 定义文章相关的数据结构和数据库映射
|
||||
*/
|
||||
package models
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"git.apinb.com/bsm-sdk/core/database"
|
||||
"git.apinb.com/bsm-sdk/core/types"
|
||||
)
|
||||
|
||||
// CmsPost CMS文章数据模型
|
||||
// 包含文章的基本信息、统计数据、关联数据等
|
||||
type CmsPost struct {
|
||||
types.Std_IICUDS // 标准IICUDS字段(Identity、CreatedAt、UpdatedAt等)
|
||||
types.Std_Owner // 标准所有者字段
|
||||
SiteIdentity string `gorm:"column:site_identity;type:varchar(36);index;" json:"site_identity"`
|
||||
|
||||
// 基本信息
|
||||
Types int32 `gorm:"column:types;type:varchar(255);default:'';" json:"types"` // 文章类型
|
||||
Title string `gorm:"column:title;type:varchar(255);default:'';" json:"title"` // 文章标题
|
||||
Hash string `gorm:"column:hash;type:varchar(255);uniqueIndex;" json:"hash"` // 文章唯一键值,用于URL等
|
||||
Description string `gorm:"column:description;type:varchar(255);default:'';" json:"description"` // 文章描述/摘要
|
||||
CoverPath string `gorm:"column:cover_path;type:varchar(255);default:'';" json:"cover_path"` // 封面图片路径
|
||||
Content string `gorm:"column:content;type:text;default:'';" json:"content"` // 文章正文内容
|
||||
Lang string `gorm:"type:varchar(20);"` // 语言
|
||||
TargetUrl string `gorm:"column:target_url;type:varchar(255);default:''" json:"target_url"` // 目标链接
|
||||
Rights string `gorm:"column:rights;type:varchar(255);default:''" json:"rights"` // 权限
|
||||
|
||||
// 作者信息
|
||||
Author string `gorm:"column:author;type:varchar(255);default:''" json:"author"` // 作者姓名
|
||||
AuthorIdentity string `gorm:"column:author_identity;type:varchar(36);default:'';" json:"author_identity"` // 作者唯一标识
|
||||
|
||||
// 来源方
|
||||
SourceOrigin string `gorm:"type:varchar(255);"` // 简称
|
||||
SourceUrl string `gorm:"column:source_url;type:varchar(255);default:''" json:"source_url"` // 源链接
|
||||
|
||||
// 统计数据
|
||||
Hits int64 `gorm:"column:hits;default:0" json:"hits"` // 点击量/浏览量
|
||||
LikeHits int64 `gorm:"column:like_hits;default:0" json:"like_hits"` // 点赞数量
|
||||
UnlikeHits int64 `gorm:"column:unlike_hits;default:0" json:"unlike_hits"` // 踩赞数量
|
||||
CommentHits int64 `gorm:"column:comment_hits;default:0" json:"comment_hits"` // 评论数量
|
||||
|
||||
// 其他属性
|
||||
HasAccessory bool `gorm:"column:has_accessory;type:bool;default:false" json:"has_accessory"` // 是否有附件
|
||||
|
||||
// 关联数据标识(不存储到数据库,仅用于数据传输)
|
||||
CategoryIdentityArray []string `gorm:"-" json:"category_identity_array"` // 关联的分类标识列表
|
||||
TagsIdentityArray []string `gorm:"-" json:"tags_identity_array"` // 关联的标签标识列表
|
||||
AccessoryIdentityArray []string `gorm:"-" json:"accessory_identity_array"` // 关联的附件标识列表
|
||||
|
||||
// 关联数据对象(通过外键关联)
|
||||
Accessories []*CmsAccessory `gorm:"foreignkey:PostId;references:ID"` // 文章附件列表
|
||||
Categories []*CmsRelateCategory `gorm:"foreignkey:PostIdentity;references:Identity"` // 文章分类关联列表
|
||||
Tags []*CmsRelateTags `gorm:"foreignkey:PostIdentity;references:Identity"` // 文章标签关联列表
|
||||
|
||||
ExtendUrl string // 扩展:URL
|
||||
ExtendData string // 扩展:数据
|
||||
ExtendImg string // 扩展:图片
|
||||
ExtendDesc string // 扩展:描述
|
||||
|
||||
Published time.Time // 事件发生时间
|
||||
}
|
||||
|
||||
// init 初始化函数,将模型注册到数据库迁移表
|
||||
func init() {
|
||||
database.MigrateTables = append(database.MigrateTables, &CmsPost{})
|
||||
}
|
||||
|
||||
// TableName 指定数据库表名
|
||||
// 返回: 数据库表名
|
||||
func (table *CmsPost) TableName() string {
|
||||
return "cms_post"
|
||||
}
|
||||
22
apps/base/cms/internal/models/cms_relate_category.go
Normal file
22
apps/base/cms/internal/models/cms_relate_category.go
Normal file
@@ -0,0 +1,22 @@
|
||||
package models
|
||||
|
||||
import "git.apinb.com/bsm-sdk/core/database"
|
||||
|
||||
// post 关联分类表
|
||||
type CmsRelateCategory struct {
|
||||
ID uint `gorm:"primarykey"` // Id
|
||||
Identity string `gorm:"column:identity;type:varchar(36);uniqueIndex;"` // 唯一标识
|
||||
PostIdentity string `gorm:"column:post_identity;type:varchar(36);index;" json:"post_identity"` // 关联的post唯一标识
|
||||
CategoryIdentity string `gorm:"column:category_identity;type:varchar(36);index;" json:"category_identity"` // 关联的category唯一标识
|
||||
|
||||
Category CmsCategory `gorm:"foreignKey:Identity;references:CategoryIdentity"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
database.MigrateTables = append(database.MigrateTables, &CmsRelateCategory{})
|
||||
}
|
||||
|
||||
// TableName .CmsRelateCategory 内容相关类别表
|
||||
func (table *CmsRelateCategory) TableName() string {
|
||||
return "cms_relate_category" // 对应数据库表名
|
||||
}
|
||||
23
apps/base/cms/internal/models/cms_relate_tags.go
Normal file
23
apps/base/cms/internal/models/cms_relate_tags.go
Normal file
@@ -0,0 +1,23 @@
|
||||
package models
|
||||
|
||||
import "git.apinb.com/bsm-sdk/core/database"
|
||||
|
||||
// post 内容相关主题表
|
||||
type CmsRelateTags struct {
|
||||
ID uint `gorm:"primarykey"` // Id
|
||||
Identity string `gorm:"column:identity;type:varchar(36);uniqueIndex;"` // 唯一标识
|
||||
PostIdentity string `gorm:"column:post_identity;type:varchar(36);index;" json:"post_identity"` // 关联文章唯一标识
|
||||
TagsIdentity string `gorm:"column:tags_identity;type:varchar(36);index;" json:"tags_identity"` // 关联分类唯一标识
|
||||
PagesIdentity string `gorm:"column:pages_identity;type:varchar(36);index;" json:"pages_identity"`
|
||||
|
||||
Tags CmsTags `gorm:"foreignKey:Identity;references:TagsIdentity"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
database.MigrateTables = append(database.MigrateTables, &CmsRelateTags{})
|
||||
}
|
||||
|
||||
// TableName .CmsRelateTopic 内容相关主题表
|
||||
func (table *CmsRelateTags) TableName() string {
|
||||
return "cms_relate_tags" // 对应数据库表名
|
||||
}
|
||||
31
apps/base/cms/internal/models/cms_site.go
Normal file
31
apps/base/cms/internal/models/cms_site.go
Normal file
@@ -0,0 +1,31 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"git.apinb.com/bsm-sdk/core/database"
|
||||
"git.apinb.com/bsm-sdk/core/types"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// CmsSite 站点配置
|
||||
type CmsSite struct {
|
||||
gorm.Model
|
||||
types.Std_Identity
|
||||
|
||||
Title string `gorm:"column:title;type:varchar(255);not null" json:"title"`
|
||||
Description string `gorm:"column:description;type:varchar(255);not null" json:"description"`
|
||||
IconPath string `gorm:"column:icon_path;type:varchar(255);not null" json:"icon_path"`
|
||||
Keywords string `gorm:"column:keywords;type:varchar(255);not null" json:"keywords"`
|
||||
Domain string `gorm:"column:domain;type:varchar(255);not null" json:"domain"`
|
||||
Seo string `gorm:"column:seo;type:text;not null" json:"seo"`
|
||||
Theme string `gorm:"column:theme;type:varchar(255);not null" json:"theme"`
|
||||
Configs string `gorm:"column:configs;type:text;not null" json:"configs"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
database.MigrateTables = append(database.MigrateTables, &CmsSite{})
|
||||
}
|
||||
|
||||
// TableName .CmsAccessory 分类表
|
||||
func (c *CmsSite) TableName() string {
|
||||
return "cms_site" // 对应数据库表名
|
||||
}
|
||||
33
apps/base/cms/internal/models/cms_tags.go
Normal file
33
apps/base/cms/internal/models/cms_tags.go
Normal file
@@ -0,0 +1,33 @@
|
||||
/**
|
||||
* @Author: david.yan@qq.com
|
||||
* @Date: 2021-11-29 15:16:26
|
||||
* @LastEditors: david.yan@qq.com
|
||||
* @LastEditTime: 2021-11-30 17:40:50
|
||||
* @FilePath: /src/git.buka.tv/Cms/internal/models/category.go
|
||||
*/
|
||||
package models
|
||||
|
||||
import (
|
||||
"git.apinb.com/bsm-sdk/core/database"
|
||||
"git.apinb.com/bsm-sdk/core/types"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// 内容标签
|
||||
type CmsTags struct {
|
||||
gorm.Model
|
||||
types.Std_Identity
|
||||
SiteIdentity string `gorm:"column:site_identity;type:varchar(36);index;" json:"site_identity"`
|
||||
Title string `gorm:"column:title;type:varchar(255);not null" json:"title"` // 标题
|
||||
CoverPath string `gorm:"column:cover_path;type:varchar(255);default:''" json:"cover_path"` // 封面
|
||||
Intro string // 介绍
|
||||
}
|
||||
|
||||
func init() {
|
||||
database.MigrateTables = append(database.MigrateTables, &CmsTags{})
|
||||
}
|
||||
|
||||
// TableName .CmsTags 内容标签表
|
||||
func (c *CmsTags) TableName() string {
|
||||
return "cms_tags" // 对应数据库表名
|
||||
}
|
||||
389
apps/base/cms/internal/models/query.go
Normal file
389
apps/base/cms/internal/models/query.go
Normal file
@@ -0,0 +1,389 @@
|
||||
// Package models 提供CMS数据模型和数据库操作
|
||||
// 包含文章、分类、标签、评论等实体的数据结构和CRUD操作
|
||||
package models
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"git.apinb.com/bsm-apps/cms/internal/impl"
|
||||
pb "git.apinb.com/bsm-apps/cms/pb"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/types"
|
||||
"git.apinb.com/bsm-sdk/core/utils"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// 数据库表名常量
|
||||
const (
|
||||
postTable = "cms_post" // 文章表
|
||||
accessoryTable = "cms_accessory" // 附件表
|
||||
postRelateCategoryTable = "cms_relate" // 关联表
|
||||
)
|
||||
|
||||
// InitData 初始化基础数据
|
||||
// 创建系统必需的默认数据,如根分类等
|
||||
func InitData() {
|
||||
var cnt int64 = 0
|
||||
|
||||
// 检查是否存在根分类,如果不存在则创建
|
||||
err := impl.DBService.Model(&CmsCategory{}).Where("identity=?", "_RootCategory").Count(&cnt).Error
|
||||
if cnt == 0 || err != nil {
|
||||
data := &CmsCategory{
|
||||
Title: "根目录",
|
||||
ParentId: 0, // 0表示顶级分类
|
||||
Std_Identity: types.Std_Identity{Identity: "_RootCategory"},
|
||||
}
|
||||
impl.DBService.Create(data)
|
||||
}
|
||||
}
|
||||
|
||||
// AddPost 添加文章及其关联数据
|
||||
// 使用事务确保数据一致性,同时创建文章、分类关联、标签关联和附件信息
|
||||
// 参数:
|
||||
// - post: 文章数据模型
|
||||
// - accessory: 附件数据列表
|
||||
// - category: 分类标识列表
|
||||
// - tags: 标签标识列表
|
||||
//
|
||||
// 返回:
|
||||
// - error: 错误信息
|
||||
func AddPost(post *CmsPost, accessory []*pb.AccessoryItem, category, tags []string) (err error) {
|
||||
var (
|
||||
accessoryPath = make([]CmsAccessory, 0) // 文章附件数据
|
||||
categoryData = make([]CmsRelateCategory, 0) // 文章分类关联数据
|
||||
TagsData = make([]CmsRelateTags, 0) // 文章标签关联数据
|
||||
)
|
||||
|
||||
// 构建分类关联数据
|
||||
for _, va := range category {
|
||||
categoryData = append(categoryData, CmsRelateCategory{
|
||||
Identity: utils.UUID(),
|
||||
PostIdentity: post.Identity,
|
||||
CategoryIdentity: va,
|
||||
})
|
||||
}
|
||||
|
||||
// 构建标签关联数据
|
||||
for _, val := range tags {
|
||||
TagsData = append(TagsData, CmsRelateTags{
|
||||
Identity: utils.ULID(),
|
||||
PostIdentity: post.Identity,
|
||||
TagsIdentity: val,
|
||||
})
|
||||
}
|
||||
|
||||
// 使用事务确保数据一致性
|
||||
return impl.DBService.Transaction(func(tx *gorm.DB) error {
|
||||
// 创建文章记录
|
||||
if err = tx.Create(post).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 创建附件关联记录
|
||||
if len(accessory) != 0 {
|
||||
for _, v := range accessory {
|
||||
accessoryPath = append(accessoryPath, CmsAccessory{
|
||||
Std_Identity: types.Std_Identity{Identity: utils.UUID()},
|
||||
PostId: post.ID,
|
||||
PostIdentity: post.Identity,
|
||||
FilePath: v.FilePath,
|
||||
Title: v.Title,
|
||||
})
|
||||
}
|
||||
if err := tx.Create(&accessoryPath).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// 创建分类关联记录
|
||||
if len(category) != 0 {
|
||||
if err := tx.Create(&categoryData).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// 创建标签关联记录
|
||||
if len(tags) != 0 {
|
||||
if err := tx.Create(&TagsData).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
// PostList 文章列表
|
||||
func PostList(page, size int64, categoryIdentity, keyword string, userType int64) (list []*CmsPost, cnt int64, err error) {
|
||||
|
||||
tx := impl.DBService.Debug().Model(&CmsPost{})
|
||||
if categoryIdentity != "" {
|
||||
tx = tx.Joins("left join cms_relate_category crc on crc.post_identity = cms_post.identity ")
|
||||
tx = tx.Where("crc.category_identity = ?", categoryIdentity)
|
||||
}
|
||||
|
||||
if keyword != "" {
|
||||
tx = tx.Where("cms_post.title like ?", "%"+keyword+"%")
|
||||
}
|
||||
|
||||
if userType != 0 {
|
||||
tx = tx.Where("cms_post.types = ?", userType)
|
||||
}
|
||||
|
||||
if err = tx.Count(&cnt).Order("cms_post.created_at desc").Limit(int(size)).Offset(int((page - 1) * size)).Error; err != nil {
|
||||
return nil, 0, errcode.ErrDB
|
||||
}
|
||||
err = tx.Preload("Accessories").Preload("Categories.Category").Preload("Tags.Tags").Find(&list).Error
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// ModifyPost 修改文章
|
||||
func ModifyPost(identity string, post *CmsPost, accessory, category, tags []string) (err error) {
|
||||
var (
|
||||
accessoryPath = make([]CmsAccessory, 0)
|
||||
categoryData = make([]CmsRelateCategory, 0)
|
||||
tagsData = make([]CmsRelateTags, 0)
|
||||
)
|
||||
for _, v := range category {
|
||||
categoryData = append(categoryData, CmsRelateCategory{
|
||||
Identity: utils.UUID(),
|
||||
PostIdentity: identity,
|
||||
CategoryIdentity: v,
|
||||
})
|
||||
}
|
||||
for _, val := range tags {
|
||||
tagsData = append(tagsData, CmsRelateTags{
|
||||
Identity: utils.ULID(),
|
||||
PostIdentity: identity,
|
||||
TagsIdentity: val,
|
||||
})
|
||||
}
|
||||
for _, v := range accessory {
|
||||
accessoryPath = append(accessoryPath, CmsAccessory{
|
||||
Std_Identity: types.Std_Identity{Identity: utils.UUID()},
|
||||
PostId: post.ID,
|
||||
PostIdentity: identity,
|
||||
FilePath: v,
|
||||
})
|
||||
}
|
||||
return impl.DBService.Transaction(func(tx *gorm.DB) error {
|
||||
if err = tx.Where("identity = ?", identity).Updates(post).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
// 删除旧的附件、分类和标签关联
|
||||
if err := tx.Where("post_identity = ?", identity).Delete(&CmsAccessory{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tx.Where("post_identity = ?", identity).Delete(&CmsRelateCategory{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tx.Where("post_identity = ?", identity).Delete(&CmsRelateTags{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
// 创建新的分类关联
|
||||
if len(category) != 0 {
|
||||
if err := tx.Create(&categoryData).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
// 创建新的标签关联
|
||||
if len(tags) != 0 {
|
||||
if err := tx.Create(&tagsData).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
// 创建新的附件关联
|
||||
if len(accessory) != 0 {
|
||||
if err := tx.Create(&accessoryPath).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
// DeletePost 删除文章
|
||||
func DeletePost(identity, authorIdentity string) (err error) {
|
||||
return impl.DBService.Transaction(func(tx *gorm.DB) error {
|
||||
if err = tx.Where("identity = ?", identity).Delete(&CmsPost{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = tx.Where("post_identity = ?", identity).Delete(&CmsRelateCategory{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = tx.Where("post_identity = ?", identity).Delete(&CmsRelateTags{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if err = tx.Where("post_identity = ?", identity).Delete(&CmsAccessory{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
// GetPost 根据指定字段获取文章详情
|
||||
// 查询成功后会更新文章的点击量
|
||||
// 参数:
|
||||
// - key: 查询字段名(如"identity"、"key"等)
|
||||
// - val: 查询字段值
|
||||
//
|
||||
// 返回:
|
||||
// - *CmsPost: 文章详情
|
||||
// - error: 错误信息
|
||||
func GetPost(key, val string) (*CmsPost, error) {
|
||||
var post = &CmsPost{}
|
||||
|
||||
// 使用事务确保查询和更新操作的原子性
|
||||
return post, impl.DBService.Transaction(func(tx *gorm.DB) error {
|
||||
// 查询文章详情,预加载关联数据
|
||||
if err := tx.Model(&CmsPost{}).Preload("Accessories").Preload("Categories").Preload("Tags").
|
||||
Where(key+" = ?", val).First(post).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 更新文章点击量,只有在查询成功后才更新
|
||||
if err := tx.Model(&CmsPost{}).Where(key+" = ?", val).
|
||||
UpdateColumn("hits", gorm.Expr("hits + 1")).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
// IncrOrDescPostField 增加或减少文章字段值
|
||||
// 用于更新文章的点赞、踩赞、评论等计数字段
|
||||
// 参数:
|
||||
// - identity: 文章唯一标识
|
||||
// - column: 要更新的字段名
|
||||
// - desc: true表示减少,false表示增加
|
||||
//
|
||||
// 返回:
|
||||
// - error: 错误信息
|
||||
func IncrOrDescPostField(identity, column string, desc bool) (err error) {
|
||||
expr := "%s + ?"
|
||||
if desc {
|
||||
expr = "%s - ?"
|
||||
}
|
||||
if err := impl.DBService.Model(&CmsPost{}).Where("identity = ?", identity).UpdateColumn(column, gorm.Expr(fmt.Sprintf(expr, column), 1)).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func AddComment(comment *CmsComment, authorIdentity string) (err error) {
|
||||
err = impl.DBService.Transaction(func(tx *gorm.DB) error {
|
||||
if err := tx.Create(comment).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
// 添加评论,更新文章评论量
|
||||
err := tx.Model(&CmsPost{}).Where("identity = ?", comment.PostIdentity).UpdateColumn("comment_hits", gorm.Expr("comment_hits + ?", 1)).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if comment.ParentId != 0 {
|
||||
// 更新被评论的那条评论的计数
|
||||
err = tx.Model(&CmsComment{}).Where("id = ?", comment.ParentId).UpdateColumn("comment_hits", gorm.Expr("comment_hits + ?", 1)).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
func ModifyComment(comment *CmsComment) (err error) {
|
||||
return impl.DBService.Where("identity = ?", comment.Identity).Updates(comment).Error
|
||||
}
|
||||
|
||||
func DeleteComment(identity string) (err error) {
|
||||
// get comment
|
||||
comment := new(CmsComment)
|
||||
err = impl.DBService.Where("identity = ?", identity).First(comment).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = impl.DBService.Transaction(func(tx *gorm.DB) error {
|
||||
// 删除评论,更新文章评论量
|
||||
if err := tx.Where("identity = ?", identity).Delete(&CmsComment{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tx.Model(&CmsPost{}).Where("identity = ?", comment.PostIdentity).
|
||||
UpdateColumn("comment_hits", gorm.Expr("comment_hits - ?", 1)).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if comment.ParentId != 0 {
|
||||
// 更新被评论的那条评论的计数
|
||||
if err := tx.Model(&CmsComment{}).Where("id = ?", comment.ParentId).
|
||||
UpdateColumn("comment_hits", gorm.Expr("comment_hits - ?", 1)).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
// 删除子级评论
|
||||
err = tx.Where("parent_id = ?", comment.ID).Delete(&CmsComment{}).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// IncrOrDescCommentField 增加或减少评论字段值
|
||||
// 用于更新评论的点赞、踩赞等计数字段
|
||||
// 参数:
|
||||
// - identity: 评论唯一标识
|
||||
// - column: 要更新的字段名
|
||||
// - desc: true表示减少,false表示增加
|
||||
//
|
||||
// 返回:
|
||||
// - error: 错误信息
|
||||
//
|
||||
// TODO: 记录点赞对象避免重复点赞
|
||||
func IncrOrDescCommentField(identity, column string, desc bool) (err error) {
|
||||
expr := "%s + ?"
|
||||
if desc {
|
||||
expr = "%s - ?"
|
||||
}
|
||||
if err = impl.DBService.Model(&CmsComment{}).Where("identity = ?", identity).UpdateColumn(column, gorm.Expr(fmt.Sprintf(expr, column), 1)).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// CategoryList 文章分类列表
|
||||
func CategoryList() (list []CmsCategory, cnt int64, err error) {
|
||||
result := impl.DBService.Preload("Children").Find(&list)
|
||||
if result.Error != nil {
|
||||
err = result.Error
|
||||
return
|
||||
}
|
||||
cnt = result.RowsAffected
|
||||
return
|
||||
}
|
||||
|
||||
// DeleteCategory 删除分类
|
||||
func DeleteCategory(identity string) (err error) {
|
||||
var (
|
||||
cnt int64 = 0
|
||||
category CmsCategory
|
||||
)
|
||||
err = impl.DBService.Model(&CmsCategory{}).Where("identity = ?", identity).Find(&category).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
impl.DBService.Model(&CmsCategory{}).Where("parent_id = ?", category.ID).Count(&cnt)
|
||||
if cnt != 0 {
|
||||
return errcode.NewError(500, "ErrCategoryHasSubcategories")
|
||||
}
|
||||
|
||||
err = impl.DBService.Where("identity = ?", identity).Delete(&CmsCategory{}).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return
|
||||
}
|
||||
36
apps/base/cms/internal/server/category_server.go
Normal file
36
apps/base/cms/internal/server/category_server.go
Normal file
@@ -0,0 +1,36 @@
|
||||
// Code generated by protoc-gen-slc. DO NOT EDIT.
|
||||
package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
"git.apinb.com/bsm-apps/cms/internal/logic/category"
|
||||
pb "git.apinb.com/bsm-apps/cms/pb"
|
||||
)
|
||||
|
||||
type CategoryServer struct {
|
||||
pb.UnimplementedCategoryServer
|
||||
}
|
||||
|
||||
func NewCategoryServer() *CategoryServer {
|
||||
return &CategoryServer{}
|
||||
}
|
||||
|
||||
// 分类列表
|
||||
func (s *CategoryServer) Fetch(ctx context.Context, in *pb.IdentRequest) (*pb.CategoryListReply, error) {
|
||||
return category.Fetch(ctx, in)
|
||||
}
|
||||
|
||||
// 添加分类
|
||||
func (s *CategoryServer) Create(ctx context.Context, in *pb.CategoryItem) (*pb.StatusReply, error) {
|
||||
return category.Create(ctx, in)
|
||||
}
|
||||
|
||||
// 修改分类
|
||||
func (s *CategoryServer) Modify(ctx context.Context, in *pb.ModifyCategoryRequest) (*pb.StatusReply, error) {
|
||||
return category.Modify(ctx, in)
|
||||
}
|
||||
|
||||
// 删除分类
|
||||
func (s *CategoryServer) Delete(ctx context.Context, in *pb.DeleteCategoryRequest) (*pb.StatusReply, error) {
|
||||
return category.Delete(ctx, in)
|
||||
}
|
||||
111
apps/base/cms/internal/server/new.go
Normal file
111
apps/base/cms/internal/server/new.go
Normal file
@@ -0,0 +1,111 @@
|
||||
// Code generated by protoc-gen-slc. DO NOT EDIT.
|
||||
package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
pb "git.apinb.com/bsm-apps/cms/pb"
|
||||
"git.apinb.com/bsm-sdk/core/vars"
|
||||
gwRuntime "github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
"google.golang.org/grpc/reflection"
|
||||
"google.golang.org/protobuf/proto"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Server struct {
|
||||
Grpc *grpc.Server
|
||||
Ctx context.Context
|
||||
Mux *gwRuntime.ServeMux
|
||||
grpcConns map[string]*grpc.ClientConn // 连接池
|
||||
}
|
||||
|
||||
func New(addr string) *Server {
|
||||
srv := &Server{
|
||||
Ctx: context.Background(),
|
||||
Grpc: grpc.NewServer(),
|
||||
Mux: gwRuntime.NewServeMux(gwRuntime.WithForwardResponseRewriter(responseEnvelope)),
|
||||
grpcConns: make(map[string]*grpc.ClientConn),
|
||||
}
|
||||
|
||||
// register service to grpc.Server
|
||||
pb.RegisterCategoryServer(srv.Grpc, NewCategoryServer())
|
||||
pb.RegisterPagesServer(srv.Grpc, NewPagesServer())
|
||||
pb.RegisterPostServer(srv.Grpc, NewPostServer())
|
||||
pb.RegisterSiteServer(srv.Grpc, NewSiteServer())
|
||||
pb.RegisterTagsServer(srv.Grpc, NewTagsServer())
|
||||
|
||||
reflection.Register(srv.Grpc)
|
||||
|
||||
// 连接池: 只创建一次连接并复用
|
||||
conn, ok := srv.grpcConns[addr]
|
||||
if !ok {
|
||||
var err error
|
||||
conn, err = grpc.NewClient(addr, grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||
if err != nil {
|
||||
panic("failed to dial grpc server: " + err.Error())
|
||||
}
|
||||
srv.grpcConns[addr] = conn
|
||||
}
|
||||
|
||||
// 将服务注册到Gateway
|
||||
|
||||
if err := pb.RegisterCategoryHandler(srv.Ctx, srv.Mux, conn); err != nil {
|
||||
panic("Failed to register Category handler: " + err.Error())
|
||||
}
|
||||
|
||||
if err := pb.RegisterPagesHandler(srv.Ctx, srv.Mux, conn); err != nil {
|
||||
panic("Failed to register Pages handler: " + err.Error())
|
||||
}
|
||||
|
||||
if err := pb.RegisterPostHandler(srv.Ctx, srv.Mux, conn); err != nil {
|
||||
panic("Failed to register Post handler: " + err.Error())
|
||||
}
|
||||
|
||||
if err := pb.RegisterSiteHandler(srv.Ctx, srv.Mux, conn); err != nil {
|
||||
panic("Failed to register Site handler: " + err.Error())
|
||||
}
|
||||
|
||||
if err := pb.RegisterTagsHandler(srv.Ctx, srv.Mux, conn); err != nil {
|
||||
panic("Failed to register Tags handler: " + err.Error())
|
||||
}
|
||||
|
||||
// Register services swagger
|
||||
srv.RegisterSwagger()
|
||||
|
||||
return srv
|
||||
}
|
||||
|
||||
// RegisterSwagger 注册swagger
|
||||
func (s *Server) RegisterSwagger() {
|
||||
srvKey := strings.ToLower(vars.ServiceKey)
|
||||
s.Mux.HandlePath("GET", "/"+srvKey+".swagger.json", func(w http.ResponseWriter, r *http.Request, pathParams map[string]string) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
bytes, err := os.ReadFile("./swagger/" + srvKey + ".swagger.json")
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
w.Write([]byte(err.Error()))
|
||||
return
|
||||
}
|
||||
w.Write(bytes)
|
||||
return
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
// response envelope
|
||||
func responseEnvelope(_ context.Context, response proto.Message) (interface{}, error) {
|
||||
name := string(response.ProtoReflect().Descriptor().Name())
|
||||
if name == "Status" || name == "Error" || name == "StatusReply" {
|
||||
return response, nil
|
||||
}
|
||||
return map[string]any{
|
||||
"code": 0,
|
||||
"message": vars.OK,
|
||||
"details": response,
|
||||
"timeseq": time.Now().Unix(),
|
||||
}, nil
|
||||
}
|
||||
46
apps/base/cms/internal/server/pages_server.go
Normal file
46
apps/base/cms/internal/server/pages_server.go
Normal file
@@ -0,0 +1,46 @@
|
||||
// Code generated by protoc-gen-slc. DO NOT EDIT.
|
||||
package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
"git.apinb.com/bsm-apps/cms/internal/logic/pages"
|
||||
pb "git.apinb.com/bsm-apps/cms/pb"
|
||||
)
|
||||
|
||||
type PagesServer struct {
|
||||
pb.UnimplementedPagesServer
|
||||
}
|
||||
|
||||
func NewPagesServer() *PagesServer {
|
||||
return &PagesServer{}
|
||||
}
|
||||
|
||||
// 单页列表
|
||||
func (s *PagesServer) Fetch(ctx context.Context, in *pb.PagesListRequest) (*pb.PagesListReply, error) {
|
||||
return pages.Fetch(ctx, in)
|
||||
}
|
||||
|
||||
// 获取单页详情 By Identity
|
||||
func (s *PagesServer) GetByIdentity(ctx context.Context, in *pb.GetPagesRequest) (*pb.PagesItem, error) {
|
||||
return pages.GetByIdentity(ctx, in)
|
||||
}
|
||||
|
||||
// 获取单页详情 By Key
|
||||
func (s *PagesServer) GetByKey(ctx context.Context, in *pb.GetPagesByKeyRequest) (*pb.PagesItem, error) {
|
||||
return pages.GetByKey(ctx, in)
|
||||
}
|
||||
|
||||
// 发布单页
|
||||
func (s *PagesServer) Create(ctx context.Context, in *pb.PagesItem) (*pb.StatusReply, error) {
|
||||
return pages.Create(ctx, in)
|
||||
}
|
||||
|
||||
// 修改单页
|
||||
func (s *PagesServer) Modify(ctx context.Context, in *pb.PagesItem) (*pb.StatusReply, error) {
|
||||
return pages.Modify(ctx, in)
|
||||
}
|
||||
|
||||
// 删除单页
|
||||
func (s *PagesServer) Delete(ctx context.Context, in *pb.IdentRequest) (*pb.StatusReply, error) {
|
||||
return pages.Delete(ctx, in)
|
||||
}
|
||||
111
apps/base/cms/internal/server/post_server.go
Normal file
111
apps/base/cms/internal/server/post_server.go
Normal file
@@ -0,0 +1,111 @@
|
||||
// Code generated by protoc-gen-slc. DO NOT EDIT.
|
||||
package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
"git.apinb.com/bsm-apps/cms/internal/logic/post"
|
||||
pb "git.apinb.com/bsm-apps/cms/pb"
|
||||
)
|
||||
|
||||
type PostServer struct {
|
||||
pb.UnimplementedPostServer
|
||||
}
|
||||
|
||||
func NewPostServer() *PostServer {
|
||||
return &PostServer{}
|
||||
}
|
||||
|
||||
// 文章列表
|
||||
func (s *PostServer) Fetch(ctx context.Context, in *pb.PostListRequest) (*pb.PostListReply, error) {
|
||||
return post.Fetch(ctx, in)
|
||||
}
|
||||
|
||||
// 获取文章详情 By Identity
|
||||
func (s *PostServer) GetByIdentity(ctx context.Context, in *pb.GetPostRequest) (*pb.PostItem, error) {
|
||||
return post.GetByIdentity(ctx, in)
|
||||
}
|
||||
|
||||
// 获取文章详情 By Key
|
||||
func (s *PostServer) GetByKey(ctx context.Context, in *pb.GetPostByKeyRequest) (*pb.PostItem, error) {
|
||||
return post.GetByKey(ctx, in)
|
||||
}
|
||||
|
||||
// 搜索文章
|
||||
func (s *PostServer) Search(ctx context.Context, in *pb.SearchRequest) (*pb.PostListReply, error) {
|
||||
return post.Search(ctx, in)
|
||||
}
|
||||
|
||||
// 发布文章
|
||||
func (s *PostServer) Create(ctx context.Context, in *pb.PostItem) (*pb.StatusReply, error) {
|
||||
return post.Create(ctx, in)
|
||||
}
|
||||
|
||||
// 修改文章
|
||||
func (s *PostServer) Modify(ctx context.Context, in *pb.PostItem) (*pb.StatusReply, error) {
|
||||
return post.Modify(ctx, in)
|
||||
}
|
||||
|
||||
// 删除文章
|
||||
func (s *PostServer) Delete(ctx context.Context, in *pb.IdentRequest) (*pb.StatusReply, error) {
|
||||
return post.Delete(ctx, in)
|
||||
}
|
||||
|
||||
// 文章点赞处理
|
||||
func (s *PostServer) IncrPostLike(ctx context.Context, in *pb.PostOpIdentityRequest) (*pb.StatusReply, error) {
|
||||
return post.IncrPostLike(ctx, in)
|
||||
}
|
||||
|
||||
// 文章点赞取消处理
|
||||
func (s *PostServer) DescPostLike(ctx context.Context, in *pb.PostOpIdentityRequest) (*pb.StatusReply, error) {
|
||||
return post.DescPostLike(ctx, in)
|
||||
}
|
||||
|
||||
// 文章点踩处理
|
||||
func (s *PostServer) IncrPostUnlike(ctx context.Context, in *pb.PostOpIdentityRequest) (*pb.StatusReply, error) {
|
||||
return post.IncrPostUnlike(ctx, in)
|
||||
}
|
||||
|
||||
// 文章点踩取消处理
|
||||
func (s *PostServer) DescPostUnlike(ctx context.Context, in *pb.PostOpIdentityRequest) (*pb.StatusReply, error) {
|
||||
return post.DescPostUnlike(ctx, in)
|
||||
}
|
||||
|
||||
// 评论列表
|
||||
func (s *PostServer) CommentList(ctx context.Context, in *pb.CommentListRequest) (*pb.CommentListResponse, error) {
|
||||
return post.CommentList(ctx, in)
|
||||
}
|
||||
|
||||
// 发布评论
|
||||
func (s *PostServer) AddComment(ctx context.Context, in *pb.CommentItem) (*pb.StatusReply, error) {
|
||||
return post.AddComment(ctx, in)
|
||||
}
|
||||
|
||||
// 修改评论
|
||||
func (s *PostServer) ModifyComment(ctx context.Context, in *pb.CommentItem) (*pb.StatusReply, error) {
|
||||
return post.ModifyComment(ctx, in)
|
||||
}
|
||||
|
||||
// 删除评论
|
||||
func (s *PostServer) DeleteComment(ctx context.Context, in *pb.DeleteCommentRequest) (*pb.StatusReply, error) {
|
||||
return post.DeleteComment(ctx, in)
|
||||
}
|
||||
|
||||
// 评论点赞处理
|
||||
func (s *PostServer) IncrCommentLike(ctx context.Context, in *pb.CommentOpIdentityRequest) (*pb.StatusReply, error) {
|
||||
return post.IncrCommentLike(ctx, in)
|
||||
}
|
||||
|
||||
// 评论点赞取消处理
|
||||
func (s *PostServer) DescCommentLike(ctx context.Context, in *pb.CommentOpIdentityRequest) (*pb.StatusReply, error) {
|
||||
return post.DescCommentLike(ctx, in)
|
||||
}
|
||||
|
||||
// 评论点踩处理
|
||||
func (s *PostServer) IncrCommentUnlike(ctx context.Context, in *pb.CommentOpIdentityRequest) (*pb.StatusReply, error) {
|
||||
return post.IncrCommentUnlike(ctx, in)
|
||||
}
|
||||
|
||||
// 评论点踩取消处理
|
||||
func (s *PostServer) DescCommentUnlike(ctx context.Context, in *pb.CommentOpIdentityRequest) (*pb.StatusReply, error) {
|
||||
return post.DescCommentUnlike(ctx, in)
|
||||
}
|
||||
41
apps/base/cms/internal/server/site_server.go
Normal file
41
apps/base/cms/internal/server/site_server.go
Normal file
@@ -0,0 +1,41 @@
|
||||
// Code generated by protoc-gen-slc. DO NOT EDIT.
|
||||
package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
"git.apinb.com/bsm-apps/cms/internal/logic/site"
|
||||
pb "git.apinb.com/bsm-apps/cms/pb"
|
||||
)
|
||||
|
||||
type SiteServer struct {
|
||||
pb.UnimplementedSiteServer
|
||||
}
|
||||
|
||||
func NewSiteServer() *SiteServer {
|
||||
return &SiteServer{}
|
||||
}
|
||||
|
||||
// 站点列表
|
||||
func (s *SiteServer) Fetch(ctx context.Context, in *pb.Empty) (*pb.SiteListReply, error) {
|
||||
return site.Fetch(ctx, in)
|
||||
}
|
||||
|
||||
// 站点详情
|
||||
func (s *SiteServer) Get(ctx context.Context, in *pb.IdentRequest) (*pb.SiteItem, error) {
|
||||
return site.Get(ctx, in)
|
||||
}
|
||||
|
||||
// 添加站点
|
||||
func (s *SiteServer) Create(ctx context.Context, in *pb.SiteItem) (*pb.StatusReply, error) {
|
||||
return site.Create(ctx, in)
|
||||
}
|
||||
|
||||
// 修改站点
|
||||
func (s *SiteServer) Modify(ctx context.Context, in *pb.SiteItem) (*pb.StatusReply, error) {
|
||||
return site.Modify(ctx, in)
|
||||
}
|
||||
|
||||
// 删除站点
|
||||
func (s *SiteServer) Delete(ctx context.Context, in *pb.IdentRequest) (*pb.StatusReply, error) {
|
||||
return site.Delete(ctx, in)
|
||||
}
|
||||
36
apps/base/cms/internal/server/tags_server.go
Normal file
36
apps/base/cms/internal/server/tags_server.go
Normal file
@@ -0,0 +1,36 @@
|
||||
// Code generated by protoc-gen-slc. DO NOT EDIT.
|
||||
package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
"git.apinb.com/bsm-apps/cms/internal/logic/tags"
|
||||
pb "git.apinb.com/bsm-apps/cms/pb"
|
||||
)
|
||||
|
||||
type TagsServer struct {
|
||||
pb.UnimplementedTagsServer
|
||||
}
|
||||
|
||||
func NewTagsServer() *TagsServer {
|
||||
return &TagsServer{}
|
||||
}
|
||||
|
||||
// 标签列表
|
||||
func (s *TagsServer) Fetch(ctx context.Context, in *pb.IdentRequest) (*pb.TagsListReply, error) {
|
||||
return tags.Fetch(ctx, in)
|
||||
}
|
||||
|
||||
// 创建标签
|
||||
func (s *TagsServer) Create(ctx context.Context, in *pb.TagsItem) (*pb.StatusReply, error) {
|
||||
return tags.Create(ctx, in)
|
||||
}
|
||||
|
||||
// 修改标签
|
||||
func (s *TagsServer) Modify(ctx context.Context, in *pb.TagsItem) (*pb.StatusReply, error) {
|
||||
return tags.Modify(ctx, in)
|
||||
}
|
||||
|
||||
// 删除标签
|
||||
func (s *TagsServer) Delete(ctx context.Context, in *pb.IdentRequest) (*pb.StatusReply, error) {
|
||||
return tags.Delete(ctx, in)
|
||||
}
|
||||
16
apps/base/cms/internal/utils/string.go
Normal file
16
apps/base/cms/internal/utils/string.go
Normal file
@@ -0,0 +1,16 @@
|
||||
// Package utils 提供通用工具函数
|
||||
// 包含字符串处理、格式化等常用功能
|
||||
package utils
|
||||
|
||||
import "strings"
|
||||
|
||||
// FormatKey 格式化键值
|
||||
// 移除空格,转换为小写,确保键值的唯一性和一致性
|
||||
// 参数:
|
||||
// - key: 原始键值
|
||||
// 返回:
|
||||
// - 格式化后的键值
|
||||
func FormatKey(key string) string {
|
||||
// 移除所有空格并转换为小写
|
||||
return strings.ToLower(strings.ReplaceAll(key, " ", ""))
|
||||
}
|
||||
Reference in New Issue
Block a user