This commit is contained in:
孟帅
2023-02-23 17:53:04 +08:00
parent 7cf1b8ce8e
commit 61d0988d2c
402 changed files with 18340 additions and 35547 deletions

View File

@@ -0,0 +1,39 @@
## @{.label}
### 简介
@{.brief}
### 使用说明
@{.description}
### 迁移或安装
1安装 HotGo (2.1.4及以上)
项目介绍https://github.com/bufanyun/hotgo
2将当前插件项目拷贝进 HotGo 根目录的 server/addons 目录下
3 HotGo 根目录的 server/addons/modules 目录下创建go文件:@{.name}.go内容如下
```go
package modules
import _ "hotgo/addons/@{.name}"
```
4HotGo 后台进入 开发工具->插件管理->找到 @{.label} (@{.name}) 进行安装
5重启服务即可生效
### 常用命令行
```shell
# 接口维护-gen service
gf gen service -s=addons/@{.name}/logic -d=addons/@{.name}/service
```

View File

@@ -0,0 +1,28 @@
// Package config
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2023 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
package config
import (
"github.com/gogf/gf/v2/frame/g"
"hotgo/addons/@{.name}/model/input/sysin"
)
// GetReq 获取指定分组的配置
type GetReq struct {
g.Meta `path:"/config/get" method:"get" tags:"@{.label}" summary:"获取指定分组的配置"`
sysin.GetConfigInp
}
type GetRes struct {
*sysin.GetConfigModel
}
// UpdateReq 获取指定分组的配置
type UpdateReq struct {
g.Meta `path:"/config/update" method:"post" tags:"@{.label}" summary:"获取指定分组的配置"`
sysin.UpdateConfigInp
}
type UpdateRes struct {
}

View File

@@ -0,0 +1,21 @@
// Package index
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2023 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
package index
import (
"github.com/gogf/gf/v2/frame/g"
"hotgo/addons/@{.name}/model/input/sysin"
)
// TestReq 测试
type TestReq struct {
g.Meta `path:"/index/test" method:"get" tags:"@{.label}" summary:"测试后台API"`
sysin.IndexTestInp
}
type TestRes struct {
*sysin.IndexTestModel
}

View File

@@ -0,0 +1,21 @@
// Package index
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2023 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
package index
import (
"github.com/gogf/gf/v2/frame/g"
"hotgo/addons/@{.name}/model/input/sysin"
)
// TestReq 测试
type TestReq struct {
g.Meta `path:"/index/test" method:"get" tags:"@{.label}" summary:"测试前台API"`
sysin.IndexTestInp
}
type TestRes struct {
*sysin.IndexTestModel
}

View File

@@ -0,0 +1,21 @@
// Package index
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2023 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
package index
import (
"github.com/gogf/gf/v2/frame/g"
"hotgo/addons/@{.name}/model/input/sysin"
)
// TestReq 测试
type TestReq struct {
g.Meta `path:"/index/test" method:"get" summary:"@{.label}" tags:"测试首页"`
sysin.IndexTestInp
}
type TestRes struct {
g.Meta `mime:"text/html" type:"string" example:"<html/>"`
}

View File

@@ -0,0 +1,21 @@
// Package index
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2023 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
package index
import (
"github.com/gogf/gf/v2/frame/g"
"hotgo/addons/@{.name}/model/input/sysin"
)
// TestReq 测试
type TestReq struct {
g.Meta `path:"/index/test" method:"get" tags:"@{.label}" summary:"测试websocket"`
sysin.IndexTestInp
}
type TestRes struct {
*sysin.IndexTestModel
}

View File

@@ -0,0 +1,46 @@
// Package sys
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2023 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
package sys
import (
"context"
"github.com/gogf/gf/v2/util/gconv"
"hotgo/addons/@{.name}/model/input/sysin"
"hotgo/addons/@{.name}/service"
"hotgo/api/admin/config"
isysin "hotgo/internal/model/input/sysin"
)
var (
Config = cConfig{}
)
type cConfig struct{}
// GetConfig 获取指定分组的配置
func (c *cConfig) GetConfig(ctx context.Context, req *config.GetReq) (res *config.GetRes, err error) {
var in sysin.GetConfigInp
if err = gconv.Scan(req, &in); err != nil {
return
}
data, err := service.SysConfig().GetConfigByGroup(ctx, in)
res = new(config.GetRes)
res.GetConfigModel = (*isysin.GetConfigModel)(data)
return
}
// UpdateConfig 更新指定分组的配置
func (c *cConfig) UpdateConfig(ctx context.Context, req *config.UpdateReq) (res *config.UpdateRes, err error) {
var in sysin.UpdateConfigInp
if err = gconv.Scan(req, &in); err != nil {
return
}
err = service.SysConfig().UpdateConfigByGroup(ctx, in)
return
}

View File

@@ -0,0 +1,42 @@
// Package sys
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2023 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
package sys
import (
"context"
"github.com/gogf/gf/v2/util/gconv"
"hotgo/addons/@{.name}/api/admin/index"
"hotgo/addons/@{.name}/model/input/sysin"
"hotgo/addons/@{.name}/service"
"hotgo/utility/validate"
)
var (
Index = cIndex{}
)
type cIndex struct{}
// Test 测试
func (c *cIndex) Test(ctx context.Context, req *index.TestReq) (res *index.TestRes, err error) {
var in sysin.IndexTestInp
if err = gconv.Scan(req, &in); err != nil {
return nil, err
}
if err = validate.PreFilter(ctx, &in); err != nil {
return nil, err
}
data, err := service.SysIndex().Test(ctx, in)
if err != nil {
return
}
res = new(index.TestRes)
res.IndexTestModel = data
return
}

View File

@@ -0,0 +1,42 @@
// Package api
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2023 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
package api
import (
"context"
"github.com/gogf/gf/v2/util/gconv"
"hotgo/addons/@{.name}/api/api/index"
"hotgo/addons/@{.name}/model/input/sysin"
"hotgo/addons/@{.name}/service"
"hotgo/utility/validate"
)
var (
Index = cIndex{}
)
type cIndex struct{}
// Test 测试
func (c *cIndex) Test(ctx context.Context, req *index.TestReq) (res *index.TestRes, err error) {
var in sysin.IndexTestInp
if err = gconv.Scan(req, &in); err != nil {
return nil, err
}
if err = validate.PreFilter(ctx, &in); err != nil {
return nil, err
}
data, err := service.SysIndex().Test(ctx, in)
if err != nil {
return
}
res = new(index.TestRes)
res.IndexTestModel = data
return
}

View File

@@ -0,0 +1,47 @@
// Package home
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2023 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
package home
import (
"context"
"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"
isc "hotgo/internal/service"
"hotgo/utility/validate"
)
// Index 基础
var Index = cIndex{}
type cIndex struct{}
func (a *cIndex) Index(ctx context.Context, req *index.TestReq) (res *index.TestRes, err error) {
var in sysin.IndexTestInp
if err = gconv.Scan(req, &in); err != nil {
return nil, err
}
if err = validate.PreFilter(ctx, &in); err != nil {
return nil, err
}
data, err := service.SysIndex().Test(ctx, in)
if err != nil {
return
}
isc.View().RenderTpl(ctx, global.Tpl("home/index.html"), model.View{Data: g.Map{
"name": data.Name,
"module": data.Module,
"time": data.Time,
}})
return
}

