379 lines
16 KiB
Go
379 lines
16 KiB
Go
package models
|
||
|
||
import (
|
||
"time"
|
||
)
|
||
|
||
// =============================================================
|
||
// 平台官网管理模型(表前缀 yz_platform_website_)
|
||
//
|
||
// 对应 platform 端「官网管理」模块,仅服务平台主站官网,
|
||
// 与租户站点内容表(yz_cms_*)互相独立。
|
||
// 建表 SQL:docs/sql/create_platform_website.sql
|
||
// =============================================================
|
||
|
||
// PlatformWebsiteCategory 平台官网-文章分类 yz_platform_website_category
|
||
type PlatformWebsiteCategory struct {
|
||
ID uint64 `orm:"column(id);pk;auto" json:"id"`
|
||
Cid uint64 `orm:"column(cid);default(0)" json:"cid"` // 父级分类ID,0 为顶级
|
||
Name string `orm:"column(name);size(100);default('')" json:"name"`
|
||
Image string `orm:"column(image);size(500);default('')" json:"image"`
|
||
Desc string `orm:"column(desc);size(500);default('')" json:"desc"`
|
||
Sort int `orm:"column(sort);default(0)" json:"sort"`
|
||
Status int8 `orm:"column(status);default(1)" json:"status"`
|
||
CreateTime time.Time `orm:"column(create_time);type(datetime);auto_now_add" json:"create_time"`
|
||
UpdateTime *time.Time `orm:"column(update_time);type(datetime);null" json:"update_time"`
|
||
DeleteTime *time.Time `orm:"column(delete_time);type(datetime);null" json:"delete_time"`
|
||
}
|
||
|
||
func (m *PlatformWebsiteCategory) TableName() string {
|
||
return "yz_platform_website_category"
|
||
}
|
||
|
||
// PlatformWebsiteArticle 平台官网-文章 yz_platform_website_article
|
||
type PlatformWebsiteArticle struct {
|
||
ID uint64 `orm:"column(id);pk;auto" json:"id"`
|
||
CateID uint64 `orm:"column(cate_id);default(0)" json:"cate_id"`
|
||
Title string `orm:"column(title);size(255);default('')" json:"title"`
|
||
Author string `orm:"column(author);size(100);default('')" json:"author"`
|
||
Desc string `orm:"column(desc);size(500);default('')" json:"desc"`
|
||
Image string `orm:"column(image);size(500);default('')" json:"image"`
|
||
Content string `orm:"column(content);type(mediumtext);null" json:"content"`
|
||
IsTrans int8 `orm:"column(is_trans);default(0)" json:"is_trans"`
|
||
TransURL *string `orm:"column(transurl);size(500);null" json:"transurl"`
|
||
Status int8 `orm:"column(status);default(0)" json:"status"` // 0 草稿 1 待审核 2 已发布 3 已隐藏
|
||
Top int8 `orm:"column(top);default(0)" json:"top"`
|
||
Recommend int8 `orm:"column(recommend);default(0)" json:"recommend"`
|
||
Views int `orm:"column(views);default(0)" json:"views"`
|
||
Likes int `orm:"column(likes);default(0)" json:"likes"`
|
||
PublisherID *uint64 `orm:"column(publisher_id);null" json:"publisher_id"`
|
||
PublishTime *time.Time `orm:"column(publish_time);type(datetime);null" json:"publish_time"`
|
||
CreateTime time.Time `orm:"column(create_time);type(datetime);auto_now_add" json:"create_time"`
|
||
UpdateTime *time.Time `orm:"column(update_time);type(datetime);null" json:"update_time"`
|
||
DeleteTime *time.Time `orm:"column(delete_time);type(datetime);null" json:"delete_time"`
|
||
}
|
||
|
||
func (m *PlatformWebsiteArticle) TableName() string {
|
||
return "yz_platform_website_article"
|
||
}
|
||
|
||
// PlatformWebsiteTag 平台官网-标签 yz_platform_website_tag
|
||
type PlatformWebsiteTag struct {
|
||
ID uint64 `orm:"column(id);pk;auto" json:"id"`
|
||
Name string `orm:"column(name);size(50);default('')" json:"name"`
|
||
Sort int `orm:"column(sort);default(0)" json:"sort"`
|
||
Status int8 `orm:"column(status);default(1)" json:"status"`
|
||
CreateTime time.Time `orm:"column(create_time);type(datetime);auto_now_add" json:"create_time"`
|
||
UpdateTime *time.Time `orm:"column(update_time);type(datetime);null" json:"update_time"`
|
||
DeleteTime *time.Time `orm:"column(delete_time);type(datetime);null" json:"delete_time"`
|
||
}
|
||
|
||
func (m *PlatformWebsiteTag) TableName() string {
|
||
return "yz_platform_website_tag"
|
||
}
|
||
|
||
// PlatformWebsiteArticleTag 平台官网-文章标签关联 yz_platform_website_article_tag
|
||
type PlatformWebsiteArticleTag struct {
|
||
ID uint64 `orm:"column(id);pk;auto" json:"id"`
|
||
ArticleID uint64 `orm:"column(article_id);default(0)" json:"article_id"`
|
||
TagID uint64 `orm:"column(tag_id);default(0)" json:"tag_id"`
|
||
CreateTime time.Time `orm:"column(create_time);type(datetime);auto_now_add" json:"create_time"`
|
||
}
|
||
|
||
func (m *PlatformWebsiteArticleTag) TableName() string {
|
||
return "yz_platform_website_article_tag"
|
||
}
|
||
|
||
// PlatformWebsiteComment 平台官网-评论 yz_platform_website_comment
|
||
type PlatformWebsiteComment struct {
|
||
ID uint64 `orm:"column(id);pk;auto" json:"id"`
|
||
ArticleID uint64 `orm:"column(article_id);default(0)" json:"article_id"`
|
||
Nickname string `orm:"column(nickname);size(100);default('')" json:"nickname"`
|
||
Email string `orm:"column(email);size(150);default('')" json:"email"`
|
||
Content string `orm:"column(content);type(text);null" json:"content"`
|
||
Reply string `orm:"column(reply);type(text);null" json:"reply"`
|
||
Status int8 `orm:"column(status);default(0)" json:"status"` // 0 待审核 1 已通过 2 已拒绝
|
||
IP string `orm:"column(ip);size(64);default('')" json:"ip"`
|
||
CreateTime time.Time `orm:"column(create_time);type(datetime);auto_now_add" json:"create_time"`
|
||
UpdateTime *time.Time `orm:"column(update_time);type(datetime);null" json:"update_time"`
|
||
DeleteTime *time.Time `orm:"column(delete_time);type(datetime);null" json:"delete_time"`
|
||
}
|
||
|
||
func (m *PlatformWebsiteComment) TableName() string {
|
||
return "yz_platform_website_comment"
|
||
}
|
||
|
||
// PlatformWebsiteNav 平台官网-导航菜单 yz_platform_website_nav
|
||
type PlatformWebsiteNav struct {
|
||
ID uint64 `orm:"column(id);pk;auto" json:"id"`
|
||
Pid uint64 `orm:"column(pid);default(0)" json:"pid"`
|
||
Title string `orm:"column(title);size(100);default('')" json:"title"`
|
||
Type int8 `orm:"column(type);default(1)" json:"type"` // 1 目录 2 页面 3 外链 4 单页
|
||
Path string `orm:"column(path);size(255);default('')" json:"path"`
|
||
ComponentPath string `orm:"column(component_path);size(255);default('')" json:"component_path"`
|
||
Icon string `orm:"column(icon);size(100);default('')" json:"icon"`
|
||
Sort int `orm:"column(sort);default(0)" json:"sort"`
|
||
Status int8 `orm:"column(status);default(1)" json:"status"`
|
||
IsVisible int8 `orm:"column(is_visible);default(1)" json:"is_visible"`
|
||
Permission string `orm:"column(permission);size(100);default('')" json:"permission"`
|
||
CreateTime time.Time `orm:"column(create_time);type(datetime);auto_now_add" json:"create_time"`
|
||
UpdateTime *time.Time `orm:"column(update_time);type(datetime);null" json:"update_time"`
|
||
DeleteTime *time.Time `orm:"column(delete_time);type(datetime);null" json:"delete_time"`
|
||
}
|
||
|
||
func (m *PlatformWebsiteNav) TableName() string {
|
||
return "yz_platform_website_nav"
|
||
}
|
||
|
||
// PlatformWebsiteLink 平台官网-友情链接 yz_platform_website_link
|
||
type PlatformWebsiteLink struct {
|
||
ID uint64 `orm:"column(id);pk;auto" json:"id"`
|
||
LinkName string `orm:"column(link_name);size(100);default('')" json:"link_name"`
|
||
LinkURL string `orm:"column(link_url);size(500);default('')" json:"link_url"`
|
||
LinkLogo string `orm:"column(link_logo);size(500);default('')" json:"link_logo"`
|
||
Description string `orm:"column(description);size(255);default('')" json:"description"`
|
||
Sort int `orm:"column(sort);default(0)" json:"sort"`
|
||
Status int8 `orm:"column(status);default(1)" json:"status"`
|
||
CreateTime time.Time `orm:"column(create_time);type(datetime);auto_now_add" json:"create_time"`
|
||
UpdateTime *time.Time `orm:"column(update_time);type(datetime);null" json:"update_time"`
|
||
DeleteTime *time.Time `orm:"column(delete_time);type(datetime);null" json:"delete_time"`
|
||
}
|
||
|
||
func (m *PlatformWebsiteLink) TableName() string {
|
||
return "yz_platform_website_link"
|
||
}
|
||
|
||
// PlatformWebsitePage 平台官网-单页 yz_platform_website_page
|
||
type PlatformWebsitePage struct {
|
||
ID uint64 `orm:"column(id);pk;auto" json:"id"`
|
||
Title string `orm:"column(title);size(255);default('')" json:"title"`
|
||
Path string `orm:"column(path);size(200);default('')" json:"path"`
|
||
Content string `orm:"column(content);type(longtext);null" json:"content"`
|
||
Sort int `orm:"column(sort);default(0)" json:"sort"`
|
||
Status int8 `orm:"column(status);default(1)" json:"status"`
|
||
CreateTime time.Time `orm:"column(create_time);type(datetime);auto_now_add" json:"create_time"`
|
||
UpdateTime *time.Time `orm:"column(update_time);type(datetime);null" json:"update_time"`
|
||
DeleteTime *time.Time `orm:"column(delete_time);type(datetime);null" json:"delete_time"`
|
||
}
|
||
|
||
func (m *PlatformWebsitePage) TableName() string {
|
||
return "yz_platform_website_page"
|
||
}
|
||
|
||
// PlatformWebsiteNotice 平台官网-站点公告 yz_platform_website_notice
|
||
// 建表 SQL:docs/sql/create_platform_website_notice.sql
|
||
type PlatformWebsiteNotice struct {
|
||
ID uint64 `orm:"column(id);pk;auto" json:"id"`
|
||
Title string `orm:"column(title);size(255);default('')" json:"title"`
|
||
Summary string `orm:"column(summary);size(500);default('')" json:"summary"`
|
||
Content string `orm:"column(content);type(mediumtext);null" json:"content"`
|
||
Type int8 `orm:"column(type);default(1)" json:"type"` // 1 通知公告 2 活动公告 3 系统维护
|
||
LinkURL string `orm:"column(link_url);size(500);default('')" json:"link_url"`
|
||
IsPopup int8 `orm:"column(is_popup);default(0)" json:"is_popup"` // 是否作为弹窗公告
|
||
Top int8 `orm:"column(top);default(0)" json:"top"` // 是否置顶
|
||
Sort int `orm:"column(sort);default(0)" json:"sort"`
|
||
Status int8 `orm:"column(status);default(0)" json:"status"` // 0 草稿 1 已发布 2 已下线
|
||
StartTime *time.Time `orm:"column(start_time);type(datetime);null" json:"start_time"`
|
||
EndTime *time.Time `orm:"column(end_time);type(datetime);null" json:"end_time"`
|
||
Views int `orm:"column(views);default(0)" json:"views"`
|
||
PublisherID *uint64 `orm:"column(publisher_id);null" json:"publisher_id"`
|
||
PublishTime *time.Time `orm:"column(publish_time);type(datetime);null" json:"publish_time"`
|
||
CreateTime time.Time `orm:"column(create_time);type(datetime);auto_now_add" json:"create_time"`
|
||
UpdateTime *time.Time `orm:"column(update_time);type(datetime);null" json:"update_time"`
|
||
DeleteTime *time.Time `orm:"column(delete_time);type(datetime);null" json:"delete_time"`
|
||
}
|
||
|
||
func (m *PlatformWebsiteNotice) TableName() string {
|
||
return "yz_platform_website_notice"
|
||
}
|
||
|
||
// ===================== 公共查询helper =====================
|
||
|
||
// PlatformWebsiteCategoryNameMap 分类ID -> 分类名称
|
||
func PlatformWebsiteCategoryNameMap(ids []uint64) map[uint64]string {
|
||
out := make(map[uint64]string)
|
||
if len(ids) == 0 {
|
||
return out
|
||
}
|
||
var rows []PlatformWebsiteCategory
|
||
if _, err := Orm.QueryTable(new(PlatformWebsiteCategory)).
|
||
Filter("id__in", ids).
|
||
All(&rows, "ID", "Name"); err != nil {
|
||
return out
|
||
}
|
||
for _, r := range rows {
|
||
out[r.ID] = r.Name
|
||
}
|
||
return out
|
||
}
|
||
|
||
// PlatformWebsiteCategoryMap 分类ID -> 分类记录
|
||
// 官网前台用:展示分类名与描述,并在文章没有封面图时用分类图片兜底。
|
||
func PlatformWebsiteCategoryMap(ids []uint64) map[uint64]PlatformWebsiteCategory {
|
||
out := make(map[uint64]PlatformWebsiteCategory)
|
||
if len(ids) == 0 {
|
||
return out
|
||
}
|
||
var rows []PlatformWebsiteCategory
|
||
if _, err := Orm.QueryTable(new(PlatformWebsiteCategory)).
|
||
Filter("id__in", ids).
|
||
All(&rows, "ID", "Name", "Desc", "Image"); err != nil {
|
||
return out
|
||
}
|
||
for _, r := range rows {
|
||
out[r.ID] = r
|
||
}
|
||
return out
|
||
}
|
||
|
||
// PlatformWebsiteCategoryDescendantMap 分类ID -> 全部后代分类ID(不含自身)
|
||
//
|
||
// 官网前台按父分类筛选 / 统计数量时,需要把整棵子树都算进来:
|
||
// 文章挂在子分类上时,点父分类也应该能看到。
|
||
// 分类数据量很小,每次整体构建一次即可;存在环时靠 seen 截断。
|
||
func PlatformWebsiteCategoryDescendantMap() map[uint64][]uint64 {
|
||
out := make(map[uint64][]uint64)
|
||
|
||
var rows []PlatformWebsiteCategory
|
||
if _, err := Orm.QueryTable(new(PlatformWebsiteCategory)).
|
||
Filter("delete_time__isnull", true).
|
||
All(&rows, "ID", "Cid"); err != nil {
|
||
return out
|
||
}
|
||
|
||
children := make(map[uint64][]uint64, len(rows))
|
||
ids := make([]uint64, 0, len(rows))
|
||
for _, r := range rows {
|
||
ids = append(ids, r.ID)
|
||
if r.Cid > 0 && r.Cid != r.ID {
|
||
children[r.Cid] = append(children[r.Cid], r.ID)
|
||
}
|
||
}
|
||
|
||
var walk func(id uint64, seen map[uint64]bool) []uint64
|
||
walk = func(id uint64, seen map[uint64]bool) []uint64 {
|
||
res := make([]uint64, 0, len(children[id]))
|
||
for _, child := range children[id] {
|
||
if seen[child] {
|
||
continue
|
||
}
|
||
seen[child] = true
|
||
res = append(res, child)
|
||
res = append(res, walk(child, seen)...)
|
||
}
|
||
return res
|
||
}
|
||
|
||
for _, id := range ids {
|
||
out[id] = walk(id, map[uint64]bool{id: true})
|
||
}
|
||
return out
|
||
}
|
||
|
||
// PlatformWebsiteArticleTitleMap 文章ID -> 标题(评论列表展示所属文章用)
|
||
func PlatformWebsiteArticleTitleMap(ids []uint64) map[uint64]string {
|
||
out := make(map[uint64]string)
|
||
if len(ids) == 0 {
|
||
return out
|
||
}
|
||
var rows []PlatformWebsiteArticle
|
||
if _, err := Orm.QueryTable(new(PlatformWebsiteArticle)).
|
||
Filter("id__in", ids).
|
||
All(&rows, "ID", "Title"); err != nil {
|
||
return out
|
||
}
|
||
for _, r := range rows {
|
||
out[r.ID] = r.Title
|
||
}
|
||
return out
|
||
}
|
||
|
||
// PlatformWebsiteArticleTagNameMap 文章ID -> 标签名称列表(官网前台展示用)
|
||
func PlatformWebsiteArticleTagNameMap(articleIDs []uint64) map[uint64][]string {
|
||
out := make(map[uint64][]string)
|
||
if len(articleIDs) == 0 {
|
||
return out
|
||
}
|
||
var links []PlatformWebsiteArticleTag
|
||
if _, err := Orm.QueryTable(new(PlatformWebsiteArticleTag)).
|
||
Filter("article_id__in", articleIDs).
|
||
All(&links, "ID", "ArticleID", "TagID"); err != nil {
|
||
return out
|
||
}
|
||
if len(links) == 0 {
|
||
return out
|
||
}
|
||
|
||
tagIDs := make([]uint64, 0, len(links))
|
||
for _, l := range links {
|
||
tagIDs = append(tagIDs, l.TagID)
|
||
}
|
||
var tags []PlatformWebsiteTag
|
||
if _, err := Orm.QueryTable(new(PlatformWebsiteTag)).
|
||
Filter("id__in", tagIDs).
|
||
Filter("delete_time__isnull", true).
|
||
All(&tags, "ID", "Name"); err != nil {
|
||
return out
|
||
}
|
||
nameMap := make(map[uint64]string, len(tags))
|
||
for _, t := range tags {
|
||
nameMap[t.ID] = t.Name
|
||
}
|
||
|
||
for _, l := range links {
|
||
if name, ok := nameMap[l.TagID]; ok && name != "" {
|
||
out[l.ArticleID] = append(out[l.ArticleID], name)
|
||
}
|
||
}
|
||
return out
|
||
}
|
||
|
||
// PlatformWebsiteArticleTagIDs 取某文章绑定的标签ID列表
|
||
func PlatformWebsiteArticleTagIDs(articleID uint64) []uint64 {
|
||
out := make([]uint64, 0)
|
||
if articleID == 0 {
|
||
return out
|
||
}
|
||
var rows []PlatformWebsiteArticleTag
|
||
if _, err := Orm.QueryTable(new(PlatformWebsiteArticleTag)).
|
||
Filter("article_id", articleID).
|
||
All(&rows, "ID", "TagID"); err != nil {
|
||
return out
|
||
}
|
||
for _, r := range rows {
|
||
out = append(out, r.TagID)
|
||
}
|
||
return out
|
||
}
|
||
|
||
// SetPlatformWebsiteArticleTags 覆盖式写入文章标签(先清空再插入)
|
||
func SetPlatformWebsiteArticleTags(articleID uint64, tagIDs []uint64) error {
|
||
if articleID == 0 {
|
||
return nil
|
||
}
|
||
if _, err := Orm.QueryTable(new(PlatformWebsiteArticleTag)).
|
||
Filter("article_id", articleID).
|
||
Delete(); err != nil {
|
||
return err
|
||
}
|
||
seen := make(map[uint64]bool, len(tagIDs))
|
||
for _, tid := range tagIDs {
|
||
if tid == 0 || seen[tid] {
|
||
continue
|
||
}
|
||
seen[tid] = true
|
||
if _, err := Orm.Insert(&PlatformWebsiteArticleTag{ArticleID: articleID, TagID: tid}); err != nil {
|
||
return err
|
||
}
|
||
}
|
||
return nil
|
||
}
|
||
|
||
// ClearPlatformWebsiteArticleTags 删除文章时清理标签关联
|
||
func ClearPlatformWebsiteArticleTags(articleID uint64) error {
|
||
_, err := Orm.QueryTable(new(PlatformWebsiteArticleTag)).
|
||
Filter("article_id", articleID).
|
||
Delete()
|
||
return err
|
||
}
|