From c007c304724b688fbaeba54c3c46485db7b674b9 Mon Sep 17 00:00:00 2001 From: truthhun <1272881215@qq.com> Date: Sat, 12 Nov 2022 09:57:47 +0800 Subject: [PATCH] =?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=88=9D=E5=A7=8B=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 6 +++ model/config.go | 12 +++--- model/data.go | 59 +++++++++++++++++++++++++++ model/data_test.go | 77 ++++++++++++++++++++++++++++++++++++ model/groupPermission.go | 6 +-- model/init.go | 62 +++++++++++++++++++++++------ model/permission.go | 8 ++-- model/user.go | 2 +- web/layouts/default.vue | 1 + web/pages/index.vue | 8 ++-- web/store/module/category.js | 2 +- web/utils/utils.js | 35 +++++++++------- 12 files changed, 232 insertions(+), 46 deletions(-) create mode 100644 model/data.go create mode 100644 model/data_test.go diff --git a/README.md b/README.md index 02d8a27..b46a7ca 100644 --- a/README.md +++ b/README.md @@ -37,3 +37,9 @@ make api - 除了文件上传相关的接口,其他接口一律使用proto进行定义。 +## 管理员初始账号密码 + +``` +账号:admin +密码:mnt.ltd +``` \ No newline at end of file diff --git a/model/config.go b/model/config.go index cd32c4e..e78b50b 100644 --- a/model/config.go +++ b/model/config.go @@ -352,7 +352,7 @@ func (m *DBModel) initConfig() (err error) { {Category: ConfigCategorySystem, Name: ConfigSystemLogo, Label: "网站Logo", Value: "", Placeholder: "请输入您网站的Logo路径", InputType: "image", Sort: 6, Options: ""}, {Category: ConfigCategorySystem, Name: ConfigSystemFavicon, Label: "网站Favicon", Value: "", Placeholder: "请输入您网站的Favicon路径", InputType: "image", Sort: 6, Options: ""}, {Category: ConfigCategorySystem, Name: ConfigSystemIcp, Label: "网站备案号", Value: "", Placeholder: "请输入您网站的备案号", InputType: "text", Sort: 6, Options: ""}, - {Category: ConfigCategorySystem, Name: ConfigSystemDomain, Label: "网站域名", Value: "", Placeholder: "请输入您网站的域名访问地址,如 https://moredoc.mnt.ltd,用以生成网站地图sitemap", InputType: "text", Sort: 7, Options: ""}, + {Category: ConfigCategorySystem, Name: ConfigSystemDomain, Label: "网站域名", Value: "https://moredoc.mnt.ltd", Placeholder: "请输入您网站的域名访问地址,如 https://moredoc.mnt.ltd,用以生成网站地图sitemap", InputType: "text", Sort: 7, Options: ""}, {Category: ConfigCategorySystem, Name: ConfigSystemCopyrightStartYear, Label: "版权起始年", Value: "2019", Placeholder: "请输入您网站版权起始年,如:2019,则前台会显示如 ©2019 - 2022 的字样", InputType: "text", Sort: 8, Options: ""}, {Category: ConfigCategorySystem, Name: ConfigSystemAnalytics, Label: "网站统计代码", Value: "", Placeholder: "请输入您网站的统计代码", InputType: "textarea", Sort: 9, Options: ""}, @@ -373,11 +373,11 @@ func (m *DBModel) initConfig() (err error) { {Category: ConfigCategorySecurity, Name: ConfigSecurityEnableCaptchaFindPassword, Label: "是否开启找回密码验证码", Value: "true", Placeholder: "请选择是否开启找回密码验证码", InputType: "switch", Sort: 22, Options: ""}, // 底部链接 - {Category: ConfigCategoryFooter, Name: ConfigFooterAbout, Label: "关于我们", Value: "", Placeholder: "请输入关于我们的链接地址,留空表示不显示", InputType: "text", Sort: 24, Options: ""}, - {Category: ConfigCategoryFooter, Name: ConfigFooterContact, Label: "联系我们", Value: "", Placeholder: "请输入联系我们的链接地址,留空表示不显示", InputType: "text", Sort: 25, Options: ""}, - {Category: ConfigCategoryFooter, Name: ConfigFooterAgreement, Label: "文库协议", Value: "", Placeholder: "请输入文库协议的链接地址,留空表示不显示", InputType: "text", Sort: 26, Options: ""}, - {Category: ConfigCategoryFooter, Name: ConfigFooterCopyright, Label: "免责声明", Value: "", Placeholder: "请输入免责声明的链接地址,留空表示不显示", InputType: "text", Sort: 27, Options: ""}, - {Category: ConfigCategoryFooter, Name: ConfigFooterFeedback, Label: "意见反馈", Value: "", Placeholder: "请输入意见反馈的链接地址,留空表示不显示", InputType: "text", Sort: 28, Options: ""}, + {Category: ConfigCategoryFooter, Name: ConfigFooterAbout, Label: "关于我们", Value: "/article/about", Placeholder: "请输入关于我们的链接地址,留空表示不显示", InputType: "text", Sort: 24, Options: ""}, + {Category: ConfigCategoryFooter, Name: ConfigFooterContact, Label: "联系我们", Value: "/article/contact", Placeholder: "请输入联系我们的链接地址,留空表示不显示", InputType: "text", Sort: 25, Options: ""}, + {Category: ConfigCategoryFooter, Name: ConfigFooterAgreement, Label: "文库协议", Value: "/article/agreement", Placeholder: "请输入文库协议的链接地址,留空表示不显示", InputType: "text", Sort: 26, Options: ""}, + {Category: ConfigCategoryFooter, Name: ConfigFooterCopyright, Label: "免责声明", Value: "/article/copyright", Placeholder: "请输入免责声明的链接地址,留空表示不显示", InputType: "text", Sort: 27, Options: ""}, + {Category: ConfigCategoryFooter, Name: ConfigFooterFeedback, Label: "意见反馈", Value: "/article/feedback", Placeholder: "请输入意见反馈的链接地址,留空表示不显示", InputType: "text", Sort: 28, Options: ""}, } for _, cfg := range cfgs { diff --git a/model/data.go b/model/data.go new file mode 100644 index 0000000..6bead13 --- /dev/null +++ b/model/data.go @@ -0,0 +1,59 @@ +package model + +func getPermissions() (permissions []Permission) { + permissions = []Permission{ + {Title: "查看用户列表", Description: "", Method: "GRPC", Path: "/api.v1.UserAPI/ListUser"}, + {Title: "创建用户组", Description: "", Method: "GRPC", Path: "/api.v1.GroupAPI/CreateGroup"}, + {Title: "查看友链列表", Description: "", Method: "GRPC", Path: "/api.v1.FriendlinkAPI/ListFriendlink"}, + {Title: "创建友链", Description: "", Method: "GRPC", Path: "/api.v1.FriendlinkAPI/CreateFriendlink"}, + {Title: "更新友链", Description: "", Method: "GRPC", Path: "/api.v1.FriendlinkAPI/UpdateFriendlink"}, + {Title: "删除友链", Description: "", Method: "GRPC", Path: "/api.v1.FriendlinkAPI/DeleteFriendlink"}, + {Title: "查看附件列表", Description: "", Method: "GRPC", Path: "/api.v1.AttachmentAPI/ListAttachment"}, + {Title: "删除附件", Description: "", Method: "GRPC", Path: "/api.v1.AttachmentAPI/DeleteAttachment"}, + {Title: "更新附件信息", Description: "", Method: "GRPC", Path: "/api.v1.AttachmentAPI/UpdateAttachment"}, + {Title: "获取横幅列表", Description: "", Method: "GRPC", Path: "/api.v1.BannerAPI/ListBanner"}, + {Title: "上传横幅", Description: "", Method: "POST", Path: "/api/v1/upload/banner"}, + {Title: "创建横幅", Description: "", Method: "GRPC", Path: "/api.v1.BannerAPI/CreateBanner"}, + {Title: "更新横幅", Description: "", Method: "GRPC", Path: "/api.v1.BannerAPI/UpdateBanner"}, + {Title: "删除横幅", Description: "", Method: "GRPC", Path: "/api.v1.BannerAPI/DeleteBanner"}, + {Title: "根据ID查询附件", Description: "", Method: "GRPC", Path: "/api.v1.AttachmentAPI/GetAttachment"}, + {Title: "根据ID查询横幅", Description: "", Method: "GRPC", Path: "/api.v1.BannerAPI/GetBanner"}, + {Title: "根据ID查询友链", Description: "", Method: "GRPC", Path: "/api.v1.FriendlinkAPI/GetFriendlink"}, + {Title: "删除用户组", Description: "", Method: "GRPC", Path: "/api.v1.GroupAPI/DeleteGroup"}, + {Title: "更新用户组", Description: "", Method: "GRPC", Path: "/api.v1.GroupAPI/UpdateGroup"}, + {Title: "获取用户组列表", Description: "", Method: "GRPC", Path: "/api.v1.GroupAPI/ListGroup"}, + {Title: "获取权限列表", Description: "", Method: "GRPC", Path: "/api.v1.PermissionAPI/ListPermission"}, + {Title: "根据ID查询权限", Description: "", Method: "GRPC", Path: "/api.v1.PermissionAPI/GetPermission"}, + {Title: "更新权限信息", Description: "", Method: "GRPC", Path: "/api.v1.PermissionAPI/UpdatePermission"}, + {Title: "获取用户组授权", Description: "", Method: "GRPC", Path: "/api.v1.GroupAPI/GetGroupPermission"}, + {Title: "给用户组授权", Description: "", Method: "GRPC", Path: "/api.v1.GroupAPI/UpdateGroupPermission"}, + {Title: "获取系统配置列表", Description: "", Method: "GRPC", Path: "/api.v1.ConfigAPI/ListConfig"}, + {Title: "更新系统配置", Description: "", Method: "GRPC", Path: "/api.v1.ConfigAPI/UpdateConfig"}, + {Title: "新增用户", Description: "", Method: "GRPC", Path: "/api.v1.UserAPI/AddUser"}, + {Title: "设置用户密码与分组", Description: "", Method: "GRPC", Path: "/api.v1.UserAPI/SetUser"}, + {Title: "删除用户", Description: "", Method: "GRPC", Path: "/api.v1.UserAPI/DeleteUser"}, + {Title: "更新用户资料", Description: "", Method: "GRPC", Path: "/api.v1.UserAPI/UpdateUserProfile"}, + {Title: "根据ID查询用户", Description: "", Method: "GRPC", Path: "/api.v1.UserAPI/GetUser"}, + {Title: "查询文档分类列表", Description: "", Method: "GRPC", Path: "/api.v1.CategoryAPI/ListCategory"}, + {Title: "根据ID查询文档分类", Description: "", Method: "GRPC", Path: "/api.v1.CategoryAPI/GetCategory"}, + {Title: "新增文档分类", Description: "", Method: "GRPC", Path: "/api.v1.CategoryAPI/CreateCategory"}, + {Title: "更新文档分类", Description: "", Method: "GRPC", Path: "/api.v1.CategoryAPI/UpdateCategory"}, + {Title: "删除文档分类", Description: "", Method: "GRPC", Path: "/api.v1.CategoryAPI/DeleteCategory"}, + {Title: "获取文档列表", Description: "", Method: "GRPC", Path: "/api.v1.DocumentAPI/ListDocument"}, + {Title: "删除文档", Description: "", Method: "GRPC", Path: "/api.v1.DocumentAPI/DeleteDocument"}, + {Title: "根据ID查询文档", Description: "", Method: "GRPC", Path: "/api.v1.DocumentAPI/GetDocument"}, + {Title: "更新文档", Description: "", Method: "GRPC", Path: "/api.v1.DocumentAPI/UpdateDocument"}, + {Title: "获取回收站文档列表", Description: "", Method: "GRPC", Path: "/api.v1.RecycleAPI/ListRecycleDocument"}, + {Title: "恢复回收站文档", Description: "", Method: "GRPC", Path: "/api.v1.RecycleAPI/RecoverRecycleDocument"}, + {Title: "清空回收站文档", Description: "", Method: "GRPC", Path: "/api.v1.RecycleAPI/ClearRecycleDocument"}, + {Title: "删除回收站文档", Description: "", Method: "GRPC", Path: "/api.v1.RecycleAPI/DeleteRecycleDocument"}, + {Title: "文章/单页管理", Description: "", Method: "GRPC", Path: "/api.v1.ArticleAPI/ListArticle"}, + {Title: "更新文章/单页", Description: "", Method: "GRPC", Path: "/api.v1.ArticleAPI/UpdateArticle"}, + {Title: "删除文章/单页", Description: "", Method: "GRPC", Path: "/api.v1.ArticleAPI/DeleteArticle"}, + {Title: "创建文章/单页", Description: "", Method: "GRPC", Path: "/api.v1.ArticleAPI/CreateArticle"}, + {Title: "上传文章图片和音视频", Description: "", Method: "POST", Path: "/api/v1/upload/article"}, + {Title: "上传文档分类封面", Description: "", Method: "POST", Path: "/api/v1/upload/category"}, + {Title: "上传配置图片文件", Description: "", Method: "POST", Path: "/api/v1/upload/config"}, + } + return +} diff --git a/model/data_test.go b/model/data_test.go new file mode 100644 index 0000000..707734f --- /dev/null +++ b/model/data_test.go @@ -0,0 +1,77 @@ +package model + +import ( + "bytes" + "os" + "strings" + "testing" + "text/template" + + "gorm.io/driver/mysql" + "gorm.io/gorm" +) + +const dataGoTpl = ` +package model + +func getPermissions() (permissions []Permission) { + permissions = []Permission{ + {{ range .Permissions }}{Title: "{{.Title}}", Description: "{{.Description}}", Method: "{{.Method}}", Path: "{{.Path}}"}, + {{end}} + } + return +} +` + +func TestGenData(t *testing.T) { + // 访问的数据库链接地址。 dsn: data source name + // 【注意】:以哪个数据库的【菜单】和【API】为准,则配置查询哪个数据库,以生成menu和api基础数据 + dsn := "root:root@tcp(127.0.0.1)/moredoc?charset=utf8mb4&parseTime=True&loc=Local" + t.Log("开始生成 data.go 文件") + t.Log("dsn:", dsn) + + db, err := gorm.Open(mysql.New(mysql.Config{ + DSN: dsn, // DSN + }), &gorm.Config{}) + if err != nil { + return + } + + defer func() { + d, _ := db.DB() + d.Close() + }() + + var ( + permissions []Permission + permissionTableName = Permission{}.TableName() + ) + + err = db.Table(permissionTableName).Find(&permissions).Error + if err != nil { + t.Errorf("生成 data.go 文件失败: %s", err.Error()) + return + } + + replacer := strings.NewReplacer("\"", "\\\"") + for idx, permission := range permissions { + permissions[idx].Title = replacer.Replace(permission.Title) + permissions[idx].Description = replacer.Replace(permission.Description) + } + + tmpl, err := template.New("data.go").Parse(dataGoTpl) + if err != nil { + t.Fatal(err.Error()) + } + buf := new(bytes.Buffer) + if err := tmpl.Execute(buf, map[string]interface{}{"Permissions": permissions}); err != nil { + t.Fatal(err.Error()) + } + + err = os.WriteFile("data.go", buf.Bytes(), 0666) + if err != nil { + t.Fatalf("生成 data.go 文件失败: %s", err.Error()) + } + + t.Log("生成 data.go 文件成功") +} diff --git a/model/groupPermission.go b/model/groupPermission.go index 3c48fa9..ca7b49b 100644 --- a/model/groupPermission.go +++ b/model/groupPermission.go @@ -7,9 +7,9 @@ import ( ) type GroupPermission struct { - Id int64 `form:"id" json:"id,omitempty" gorm:"column:id;type:bigint(20);size:20;default:0;comment:;"` - GroupId int64 `form:"group_id" json:"group_id,omitempty" gorm:"primaryKey;autoIncrement;index:group_permission,unique;index:group_id;column:group_id;comment:组ID;"` - PermissionId int64 `form:"permission_id" json:"permission_id,omitempty" gorm:"primaryKey;autoIncrement;index:group_permission,unique;column:permission_id;comment:权限ID;"` + Id int64 `form:"id" json:"id,omitempty" gorm:"primaryKey;autoIncrement;column:id;comment:自增主键;"` + GroupId int64 `form:"group_id" json:"group_id,omitempty" gorm:"index:group_permission,unique;index:group_id;column:group_id;comment:组ID;"` + PermissionId int64 `form:"permission_id" json:"permission_id,omitempty" gorm:"index:group_permission,unique;column:permission_id;comment:权限ID;"` CreatedAt *time.Time `form:"created_at" json:"created_at,omitempty" gorm:"column:created_at;type:datetime;comment:创建时间;"` UpdatedAt *time.Time `form:"updated_at" json:"updated_at,omitempty" gorm:"column:updated_at;type:datetime;comment:更新时间;"` } diff --git a/model/init.go b/model/init.go index 19f6ec9..ce58cce 100644 --- a/model/init.go +++ b/model/init.go @@ -27,7 +27,8 @@ type TableColumn struct { Comment string `gorm:"Comment"` } -var tablePrefix string +// 默认表前缀 +var tablePrefix string = "mnt_" type DBModel struct { db *gorm.DB @@ -204,26 +205,27 @@ func (m *DBModel) showTableColumn(tableName string) (columns []TableColumn, err // initialDatabase 初始化数据库相关数据 func (m *DBModel) initDatabase() (err error) { - // if err = m.initPermission(); err != nil { - // m.logger.Error("initialDatabase", zap.Error(err)) - // return - // } - // 初始化用户组及其权限 if err = m.initGroupAndPermission(); err != nil { - m.logger.Error("initialDatabase", zap.Error(err)) + m.logger.Error("initGroupAndPermission", zap.Error(err)) return } // 初始化用户 if err = m.initUser(); err != nil { - m.logger.Error("initialDatabase", zap.Error(err)) + m.logger.Error("initUser", zap.Error(err)) return } // 初始化配置 if err = m.initConfig(); err != nil { - m.logger.Error("initialDatabase", zap.Error(err)) + m.logger.Error("initConfig", zap.Error(err)) + return + } + + // 初始化友情链接 + if err = m.initFriendlink(); err != nil { + m.logger.Error("initFriendlink", zap.Error(err)) return } return @@ -234,7 +236,6 @@ func (m *DBModel) initGroupAndPermission() (err error) { groups := []Group{ {Id: 1, Title: "超级管理员", IsDisplay: true, Description: "系统超级管理员", UserCount: 0, Sort: 0}, {Id: 2, Title: "普通用户", IsDisplay: true, Description: "普通用户", UserCount: 0, Sort: 0, IsDefault: true}, - {Id: 3, Title: "游客", IsDisplay: true, Description: "游客", UserCount: 0, Sort: 0}, } // 如果没有任何用户组,则初始化 @@ -244,11 +245,50 @@ func (m *DBModel) initGroupAndPermission() (err error) { return } - err = m.db.Create(&groups).Error + sess := m.db.Begin() + defer func() { + if err != nil { + sess.Rollback() + } else { + sess.Commit() + } + }() + + err = sess.Create(&groups).Error if err != nil { m.logger.Error("initGroup", zap.Error(err)) + return } + // 初始化权限 + for _, permission := range getPermissions() { + err = sess.Where("method = ? and path = ?", permission.Method, permission.Path).FirstOrCreate(&permission).Error + if err != nil { + m.logger.Error("initPermission", zap.Error(err)) + return + } + } + + return +} + +func (m *DBModel) initFriendlink() (err error) { + var friendlink Friendlink + m.db.Find(&friendlink) + if friendlink.Id > 0 { + return + } + + // 默认友链 + var friendlinks = []Friendlink{ + {Title: "摩枫网络科技", Link: "https://mnt.ltd", Enable: true}, + {Title: "书栈网", Link: "https://www.bookstack.cn", Enable: true}, + } + + err = m.db.Create(&friendlinks).Error + if err != nil { + m.logger.Error("initFriendlink", zap.Error(err)) + } return } diff --git a/model/permission.go b/model/permission.go index 6205473..1427636 100644 --- a/model/permission.go +++ b/model/permission.go @@ -119,10 +119,10 @@ func (m *DBModel) CheckPermissionByUserId(userId int64, path string, httpMethod ) // NOTE: ID为1的用户,拥有所有权限,可以理解为类似linux的root用户 - // TODO: 后续应该直接打开这里的注释 - // if userId == 1 { - // return true - // } + if userId == 1 { + yes = true + return + } if len(httpMethod) > 0 { method = httpMethod[0] diff --git a/model/user.go b/model/user.go index 095ba6c..ca0ffb6 100644 --- a/model/user.go +++ b/model/user.go @@ -305,7 +305,7 @@ func (m *DBModel) initUser() (err error) { } // 初始化一个用户 - user := &User{Username: "admin", Password: "123456"} + user := &User{Username: "admin", Password: "mnt.ltd"} var groupId int64 = 1 // ID==1的用户组为管理员组 err = m.CreateUser(user, groupId) if err != nil { diff --git a/web/layouts/default.vue b/web/layouts/default.vue index a2d8e9e..7c0b92c 100644 --- a/web/layouts/default.vue +++ b/web/layouts/default.vue @@ -245,6 +245,7 @@ export default {