View File

@@ -0,0 +1,42 @@
// Package websocket
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2023 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
package websocket
import (
"context"
"github.com/gogf/gf/v2/util/gconv"
"hotgo/addons/@{.name}/api/websocket/index"
"hotgo/addons/@{.name}/model/input/sysin"
"hotgo/addons/@{.name}/service"
"hotgo/utility/validate"
)
var (
Index = cIndex{}
)
type cIndex struct{}
// Test 测试
func (c *cIndex) Test(ctx context.Context, req *index.TestReq) (res *index.TestRes, err error) {
var in sysin.IndexTestInp
if err = gconv.Scan(req, &in); err != nil {
return nil, err
}
if err = validate.PreFilter(ctx, &in); err != nil {
return nil, err
}
data, err := service.SysIndex().Test(ctx, in)
if err != nil {
return
}
res = new(index.TestRes)
res.IndexTestModel = data
return
}

View File

@@ -0,0 +1,12 @@
// Package global
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2023 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
package global
import "hotgo/internal/library/addons"
var (
skeleton *addons.Skeleton // 插件架子
)

View File

@@ -0,0 +1,26 @@
// Package global
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2023 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
package global
import (
"context"
"hotgo/internal/library/addons"
)
func Init(ctx context.Context, sk *addons.Skeleton) {
skeleton = sk
}
func GetSkeleton() *addons.Skeleton {
if skeleton == nil {
panic("addon skeleton not initialized.")
}
return skeleton
}
func Tpl(tpl string) string {
return addons.Tpl(skeleton.Name, tpl)
}

View File

@@ -0,0 +1,9 @@
// ==========================================================================
// Code generated by GoFrame CLI tool. DO NOT EDIT.
// ==========================================================================
package logic
import (
_ "hotgo/addons/@{.name}/logic/sys"
)

View File

@@ -0,0 +1,60 @@
// Package sys
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2023 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
package sys
import (
"context"
"github.com/gogf/gf/v2/util/gconv"
"hotgo/addons/@{.name}/global"
"hotgo/addons/@{.name}/model"
"hotgo/addons/@{.name}/model/input/sysin"
"hotgo/addons/@{.name}/service"
isysin "hotgo/internal/model/input/sysin"
isc "hotgo/internal/service"
)
type sSysConfig struct{}
func NewSysConfig() *sSysConfig {
return &sSysConfig{}
}
func init() {
service.RegisterSysConfig(NewSysConfig())
}
// GetBasic 获取基础配置
func (s *sSysConfig) GetBasic(ctx context.Context) (conf *model.BasicConfig, err error) {
var in = isysin.GetAddonsConfigInp{AddonName: global.GetSkeleton().Name, Group: "basic"}
models, err := isc.SysAddonsConfig().GetConfigByGroup(ctx, in)
if err != nil {
return
}
if err = gconv.Struct(models.List, &conf); err != nil {
return
}
return
}
// GetConfigByGroup 获取指定分组配置
func (s *sSysConfig) GetConfigByGroup(ctx context.Context, in sysin.GetConfigInp) (res *sysin.GetConfigModel, err error) {
in.GetAddonsConfigInp.AddonName = global.GetSkeleton().Name
models, err := isc.SysAddonsConfig().GetConfigByGroup(ctx, in.GetAddonsConfigInp)
if err != nil {
return
}
res = new(sysin.GetConfigModel)
res.List = models.List
return
}
// UpdateConfigByGroup 更新指定分组的配置
func (s *sSysConfig) UpdateConfigByGroup(ctx context.Context, in sysin.UpdateConfigInp) error {
in.UpdateAddonsConfigInp.AddonName = global.GetSkeleton().Name
return isc.SysAddonsConfig().UpdateConfigByGroup(ctx, in.UpdateAddonsConfigInp)
}

View File

@@ -0,0 +1,35 @@
// Package sys
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2023 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
package sys
import (
"context"
"fmt"
"github.com/gogf/gf/v2/os/gtime"
"hotgo/addons/@{.name}/global"
"hotgo/addons/@{.name}/model/input/sysin"
"hotgo/addons/@{.name}/service"
"hotgo/internal/library/contexts"
)
type sSysIndex struct{}
func NewSysIndex() *sSysIndex {
return &sSysIndex{}
}
func init() {
service.RegisterSysIndex(NewSysIndex())
}
// Test 测试
func (s *sSysIndex) Test(ctx context.Context, in sysin.IndexTestInp) (res *sysin.IndexTestModel, err error) {
res = new(sysin.IndexTestModel)
res.Name = in.Name
res.Module = fmt.Sprintf("当前插件模块是:%s当前应用模块是%s", global.GetSkeleton().Name, contexts.Get(ctx).Module)
res.Time = gtime.Now()
return
}

View File

@@ -0,0 +1,91 @@
// Package @{.name}
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2023 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
package @{.name}
import (
"context"
"github.com/gogf/gf/v2/net/ghttp"
"github.com/gogf/gf/v2/os/gctx"
"hotgo/addons/@{.name}/global"
_ "hotgo/addons/@{.name}/logic"
"hotgo/addons/@{.name}/router"
"hotgo/internal/library/addons"
"hotgo/internal/service"
"sync"
)
type module struct {
skeleton *addons.Skeleton
ctx context.Context
sync.Mutex
}
func init() {
newModule()
}
func newModule() {
m := &module{
skeleton: &addons.Skeleton{
Label: `@{.label}`,
Name: `@{.name}`,
Group: @{.group},
Logo: "",
Brief: `@{.brief}`,
Description: `@{.description}`,
Author: `@{.author}`,
Version: `@{.version}`, // 当该版本号高于已安装的版本号时,会提示可以更新
RootPath: addons.GetModulePath("@{.name}"),
},
ctx: gctx.New(),
}
addons.RegisterModule(m)
}
// Init 初始化
func (m *module) Init(ctx context.Context) {
global.Init(ctx, m.skeleton)
// ...
}
// 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)
router.WebSocket(ctx, group)
}
// Ctx 上下文
func (m *module) Ctx() context.Context {
return m.ctx
}
// GetSkeleton 架子
func (m *module) GetSkeleton() *addons.Skeleton {
return m.skeleton
}
// Install 安装模块
func (m *module) Install(ctx context.Context) (err error) {
// ...
return
}
// Upgrade 更新模块
func (m *module) Upgrade(ctx context.Context) (err error) {
// ...
return
}
// UnInstall 卸载模块
func (m *module) UnInstall(ctx context.Context) (err error) {
// ...
return
}

View File

@@ -0,0 +1,11 @@
// Package model
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2023 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
package model
// BasicConfig 基础配置
type BasicConfig struct {
Test string `json:"basicTest"`
}

View File

@@ -0,0 +1,24 @@
// Package sysin
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2023 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
package sysin
import (
"github.com/gogf/gf/v2/frame/g"
"hotgo/internal/model/input/sysin"
)
// UpdateConfigInp 更新指定配置
type UpdateConfigInp struct {
sysin.UpdateAddonsConfigInp
}
type GetConfigInp struct {
sysin.GetAddonsConfigInp
}
type GetConfigModel struct {
List g.Map `json:"list"`
}

View File

