优化企业网站功能

This commit is contained in:
2026-08-20 16:21:07 +08:00
parent 112d60b993
commit 3f0fcb88e7
45 changed files with 8758 additions and 5058 deletions
+1 -1
View File
@@ -30,4 +30,4 @@ func (m *BackendMenuFront) TableName() string {
func init() {
orm.RegisterModel(new(BackendMenuFront))
}
}
-41
View File
@@ -109,47 +109,6 @@ CREATE TABLE IF NOT EXISTS yz_cms_article (
return err
}
func EnsureCmsArticleDefaultCategories() error {
// 只初始化两级全局分类:文章中心(顶级)和新闻中心(文章中心的子分类)。
// 不在启动时创建其它业务分类,后续分类由管理员按需新增。
defaults := []struct {
name string
cid uint64
sort int
}{
{name: "文章中心", cid: 0, sort: 1},
{name: "新闻中心", cid: 1, sort: 2},
}
for _, item := range defaults {
count, err := Orm.QueryTable(new(CmsArticleCategory)).
Filter("tid", 0).
Filter("name", item.name).
Filter("cid", item.cid).
Filter("delete_time__isnull", true).
Count()
if err != nil {
return err
}
if count > 0 {
continue
}
now := time.Now()
_, err = Orm.Insert(&CmsArticleCategory{
Tid: 0,
Cid: item.cid,
Name: item.name,
Sort: item.sort,
Status: 1,
CreateTime: now,
})
if err != nil {
return err
}
}
return nil
}
func CmsCategoryNameMap(tid uint64, ids []uint64) map[uint64]string {
out := make(map[uint64]string)
if len(ids) == 0 {
+89
View File
@@ -0,0 +1,89 @@
package models
import (
"sync"
"time"
)
// CmsProduct CMS 产品 yz_cms_product
type CmsProduct struct {
ID uint64 `orm:"column(id);pk;auto" json:"id"`
Tid uint64 `orm:"column(tid);default(0)" json:"tid"`
Title string `orm:"column(title);size(100)" json:"title"`
Thumb string `orm:"column(thumb);size(500);default()" json:"thumb"`
Desc string `orm:"column(desc);size(500);default()" json:"desc"`
Content string `orm:"column(content);type(mediumtext);null" json:"content"`
URL string `orm:"column(url);size(500);default()" json:"url"`
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);auto_now_add;type(datetime)" 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 *CmsProduct) TableName() string {
return "yz_cms_product"
}
// CmsProductCategory CMS 产品分类 yz_cms_product_category
type CmsProductCategory struct {
ID uint64 `orm:"column(id);pk;auto" json:"id"`
Tid uint64 `orm:"column(tid);default(0)" json:"tid"`
Title string `orm:"column(title);size(100)" json:"title"`
Pid uint64 `orm:"column(pid);default(0)" json:"pid"`
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);auto_now_add;type(datetime)" 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 *CmsProductCategory) TableName() string {
return "yz_cms_product_category"
}
var cmsProductTablesOnce sync.Once
// EnsureCmsProductTables 首次使用时自动建表(若不存在)。
func EnsureCmsProductTables() error {
var err error
cmsProductTablesOnce.Do(func() {
_, err = Orm.Raw(`
CREATE TABLE IF NOT EXISTS yz_cms_product (
id bigint unsigned NOT NULL AUTO_INCREMENT,
tid bigint unsigned NOT NULL DEFAULT 0,
title varchar(100) NOT NULL DEFAULT '',
thumb varchar(500) NOT NULL DEFAULT '',
` + "`desc`" + ` varchar(500) NOT NULL DEFAULT '',
content mediumtext,
url varchar(500) NOT NULL DEFAULT '',
sort int NOT NULL DEFAULT 0,
status tinyint NOT NULL DEFAULT 1,
create_time datetime NOT NULL,
update_time datetime DEFAULT NULL,
delete_time datetime DEFAULT NULL,
PRIMARY KEY (id),
KEY idx_tid_status (tid, status)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4`).Exec()
if err != nil {
return
}
_, err = Orm.Raw(`
CREATE TABLE IF NOT EXISTS yz_cms_product_category (
id bigint unsigned NOT NULL AUTO_INCREMENT,
tid bigint unsigned NOT NULL DEFAULT 0,
title varchar(100) NOT NULL DEFAULT '',
pid bigint unsigned NOT NULL DEFAULT 0,
` + "`desc`" + ` varchar(500) NOT NULL DEFAULT '',
sort int NOT NULL DEFAULT 0,
status tinyint NOT NULL DEFAULT 1,
create_time datetime NOT NULL,
update_time datetime DEFAULT NULL,
delete_time datetime DEFAULT NULL,
PRIMARY KEY (id),
KEY idx_tid_pid (tid, pid)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4`).Exec()
})
return err
}
+87
View File
@@ -0,0 +1,87 @@
package models
import (
"sync"
"time"
)
// CmsSolution CMS 解决方案(特色服务) yz_cms_solution
type CmsSolution struct {
ID uint64 `orm:"column(id);pk;auto" json:"id"`
Tid uint64 `orm:"column(tid);default(0)" json:"tid"`
Title string `orm:"column(title);size(100)" json:"title"`
Thumb string `orm:"column(thumb);size(500);default()" json:"thumb"`
Desc string `orm:"column(desc);size(500);default()" json:"desc"`
URL string `orm:"column(url);size(500);default()" json:"url"`
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);auto_now_add;type(datetime)" 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 *CmsSolution) TableName() string {
return "yz_cms_solution"
}
// CmsSolutionCategory CMS 解决方案分类 yz_cms_solution_category
type CmsSolutionCategory struct {
ID uint64 `orm:"column(id);pk;auto" json:"id"`
Tid uint64 `orm:"column(tid);default(0)" json:"tid"`
Title string `orm:"column(title);size(100)" json:"title"`
Pid uint64 `orm:"column(pid);default(0)" json:"pid"`
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);auto_now_add;type(datetime)" 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 *CmsSolutionCategory) TableName() string {
return "yz_cms_solution_category"
}
var cmsSolutionTablesOnce sync.Once
// EnsureCmsSolutionTables 首次使用时自动建表(若不存在)。
func EnsureCmsSolutionTables() error {
var err error
cmsSolutionTablesOnce.Do(func() {
_, err = Orm.Raw(`
CREATE TABLE IF NOT EXISTS yz_cms_solution (
id bigint unsigned NOT NULL AUTO_INCREMENT,
tid bigint unsigned NOT NULL DEFAULT 0,
title varchar(100) NOT NULL DEFAULT '',
thumb varchar(500) NOT NULL DEFAULT '',
` + "`desc`" + ` varchar(500) NOT NULL DEFAULT '',
url varchar(500) NOT NULL DEFAULT '',
sort int NOT NULL DEFAULT 0,
status tinyint NOT NULL DEFAULT 1,
create_time datetime NOT NULL,
update_time datetime DEFAULT NULL,
delete_time datetime DEFAULT NULL,
PRIMARY KEY (id),
KEY idx_tid_status (tid, status)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4`).Exec()
if err != nil {
return
}
_, err = Orm.Raw(`
CREATE TABLE IF NOT EXISTS yz_cms_solution_category (
id bigint unsigned NOT NULL AUTO_INCREMENT,
tid bigint unsigned NOT NULL DEFAULT 0,
title varchar(100) NOT NULL DEFAULT '',
pid bigint unsigned NOT NULL DEFAULT 0,
` + "`desc`" + ` varchar(500) NOT NULL DEFAULT '',
sort int NOT NULL DEFAULT 0,
status tinyint NOT NULL DEFAULT 1,
create_time datetime NOT NULL,
update_time datetime DEFAULT NULL,
delete_time datetime DEFAULT NULL,
PRIMARY KEY (id),
KEY idx_tid_pid (tid, pid)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4`).Exec()
})
return err
}
+77
View File
@@ -0,0 +1,77 @@
package models
import "time"
// FrontMenuDefault 全局默认前端导航项定义
type FrontMenuDefault struct {
Title string
Path string
Type int8 // 菜单类型:2 页面 / 4 单页
Sort int
}
// FrontMenuDefaults 所有租户共用的默认导航(不可删除)。
// 以 tenant_id=0 存放于同一张菜单表,表示全局共享:
// 租户端增删改接口都带 tenant_id 过滤,天然无法触碰这些行。
// 路径对应官网前台路由:新闻中心 /news,其余为单页 /page/:path
// (单页内容在 backend 端 - 单页管理 中按 path 维护)。
var FrontMenuDefaults = []FrontMenuDefault{
{Title: "新闻中心", Path: "/news", Type: 2, Sort: 1},
{Title: "产品展示", Path: "/page/products", Type: 4, Sort: 2},
{Title: "解决方案", Path: "/page/solutions", Type: 4, Sort: 3},
{Title: "关于我们", Path: "/page/about", Type: 4, Sort: 4},
{Title: "联系我们", Path: "/page/contact", Type: 4, Sort: 5},
}
// EnsureGlobalDefaultFrontMenus 保证全局默认导航(tenant_id=0)齐全:
// 缺失的自动新增;被误删(软删)的自动恢复;已存在(含改名)的不动。
// 以"在库生效数量 >= 默认项总数"作为短路条件,避免改名后重复插入。
// 供后台菜单列表与前台导航渲染前调用,任何失败均静默忽略不阻断主流程。
func EnsureGlobalDefaultFrontMenus() {
if Orm == nil {
return
}
qs := Orm.QueryTable(new(BackendMenuFront)).Filter("tenant_id", 0)
activeCnt, err := qs.Filter("delete_time__isnull", true).Count()
if err != nil || activeCnt >= int64(len(FrontMenuDefaults)) {
return
}
// 含软删记录一起取,用于恢复被误删的默认菜单
var rows []BackendMenuFront
if _, err := qs.All(&rows); err != nil {
return
}
exist := make(map[string]*BackendMenuFront, len(rows))
for i := range rows {
exist[rows[i].Title] = &rows[i]
}
now := time.Now()
for _, def := range FrontMenuDefaults {
if row, ok := exist[def.Title]; ok {
if row.DeleteTime != nil {
_, _ = Orm.QueryTable(new(BackendMenuFront)).
Filter("id", row.ID).
Update(map[string]interface{}{
"delete_time": nil,
"status": 1,
"is_visible": 1,
"update_time": now,
})
}
continue
}
_, _ = Orm.Insert(&BackendMenuFront{
TenantID: 0,
Pid: 0,
Title: def.Title,
Path: def.Path,
Sort: def.Sort,
Status: 1,
IsVisible: 1,
Type: def.Type,
})
}
}