diff --git a/docs/guide-zh-CN/addon-flow.md b/docs/guide-zh-CN/addon-flow.md index 074c903..eeed751 100644 --- a/docs/guide-zh-CN/addon-flow.md +++ b/docs/guide-zh-CN/addon-flow.md @@ -19,9 +19,8 @@ 1. /server/addons/hgexample/ # 插件模块目录 2. /server/addons/modules/hgexample.go # 隐式注册插件文件 -3. /server/resource/template/addons/hgexample # pc模板目录 -4. /web/src/api/addons/hgexample # webApi目录 -5. /web/src/views/addons/hgexample # web页面目录 +3. /web/src/api/addons/hgexample # webApi目录 +4. /web/src/views/addons/hgexample # web页面目录 # 默认情况下没有为web页面生成菜单权限,因为在实际场景中插件不一定需要用到web页面,所以如有需要请手动到后台 权限管理 -> 菜单权限->自行添加菜单和配置权限 ``` @@ -170,7 +169,7 @@ func (s *sSysAddonsConfig) UpdateConfigByGroup(ctx context.Context, in sysin.Upd 如:127.0.0.1:8000/admin/hgexample/index/test ``` -对应控制器路径:`server/addons/hgexample/controller/admin/sys/index.go` +- 对应控制器路径:`server/addons/hgexample/controller/admin/sys/index.go` #### 前端API插件访问路径 @@ -179,7 +178,7 @@ func (s *sSysAddonsConfig) UpdateConfigByGroup(ctx context.Context, in sysin.Upd 如:127.0.0.1:8000/api/hgexample/index/test ``` -对应控制器路径:`server/addons/hgexample/controller/api/index.go` +- 对应控制器路径:`server/addons/hgexample/controller/api/index.go` #### 前台页面插件访问路径 @@ -188,7 +187,17 @@ func (s *sSysAddonsConfig) UpdateConfigByGroup(ctx context.Context, in sysin.Upd 如:127.0.0.1:8000/home/hgexample/index/test ``` -对应控制器路径:`server/addons/hgexample/controller/home/index.go` +- 对应控制器路径:`server/addons/hgexample/controller/home/index.go` +- 对应模板路径:`server/addons/hgexample/resource/public/template` + +#### 静态资源插件访问路径 + +``` +// IP+端口或域名/home/插件名称/API路径 +如:127.0.0.1:8000/addons/hgexample/default +``` + +- 对应资源路径:`server/addons/hgexample/resource/public` #### Websocket插件访问路径 @@ -198,9 +207,9 @@ func (s *sSysAddonsConfig) UpdateConfigByGroup(ctx context.Context, in sysin.Upd 如:127.0.0.1:8000/socket/hgexample/index/test ``` -对应控制器路径:`server/addons/hgexample/controller/socket/index.go` +- 对应控制器路径:`server/addons/hgexample/controller/socket/index.go` ### 数据迁移 -可以将数据迁移逻辑写进server/xxx插件/main.go 文件中的Install方法中,并遵循系统规范进行数据安装 +- 可以将数据迁移逻辑写进server/xxx插件/main.go 文件中的Install方法中,并遵循系统规范进行数据安装 diff --git a/docs/guide-zh-CN/addon-helper.md b/docs/guide-zh-CN/addon-helper.md index 7466111..cd1101c 100644 --- a/docs/guide-zh-CN/addon-helper.md +++ b/docs/guide-zh-CN/addon-helper.md @@ -12,15 +12,16 @@ ```go // Skeleton 模块骨架 type Skeleton struct { - Label string `json:"label"` // 标识 - Name string `json:"name"` // 名称 - Group int `json:"group"` // 分组 - Logo string `json:"logo"` // logo - Brief string `json:"brief"` // 简介 - Description string `json:"description"` // 详细描述 - Author string `json:"author"` // 作者 - Version string `json:"version"` // 版本号 - RootPath string `json:"rootPath"` // 根路径 + Label string `json:"label"` // 标识 + Name string `json:"name"` // 名称 + Group int `json:"group"` // 分组 + Logo string `json:"logo"` // logo + Brief string `json:"brief"` // 简介 + Description string `json:"description"` // 详细描述 + Author string `json:"author"` // 作者 + Version string `json:"version"` // 版本号 + RootPath string `json:"rootPath"` // 根路径 + View *gview.View `json:"view"` // 模板引擎 } func (s *Skeleton) GetModule() Module { @@ -79,26 +80,4 @@ func test(ctx context.Context) { #### 插件路由规则 - 如果你不喜欢现在的路由风格,可以自行调整。修改位置在:\server\internal\library\addons\addons.go的RouterPrefix方法。 -- 调整后如web前端页面中有之前的路由风格也需同步修改。 - -```go -package main - -import ( - "context" - "github.com/gogf/gf/v2/frame/g" - "hotgo/internal/consts" -) - -// RouterPrefix 路由前缀 -// 最终效果:/应用名称/插件模块名称/xxx/xxx。如果你不喜欢现在的路由风格,可以自行调整 -func RouterPrefix(ctx context.Context, app, name string) string { - var prefix = "/" - - if app != "" { - prefix = g.Cfg().MustGet(ctx, "router."+app+".prefix", "/"+app+"").String() - } - - return prefix + "/" + name -} -``` \ No newline at end of file +- 注意调整后如web前端页面中如有之前的路由风格也需同步修改。 diff --git a/docs/guide-zh-CN/addon-introduce-catalog.md b/docs/guide-zh-CN/addon-introduce-catalog.md index 8591ded..3158900 100644 --- a/docs/guide-zh-CN/addon-introduce-catalog.md +++ b/docs/guide-zh-CN/addon-introduce-catalog.md @@ -26,9 +26,12 @@ HotGo 入口文件->隐式注入(hotgo/addons/modules)->注册所有插件->初 │ ├── xxx插件 │ | ├── api │ | ├── controller +│ | ├── crons │ | ├── global │ | ├── logic │ | ├── model +│ | ├── queues +│ | ├── resource │ | ├── router │ | ├── service │ | ├── main.go diff --git a/docs/guide-zh-CN/sys-catalog.md b/docs/guide-zh-CN/sys-catalog.md index 14ef0c6..f2cd356 100644 --- a/docs/guide-zh-CN/sys-catalog.md +++ b/docs/guide-zh-CN/sys-catalog.md @@ -15,9 +15,12 @@ │ ├── xxx插件 │ | ├── api │ | ├── controller +│ | ├── crons │ | ├── global │ | ├── logic │ | ├── model +│ | ├── queues +│ | ├── resource │ | ├── router │ | ├── service │ | ├── main.go @@ -68,10 +71,13 @@ | --- --- --- home | 前台PC端页面 | | --- --- --- websocket | 可同时为多应用提供websocket接口 | | --- --- controller | 接收/解析用户输入参数的入口/接口层,也可以理解为控制器 | +| --- --- crons | 项目中由系统统一接管的定时任务处理 | | --- --- global | 项目内主要的全局变量和系统的一些初始化操作 | | --- --- logic | 业务逻辑封装管理,特定的业务逻辑实现和封装往往是项目中最复杂的部分 | | --- --- model | 数据结构管理模块,管理数据实体对象,以及输入与输出数据结构定义 | -| --- --- --- input | 对内接口。用于controller调用service或service之间调用时的输入/输出结构定义,以及输入过滤和预处理 | +| --- --- --- input | 对内接口。用于controller调用service或service之间调用时的输入/输出结构定义,以及输入过滤和预处理 | +| --- queues | 为项目内所有的消息队列的消费者提供统一的初始化和处理 | +| --- resource | 静态资源文件。这些文件往往可以通过 资源打包/镜像编译 的形式注入到发布文件中 | | --- --- router | 注册对外接口和分组中间件 | | --- --- service | 用于业务模块解耦的接口定义层具体的接口实现在logic中进行注入 | | --- main.go | 插件始化文件和模块插拔接口 | @@ -93,7 +99,7 @@ | --- model | 数据结构管理模块,管理数据实体对象,以及输入与输出数据结构定义 | | --- --- do | 用于dao数据操作中业务模型与实例模型转换,由工具维护,用户不能修改 | | --- --- entity | 与数据集合绑定的程序数据结构定义,通常和数据表一一对应 | -| --- --- input | 对内接口。用于controller调用service或service之间调用时的输入/输出结构定义,以及输入过滤和预处理 | +| --- --- input | 对内接口。用于controller调用service或service之间调用时的输入/输出结构定义,以及输入过滤和预处理 | | --- packed | 将静态资源打包进可执行文件,无需单独部署 | | --- queues | 为项目内所有的消息队列的消费者提供统一的初始化和处理 | | --- router | 注册对外接口和分组中间件 | diff --git a/server/addons/hgexample/controller/home/index.go b/server/addons/hgexample/controller/home/index.go index f9017d8..3dd7e47 100644 --- a/server/addons/hgexample/controller/home/index.go +++ b/server/addons/hgexample/controller/home/index.go @@ -3,7 +3,6 @@ // @Copyright Copyright (c) 2023 HotGo CLI // @Author Ms <133814250@qq.com> // @License https://github.com/bufanyun/hotgo/blob/master/LICENSE -// package home import ( @@ -11,7 +10,6 @@ import ( "github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/util/gconv" "hotgo/addons/hgexample/api/home/index" - "hotgo/addons/hgexample/global" "hotgo/addons/hgexample/model/input/sysin" "hotgo/addons/hgexample/service" "hotgo/internal/model" @@ -39,7 +37,7 @@ func (a *cIndex) Index(ctx context.Context, req *index.TestReq) (res *index.Test return } - isc.View().RenderTpl(ctx, global.Tpl("home/index.html"), model.View{Data: g.Map{ + isc.View().RenderTpl(ctx, "home/index.html", model.View{Data: g.Map{ "name": data.Name, "module": data.Module, "time": data.Time, diff --git a/server/addons/hgexample/crons/crons.go b/server/addons/hgexample/crons/crons.go new file mode 100644 index 0000000..cbcbe05 --- /dev/null +++ b/server/addons/hgexample/crons/crons.go @@ -0,0 +1,4 @@ +package crons + +// 定时任务. +// 插件中的定时任务可以统一在这里注册和处理 diff --git a/server/addons/hgexample/global/init.go b/server/addons/hgexample/global/init.go index 1a13b3f..9db6de9 100644 --- a/server/addons/hgexample/global/init.go +++ b/server/addons/hgexample/global/init.go @@ -20,7 +20,3 @@ func GetSkeleton() *addons.Skeleton { } return skeleton } - -func Tpl(tpl string) string { - return addons.Tpl(skeleton.Name, tpl) -} diff --git a/server/addons/hgexample/main.go b/server/addons/hgexample/main.go index ac3e85d..97af95f 100644 --- a/server/addons/hgexample/main.go +++ b/server/addons/hgexample/main.go @@ -9,10 +9,13 @@ import ( "context" "github.com/gogf/gf/v2/net/ghttp" "github.com/gogf/gf/v2/os/gctx" + _ "hotgo/addons/hgexample/crons" "hotgo/addons/hgexample/global" _ "hotgo/addons/hgexample/logic" + _ "hotgo/addons/hgexample/queues" "hotgo/addons/hgexample/router" "hotgo/internal/library/addons" + "hotgo/internal/service" "sync" ) @@ -37,7 +40,6 @@ func newModule() { Description: "系统自带的功能使用示例及其说明,包含一些简单的交互", Author: "孟帅", Version: "v1.0.0", // 当该版本号高于已安装的版本号时,会提示可以更新 - RootPath: addons.GetModulePath("hgexample"), }, ctx: gctx.New(), } @@ -54,6 +56,7 @@ func (m *module) Init(ctx context.Context) { // InitRouter 初始化WEB路由 func (m *module) InitRouter(ctx context.Context, group *ghttp.RouterGroup) { m.Init(ctx) + group.Middleware(service.Middleware().Addon) router.Admin(ctx, group) router.Api(ctx, group) router.Home(ctx, group) diff --git a/server/addons/hgexample/queues/queues.go b/server/addons/hgexample/queues/queues.go new file mode 100644 index 0000000..892a3d2 --- /dev/null +++ b/server/addons/hgexample/queues/queues.go @@ -0,0 +1,4 @@ +package queues + +// 消息队列. +// 插件中的消息队列消费者可以统一在这里注册和处理 diff --git a/server/addons/hgexample/resource/public/default b/server/addons/hgexample/resource/public/default new file mode 100644 index 0000000..52e122c --- /dev/null +++ b/server/addons/hgexample/resource/public/default @@ -0,0 +1 @@ +Hello!这是创建插件 [功能案例] 时默认生成的一个静态目录文件,用于测试,当你看到这个提示时,说明已经联调成功啦! diff --git a/server/resource/template/addons/hgexample/home/index.html b/server/addons/hgexample/resource/template/home/index.html similarity index 100% rename from server/resource/template/addons/hgexample/home/index.html rename to server/addons/hgexample/resource/template/home/index.html diff --git a/server/internal/cmd/http.go b/server/internal/cmd/http.go index 6ccf42d..c5f3e22 100644 --- a/server/internal/cmd/http.go +++ b/server/internal/cmd/http.go @@ -71,6 +71,9 @@ var ( addons.RegisterModulesRouter(ctx, group) }) + // 设置插件静态目录映射 + addons.AddStaticPath(ctx, s) + // 初始化casbin权限 casbin.InitEnforcer(ctx) diff --git a/server/internal/library/addons/addons.go b/server/internal/library/addons/addons.go index 108d7a9..b080627 100644 --- a/server/internal/library/addons/addons.go +++ b/server/internal/library/addons/addons.go @@ -11,16 +11,26 @@ import ( "hotgo/internal/consts" ) -func GetTag(name string) string { - return consts.AddonsTag + name +// GetModulePath 获取指定模块相对路径 +func GetModulePath(name string) string { + return "./" + consts.AddonsDir + "/" + name } -func Tpl(name, tpl string) string { - return consts.AddonsDir + "/" + name + "/" + tpl +// ViewPath 默认的插件模板路径 +func ViewPath(name string) string { + return consts.AddonsDir + "/" + name + "/" + "resource/template" +} + +// StaticPath 默认的插件静态路映射关系 +// 最终效果:对外访问地址:/addons/插件模块名称;静态资源路径:/addons/插件模块名称/设置的子路径。 +// 如果你不喜欢现在的路由风格,可以自行调整 +func StaticPath(name, path string) (string, string) { + return "/" + consts.AddonsDir + "/" + name, consts.AddonsDir + "/" + name + "/" + path } // RouterPrefix 路由前缀 -// 最终效果:/应用名称/插件模块名称/xxx/xxx。如果你不喜欢现在的路由风格,可以自行调整 +// 最终效果:/应用名称/插件模块名称/xxx/xxx。 +// 如果你不喜欢现在的路由风格,可以自行调整 func RouterPrefix(ctx context.Context, app, name string) string { var prefix = "/" if app != "" { diff --git a/server/internal/library/addons/build.go b/server/internal/library/addons/build.go index 02b4afa..0b00756 100644 --- a/server/internal/library/addons/build.go +++ b/server/internal/library/addons/build.go @@ -2,7 +2,7 @@ package addons import ( "context" - "fmt" + "github.com/gogf/gf/v2/errors/gerror" "github.com/gogf/gf/v2/os/gfile" "github.com/gogf/gf/v2/text/gstr" "hotgo/internal/consts" @@ -16,7 +16,6 @@ func Build(ctx context.Context, sk Skeleton, conf *model.BuildAddonConfig) (err var ( buildPath = "./" + consts.AddonsDir + "/" + sk.Name modulesPath = "./" + consts.AddonsDir + "/modules/" + sk.Name + ".go" - templatePath = gstr.Replace(conf.TemplatePath, "{$name}", sk.Name) webApiPath = gstr.Replace(conf.WebApiPath, "{$name}", sk.Name) webViewsPath = gstr.Replace(conf.WebViewsPath, "{$name}", sk.Name) replaces = map[string]string{ @@ -31,7 +30,7 @@ func Build(ctx context.Context, sk Skeleton, conf *model.BuildAddonConfig) (err } ) - if err = checkBuildDir(buildPath, modulesPath, templatePath, webApiPath, webViewsPath); err != nil { + if err = checkBuildDir(buildPath, modulesPath, webApiPath, webViewsPath); err != nil { return } @@ -46,7 +45,7 @@ func Build(ctx context.Context, sk Skeleton, conf *model.BuildAddonConfig) (err for _, path := range list { if !gfile.IsReadable(path) { - err = fmt.Errorf("file:%v is unreadable, please check permissions", path) + err = gerror.Newf("file:%v is unreadable, please check permissions", path) return } @@ -72,11 +71,6 @@ func Build(ctx context.Context, sk Skeleton, conf *model.BuildAddonConfig) (err return } - // home默认页面 - if err = gfile.PutContents(templatePath+"/home/index.html", gstr.ReplaceByMap(homeLayout, replaces)); err != nil { - return - } - // webApi if err = gfile.PutContents(webApiPath+"/config/index.ts", gstr.ReplaceByMap(webApiLayout, replaces)); err != nil { return @@ -94,15 +88,15 @@ func Build(ctx context.Context, sk Skeleton, conf *model.BuildAddonConfig) (err return } -func checkBuildDir(paths ...string) error { +func checkBuildDir(paths ...string) (err error) { if len(paths) == 0 { - return nil + return } for _, path := range paths { if gfile.Exists(path) { - return fmt.Errorf("插件已存在,请换一个插件名称或者经确认无误后依次删除文件夹: [%v] 后重新生成", strings.Join(paths, "、\t")) + return gerror.Newf("插件已存在,请换一个插件名称或者经确认无误后依次删除文件夹: [%v] 后重新生成", strings.Join(paths, "、\t")) } } - return nil + return } diff --git a/server/internal/library/addons/build_layout.go b/server/internal/library/addons/build_layout.go index 8ebc15e..d5d8c75 100644 --- a/server/internal/library/addons/build_layout.go +++ b/server/internal/library/addons/build_layout.go @@ -11,39 +11,6 @@ package modules import _ "hotgo/addons/@{.name}" ` - homeLayout = ` - - - - - - - - @{.Title} - - - - -
-