@@ -0,0 +1,27 @@
// Package sysin
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2023 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
//
package sysin
import (
"context"
"github.com/gogf/gf/v2/os/gtime"
)
// IndexTestInp 测试
type IndexTestInp struct {
Name string `json:"name" d:"HotGo" dc:"名称"`
}
func (in *IndexTestInp) Filter(ctx context.Context) (err error) {
return
}
type IndexTestModel struct {
Name string `json:"name" dc:"名称"`
Module string `json:"module" dc:"当前插件模块"`
Time *gtime.Time `json:"time" dc:"当前时间"`
}

View File

@@ -0,0 +1,34 @@
// Package router
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2023 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
package router
import (
"context"
"github.com/gogf/gf/v2/net/ghttp"
"hotgo/addons/@{.name}/controller/admin/sys"
"hotgo/addons/@{.name}/global"
"hotgo/addons/@{.name}/router/genrouter"
"hotgo/internal/consts"
"hotgo/internal/library/addons"
"hotgo/internal/service"
)
// Admin 后台路由
func Admin(ctx context.Context, group *ghttp.RouterGroup) {
prefix := addons.RouterPrefix(ctx, consts.AppAdmin, global.GetSkeleton().Name)
group.Group(prefix, func(group *ghttp.RouterGroup) {
group.Bind(
sys.Index,
)
group.Middleware(service.Middleware().AdminAuth)
group.Bind(
sys.Config,
)
})
// 注册生成路由
genrouter.Register(ctx, group)
}

View File

@@ -0,0 +1,32 @@
// Package router
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2023 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
package router
import (
"context"
"github.com/gogf/gf/v2/net/ghttp"
"hotgo/addons/@{.name}/controller/api"
"hotgo/addons/@{.name}/global"
"hotgo/internal/consts"
"hotgo/internal/library/addons"
"hotgo/internal/service"
)
// Api 前台路由
func Api(ctx context.Context, group *ghttp.RouterGroup) {
prefix := addons.RouterPrefix(ctx, consts.AppApi, global.GetSkeleton().Name)
group.Group(prefix, func(group *ghttp.RouterGroup) {
group.Bind(
// 无需验证的路由
api.Index,
)
group.Middleware(service.Middleware().ApiAuth)
group.Bind(
// 需要验证的路由
// ...
)
})
}

View File

@@ -0,0 +1,34 @@
// Package genrouter
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2023 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
package genrouter
import (
"context"
"github.com/gogf/gf/v2/net/ghttp"
"hotgo/addons/@{.name}/global"
"hotgo/internal/consts"
"hotgo/internal/library/addons"
"hotgo/internal/service"
)
var (
NoLogin []interface{} // 无需登录
LoginRequiredRouter []interface{} // 需要登录
)
// Register 注册通过代码生成的后台路由
func Register(ctx context.Context, group *ghttp.RouterGroup) {
prefix := addons.RouterPrefix(ctx, consts.AppAdmin, global.GetSkeleton().Name)
group.Group(prefix, func(group *ghttp.RouterGroup) {
if len(NoLogin) > 0 {
group.Bind(NoLogin...)
}
group.Middleware(service.Middleware().AdminAuth)
if len(LoginRequiredRouter) > 0 {
group.Bind(LoginRequiredRouter...)
}
})
}

View File

@@ -0,0 +1,25 @@
// Package router
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2023 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
package router
import (
"context"
"github.com/gogf/gf/v2/net/ghttp"
"hotgo/addons/@{.name}/controller/home"
"hotgo/addons/@{.name}/global"
"hotgo/internal/consts"
"hotgo/internal/library/addons"
)
// Home 前台页面路由
func Home(ctx context.Context, group *ghttp.RouterGroup) {
prefix := addons.RouterPrefix(ctx, consts.AppHome, global.GetSkeleton().Name)
group.Group(prefix, func(group *ghttp.RouterGroup) {
group.Bind(
home.Index,
)
})
}

View File

@@ -0,0 +1,40 @@
// Package router
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2023 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
package router
import (
"context"
"github.com/gogf/gf/v2/net/ghttp"
"hotgo/addons/@{.name}/controller/websocket"
"hotgo/addons/@{.name}/global"
"hotgo/internal/consts"
"hotgo/internal/library/addons"
"hotgo/internal/service"
ws "hotgo/internal/websocket"
)
// WebSocket ws路由配置
func WebSocket(ctx context.Context, group *ghttp.RouterGroup) {
prefix := addons.RouterPrefix(ctx, consts.AppWebSocket, global.GetSkeleton().Name)
group.Group(prefix, func(group *ghttp.RouterGroup) {
group.Bind(
// 无需验证的路由
websocket.Index,
)
// ws连接中间件
group.Middleware(service.Middleware().WebSocketToken)
group.Bind(
// 需要验证的路由
// ..
)
})
// 注册消息路由
ws.RegisterMsg(ws.EventHandlers{
// ...
})
}

View File

@@ -0,0 +1,50 @@
// ================================================================================
// Code generated by GoFrame CLI tool. DO NOT EDIT.
// You can delete these comments if you wish manually maintain this interface file.
// ================================================================================
package service
import (
"context"
"hotgo/addons/@{.name}/model"
"hotgo/addons/@{.name}/model/input/sysin"
)
type (
ISysConfig interface {
GetBasic(ctx context.Context) (conf *model.BasicConfig, err error)
GetConfigByGroup(ctx context.Context, in sysin.GetConfigInp) (res *sysin.GetConfigModel, err error)
UpdateConfigByGroup(ctx context.Context, in sysin.UpdateConfigInp) error
}
ISysIndex interface {
Test(ctx context.Context, in sysin.IndexTestInp) (res *sysin.IndexTestModel, err error)
}
)
var (
localSysConfig ISysConfig
localSysIndex ISysIndex
)
func SysConfig() ISysConfig {
if localSysConfig == nil {
panic("implement not found for interface ISysConfig, forgot register?")
}
return localSysConfig
}
func RegisterSysConfig(i ISysConfig) {
localSysConfig = i
}
func SysIndex() ISysIndex {
if localSysIndex == nil {
panic("implement not found for interface ISysIndex, forgot register?")
}
return localSysIndex
}
func RegisterSysIndex(i ISysIndex) {
localSysIndex = i
}

View File

