Skip to content

Commit

Permalink
Merge branch 'dev.content'
Browse files Browse the repository at this point in the history
  • Loading branch information
caixw committed Jan 10, 2025
2 parents 1932c47 + 78efc67 commit 76b4b83
Show file tree
Hide file tree
Showing 24 changed files with 1,805 additions and 1 deletion.
4 changes: 4 additions & 0 deletions cmfx/categories/linkage/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,10 @@ func (m *Module) Validator(v int64) bool {
return false
}

if v == root.ID {
return true
}

curr, _ := find(v, root)
return curr != nil
}
Expand Down
1 change: 1 addition & 0 deletions cmfx/cmfx.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ const (
const (
Forbidden = web.ProblemForbidden
ForbiddenCaNotDeleteYourself = "40301"
ForbiddenMustBeAuthor = "40302"
)

// 404
Expand Down
21 changes: 21 additions & 0 deletions cmfx/contents/article/article.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// SPDX-FileCopyrightText: 2025 caixw
//
// SPDX-License-Identifier: MIT

// Package article 文章管理
package article

import (
"github.com/issue9/orm/v6"

"github.com/issue9/cmfx/cmfx"
)

const (
topicsTableName = "topics"
tagsTableName = "tags"
)

func buildDB(mod *cmfx.Module, tableName string) *orm.DB {
return mod.DB().New(mod.DB().TablePrefix() + "_" + tableName)
}
31 changes: 31 additions & 0 deletions cmfx/contents/article/install.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// SPDX-FileCopyrightText: 2025 caixw
//
// SPDX-License-Identifier: MIT

package article

import (
"github.com/issue9/web"

"github.com/issue9/cmfx/cmfx"
"github.com/issue9/cmfx/cmfx/categories/linkage"
"github.com/issue9/cmfx/cmfx/categories/tag"
"github.com/issue9/cmfx/cmfx/relationship"
)

// Install 安装数据
//
// mod 所属模块;tablePrefix 表名前缀;ts 关联的标签列表;
func Install(mod *cmfx.Module, tablePrefix string, ts ...string) *Module {
linkage.Install(mod, tablePrefix+"_"+topicsTableName, &linkage.Linkage{Title: "topics"})
tag.Install(mod, tablePrefix+"_"+tagsTableName, ts...)
relationship.Install[int64, int64](mod, tablePrefix+"_article_topic")
relationship.Install[int64, int64](mod, tablePrefix+"_article_tag")

db := buildDB(mod, tablePrefix)
if err := db.Create(&snapshotPO{}, &articlePO{}); err != nil {
panic(web.SprintError(mod.Server().Locale().Printer(), true, err))
}

return Load(mod, tablePrefix)
}
29 changes: 29 additions & 0 deletions cmfx/contents/article/install_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// SPDX-FileCopyrightText: 2025 caixw
//
// SPDX-License-Identifier: MIT

package article

import (
"testing"

"github.com/issue9/assert/v4"

"github.com/issue9/cmfx/cmfx/initial/test"
)

func TestInstall(t *testing.T) {
a := assert.New(t, false)

s := test.NewSuite(a)
defer s.Close()

mod := s.NewModule("test")
Install(mod, "abc")
prefix := mod.ID() + "_" + "abc"

s.TableExists(prefix + "_article_snapshots").
TableExists(prefix + "_articles").
TableExists(prefix + "_" + tagsTableName).
TableExists(prefix + "_" + topicsTableName)
}
73 changes: 73 additions & 0 deletions cmfx/contents/article/models.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// SPDX-FileCopyrightText: 2025 caixw
//
// SPDX-License-Identifier: MIT

package article

import (
"database/sql"
"errors"
"html"
"time"

"github.com/issue9/cmfx/cmfx/types"
)

// 文章快照的内容
type snapshotPO struct {
ID int64 `orm:"name(id);ai"`
Article int64 `orm:"name(article)"` // 所属的文章 ID
Author string `orm:"name(author);len(20)"` // 显示的作者信息
Title string `orm:"name(title);len(100)"` // 标题
Images types.Strings `orm:"name(images);len(1000)"` // 缩略图
Keywords string `orm:"name(keywords)"` // 关键字
Summary string `orm:"name(summary);len(2000)"` // 摘要
Content string `orm:"name(content);len(-1)"` // 文章内容
Created time.Time `orm:"name(created)"`
Creator int64 `orm:"name(creator)"`
}

type articlePO struct {
ID int64 `orm:"name(id);ai"`
Slug string `orm:"name(slug);len(200);unique(slug)"`
Last int64 `orm:"name(last)"` // 最后一次的快照 ID
Views int `orm:"name(views)"` // 查看数量
Order int `orm:"name(order)"` // 排序,按从小到大排序

Created time.Time `orm:"name(created)"`
Creator int64 `orm:"name(creator)"`
Modified time.Time `orm:"name(modified)"`
Modifier int64 `orm:"name(modifier)"`
Deleted sql.NullTime `orm:"name(deleted);nullable"`
Deleter int64 `orm:"name(deleter)"`
}

func (*snapshotPO) TableName() string { return `_article_snapshots` }

func (l *snapshotPO) BeforeInsert() error {
l.ID = 0
l.Title = html.EscapeString(l.Title)
l.Author = html.EscapeString(l.Author)
l.Keywords = html.EscapeString(l.Keywords)
l.Created = time.Now()

return nil
}

func (l *snapshotPO) BeforeUpdate() error {
return errors.New("快照不会执行更新操作")
}

func (*articlePO) TableName() string { return `_articles` }

func (l *articlePO) BeforeInsert() error {
l.ID = 0
l.Created = time.Now()

return nil
}

func (l *articlePO) BeforeUpdate() error {
l.Modified = time.Now()
return nil
}
15 changes: 15 additions & 0 deletions cmfx/contents/article/models_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// SPDX-FileCopyrightText: 2025 caixw
//
// SPDX-License-Identifier: MIT

package article

import "github.com/issue9/orm/v6"

var (
_ orm.TableNamer = &snapshotPO{}
_ orm.BeforeInserter = &snapshotPO{}
_ orm.BeforeUpdater = &snapshotPO{}

_ orm.TableNamer = &articlePO{}
)
46 changes: 46 additions & 0 deletions cmfx/contents/article/module.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// SPDX-FileCopyrightText: 2025 caixw
//
// SPDX-License-Identifier: MIT

package article

import (
"github.com/issue9/orm/v6"

"github.com/issue9/cmfx/cmfx"
"github.com/issue9/cmfx/cmfx/categories/linkage"
"github.com/issue9/cmfx/cmfx/categories/tag"
"github.com/issue9/cmfx/cmfx/relationship"
)

type Module struct {
db *orm.DB
mod *cmfx.Module
topics *linkage.Module
tags *tag.Module
topicRel *relationship.Module[int64, int64]
tagRel *relationship.Module[int64, int64]
}

// Load 加载内容管理模块
//
// tablePrefix 其它表都以此作为表名前缀;
// mod 所属的模块;
func Load(mod *cmfx.Module, tablePrefix string) *Module {
m := &Module{
db: buildDB(mod, tablePrefix),
mod: mod,
topics: linkage.Load(mod, tablePrefix+"_"+topicsTableName),
tags: tag.Load(mod, tablePrefix+"_"+tagsTableName),
topicRel: relationship.Load[int64, int64](mod, tablePrefix+"_article_topic"),
tagRel: relationship.Load[int64, int64](mod, tablePrefix+"_article_tag"),
}

return m
}

// Topics 用到的主题分类
func (m *Module) Topics() *linkage.Module { return m.topics }

// Tags 用到的标签分类
func (m *Module) Tags() *tag.Module { return m.tags }
Loading

0 comments on commit 76b4b83

Please sign in to comment.