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 }