@@ -0,0 +1,91 @@
// Package @{.varName | ToLower}
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) @{NowYear} HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
// @AutoGenerate Version @{.hgVersion}
// @AutoGenerate Date @{.nowTime}
//
package @{.varName | ToLower}
import (
"github.com/gogf/gf/v2/frame/g"
"@{.importInput}"
"hotgo/internal/model/input/form"
)
// ListReq 查询@{.tableComment}列表
type ListReq struct {
g.Meta `path:"/@{.varName | LcFirst}/list" method:"get" tags:"@{.tableComment}" summary:"获取@{.tableComment}列表"`
@{.templateGroup}in.@{.varName}ListInp
}
type ListRes struct {
form.PageRes
List []*@{.templateGroup}in.@{.varName}ListModel `json:"list" dc:"数据列表"`
}
@{ if eq .options.Step.HasExport true }
// ExportReq 导出@{.tableComment}列表
type ExportReq struct {
g.Meta `path:"/@{.varName | LcFirst}/export" method:"get" tags:"@{.tableComment}" summary:"导出@{.tableComment}列表"`
@{.templateGroup}in.@{.varName}ListInp
}
type ExportRes struct{}
@{end}
@{ if eq .options.Step.HasView true }
// ViewReq 获取@{.tableComment}指定信息
type ViewReq struct {
g.Meta `path:"/@{.varName | LcFirst}/view" method:"get" tags:"@{.tableComment}" summary:"获取@{.tableComment}指定信息"`
@{.templateGroup}in.@{.varName}ViewInp
}
type ViewRes struct {
*@{.templateGroup}in.@{.varName}ViewModel
}
@{end}
@{ if eq .options.Step.HasEdit true }
// EditReq 修改/新增@{.tableComment}
type EditReq struct {
g.Meta `path:"/@{.varName | LcFirst}/edit" method:"post" tags:"@{.tableComment}" summary:"修改/新增@{.tableComment}"`
@{.templateGroup}in.@{.varName}EditInp
}
type EditRes struct{}
@{end}
@{ if eq .options.Step.HasDel true }
// DeleteReq 删除@{.tableComment}
type DeleteReq struct {
g.Meta `path:"/@{.varName | LcFirst}/delete" method:"post" tags:"@{.tableComment}" summary:"删除@{.tableComment}"`
@{.templateGroup}in.@{.varName}DeleteInp
}
type DeleteRes struct{}
@{end}
@{ if and (eq .options.Step.HasEdit true) (eq .options.Step.HasMaxSort true) }
// MaxSortReq 获取@{.tableComment}最大排序
type MaxSortReq struct {
g.Meta `path:"/@{.varName | LcFirst}/maxSort" method:"get" tags:"@{.tableComment}" summary:"获取@{.tableComment}最大排序"`
}
type MaxSortRes struct {
*@{.templateGroup}in.@{.varName}MaxSortModel
}
@{end}
@{ if eq .options.Step.HasStatus true }
// StatusReq 更新@{.tableComment}状态
type StatusReq struct {
g.Meta `path:"/@{.varName | LcFirst}/status" method:"post" tags:"@{.tableComment}" summary:"更新@{.tableComment}状态"`
@{.templateGroup}in.@{.varName}StatusInp
}
type StatusRes struct{}
@{end}
@{ if eq .options.Step.HasSwitch true }
// SwitchReq 更新@{.tableComment}开关状态
type SwitchReq struct {
g.Meta `path:"/@{.varName | LcFirst}/switch" method:"post" tags:"@{.tableComment}" summary:"更新@{.tableComment}状态"`
@{.templateGroup}in.@{.varName}SwitchInp
}
type SwitchRes struct{}
@{end}

View File

@@ -0,0 +1,164 @@
// Package @{.templateGroup}
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) @{NowYear} HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
// @AutoGenerate Version @{.hgVersion}
// @AutoGenerate Date @{.nowTime}
//
package @{.templateGroup}
import (
"context"
"github.com/gogf/gf/v2/util/gconv"
"@{.importApi}"
"@{.importInput}"
"hotgo/internal/model/input/form"
"@{.importService}"
"hotgo/utility/validate"
)
var (
@{.varName} = c@{.varName}{}
)
type c@{.varName} struct{}
// List 查看@{.tableComment}列表
func (c *c@{.varName}) List(ctx context.Context, req *@{.varName | ToLower}.ListReq) (res *@{.varName | ToLower}.ListRes, err error) {
var in @{.templateGroup}in.@{.varName}ListInp
if err = gconv.Scan(req, &in); err != nil {
return
}
if err = validate.PreFilter(ctx, &in); err != nil {
return
}
list, totalCount, err := service.@{.templateGroup | UcFirst}@{.varName}().List(ctx, in)
if err != nil {
return
}
res = new(@{.varName | ToLower}.ListRes)
res.List = list
res.PageCount = form.CalPageCount(totalCount, req.PerPage)
res.Page = req.Page
res.PerPage = req.PerPage
return
}
@{ if eq .options.Step.HasExport true }
// Export 导出@{.tableComment}列表
func (c *c@{.varName}) Export(ctx context.Context, req *@{.varName | ToLower}.ExportReq) (res *@{.varName | ToLower}.ExportRes, err error) {
var in @{.templateGroup}in.@{.varName}ListInp
if err = gconv.Scan(req, &in); err != nil {
return
}
if err = validate.PreFilter(ctx, &in); err != nil {
return
}
err = service.@{.templateGroup | UcFirst}@{.varName}().Export(ctx, in)
return
}
@{end}
@{ if eq .options.Step.HasEdit true }
// Edit 更新@{.tableComment}
func (c *c@{.varName}) Edit(ctx context.Context, req *@{.varName | ToLower}.EditReq) (res *@{.varName | ToLower}.EditRes, err error) {
var in @{.templateGroup}in.@{.varName}EditInp
if err = gconv.Scan(req, &in); err != nil {
return
}
if err = validate.PreFilter(ctx, &in); err != nil {
return
}
err = service.@{.templateGroup | UcFirst}@{.varName}().Edit(ctx, in)
return
}
@{end}
@{ if and (eq .options.Step.HasEdit true) (eq .options.Step.HasMaxSort true) }
// MaxSort 获取@{.tableComment}最大排序
func (c *c@{.varName}) MaxSort(ctx context.Context, req *@{.varName | ToLower}.MaxSortReq) (res *@{.varName | ToLower}.MaxSortRes, err error) {
data, err := service.@{.templateGroup | UcFirst}@{.varName}().MaxSort(ctx, sysin.@{.varName}MaxSortInp{})
if err != nil {
return
}
res = new(@{.varName | ToLower}.MaxSortRes)
res.@{.varName}MaxSortModel = data
return
}
@{end}
@{ if eq .options.Step.HasView true }
// View 获取指定@{.tableComment}信息
func (c *c@{.varName}) View(ctx context.Context, req *@{.varName | ToLower}.ViewReq) (res *@{.varName | ToLower}.ViewRes, err error) {
var in @{.templateGroup}in.@{.varName}ViewInp
if err = gconv.Scan(req, &in); err != nil {
return
}
if err = validate.PreFilter(ctx, &in); err != nil {
return
}
data, err := service.@{.templateGroup | UcFirst}@{.varName}().View(ctx, in)
if err != nil {
return
}
res = new(@{.varName | ToLower}.ViewRes)
res.@{.varName}ViewModel = data
return
}
@{end}
@{ if eq .options.Step.HasDel true }
// Delete 删除@{.tableComment}
func (c *c@{.varName}) Delete(ctx context.Context, req *@{.varName | ToLower}.DeleteReq) (res *@{.varName | ToLower}.DeleteRes, err error) {
var in @{.templateGroup}in.@{.varName}DeleteInp
if err = gconv.Scan(req, &in); err != nil {
return
}
if err = validate.PreFilter(ctx, &in); err != nil {
return
}
err = service.@{.templateGroup | UcFirst}@{.varName}().Delete(ctx, in)
return
}
@{end}
@{ if eq .options.Step.HasStatus true }
// Status 更新@{.tableComment}状态
func (c *c@{.varName}) Status(ctx context.Context, req *@{.varName | ToLower}.StatusReq) (res *@{.varName | ToLower}.StatusRes, err error) {
var in @{.templateGroup}in.@{.varName}StatusInp
if err = gconv.Scan(req, &in); err != nil {
return
}
if err = validate.PreFilter(ctx, &in); err != nil {
return
}
err = service.@{.templateGroup | UcFirst}@{.varName}().Status(ctx, in)
return
}
@{end}
@{ if eq .options.Step.HasSwitch true }
// Switch 更新@{.tableComment}开关状态
func (c *c@{.varName}) Switch(ctx context.Context, req *@{.varName | ToLower}.SwitchReq) (res *@{.varName | ToLower}.SwitchRes, err error) {
var in @{.templateGroup}in.@{.varName}SwitchInp
if err = gconv.Scan(req, &in); err != nil {
return
}
if err = validate.PreFilter(ctx, &in); err != nil {
return
}
err = service.@{.templateGroup | UcFirst}@{.varName}().Switch(ctx, in)
return
}
@{end}