Hello,@{.Data.name}!!

-

@{.Data.module}

-

服务器时间:@{.Data.time}

-
- - - -` - webApiLayout = `import { http } from '@/utils/http/axios'; export function getConfig(params) { diff --git a/server/internal/library/addons/install.go b/server/internal/library/addons/install.go index a0b4e7f..2614af5 100644 --- a/server/internal/library/addons/install.go +++ b/server/internal/library/addons/install.go @@ -23,11 +23,12 @@ type InstallRecord struct { UpdatedAt *gtime.Time `json:"updatedAt" description:"更新时间"` } +func GetModel(ctx context.Context) *gdb.Model { + return g.Model("sys_addons_install").Ctx(ctx) +} + func ScanInstall(m Module) (record *InstallRecord, err error) { - err = g.Model("sys_addons_install"). - Ctx(m.Ctx()). - Where("name", m.GetSkeleton().Name). - Scan(&record) + err = GetModel(m.Ctx()).Where("name", m.GetSkeleton().Name).Scan(&record) return } @@ -59,23 +60,14 @@ func Install(m Module) (err error) { "version": m.GetSkeleton().Version, "status": consts.AddonsInstallStatusOk, } - return g.DB().Transaction(m.Ctx(), func(ctx context.Context, tx gdb.TX) error { if record != nil { - _, err = g.Model("sys_addons_install"). - Ctx(m.Ctx()). - Where("id", record.Id). - Delete() + _, _ = GetModel(m.Ctx()).Where("id", record.Id).Delete() } - _, err = g.Model("sys_addons_install"). - Ctx(m.Ctx()). - Data(data). - Insert() - if err != nil { + if _, err = GetModel(m.Ctx()).Data(data).Insert(); err != nil { return err } - return m.Install(ctx) }) } @@ -94,18 +86,10 @@ func Upgrade(m Module) (err error) { data := g.Map{ "version": m.GetSkeleton().Version, } - return g.DB().Transaction(m.Ctx(), func(ctx context.Context, tx gdb.TX) error { - _, err = g.Model("sys_addons_install"). - Ctx(m.Ctx()). - Where("id", record.Id). - Data(data). - Update() - - if err != nil { + if _, err = GetModel(m.Ctx()).Where("id", record.Id).Data(data).Update(); err != nil { return err } - return m.Upgrade(ctx) }) } @@ -125,18 +109,10 @@ func UnInstall(m Module) (err error) { "version": m.GetSkeleton().Version, "status": consts.AddonsInstallStatusUn, } - return g.DB().Transaction(m.Ctx(), func(ctx context.Context, tx gdb.TX) error { - _, err = g.Model("sys_addons_install"). - Ctx(m.Ctx()). - Where("id", record.Id). - Data(data). - Update() - - if err != nil { + if _, err = GetModel(m.Ctx()).Where("id", record.Id).Data(data).Update(); err != nil { return err } - return m.UnInstall(ctx) }) } diff --git a/server/internal/library/addons/module.go b/server/internal/library/addons/module.go index 34feb5c..2dc0f81 100644 --- a/server/internal/library/addons/module.go +++ b/server/internal/library/addons/module.go @@ -7,9 +7,10 @@ package addons import ( "context" + "github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/net/ghttp" "github.com/gogf/gf/v2/os/gfile" - "hotgo/internal/consts" + "github.com/gogf/gf/v2/os/gview" "hotgo/internal/model/input/form" "sort" "sync" @@ -17,15 +18,16 @@ import ( // Skeleton 模块骨架 type Skeleton struct { - Label string `json:"label"` // 标识 - Name string `json:"name"` // 名称 - Group int `json:"group"` // 分组 - Logo string `json:"logo"` // logo - Brief string `json:"brief"` // 简介 - Description string `json:"description"` // 详细描述 - Author string `json:"author"` // 作者 - Version string `json:"version"` // 版本号 - RootPath string `json:"rootPath"` // 根路径 + Label string `json:"label"` // 标识 + Name string `json:"name"` // 名称 + Group int `json:"group"` // 分组 + Logo string `json:"logo"` // logo + Brief string `json:"brief"` // 简介 + Description string `json:"description"` // 详细描述 + Author string `json:"author"` // 作者 + Version string `json:"version"` // 版本号 + RootPath string `json:"rootPath"` // 根路径 + View *gview.View `json:"view"` // 模板引擎 } func (s *Skeleton) GetModule() Module { @@ -71,6 +73,14 @@ func RegisterModule(m Module) Module { if ok { panic("module repeat registration, name:" + name) } + + sk := m.GetSkeleton() + if sk == nil { + panic("module skeleton not initialized, name:" + name) + } + + sk.RootPath = GetModulePath(name) + sk.View = NewView(m.Ctx(), name) modules[name] = m return m } @@ -110,9 +120,45 @@ func GetModuleRealPath(name string) string { return path } -// GetModulePath 获取指定模块相对路径 -func GetModulePath(name string) string { - return "./" + consts.AddonsDir + "/" + name +// NewView 初始化一个插件的模板引擎 +func NewView(ctx context.Context, name string) *gview.View { + view := gview.New() + + if err := view.SetPath(ViewPath(name)); err != nil { + g.Log().Warningf(ctx, "NewView SetPath err:%+v", err) + return nil + } + + // 默认和主模块使用一致的变量分隔符号 + delimiters := g.Cfg().MustGet(ctx, "viewer.delimiters", []string{"@{", "}"}).Strings() + if len(delimiters) != 2 { + g.Log().Warning(ctx, "NewView delimiters config error") + return nil + } + view.SetDelimiters(delimiters[0], delimiters[1]) + + //// 更多配置 + //view.SetI18n() + //// ... + return view +} + +// AddStaticPath 设置插件静态目录映射 +func AddStaticPath(ctx context.Context, server *ghttp.Server, p ...string) { + basePath := g.Cfg().MustGet(ctx, "server.serverRoot").String() + if len(p) > 0 { + basePath = p[0] + } + + if basePath == "" { + return + } + + for _, module := range filterInstalled() { + name := module.GetSkeleton().Name + prefix, path := StaticPath(name, basePath) + server.AddStaticPath(prefix, path) + } } // filterInstalled 过滤已安装模块 diff --git a/server/internal/logic/middleware/init.go b/server/internal/logic/middleware/init.go index 94f9a24..1c0f6a6 100644 --- a/server/internal/logic/middleware/init.go +++ b/server/internal/logic/middleware/init.go @@ -133,7 +133,23 @@ func (s *sMiddleware) Addon(r *ghttp.Request) { return } - contexts.SetAddonName(ctx, addons.GetModule(ss[0]).GetSkeleton().Name) + module := addons.GetModule(ss[0]) + if module == nil { + g.Log().Warningf(ctx, "addon module = nil, name:%v", ss[0]) + return + } + + sk := module.GetSkeleton() + if sk == nil { + g.Log().Warningf(ctx, "addon skeleton = nil, name:%v", ss[0]) + return + } + + if sk.View != nil { + r.SetView(sk.View) + } + + contexts.SetAddonName(ctx, sk.Name) r.Middleware.Next() } diff --git a/server/internal/model/config_load.go b/server/internal/model/config_load.go index 99bbd43..c22e44f 100644 --- a/server/internal/model/config_load.go +++ b/server/internal/model/config_load.go @@ -69,7 +69,6 @@ type GenerateConfig struct { // BuildAddonConfig 构建插件模块配置 type BuildAddonConfig struct { SrcPath string `json:"srcPath"` - TemplatePath string `json:"templatePath"` WebApiPath string `json:"webApiPath"` WebViewsPath string `json:"webViewsPath"` } diff --git a/server/manifest/config/config.example.yaml b/server/manifest/config/config.example.yaml index ee09bb9..52ac4fa 100644 --- a/server/manifest/config/config.example.yaml +++ b/server/manifest/config/config.example.yaml @@ -301,6 +301,5 @@ hggen: # 生成插件模块,通过后台创建新插件时使用的模板,允许自定义,可以参考default模板进行改造 addon: srcPath: "./resource/generate/default/addon" # 生成模板路径 - templatePath: "./resource/template/addons/{$name}" # 页面模板路径 webApiPath: "../web/src/api/addons/{$name}" # webApi生成路径 webViewsPath: "../web/src/views/addons/{$name}" # web页面生成路径 \ No newline at end of file diff --git a/server/resource/generate/default/addon/controller/home/index.go.template b/server/resource/generate/default/addon/controller/home/index.go.template index a3fa3e2..bc4240f 100644 --- a/server/resource/generate/default/addon/controller/home/index.go.template +++ b/server/resource/generate/default/addon/controller/home/index.go.template @@ -10,7 +10,6 @@ import ( "github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/util/gconv" "hotgo/addons/@{.name}/api/home/index" - "hotgo/addons/@{.name}/global" "hotgo/addons/@{.name}/model/input/sysin" "hotgo/addons/@{.name}/service" "hotgo/internal/model" @@ -38,7 +37,7 @@ func (a *cIndex) Index(ctx context.Context, req *index.TestReq) (res *index.Test return } - isc.View().RenderTpl(ctx, global.Tpl("home/index.html"), model.View{Data: g.Map{ + isc.View().RenderTpl(ctx, "home/index.html", model.View{Data: g.Map{ "name": data.Name, "module": data.Module, "time": data.Time, diff --git a/server/resource/generate/default/addon/crons/crons.go.template b/server/resource/generate/default/addon/crons/crons.go.template new file mode 100644 index 0000000..cbcbe05 --- /dev/null +++ b/server/resource/generate/default/addon/crons/crons.go.template @@ -0,0 +1,4 @@ +package crons + +// 定时任务. +// 插件中的定时任务可以统一在这里注册和处理 diff --git a/server/resource/generate/default/addon/global/init.go.template b/server/resource/generate/default/addon/global/init.go.template index 1a13b3f..9db6de9 100644 --- a/server/resource/generate/default/addon/global/init.go.template +++ b/server/resource/generate/default/addon/global/init.go.template @@ -20,7 +20,3 @@ func GetSkeleton() *addons.Skeleton { } return skeleton } - -func Tpl(tpl string) string { - return addons.Tpl(skeleton.Name, tpl) -} diff --git a/server/resource/generate/default/addon/main.go.template b/server/resource/generate/default/addon/main.go.template index d8f5a48..7abbed0 100644 --- a/server/resource/generate/default/addon/main.go.template +++ b/server/resource/generate/default/addon/main.go.template @@ -9,8 +9,10 @@ import ( "context" "github.com/gogf/gf/v2/net/ghttp" "github.com/gogf/gf/v2/os/gctx" + _ "hotgo/addons/@{.name}/crons" "hotgo/addons/@{.name}/global" _ "hotgo/addons/@{.name}/logic" + _ "hotgo/addons/@{.name}/queues" "hotgo/addons/@{.name}/router" "hotgo/internal/library/addons" "hotgo/internal/service" @@ -38,11 +40,9 @@ func newModule() { Description: `@{.description}`, Author: `@{.author}`, Version: `@{.version}`, // 当该版本号高于已安装的版本号时,会提示可以更新 - RootPath: addons.GetModulePath("@{.name}"), }, ctx: gctx.New(), } - addons.RegisterModule(m) } diff --git a/server/resource/generate/default/addon/queues/queues.go.template b/server/resource/generate/default/addon/queues/queues.go.template new file mode 100644 index 0000000..892a3d2 --- /dev/null +++ b/server/resource/generate/default/addon/queues/queues.go.template @@ -0,0 +1,4 @@ +package queues + +// 消息队列. +// 插件中的消息队列消费者可以统一在这里注册和处理 diff --git a/server/resource/template/addons/.gitkeep b/server/resource/generate/default/addon/resource/public/.gitkeep similarity index 100% rename from server/resource/template/addons/.gitkeep rename to server/resource/generate/default/addon/resource/public/.gitkeep diff --git a/server/resource/generate/default/addon/resource/public/default.template b/server/resource/generate/default/addon/resource/public/default.template new file mode 100644 index 0000000..2199eab --- /dev/null +++ b/server/resource/generate/default/addon/resource/public/default.template @@ -0,0 +1 @@ +Hello!这是创建插件 [@{.label}] 时默认生成的一个静态目录文件,用于测试,当你看到这个提示时,说明已经联调成功啦! diff --git a/server/resource/generate/default/addon/resource/template/home/index.html b/server/resource/generate/default/addon/resource/template/home/index.html new file mode 100644 index 0000000..3502f4a --- /dev/null +++ b/server/resource/generate/default/addon/resource/template/home/index.html @@ -0,0 +1,30 @@ + + + + + + + + + @{.Title} + + + + +
+

Hello,@{.Data.name}!!

+

@{.Data.module}

+

服务器时间:@{.Data.time}

+
+ + + \ No newline at end of file diff --git a/server/resource/template/home/index.html b/server/resource/template/home/index.html index f2e5308..59ec6db 100644 --- a/server/resource/template/home/index.html +++ b/server/resource/template/home/index.html @@ -23,11 +23,7 @@

Hello,@{.Data.name}!!

当前版本:@{.Data.version}

- - - \ No newline at end of file diff --git a/web/src/views/addons/hgexample/portal/index.vue b/web/src/views/addons/hgexample/portal/index.vue index 743ef69..b0c9fc1 100644 --- a/web/src/views/addons/hgexample/portal/index.vue +++ b/web/src/views/addons/hgexample/portal/index.vue @@ -11,6 +11,9 @@
+ + +