View File

@@ -0,0 +1,117 @@
// Package @{.templateGroup}in
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) @{NowYear} HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
// @AutoGenerate Version @{.hgVersion}
// @AutoGenerate Date @{.nowTime}
//
package @{.templateGroup}in
import (
"context"
"errors"
"github.com/gogf/gf/v2/encoding/gjson"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
"hotgo/internal/consts"
"hotgo/internal/model/entity"
"hotgo/internal/model/input/form"
"hotgo/utility/validate"
)
@{ if eq .options.Step.HasEdit true }
// @{.varName}EditInp 修改/新增@{.tableComment}
type @{.varName}EditInp struct {
entity.@{.daoName}
}
func (in *@{.varName}EditInp) Filter(ctx context.Context) (err error) {
return
}
type @{.varName}EditModel struct{}
@{end}
@{ if eq .options.Step.HasDel true }
// @{.varName}DeleteInp 删除@{.tableComment}
type @{.varName}DeleteInp struct {
@{.pk.GoName} interface{} `json:"@{.pk.TsName}" v:"required#@{.pk.Dc}不能为空" dc:"@{.pk.Dc}"`
}
func (in *@{.varName}DeleteInp) Filter(ctx context.Context) (err error) {
return
}
type @{.varName}DeleteModel struct{}
@{end}
@{ if eq .options.Step.HasView true }
// @{.varName}ViewInp 获取指定@{.tableComment}信息
type @{.varName}ViewInp struct {
@{.pk.GoName} @{.pk.GoType} `json:"@{.pk.TsName}" v:"required#@{.pk.Dc}不能为空" dc:"@{.pk.Dc}"`
}
func (in *@{.varName}ViewInp) Filter(ctx context.Context) (err error) {
return
}
type @{.varName}ViewModel struct {
entity.@{.daoName}
}@{end}
// @{.varName}ListInp 获取@{.tableComment}列表
type @{.varName}ListInp struct {
form.PageReq
@{.listInpColumns}
}
func (in *@{.varName}ListInp) Filter(ctx context.Context) (err error) {
return
}
type @{.varName}ListModel struct {
@{.listModelColumns}
}
@{ if eq .options.Step.HasExport true }
// @{.varName}ExportModel 导出@{.tableComment}
type @{.varName}ExportModel struct {
@{.exportModelColumns}
}@{end}
@{ if and (eq .options.Step.HasEdit true) (eq .options.Step.HasMaxSort true) }
// @{.varName}MaxSortInp 获取@{.tableComment}最大排序
type @{.varName}MaxSortInp struct{}
func (in *@{.varName}MaxSortInp) Filter(ctx context.Context) (err error) {
return
}
type @{.varName}MaxSortModel struct {
Sort int `json:"sort" description:"排序"`
}
@{end}
@{ if eq .options.Step.HasStatus true }
// @{.varName}StatusInp 更新@{.tableComment}状态
type @{.varName}StatusInp struct {
@{.pk.GoName} @{.pk.GoType} `json:"@{.pk.TsName}" v:"required#@{.pk.Dc}不能为空" dc:"@{.pk.Dc}"`
Status int `json:"status" dc:"状态"`
}
func (in *@{.varName}StatusInp) Filter(ctx context.Context) (err error) {
return
}
type @{.varName}StatusModel struct{}
@{end}
@{ if eq .options.Step.HasSwitch true }
// @{.varName}SwitchInp 更新@{.tableComment}开关状态
type @{.varName}SwitchInp struct {
form.SwitchReq
@{.pk.GoName} @{.pk.GoType} `json:"@{.pk.TsName}" v:"required#@{.pk.Dc}不能为空" dc:"@{.pk.Dc}"`
}
func (in *@{.varName}SwitchInp) Filter(ctx context.Context) (err error) {
return
}
type @{.varName}SwitchModel struct{}
@{end}

View File

@@ -0,0 +1,172 @@
// Package @{.templateGroup}
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) @{NowYear} HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
// @AutoGenerate Version @{.hgVersion}
// @AutoGenerate Date @{.nowTime}
//
package @{.templateGroup}
import (
"context"
"fmt"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gctx"
"github.com/gogf/gf/v2/os/gtime"
"github.com/gogf/gf/v2/util/gconv"
"hotgo/internal/consts"
"hotgo/internal/dao"
"hotgo/internal/library/contexts"
"hotgo/internal/library/hgorm"
"hotgo/internal/library/hgorm/handler"
"@{.importInput}"
"hotgo/internal/model/input/form"
"@{.importService}"
"hotgo/utility/convert"
"hotgo/utility/excel"
"hotgo/utility/validate"
)
type s@{.servFunName} struct{}
func New@{.servFunName}() *s@{.servFunName} {
return &s@{.servFunName}{}
}
func init() {
service.Register@{.servFunName}(New@{.servFunName}())
}
// Model @{.tableComment}ORM模型
func (s *s@{.servFunName}) Model(ctx context.Context, option ...*handler.Option) *gdb.Model {
return handler.Model(dao.@{.daoName}.Ctx(ctx), option...)
}
// List 获取@{.tableComment}列表
func (s *s@{.servFunName}) List(ctx context.Context, in @{.templateGroup}in.@{.varName}ListInp) (list []*@{.templateGroup}in.@{.varName}ListModel, totalCount int, err error) {
mod := s.Model(ctx)
@{.listWhere}
@{.listJoin.link}
totalCount, err = mod.Clone().Count(1)
if err != nil {
return
}
if totalCount == 0 {
return
}
@{.listJoin.select}
err = mod.Fields(fields).Page(in.Page, in.PerPage).@{.listOrder}.Scan(&list)
return
}
@{ if eq .options.Step.HasExport true }
// Export 导出@{.tableComment}
func (s *s@{.servFunName}) Export(ctx context.Context, in @{.templateGroup}in.@{.varName}ListInp) (err error) {
list, totalCount, err := s.List(ctx, in)
if err != nil {
return
}
// 字段的排序是依据tags的字段顺序如果你不想使用默认的排序方式可以直接定义 tags = []string{"字段名称", "字段名称2", ...}
tags, err := convert.GetEntityDescTags(@{.templateGroup}in.@{.varName}ExportModel{})
if err != nil {
return
}
var (
fileName = "导出@{.tableComment}-" + gctx.CtxId(ctx) + ".xlsx"
sheetName = fmt.Sprintf("索引条件共%v行,共%v页,当前导出是第%v页,本页共%v行", totalCount, form.CalPageCount(totalCount, in.PerPage), in.Page, len(list))
exports []@{.templateGroup}in.@{.varName}ExportModel
)
if err = gconv.Scan(list, &exports);err != nil {
return
}
err = excel.ExportByStructs(ctx, tags, exports, fileName, sheetName)
return
}@{end}
@{ if eq .options.Step.HasEdit true }
// Edit 修改/新增@{.tableComment}
func (s *s@{.servFunName}) Edit(ctx context.Context, in @{.templateGroup}in.@{.varName}EditInp) (err error) {
// 修改
if in.@{.pk.GoName} > 0 {
@{.edit.update}
}
// 新增
@{.edit.insert}
return
}
@{end}
@{ if eq .options.Step.HasDel true }
// Delete 删除@{.tableComment}
func (s *s@{.servFunName}) Delete(ctx context.Context, in @{.templateGroup}in.@{.varName}DeleteInp) (err error) {
_, err = s.Model(ctx).Where(dao.@{.daoName}.Columns().@{.pk.GoName}, in.@{.pk.GoName}).Delete()
return
}@{end}
@{ if and (eq .options.Step.HasEdit true) (eq .options.Step.HasMaxSort true) }
// MaxSort 获取@{.tableComment}最大排序
func (s *s@{.servFunName}) MaxSort(ctx context.Context, in @{.templateGroup}in.@{.varName}MaxSortInp) (res *@{.templateGroup}in.@{.varName}MaxSortModel, err error) {
if err = dao.@{.daoName}.Ctx(ctx).Fields(dao.@{.daoName}.Columns().Sort).OrderDesc(dao.@{.daoName}.Columns().Sort).Scan(&res); err != nil {
return
}
if res == nil {
res = new(@{.templateGroup}in.@{.varName}MaxSortModel)
}
res.Sort = form.DefaultMaxSort(ctx, res.Sort)
return
}
@{end}
@{ if eq .options.Step.HasView true }
// View 获取@{.tableComment}指定信息
func (s *s@{.servFunName}) View(ctx context.Context, in @{.templateGroup}in.@{.varName}ViewInp) (res *@{.templateGroup}in.@{.varName}ViewModel, err error) {
err = s.Model(ctx).Where(dao.@{.daoName}.Columns().@{.pk.GoName}, in.@{.pk.GoName}).Scan(&res)
return
}@{end}
@{ if eq .options.Step.HasStatus true }
// Status 更新@{.tableComment}状态
func (s *s@{.servFunName}) Status(ctx context.Context, in @{.templateGroup}in.@{.varName}StatusInp) (err error) {
if in.@{.pk.GoName} <= 0 {
err = gerror.New("@{.pk.Dc}不能为空")
return
}
if in.Status <= 0 {
err = gerror.New("状态不能为空")
return
}
if !validate.InSliceInt(consts.StatusMap, in.Status) {
err = gerror.New("状态不正确")
return
}
_, err = s.Model(ctx).Where(dao.@{.daoName}.Columns().@{.pk.GoName}, in.@{.pk.GoName}).Data(@{.statusUpdate}).Update()
return
}
@{end}
@{ if eq .options.Step.HasSwitch true }
// Switch 更新@{.tableComment}开关
func (s *s@{.servFunName}) Switch(ctx context.Context, in @{.templateGroup}in.@{.varName}SwitchInp) (err error) {
var fields = []string{
@{.switchFields}
// ...
}
if !validate.InSliceString(fields, in.Key) {
err = gerror.New("开关键名不在白名单")
return
}
_, err = s.Model(ctx).Where(dao.@{.daoName}.Columns().@{.pk.GoName}, in.@{.pk.GoName}).Data(@{.switchUpdate}).Update()
return
}
@{end}

View File

@@ -0,0 +1,15 @@
// Package genrouter
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) @{NowYear} HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
// @AutoGenerate Version @{.hgVersion}
// @AutoGenerate Date @{.nowTime}
//
package genrouter
import "@{.importController}"
func init() {
LoginRequiredRouter = append(LoginRequiredRouter, @{.templateGroup}.@{.varName}) // @{.tableComment}
}

View File

@@ -0,0 +1,71 @@
-- hotgo自动生成菜单权限SQL 通常情况下只在首次生成代码时自动执行一次
-- 如需再次执行请先手动删除生成的菜单权限和在SQL文件@{.generatePath}
-- Version: @{.hgVersion}
-- Date: @{.nowTime}
-- Link https://github.com/bufanyun/hotgo
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET AUTOCOMMIT = 0;
START TRANSACTION;
--
-- 数据库 `@{.dbName}`
--
-- --------------------------------------------------------
--
-- 插入表中的数据 `@{.menuTable}`
--
SET @now := now();
-- 菜单目录
INSERT INTO `@{.menuTable}` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`) VALUES (NULL, '@{.options.Menu.Pid}', '@{.tableComment}', '@{.varName | LcFirst}', '/@{.varName | LcFirst}', '@{.options.Menu.Icon}', '1', '', '', '', '@{.mainComponent}', '1', '', '0', '0', '', '0', '0', '0', '1', '', '@{.options.Menu.Sort}', '', '1', @now, @now);
SET @dirId = LAST_INSERT_ID();
-- 菜单页面
-- 列表
INSERT INTO `@{.menuTable}` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`) VALUES (NULL, @dirId, '@{.tableComment}列表', '@{.varName | LcFirst}Index', 'index', '', '2', '', '/@{.apiPrefix}/list', '', '/@{.componentPrefix}/index', '1', '', '0', '0', '', '0', '0', '0', '2', '', '10', '', '1', @now, @now);
SET @listId = LAST_INSERT_ID();
@{ if eq .options.Step.HasView true }
-- 详情
INSERT INTO `@{.menuTable}` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`) VALUES (NULL, @dirId, '@{.tableComment}详情', '@{.varName | LcFirst}View', 'view/:id?', '', '2', '', '/@{.apiPrefix}/view', '', '/@{.componentPrefix}/view', '0', '@{.varName | LcFirst}Index', '0', '0', '', '0', '1', '0', '2', '', '20', '', '1', @now, @now);
@{end}
-- 菜单按钮
@{ if eq .options.Step.HasEdit true }
-- 编辑
INSERT INTO `@{.menuTable}` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`) VALUES (NULL, @listId, '编辑/新增@{.tableComment}', '@{.varName | LcFirst}Edit', '', '', '3', '', '/@{.apiPrefix}/edit', '', '', '1', '', '0', '0', '', '0', '1', '0', '3', '', '10', '', '1', @now, @now);
@{end}
SET @editId = LAST_INSERT_ID();
@{ if and (eq .options.Step.HasEdit true) (eq .options.Step.HasMaxSort true) }
-- 获取最大排序
INSERT INTO `@{.menuTable}` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`) VALUES (NULL, @editId, '获取@{.tableComment}最大排序', '@{.varName | LcFirst}MaxSort', '', '', '3', '', '/@{.apiPrefix}/maxSort', '', '', '1', '', '0', '0', '', '0', '0', '0', '3', '', '10', '', '1', @now, @now);
@{end}
@{ if eq .options.Step.HasDel true }
-- 删除
INSERT INTO `@{.menuTable}` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`) VALUES (NULL, @listId, '删除@{.tableComment}', '@{.varName | LcFirst}Delete', '', '', '3', '', '/@{.apiPrefix}/delete', '', '', '1', '', '0', '0', '', '0', '0', '0', '3', '', '10', '', '1', @now, @now);
@{end}
@{ if eq .options.Step.HasStatus true }
-- 更新状态
INSERT INTO `@{.menuTable}` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`) VALUES (NULL, @listId, '修改@{.tableComment}状态', '@{.varName | LcFirst}Status', '', '', '3', '', '/@{.apiPrefix}/status', '', '', '1', '', '0', '0', '', '0', '0', '0', '3', '', '10', '', '1', @now, @now);
@{end}
@{ if eq .options.Step.HasSwitch true }
-- 操作开关
INSERT INTO `@{.menuTable}` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`) VALUES (NULL, @listId, '操作@{.tableComment}开关', '@{.varName | LcFirst}Switch', '', '', '3', '', '/@{.apiPrefix}/switch', '', '', '1', '', '0', '0', '', '0', '0', '0', '3', '', '10', '', '1', @now, @now);
@{end}
@{ if eq .options.Step.HasExport true }
-- 导出
INSERT INTO `@{.menuTable}` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`) VALUES (NULL, @listId, '导出@{.tableComment}', '@{.varName | LcFirst}Export', '', '', '3', '', '/@{.apiPrefix}/export', '', '', '1', '', '0', '0', '', '0', '0', '0', '3', '', '10', '', '1', @now, @now);
@{end}
COMMIT;

View File

@@ -0,0 +1,75 @@
import { http, jumpExport } from '@/utils/http/axios';
// 获取@{.tableComment}列表
export function List(params) {
return http.request({
url: '/@{.apiPrefix}/list',
method: 'get',
params,
});
}
@{ if eq .options.Step.HasDel true }
// 删除/批量删除@{.tableComment}
export function Delete(params) {
return http.request({
url: '/@{.apiPrefix}/delete',
method: 'POST',
params,
});
}
@{end}
@{ if eq .options.Step.HasEdit true }
// 添加/编辑@{.tableComment}
export function Edit(params) {
return http.request({
url: '/@{.apiPrefix}/edit',
method: 'POST',
params,
});
}
@{end}
@{ if eq .options.Step.HasStatus true }
// 修改@{.tableComment}状态
export function Status(params) {
return http.request({
url: '/@{.apiPrefix}/status',
method: 'POST',
params,
});
}
@{end}
@{ if eq .options.Step.HasSwitch true }
// 操作@{.tableComment}开关
export function Switch(params) {
return http.request({
url: '/@{.apiPrefix}/switch',
method: 'POST',
params,
});
}
@{end}
@{ if eq .options.Step.HasView true }
// 获取@{.tableComment}指定详情
export function View(params) {
return http.request({
url: '/@{.apiPrefix}/view',
method: 'GET',
params,
});
}
@{end}
@{ if eq .options.Step.HasMaxSort true }
// 获取@{.tableComment}最大排序
export function MaxSort() {
return http.request({
url: '/@{.apiPrefix}/maxSort',
method: 'GET',
});
}
@{end}
@{ if eq .options.Step.HasExport true }
// 导出@{.tableComment}
export function Export(params) {
jumpExport('/@{.apiPrefix}/export', params);
}
@{end}

View File

@@ -0,0 +1,99 @@
<template>
<div>
<n-spin :show="loading" description="请稍候...">
<n-modal
v-model:show="isShowModal"
:show-icon="false"
preset="dialog"
:title="params?.@{.pk.TsName} > 0 ? '编辑 #' + params?.@{.pk.TsName} : '添加'"
:style="{
width: dialogWidth,
}"
>
<n-form
:model="params"
:rules="rules"
ref="formRef"
label-placement="left"
:label-width="80"
class="py-4"
>
@{.formItem}
</n-form>
<template #action>
<n-space>
<n-button @click="closeForm">取消</n-button>
<n-button type="info" :loading="formBtnLoading" @click="confirmForm">确定</n-button>
</n-space>
</template>
</n-modal>
</n-spin>
</div>
</template>
<script lang="ts" setup>
@{.script.import} import { rules, options, State, newState } from './model';
import { useMessage } from 'naive-ui';
import { adaModalWidth } from '@/utils/hotgo';
const emit = defineEmits(['reloadTable', 'updateShowModal']);
interface Props {
showModal: boolean;
formParams?: State;
}
const props = withDefaults(defineProps<Props>(), {
showModal: false,
formParams: () => {
return newState(null);
},
});
const isShowModal = computed({
get: () => {
return props.showModal;
},
set: (value) => {
emit('updateShowModal', value);
},
});
const loading = ref(false);
const params = ref<State>(props.formParams);
const message = useMessage();
const formRef = ref<any>({});
const dialogWidth = ref('75%');
const formBtnLoading = ref(false);
function confirmForm(e) {
e.preventDefault();
formBtnLoading.value = true;
formRef.value.validate((errors) => {
if (!errors) {
Edit(params.value).then((_res) => {
message.success('操作成功');
setTimeout(() => {
isShowModal.value = false;
emit('reloadTable');
});
});
} else {
message.error('请填写完整信息');
}
formBtnLoading.value = false;
});
}
onMounted(async () => {
adaModalWidth(dialogWidth);
});
function closeForm() {
isShowModal.value = false;
}
@{.script.setup}
</script>
<style lang="less"></style>

View File

@@ -0,0 +1,249 @@
<template>
<div>
<n-card :bordered="false" class="proCard">
<div class="n-layout-page-header">
<n-card :bordered="false" title="@{.tableComment}">
<!-- 这是系统自动生成的CURD表格你可以将此行注释改为表格的描述 -->
</n-card>
</div>
<BasicForm
@register="register"
@submit="reloadTable"
@reset="reloadTable"
@keyup.enter="reloadTable"
ref="searchFormRef"
>
<template #statusSlot="{ model, field }">
<n-input v-model:value="model[field]" />
</template>
</BasicForm>
<BasicTable
:openChecked="@{.options.Step.HasCheck}"
:columns="columns"
:request="loadDataTable"
:row-key="(row) => row.id"
ref="actionRef"
:actionColumn="actionColumn"
@update:checked-row-keys="onCheckedRow"
:scroll-x="1090"
:resizeHeightOffset="-10000"
size="small"
>
<template #tableTitle>
@{ if eq .options.Step.HasAdd true } <n-button
type="primary"
@click="addTable"
class="min-left-space"
v-if="hasPermission(['/@{.apiPrefix}/edit'])"
>
<template #icon>
<n-icon>
<PlusOutlined />
</n-icon>
</template>
添加
</n-button>@{end}
@{ if eq .options.Step.HasBatchDel true } <n-button
type="error"
@click="handleBatchDelete"
:disabled="batchDeleteDisabled"
class="min-left-space"
v-if="hasPermission(['/@{.apiPrefix}/delete'])"
>
<template #icon>
<n-icon>
<DeleteOutlined />
</n-icon>
</template>
批量删除
</n-button>@{end}
@{ if eq .options.Step.HasExport true } <n-button
type="primary"
@click="handleExport"
class="min-left-space"
v-if="hasPermission(['/@{.apiPrefix}/delete'])"
>
<template #icon>
<n-icon>
<ExportOutlined />
</n-icon>
</template>
导出
</n-button>@{end}
</template>
</BasicTable>
</n-card>
@{ if eq .options.Step.HasEdit true } <Edit
@reloadTable="reloadTable"
@updateShowModal="updateShowModal"
:showModal="showModal"
:formParams="formParams"
/>@{end}
</div>
</template>
<script lang="ts" setup>
import { h, reactive, ref } from 'vue';
import { useDialog, useMessage } from 'naive-ui';
import { BasicTable, TableAction } from '@/components/Table';
import { BasicForm, useForm } from '@/components/Form/index';
import { usePermission } from '@/hooks/web/usePermission';
@{.apiImport}
import { State, columns, schemas, options, newState } from './model';
@{.iconsImport}
@{ if eq .options.Step.HasView true } import { useRouter } from 'vue-router';@{end}
import { getOptionLabel } from '@/utils/hotgo';
@{ if eq .options.Step.HasEdit true } import Edit from './edit.vue';@{end}
const { hasPermission } = usePermission();
@{ if eq .options.Step.HasView true } const router = useRouter();@{end}
const actionRef = ref();
const dialog = useDialog();
const message = useMessage();
const searchFormRef = ref<any>({});
const batchDeleteDisabled = ref(true);
const checkedIds = ref([]);
const showModal = ref(false);
const formParams = ref<State>();
const actionColumn = reactive({
width: 300,
title: '操作',
key: 'action',
// fixed: 'right',
render(record) {
return h(TableAction as any, {
style: 'button',
actions: [
@{ if eq .options.Step.HasEdit true } {
label: '编辑',
onClick: handleEdit.bind(null, record),
auth: ['/@{.apiPrefix}/edit'],
},@{end}
@{ if eq .options.Step.HasStatus true } {
label: '禁用',
onClick: handleStatus.bind(null, record, 2),
ifShow: () => {
return record.status === 1;
},
auth: ['/@{.apiPrefix}/status'],
},
{
label: '启用',
onClick: handleStatus.bind(null, record, 1),
ifShow: () => {
return record.status === 2;
},
auth: ['/@{.apiPrefix}/status'],
},@{end}
@{ if eq .options.Step.HasDel true } {
label: '删除',
onClick: handleDelete.bind(null, record),
auth: ['/@{.apiPrefix}/delete'],
},@{end}
],
@{ if eq .options.Step.HasView true } dropDownActions: [
{
label: '查看详情',
key: 'view',
auth: ['/@{.apiPrefix}/view'],
},
],
select: (key) => {
if (key === 'view') {
return handleView(record);
}
},@{end}
});
},
});
const [register, {}] = useForm({
gridProps: { cols: '1 s:1 m:2 l:3 xl:4 2xl:4' },
labelWidth: 80,
schemas,
});
const loadDataTable = async (res) => {
return await List({ ...searchFormRef.value?.formModel, ...res });
};
@{ if eq .options.Step.HasAdd true }
function addTable() {
showModal.value = true;
formParams.value = newState(null);
}@{end}
@{ if or (eq .options.Step.HasAdd true) (eq .options.Step.HasEdit true) }
function updateShowModal(value) {
showModal.value = value;
}@{end}
@{ if eq .options.Step.HasCheck true } function onCheckedRow(rowKeys) {
batchDeleteDisabled.value = rowKeys.length <= 0;
checkedIds.value = rowKeys;
}@{end}
function reloadTable() {
actionRef.value.reload();
}
@{ if eq .options.Step.HasView true }
function handleView(record: Recordable) {
router.push({ name: '@{.varName | LcFirst}View', params: { id: record.@{.pk.TsName} } });
}@{end}
@{ if eq .options.Step.HasEdit true }
function handleEdit(record: Recordable) {
showModal.value = true;
formParams.value = newState(record as State);
}@{end}
@{ if eq .options.Step.HasDel true } function handleDelete(record: Recordable) {
dialog.warning({
title: '警告',
content: '你确定要删除',
positiveText: '确定',
negativeText: '取消',
onPositiveClick: () => {
Delete(record).then((_res) => {
message.success('删除成功');
reloadTable();
});
},
onNegativeClick: () => {
// message.error('取消');
},
});
}@{end}
@{ if eq .options.Step.HasBatchDel true } function handleBatchDelete() {
dialog.warning({
title: '警告',
content: '你确定要批量删除',
positiveText: '确定',
negativeText: '取消',
onPositiveClick: () => {
Delete({ id: checkedIds.value }).then((_res) => {
message.success('删除成功');
reloadTable();
});
},
onNegativeClick: () => {
// message.error('取消');
},
});
}@{end}
@{ if eq .options.Step.HasExport true } function handleExport() {
message.loading('正在导出列表...', { duration: 1200 });
Export(searchFormRef.value?.formModel);
}@{end}
@{ if eq .options.Step.HasStatus true } function handleStatus(record: Recordable, status: number) {
Status({ @{.pk.TsName}: record.@{.pk.TsName}, status: status }).then((_res) => {
message.success('设为' + getOptionLabel(options.value.sys_normal_disable, status) + '成功');
setTimeout(() => {
reloadTable();
});
});
}@{end}
</script>
<style lang="less" scoped></style>

View File

@@ -0,0 +1,34 @@
import { h, ref } from 'vue';
import { NAvatar, NImage, NTag, NSwitch, NRate } from 'naive-ui';
import { cloneDeep } from 'lodash-es';
import { FormSchema } from '@/components/Form';
import { Dicts } from '@/api/dict/dict';
@{ if eq .options.Step.HasSwitch true }import { Switch } from '@/api/@{.varName | LcFirst}';@{end}
import { isArray, isNullObject } from '@/utils/is';
import { getFileExt } from '@/utils/urlUtils';
import { defRangeShortcuts, defShortcuts, formatToDate } from '@/utils/dateUtil';
import { validate } from '@/utils/validateUtil';
import { getOptionLabel, getOptionTag, Options, errorImg } from '@/utils/hotgo';
@{ if eq .options.Step.HasSwitch true }
import { usePermission } from '@/hooks/web/usePermission';
const { hasPermission } = usePermission();
const $message = window['$message'];
@{end}
@{.state}
@{.defaultState}
export function newState(state: State | null): State {
if (state !== null) {
return cloneDeep(state);
}
return cloneDeep(defaultState);
}
@{.dictOptions.const}
@{.rules}
@{.formSchema}
@{.columns}
@{.dictOptions.load}

View File

@@ -0,0 +1,48 @@
<template>
<div>
<div class="n-layout-page-header">
<n-card :bordered="false" title="@{.tableComment}详情"> <!-- CURD详情页--> </n-card>
</div>
<n-card :bordered="false" class="proCard mt-4" size="small" :segmented="{ content: true }">
<n-descriptions label-placement="left" class="py-2" column="4">
@{.item}
</n-descriptions>
</n-card>
</div>
</template>
<script lang="ts" setup>
import { computed, onMounted, ref } from 'vue';
import { useRouter } from 'vue-router';
import { useMessage } from 'naive-ui';
import { View } from '@{.importWebApi}';
import { newState, options } from './model';
import { getOptionLabel, getOptionTag } from '@/utils/hotgo';
import { getFileExt } from '@/utils/urlUtils';
const message = useMessage();
const router = useRouter();
const id = Number(router.currentRoute.value.params.id);
const formValue = ref(newState(null));
const fileAvatarCSS = computed(() => {
return {
'--n-merged-size': `var(--n-avatar-size-override, 80px)`,
'--n-font-size': `18px`,
};
});
//下载
function download(url: string) {
window.open(url);
}
onMounted(async () => {
if (id < 1) {
message.error('@{.pk.Dc}不正确请检查');
return;
}
formValue.value = await View({ @{.pk.TsName}: id });
});
</script>
<style lang="less" scoped></style>