mirror of
https://github.com/bufanyun/hotgo.git
synced 2026-02-13 18:04:30 +08:00
发布代码生成、更新20+表单组件,优化数据字典,gf版本更新到2.3.1
This commit is contained in:
@@ -16,26 +16,33 @@ import (
|
||||
var (
|
||||
serverCloseSignal chan struct{}
|
||||
Main = &gcmd.Command{
|
||||
Description: `
|
||||
命令提示符
|
||||
---------------------------------------------------------------------------------
|
||||
启动服务
|
||||
>> HTTP服务 [go run main.go http]
|
||||
>> 消息队列 [go run main.go queue]
|
||||
>> 所有服务 [go run main.go all]
|
||||
|
||||
---------------------------------------------------------------------------------
|
||||
工具
|
||||
>> 释放casbin权限,用于清理无效的权限设置 [go run main.go tools -m=casbin -a1=refresh]
|
||||
`,
|
||||
Description: `默认启动所有服务`,
|
||||
Func: func(ctx context.Context, parser *gcmd.Parser) (err error) {
|
||||
return All.Func(ctx, parser)
|
||||
},
|
||||
}
|
||||
|
||||
Help = &gcmd.Command{
|
||||
Name: "help",
|
||||
Brief: "查看帮助",
|
||||
Description: `
|
||||
github地址:https://github.com/bufanyun/hotgo
|
||||
文档地址:文档正在书写中,请耐心等一等。
|
||||
命令提示符
|
||||
---------------------------------------------------------------------------------
|
||||
启动服务
|
||||
>> 所有服务 [go run main.go] 热编译 [gf run main.go]
|
||||
>> HTTP服务 [go run main.go http]
|
||||
>> 消息队列 [go run main.go queue]
|
||||
>> 查看帮助 [go run main.go help]
|
||||
|
||||
---------------------------------------------------------------------------------
|
||||
工具
|
||||
>> 释放casbin权限,用于清理无效的权限设置 [go run main.go tools -m=casbin -a1=refresh]
|
||||
|
||||
---------------------------------------------------------------------------------
|
||||
更多
|
||||
github地址:https://github.com/bufanyun/hotgo
|
||||
文档地址:文档正在书写中,请耐心等一等。
|
||||
HotGo框架交流1群:190966648
|
||||
`,
|
||||
}
|
||||
|
||||
@@ -44,7 +51,7 @@ var (
|
||||
Brief: "start all server",
|
||||
Description: "this is the command entry for starting all server",
|
||||
Func: func(ctx context.Context, parser *gcmd.Parser) (err error) {
|
||||
g.Log().Info(ctx, "start all server")
|
||||
g.Log().Debug(ctx, "starting all server")
|
||||
|
||||
simple.SafeGo(ctx, func(ctx context.Context) {
|
||||
if err := Http.Func(ctx, parser); err != nil {
|
||||
|
||||
@@ -11,10 +11,7 @@ import (
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
"github.com/gogf/gf/v2/os/gcmd"
|
||||
baseApi "hotgo/api/home/base"
|
||||
"hotgo/internal/controller/home/base"
|
||||
"hotgo/internal/library/casbin"
|
||||
"hotgo/internal/model"
|
||||
"hotgo/internal/router"
|
||||
"hotgo/internal/service"
|
||||
)
|
||||
@@ -25,10 +22,6 @@ var (
|
||||
Usage: "http",
|
||||
Brief: "HTTP服务",
|
||||
Func: func(ctx context.Context, parser *gcmd.Parser) (err error) {
|
||||
if _, err := g.Cfg().Get(ctx, "hotgo.debug"); err != nil {
|
||||
g.Log().Fatal(ctx, "配置读取异常:", err, "\r\n你确定 config/config.yaml 文件存在且格式正确吗?\r\n")
|
||||
}
|
||||
|
||||
// 加载权限
|
||||
casbin.InitEnforcer(ctx)
|
||||
|
||||
@@ -55,20 +48,10 @@ var (
|
||||
service.Middleware().ResponseHandler,
|
||||
)
|
||||
|
||||
// 注册默认首页路由
|
||||
group.ALL("/", func(r *ghttp.Request) {
|
||||
_, _ = base.Site.Index(r.Context(), &baseApi.SiteIndexReq{})
|
||||
return
|
||||
})
|
||||
|
||||
group.ALL("/login", func(r *ghttp.Request) {
|
||||
r.Response.RedirectTo("/admin")
|
||||
})
|
||||
|
||||
// 注册后台路由
|
||||
router.Admin(ctx, group)
|
||||
|
||||
// 注册前台路由
|
||||
// 注册Api路由
|
||||
router.Api(ctx, group)
|
||||
|
||||
// 注册websocket路由
|
||||
@@ -84,18 +67,8 @@ var (
|
||||
// 信号监听
|
||||
signalListen(ctx, signalHandlerForCron, signalHandlerForWebSocket)
|
||||
|
||||
// 开启https访问
|
||||
var (
|
||||
sSLConfig *model.SSLConfig
|
||||
ssl, _ = g.Cfg().Get(ctx, "hotgo.ssl")
|
||||
)
|
||||
if err := ssl.Struct(&sSLConfig); err != nil {
|
||||
g.Log().Fatalf(ctx, "hotgo启动失败, ssl err:", err)
|
||||
return err
|
||||
}
|
||||
if sSLConfig != nil && sSLConfig.Switch {
|
||||
s.EnableHTTPS(sSLConfig.CrtPath, sSLConfig.KeyPath)
|
||||
}
|
||||
// https
|
||||
setSSL(ctx, s)
|
||||
|
||||
// Just run the server.
|
||||
s.Run()
|
||||
@@ -104,3 +77,14 @@ var (
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
func setSSL(ctx context.Context, s *ghttp.Server) {
|
||||
config, err := service.SysConfig().GetLoadSSL(ctx)
|
||||
if err != nil {
|
||||
g.Log().Fatal(ctx, "ssl配置获取失败:err:%+v", err)
|
||||
return
|
||||
}
|
||||
if config != nil && config.Switch {
|
||||
s.EnableHTTPS(config.CrtPath, config.KeyPath)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ var (
|
||||
Brief: "消息队列",
|
||||
Description: ``,
|
||||
Func: func(ctx context.Context, parser *gcmd.Parser) (err error) {
|
||||
g.Log().Infof(ctx, "start queue consumer..")
|
||||
g.Log().Debug(ctx, "start queue consumer..")
|
||||
queues.Run(ctx)
|
||||
return
|
||||
},
|
||||
|
||||
@@ -20,7 +20,7 @@ var (
|
||||
Description: ``,
|
||||
Func: func(ctx context.Context, parser *gcmd.Parser) (err error) {
|
||||
flags := parser.GetOptAll()
|
||||
g.Log().Warningf(ctx, "flags:%+v", flags)
|
||||
g.Log().Debug(ctx, "flags:%+v", flags)
|
||||
if len(flags) == 0 {
|
||||
g.Log().Fatal(ctx, "工具参数不能为空")
|
||||
return
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
// Package consts
|
||||
// @Link https://github.com/bufanyun/hotgo
|
||||
// @Copyright Copyright (c) 2022 HotGo CLI
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
|
||||
//
|
||||
package consts
|
||||
|
||||
// 全局状态码
|
||||
const (
|
||||
CodeNil = -1 // No error code specified.
|
||||
CodeOK = 0 // It is OK.
|
||||
CodeInternalError = 50 // An error occurred internally.
|
||||
CodeValidationFailed = 51 // Data validation failed.
|
||||
CodeDbOperationError = 52 // Database operation error.
|
||||
CodeInvalidParameter = 53 // The given parameter for current operation is invalid.
|
||||
CodeMissingParameter = 54 // Parameter for current operation is missing.
|
||||
CodeInvalidOperation = 55 // The function cannot be used like this.
|
||||
CodeInvalidConfiguration = 56 // The configuration is invalid for current operation.
|
||||
CodeMissingConfiguration = 57 // The configuration is missing for current operation.
|
||||
CodeNotImplemented = 58 // The operation is not implemented yet.
|
||||
CodeNotSupported = 59 // The operation is not supported yet.
|
||||
CodeOperationFailed = 60 // I tried, but I cannot give you what you want.
|
||||
CodeNotAuthorized = 61 // Not Authorized.
|
||||
CodeSecurityReason = 62 // Security Reason.
|
||||
CodeServerBusy = 63 // Server is busy, please try again later.
|
||||
CodeUnknown = 64 // Unknown error.
|
||||
CodeNotFound = 65 // Resource does not exist.
|
||||
CodeInvalidRequest = 66 // Invalid request.
|
||||
CodeBusinessValidationFailed = 300 // Business validation failed.
|
||||
)
|
||||
@@ -6,10 +6,74 @@
|
||||
//
|
||||
package consts
|
||||
|
||||
import "github.com/gogf/gf/v2/util/gconv"
|
||||
|
||||
// 配置数据类型
|
||||
const (
|
||||
ConfigTypeString = "string"
|
||||
ConfigTypeInt = "int"
|
||||
ConfigTypeBool = "bool"
|
||||
ConfigTypeArray = "array"
|
||||
ConfigTypeDate = "date"
|
||||
ConfigTypeString = "string"
|
||||
ConfigTypeInt = "int"
|
||||
ConfigTypeInt8 = "int8"
|
||||
ConfigTypeInt16 = "int16"
|
||||
ConfigTypeInt32 = "int32"
|
||||
ConfigTypeInt64 = "int64"
|
||||
ConfigTypeUint = "uint"
|
||||
ConfigTypeUint8 = "uint8"
|
||||
ConfigTypeUint16 = "uint16"
|
||||
ConfigTypeUint32 = "uint32"
|
||||
ConfigTypeUint64 = "uint64"
|
||||
ConfigTypeFloat32 = "float32"
|
||||
ConfigTypeFloat64 = "float64"
|
||||
ConfigTypeBool = "bool"
|
||||
ConfigTypeDate = "date"
|
||||
ConfigTypeDateTime = "datetime"
|
||||
)
|
||||
|
||||
var ConfigTypes = []string{ConfigTypeString,
|
||||
ConfigTypeInt, ConfigTypeInt8, ConfigTypeInt16, ConfigTypeInt32, ConfigTypeInt64,
|
||||
ConfigTypeUint, ConfigTypeUint8, ConfigTypeUint16, ConfigTypeUint32, ConfigTypeUint64,
|
||||
ConfigTypeFloat32, ConfigTypeFloat64,
|
||||
ConfigTypeBool,
|
||||
ConfigTypeDate, ConfigTypeDateTime,
|
||||
}
|
||||
|
||||
// ConvType 类型转换
|
||||
func ConvType(val interface{}, t string) interface{} {
|
||||
switch t {
|
||||
case ConfigTypeString:
|
||||
val = gconv.String(val)
|
||||
case ConfigTypeInt:
|
||||
val = gconv.Int(val)
|
||||
case ConfigTypeInt8:
|
||||
val = gconv.Int8(val)
|
||||
case ConfigTypeInt16:
|
||||
val = gconv.Int16(val)
|
||||
case ConfigTypeInt32:
|
||||
val = gconv.Int32(val)
|
||||
case ConfigTypeInt64:
|
||||
val = gconv.Int64(val)
|
||||
case ConfigTypeUint:
|
||||
val = gconv.Uint(val)
|
||||
case ConfigTypeUint8:
|
||||
val = gconv.Uint8(val)
|
||||
case ConfigTypeUint16:
|
||||
val = gconv.Uint16(val)
|
||||
case ConfigTypeUint32:
|
||||
val = gconv.Uint32(val)
|
||||
case ConfigTypeUint64:
|
||||
val = gconv.Uint64(val)
|
||||
case ConfigTypeFloat32:
|
||||
val = gconv.Float32(val)
|
||||
case ConfigTypeFloat64:
|
||||
val = gconv.Float64(val)
|
||||
case ConfigTypeBool:
|
||||
val = gconv.Bool(val)
|
||||
case ConfigTypeDate:
|
||||
val = gconv.Time(val, "Y-m-d")
|
||||
case ConfigTypeDateTime:
|
||||
val = gconv.Time(val, "Y-m-d H:i:s")
|
||||
default:
|
||||
val = gconv.String(val)
|
||||
}
|
||||
|
||||
return val
|
||||
}
|
||||
|
||||
@@ -9,5 +9,6 @@ package consts
|
||||
// 碎片
|
||||
|
||||
const (
|
||||
DemoTips = "演示系统已隐藏"
|
||||
DemoTips = "演示系统已隐藏"
|
||||
NilJsonToString = "{}" // 空json初始化值
|
||||
)
|
||||
|
||||
74
server/internal/consts/gencodes.go
Normal file
74
server/internal/consts/gencodes.go
Normal file
@@ -0,0 +1,74 @@
|
||||
// Package consts
|
||||
// @Link https://github.com/bufanyun/hotgo
|
||||
// @Copyright Copyright (c) 2022 HotGo CLI
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
|
||||
//
|
||||
package consts
|
||||
|
||||
// 生成代码类型
|
||||
const (
|
||||
GenCodesTypeCurd = 10 // 增删改查列表
|
||||
GenCodesTypeTree = 11 // 树列表
|
||||
GenCodesTypeQueue = 20 // 队列消费者
|
||||
GenCodesTypeCron = 30 // 定时任务
|
||||
)
|
||||
|
||||
var GenCodesTypeNameMap = map[int]string{
|
||||
GenCodesTypeCurd: "增删改查列表",
|
||||
GenCodesTypeTree: "关系树列表(未实现)",
|
||||
GenCodesTypeQueue: "队列消费者(未实现)",
|
||||
GenCodesTypeCron: "定时任务(未实现)",
|
||||
}
|
||||
|
||||
// 生成代码状态
|
||||
const (
|
||||
GenCodesStatusOk = 1 // 生成成功
|
||||
GenCodesStatusWait = 2 // 未生成
|
||||
GenCodesStatusFail = 3 // 生成失败
|
||||
)
|
||||
|
||||
var GenCodesStatusNameMap = map[int]string{
|
||||
GenCodesStatusOk: "生成成功",
|
||||
GenCodesStatusWait: "未生成",
|
||||
GenCodesStatusFail: "生成失败",
|
||||
}
|
||||
|
||||
// 生成代码关联表方式
|
||||
const (
|
||||
GenCodesJoinLeft = 1 // 左关联
|
||||
GenCodesJoinRight = 2 // 右关联
|
||||
GenCodesJoinInner = 3 // 内关联
|
||||
)
|
||||
|
||||
var GenCodesJoinNameMap = map[int]string{
|
||||
GenCodesJoinLeft: "左关联",
|
||||
GenCodesJoinRight: "右关联",
|
||||
GenCodesJoinInner: "内关联",
|
||||
}
|
||||
|
||||
var GenCodesJoinLinkMap = map[int]string{
|
||||
GenCodesJoinLeft: "LeftJoin",
|
||||
GenCodesJoinRight: "RightJoin",
|
||||
GenCodesJoinInner: "InnerJoin",
|
||||
}
|
||||
|
||||
// 生成代码的生成方式
|
||||
const (
|
||||
GenCodesBuildMethCreate = 1 // 创建
|
||||
GenCodesBuildMethCover = 2 // 覆盖
|
||||
GenCodesBuildMethSkip = 3 // 跳过
|
||||
GenCodesBuildIgnore = 4 // 不生成
|
||||
)
|
||||
|
||||
var GenCodesBuildMethNameMap = map[int]string{
|
||||
GenCodesBuildMethCreate: "创建文件",
|
||||
GenCodesBuildMethCover: "强制覆盖",
|
||||
GenCodesBuildMethSkip: "已存在跳过",
|
||||
GenCodesBuildIgnore: "不生成",
|
||||
}
|
||||
|
||||
const (
|
||||
GenCodesIndexPK = "PRI" // 主键索引
|
||||
GenCodesIndexUNI = "UNI" // 唯一索引
|
||||
)
|
||||
32
server/internal/consts/role.go
Normal file
32
server/internal/consts/role.go
Normal file
@@ -0,0 +1,32 @@
|
||||
// Package consts
|
||||
// @Link https://github.com/bufanyun/hotgo
|
||||
// @Copyright Copyright (c) 2022 HotGo CLI
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
|
||||
//
|
||||
package consts
|
||||
|
||||
// 数据范围
|
||||
const (
|
||||
RoleDataAll = 1 // 全部权限
|
||||
|
||||
// 通过部门划分
|
||||
RoleDataNowDept = 2 // 当前部门
|
||||
RoleDataDeptAndSub = 3 // 当前部门及以下部门
|
||||
RoleDataDeptCustom = 4 // 自定义部门
|
||||
|
||||
// 通过上下级关系划分
|
||||
RoleDataSelf = 5 // 仅自己
|
||||
RoleDataSelfAndSub = 6 // 自己和直属下级
|
||||
RoleDataSelfAndAllSub = 7 // 自己和全部下级
|
||||
)
|
||||
|
||||
var RoleDataNameMap = map[int]string{
|
||||
RoleDataAll: "全部权限",
|
||||
RoleDataNowDept: "当前部门",
|
||||
RoleDataDeptAndSub: "当前及以下部门",
|
||||
RoleDataDeptCustom: "自定义部门",
|
||||
RoleDataSelf: "仅自己",
|
||||
RoleDataSelfAndSub: "自己和直属下级",
|
||||
RoleDataSelfAndAllSub: "自己和全部下级",
|
||||
}
|
||||
@@ -7,6 +7,7 @@
|
||||
package consts
|
||||
|
||||
const (
|
||||
UploadDriveLocal = "local" // 本地驱动
|
||||
UploadDriveOss = "oss" // 阿里云oss
|
||||
UploadDriveLocal = "local" // 本地驱动
|
||||
UploadDriveOss = "oss" // 阿里云oss
|
||||
UploadDriveUCloud = "ucloud" // ucloud对象存储
|
||||
)
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
//
|
||||
package consts
|
||||
|
||||
// VersionApp 应用版本
|
||||
// VersionApp HotGo版本
|
||||
const (
|
||||
VersionApp = "2.0.3"
|
||||
VersionApp = "2.1.0"
|
||||
)
|
||||
|
||||
@@ -81,14 +81,14 @@ func (c *cMember) Profile(ctx context.Context, req *member.ProfileReq) (*member.
|
||||
res.SysDept = sysDept
|
||||
|
||||
// 角色列表
|
||||
sysRoles, err := service.AdminRole().GetMemberList(ctx, memberInfo.Role)
|
||||
sysRoles, err := service.AdminRole().GetMemberList(ctx, memberInfo.RoleId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res.SysRoles = sysRoles
|
||||
|
||||
// 获取角色名称
|
||||
roleGroup, err := service.AdminRole().GetName(ctx, memberInfo.Role)
|
||||
roleGroup, err := service.AdminRole().GetName(ctx, memberInfo.RoleId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -174,6 +174,8 @@ func (c *cMember) Edit(ctx context.Context, req *member.EditReq) (res *member.Ed
|
||||
if err = gconv.Scan(req, &in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
in.PostIds = req.PostIds
|
||||
if err = service.AdminMember().Edit(ctx, in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -227,7 +229,7 @@ func (c *cMember) View(ctx context.Context, req *member.ViewReq) (*member.ViewRe
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res.RoleIds = []int64{memberInfo.Role}
|
||||
res.RoleIds = []int64{memberInfo.RoleId}
|
||||
res.DeptName, err = service.AdminDept().GetName(ctx, memberInfo.DeptId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -56,7 +56,7 @@ func (c *cMonitor) OnlineList(ctx context.Context, req *monitor.OnlineListReq) (
|
||||
var (
|
||||
res monitor.OnlineListRes
|
||||
clients []*monitor.OnlineModel
|
||||
i int64
|
||||
i int
|
||||
)
|
||||
|
||||
if c.wsManager.GetClientsLen() == 0 {
|
||||
@@ -86,16 +86,16 @@ func (c *cMonitor) OnlineList(ctx context.Context, req *monitor.OnlineListReq) (
|
||||
})
|
||||
}
|
||||
|
||||
res.PageCount = form.CalPageCount(int64(len(clients)), req.PerPage)
|
||||
res.PageCount = form.CalPageCount(len(clients), req.PerPage)
|
||||
res.Page = req.Page
|
||||
res.PerPage = req.PerPage
|
||||
|
||||
sort.Sort(monitor.OnlineModels(clients))
|
||||
isDemo, _ := g.Cfg().Get(ctx, "hotgo.isDemo", false)
|
||||
isDemo := g.Cfg().MustGet(ctx, "hotgo.isDemo", false)
|
||||
_, perPage, offset := form.CalPage(ctx, req.Page, req.PerPage)
|
||||
|
||||
for k, v := range clients {
|
||||
if int64(k) >= offset && i <= perPage {
|
||||
if k >= offset && i <= perPage {
|
||||
i++
|
||||
if isDemo.Bool() {
|
||||
v.Addr = consts.DemoTips
|
||||
|
||||
@@ -45,11 +45,11 @@ func (c *cRole) RoleMemberList(ctx context.Context, req *role.MemberListReq) (*r
|
||||
|
||||
// List 获取列表
|
||||
func (c *cRole) List(ctx context.Context, req *role.ListReq) (*role.ListRes, error) {
|
||||
|
||||
list, totalCount, err := service.AdminRole().List(ctx, adminin.RoleListInp{
|
||||
Page: req.Page,
|
||||
PerPage: req.PerPage,
|
||||
})
|
||||
var in adminin.RoleListInp
|
||||
if err := gconv.Scan(req, &in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
list, totalCount, err := service.AdminRole().List(ctx, in)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -57,7 +57,7 @@ func (c *cRole) List(ctx context.Context, req *role.ListReq) (*role.ListRes, err
|
||||
var res role.ListRes
|
||||
res.List = list
|
||||
res.PageCount = form.CalPageCount(totalCount, req.PerPage)
|
||||
res.PerPage = req.Page
|
||||
res.Page = req.Page
|
||||
res.PerPage = req.PerPage
|
||||
|
||||
return &res, nil
|
||||
@@ -115,3 +115,27 @@ func (c *cRole) UpdatePermissions(ctx context.Context, req *role.UpdatePermissio
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// DataScopeSelect 获取数据权限选项
|
||||
func (c *cRole) DataScopeSelect(ctx context.Context, req *role.DataScopeSelectReq) (res *role.DataScopeSelectRes, err error) {
|
||||
data := service.AdminRole().DataScopeSelect(ctx)
|
||||
res = new(role.DataScopeSelectRes)
|
||||
res.List = data
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// DataScopeEdit 获取数据权限选项
|
||||
func (c *cRole) DataScopeEdit(ctx context.Context, req *role.DataScopeEditReq) (res *role.DataScopeEditRes, err error) {
|
||||
var in adminin.DataScopeEditInp
|
||||
if err = gconv.Scan(req, &in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
in.CustomDept = req.CustomDept
|
||||
err = service.AdminRole().DataScopeEdit(ctx, &in)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
144
server/internal/controller/backend/admin/test.go
Normal file
144
server/internal/controller/backend/admin/test.go
Normal file
@@ -0,0 +1,144 @@
|
||||
// Package admin
|
||||
// @Link https://github.com/bufanyun/hotgo
|
||||
// @Copyright Copyright (c) 2022 HotGo CLI
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
|
||||
//
|
||||
package admin
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
"hotgo/api/backend/test"
|
||||
"hotgo/internal/model/input/adminin"
|
||||
"hotgo/internal/model/input/form"
|
||||
"hotgo/internal/service"
|
||||
"hotgo/utility/validate"
|
||||
)
|
||||
|
||||
var (
|
||||
Test = cTest{}
|
||||
)
|
||||
|
||||
type cTest struct{}
|
||||
|
||||
// List 查看列表
|
||||
func (c *cTest) List(ctx context.Context, req *test.ListReq) (res *test.ListRes, err error) {
|
||||
var in adminin.TestListInp
|
||||
if err = gconv.Scan(req, &in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = validate.PreFilter(ctx, &in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
list, totalCount, err := service.AdminTest().List(ctx, in)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res = new(test.ListRes)
|
||||
res.List = list
|
||||
res.PageCount = form.CalPageCount(totalCount, req.PerPage)
|
||||
res.Page = req.Page
|
||||
res.PerPage = req.PerPage
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// Export 导出列表
|
||||
func (c *cTest) Export(ctx context.Context, req *test.ExportReq) (res *test.ExportRes, err error) {
|
||||
var in adminin.TestListInp
|
||||
if err = gconv.Scan(req, &in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = service.AdminTest().Export(ctx, in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// Edit 更新
|
||||
func (c *cTest) Edit(ctx context.Context, req *test.EditReq) (res *test.EditRes, err error) {
|
||||
var in adminin.TestEditInp
|
||||
if err = gconv.Scan(req, &in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = validate.PreFilter(ctx, &in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = service.AdminTest().Edit(ctx, in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// MaxSort 最大排序
|
||||
func (c *cTest) MaxSort(ctx context.Context, req *test.MaxSortReq) (res *test.MaxSortRes, err error) {
|
||||
data, err := service.AdminTest().MaxSort(ctx, adminin.TestMaxSortInp{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res = new(test.MaxSortRes)
|
||||
res.TestMaxSortModel = data
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// View 获取指定信息
|
||||
func (c *cTest) View(ctx context.Context, req *test.ViewReq) (res *test.ViewRes, err error) {
|
||||
var in adminin.TestViewInp
|
||||
if err = gconv.Scan(req, &in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
data, err := service.AdminTest().View(ctx, in)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res = new(test.ViewRes)
|
||||
res.TestViewModel = data
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// Delete 删除
|
||||
func (c *cTest) Delete(ctx context.Context, req *test.DeleteReq) (res *test.DeleteRes, err error) {
|
||||
var in adminin.TestDeleteInp
|
||||
if err = gconv.Scan(req, &in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = service.AdminTest().Delete(ctx, in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// Status 更新状态
|
||||
func (c *cTest) Status(ctx context.Context, req *test.StatusReq) (res *test.StatusRes, err error) {
|
||||
var in adminin.TestStatusInp
|
||||
if err = gconv.Scan(req, &in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = service.AdminTest().Status(ctx, in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// Switch 更新开关状态
|
||||
func (c *cTest) Switch(ctx context.Context, req *test.SwitchReq) (res *test.SwitchRes, err error) {
|
||||
var in adminin.TestSwitchInp
|
||||
if err = gconv.Scan(req, &in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = service.AdminTest().Switch(ctx, in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
@@ -33,16 +33,31 @@ func (c *cSite) Ping(ctx context.Context, req *common.SitePingReq) (res *common.
|
||||
|
||||
// Config 获取配置
|
||||
func (c *cSite) Config(ctx context.Context, req *common.SiteConfigReq) (res *common.SiteConfigRes, err error) {
|
||||
|
||||
wsAddr, _ := g.Cfg().Get(ctx, "hotgo.wsAddr", "ws://127.0.0.1:8000/ws")
|
||||
g.Log().Warningf(ctx, "wsAddr:%+v", wsAddr.String())
|
||||
res = &common.SiteConfigRes{
|
||||
Version: consts.VersionApp,
|
||||
WsAddr: wsAddr.String(),
|
||||
WsAddr: c.getWsAddr(ctx),
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (c *cSite) getWsAddr(ctx context.Context) string {
|
||||
ws := g.Cfg().MustGet(ctx, "hotgo.wsAddr", "ws://127.0.0.1:8000/socket")
|
||||
return ws.String()
|
||||
|
||||
//// nginx负载均衡部署
|
||||
//// 如果是IP访问,则认为是调试模式,走配置中的ws地址,否则走实际请求中的域名+协议
|
||||
//if !validate.IsDNSName(ghttp.RequestFromCtx(ctx).Host) {
|
||||
// ws := g.Cfg().MustGet(ctx, "hotgo.wsAddr", "ws://127.0.0.1:8000/socket")
|
||||
// return ws.String()
|
||||
//}
|
||||
//
|
||||
//if !validate.IsHTTPS(ctx) {
|
||||
// return fmt.Sprintf("ws://%s/socket", url.GetDomain(ctx))
|
||||
//}
|
||||
//
|
||||
//return fmt.Sprintf("wss://%s/socket", url.GetDomain(ctx))
|
||||
}
|
||||
|
||||
// Captcha 登录验证码
|
||||
func (c *cSite) Captcha(ctx context.Context, req *common.LoginCaptchaReq) (res *common.LoginCaptchaRes, err error) {
|
||||
|
||||
|
||||
@@ -34,3 +34,20 @@ func (c *cUpload) UploadImage(ctx context.Context, req *common.UploadImageReq) (
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// UploadFile 上传附件
|
||||
func (c *cUpload) UploadFile(ctx context.Context, req *common.UploadFileReq) (res common.UploadFileRes, err error) {
|
||||
r := g.RequestFromCtx(ctx)
|
||||
file := r.GetUploadFile("file")
|
||||
if file == nil {
|
||||
err = gerror.New("没有找到上传的文件")
|
||||
return
|
||||
}
|
||||
|
||||
res, err = service.CommonUpload().UploadFile(ctx, file)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -10,6 +10,8 @@ import (
|
||||
"context"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
"hotgo/api/backend/config"
|
||||
"hotgo/internal/consts"
|
||||
"hotgo/internal/model/input/form"
|
||||
"hotgo/internal/model/input/sysin"
|
||||
"hotgo/internal/service"
|
||||
)
|
||||
@@ -55,3 +57,15 @@ func (c *cConfig) UpdateConfig(ctx context.Context, req *config.UpdateReq) (*con
|
||||
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
// TypeSelect 数据类型选项
|
||||
func (c *cConfig) TypeSelect(ctx context.Context, req *config.TypeSelectReq) (res config.TypeSelectRes, err error) {
|
||||
for _, v := range consts.ConfigTypes {
|
||||
res = append(res, form.Select{
|
||||
Value: v,
|
||||
Name: v,
|
||||
Label: v,
|
||||
})
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
169
server/internal/controller/backend/sys/curd_demo.go
Normal file
169
server/internal/controller/backend/sys/curd_demo.go
Normal file
@@ -0,0 +1,169 @@
|
||||
// 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
|
||||
// @AutoGenerate Version 2.1.0
|
||||
// @AutoGenerate Date 2023-01-18 15:19:42
|
||||
//
|
||||
package sys
|
||||
|
||||
import (
|
||||
"context"
|
||||
"hotgo/api/backend/curddemo"
|
||||
"hotgo/internal/model/input/form"
|
||||
"hotgo/internal/model/input/sysin"
|
||||
"hotgo/internal/service"
|
||||
"hotgo/utility/validate"
|
||||
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
)
|
||||
|
||||
var (
|
||||
CurdDemo = cCurdDemo{}
|
||||
)
|
||||
|
||||
type cCurdDemo struct{}
|
||||
|
||||
// List 查看生成演示列表
|
||||
func (c *cCurdDemo) List(ctx context.Context, req *curddemo.ListReq) (res *curddemo.ListRes, err error) {
|
||||
var in sysin.CurdDemoListInp
|
||||
if err = gconv.Scan(req, &in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = validate.PreFilter(ctx, &in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
list, totalCount, err := service.SysCurdDemo().List(ctx, in)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res = new(curddemo.ListRes)
|
||||
res.List = list
|
||||
res.PageCount = form.CalPageCount(totalCount, req.PerPage)
|
||||
res.Page = req.Page
|
||||
res.PerPage = req.PerPage
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// Export 导出生成演示列表
|
||||
func (c *cCurdDemo) Export(ctx context.Context, req *curddemo.ExportReq) (res *curddemo.ExportRes, err error) {
|
||||
var in sysin.CurdDemoListInp
|
||||
if err = gconv.Scan(req, &in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = validate.PreFilter(ctx, &in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = service.SysCurdDemo().Export(ctx, in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// Edit 更新生成演示
|
||||
func (c *cCurdDemo) Edit(ctx context.Context, req *curddemo.EditReq) (res *curddemo.EditRes, err error) {
|
||||
var in sysin.CurdDemoEditInp
|
||||
if err = gconv.Scan(req, &in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = validate.PreFilter(ctx, &in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = service.SysCurdDemo().Edit(ctx, in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// MaxSort 获取生成演示最大排序
|
||||
func (c *cCurdDemo) MaxSort(ctx context.Context, req *curddemo.MaxSortReq) (res *curddemo.MaxSortRes, err error) {
|
||||
data, err := service.SysCurdDemo().MaxSort(ctx, sysin.CurdDemoMaxSortInp{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res = new(curddemo.MaxSortRes)
|
||||
res.CurdDemoMaxSortModel = data
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// View 获取指定生成演示信息
|
||||
func (c *cCurdDemo) View(ctx context.Context, req *curddemo.ViewReq) (res *curddemo.ViewRes, err error) {
|
||||
var in sysin.CurdDemoViewInp
|
||||
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.SysCurdDemo().View(ctx, in)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res = new(curddemo.ViewRes)
|
||||
res.CurdDemoViewModel = data
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// Delete 删除生成演示
|
||||
func (c *cCurdDemo) Delete(ctx context.Context, req *curddemo.DeleteReq) (res *curddemo.DeleteRes, err error) {
|
||||
var in sysin.CurdDemoDeleteInp
|
||||
if err = gconv.Scan(req, &in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = validate.PreFilter(ctx, &in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = service.SysCurdDemo().Delete(ctx, in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// Status 更新生成演示状态
|
||||
func (c *cCurdDemo) Status(ctx context.Context, req *curddemo.StatusReq) (res *curddemo.StatusRes, err error) {
|
||||
var in sysin.CurdDemoStatusInp
|
||||
if err = gconv.Scan(req, &in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = validate.PreFilter(ctx, &in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = service.SysCurdDemo().Status(ctx, in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// Switch 更新生成演示开关状态
|
||||
func (c *cCurdDemo) Switch(ctx context.Context, req *curddemo.SwitchReq) (res *curddemo.SwitchRes, err error) {
|
||||
var in sysin.CurdDemoSwitchInp
|
||||
if err = gconv.Scan(req, &in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = validate.PreFilter(ctx, &in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = service.SysCurdDemo().Switch(ctx, in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
@@ -49,7 +49,6 @@ func (c *cDictData) Edit(ctx context.Context, req *dict.DataEditReq) (res *dict.
|
||||
|
||||
// List 查看列表
|
||||
func (c *cDictData) List(ctx context.Context, req *dict.DataListReq) (*dict.DataListRes, error) {
|
||||
|
||||
var (
|
||||
in sysin.DictDataListInp
|
||||
res dict.DataListRes
|
||||
@@ -71,3 +70,37 @@ func (c *cDictData) List(ctx context.Context, req *dict.DataListReq) (*dict.Data
|
||||
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
// Select 指定选项
|
||||
func (c *cDictData) Select(ctx context.Context, req *dict.DataSelectReq) (*dict.DataSelectRes, error) {
|
||||
var (
|
||||
in sysin.DataSelectInp
|
||||
res dict.DataSelectRes
|
||||
)
|
||||
|
||||
if err := gconv.Scan(req, &in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
list, err := service.SysDictData().Select(ctx, in)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res = dict.DataSelectRes(list)
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
// Selects 多个选项
|
||||
func (c *cDictData) Selects(ctx context.Context, req *dict.DataSelectsReq) (*dict.DataSelectsRes, error) {
|
||||
res := make(dict.DataSelectsRes)
|
||||
for _, v := range req.Types {
|
||||
option, err := service.SysDictData().Select(ctx, sysin.DataSelectInp{Type: v})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res[v] = option
|
||||
}
|
||||
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
208
server/internal/controller/backend/sys/gen_codes.go
Normal file
208
server/internal/controller/backend/sys/gen_codes.go
Normal file
@@ -0,0 +1,208 @@
|
||||
// Package sys
|
||||
// @Link https://github.com/bufanyun/hotgo
|
||||
// @Copyright Copyright (c) 2022 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/api/backend/gencodes"
|
||||
"hotgo/internal/model/input/form"
|
||||
"hotgo/internal/model/input/sysin"
|
||||
"hotgo/internal/service"
|
||||
)
|
||||
|
||||
var (
|
||||
GenCodes = cGenCodes{}
|
||||
)
|
||||
|
||||
type cGenCodes struct{}
|
||||
|
||||
// Delete 删除
|
||||
func (c *cGenCodes) Delete(ctx context.Context, req *gencodes.DeleteReq) (res *gencodes.DeleteRes, err error) {
|
||||
var in sysin.GenCodesDeleteInp
|
||||
if err = gconv.Scan(req, &in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = service.SysGenCodes().Delete(ctx, in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// Edit 更新
|
||||
func (c *cGenCodes) Edit(ctx context.Context, req *gencodes.EditReq) (res *gencodes.EditRes, err error) {
|
||||
|
||||
var in sysin.GenCodesEditInp
|
||||
if err = gconv.Scan(req, &in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
data, err := service.SysGenCodes().Edit(ctx, in)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res = new(gencodes.EditRes)
|
||||
res.GenCodesEditModel = data
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// MaxSort 最大排序
|
||||
func (c *cGenCodes) MaxSort(ctx context.Context, req *gencodes.MaxSortReq) (*gencodes.MaxSortRes, error) {
|
||||
|
||||
data, err := service.SysGenCodes().MaxSort(ctx, sysin.GenCodesMaxSortInp{Id: req.Id})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var res gencodes.MaxSortRes
|
||||
res.Sort = data.Sort
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
// View 获取指定信息
|
||||
func (c *cGenCodes) View(ctx context.Context, req *gencodes.ViewReq) (*gencodes.ViewRes, error) {
|
||||
|
||||
data, err := service.SysGenCodes().View(ctx, sysin.GenCodesViewInp{Id: req.Id})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var res gencodes.ViewRes
|
||||
res.GenCodesViewModel = data
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
// List 查看列表
|
||||
func (c *cGenCodes) List(ctx context.Context, req *gencodes.ListReq) (*gencodes.ListRes, error) {
|
||||
|
||||
var (
|
||||
in sysin.GenCodesListInp
|
||||
res gencodes.ListRes
|
||||
)
|
||||
|
||||
if err := gconv.Scan(req, &in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
list, totalCount, err := service.SysGenCodes().List(ctx, in)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res.List = list
|
||||
res.PageCount = form.CalPageCount(totalCount, req.PerPage)
|
||||
res.Page = req.Page
|
||||
res.PerPage = req.PerPage
|
||||
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
// Status 更新部门状态
|
||||
func (c *cGenCodes) Status(ctx context.Context, req *gencodes.StatusReq) (res *gencodes.StatusRes, err error) {
|
||||
|
||||
var in sysin.GenCodesStatusInp
|
||||
if err = gconv.Scan(req, &in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = service.SysGenCodes().Status(ctx, in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// Selects 获取指定信息
|
||||
func (c *cGenCodes) Selects(ctx context.Context, req *gencodes.SelectsReq) (*gencodes.SelectsRes, error) {
|
||||
data, err := service.SysGenCodes().Selects(ctx, sysin.GenCodesSelectsInp{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var res gencodes.SelectsRes
|
||||
res.GenCodesSelectsModel = data
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
// TableSelect 数据库表选项
|
||||
func (c *cGenCodes) TableSelect(ctx context.Context, req *gencodes.TableSelectReq) (*gencodes.TableSelectRes, error) {
|
||||
data, err := service.SysGenCodes().TableSelect(ctx, sysin.GenCodesTableSelectInp{Name: req.Name})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var res gencodes.TableSelectRes
|
||||
res = data
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
// ColumnSelect 表字段选项
|
||||
func (c *cGenCodes) ColumnSelect(ctx context.Context, req *gencodes.ColumnSelectReq) (*gencodes.ColumnSelectRes, error) {
|
||||
data, err := service.SysGenCodes().ColumnSelect(ctx, sysin.GenCodesColumnSelectInp{Name: req.Name, Table: req.Table})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var res gencodes.ColumnSelectRes
|
||||
res = data
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
// ColumnList 表字段列表
|
||||
func (c *cGenCodes) ColumnList(ctx context.Context, req *gencodes.ColumnListReq) (*gencodes.ColumnListRes, error) {
|
||||
var (
|
||||
in sysin.GenCodesColumnListInp
|
||||
err error
|
||||
)
|
||||
if err = gconv.Scan(req, &in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
data, err := service.SysGenCodes().ColumnList(ctx, in)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var res gencodes.ColumnListRes
|
||||
res = data
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
// Preview 生成预览
|
||||
func (c *cGenCodes) Preview(ctx context.Context, req *gencodes.PreviewReq) (*gencodes.PreviewRes, error) {
|
||||
var (
|
||||
in sysin.GenCodesPreviewInp
|
||||
err error
|
||||
)
|
||||
if err = gconv.Scan(req, &in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
data, err := service.SysGenCodes().Preview(ctx, in)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res := new(gencodes.PreviewRes)
|
||||
res.GenCodesPreviewModel = data
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// Build 生成预览
|
||||
func (c *cGenCodes) Build(ctx context.Context, req *gencodes.BuildReq) (*gencodes.BuildRes, error) {
|
||||
var (
|
||||
in sysin.GenCodesBuildInp
|
||||
err error
|
||||
)
|
||||
if err = gconv.Scan(req, &in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = service.SysGenCodes().Build(ctx, in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
@@ -24,6 +24,7 @@ func (a *cSite) Index(ctx context.Context, req *base.SiteIndexReq) (res *base.Si
|
||||
service.View().Render(ctx, model.View{Data: g.Map{
|
||||
"name": "HotGo",
|
||||
"version": consts.VersionApp,
|
||||
"debug": g.Cfg().MustGet(ctx, "hotgo.debug", true),
|
||||
}})
|
||||
return
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ func (c *cMonitor) RunInfo(client *websocket.Client, req *websocket.WRequest) {
|
||||
"goSize": file.DirSize(pwd),
|
||||
}
|
||||
|
||||
isDemo, _ := g.Cfg().Get(client.Context(), "hotgo.isDemo", false)
|
||||
isDemo := g.Cfg().MustGet(client.Context(), "hotgo.isDemo", false)
|
||||
if isDemo.Bool() {
|
||||
data["rootPath"] = consts.DemoTips
|
||||
data["pwd"] = consts.DemoTips
|
||||
|
||||
@@ -130,7 +130,7 @@ func StartALL(sysCron []*entity.SysCron) error {
|
||||
}
|
||||
}
|
||||
|
||||
g.Log().Info(ct, "定时任务启动完毕...")
|
||||
g.Log().Debug(ct, "load scheduled task complete..")
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -29,15 +29,9 @@ var (
|
||||
}
|
||||
)
|
||||
|
||||
// UpdatePostIds
|
||||
// @Description:
|
||||
// @receiver dao
|
||||
// @param ctx
|
||||
// @param memberId
|
||||
// @param postIds
|
||||
// @return err
|
||||
//
|
||||
// UpdatePostIds 更新管理员岗位
|
||||
func (dao *adminMemberPostDao) UpdatePostIds(ctx context.Context, memberId int64, postIds []int64) (err error) {
|
||||
g.DumpWithType(postIds)
|
||||
_, err = dao.Ctx(ctx).
|
||||
Where("member_id", memberId).
|
||||
Delete()
|
||||
@@ -61,16 +55,8 @@ func (dao *adminMemberPostDao) UpdatePostIds(ctx context.Context, memberId int64
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetMemberByIds 获取指定会员的岗位ids
|
||||
// @Description:
|
||||
// @receiver dao
|
||||
// @param ctx
|
||||
// @param memberId
|
||||
// @return postIds
|
||||
// @return err
|
||||
//
|
||||
// GetMemberByIds 获取指定关联员的岗位ids
|
||||
func (dao *adminMemberPostDao) GetMemberByIds(ctx context.Context, memberId int64) (postIds []int64, err error) {
|
||||
|
||||
var list []*entity.AdminMemberPost
|
||||
err = dao.Ctx(ctx).
|
||||
Fields("post_id").
|
||||
@@ -85,6 +71,5 @@ func (dao *adminMemberPostDao) GetMemberByIds(ctx context.Context, memberId int6
|
||||
postIds = append(postIds, list[i].PostId)
|
||||
}
|
||||
|
||||
g.Log().Print(ctx, "post_ids:", postIds)
|
||||
return postIds, nil
|
||||
}
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
// =================================================================================
|
||||
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
|
||||
// =================================================================================
|
||||
|
||||
package dao
|
||||
|
||||
import (
|
||||
"hotgo/internal/dao/internal"
|
||||
)
|
||||
|
||||
// internalAdminRoleDeptDao is internal type for wrapping internal DAO implements.
|
||||
type internalAdminRoleDeptDao = *internal.AdminRoleDeptDao
|
||||
|
||||
// adminRoleDeptDao is the data access object for table hg_admin_role_dept.
|
||||
// You can define custom methods on it to extend its functionality as you wish.
|
||||
type adminRoleDeptDao struct {
|
||||
internalAdminRoleDeptDao
|
||||
}
|
||||
|
||||
var (
|
||||
// AdminRoleDept is globally common accessible object for table hg_admin_role_dept operations.
|
||||
AdminRoleDept = adminRoleDeptDao{
|
||||
internal.NewAdminRoleDeptDao(),
|
||||
}
|
||||
)
|
||||
|
||||
// Fill with you ideas below.
|
||||
27
server/internal/dao/demo.go
Normal file
27
server/internal/dao/demo.go
Normal file
@@ -0,0 +1,27 @@
|
||||
// =================================================================================
|
||||
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
|
||||
// =================================================================================
|
||||
|
||||
package dao
|
||||
|
||||
import (
|
||||
"hotgo/internal/dao/internal"
|
||||
)
|
||||
|
||||
// internalDemoDao is internal type for wrapping internal DAO implements.
|
||||
type internalDemoDao = *internal.DemoDao
|
||||
|
||||
// demoDao is the data access object for table hg_demo.
|
||||
// You can define custom methods on it to extend its functionality as you wish.
|
||||
type demoDao struct {
|
||||
internalDemoDao
|
||||
}
|
||||
|
||||
var (
|
||||
// Demo is globally public accessible object for table hg_demo operations.
|
||||
Demo = demoDao{
|
||||
internal.NewDemoDao(),
|
||||
}
|
||||
)
|
||||
|
||||
// Fill with you ideas below.
|
||||
@@ -20,8 +20,8 @@ type AdminDeptDao struct {
|
||||
|
||||
// AdminDeptColumns defines and stores column names for table hg_admin_dept.
|
||||
type AdminDeptColumns struct {
|
||||
Id string // 部门id
|
||||
Pid string // 父部门id
|
||||
Id string // 部门ID
|
||||
Pid string // 父部门ID
|
||||
Name string // 部门名称
|
||||
Code string // 部门编码
|
||||
Type string // 部门类型
|
||||
@@ -34,7 +34,7 @@ type AdminDeptColumns struct {
|
||||
UpdatedAt string // 更新时间
|
||||
}
|
||||
|
||||
// adminDeptColumns holds the columns for table hg_admin_dept.
|
||||
// adminDeptColumns holds the columns for table hg_admin_dept.
|
||||
var adminDeptColumns = AdminDeptColumns{
|
||||
Id: "id",
|
||||
Pid: "pid",
|
||||
@@ -90,6 +90,6 @@ func (dao *AdminDeptDao) Ctx(ctx context.Context) *gdb.Model {
|
||||
//
|
||||
// Note that, you should not Commit or Rollback the transaction in function f
|
||||
// as it is automatically handled by this function.
|
||||
func (dao *AdminDeptDao) Transaction(ctx context.Context, f func(ctx context.Context, tx *gdb.TX) error) (err error) {
|
||||
func (dao *AdminDeptDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
|
||||
return dao.Ctx(ctx).Transaction(ctx, f)
|
||||
}
|
||||
|
||||
@@ -20,64 +20,64 @@ type AdminMemberDao struct {
|
||||
|
||||
// AdminMemberColumns defines and stores column names for table hg_admin_member.
|
||||
type AdminMemberColumns struct {
|
||||
Id string //
|
||||
Id string // 管理员ID
|
||||
DeptId string // 部门ID
|
||||
RoleId string // 角色ID
|
||||
RealName string // 真实姓名
|
||||
Username string // 帐号
|
||||
PasswordHash string // 密码
|
||||
Salt string // 密码盐
|
||||
AuthKey string // 授权令牌
|
||||
PasswordResetToken string // 密码重置令牌
|
||||
Type string // 1:普通管理员;10超级管理员
|
||||
Realname string // 真实姓名
|
||||
Avatar string // 头像
|
||||
Sex string // 性别[1:男;2:女;3:未知]
|
||||
Sex string // 性别
|
||||
Qq string // qq
|
||||
Email string // 邮箱
|
||||
Birthday string // 生日
|
||||
ProvinceId string // 省
|
||||
CityId string // 城市
|
||||
AreaId string // 地区
|
||||
Address string // 默认地址
|
||||
Mobile string // 手机号码
|
||||
HomePhone string // 家庭号码
|
||||
DingtalkRobotToken string // 钉钉机器人token
|
||||
Birthday string // 生日
|
||||
ProvinceId string // 省编码
|
||||
CityId string // 城市编码
|
||||
CountyId string // 区域编码
|
||||
Address string // 联系地址
|
||||
VisitCount string // 访问次数
|
||||
LastTime string // 最后一次登录时间
|
||||
LastIp string // 最后一次登录ip
|
||||
Role string // 权限
|
||||
Pid string // 上级管理员ID
|
||||
Level string // 关系树等级
|
||||
Tree string // 关系树
|
||||
Remark string // 备注
|
||||
Status string // 状态
|
||||
CreatedAt string // 创建时间
|
||||
UpdatedAt string // 修改时间
|
||||
}
|
||||
|
||||
// adminMemberColumns holds the columns for table hg_admin_member.
|
||||
// adminMemberColumns holds the columns for table hg_admin_member.
|
||||
var adminMemberColumns = AdminMemberColumns{
|
||||
Id: "id",
|
||||
DeptId: "dept_id",
|
||||
RoleId: "role_id",
|
||||
RealName: "real_name",
|
||||
Username: "username",
|
||||
PasswordHash: "password_hash",
|
||||
Salt: "salt",
|
||||
AuthKey: "auth_key",
|
||||
PasswordResetToken: "password_reset_token",
|
||||
Type: "type",
|
||||
Realname: "realname",
|
||||
Avatar: "avatar",
|
||||
Sex: "sex",
|
||||
Qq: "qq",
|
||||
Email: "email",
|
||||
Mobile: "mobile",
|
||||
Birthday: "birthday",
|
||||
ProvinceId: "province_id",
|
||||
CityId: "city_id",
|
||||
AreaId: "area_id",
|
||||
CountyId: "county_id",
|
||||
Address: "address",
|
||||
Mobile: "mobile",
|
||||
HomePhone: "home_phone",
|
||||
DingtalkRobotToken: "dingtalk_robot_token",
|
||||
VisitCount: "visit_count",
|
||||
LastTime: "last_time",
|
||||
LastIp: "last_ip",
|
||||
Role: "role",
|
||||
Pid: "pid",
|
||||
Level: "level",
|
||||
Tree: "tree",
|
||||
Remark: "remark",
|
||||
Status: "status",
|
||||
CreatedAt: "created_at",
|
||||
@@ -124,6 +124,6 @@ func (dao *AdminMemberDao) Ctx(ctx context.Context) *gdb.Model {
|
||||
//
|
||||
// Note that, you should not Commit or Rollback the transaction in function f
|
||||
// as it is automatically handled by this function.
|
||||
func (dao *AdminMemberDao) Transaction(ctx context.Context, f func(ctx context.Context, tx *gdb.TX) error) (err error) {
|
||||
func (dao *AdminMemberDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
|
||||
return dao.Ctx(ctx).Transaction(ctx, f)
|
||||
}
|
||||
|
||||
@@ -20,11 +20,11 @@ type AdminMemberPostDao struct {
|
||||
|
||||
// AdminMemberPostColumns defines and stores column names for table hg_admin_member_post.
|
||||
type AdminMemberPostColumns struct {
|
||||
MemberId string // 用户ID
|
||||
MemberId string // 管理员ID
|
||||
PostId string // 岗位ID
|
||||
}
|
||||
|
||||
// adminMemberPostColumns holds the columns for table hg_admin_member_post.
|
||||
// adminMemberPostColumns holds the columns for table hg_admin_member_post.
|
||||
var adminMemberPostColumns = AdminMemberPostColumns{
|
||||
MemberId: "member_id",
|
||||
PostId: "post_id",
|
||||
@@ -70,6 +70,6 @@ func (dao *AdminMemberPostDao) Ctx(ctx context.Context) *gdb.Model {
|
||||
//
|
||||
// Note that, you should not Commit or Rollback the transaction in function f
|
||||
// as it is automatically handled by this function.
|
||||
func (dao *AdminMemberPostDao) Transaction(ctx context.Context, f func(ctx context.Context, tx *gdb.TX) error) (err error) {
|
||||
func (dao *AdminMemberPostDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
|
||||
return dao.Ctx(ctx).Transaction(ctx, f)
|
||||
}
|
||||
|
||||
@@ -20,11 +20,11 @@ type AdminMemberRoleDao struct {
|
||||
|
||||
// AdminMemberRoleColumns defines and stores column names for table hg_admin_member_role.
|
||||
type AdminMemberRoleColumns struct {
|
||||
MemberId string // 用户ID
|
||||
MemberId string // 管理员ID
|
||||
RoleId string // 角色ID
|
||||
}
|
||||
|
||||
// adminMemberRoleColumns holds the columns for table hg_admin_member_role.
|
||||
// adminMemberRoleColumns holds the columns for table hg_admin_member_role.
|
||||
var adminMemberRoleColumns = AdminMemberRoleColumns{
|
||||
MemberId: "member_id",
|
||||
RoleId: "role_id",
|
||||
@@ -70,6 +70,6 @@ func (dao *AdminMemberRoleDao) Ctx(ctx context.Context) *gdb.Model {
|
||||
//
|
||||
// Note that, you should not Commit or Rollback the transaction in function f
|
||||
// as it is automatically handled by this function.
|
||||
func (dao *AdminMemberRoleDao) Transaction(ctx context.Context, f func(ctx context.Context, tx *gdb.TX) error) (err error) {
|
||||
func (dao *AdminMemberRoleDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
|
||||
return dao.Ctx(ctx).Transaction(ctx, f)
|
||||
}
|
||||
|
||||
@@ -39,8 +39,8 @@ type AdminMenuColumns struct {
|
||||
KeepAlive string // 缓存该路由
|
||||
Hidden string // 是否隐藏
|
||||
Affix string // 是否固定
|
||||
Level string // 级别
|
||||
Tree string // 树
|
||||
Level string // 关系树等级
|
||||
Tree string // 关系树
|
||||
Sort string // 排序
|
||||
Remark string // 备注
|
||||
Status string // 菜单状态
|
||||
@@ -48,7 +48,7 @@ type AdminMenuColumns struct {
|
||||
UpdatedAt string // 更新时间
|
||||
}
|
||||
|
||||
// adminMenuColumns holds the columns for table hg_admin_menu.
|
||||
// adminMenuColumns holds the columns for table hg_admin_menu.
|
||||
var adminMenuColumns = AdminMenuColumns{
|
||||
Id: "id",
|
||||
Pid: "pid",
|
||||
@@ -118,6 +118,6 @@ func (dao *AdminMenuDao) Ctx(ctx context.Context) *gdb.Model {
|
||||
//
|
||||
// Note that, you should not Commit or Rollback the transaction in function f
|
||||
// as it is automatically handled by this function.
|
||||
func (dao *AdminMenuDao) Transaction(ctx context.Context, f func(ctx context.Context, tx *gdb.TX) error) (err error) {
|
||||
func (dao *AdminMenuDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
|
||||
return dao.Ctx(ctx).Transaction(ctx, f)
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ type AdminNoticeDao struct {
|
||||
type AdminNoticeColumns struct {
|
||||
Id string // 公告ID
|
||||
Title string // 公告标题
|
||||
Type string // 公告类型(1通知 2公告)
|
||||
Type string // 公告类型
|
||||
Content string // 公告内容
|
||||
Receiver string // 接收者
|
||||
Reader string // 已读人
|
||||
@@ -33,7 +33,7 @@ type AdminNoticeColumns struct {
|
||||
UpdatedAt string // 更新时间
|
||||
}
|
||||
|
||||
// adminNoticeColumns holds the columns for table hg_admin_notice.
|
||||
// adminNoticeColumns holds the columns for table hg_admin_notice.
|
||||
var adminNoticeColumns = AdminNoticeColumns{
|
||||
Id: "id",
|
||||
Title: "title",
|
||||
@@ -88,6 +88,6 @@ func (dao *AdminNoticeDao) Ctx(ctx context.Context) *gdb.Model {
|
||||
//
|
||||
// Note that, you should not Commit or Rollback the transaction in function f
|
||||
// as it is automatically handled by this function.
|
||||
func (dao *AdminNoticeDao) Transaction(ctx context.Context, f func(ctx context.Context, tx *gdb.TX) error) (err error) {
|
||||
func (dao *AdminNoticeDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
|
||||
return dao.Ctx(ctx).Transaction(ctx, f)
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ type AdminPostColumns struct {
|
||||
UpdatedAt string // 更新时间
|
||||
}
|
||||
|
||||
// adminPostColumns holds the columns for table hg_admin_post.
|
||||
// adminPostColumns holds the columns for table hg_admin_post.
|
||||
var adminPostColumns = AdminPostColumns{
|
||||
Id: "id",
|
||||
Code: "code",
|
||||
@@ -82,6 +82,6 @@ func (dao *AdminPostDao) Ctx(ctx context.Context) *gdb.Model {
|
||||
//
|
||||
// Note that, you should not Commit or Rollback the transaction in function f
|
||||
// as it is automatically handled by this function.
|
||||
func (dao *AdminPostDao) Transaction(ctx context.Context, f func(ctx context.Context, tx *gdb.TX) error) (err error) {
|
||||
func (dao *AdminPostDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
|
||||
return dao.Ctx(ctx).Transaction(ctx, f)
|
||||
}
|
||||
|
||||
@@ -20,32 +20,36 @@ type AdminRoleDao struct {
|
||||
|
||||
// AdminRoleColumns defines and stores column names for table hg_admin_role.
|
||||
type AdminRoleColumns struct {
|
||||
Id string // 角色ID
|
||||
Name string // 角色名称
|
||||
Key string // 角色权限字符串
|
||||
DataScope string // 数据范围(1:全部数据权限 2:自定数据权限 3:本部门数据权限 4:本部门及以下数据权限)
|
||||
MenuCheckStrictly string // 菜单树选择项是否关联显示
|
||||
DeptCheckStrictly string // 部门树选择项是否关联显示
|
||||
Remark string // 备注
|
||||
Sort string // 排序
|
||||
Status string // 角色状态
|
||||
CreatedAt string // 创建时间
|
||||
UpdatedAt string // 更新时间
|
||||
Id string // 角色ID
|
||||
Name string // 角色名称
|
||||
Key string // 角色权限字符串
|
||||
DataScope string // 数据范围
|
||||
CustomDept string // 自定义部门权限
|
||||
Pid string // 上级角色ID
|
||||
Level string // 关系树等级
|
||||
Tree string // 关系树
|
||||
Remark string // 备注
|
||||
Sort string // 排序
|
||||
Status string // 角色状态
|
||||
CreatedAt string // 创建时间
|
||||
UpdatedAt string // 更新时间
|
||||
}
|
||||
|
||||
// adminRoleColumns holds the columns for table hg_admin_role.
|
||||
// adminRoleColumns holds the columns for table hg_admin_role.
|
||||
var adminRoleColumns = AdminRoleColumns{
|
||||
Id: "id",
|
||||
Name: "name",
|
||||
Key: "key",
|
||||
DataScope: "data_scope",
|
||||
MenuCheckStrictly: "menu_check_strictly",
|
||||
DeptCheckStrictly: "dept_check_strictly",
|
||||
Remark: "remark",
|
||||
Sort: "sort",
|
||||
Status: "status",
|
||||
CreatedAt: "created_at",
|
||||
UpdatedAt: "updated_at",
|
||||
Id: "id",
|
||||
Name: "name",
|
||||
Key: "key",
|
||||
DataScope: "data_scope",
|
||||
CustomDept: "custom_dept",
|
||||
Pid: "pid",
|
||||
Level: "level",
|
||||
Tree: "tree",
|
||||
Remark: "remark",
|
||||
Sort: "sort",
|
||||
Status: "status",
|
||||
CreatedAt: "created_at",
|
||||
UpdatedAt: "updated_at",
|
||||
}
|
||||
|
||||
// NewAdminRoleDao creates and returns a new DAO object for table data access.
|
||||
@@ -88,6 +92,6 @@ func (dao *AdminRoleDao) Ctx(ctx context.Context) *gdb.Model {
|
||||
//
|
||||
// Note that, you should not Commit or Rollback the transaction in function f
|
||||
// as it is automatically handled by this function.
|
||||
func (dao *AdminRoleDao) Transaction(ctx context.Context, f func(ctx context.Context, tx *gdb.TX) error) (err error) {
|
||||
func (dao *AdminRoleDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
|
||||
return dao.Ctx(ctx).Transaction(ctx, f)
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ type AdminRoleCasbinColumns struct {
|
||||
V5 string //
|
||||
}
|
||||
|
||||
// adminRoleCasbinColumns holds the columns for table hg_admin_role_casbin.
|
||||
// adminRoleCasbinColumns holds the columns for table hg_admin_role_casbin.
|
||||
var adminRoleCasbinColumns = AdminRoleCasbinColumns{
|
||||
Id: "id",
|
||||
PType: "p_type",
|
||||
@@ -82,6 +82,6 @@ func (dao *AdminRoleCasbinDao) Ctx(ctx context.Context) *gdb.Model {
|
||||
//
|
||||
// Note that, you should not Commit or Rollback the transaction in function f
|
||||
// as it is automatically handled by this function.
|
||||
func (dao *AdminRoleCasbinDao) Transaction(ctx context.Context, f func(ctx context.Context, tx *gdb.TX) error) (err error) {
|
||||
func (dao *AdminRoleCasbinDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
|
||||
return dao.Ctx(ctx).Transaction(ctx, f)
|
||||
}
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
// ==========================================================================
|
||||
// Code generated by GoFrame CLI tool. DO NOT EDIT.
|
||||
// ==========================================================================
|
||||
|
||||
package internal
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/gogf/gf/v2/database/gdb"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
)
|
||||
|
||||
// AdminRoleDeptDao is the data access object for table hg_admin_role_dept.
|
||||
type AdminRoleDeptDao struct {
|
||||
table string // table is the underlying table name of the DAO.
|
||||
group string // group is the database configuration group name of current DAO.
|
||||
columns AdminRoleDeptColumns // columns contains all the column names of Table for convenient usage.
|
||||
}
|
||||
|
||||
// AdminRoleDeptColumns defines and stores column names for table hg_admin_role_dept.
|
||||
type AdminRoleDeptColumns struct {
|
||||
RoleId string // 角色ID
|
||||
DeptId string // 部门ID
|
||||
}
|
||||
|
||||
// adminRoleDeptColumns holds the columns for table hg_admin_role_dept.
|
||||
var adminRoleDeptColumns = AdminRoleDeptColumns{
|
||||
RoleId: "role_id",
|
||||
DeptId: "dept_id",
|
||||
}
|
||||
|
||||
// NewAdminRoleDeptDao creates and returns a new DAO object for table data access.
|
||||
func NewAdminRoleDeptDao() *AdminRoleDeptDao {
|
||||
return &AdminRoleDeptDao{
|
||||
group: "default",
|
||||
table: "hg_admin_role_dept",
|
||||
columns: adminRoleDeptColumns,
|
||||
}
|
||||
}
|
||||
|
||||
// DB retrieves and returns the underlying raw database management object of current DAO.
|
||||
func (dao *AdminRoleDeptDao) DB() gdb.DB {
|
||||
return g.DB(dao.group)
|
||||
}
|
||||
|
||||
// Table returns the table name of current dao.
|
||||
func (dao *AdminRoleDeptDao) Table() string {
|
||||
return dao.table
|
||||
}
|
||||
|
||||
// Columns returns all column names of current dao.
|
||||
func (dao *AdminRoleDeptDao) Columns() AdminRoleDeptColumns {
|
||||
return dao.columns
|
||||
}
|
||||
|
||||
// Group returns the configuration group name of database of current dao.
|
||||
func (dao *AdminRoleDeptDao) Group() string {
|
||||
return dao.group
|
||||
}
|
||||
|
||||
// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation.
|
||||
func (dao *AdminRoleDeptDao) Ctx(ctx context.Context) *gdb.Model {
|
||||
return dao.DB().Model(dao.table).Safe().Ctx(ctx)
|
||||
}
|
||||
|
||||
// Transaction wraps the transaction logic using function f.
|
||||
// It rollbacks the transaction and returns the error from function f if it returns non-nil error.
|
||||
// It commits the transaction and returns nil if function f returns nil.
|
||||
//
|
||||
// Note that, you should not Commit or Rollback the transaction in function f
|
||||
// as it is automatically handled by this function.
|
||||
func (dao *AdminRoleDeptDao) Transaction(ctx context.Context, f func(ctx context.Context, tx *gdb.TX) error) (err error) {
|
||||
return dao.Ctx(ctx).Transaction(ctx, f)
|
||||
}
|
||||
@@ -24,7 +24,7 @@ type AdminRoleMenuColumns struct {
|
||||
MenuId string // 菜单ID
|
||||
}
|
||||
|
||||
// adminRoleMenuColumns holds the columns for table hg_admin_role_menu.
|
||||
// adminRoleMenuColumns holds the columns for table hg_admin_role_menu.
|
||||
var adminRoleMenuColumns = AdminRoleMenuColumns{
|
||||
RoleId: "role_id",
|
||||
MenuId: "menu_id",
|
||||
@@ -70,6 +70,6 @@ func (dao *AdminRoleMenuDao) Ctx(ctx context.Context) *gdb.Model {
|
||||
//
|
||||
// Note that, you should not Commit or Rollback the transaction in function f
|
||||
// as it is automatically handled by this function.
|
||||
func (dao *AdminRoleMenuDao) Transaction(ctx context.Context, f func(ctx context.Context, tx *gdb.TX) error) (err error) {
|
||||
func (dao *AdminRoleMenuDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
|
||||
return dao.Ctx(ctx).Transaction(ctx, f)
|
||||
}
|
||||
|
||||
143
server/internal/dao/internal/demo.go
Normal file
143
server/internal/dao/internal/demo.go
Normal file
@@ -0,0 +1,143 @@
|
||||
// ==========================================================================
|
||||
// Code generated by GoFrame CLI tool. DO NOT EDIT.
|
||||
// ==========================================================================
|
||||
|
||||
package internal
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/gogf/gf/v2/database/gdb"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
)
|
||||
|
||||
// DemoDao is the data access object for table hg_demo.
|
||||
type DemoDao struct {
|
||||
table string // table is the underlying table name of the DAO.
|
||||
group string // group is the database configuration group name of current DAO.
|
||||
columns DemoColumns // columns contains all the column names of Table for convenient usage.
|
||||
}
|
||||
|
||||
// DemoColumns defines and stores column names for table hg_demo.
|
||||
type DemoColumns struct {
|
||||
Id string // ID
|
||||
CategoryId string // 分类ID
|
||||
Flag string // 标签
|
||||
Title string // 标题
|
||||
Description string // 描述
|
||||
Content string // 内容
|
||||
Image string // 单图
|
||||
Images string // 多图
|
||||
Attachfile string // 附件
|
||||
Attachfiles string // 多附件
|
||||
Map string // 动态键值对
|
||||
Star string // 推荐星
|
||||
Price string // 价格
|
||||
Views string // 浏览次数
|
||||
ActivityAt string // 活动时间
|
||||
StartAt string // 开启时间
|
||||
EndAt string // 结束时间
|
||||
Switch string // 开关
|
||||
Sort string // 排序
|
||||
Avatar string // 头像
|
||||
Sex string // 性别
|
||||
Qq string // qq
|
||||
Email string // 邮箱
|
||||
Mobile string // 手机号码
|
||||
Hobby string // 爱好
|
||||
Channel string // 渠道
|
||||
Pid string // 上级ID
|
||||
Level string // 树等级
|
||||
Tree string // 关系树
|
||||
Remark string // 备注
|
||||
Status string // 状态
|
||||
CreatedBy string // 创建者
|
||||
UpdatedBy string // 更新者
|
||||
CreatedAt string // 创建时间
|
||||
UpdatedAt string // 修改时间
|
||||
DeletedAt string // 删除时间
|
||||
}
|
||||
|
||||
// demoColumns holds the columns for table hg_demo.
|
||||
var demoColumns = DemoColumns{
|
||||
Id: "id",
|
||||
CategoryId: "category_id",
|
||||
Flag: "flag",
|
||||
Title: "title",
|
||||
Description: "description",
|
||||
Content: "content",
|
||||
Image: "image",
|
||||
Images: "images",
|
||||
Attachfile: "attachfile",
|
||||
Attachfiles: "attachfiles",
|
||||
Map: "map",
|
||||
Star: "star",
|
||||
Price: "price",
|
||||
Views: "views",
|
||||
ActivityAt: "activity_at",
|
||||
StartAt: "start_at",
|
||||
EndAt: "end_at",
|
||||
Switch: "switch",
|
||||
Sort: "sort",
|
||||
Avatar: "avatar",
|
||||
Sex: "sex",
|
||||
Qq: "qq",
|
||||
Email: "email",
|
||||
Mobile: "mobile",
|
||||
Hobby: "hobby",
|
||||
Channel: "channel",
|
||||
Pid: "pid",
|
||||
Level: "level",
|
||||
Tree: "tree",
|
||||
Remark: "remark",
|
||||
Status: "status",
|
||||
CreatedBy: "created_by",
|
||||
UpdatedBy: "updated_by",
|
||||
CreatedAt: "created_at",
|
||||
UpdatedAt: "updated_at",
|
||||
DeletedAt: "deleted_at",
|
||||
}
|
||||
|
||||
// NewDemoDao creates and returns a new DAO object for table data access.
|
||||
func NewDemoDao() *DemoDao {
|
||||
return &DemoDao{
|
||||
group: "default",
|
||||
table: "hg_demo",
|
||||
columns: demoColumns,
|
||||
}
|
||||
}
|
||||
|
||||
// DB retrieves and returns the underlying raw database management object of current DAO.
|
||||
func (dao *DemoDao) DB() gdb.DB {
|
||||
return g.DB(dao.group)
|
||||
}
|
||||
|
||||
// Table returns the table name of current dao.
|
||||
func (dao *DemoDao) Table() string {
|
||||
return dao.table
|
||||
}
|
||||
|
||||
// Columns returns all column names of current dao.
|
||||
func (dao *DemoDao) Columns() DemoColumns {
|
||||
return dao.columns
|
||||
}
|
||||
|
||||
// Group returns the configuration group name of database of current dao.
|
||||
func (dao *DemoDao) Group() string {
|
||||
return dao.group
|
||||
}
|
||||
|
||||
// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation.
|
||||
func (dao *DemoDao) Ctx(ctx context.Context) *gdb.Model {
|
||||
return dao.DB().Model(dao.table).Safe().Ctx(ctx)
|
||||
}
|
||||
|
||||
// Transaction wraps the transaction logic using function f.
|
||||
// It rollbacks the transaction and returns the error from function f if it returns non-nil error.
|
||||
// It commits the transaction and returns nil if function f returns nil.
|
||||
//
|
||||
// Note that, you should not Commit or Rollback the transaction in function f
|
||||
// as it is automatically handled by this function.
|
||||
func (dao *DemoDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
|
||||
return dao.Ctx(ctx).Transaction(ctx, f)
|
||||
}
|
||||
@@ -20,18 +20,18 @@ type SysAttachmentDao struct {
|
||||
|
||||
// SysAttachmentColumns defines and stores column names for table hg_sys_attachment.
|
||||
type SysAttachmentColumns struct {
|
||||
Id string //
|
||||
Id string // 文件ID
|
||||
AppId string // 应用ID
|
||||
MemberId string // 用户
|
||||
CateId string // 分类
|
||||
Drive string // 驱动
|
||||
MemberId string // 管理员ID
|
||||
CateId string // 上传分类
|
||||
Drive string // 上传驱动
|
||||
Name string // 文件原始名
|
||||
Kind string // 上传类型
|
||||
MetaType string // 类别
|
||||
MetaType string // 文件类型
|
||||
NaiveType string // NaiveUI类型
|
||||
Path string // 本地路径
|
||||
FileUrl string // url
|
||||
Size string // 长度
|
||||
Size string // 文件大小
|
||||
Ext string // 扩展名
|
||||
Md5 string // md5校验码
|
||||
Status string // 状态
|
||||
@@ -39,7 +39,7 @@ type SysAttachmentColumns struct {
|
||||
UpdatedAt string // 修改时间
|
||||
}
|
||||
|
||||
// sysAttachmentColumns holds the columns for table hg_sys_attachment.
|
||||
// sysAttachmentColumns holds the columns for table hg_sys_attachment.
|
||||
var sysAttachmentColumns = SysAttachmentColumns{
|
||||
Id: "id",
|
||||
AppId: "app_id",
|
||||
@@ -100,6 +100,6 @@ func (dao *SysAttachmentDao) Ctx(ctx context.Context) *gdb.Model {
|
||||
//
|
||||
// Note that, you should not Commit or Rollback the transaction in function f
|
||||
// as it is automatically handled by this function.
|
||||
func (dao *SysAttachmentDao) Transaction(ctx context.Context, f func(ctx context.Context, tx *gdb.TX) error) (err error) {
|
||||
func (dao *SysAttachmentDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
|
||||
return dao.Ctx(ctx).Transaction(ctx, f)
|
||||
}
|
||||
|
||||
@@ -20,15 +20,15 @@ type SysBlacklistDao struct {
|
||||
|
||||
// SysBlacklistColumns defines and stores column names for table hg_sys_blacklist.
|
||||
type SysBlacklistColumns struct {
|
||||
Id string // 主键
|
||||
Ip string // ip地址
|
||||
Id string // 黑名单ID
|
||||
Ip string // IP地址
|
||||
Remark string // 备注
|
||||
Status string // 状态
|
||||
CreatedAt string // 创建时间
|
||||
UpdatedAt string // 更新时间
|
||||
}
|
||||
|
||||
// sysBlacklistColumns holds the columns for table hg_sys_blacklist.
|
||||
// sysBlacklistColumns holds the columns for table hg_sys_blacklist.
|
||||
var sysBlacklistColumns = SysBlacklistColumns{
|
||||
Id: "id",
|
||||
Ip: "ip",
|
||||
@@ -78,6 +78,6 @@ func (dao *SysBlacklistDao) Ctx(ctx context.Context) *gdb.Model {
|
||||
//
|
||||
// Note that, you should not Commit or Rollback the transaction in function f
|
||||
// as it is automatically handled by this function.
|
||||
func (dao *SysBlacklistDao) Transaction(ctx context.Context, f func(ctx context.Context, tx *gdb.TX) error) (err error) {
|
||||
func (dao *SysBlacklistDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
|
||||
return dao.Ctx(ctx).Transaction(ctx, f)
|
||||
}
|
||||
|
||||
@@ -21,21 +21,21 @@ type SysConfigDao struct {
|
||||
// SysConfigColumns defines and stores column names for table hg_sys_config.
|
||||
type SysConfigColumns struct {
|
||||
Id string // 配置ID
|
||||
Group string // 分组
|
||||
Group string // 配置分组
|
||||
Name string // 参数名称
|
||||
Type string // 类型:string,text,int,bool,array,datetime,date,file
|
||||
Type string // 键值类型:string,int,uint,bool,datetime,date
|
||||
Key string // 参数键名
|
||||
Value string // 参数键值
|
||||
DefaultValue string // 默认值
|
||||
Sort string // 排序
|
||||
Tip string // 变量描述
|
||||
IsDefault string // 是否默认
|
||||
IsDefault string // 是否为系统默认
|
||||
Status string // 状态
|
||||
CreatedAt string // 创建时间
|
||||
UpdatedAt string // 更新时间
|
||||
}
|
||||
|
||||
// sysConfigColumns holds the columns for table hg_sys_config.
|
||||
// sysConfigColumns holds the columns for table hg_sys_config.
|
||||
var sysConfigColumns = SysConfigColumns{
|
||||
Id: "id",
|
||||
Group: "group",
|
||||
@@ -92,6 +92,6 @@ func (dao *SysConfigDao) Ctx(ctx context.Context) *gdb.Model {
|
||||
//
|
||||
// Note that, you should not Commit or Rollback the transaction in function f
|
||||
// as it is automatically handled by this function.
|
||||
func (dao *SysConfigDao) Transaction(ctx context.Context, f func(ctx context.Context, tx *gdb.TX) error) (err error) {
|
||||
func (dao *SysConfigDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
|
||||
return dao.Ctx(ctx).Transaction(ctx, f)
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ type SysCronDao struct {
|
||||
|
||||
// SysCronColumns defines and stores column names for table hg_sys_cron.
|
||||
type SysCronColumns struct {
|
||||
Id string // 主键
|
||||
Id string // 任务ID
|
||||
GroupId string // 分组ID
|
||||
Name string // 任务名称
|
||||
Params string // 函数参数
|
||||
@@ -29,12 +29,12 @@ type SysCronColumns struct {
|
||||
Count string // 执行次数
|
||||
Sort string // 排序
|
||||
Remark string // 备注
|
||||
Status string // 状态
|
||||
Status string // 任务状态
|
||||
CreatedAt string // 创建时间
|
||||
UpdatedAt string // 更新时间
|
||||
}
|
||||
|
||||
// sysCronColumns holds the columns for table hg_sys_cron.
|
||||
// sysCronColumns holds the columns for table hg_sys_cron.
|
||||
var sysCronColumns = SysCronColumns{
|
||||
Id: "id",
|
||||
GroupId: "group_id",
|
||||
@@ -90,6 +90,6 @@ func (dao *SysCronDao) Ctx(ctx context.Context) *gdb.Model {
|
||||
//
|
||||
// Note that, you should not Commit or Rollback the transaction in function f
|
||||
// as it is automatically handled by this function.
|
||||
func (dao *SysCronDao) Transaction(ctx context.Context, f func(ctx context.Context, tx *gdb.TX) error) (err error) {
|
||||
func (dao *SysCronDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
|
||||
return dao.Ctx(ctx).Transaction(ctx, f)
|
||||
}
|
||||
|
||||
@@ -20,18 +20,18 @@ type SysCronGroupDao struct {
|
||||
|
||||
// SysCronGroupColumns defines and stores column names for table hg_sys_cron_group.
|
||||
type SysCronGroupColumns struct {
|
||||
Id string // 主键
|
||||
Pid string // 父类ID
|
||||
Id string // 任务分组ID
|
||||
Pid string // 父类任务分组ID
|
||||
Name string // 分组名称
|
||||
IsDefault string // 是否默认
|
||||
Sort string // 排序
|
||||
Remark string // 备注
|
||||
Status string // 状态
|
||||
Status string // 分组状态
|
||||
CreatedAt string // 创建时间
|
||||
UpdatedAt string // 更新时间
|
||||
}
|
||||
|
||||
// sysCronGroupColumns holds the columns for table hg_sys_cron_group.
|
||||
// sysCronGroupColumns holds the columns for table hg_sys_cron_group.
|
||||
var sysCronGroupColumns = SysCronGroupColumns{
|
||||
Id: "id",
|
||||
Pid: "pid",
|
||||
@@ -84,6 +84,6 @@ func (dao *SysCronGroupDao) Ctx(ctx context.Context) *gdb.Model {
|
||||
//
|
||||
// Note that, you should not Commit or Rollback the transaction in function f
|
||||
// as it is automatically handled by this function.
|
||||
func (dao *SysCronGroupDao) Transaction(ctx context.Context, f func(ctx context.Context, tx *gdb.TX) error) (err error) {
|
||||
func (dao *SysCronGroupDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
|
||||
return dao.Ctx(ctx).Transaction(ctx, f)
|
||||
}
|
||||
|
||||
@@ -20,12 +20,13 @@ type SysDictDataDao struct {
|
||||
|
||||
// SysDictDataColumns defines and stores column names for table hg_sys_dict_data.
|
||||
type SysDictDataColumns struct {
|
||||
Id string // 字典编码
|
||||
Id string // 字典数据ID
|
||||
Label string // 字典标签
|
||||
Value string // 字典键值
|
||||
ValueType string // 键值数据类型:string,int,uint,bool,datetime,date
|
||||
Type string // 字典类型
|
||||
ListClass string // 表格回显样式
|
||||
IsDefault string // 是否默认
|
||||
IsDefault string // 是否为系统默认
|
||||
Sort string // 字典排序
|
||||
Remark string // 备注
|
||||
Status string // 状态
|
||||
@@ -33,11 +34,12 @@ type SysDictDataColumns struct {
|
||||
UpdatedAt string // 更新时间
|
||||
}
|
||||
|
||||
// sysDictDataColumns holds the columns for table hg_sys_dict_data.
|
||||
// sysDictDataColumns holds the columns for table hg_sys_dict_data.
|
||||
var sysDictDataColumns = SysDictDataColumns{
|
||||
Id: "id",
|
||||
Label: "label",
|
||||
Value: "value",
|
||||
ValueType: "value_type",
|
||||
Type: "type",
|
||||
ListClass: "list_class",
|
||||
IsDefault: "is_default",
|
||||
@@ -88,6 +90,6 @@ func (dao *SysDictDataDao) Ctx(ctx context.Context) *gdb.Model {
|
||||
//
|
||||
// Note that, you should not Commit or Rollback the transaction in function f
|
||||
// as it is automatically handled by this function.
|
||||
func (dao *SysDictDataDao) Transaction(ctx context.Context, f func(ctx context.Context, tx *gdb.TX) error) (err error) {
|
||||
func (dao *SysDictDataDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
|
||||
return dao.Ctx(ctx).Transaction(ctx, f)
|
||||
}
|
||||
|
||||
@@ -20,18 +20,18 @@ type SysDictTypeDao struct {
|
||||
|
||||
// SysDictTypeColumns defines and stores column names for table hg_sys_dict_type.
|
||||
type SysDictTypeColumns struct {
|
||||
Id string // 字典主键
|
||||
Pid string // 父类ID
|
||||
Name string // 字典名称
|
||||
Id string // 字典类型ID
|
||||
Pid string // 父类字典类型ID
|
||||
Name string // 字典类型名称
|
||||
Type string // 字典类型
|
||||
Sort string // 排序
|
||||
Remark string // 备注
|
||||
Status string // 状态
|
||||
Status string // 字典类型状态
|
||||
CreatedAt string // 创建时间
|
||||
UpdatedAt string // 更新时间
|
||||
}
|
||||
|
||||
// sysDictTypeColumns holds the columns for table hg_sys_dict_type.
|
||||
// sysDictTypeColumns holds the columns for table hg_sys_dict_type.
|
||||
var sysDictTypeColumns = SysDictTypeColumns{
|
||||
Id: "id",
|
||||
Pid: "pid",
|
||||
@@ -84,6 +84,6 @@ func (dao *SysDictTypeDao) Ctx(ctx context.Context) *gdb.Model {
|
||||
//
|
||||
// Note that, you should not Commit or Rollback the transaction in function f
|
||||
// as it is automatically handled by this function.
|
||||
func (dao *SysDictTypeDao) Transaction(ctx context.Context, f func(ctx context.Context, tx *gdb.TX) error) (err error) {
|
||||
func (dao *SysDictTypeDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
|
||||
return dao.Ctx(ctx).Transaction(ctx, f)
|
||||
}
|
||||
|
||||
95
server/internal/dao/internal/sys_gen_codes.go
Normal file
95
server/internal/dao/internal/sys_gen_codes.go
Normal file
@@ -0,0 +1,95 @@
|
||||
// ==========================================================================
|
||||
// Code generated by GoFrame CLI tool. DO NOT EDIT.
|
||||
// ==========================================================================
|
||||
|
||||
package internal
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/gogf/gf/v2/database/gdb"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
)
|
||||
|
||||
// SysGenCodesDao is the data access object for table hg_sys_gen_codes.
|
||||
type SysGenCodesDao struct {
|
||||
table string // table is the underlying table name of the DAO.
|
||||
group string // group is the database configuration group name of current DAO.
|
||||
columns SysGenCodesColumns // columns contains all the column names of Table for convenient usage.
|
||||
}
|
||||
|
||||
// SysGenCodesColumns defines and stores column names for table hg_sys_gen_codes.
|
||||
type SysGenCodesColumns struct {
|
||||
Id string // 生成ID
|
||||
GenType string // 生成类型
|
||||
VarName string // 实体命名
|
||||
Options string // 配置选项
|
||||
DbName string // 数据库名称
|
||||
TableName string // 主表名称
|
||||
TableComment string // 主表注释
|
||||
DaoName string // 主表dao模型
|
||||
MasterColumns string // 主表字段
|
||||
Status string // 生成状态
|
||||
CreatedAt string // 创建时间
|
||||
UpdatedAt string // 更新时间
|
||||
}
|
||||
|
||||
// sysGenCodesColumns holds the columns for table hg_sys_gen_codes.
|
||||
var sysGenCodesColumns = SysGenCodesColumns{
|
||||
Id: "id",
|
||||
GenType: "gen_type",
|
||||
VarName: "var_name",
|
||||
Options: "options",
|
||||
DbName: "db_name",
|
||||
TableName: "table_name",
|
||||
TableComment: "table_comment",
|
||||
DaoName: "dao_name",
|
||||
MasterColumns: "master_columns",
|
||||
Status: "status",
|
||||
CreatedAt: "created_at",
|
||||
UpdatedAt: "updated_at",
|
||||
}
|
||||
|
||||
// NewSysGenCodesDao creates and returns a new DAO object for table data access.
|
||||
func NewSysGenCodesDao() *SysGenCodesDao {
|
||||
return &SysGenCodesDao{
|
||||
group: "default",
|
||||
table: "hg_sys_gen_codes",
|
||||
columns: sysGenCodesColumns,
|
||||
}
|
||||
}
|
||||
|
||||
// DB retrieves and returns the underlying raw database management object of current DAO.
|
||||
func (dao *SysGenCodesDao) DB() gdb.DB {
|
||||
return g.DB(dao.group)
|
||||
}
|
||||
|
||||
// Table returns the table name of current dao.
|
||||
func (dao *SysGenCodesDao) Table() string {
|
||||
return dao.table
|
||||
}
|
||||
|
||||
// Columns returns all column names of current dao.
|
||||
func (dao *SysGenCodesDao) Columns() SysGenCodesColumns {
|
||||
return dao.columns
|
||||
}
|
||||
|
||||
// Group returns the configuration group name of database of current dao.
|
||||
func (dao *SysGenCodesDao) Group() string {
|
||||
return dao.group
|
||||
}
|
||||
|
||||
// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation.
|
||||
func (dao *SysGenCodesDao) Ctx(ctx context.Context) *gdb.Model {
|
||||
return dao.DB().Model(dao.table).Safe().Ctx(ctx)
|
||||
}
|
||||
|
||||
// Transaction wraps the transaction logic using function f.
|
||||
// It rollbacks the transaction and returns the error from function f if it returns non-nil error.
|
||||
// It commits the transaction and returns nil if function f returns nil.
|
||||
//
|
||||
// Note that, you should not Commit or Rollback the transaction in function f
|
||||
// as it is automatically handled by this function.
|
||||
func (dao *SysGenCodesDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
|
||||
return dao.Ctx(ctx).Transaction(ctx, f)
|
||||
}
|
||||
101
server/internal/dao/internal/sys_gen_curd_demo.go
Normal file
101
server/internal/dao/internal/sys_gen_curd_demo.go
Normal file
@@ -0,0 +1,101 @@
|
||||
// ==========================================================================
|
||||
// Code generated by GoFrame CLI tool. DO NOT EDIT.
|
||||
// ==========================================================================
|
||||
|
||||
package internal
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/gogf/gf/v2/database/gdb"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
)
|
||||
|
||||
// SysGenCurdDemoDao is the data access object for table hg_sys_gen_curd_demo.
|
||||
type SysGenCurdDemoDao struct {
|
||||
table string // table is the underlying table name of the DAO.
|
||||
group string // group is the database configuration group name of current DAO.
|
||||
columns SysGenCurdDemoColumns // columns contains all the column names of Table for convenient usage.
|
||||
}
|
||||
|
||||
// SysGenCurdDemoColumns defines and stores column names for table hg_sys_gen_curd_demo.
|
||||
type SysGenCurdDemoColumns struct {
|
||||
Id string // ID
|
||||
CategoryId string // 分类ID
|
||||
Title string // 标题
|
||||
Description string // 描述
|
||||
Content string // 内容
|
||||
Image string // 单图
|
||||
Attachfile string // 附件
|
||||
Switch string // 显示开关
|
||||
Sort string // 排序
|
||||
Status string // 状态
|
||||
CreatedBy string // 创建者
|
||||
UpdatedBy string // 更新者
|
||||
CreatedAt string // 创建时间
|
||||
UpdatedAt string // 修改时间
|
||||
DeletedAt string // 删除时间
|
||||
}
|
||||
|
||||
// sysGenCurdDemoColumns holds the columns for table hg_sys_gen_curd_demo.
|
||||
var sysGenCurdDemoColumns = SysGenCurdDemoColumns{
|
||||
Id: "id",
|
||||
CategoryId: "category_id",
|
||||
Title: "title",
|
||||
Description: "description",
|
||||
Content: "content",
|
||||
Image: "image",
|
||||
Attachfile: "attachfile",
|
||||
Switch: "switch",
|
||||
Sort: "sort",
|
||||
Status: "status",
|
||||
CreatedBy: "created_by",
|
||||
UpdatedBy: "updated_by",
|
||||
CreatedAt: "created_at",
|
||||
UpdatedAt: "updated_at",
|
||||
DeletedAt: "deleted_at",
|
||||
}
|
||||
|
||||
// NewSysGenCurdDemoDao creates and returns a new DAO object for table data access.
|
||||
func NewSysGenCurdDemoDao() *SysGenCurdDemoDao {
|
||||
return &SysGenCurdDemoDao{
|
||||
group: "default",
|
||||
table: "hg_sys_gen_curd_demo",
|
||||
columns: sysGenCurdDemoColumns,
|
||||
}
|
||||
}
|
||||
|
||||
// DB retrieves and returns the underlying raw database management object of current DAO.
|
||||
func (dao *SysGenCurdDemoDao) DB() gdb.DB {
|
||||
return g.DB(dao.group)
|
||||
}
|
||||
|
||||
// Table returns the table name of current dao.
|
||||
func (dao *SysGenCurdDemoDao) Table() string {
|
||||
return dao.table
|
||||
}
|
||||
|
||||
// Columns returns all column names of current dao.
|
||||
func (dao *SysGenCurdDemoDao) Columns() SysGenCurdDemoColumns {
|
||||
return dao.columns
|
||||
}
|
||||
|
||||
// Group returns the configuration group name of database of current dao.
|
||||
func (dao *SysGenCurdDemoDao) Group() string {
|
||||
return dao.group
|
||||
}
|
||||
|
||||
// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation.
|
||||
func (dao *SysGenCurdDemoDao) Ctx(ctx context.Context) *gdb.Model {
|
||||
return dao.DB().Model(dao.table).Safe().Ctx(ctx)
|
||||
}
|
||||
|
||||
// Transaction wraps the transaction logic using function f.
|
||||
// It rollbacks the transaction and returns the error from function f if it returns non-nil error.
|
||||
// It commits the transaction and returns nil if function f returns nil.
|
||||
//
|
||||
// Note that, you should not Commit or Rollback the transaction in function f
|
||||
// as it is automatically handled by this function.
|
||||
func (dao *SysGenCurdDemoDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
|
||||
return dao.Ctx(ctx).Transaction(ctx, f)
|
||||
}
|
||||
@@ -20,23 +20,23 @@ type SysLogDao struct {
|
||||
|
||||
// SysLogColumns defines and stores column names for table hg_sys_log.
|
||||
type SysLogColumns struct {
|
||||
Id string //
|
||||
AppId string // 应用id
|
||||
MerchantId string // 商户id
|
||||
MemberId string // 用户id
|
||||
Id string // 日志ID
|
||||
AppId string // 应用ID
|
||||
MerchantId string // 商户ID
|
||||
MemberId string // 用户ID
|
||||
Method string // 提交类型
|
||||
Module string // 模块
|
||||
Module string // 访问模块
|
||||
Url string // 提交url
|
||||
GetData string // get数据
|
||||
PostData string // post数据
|
||||
HeaderData string // header数据
|
||||
Ip string // ip地址
|
||||
Ip string // IP地址
|
||||
ProvinceId string // 省编码
|
||||
CityId string // 市编码
|
||||
ErrorCode string // 报错code
|
||||
ErrorMsg string // 报错信息
|
||||
ErrorData string // 报错日志
|
||||
ReqId string // 对外id
|
||||
ReqId string // 对外ID
|
||||
Timestamp string // 响应时间
|
||||
UserAgent string // UA信息
|
||||
TakeUpTime string // 请求耗时
|
||||
@@ -45,7 +45,7 @@ type SysLogColumns struct {
|
||||
UpdatedAt string // 修改时间
|
||||
}
|
||||
|
||||
// sysLogColumns holds the columns for table hg_sys_log.
|
||||
// sysLogColumns holds the columns for table hg_sys_log.
|
||||
var sysLogColumns = SysLogColumns{
|
||||
Id: "id",
|
||||
AppId: "app_id",
|
||||
@@ -112,6 +112,6 @@ func (dao *SysLogDao) Ctx(ctx context.Context) *gdb.Model {
|
||||
//
|
||||
// Note that, you should not Commit or Rollback the transaction in function f
|
||||
// as it is automatically handled by this function.
|
||||
func (dao *SysLogDao) Transaction(ctx context.Context, f func(ctx context.Context, tx *gdb.TX) error) (err error) {
|
||||
func (dao *SysLogDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
|
||||
return dao.Ctx(ctx).Transaction(ctx, f)
|
||||
}
|
||||
|
||||
@@ -20,34 +20,34 @@ type SysProvincesDao struct {
|
||||
|
||||
// SysProvincesColumns defines and stores column names for table hg_sys_provinces.
|
||||
type SysProvincesColumns struct {
|
||||
Id string // ID
|
||||
Title string // 栏目名
|
||||
Pid string // 父栏目
|
||||
Id string // 省市区ID
|
||||
Title string // 栏目名称
|
||||
ShortTitle string // 缩写
|
||||
Areacode string // 区域编码
|
||||
Zipcode string // 邮政编码
|
||||
Pinyin string // 拼音
|
||||
Lng string // 经度
|
||||
Lat string // 纬度
|
||||
Level string // 级别
|
||||
Tree string //
|
||||
Pid string // 父栏目
|
||||
Level string // 关系树等级
|
||||
Tree string // 关系
|
||||
Sort string // 排序
|
||||
Status string // 状态
|
||||
CreatedAt string // 创建时间
|
||||
UpdatedAt string // 更新时间
|
||||
}
|
||||
|
||||
// sysProvincesColumns holds the columns for table hg_sys_provinces.
|
||||
// sysProvincesColumns holds the columns for table hg_sys_provinces.
|
||||
var sysProvincesColumns = SysProvincesColumns{
|
||||
Id: "id",
|
||||
Title: "title",
|
||||
Pid: "pid",
|
||||
ShortTitle: "short_title",
|
||||
Areacode: "areacode",
|
||||
Zipcode: "zipcode",
|
||||
Pinyin: "pinyin",
|
||||
Lng: "lng",
|
||||
Lat: "lat",
|
||||
Pid: "pid",
|
||||
Level: "level",
|
||||
Tree: "tree",
|
||||
Sort: "sort",
|
||||
@@ -96,6 +96,6 @@ func (dao *SysProvincesDao) Ctx(ctx context.Context) *gdb.Model {
|
||||
//
|
||||
// Note that, you should not Commit or Rollback the transaction in function f
|
||||
// as it is automatically handled by this function.
|
||||
func (dao *SysProvincesDao) Transaction(ctx context.Context, f func(ctx context.Context, tx *gdb.TX) error) (err error) {
|
||||
func (dao *SysProvincesDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
|
||||
return dao.Ctx(ctx).Transaction(ctx, f)
|
||||
}
|
||||
|
||||
143
server/internal/dao/internal/test.go
Normal file
143
server/internal/dao/internal/test.go
Normal file
@@ -0,0 +1,143 @@
|
||||
// ==========================================================================
|
||||
// Code generated by GoFrame CLI tool. DO NOT EDIT.
|
||||
// ==========================================================================
|
||||
|
||||
package internal
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/gogf/gf/v2/database/gdb"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
)
|
||||
|
||||
// TestDao is the data access object for table hg_test.
|
||||
type TestDao struct {
|
||||
table string // table is the underlying table name of the DAO.
|
||||
group string // group is the database configuration group name of current DAO.
|
||||
columns TestColumns // columns contains all the column names of Table for convenient usage.
|
||||
}
|
||||
|
||||
// TestColumns defines and stores column names for table hg_test.
|
||||
type TestColumns struct {
|
||||
Id string // ID
|
||||
CategoryId string // 分类ID
|
||||
Flag string // 标签
|
||||
Title string // 标题
|
||||
Description string // 描述
|
||||
Content string // 内容
|
||||
Image string // 单图
|
||||
Images string // 多图
|
||||
Attachfile string // 附件
|
||||
Attachfiles string // 多附件
|
||||
Map string // 动态键值对
|
||||
Star string // 推荐星
|
||||
Price string // 价格
|
||||
Views string // 浏览次数
|
||||
ActivityAt string // 活动时间
|
||||
StartAt string // 开启时间
|
||||
EndAt string // 结束时间
|
||||
Switch string // 开关
|
||||
Sort string // 排序
|
||||
Avatar string // 头像
|
||||
Sex string // 性别
|
||||
Qq string // qq
|
||||
Email string // 邮箱
|
||||
Mobile string // 手机号码
|
||||
Hobby string // 爱好
|
||||
Channel string // 渠道
|
||||
Pid string // 上级ID
|
||||
Level string // 树等级
|
||||
Tree string // 关系树
|
||||
Remark string // 备注
|
||||
Status string // 状态
|
||||
CreatedBy string // 创建者
|
||||
UpdatedBy string // 更新者
|
||||
CreatedAt string // 创建时间
|
||||
UpdatedAt string // 修改时间
|
||||
DeletedAt string // 删除时间
|
||||
}
|
||||
|
||||
// testColumns holds the columns for table hg_test.
|
||||
var testColumns = TestColumns{
|
||||
Id: "id",
|
||||
CategoryId: "category_id",
|
||||
Flag: "flag",
|
||||
Title: "title",
|
||||
Description: "description",
|
||||
Content: "content",
|
||||
Image: "image",
|
||||
Images: "images",
|
||||
Attachfile: "attachfile",
|
||||
Attachfiles: "attachfiles",
|
||||
Map: "map",
|
||||
Star: "star",
|
||||
Price: "price",
|
||||
Views: "views",
|
||||
ActivityAt: "activity_at",
|
||||
StartAt: "start_at",
|
||||
EndAt: "end_at",
|
||||
Switch: "switch",
|
||||
Sort: "sort",
|
||||
Avatar: "avatar",
|
||||
Sex: "sex",
|
||||
Qq: "qq",
|
||||
Email: "email",
|
||||
Mobile: "mobile",
|
||||
Hobby: "hobby",
|
||||
Channel: "channel",
|
||||
Pid: "pid",
|
||||
Level: "level",
|
||||
Tree: "tree",
|
||||
Remark: "remark",
|
||||
Status: "status",
|
||||
CreatedBy: "created_by",
|
||||
UpdatedBy: "updated_by",
|
||||
CreatedAt: "created_at",
|
||||
UpdatedAt: "updated_at",
|
||||
DeletedAt: "deleted_at",
|
||||
}
|
||||
|
||||
// NewTestDao creates and returns a new DAO object for table data access.
|
||||
func NewTestDao() *TestDao {
|
||||
return &TestDao{
|
||||
group: "default",
|
||||
table: "hg_test",
|
||||
columns: testColumns,
|
||||
}
|
||||
}
|
||||
|
||||
// DB retrieves and returns the underlying raw database management object of current DAO.
|
||||
func (dao *TestDao) DB() gdb.DB {
|
||||
return g.DB(dao.group)
|
||||
}
|
||||
|
||||
// Table returns the table name of current dao.
|
||||
func (dao *TestDao) Table() string {
|
||||
return dao.table
|
||||
}
|
||||
|
||||
// Columns returns all column names of current dao.
|
||||
func (dao *TestDao) Columns() TestColumns {
|
||||
return dao.columns
|
||||
}
|
||||
|
||||
// Group returns the configuration group name of database of current dao.
|
||||
func (dao *TestDao) Group() string {
|
||||
return dao.group
|
||||
}
|
||||
|
||||
// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation.
|
||||
func (dao *TestDao) Ctx(ctx context.Context) *gdb.Model {
|
||||
return dao.DB().Model(dao.table).Safe().Ctx(ctx)
|
||||
}
|
||||
|
||||
// Transaction wraps the transaction logic using function f.
|
||||
// It rollbacks the transaction and returns the error from function f if it returns non-nil error.
|
||||
// It commits the transaction and returns nil if function f returns nil.
|
||||
//
|
||||
// Note that, you should not Commit or Rollback the transaction in function f
|
||||
// as it is automatically handled by this function.
|
||||
func (dao *TestDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
|
||||
return dao.Ctx(ctx).Transaction(ctx, f)
|
||||
}
|
||||
89
server/internal/dao/internal/test_category.go
Normal file
89
server/internal/dao/internal/test_category.go
Normal file
@@ -0,0 +1,89 @@
|
||||
// ==========================================================================
|
||||
// Code generated by GoFrame CLI tool. DO NOT EDIT.
|
||||
// ==========================================================================
|
||||
|
||||
package internal
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/gogf/gf/v2/database/gdb"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
)
|
||||
|
||||
// TestCategoryDao is the data access object for table hg_test_category.
|
||||
type TestCategoryDao struct {
|
||||
table string // table is the underlying table name of the DAO.
|
||||
group string // group is the database configuration group name of current DAO.
|
||||
columns TestCategoryColumns // columns contains all the column names of Table for convenient usage.
|
||||
}
|
||||
|
||||
// TestCategoryColumns defines and stores column names for table hg_test_category.
|
||||
type TestCategoryColumns struct {
|
||||
Id string // 分类ID
|
||||
Name string // 分类名称
|
||||
Description string // 描述
|
||||
Sort string // 排序
|
||||
Remark string // 备注
|
||||
Status string // 状态
|
||||
CreatedAt string // 创建时间
|
||||
UpdatedAt string // 修改时间
|
||||
DeletedAt string // 删除时间
|
||||
}
|
||||
|
||||
// testCategoryColumns holds the columns for table hg_test_category.
|
||||
var testCategoryColumns = TestCategoryColumns{
|
||||
Id: "id",
|
||||
Name: "name",
|
||||
Description: "description",
|
||||
Sort: "sort",
|
||||
Remark: "remark",
|
||||
Status: "status",
|
||||
CreatedAt: "created_at",
|
||||
UpdatedAt: "updated_at",
|
||||
DeletedAt: "deleted_at",
|
||||
}
|
||||
|
||||
// NewTestCategoryDao creates and returns a new DAO object for table data access.
|
||||
func NewTestCategoryDao() *TestCategoryDao {
|
||||
return &TestCategoryDao{
|
||||
group: "default",
|
||||
table: "hg_test_category",
|
||||
columns: testCategoryColumns,
|
||||
}
|
||||
}
|
||||
|
||||
// DB retrieves and returns the underlying raw database management object of current DAO.
|
||||
func (dao *TestCategoryDao) DB() gdb.DB {
|
||||
return g.DB(dao.group)
|
||||
}
|
||||
|
||||
// Table returns the table name of current dao.
|
||||
func (dao *TestCategoryDao) Table() string {
|
||||
return dao.table
|
||||
}
|
||||
|
||||
// Columns returns all column names of current dao.
|
||||
func (dao *TestCategoryDao) Columns() TestCategoryColumns {
|
||||
return dao.columns
|
||||
}
|
||||
|
||||
// Group returns the configuration group name of database of current dao.
|
||||
func (dao *TestCategoryDao) Group() string {
|
||||
return dao.group
|
||||
}
|
||||
|
||||
// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation.
|
||||
func (dao *TestCategoryDao) Ctx(ctx context.Context) *gdb.Model {
|
||||
return dao.DB().Model(dao.table).Safe().Ctx(ctx)
|
||||
}
|
||||
|
||||
// Transaction wraps the transaction logic using function f.
|
||||
// It rollbacks the transaction and returns the error from function f if it returns non-nil error.
|
||||
// It commits the transaction and returns nil if function f returns nil.
|
||||
//
|
||||
// Note that, you should not Commit or Rollback the transaction in function f
|
||||
// as it is automatically handled by this function.
|
||||
func (dao *TestCategoryDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
|
||||
return dao.Ctx(ctx).Transaction(ctx, f)
|
||||
}
|
||||
@@ -7,6 +7,8 @@ package dao
|
||||
import (
|
||||
"context"
|
||||
"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/dao/internal"
|
||||
"hotgo/internal/model/input/sysin"
|
||||
@@ -31,10 +33,8 @@ var (
|
||||
)
|
||||
|
||||
func (dao *sysAttachmentDao) GetMd5File(ctx context.Context, md5 string) (data *sysin.AttachmentListModel, err error) {
|
||||
|
||||
if err = dao.Ctx(ctx).
|
||||
Where("md5", md5).
|
||||
Where("status", consts.StatusEnabled).
|
||||
Scan(&data); err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
return nil, err
|
||||
@@ -44,8 +44,21 @@ func (dao *sysAttachmentDao) GetMd5File(ctx context.Context, md5 string) (data *
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
conf, err := service.SysConfig().GetUpload(ctx)
|
||||
if err != nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
data.SizeFormat = format.FileSize(data.Size)
|
||||
data.FileUrl = service.CommonUpload().LastUrl(ctx, data.FileUrl, data.Drive)
|
||||
data.FileUrl = service.CommonUpload().LastUrl(ctx, conf, data.FileUrl, data.Drive)
|
||||
|
||||
// 只有在上传时才会检查md5值,如果文件存在则更新最后上传时间,保证上传列表更新显示在最前面
|
||||
if data.Id > 0 {
|
||||
_, _ = dao.Ctx(ctx).Where("id", data.Id).Data(g.Map{
|
||||
"status": consts.StatusEnabled,
|
||||
"updated_at": gtime.Now(),
|
||||
}).Update()
|
||||
}
|
||||
|
||||
return data, nil
|
||||
}
|
||||
|
||||
27
server/internal/dao/sys_gen_codes.go
Normal file
27
server/internal/dao/sys_gen_codes.go
Normal file
@@ -0,0 +1,27 @@
|
||||
// =================================================================================
|
||||
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
|
||||
// =================================================================================
|
||||
|
||||
package dao
|
||||
|
||||
import (
|
||||
"hotgo/internal/dao/internal"
|
||||
)
|
||||
|
||||
// internalSysGenCodesDao is internal type for wrapping internal DAO implements.
|
||||
type internalSysGenCodesDao = *internal.SysGenCodesDao
|
||||
|
||||
// sysGenCodesDao is the data access object for table hg_sys_gen_codes.
|
||||
// You can define custom methods on it to extend its functionality as you wish.
|
||||
type sysGenCodesDao struct {
|
||||
internalSysGenCodesDao
|
||||
}
|
||||
|
||||
var (
|
||||
// SysGenCodes is globally public accessible object for table hg_sys_gen_codes operations.
|
||||
SysGenCodes = sysGenCodesDao{
|
||||
internal.NewSysGenCodesDao(),
|
||||
}
|
||||
)
|
||||
|
||||
// Fill with you ideas below.
|
||||
27
server/internal/dao/sys_gen_curd_demo.go
Normal file
27
server/internal/dao/sys_gen_curd_demo.go
Normal file
@@ -0,0 +1,27 @@
|
||||
// =================================================================================
|
||||
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
|
||||
// =================================================================================
|
||||
|
||||
package dao
|
||||
|
||||
import (
|
||||
"hotgo/internal/dao/internal"
|
||||
)
|
||||
|
||||
// internalSysGenCurdDemoDao is internal type for wrapping internal DAO implements.
|
||||
type internalSysGenCurdDemoDao = *internal.SysGenCurdDemoDao
|
||||
|
||||
// sysGenCurdDemoDao is the data access object for table hg_sys_gen_curd_demo.
|
||||
// You can define custom methods on it to extend its functionality as you wish.
|
||||
type sysGenCurdDemoDao struct {
|
||||
internalSysGenCurdDemoDao
|
||||
}
|
||||
|
||||
var (
|
||||
// SysGenCurdDemo is globally public accessible object for table hg_sys_gen_curd_demo operations.
|
||||
SysGenCurdDemo = sysGenCurdDemoDao{
|
||||
internal.NewSysGenCurdDemoDao(),
|
||||
}
|
||||
)
|
||||
|
||||
// Fill with you ideas below.
|
||||
27
server/internal/dao/test.go
Normal file
27
server/internal/dao/test.go
Normal file
@@ -0,0 +1,27 @@
|
||||
// =================================================================================
|
||||
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
|
||||
// =================================================================================
|
||||
|
||||
package dao
|
||||
|
||||
import (
|
||||
"hotgo/internal/dao/internal"
|
||||
)
|
||||
|
||||
// internalTestDao is internal type for wrapping internal DAO implements.
|
||||
type internalTestDao = *internal.TestDao
|
||||
|
||||
// testDao is the data access object for table hg_test.
|
||||
// You can define custom methods on it to extend its functionality as you wish.
|
||||
type testDao struct {
|
||||
internalTestDao
|
||||
}
|
||||
|
||||
var (
|
||||
// Test is globally public accessible object for table hg_test operations.
|
||||
Test = testDao{
|
||||
internal.NewTestDao(),
|
||||
}
|
||||
)
|
||||
|
||||
// Fill with you ideas below.
|
||||
27
server/internal/dao/test_category.go
Normal file
27
server/internal/dao/test_category.go
Normal file
@@ -0,0 +1,27 @@
|
||||
// =================================================================================
|
||||
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
|
||||
// =================================================================================
|
||||
|
||||
package dao
|
||||
|
||||
import (
|
||||
"hotgo/internal/dao/internal"
|
||||
)
|
||||
|
||||
// internalTestCategoryDao is internal type for wrapping internal DAO implements.
|
||||
type internalTestCategoryDao = *internal.TestCategoryDao
|
||||
|
||||
// testCategoryDao is the data access object for table hg_test_category.
|
||||
// You can define custom methods on it to extend its functionality as you wish.
|
||||
type testCategoryDao struct {
|
||||
internalTestCategoryDao
|
||||
}
|
||||
|
||||
var (
|
||||
// TestCategory is globally public accessible object for table hg_test_category operations.
|
||||
TestCategory = testCategoryDao{
|
||||
internal.NewTestCategoryDao(),
|
||||
}
|
||||
)
|
||||
|
||||
// Fill with you ideas below.
|
||||
@@ -10,29 +10,55 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/gogf/gf/v2"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gcache"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
"hotgo/internal/consts"
|
||||
"hotgo/internal/library/hggen"
|
||||
"hotgo/internal/library/location"
|
||||
"hotgo/utility/simple"
|
||||
"os"
|
||||
)
|
||||
|
||||
func Init(ctx context.Context) {
|
||||
if _, err := g.Cfg().Get(ctx, "hotgo.debug"); err != nil {
|
||||
g.Log().Fatal(ctx, "配置读取异常:", err, "\r\n你确定 config/config.yaml 文件存在且格式正确吗?\r\n")
|
||||
}
|
||||
// 默认上海时区
|
||||
if err := gtime.SetTimeZone("Asia/Shanghai"); err != nil {
|
||||
fmt.Printf("时区设置异常err:%v \r\n", err)
|
||||
g.Log().Fatalf(ctx, "时区设置异常err:%+v", err)
|
||||
return
|
||||
}
|
||||
|
||||
RootPtah, _ = os.Getwd()
|
||||
fmt.Printf("欢迎使用HotGo!\r\n当前运行环境:%v, 运行根路径为:%v \r\nHotGo版本:v%v, gf版本:%v \n", SysType, RootPtah, consts.VersionApp, gf.VERSION)
|
||||
loadMonitor(ctx)
|
||||
|
||||
setOrmCacheAdapter()
|
||||
|
||||
startMonitor(ctx)
|
||||
|
||||
hggen.InIt(ctx)
|
||||
|
||||
}
|
||||
|
||||
func loadMonitor(ctx context.Context) {
|
||||
func startMonitor(ctx context.Context) {
|
||||
simple.SafeGo(ctx, func(ctx context.Context) {
|
||||
MonitorData.STartTime = gtime.Now()
|
||||
MonitorData.IntranetIP, _ = location.GetLocalIP()
|
||||
MonitorData.PublicIP, _ = location.GetPublicIP()
|
||||
intranetIP, err := location.GetLocalIP()
|
||||
if err != nil {
|
||||
g.Log().Warningf(ctx, "parse intranetIP err:%+v", err)
|
||||
}
|
||||
MonitorData.IntranetIP = intranetIP
|
||||
|
||||
publicIP, err := location.GetPublicIP(ctx)
|
||||
if err != nil {
|
||||
g.Log().Warningf(ctx, "parse publicIP err:%+v", err)
|
||||
}
|
||||
MonitorData.PublicIP = publicIP
|
||||
})
|
||||
}
|
||||
|
||||
func setOrmCacheAdapter() {
|
||||
redisCache := gcache.NewAdapterRedis(g.Redis())
|
||||
g.DB().GetCache().SetAdapter(redisCache)
|
||||
}
|
||||
|
||||
@@ -13,7 +13,6 @@ import (
|
||||
"github.com/casbin/casbin/v2/model"
|
||||
"github.com/casbin/casbin/v2/persist"
|
||||
"github.com/gogf/gf/v2/database/gdb"
|
||||
"log"
|
||||
"math"
|
||||
"strings"
|
||||
)
|
||||
@@ -119,7 +118,6 @@ func (a *adapter) dropPolicyTable() (err error) {
|
||||
|
||||
// LoadPolicy loads all policy rules from the storage.
|
||||
func (a *adapter) LoadPolicy(model model.Model) (err error) {
|
||||
log.Println("LoadPolicy...")
|
||||
var rules []policyRule
|
||||
|
||||
if err = a.model().Scan(&rules); err != nil {
|
||||
@@ -248,7 +246,7 @@ func (a *adapter) UpdatePolicies(sec string, ptype string, oldRules, newRules []
|
||||
return
|
||||
}
|
||||
|
||||
err = a.db.Transaction(context.TODO(), func(ctx context.Context, tx *gdb.TX) error {
|
||||
err = a.db.Transaction(context.TODO(), func(ctx context.Context, tx gdb.TX) error {
|
||||
for i := 0; i < int(math.Min(float64(len(oldRules)), float64(len(newRules)))); i++ {
|
||||
if _, err = tx.Model(a.table).Update(a.buildPolicyRule(ptype, newRules[i]), a.buildPolicyRule(ptype, oldRules[i])); err != nil {
|
||||
return err
|
||||
|
||||
@@ -29,8 +29,8 @@ var Enforcer *casbin.Enforcer
|
||||
// InitEnforcer 初始化
|
||||
func InitEnforcer(ctx context.Context) {
|
||||
var (
|
||||
link, _ = g.Cfg().Get(ctx, "database.default.link")
|
||||
a, err = NewAdapter(link.String())
|
||||
link = g.Cfg().MustGet(ctx, "database.default.link")
|
||||
a, err = NewAdapter(link.String())
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
@@ -53,10 +53,10 @@ func loadPermissions(ctx context.Context) {
|
||||
Permissions string `json:"permissions"`
|
||||
}
|
||||
var (
|
||||
rules [][]string
|
||||
polices []*Policy
|
||||
err error
|
||||
superRoleKey, _ = g.Cfg().Get(ctx, "hotgo.admin.superRoleKey")
|
||||
rules [][]string
|
||||
polices []*Policy
|
||||
err error
|
||||
superRoleKey = g.Cfg().MustGet(ctx, "hotgo.admin.superRoleKey")
|
||||
)
|
||||
|
||||
err = g.Model("hg_admin_role r").
|
||||
|
||||
@@ -67,7 +67,7 @@ func GetRoleId(ctx context.Context) int64 {
|
||||
return 0
|
||||
}
|
||||
|
||||
return user.Role
|
||||
return user.RoleId
|
||||
}
|
||||
|
||||
// GetRoleKey 获取用户角色唯一编码
|
||||
|
||||
13
server/internal/library/debris/debris.go
Normal file
13
server/internal/library/debris/debris.go
Normal file
@@ -0,0 +1,13 @@
|
||||
// Package debris
|
||||
// @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 debris
|
||||
|
||||
// 碎片
|
||||
|
||||
func Test() {
|
||||
|
||||
}
|
||||
192
server/internal/library/hggen/hggen.go
Normal file
192
server/internal/library/hggen/hggen.go
Normal file
@@ -0,0 +1,192 @@
|
||||
// Package hggen
|
||||
// @Link https://github.com/bufanyun/hotgo
|
||||
// @Copyright Copyright (c) 2022 HotGo CLI
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
|
||||
//
|
||||
package hggen
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
"hotgo/internal/consts"
|
||||
"hotgo/internal/library/hggen/internal/cmd"
|
||||
"hotgo/internal/library/hggen/internal/cmd/gendao"
|
||||
"hotgo/internal/library/hggen/views"
|
||||
"hotgo/internal/model/input/form"
|
||||
"hotgo/internal/model/input/sysin"
|
||||
"hotgo/internal/service"
|
||||
"sort"
|
||||
)
|
||||
|
||||
// Dao 生成数据库实体
|
||||
func Dao(ctx context.Context) (err error) {
|
||||
for _, v := range daoConfig {
|
||||
inp := defaultGenDaoInput
|
||||
err = gconv.Scan(v, &inp)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
gendao.DoGenDaoForArray(ctx, inp)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Service 生成业务接口
|
||||
func Service(ctx context.Context) (err error) {
|
||||
_, err = cmd.Gen.Service(ctx, GetServiceConfig())
|
||||
return
|
||||
}
|
||||
|
||||
// TableColumns 获取指定表生成字段列表
|
||||
func TableColumns(ctx context.Context, in sysin.GenCodesColumnListInp) (fields []*sysin.GenCodesColumnListModel, err error) {
|
||||
return views.DoTableColumns(ctx, in, GetDaoConfig(in.Name))
|
||||
}
|
||||
|
||||
func TableSelects(ctx context.Context, in sysin.GenCodesSelectsInp) (res *sysin.GenCodesSelectsModel, err error) {
|
||||
res = new(sysin.GenCodesSelectsModel)
|
||||
for k, v := range consts.GenCodesTypeNameMap {
|
||||
res.GenType = append(res.GenType, &form.Select{
|
||||
Value: k,
|
||||
Name: v,
|
||||
Label: v,
|
||||
})
|
||||
}
|
||||
sort.Sort(res.GenType)
|
||||
res.Db = DbSelect(ctx)
|
||||
|
||||
for k, v := range consts.GenCodesStatusNameMap {
|
||||
res.Status = append(res.Status, &form.Select{
|
||||
Value: k,
|
||||
Name: v,
|
||||
Label: v,
|
||||
})
|
||||
}
|
||||
sort.Sort(res.Status)
|
||||
|
||||
for k, v := range consts.GenCodesJoinNameMap {
|
||||
res.LinkMode = append(res.LinkMode, &form.Select{
|
||||
Value: k,
|
||||
Name: v,
|
||||
Label: v,
|
||||
})
|
||||
}
|
||||
sort.Sort(res.LinkMode)
|
||||
|
||||
for k, v := range consts.GenCodesBuildMethNameMap {
|
||||
res.BuildMeth = append(res.BuildMeth, &form.Select{
|
||||
Value: k,
|
||||
Name: v,
|
||||
Label: v,
|
||||
})
|
||||
}
|
||||
sort.Sort(res.BuildMeth)
|
||||
|
||||
for _, v := range views.FormModes {
|
||||
res.FormMode = append(res.FormMode, &form.Select{
|
||||
Value: v,
|
||||
Name: views.FormModeMap[v],
|
||||
Label: views.FormModeMap[v],
|
||||
})
|
||||
}
|
||||
sort.Sort(res.FormMode)
|
||||
|
||||
for k, v := range views.FormRoleMap {
|
||||
res.FormRole = append(res.FormRole, &form.Select{
|
||||
Value: k,
|
||||
Name: v,
|
||||
Label: v,
|
||||
})
|
||||
}
|
||||
sort.Sort(res.FormRole)
|
||||
|
||||
dictMode, _ := service.SysDictType().TreeSelect(ctx, sysin.DictTreeSelectInp{})
|
||||
|
||||
res.DictMode = dictMode
|
||||
for _, v := range views.WhereModes {
|
||||
res.WhereMode = append(res.WhereMode, &form.Select{
|
||||
Value: v,
|
||||
Name: v,
|
||||
Label: v,
|
||||
})
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// DbSelect db选项
|
||||
func DbSelect(ctx context.Context) (res form.Selects) {
|
||||
dbs := g.Cfg().MustGet(ctx, "hggen.selectDbs")
|
||||
if len(dbs.Strings()) == 0 {
|
||||
res = make(form.Selects, 0)
|
||||
return res
|
||||
}
|
||||
|
||||
for _, v := range dbs.Strings() {
|
||||
res = append(res, &form.Select{
|
||||
Value: v,
|
||||
Label: v,
|
||||
Name: v,
|
||||
})
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// Preview 生成预览
|
||||
func Preview(ctx context.Context, in sysin.GenCodesPreviewInp) (res *sysin.GenCodesPreviewModel, err error) {
|
||||
genConfig, err := service.SysConfig().GetLoadGenerate(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
switch in.GenType {
|
||||
case consts.GenCodesTypeCurd:
|
||||
return views.Curd.DoPreview(ctx, &views.CurdPreviewInput{
|
||||
In: in,
|
||||
DaoConfig: GetDaoConfig(in.DbName),
|
||||
Config: genConfig,
|
||||
})
|
||||
case consts.GenCodesTypeTree:
|
||||
err = gerror.Newf("生成类型开发中!")
|
||||
return
|
||||
case consts.GenCodesTypeQueue:
|
||||
err = gerror.Newf("生成类型开发中!")
|
||||
return
|
||||
default:
|
||||
err = gerror.Newf("生成类型暂不支持!")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Build 提交生成
|
||||
func Build(ctx context.Context, in sysin.GenCodesBuildInp) (err error) {
|
||||
genConfig, err := service.SysConfig().GetLoadGenerate(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch in.GenType {
|
||||
case consts.GenCodesTypeCurd:
|
||||
return views.Curd.DoBuild(ctx, &views.CurdBuildInput{
|
||||
PreviewIn: &views.CurdPreviewInput{
|
||||
In: sysin.GenCodesPreviewInp(in),
|
||||
DaoConfig: GetDaoConfig(in.DbName),
|
||||
Config: genConfig,
|
||||
},
|
||||
BeforeEvent: views.CurdBuildEvent{"runDao": Dao},
|
||||
AfterEvent: views.CurdBuildEvent{"runService": Service},
|
||||
})
|
||||
case consts.GenCodesTypeTree:
|
||||
err = gerror.Newf("生成类型开发中!")
|
||||
return
|
||||
case consts.GenCodesTypeQueue:
|
||||
err = gerror.Newf("生成类型开发中!")
|
||||
return
|
||||
default:
|
||||
err = gerror.Newf("生成类型暂不支持!")
|
||||
return
|
||||
}
|
||||
}
|
||||
133
server/internal/library/hggen/init.go
Normal file
133
server/internal/library/hggen/init.go
Normal file
@@ -0,0 +1,133 @@
|
||||
// Package hggen
|
||||
// @Link https://github.com/bufanyun/hotgo
|
||||
// @Copyright Copyright (c) 2022 HotGo CLI
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
|
||||
//
|
||||
package hggen
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gfile"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
"gopkg.in/yaml.v3"
|
||||
"hotgo/internal/library/hggen/internal/cmd/gendao"
|
||||
"hotgo/internal/library/hggen/internal/cmd/genservice"
|
||||
)
|
||||
|
||||
const (
|
||||
cliFolderName = `hack/config.yaml`
|
||||
RequiredErrorTag = `the cli configuration file must be configured %s`
|
||||
)
|
||||
|
||||
var (
|
||||
config g.Map
|
||||
daoConfig []interface{}
|
||||
serviceConfig g.Map
|
||||
|
||||
// 生成service默认参数,请不要直接修改以下配置,如需调整请到/hack/config.yaml,可参考:https://goframe.org/pages/viewpage.action?pageId=49770772
|
||||
defaultGenServiceInput = genservice.CGenServiceInput{
|
||||
SrcFolder: "internal/logic",
|
||||
DstFolder: "internal/service",
|
||||
DstFileNameCase: "Snake",
|
||||
StPattern: `s([A-Z]\w+)`,
|
||||
Clear: false,
|
||||
}
|
||||
|
||||
// 生成dao默认参数,请不要直接修改以下配置,如需调整请到/hack/config.yaml,可参考:https://goframe.org/pages/viewpage.action?pageId=3673173
|
||||
defaultGenDaoInput = gendao.CGenDaoInput{
|
||||
Path: "internal",
|
||||
Group: "default",
|
||||
JsonCase: "CamelLower",
|
||||
DaoPath: "dao",
|
||||
DoPath: "model/do",
|
||||
EntityPath: "model/entity",
|
||||
StdTime: false,
|
||||
WithTime: false,
|
||||
GJsonSupport: false,
|
||||
OverwriteDao: false,
|
||||
DescriptionTag: true,
|
||||
NoJsonTag: false,
|
||||
NoModelComment: false,
|
||||
Clear: false,
|
||||
}
|
||||
)
|
||||
|
||||
func GetServiceConfig() genservice.CGenServiceInput {
|
||||
inp := defaultGenServiceInput
|
||||
_ = gconv.Scan(serviceConfig, &inp)
|
||||
return inp
|
||||
}
|
||||
|
||||
func GetDaoConfig(group string) gendao.CGenDaoInput {
|
||||
inp := defaultGenDaoInput
|
||||
find := func(group string) g.Map {
|
||||
for _, v := range daoConfig {
|
||||
if v.(g.Map)["group"].(string) == group {
|
||||
return v.(g.Map)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
v := find(group)
|
||||
if v != nil {
|
||||
err := gconv.Scan(v, &inp)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
return inp
|
||||
}
|
||||
|
||||
func InIt(ctx context.Context) {
|
||||
path, err := gfile.Search(cliFolderName)
|
||||
if err != nil {
|
||||
g.Log().Fatalf(ctx, "get cli configuration file:%v, err:%+v", cliFolderName, err)
|
||||
}
|
||||
if path == "" {
|
||||
g.Log().Fatalf(ctx, "get cli configuration file:%v fail", cliFolderName)
|
||||
}
|
||||
if config == nil {
|
||||
config = make(g.Map)
|
||||
}
|
||||
err = yaml.Unmarshal(gfile.GetBytes(path), &config)
|
||||
if err != nil {
|
||||
g.Log().Fatalf(ctx, "load cli configuration file:%v, yaml err:%+v", cliFolderName, err)
|
||||
}
|
||||
loadConfig(ctx)
|
||||
}
|
||||
|
||||
func loadConfig(ctx context.Context) {
|
||||
if _, ok := config["gfcli"]; !ok {
|
||||
g.Log().Fatalf(ctx, RequiredErrorTag, "gfcli")
|
||||
}
|
||||
|
||||
if _, ok := config["gfcli"].(g.Map)["gen"]; !ok {
|
||||
g.Log().Fatalf(ctx, RequiredErrorTag, "gfcli.gen")
|
||||
}
|
||||
|
||||
dao, ok := config["gfcli"].(g.Map)["gen"].(map[string]interface{})["dao"]
|
||||
if !ok {
|
||||
g.Log().Fatalf(ctx, RequiredErrorTag, "gfcli.gen.dao")
|
||||
}
|
||||
daoConf, ok := dao.([]interface{})
|
||||
if !ok {
|
||||
g.Log().Fatalf(ctx, RequiredErrorTag, "gfcli.gen.dao format error")
|
||||
}
|
||||
daoConfig = daoConf
|
||||
for _, v := range daoConfig {
|
||||
if _, ok := v.(g.Map)["group"].(string); !ok {
|
||||
g.Log().Fatalf(ctx, "group must be configured in %s: `gfcli.gen.dao` and must be the same as the database group", cliFolderName)
|
||||
}
|
||||
}
|
||||
|
||||
if serviceConf, ok := config["gfcli"].(g.Map)["gen"].(map[string]interface{})["service"]; ok {
|
||||
if serviceConfig == nil {
|
||||
serviceConfig = make(g.Map)
|
||||
}
|
||||
serviceConfig = serviceConf.(g.Map)
|
||||
}
|
||||
}
|
||||
66
server/internal/library/hggen/internal/cmd/cmd.go
Normal file
66
server/internal/library/hggen/internal/cmd/cmd.go
Normal file
@@ -0,0 +1,66 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gcmd"
|
||||
"github.com/gogf/gf/v2/util/gtag"
|
||||
|
||||
"hotgo/internal/library/hggen/internal/service"
|
||||
"hotgo/internal/library/hggen/internal/utility/mlog"
|
||||
)
|
||||
|
||||
var (
|
||||
GF = cGF{}
|
||||
)
|
||||
|
||||
type cGF struct {
|
||||
g.Meta `name:"gf" ad:"{cGFAd}"`
|
||||
}
|
||||
|
||||
const (
|
||||
cGFAd = `
|
||||
ADDITIONAL
|
||||
Use "gf COMMAND -h" for details about a command.
|
||||
`
|
||||
)
|
||||
|
||||
func init() {
|
||||
gtag.Sets(g.MapStrStr{
|
||||
`cGFAd`: cGFAd,
|
||||
})
|
||||
}
|
||||
|
||||
type cGFInput struct {
|
||||
g.Meta `name:"gf"`
|
||||
Yes bool `short:"y" name:"yes" brief:"all yes for all command without prompt ask" orphan:"true"`
|
||||
Version bool `short:"v" name:"version" brief:"show version information of current binary" orphan:"true"`
|
||||
Debug bool `short:"d" name:"debug" brief:"show internal detailed debugging information" orphan:"true"`
|
||||
}
|
||||
|
||||
type cGFOutput struct{}
|
||||
|
||||
func (c cGF) Index(ctx context.Context, in cGFInput) (out *cGFOutput, err error) {
|
||||
// Version.
|
||||
if in.Version {
|
||||
_, err = Version.Index(ctx, cVersionInput{})
|
||||
return
|
||||
}
|
||||
// No argument or option, do installation checks.
|
||||
if !service.Install.IsInstalled() {
|
||||
mlog.Print("hi, it seams it's the first time you installing gf cli.")
|
||||
s := gcmd.Scanf("do you want to install gf binary to your system? [y/n]: ")
|
||||
if strings.EqualFold(s, "y") {
|
||||
if err = service.Install.Run(ctx); err != nil {
|
||||
return
|
||||
}
|
||||
gcmd.Scan("press `Enter` to exit...")
|
||||
return
|
||||
}
|
||||
}
|
||||
// Print help content.
|
||||
gcmd.CommandFromCtx(ctx).Print()
|
||||
return
|
||||
}
|
||||
327
server/internal/library/hggen/internal/cmd/cmd_build.go
Normal file
327
server/internal/library/hggen/internal/cmd/cmd_build.go
Normal file
@@ -0,0 +1,327 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"github.com/gogf/gf/v2/encoding/gbase64"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gcmd"
|
||||
"github.com/gogf/gf/v2/os/genv"
|
||||
"github.com/gogf/gf/v2/os/gfile"
|
||||
"github.com/gogf/gf/v2/os/gproc"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
"github.com/gogf/gf/v2/text/gregex"
|
||||
"github.com/gogf/gf/v2/text/gstr"
|
||||
"github.com/gogf/gf/v2/util/gtag"
|
||||
|
||||
"hotgo/internal/library/hggen/internal/utility/mlog"
|
||||
)
|
||||
|
||||
var (
|
||||
Build = cBuild{
|
||||
nodeNameInConfigFile: "gfcli.build",
|
||||
packedGoFileName: "internal/packed/build_pack_data.go",
|
||||
}
|
||||
)
|
||||
|
||||
type cBuild struct {
|
||||
g.Meta `name:"build" brief:"{cBuildBrief}" dc:"{cBuildDc}" eg:"{cBuildEg}" ad:"{cBuildAd}"`
|
||||
nodeNameInConfigFile string // nodeNameInConfigFile is the node name for compiler configurations in configuration file.
|
||||
packedGoFileName string // packedGoFileName specifies the file name for packing common folders into one single go file.
|
||||
}
|
||||
|
||||
const (
|
||||
cBuildBrief = `cross-building go project for lots of platforms`
|
||||
cBuildEg = `
|
||||
gf build main.go
|
||||
gf build main.go --pack public,template
|
||||
gf build main.go --cgo
|
||||
gf build main.go -m none
|
||||
gf build main.go -n my-app -a all -s all
|
||||
gf build main.go -n my-app -a amd64,386 -s linux -p .
|
||||
gf build main.go -n my-app -v 1.0 -a amd64,386 -s linux,windows,darwin -p ./docker/bin
|
||||
`
|
||||
cBuildDc = `
|
||||
The "build" command is most commonly used command, which is designed as a powerful wrapper for
|
||||
"go build" command for convenience cross-compiling usage.
|
||||
It provides much more features for building binary:
|
||||
1. Cross-Compiling for many platforms and architectures.
|
||||
2. Configuration file support for compiling.
|
||||
3. Build-In Variables.
|
||||
`
|
||||
cBuildAd = `
|
||||
PLATFORMS
|
||||
darwin amd64,arm64
|
||||
freebsd 386,amd64,arm
|
||||
linux 386,amd64,arm,arm64,ppc64,ppc64le,mips,mipsle,mips64,mips64le
|
||||
netbsd 386,amd64,arm
|
||||
openbsd 386,amd64,arm
|
||||
windows 386,amd64
|
||||
`
|
||||
// https://golang.google.cn/doc/install/source
|
||||
cBuildPlatforms = `
|
||||
darwin amd64
|
||||
darwin arm64
|
||||
ios amd64
|
||||
ios arm64
|
||||
freebsd 386
|
||||
freebsd amd64
|
||||
freebsd arm
|
||||
linux 386
|
||||
linux amd64
|
||||
linux arm
|
||||
linux arm64
|
||||
linux ppc64
|
||||
linux ppc64le
|
||||
linux mips
|
||||
linux mipsle
|
||||
linux mips64
|
||||
linux mips64le
|
||||
netbsd 386
|
||||
netbsd amd64
|
||||
netbsd arm
|
||||
openbsd 386
|
||||
openbsd amd64
|
||||
openbsd arm
|
||||
windows 386
|
||||
windows amd64
|
||||
android arm
|
||||
dragonfly amd64
|
||||
plan9 386
|
||||
plan9 amd64
|
||||
solaris amd64
|
||||
`
|
||||
)
|
||||
|
||||
func init() {
|
||||
gtag.Sets(g.MapStrStr{
|
||||
`cBuildBrief`: cBuildBrief,
|
||||
`cBuildDc`: cBuildDc,
|
||||
`cBuildEg`: cBuildEg,
|
||||
`cBuildAd`: cBuildAd,
|
||||
})
|
||||
}
|
||||
|
||||
type cBuildInput struct {
|
||||
g.Meta `name:"build" config:"gfcli.build"`
|
||||
File string `name:"FILE" arg:"true" brief:"building file path"`
|
||||
Name string `short:"n" name:"name" brief:"output binary name"`
|
||||
Version string `short:"v" name:"version" brief:"output binary version"`
|
||||
Arch string `short:"a" name:"arch" brief:"output binary architecture, multiple arch separated with ','"`
|
||||
System string `short:"s" name:"system" brief:"output binary system, multiple os separated with ','"`
|
||||
Output string `short:"o" name:"output" brief:"output binary path, used when building single binary file"`
|
||||
Path string `short:"p" name:"path" brief:"output binary directory path, default is './temp'" d:"./temp"`
|
||||
Extra string `short:"e" name:"extra" brief:"extra custom \"go build\" options"`
|
||||
Mod string `short:"m" name:"mod" brief:"like \"-mod\" option of \"go build\", use \"-m none\" to disable go module"`
|
||||
Cgo bool `short:"c" name:"cgo" brief:"enable or disable cgo feature, it's disabled in default" orphan:"true"`
|
||||
VarMap g.Map `short:"r" name:"varMap" brief:"custom built embedded variable into binary"`
|
||||
PackSrc string `short:"ps" name:"packSrc" brief:"pack one or more folders into one go file before building"`
|
||||
PackDst string `short:"pd" name:"packDst" brief:"temporary go file path for pack, this go file will be automatically removed after built" d:"internal/packed/build_pack_data.go"`
|
||||
ExitWhenError bool `short:"ew" name:"exitWhenError" brief:"exit building when any error occurs, default is false" orphan:"true"`
|
||||
}
|
||||
|
||||
type cBuildOutput struct{}
|
||||
|
||||
func (c cBuild) Index(ctx context.Context, in cBuildInput) (out *cBuildOutput, err error) {
|
||||
mlog.SetHeaderPrint(true)
|
||||
|
||||
mlog.Debugf(`build input: %+v`, in)
|
||||
// Necessary check.
|
||||
if gproc.SearchBinary("go") == "" {
|
||||
mlog.Fatalf(`command "go" not found in your environment, please install golang first to proceed this command`)
|
||||
}
|
||||
|
||||
var (
|
||||
parser = gcmd.ParserFromCtx(ctx)
|
||||
file = parser.GetArg(2).String()
|
||||
)
|
||||
if len(file) < 1 {
|
||||
// Check and use the main.go file.
|
||||
if gfile.Exists("main.go") {
|
||||
file = "main.go"
|
||||
} else {
|
||||
mlog.Fatal("build file path cannot be empty")
|
||||
}
|
||||
}
|
||||
if in.Name == "" {
|
||||
in.Name = gfile.Name(file)
|
||||
}
|
||||
if len(in.Name) < 1 || in.Name == "*" {
|
||||
mlog.Fatal("name cannot be empty")
|
||||
}
|
||||
if in.Mod != "" && in.Mod != "none" {
|
||||
mlog.Debugf(`mod is %s`, in.Mod)
|
||||
if in.Extra == "" {
|
||||
in.Extra = fmt.Sprintf(`-mod=%s`, in.Mod)
|
||||
} else {
|
||||
in.Extra = fmt.Sprintf(`-mod=%s %s`, in.Mod, in.Extra)
|
||||
}
|
||||
}
|
||||
if in.Extra != "" {
|
||||
in.Extra += " "
|
||||
}
|
||||
var (
|
||||
customSystems = gstr.SplitAndTrim(in.System, ",")
|
||||
customArches = gstr.SplitAndTrim(in.Arch, ",")
|
||||
)
|
||||
if len(in.Version) > 0 {
|
||||
in.Path += "/" + in.Version
|
||||
}
|
||||
// System and arch checks.
|
||||
var (
|
||||
spaceRegex = regexp.MustCompile(`\s+`)
|
||||
platformMap = make(map[string]map[string]bool)
|
||||
)
|
||||
for _, line := range strings.Split(strings.TrimSpace(cBuildPlatforms), "\n") {
|
||||
line = gstr.Trim(line)
|
||||
line = spaceRegex.ReplaceAllString(line, " ")
|
||||
var (
|
||||
array = strings.Split(line, " ")
|
||||
system = strings.TrimSpace(array[0])
|
||||
arch = strings.TrimSpace(array[1])
|
||||
)
|
||||
if platformMap[system] == nil {
|
||||
platformMap[system] = make(map[string]bool)
|
||||
}
|
||||
platformMap[system][arch] = true
|
||||
}
|
||||
// Auto packing.
|
||||
if in.PackSrc != "" {
|
||||
if in.PackDst == "" {
|
||||
mlog.Fatal(`parameter "packDst" should not be empty when "packSrc" is used`)
|
||||
}
|
||||
if gfile.Exists(in.PackDst) && !gfile.IsFile(in.PackDst) {
|
||||
mlog.Fatalf(`parameter "packDst" path "%s" should be type of file not directory`, in.PackDst)
|
||||
}
|
||||
if !gfile.Exists(in.PackDst) {
|
||||
// Remove the go file that is automatically packed resource.
|
||||
defer func() {
|
||||
_ = gfile.Remove(in.PackDst)
|
||||
mlog.Printf(`remove the automatically generated resource go file: %s`, in.PackDst)
|
||||
}()
|
||||
}
|
||||
// remove black space in separator.
|
||||
in.PackSrc, _ = gregex.ReplaceString(`,\s+`, `,`, in.PackSrc)
|
||||
packCmd := fmt.Sprintf(`gf pack %s %s --keepPath=true`, in.PackSrc, in.PackDst)
|
||||
mlog.Print(packCmd)
|
||||
gproc.MustShellRun(ctx, packCmd)
|
||||
}
|
||||
|
||||
// Injected information by building flags.
|
||||
ldFlags := fmt.Sprintf(
|
||||
`-X 'github.com/gogf/gf/v2/os/gbuild.builtInVarStr=%v'`,
|
||||
c.getBuildInVarStr(ctx, in),
|
||||
)
|
||||
|
||||
// start building
|
||||
mlog.Print("start building...")
|
||||
if in.Cgo {
|
||||
genv.MustSet("CGO_ENABLED", "1")
|
||||
} else {
|
||||
genv.MustSet("CGO_ENABLED", "0")
|
||||
}
|
||||
var (
|
||||
cmd = ""
|
||||
ext = ""
|
||||
)
|
||||
for system, item := range platformMap {
|
||||
cmd = ""
|
||||
ext = ""
|
||||
if len(customSystems) > 0 && customSystems[0] != "all" && !gstr.InArray(customSystems, system) {
|
||||
continue
|
||||
}
|
||||
for arch, _ := range item {
|
||||
if len(customArches) > 0 && customArches[0] != "all" && !gstr.InArray(customArches, arch) {
|
||||
continue
|
||||
}
|
||||
if len(customSystems) == 0 && len(customArches) == 0 {
|
||||
if runtime.GOOS == "windows" {
|
||||
ext = ".exe"
|
||||
}
|
||||
// Single binary building, output the binary to current working folder.
|
||||
output := ""
|
||||
if len(in.Output) > 0 {
|
||||
output = "-o " + in.Output + ext
|
||||
} else {
|
||||
output = "-o " + in.Name + ext
|
||||
}
|
||||
cmd = fmt.Sprintf(`go build %s -ldflags "%s" %s %s`, output, ldFlags, in.Extra, file)
|
||||
} else {
|
||||
// Cross-building, output the compiled binary to specified path.
|
||||
if system == "windows" {
|
||||
ext = ".exe"
|
||||
}
|
||||
genv.MustSet("GOOS", system)
|
||||
genv.MustSet("GOARCH", arch)
|
||||
cmd = fmt.Sprintf(
|
||||
`go build -o %s/%s/%s%s -ldflags "%s" %s%s`,
|
||||
in.Path, system+"_"+arch, in.Name, ext, ldFlags, in.Extra, file,
|
||||
)
|
||||
}
|
||||
mlog.Debug(cmd)
|
||||
// It's not necessary printing the complete command string.
|
||||
cmdShow, _ := gregex.ReplaceString(`\s+(-ldflags ".+?")\s+`, " ", cmd)
|
||||
mlog.Print(cmdShow)
|
||||
if result, err := gproc.ShellExec(ctx, cmd); err != nil {
|
||||
mlog.Printf(
|
||||
"failed to build, os:%s, arch:%s, error:\n%s\n\n%s\n",
|
||||
system, arch, gstr.Trim(result),
|
||||
`you may use command option "--debug" to enable debug info and check the details`,
|
||||
)
|
||||
if in.ExitWhenError {
|
||||
os.Exit(1)
|
||||
}
|
||||
} else {
|
||||
mlog.Debug(gstr.Trim(result))
|
||||
}
|
||||
// single binary building.
|
||||
if len(customSystems) == 0 && len(customArches) == 0 {
|
||||
goto buildDone
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
buildDone:
|
||||
mlog.Print("done!")
|
||||
return
|
||||
}
|
||||
|
||||
// getBuildInVarMapJson retrieves and returns the custom build-in variables in configuration
|
||||
// file as json.
|
||||
func (c cBuild) getBuildInVarStr(ctx context.Context, in cBuildInput) string {
|
||||
buildInVarMap := in.VarMap
|
||||
if buildInVarMap == nil {
|
||||
buildInVarMap = make(g.Map)
|
||||
}
|
||||
buildInVarMap["builtGit"] = c.getGitCommit(ctx)
|
||||
buildInVarMap["builtTime"] = gtime.Now().String()
|
||||
b, err := json.Marshal(buildInVarMap)
|
||||
if err != nil {
|
||||
mlog.Fatal(err)
|
||||
}
|
||||
return gbase64.EncodeToString(b)
|
||||
}
|
||||
|
||||
// getGitCommit retrieves and returns the latest git commit hash string if present.
|
||||
func (c cBuild) getGitCommit(ctx context.Context) string {
|
||||
if gproc.SearchBinary("git") == "" {
|
||||
return ""
|
||||
}
|
||||
var (
|
||||
cmd = `git log -1 --format="%cd %H" --date=format:"%Y-%m-%d %H:%M:%S"`
|
||||
s, _ = gproc.ShellExec(ctx, cmd)
|
||||
)
|
||||
mlog.Debug(cmd)
|
||||
if s != "" {
|
||||
if !gstr.Contains(s, "fatal") {
|
||||
return gstr.Trim(s)
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
163
server/internal/library/hggen/internal/cmd/cmd_docker.go
Normal file
163
server/internal/library/hggen/internal/cmd/cmd_docker.go
Normal file
@@ -0,0 +1,163 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"runtime"
|
||||
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gfile"
|
||||
"github.com/gogf/gf/v2/os/gproc"
|
||||
"github.com/gogf/gf/v2/text/gstr"
|
||||
"github.com/gogf/gf/v2/util/gtag"
|
||||
|
||||
"hotgo/internal/library/hggen/internal/utility/mlog"
|
||||
)
|
||||
|
||||
var (
|
||||
Docker = cDocker{}
|
||||
)
|
||||
|
||||
type cDocker struct {
|
||||
g.Meta `name:"docker" usage:"{cDockerUsage}" brief:"{cDockerBrief}" eg:"{cDockerEg}" dc:"{cDockerDc}"`
|
||||
}
|
||||
|
||||
const (
|
||||
cDockerUsage = `gf docker [MAIN] [OPTION]`
|
||||
cDockerBrief = `build docker image for current GoFrame project`
|
||||
cDockerEg = `
|
||||
gf docker
|
||||
gf docker -t hub.docker.com/john/image:tag
|
||||
gf docker -p -t hub.docker.com/john/image:tag
|
||||
gf docker main.go
|
||||
gf docker main.go -t hub.docker.com/john/image:tag
|
||||
gf docker main.go -t hub.docker.com/john/image:tag
|
||||
gf docker main.go -p -t hub.docker.com/john/image:tag
|
||||
`
|
||||
cDockerDc = `
|
||||
The "docker" command builds the GF project to a docker images.
|
||||
It runs "gf build" firstly to compile the project to binary file.
|
||||
It then runs "docker build" command automatically to generate the docker image.
|
||||
You should have docker installed, and there must be a Dockerfile in the root of the project.
|
||||
`
|
||||
cDockerMainBrief = `main file path for "gf build", it's "main.go" in default. empty string for no binary build`
|
||||
cDockerBuildBrief = `binary build options before docker image build, it's "-a amd64 -s linux" in default`
|
||||
cDockerFileBrief = `file path of the Dockerfile. it's "manifest/docker/Dockerfile" in default`
|
||||
cDockerShellBrief = `path of the shell file which is executed before docker build`
|
||||
cDockerPushBrief = `auto push the docker image to docker registry if "-t" option passed`
|
||||
cDockerTagNameBrief = `tag name for this docker, pattern like "image:tag". this option is required with TagPrefixes`
|
||||
cDockerTagPrefixesBrief = `tag prefixes for this docker, which are used for docker push. this option is required with TagName`
|
||||
cDockerExtraBrief = `extra build options passed to "docker image"`
|
||||
)
|
||||
|
||||
func init() {
|
||||
gtag.Sets(g.MapStrStr{
|
||||
`cDockerUsage`: cDockerUsage,
|
||||
`cDockerBrief`: cDockerBrief,
|
||||
`cDockerEg`: cDockerEg,
|
||||
`cDockerDc`: cDockerDc,
|
||||
`cDockerMainBrief`: cDockerMainBrief,
|
||||
`cDockerFileBrief`: cDockerFileBrief,
|
||||
`cDockerShellBrief`: cDockerShellBrief,
|
||||
`cDockerBuildBrief`: cDockerBuildBrief,
|
||||
`cDockerPushBrief`: cDockerPushBrief,
|
||||
`cDockerTagNameBrief`: cDockerTagNameBrief,
|
||||
`cDockerTagPrefixesBrief`: cDockerTagPrefixesBrief,
|
||||
`cDockerExtraBrief`: cDockerExtraBrief,
|
||||
})
|
||||
}
|
||||
|
||||
type cDockerInput struct {
|
||||
g.Meta `name:"docker" config:"gfcli.docker"`
|
||||
Main string `name:"MAIN" arg:"true" brief:"{cDockerMainBrief}" d:"main.go"`
|
||||
File string `name:"file" short:"f" brief:"{cDockerFileBrief}" d:"manifest/docker/Dockerfile"`
|
||||
Shell string `name:"shell" short:"s" brief:"{cDockerShellBrief}" d:"manifest/docker/docker.sh"`
|
||||
Build string `name:"build" short:"b" brief:"{cDockerBuildBrief}" d:"-a amd64 -s linux"`
|
||||
TagName string `name:"tagName" short:"tn" brief:"{cDockerTagNameBrief}" v:"required-with:TagPrefixes"`
|
||||
TagPrefixes []string `name:"tagPrefixes" short:"tp" brief:"{cDockerTagPrefixesBrief}" v:"required-with:TagName"`
|
||||
Push bool `name:"push" short:"p" brief:"{cDockerPushBrief}" orphan:"true"`
|
||||
Extra string `name:"extra" short:"e" brief:"{cDockerExtraBrief}"`
|
||||
}
|
||||
|
||||
type cDockerOutput struct{}
|
||||
|
||||
func (c cDocker) Index(ctx context.Context, in cDockerInput) (out *cDockerOutput, err error) {
|
||||
// Necessary check.
|
||||
if gproc.SearchBinary("docker") == "" {
|
||||
mlog.Fatalf(`command "docker" not found in your environment, please install docker first to proceed this command`)
|
||||
}
|
||||
|
||||
// Binary build.
|
||||
in.Build += " --exit"
|
||||
if in.Main != "" {
|
||||
if err = gproc.ShellRun(ctx, fmt.Sprintf(`gf build %s %s`, in.Main, in.Build)); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Shell executing.
|
||||
if in.Shell != "" && gfile.Exists(in.Shell) {
|
||||
if err = c.exeDockerShell(ctx, in.Shell); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
// Docker build.
|
||||
var (
|
||||
dockerBuildOptions string
|
||||
dockerTags []string
|
||||
dockerTagBase string
|
||||
)
|
||||
if len(in.TagPrefixes) > 0 {
|
||||
for _, tagPrefix := range in.TagPrefixes {
|
||||
tagPrefix = gstr.TrimRight(tagPrefix, "/")
|
||||
dockerTags = append(dockerTags, fmt.Sprintf(`%s/%s`, tagPrefix, in.TagName))
|
||||
}
|
||||
}
|
||||
if len(dockerTags) == 0 {
|
||||
dockerTags = []string{""}
|
||||
}
|
||||
for i, dockerTag := range dockerTags {
|
||||
if i > 0 {
|
||||
err = gproc.ShellRun(ctx, fmt.Sprintf(`docker tag %s %s`, dockerTagBase, dockerTag))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
continue
|
||||
}
|
||||
dockerTagBase = dockerTag
|
||||
dockerBuildOptions = ""
|
||||
if dockerTag != "" {
|
||||
dockerBuildOptions = fmt.Sprintf(`-t %s`, dockerTag)
|
||||
}
|
||||
if in.Extra != "" {
|
||||
dockerBuildOptions = fmt.Sprintf(`%s %s`, dockerBuildOptions, in.Extra)
|
||||
}
|
||||
err = gproc.ShellRun(ctx, fmt.Sprintf(`docker build -f %s . %s`, in.File, dockerBuildOptions))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Docker push.
|
||||
if !in.Push {
|
||||
return
|
||||
}
|
||||
for _, dockerTag := range dockerTags {
|
||||
if dockerTag == "" {
|
||||
continue
|
||||
}
|
||||
err = gproc.ShellRun(ctx, fmt.Sprintf(`docker push %s`, dockerTag))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (c cDocker) exeDockerShell(ctx context.Context, shellFilePath string) error {
|
||||
if gfile.ExtName(shellFilePath) == "sh" && runtime.GOOS == "windows" {
|
||||
mlog.Debugf(`ignore shell file "%s", as it cannot be run on windows system`, shellFilePath)
|
||||
return nil
|
||||
}
|
||||
return gproc.ShellRun(ctx, gfile.GetContents(shellFilePath))
|
||||
}
|
||||
63
server/internal/library/hggen/internal/cmd/cmd_env.go
Normal file
63
server/internal/library/hggen/internal/cmd/cmd_env.go
Normal file
@@ -0,0 +1,63 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gproc"
|
||||
"github.com/gogf/gf/v2/text/gregex"
|
||||
"github.com/gogf/gf/v2/text/gstr"
|
||||
"github.com/olekukonko/tablewriter"
|
||||
|
||||
"hotgo/internal/library/hggen/internal/utility/mlog"
|
||||
)
|
||||
|
||||
var (
|
||||
Env = cEnv{}
|
||||
)
|
||||
|
||||
type cEnv struct {
|
||||
g.Meta `name:"env" brief:"show current Golang environment variables"`
|
||||
}
|
||||
|
||||
type cEnvInput struct {
|
||||
g.Meta `name:"env"`
|
||||
}
|
||||
|
||||
type cEnvOutput struct{}
|
||||
|
||||
func (c cEnv) Index(ctx context.Context, in cEnvInput) (out *cEnvOutput, err error) {
|
||||
result, err := gproc.ShellExec(ctx, "go env")
|
||||
if err != nil {
|
||||
mlog.Fatal(err)
|
||||
}
|
||||
if result == "" {
|
||||
mlog.Fatal(`retrieving Golang environment variables failed, did you install Golang?`)
|
||||
}
|
||||
var (
|
||||
lines = gstr.Split(result, "\n")
|
||||
buffer = bytes.NewBuffer(nil)
|
||||
)
|
||||
array := make([][]string, 0)
|
||||
for _, line := range lines {
|
||||
line = gstr.Trim(line)
|
||||
if line == "" {
|
||||
continue
|
||||
}
|
||||
if gstr.Pos(line, "set ") == 0 {
|
||||
line = line[4:]
|
||||
}
|
||||
match, _ := gregex.MatchString(`(.+?)=(.*)`, line)
|
||||
if len(match) < 3 {
|
||||
mlog.Fatalf(`invalid Golang environment variable: "%s"`, line)
|
||||
}
|
||||
array = append(array, []string{gstr.Trim(match[1]), gstr.Trim(match[2])})
|
||||
}
|
||||
tw := tablewriter.NewWriter(buffer)
|
||||
tw.SetColumnAlignment([]int{tablewriter.ALIGN_LEFT, tablewriter.ALIGN_LEFT})
|
||||
tw.AppendBulk(array)
|
||||
tw.Render()
|
||||
mlog.Print(buffer.String())
|
||||
return
|
||||
}
|
||||
99
server/internal/library/hggen/internal/cmd/cmd_fix.go
Normal file
99
server/internal/library/hggen/internal/cmd/cmd_fix.go
Normal file
@@ -0,0 +1,99 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gfile"
|
||||
"github.com/gogf/gf/v2/text/gstr"
|
||||
"hotgo/internal/library/hggen/internal/utility/mlog"
|
||||
)
|
||||
|
||||
var (
|
||||
Fix = cFix{}
|
||||
)
|
||||
|
||||
type cFix struct {
|
||||
g.Meta `name:"fix" brief:"auto fixing codes after upgrading to new GoFrame version" usage:"gf fix" `
|
||||
}
|
||||
|
||||
type cFixInput struct {
|
||||
g.Meta `name:"fix"`
|
||||
}
|
||||
|
||||
type cFixOutput struct{}
|
||||
|
||||
type cFixItem struct {
|
||||
Version string
|
||||
Func func(version string) error
|
||||
}
|
||||
|
||||
func (c cFix) Index(ctx context.Context, in cFixInput) (out *cFixOutput, err error) {
|
||||
mlog.Print(`start auto fixing...`)
|
||||
defer mlog.Print(`done!`)
|
||||
err = c.doFix()
|
||||
return
|
||||
}
|
||||
|
||||
func (c cFix) doFix() (err error) {
|
||||
version, err := c.getVersion()
|
||||
if err != nil {
|
||||
mlog.Fatal(err)
|
||||
}
|
||||
if version == "" {
|
||||
mlog.Print(`no GoFrame usage found, exit fixing`)
|
||||
return
|
||||
}
|
||||
mlog.Debugf(`current GoFrame version found "%s"`, version)
|
||||
|
||||
var items = []cFixItem{
|
||||
{Version: "v2.3", Func: c.doFixV23},
|
||||
}
|
||||
for _, item := range items {
|
||||
if gstr.CompareVersionGo(version, item.Version) < 0 {
|
||||
mlog.Debugf(
|
||||
`current GoFrame version "%s" is lesser than "%s", nothing to do`,
|
||||
version, item.Version,
|
||||
)
|
||||
continue
|
||||
}
|
||||
if err = item.Func(version); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// doFixV23 fixes code when upgrading to GoFrame v2.3.
|
||||
func (c cFix) doFixV23(version string) error {
|
||||
replaceFunc := func(path, content string) string {
|
||||
content = gstr.Replace(content, "*gdb.TX", "gdb.TX")
|
||||
return content
|
||||
}
|
||||
return gfile.ReplaceDirFunc(replaceFunc, ".", "*.go", true)
|
||||
}
|
||||
|
||||
func (c cFix) getVersion() (string, error) {
|
||||
var (
|
||||
err error
|
||||
path = "go.mod"
|
||||
version string
|
||||
)
|
||||
if !gfile.Exists(path) {
|
||||
return "", gerror.Newf(`"%s" not found in current working directory`, path)
|
||||
}
|
||||
err = gfile.ReadLines(path, func(line string) error {
|
||||
array := gstr.SplitAndTrim(line, " ")
|
||||
if len(array) > 0 {
|
||||
if array[0] == gfPackage {
|
||||
version = array[1]
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
mlog.Fatal(err)
|
||||
}
|
||||
return version, nil
|
||||
}
|
||||
34
server/internal/library/hggen/internal/cmd/cmd_gen.go
Normal file
34
server/internal/library/hggen/internal/cmd/cmd_gen.go
Normal file
@@ -0,0 +1,34 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/util/gtag"
|
||||
)
|
||||
|
||||
var (
|
||||
Gen = cGen{}
|
||||
)
|
||||
|
||||
type cGen struct {
|
||||
g.Meta `name:"hggen" brief:"{cGenBrief}" dc:"{cGenDc}"`
|
||||
cGenDao
|
||||
cGenPb
|
||||
cGenPbEntity
|
||||
cGenService
|
||||
}
|
||||
|
||||
const (
|
||||
cGenBrief = `automatically generate go files for dao/do/entity/pb/pbentity`
|
||||
cGenDc = `
|
||||
The "hggen" command is designed for multiple generating purposes.
|
||||
It's currently supporting generating go files for ORM models, protobuf and protobuf entity files.
|
||||
Please use "gf hggen dao -h" for specified type help.
|
||||
`
|
||||
)
|
||||
|
||||
func init() {
|
||||
gtag.Sets(g.MapStrStr{
|
||||
`cGenBrief`: cGenBrief,
|
||||
`cGenDc`: cGenDc,
|
||||
})
|
||||
}
|
||||
15
server/internal/library/hggen/internal/cmd/cmd_gen_dao.go
Normal file
15
server/internal/library/hggen/internal/cmd/cmd_gen_dao.go
Normal file
@@ -0,0 +1,15 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
//_ "github.com/gogf/gf/contrib/drivers/mssql/v2"
|
||||
//_ "github.com/gogf/gf/contrib/drivers/mysql/v2"
|
||||
//_ "github.com/gogf/gf/contrib/drivers/oracle/v2"
|
||||
//_ "github.com/gogf/gf/contrib/drivers/pgsql/v2"
|
||||
//_ "github.com/gogf/gf/contrib/drivers/sqlite/v2"
|
||||
|
||||
"hotgo/internal/library/hggen/internal/cmd/gendao"
|
||||
)
|
||||
|
||||
type (
|
||||
cGenDao = gendao.CGenDao
|
||||
)
|
||||
79
server/internal/library/hggen/internal/cmd/cmd_gen_pb.go
Normal file
79
server/internal/library/hggen/internal/cmd/cmd_gen_pb.go
Normal file
@@ -0,0 +1,79 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/gogf/gf/v2/container/gset"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/genv"
|
||||
"github.com/gogf/gf/v2/os/gfile"
|
||||
"github.com/gogf/gf/v2/os/gproc"
|
||||
"hotgo/internal/library/hggen/internal/utility/mlog"
|
||||
)
|
||||
|
||||
type (
|
||||
cGenPb struct{}
|
||||
cGenPbInput struct {
|
||||
g.Meta `name:"pb" brief:"parse proto files and generate protobuf go files"`
|
||||
}
|
||||
cGenPbOutput struct{}
|
||||
)
|
||||
|
||||
func (c cGenPb) Pb(ctx context.Context, in cGenPbInput) (out *cGenPbOutput, err error) {
|
||||
// Necessary check.
|
||||
if gproc.SearchBinary("protoc") == "" {
|
||||
mlog.Fatalf(`command "protoc" not found in your environment, please install protoc first to proceed this command`)
|
||||
}
|
||||
|
||||
// protocol fold checks.
|
||||
protoFolder := "protocol"
|
||||
if !gfile.Exists(protoFolder) {
|
||||
mlog.Fatalf(`proto files folder "%s" does not exist`, protoFolder)
|
||||
}
|
||||
// folder scanning.
|
||||
files, err := gfile.ScanDirFile(protoFolder, "*.proto", true)
|
||||
if err != nil {
|
||||
mlog.Fatal(err)
|
||||
}
|
||||
if len(files) == 0 {
|
||||
mlog.Fatalf(`no proto files found in folder "%s"`, protoFolder)
|
||||
}
|
||||
dirSet := gset.NewStrSet()
|
||||
for _, file := range files {
|
||||
dirSet.Add(gfile.Dir(file))
|
||||
}
|
||||
var (
|
||||
servicePath = gfile.RealPath(".")
|
||||
goPathSrc = gfile.RealPath(gfile.Join(genv.Get("GOPATH").String(), "src"))
|
||||
)
|
||||
dirSet.Iterator(func(protoDirPath string) bool {
|
||||
parsingCommand := fmt.Sprintf(
|
||||
"protoc --gofast_out=plugins=grpc:. %s/*.proto -I%s",
|
||||
protoDirPath,
|
||||
servicePath,
|
||||
)
|
||||
if goPathSrc != "" {
|
||||
parsingCommand += " -I" + goPathSrc
|
||||
}
|
||||
mlog.Print(parsingCommand)
|
||||
if output, err := gproc.ShellExec(ctx, parsingCommand); err != nil {
|
||||
mlog.Print(output)
|
||||
mlog.Fatal(err)
|
||||
}
|
||||
return true
|
||||
})
|
||||
// Custom replacement.
|
||||
//pbFolder := "protobuf"
|
||||
//_, _ = gfile.ScanDirFileFunc(pbFolder, "*.go", true, func(path string) string {
|
||||
// content := gfile.GetContents(path)
|
||||
// content = gstr.ReplaceByArray(content, g.SliceStr{
|
||||
// `gtime "gtime"`, `gtime "github.com/gogf/gf/v2/os/gtime"`,
|
||||
// })
|
||||
// _ = gfile.PutContents(path, content)
|
||||
// utils.GoFmt(path)
|
||||
// return path
|
||||
//})
|
||||
mlog.Print("done!")
|
||||
return
|
||||
}
|
||||
411
server/internal/library/hggen/internal/cmd/cmd_gen_pbentity.go
Normal file
411
server/internal/library/hggen/internal/cmd/cmd_gen_pbentity.go
Normal file
@@ -0,0 +1,411 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/gogf/gf/v2/database/gdb"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gfile"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
"github.com/gogf/gf/v2/text/gregex"
|
||||
"github.com/gogf/gf/v2/text/gstr"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
"github.com/gogf/gf/v2/util/gtag"
|
||||
"github.com/olekukonko/tablewriter"
|
||||
|
||||
"hotgo/internal/library/hggen/internal/consts"
|
||||
"hotgo/internal/library/hggen/internal/utility/mlog"
|
||||
)
|
||||
|
||||
type (
|
||||
cGenPbEntity struct{}
|
||||
cGenPbEntityInput struct {
|
||||
g.Meta `name:"pbentity" config:"{cGenPbEntityConfig}" brief:"{cGenPbEntityBrief}" eg:"{cGenPbEntityEg}" ad:"{cGenPbEntityAd}"`
|
||||
Path string `name:"path" short:"p" brief:"{cGenPbEntityBriefPath}"`
|
||||
Package string `name:"package" short:"k" brief:"{cGenPbEntityBriefPackage}"`
|
||||
Link string `name:"link" short:"l" brief:"{cGenPbEntityBriefLink}"`
|
||||
Tables string `name:"tables" short:"t" brief:"{cGenPbEntityBriefTables}"`
|
||||
Prefix string `name:"prefix" short:"f" brief:"{cGenPbEntityBriefPrefix}"`
|
||||
RemovePrefix string `name:"removePrefix" short:"r" brief:"{cGenPbEntityBriefRemovePrefix}"`
|
||||
NameCase string `name:"nameCase" short:"n" brief:"{cGenPbEntityBriefNameCase}" d:"Camel"`
|
||||
JsonCase string `name:"jsonCase" short:"j" brief:"{cGenPbEntityBriefJsonCase}" d:"CamelLower"`
|
||||
Option string `name:"option" short:"o" brief:"{cGenPbEntityBriefOption}"`
|
||||
}
|
||||
cGenPbEntityOutput struct{}
|
||||
|
||||
cGenPbEntityInternalInput struct {
|
||||
cGenPbEntityInput
|
||||
TableName string // TableName specifies the table name of the table.
|
||||
NewTableName string // NewTableName specifies the prefix-stripped name of the table.
|
||||
}
|
||||
)
|
||||
|
||||
const (
|
||||
cGenPbEntityConfig = `gfcli.hggen.pbentity`
|
||||
cGenPbEntityBrief = `generate entity message files in protobuf3 format`
|
||||
cGenPbEntityEg = `
|
||||
gf hggen pbentity
|
||||
gf hggen pbentity -l "mysql:root:12345678@tcp(127.0.0.1:3306)/test"
|
||||
gf hggen pbentity -p ./protocol/demos/entity -t user,user_detail,user_login
|
||||
gf hggen pbentity -r user_
|
||||
`
|
||||
|
||||
cGenPbEntityAd = `
|
||||
CONFIGURATION SUPPORT
|
||||
Options are also supported by configuration file.
|
||||
It's suggested using configuration file instead of command line arguments making producing.
|
||||
The configuration node name is "gf.hggen.pbentity", which also supports multiple databases, for example(config.yaml):
|
||||
gfcli:
|
||||
hggen:
|
||||
- pbentity:
|
||||
link: "mysql:root:12345678@tcp(127.0.0.1:3306)/test"
|
||||
path: "protocol/demos/entity"
|
||||
tables: "order,products"
|
||||
package: "demos"
|
||||
- pbentity:
|
||||
link: "mysql:root:12345678@tcp(127.0.0.1:3306)/primary"
|
||||
path: "protocol/demos/entity"
|
||||
prefix: "primary_"
|
||||
tables: "user, userDetail"
|
||||
package: "demos"
|
||||
option: |
|
||||
option go_package = "protobuf/demos";
|
||||
option java_package = "protobuf/demos";
|
||||
option php_namespace = "protobuf/demos";
|
||||
`
|
||||
cGenPbEntityBriefPath = `directory path for generated files`
|
||||
cGenPbEntityBriefPackage = `package name for all entity proto files`
|
||||
cGenPbEntityBriefLink = `database configuration, the same as the ORM configuration of GoFrame`
|
||||
cGenPbEntityBriefTables = `generate models only for given tables, multiple table names separated with ','`
|
||||
cGenPbEntityBriefPrefix = `add specified prefix for all entity names and entity proto files`
|
||||
cGenPbEntityBriefRemovePrefix = `remove specified prefix of the table, multiple prefix separated with ','`
|
||||
cGenPbEntityBriefOption = `extra protobuf options`
|
||||
cGenPbEntityBriefGroup = `
|
||||
specifying the configuration group name of database for generated ORM instance,
|
||||
it's not necessary and the default value is "default"
|
||||
`
|
||||
|
||||
cGenPbEntityBriefNameCase = `
|
||||
case for message attribute names, default is "Camel":
|
||||
| Case | Example |
|
||||
|---------------- |--------------------|
|
||||
| Camel | AnyKindOfString |
|
||||
| CamelLower | anyKindOfString | default
|
||||
| Snake | any_kind_of_string |
|
||||
| SnakeScreaming | ANY_KIND_OF_STRING |
|
||||
| SnakeFirstUpper | rgb_code_md5 |
|
||||
| Kebab | any-kind-of-string |
|
||||
| KebabScreaming | ANY-KIND-OF-STRING |
|
||||
`
|
||||
|
||||
cGenPbEntityBriefJsonCase = `
|
||||
case for message json tag, cases are the same as "nameCase", default "CamelLower".
|
||||
set it to "none" to ignore json tag generating.
|
||||
`
|
||||
)
|
||||
|
||||
func init() {
|
||||
gtag.Sets(g.MapStrStr{
|
||||
`cGenPbEntityConfig`: cGenPbEntityConfig,
|
||||
`cGenPbEntityBrief`: cGenPbEntityBrief,
|
||||
`cGenPbEntityEg`: cGenPbEntityEg,
|
||||
`cGenPbEntityAd`: cGenPbEntityAd,
|
||||
`cGenPbEntityBriefPath`: cGenPbEntityBriefPath,
|
||||
`cGenPbEntityBriefPackage`: cGenPbEntityBriefPackage,
|
||||
`cGenPbEntityBriefLink`: cGenPbEntityBriefLink,
|
||||
`cGenPbEntityBriefTables`: cGenPbEntityBriefTables,
|
||||
`cGenPbEntityBriefPrefix`: cGenPbEntityBriefPrefix,
|
||||
`cGenPbEntityBriefRemovePrefix`: cGenPbEntityBriefRemovePrefix,
|
||||
`cGenPbEntityBriefGroup`: cGenPbEntityBriefGroup,
|
||||
`cGenPbEntityBriefNameCase`: cGenPbEntityBriefNameCase,
|
||||
`cGenPbEntityBriefJsonCase`: cGenPbEntityBriefJsonCase,
|
||||
`cGenPbEntityBriefOption`: cGenPbEntityBriefOption,
|
||||
})
|
||||
}
|
||||
|
||||
func (c cGenPbEntity) PbEntity(ctx context.Context, in cGenPbEntityInput) (out *cGenPbEntityOutput, err error) {
|
||||
var (
|
||||
config = g.Cfg()
|
||||
)
|
||||
if config.Available(ctx) {
|
||||
v := config.MustGet(ctx, cGenPbEntityConfig)
|
||||
if v.IsSlice() {
|
||||
for i := 0; i < len(v.Interfaces()); i++ {
|
||||
doGenPbEntityForArray(ctx, i, in)
|
||||
}
|
||||
} else {
|
||||
doGenPbEntityForArray(ctx, -1, in)
|
||||
}
|
||||
} else {
|
||||
doGenPbEntityForArray(ctx, -1, in)
|
||||
}
|
||||
mlog.Print("done!")
|
||||
return
|
||||
}
|
||||
|
||||
func doGenPbEntityForArray(ctx context.Context, index int, in cGenPbEntityInput) {
|
||||
var (
|
||||
err error
|
||||
db gdb.DB
|
||||
)
|
||||
if index >= 0 {
|
||||
err = g.Cfg().MustGet(
|
||||
ctx,
|
||||
fmt.Sprintf(`%s.%d`, cGenPbEntityConfig, index),
|
||||
).Scan(&in)
|
||||
if err != nil {
|
||||
mlog.Fatalf(`invalid configuration of "%s": %+v`, cGenPbEntityConfig, err)
|
||||
}
|
||||
}
|
||||
if in.Package == "" {
|
||||
mlog.Fatal("package name should not be empty")
|
||||
}
|
||||
removePrefixArray := gstr.SplitAndTrim(in.RemovePrefix, ",")
|
||||
// It uses user passed database configuration.
|
||||
if in.Link != "" {
|
||||
var (
|
||||
tempGroup = gtime.TimestampNanoStr()
|
||||
match, _ = gregex.MatchString(`([a-z]+):(.+)`, in.Link)
|
||||
)
|
||||
if len(match) == 3 {
|
||||
gdb.AddConfigNode(tempGroup, gdb.ConfigNode{
|
||||
Type: gstr.Trim(match[1]),
|
||||
Link: gstr.Trim(match[2]),
|
||||
})
|
||||
db, _ = gdb.Instance(tempGroup)
|
||||
}
|
||||
} else {
|
||||
db = g.DB()
|
||||
}
|
||||
if db == nil {
|
||||
mlog.Fatal("database initialization failed")
|
||||
}
|
||||
|
||||
tableNames := ([]string)(nil)
|
||||
if in.Tables != "" {
|
||||
tableNames = gstr.SplitAndTrim(in.Tables, ",")
|
||||
} else {
|
||||
tableNames, err = db.Tables(context.TODO())
|
||||
if err != nil {
|
||||
mlog.Fatalf("fetching tables failed: \n %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
for _, tableName := range tableNames {
|
||||
newTableName := tableName
|
||||
for _, v := range removePrefixArray {
|
||||
newTableName = gstr.TrimLeftStr(newTableName, v, 1)
|
||||
}
|
||||
generatePbEntityContentFile(ctx, db, cGenPbEntityInternalInput{
|
||||
cGenPbEntityInput: in,
|
||||
TableName: tableName,
|
||||
NewTableName: newTableName,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// generatePbEntityContentFile generates the protobuf files for given table.
|
||||
func generatePbEntityContentFile(ctx context.Context, db gdb.DB, in cGenPbEntityInternalInput) {
|
||||
fieldMap, err := db.TableFields(ctx, in.TableName)
|
||||
if err != nil {
|
||||
mlog.Fatalf("fetching tables fields failed for table '%s':\n%v", in.TableName, err)
|
||||
}
|
||||
// Change the `newTableName` if `Prefix` is given.
|
||||
newTableName := "Entity_" + in.Prefix + in.NewTableName
|
||||
var (
|
||||
tableNameCamelCase = gstr.CaseCamel(newTableName)
|
||||
tableNameSnakeCase = gstr.CaseSnake(newTableName)
|
||||
entityMessageDefine = generateEntityMessageDefinition(tableNameCamelCase, fieldMap, in)
|
||||
fileName = gstr.Trim(tableNameSnakeCase, "-_.")
|
||||
path = gfile.Join(in.Path, fileName+".proto")
|
||||
)
|
||||
entityContent := gstr.ReplaceByMap(getTplPbEntityContent(""), g.MapStrStr{
|
||||
"{PackageName}": in.Package,
|
||||
"{OptionContent}": in.Option,
|
||||
"{EntityMessage}": entityMessageDefine,
|
||||
})
|
||||
if err := gfile.PutContents(path, strings.TrimSpace(entityContent)); err != nil {
|
||||
mlog.Fatalf("writing content to '%s' failed: %v", path, err)
|
||||
} else {
|
||||
mlog.Print("generated:", path)
|
||||
}
|
||||
}
|
||||
|
||||
// generateEntityMessageDefinition generates and returns the message definition for specified table.
|
||||
func generateEntityMessageDefinition(entityName string, fieldMap map[string]*gdb.TableField, in cGenPbEntityInternalInput) string {
|
||||
var (
|
||||
buffer = bytes.NewBuffer(nil)
|
||||
array = make([][]string, len(fieldMap))
|
||||
names = sortFieldKeyForPbEntity(fieldMap)
|
||||
)
|
||||
for index, name := range names {
|
||||
array[index] = generateMessageFieldForPbEntity(index+1, fieldMap[name], in)
|
||||
}
|
||||
tw := tablewriter.NewWriter(buffer)
|
||||
tw.SetBorder(false)
|
||||
tw.SetRowLine(false)
|
||||
tw.SetAutoWrapText(false)
|
||||
tw.SetColumnSeparator("")
|
||||
tw.AppendBulk(array)
|
||||
tw.Render()
|
||||
stContent := buffer.String()
|
||||
// Let's do this hack of table writer for indent!
|
||||
stContent = gstr.Replace(stContent, " #", "")
|
||||
buffer.Reset()
|
||||
buffer.WriteString(fmt.Sprintf("message %s {\n", entityName))
|
||||
buffer.WriteString(stContent)
|
||||
buffer.WriteString("}")
|
||||
return buffer.String()
|
||||
}
|
||||
|
||||
// generateMessageFieldForPbEntity generates and returns the message definition for specified field.
|
||||
func generateMessageFieldForPbEntity(index int, field *gdb.TableField, in cGenPbEntityInternalInput) []string {
|
||||
var (
|
||||
typeName string
|
||||
comment string
|
||||
jsonTagStr string
|
||||
)
|
||||
t, _ := gregex.ReplaceString(`\(.+\)`, "", field.Type)
|
||||
t = gstr.Split(gstr.Trim(t), " ")[0]
|
||||
t = gstr.ToLower(t)
|
||||
switch t {
|
||||
case "binary", "varbinary", "blob", "tinyblob", "mediumblob", "longblob":
|
||||
typeName = "bytes"
|
||||
|
||||
case "bit", "int", "tinyint", "small_int", "smallint", "medium_int", "mediumint", "serial":
|
||||
if gstr.ContainsI(field.Type, "unsigned") {
|
||||
typeName = "uint32"
|
||||
} else {
|
||||
typeName = "int32"
|
||||
}
|
||||
|
||||
case "int8", "big_int", "bigint", "bigserial":
|
||||
if gstr.ContainsI(field.Type, "unsigned") {
|
||||
typeName = "uint64"
|
||||
} else {
|
||||
typeName = "int64"
|
||||
}
|
||||
|
||||
case "real":
|
||||
typeName = "float"
|
||||
|
||||
case "float", "double", "decimal", "smallmoney":
|
||||
typeName = "double"
|
||||
|
||||
case "bool":
|
||||
typeName = "bool"
|
||||
|
||||
case "datetime", "timestamp", "date", "time":
|
||||
typeName = "int64"
|
||||
|
||||
default:
|
||||
// Auto detecting type.
|
||||
switch {
|
||||
case strings.Contains(t, "int"):
|
||||
typeName = "int"
|
||||
case strings.Contains(t, "text") || strings.Contains(t, "char"):
|
||||
typeName = "string"
|
||||
case strings.Contains(t, "float") || strings.Contains(t, "double"):
|
||||
typeName = "double"
|
||||
case strings.Contains(t, "bool"):
|
||||
typeName = "bool"
|
||||
case strings.Contains(t, "binary") || strings.Contains(t, "blob"):
|
||||
typeName = "bytes"
|
||||
case strings.Contains(t, "date") || strings.Contains(t, "time"):
|
||||
typeName = "int64"
|
||||
default:
|
||||
typeName = "string"
|
||||
}
|
||||
}
|
||||
comment = gstr.ReplaceByArray(field.Comment, g.SliceStr{
|
||||
"\n", " ",
|
||||
"\r", " ",
|
||||
})
|
||||
comment = gstr.Trim(comment)
|
||||
comment = gstr.Replace(comment, `\n`, " ")
|
||||
comment, _ = gregex.ReplaceString(`\s{2,}`, ` `, comment)
|
||||
if jsonTagName := formatCase(field.Name, in.JsonCase); jsonTagName != "" {
|
||||
jsonTagStr = fmt.Sprintf(`[(gogoproto.jsontag) = "%s"]`, jsonTagName)
|
||||
// beautiful indent.
|
||||
if index < 10 {
|
||||
// 3 spaces
|
||||
jsonTagStr = " " + jsonTagStr
|
||||
} else if index < 100 {
|
||||
// 2 spaces
|
||||
jsonTagStr = " " + jsonTagStr
|
||||
} else {
|
||||
// 1 spaces
|
||||
jsonTagStr = " " + jsonTagStr
|
||||
}
|
||||
}
|
||||
return []string{
|
||||
" #" + typeName,
|
||||
" #" + formatCase(field.Name, in.NameCase),
|
||||
" #= " + gconv.String(index) + jsonTagStr + ";",
|
||||
" #" + fmt.Sprintf(`// %s`, comment),
|
||||
}
|
||||
}
|
||||
|
||||
func getTplPbEntityContent(tplEntityPath string) string {
|
||||
if tplEntityPath != "" {
|
||||
return gfile.GetContents(tplEntityPath)
|
||||
}
|
||||
return consts.TemplatePbEntityMessageContent
|
||||
}
|
||||
|
||||
// formatCase call gstr.Case* function to convert the s to specified case.
|
||||
func formatCase(str, caseStr string) string {
|
||||
switch gstr.ToLower(caseStr) {
|
||||
case gstr.ToLower("Camel"):
|
||||
return gstr.CaseCamel(str)
|
||||
|
||||
case gstr.ToLower("CamelLower"):
|
||||
return gstr.CaseCamelLower(str)
|
||||
|
||||
case gstr.ToLower("Kebab"):
|
||||
return gstr.CaseKebab(str)
|
||||
|
||||
case gstr.ToLower("KebabScreaming"):
|
||||
return gstr.CaseKebabScreaming(str)
|
||||
|
||||
case gstr.ToLower("Snake"):
|
||||
return gstr.CaseSnake(str)
|
||||
|
||||
case gstr.ToLower("SnakeFirstUpper"):
|
||||
return gstr.CaseSnakeFirstUpper(str)
|
||||
|
||||
case gstr.ToLower("SnakeScreaming"):
|
||||
return gstr.CaseSnakeScreaming(str)
|
||||
|
||||
case "none":
|
||||
return ""
|
||||
}
|
||||
return str
|
||||
}
|
||||
|
||||
func sortFieldKeyForPbEntity(fieldMap map[string]*gdb.TableField) []string {
|
||||
names := make(map[int]string)
|
||||
for _, field := range fieldMap {
|
||||
names[field.Index] = field.Name
|
||||
}
|
||||
var (
|
||||
result = make([]string, len(names))
|
||||
i = 0
|
||||
j = 0
|
||||
)
|
||||
for {
|
||||
if len(names) == 0 {
|
||||
break
|
||||
}
|
||||
if val, ok := names[i]; ok {
|
||||
result[j] = val
|
||||
j++
|
||||
delete(names, i)
|
||||
}
|
||||
i++
|
||||
}
|
||||
return result
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"hotgo/internal/library/hggen/internal/cmd/genservice"
|
||||
)
|
||||
|
||||
type (
|
||||
cGenService = genservice.CGenService
|
||||
)
|
||||
126
server/internal/library/hggen/internal/cmd/cmd_init.go
Normal file
126
server/internal/library/hggen/internal/cmd/cmd_init.go
Normal file
@@ -0,0 +1,126 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gcmd"
|
||||
"github.com/gogf/gf/v2/os/gfile"
|
||||
"github.com/gogf/gf/v2/os/gproc"
|
||||
"github.com/gogf/gf/v2/os/gres"
|
||||
"github.com/gogf/gf/v2/util/gtag"
|
||||
|
||||
"hotgo/internal/library/hggen/internal/utility/allyes"
|
||||
"hotgo/internal/library/hggen/internal/utility/mlog"
|
||||
)
|
||||
|
||||
var (
|
||||
Init = cInit{}
|
||||
)
|
||||
|
||||
type cInit struct {
|
||||
g.Meta `name:"init" brief:"{cInitBrief}" eg:"{cInitEg}"`
|
||||
}
|
||||
|
||||
const (
|
||||
cInitRepoPrefix = `github.com/gogf/`
|
||||
cInitMonoRepo = `template-mono`
|
||||
cInitSingleRepo = `template-single`
|
||||
cInitBrief = `create and initialize an empty GoFrame project`
|
||||
cInitEg = `
|
||||
gf init my-project
|
||||
gf init my-mono-repo -m
|
||||
`
|
||||
cInitNameBrief = `
|
||||
name for the project. It will create a folder with NAME in current directory.
|
||||
The NAME will also be the module name for the project.
|
||||
`
|
||||
)
|
||||
|
||||
func init() {
|
||||
gtag.Sets(g.MapStrStr{
|
||||
`cInitBrief`: cInitBrief,
|
||||
`cInitEg`: cInitEg,
|
||||
`cInitNameBrief`: cInitNameBrief,
|
||||
})
|
||||
}
|
||||
|
||||
type cInitInput struct {
|
||||
g.Meta `name:"init"`
|
||||
Name string `name:"NAME" arg:"true" v:"required" brief:"{cInitNameBrief}"`
|
||||
Mono bool `name:"mono" short:"m" brief:"initialize a mono-repo instead a single-repo" orphan:"true"`
|
||||
Update bool `name:"update" short:"u" brief:"update to the latest goframe version" orphan:"true"`
|
||||
}
|
||||
|
||||
type cInitOutput struct{}
|
||||
|
||||
func (c cInit) Index(ctx context.Context, in cInitInput) (out *cInitOutput, err error) {
|
||||
if !gfile.IsEmpty(in.Name) && !allyes.Check() {
|
||||
s := gcmd.Scanf(`the folder "%s" is not empty, files might be overwrote, continue? [y/n]: `, in.Name)
|
||||
if strings.EqualFold(s, "n") {
|
||||
return
|
||||
}
|
||||
}
|
||||
mlog.Print("initializing...")
|
||||
|
||||
// Create project folder and files.
|
||||
var (
|
||||
templateRepoName string
|
||||
)
|
||||
if in.Mono {
|
||||
templateRepoName = cInitMonoRepo
|
||||
} else {
|
||||
templateRepoName = cInitSingleRepo
|
||||
}
|
||||
err = gres.Export(templateRepoName, in.Name, gres.ExportOption{
|
||||
RemovePrefix: templateRepoName,
|
||||
})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Replace template name to project name.
|
||||
err = gfile.ReplaceDir(
|
||||
cInitRepoPrefix+templateRepoName,
|
||||
gfile.Basename(gfile.RealPath(in.Name)),
|
||||
in.Name,
|
||||
"*",
|
||||
true,
|
||||
)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Update the GoFrame version.
|
||||
if in.Update {
|
||||
mlog.Print("update goframe...")
|
||||
// go get -u github.com/gogf/gf/v2@latest
|
||||
updateCommand := `go get -u github.com/gogf/gf/v2@latest`
|
||||
if in.Name != "." {
|
||||
updateCommand = fmt.Sprintf(`cd %s && %s`, in.Name, updateCommand)
|
||||
}
|
||||
if err = gproc.ShellRun(ctx, updateCommand); err != nil {
|
||||
mlog.Fatal(err)
|
||||
}
|
||||
// go mod tidy
|
||||
gomModTidyCommand := `go mod tidy`
|
||||
if in.Name != "." {
|
||||
gomModTidyCommand = fmt.Sprintf(`cd %s && %s`, in.Name, gomModTidyCommand)
|
||||
}
|
||||
if err = gproc.ShellRun(ctx, gomModTidyCommand); err != nil {
|
||||
mlog.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
mlog.Print("initialization done! ")
|
||||
if !in.Mono {
|
||||
enjoyCommand := `gf run main.go`
|
||||
if in.Name != "." {
|
||||
enjoyCommand = fmt.Sprintf(`cd %s && %s`, in.Name, enjoyCommand)
|
||||
}
|
||||
mlog.Printf(`you can now run "%s" to start your journey, enjoy!`, enjoyCommand)
|
||||
}
|
||||
return
|
||||
}
|
||||
28
server/internal/library/hggen/internal/cmd/cmd_install.go
Normal file
28
server/internal/library/hggen/internal/cmd/cmd_install.go
Normal file
@@ -0,0 +1,28 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
|
||||
"hotgo/internal/library/hggen/internal/service"
|
||||
)
|
||||
|
||||
var (
|
||||
Install = cInstall{}
|
||||
)
|
||||
|
||||
type cInstall struct {
|
||||
g.Meta `name:"install" brief:"install gf binary to system (might need root/admin permission)"`
|
||||
}
|
||||
|
||||
type cInstallInput struct {
|
||||
g.Meta `name:"install"`
|
||||
}
|
||||
|
||||
type cInstallOutput struct{}
|
||||
|
||||
func (c cInstall) Index(ctx context.Context, in cInstallInput) (out *cInstallOutput, err error) {
|
||||
err = service.Install.Run(ctx)
|
||||
return
|
||||
}
|
||||
98
server/internal/library/hggen/internal/cmd/cmd_pack.go
Normal file
98
server/internal/library/hggen/internal/cmd/cmd_pack.go
Normal file
@@ -0,0 +1,98 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gcmd"
|
||||
"github.com/gogf/gf/v2/os/gfile"
|
||||
"github.com/gogf/gf/v2/os/gres"
|
||||
"github.com/gogf/gf/v2/util/gtag"
|
||||
|
||||
"hotgo/internal/library/hggen/internal/utility/allyes"
|
||||
"hotgo/internal/library/hggen/internal/utility/mlog"
|
||||
)
|
||||
|
||||
var (
|
||||
Pack = cPack{}
|
||||
)
|
||||
|
||||
type cPack struct {
|
||||
g.Meta `name:"pack" usage:"{cPackUsage}" brief:"{cPackBrief}" eg:"{cPackEg}"`
|
||||
}
|
||||
|
||||
const (
|
||||
cPackUsage = `gf pack SRC DST`
|
||||
cPackBrief = `packing any file/directory to a resource file, or a go file`
|
||||
cPackEg = `
|
||||
gf pack public data.bin
|
||||
gf pack public,template data.bin
|
||||
gf pack public,template packed/data.go
|
||||
gf pack public,template,config packed/data.go
|
||||
gf pack public,template,config packed/data.go -n=packed -p=/var/www/my-app
|
||||
gf pack /var/www/public packed/data.go -n=packed
|
||||
`
|
||||
cPackSrcBrief = `source path for packing, which can be multiple source paths.`
|
||||
cPackDstBrief = `
|
||||
destination file path for packed file. if extension of the filename is ".go" and "-n" option is given,
|
||||
it enables packing SRC to go file, or else it packs SRC into a binary file.
|
||||
`
|
||||
cPackNameBrief = `package name for output go file, it's set as its directory name if no name passed`
|
||||
cPackPrefixBrief = `prefix for each file packed into the resource file`
|
||||
cPackKeepPathBrief = `keep the source path from system to resource file, usually for relative path`
|
||||
)
|
||||
|
||||
func init() {
|
||||
gtag.Sets(g.MapStrStr{
|
||||
`cPackUsage`: cPackUsage,
|
||||
`cPackBrief`: cPackBrief,
|
||||
`cPackEg`: cPackEg,
|
||||
`cPackSrcBrief`: cPackSrcBrief,
|
||||
`cPackDstBrief`: cPackDstBrief,
|
||||
`cPackNameBrief`: cPackNameBrief,
|
||||
`cPackPrefixBrief`: cPackPrefixBrief,
|
||||
`cPackKeepPathBrief`: cPackKeepPathBrief,
|
||||
})
|
||||
}
|
||||
|
||||
type cPackInput struct {
|
||||
g.Meta `name:"pack"`
|
||||
Src string `name:"SRC" arg:"true" v:"required" brief:"{cPackSrcBrief}"`
|
||||
Dst string `name:"DST" arg:"true" v:"required" brief:"{cPackDstBrief}"`
|
||||
Name string `name:"name" short:"n" brief:"{cPackNameBrief}"`
|
||||
Prefix string `name:"prefix" short:"p" brief:"{cPackPrefixBrief}"`
|
||||
KeepPath bool `name:"keepPath" short:"k" brief:"{cPackKeepPathBrief}" orphan:"true"`
|
||||
}
|
||||
|
||||
type cPackOutput struct{}
|
||||
|
||||
func (c cPack) Index(ctx context.Context, in cPackInput) (out *cPackOutput, err error) {
|
||||
if gfile.Exists(in.Dst) && gfile.IsDir(in.Dst) {
|
||||
mlog.Fatalf("DST path '%s' cannot be a directory", in.Dst)
|
||||
}
|
||||
if !gfile.IsEmpty(in.Dst) && !allyes.Check() {
|
||||
s := gcmd.Scanf("path '%s' is not empty, files might be overwrote, continue? [y/n]: ", in.Dst)
|
||||
if strings.EqualFold(s, "n") {
|
||||
return
|
||||
}
|
||||
}
|
||||
if in.Name == "" && gfile.ExtName(in.Dst) == "go" {
|
||||
in.Name = gfile.Basename(gfile.Dir(in.Dst))
|
||||
}
|
||||
var option = gres.Option{
|
||||
Prefix: in.Prefix,
|
||||
KeepPath: in.KeepPath,
|
||||
}
|
||||
if in.Name != "" {
|
||||
if err = gres.PackToGoFileWithOption(in.Src, in.Dst, in.Name, option); err != nil {
|
||||
mlog.Fatalf("pack failed: %v", err)
|
||||
}
|
||||
} else {
|
||||
if err = gres.PackToFileWithOption(in.Src, in.Dst, option); err != nil {
|
||||
mlog.Fatalf("pack failed: %v", err)
|
||||
}
|
||||
}
|
||||
mlog.Print("done!")
|
||||
return
|
||||
}
|
||||
166
server/internal/library/hggen/internal/cmd/cmd_run.go
Normal file
166
server/internal/library/hggen/internal/cmd/cmd_run.go
Normal file
@@ -0,0 +1,166 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"runtime"
|
||||
|
||||
"github.com/gogf/gf/v2/container/gtype"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gfile"
|
||||
"github.com/gogf/gf/v2/os/gfsnotify"
|
||||
"github.com/gogf/gf/v2/os/gproc"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
"github.com/gogf/gf/v2/os/gtimer"
|
||||
"github.com/gogf/gf/v2/util/gtag"
|
||||
|
||||
"hotgo/internal/library/hggen/internal/utility/mlog"
|
||||
)
|
||||
|
||||
var (
|
||||
Run = cRun{}
|
||||
)
|
||||
|
||||
type cRun struct {
|
||||
g.Meta `name:"run" usage:"{cRunUsage}" brief:"{cRunBrief}" eg:"{cRunEg}" dc:"{cRunDc}"`
|
||||
}
|
||||
|
||||
type cRunApp struct {
|
||||
File string // Go run file name.
|
||||
Path string // Directory storing built binary.
|
||||
Options string // Extra "go run" options.
|
||||
Args string // Custom arguments.
|
||||
}
|
||||
|
||||
const (
|
||||
cRunUsage = `gf run FILE [OPTION]`
|
||||
cRunBrief = `running go codes with hot-compiled-like feature`
|
||||
cRunEg = `
|
||||
gf run main.go
|
||||
gf run main.go --args "server -p 8080"
|
||||
gf run main.go -mod=vendor
|
||||
`
|
||||
cRunDc = `
|
||||
The "run" command is used for running go codes with hot-compiled-like feature,
|
||||
which compiles and runs the go codes asynchronously when codes change.
|
||||
`
|
||||
cRunFileBrief = `building file path.`
|
||||
cRunPathBrief = `output directory path for built binary file. it's "manifest/output" in default`
|
||||
cRunExtraBrief = `the same options as "go run"/"go build" except some options as follows defined`
|
||||
cRunArgsBrief = `custom arguments for your process`
|
||||
)
|
||||
|
||||
var (
|
||||
process *gproc.Process
|
||||
)
|
||||
|
||||
func init() {
|
||||
gtag.Sets(g.MapStrStr{
|
||||
`cRunUsage`: cRunUsage,
|
||||
`cRunBrief`: cRunBrief,
|
||||
`cRunEg`: cRunEg,
|
||||
`cRunDc`: cRunDc,
|
||||
`cRunFileBrief`: cRunFileBrief,
|
||||
`cRunPathBrief`: cRunPathBrief,
|
||||
`cRunExtraBrief`: cRunExtraBrief,
|
||||
`cRunArgsBrief`: cRunArgsBrief,
|
||||
})
|
||||
}
|
||||
|
||||
type (
|
||||
cRunInput struct {
|
||||
g.Meta `name:"run"`
|
||||
File string `name:"FILE" arg:"true" brief:"{cRunFileBrief}" v:"required"`
|
||||
Path string `name:"path" short:"p" brief:"{cRunPathBrief}" d:"./"`
|
||||
Extra string `name:"extra" short:"e" brief:"{cRunExtraBrief}"`
|
||||
Args string `name:"args" short:"a" brief:"{cRunArgsBrief}"`
|
||||
}
|
||||
cRunOutput struct{}
|
||||
)
|
||||
|
||||
func (c cRun) Index(ctx context.Context, in cRunInput) (out *cRunOutput, err error) {
|
||||
// Necessary check.
|
||||
if gproc.SearchBinary("go") == "" {
|
||||
mlog.Fatalf(`command "go" not found in your environment, please install golang first to proceed this command`)
|
||||
}
|
||||
|
||||
app := &cRunApp{
|
||||
File: in.File,
|
||||
Path: in.Path,
|
||||
Options: in.Extra,
|
||||
Args: in.Args,
|
||||
}
|
||||
dirty := gtype.NewBool()
|
||||
_, err = gfsnotify.Add(gfile.RealPath("."), func(event *gfsnotify.Event) {
|
||||
if gfile.ExtName(event.Path) != "go" {
|
||||
return
|
||||
}
|
||||
// Variable `dirty` is used for running the changes only one in one second.
|
||||
if !dirty.Cas(false, true) {
|
||||
return
|
||||
}
|
||||
// With some delay in case of multiple code changes in very short interval.
|
||||
gtimer.SetTimeout(ctx, 1500*gtime.MS, func(ctx context.Context) {
|
||||
defer dirty.Set(false)
|
||||
mlog.Printf(`go file changes: %s`, event.String())
|
||||
app.Run(ctx)
|
||||
})
|
||||
})
|
||||
if err != nil {
|
||||
mlog.Fatal(err)
|
||||
}
|
||||
go app.Run(ctx)
|
||||
select {}
|
||||
}
|
||||
|
||||
func (app *cRunApp) Run(ctx context.Context) {
|
||||
// Rebuild and run the codes.
|
||||
renamePath := ""
|
||||
mlog.Printf("build: %s", app.File)
|
||||
outputPath := gfile.Join(app.Path, gfile.Name(app.File))
|
||||
if runtime.GOOS == "windows" {
|
||||
outputPath += ".exe"
|
||||
if gfile.Exists(outputPath) {
|
||||
renamePath = outputPath + "~"
|
||||
if err := gfile.Rename(outputPath, renamePath); err != nil {
|
||||
mlog.Print(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
// In case of `pipe: too many open files` error.
|
||||
// Build the app.
|
||||
buildCommand := fmt.Sprintf(
|
||||
`go build -o %s %s %s`,
|
||||
outputPath,
|
||||
app.Options,
|
||||
app.File,
|
||||
)
|
||||
mlog.Print(buildCommand)
|
||||
result, err := gproc.ShellExec(ctx, buildCommand)
|
||||
if err != nil {
|
||||
mlog.Printf("build error: \n%s%s", result, err.Error())
|
||||
return
|
||||
}
|
||||
// Kill the old process if build successfully.
|
||||
if process != nil {
|
||||
if err := process.Kill(); err != nil {
|
||||
mlog.Debugf("kill process error: %s", err.Error())
|
||||
//return
|
||||
}
|
||||
}
|
||||
// Run the binary file.
|
||||
runCommand := fmt.Sprintf(`%s %s`, outputPath, app.Args)
|
||||
mlog.Print(runCommand)
|
||||
if runtime.GOOS == "windows" {
|
||||
// Special handling for windows platform.
|
||||
// DO NOT USE "cmd /c" command.
|
||||
process = gproc.NewProcess(runCommand, nil)
|
||||
} else {
|
||||
process = gproc.NewProcessCmd(runCommand, nil)
|
||||
}
|
||||
if pid, err := process.Start(ctx); err != nil {
|
||||
mlog.Printf("build running error: %s", err.Error())
|
||||
} else {
|
||||
mlog.Printf("build running pid: %d", pid)
|
||||
}
|
||||
}
|
||||
168
server/internal/library/hggen/internal/cmd/cmd_tpl.go
Normal file
168
server/internal/library/hggen/internal/cmd/cmd_tpl.go
Normal file
@@ -0,0 +1,168 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"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/gfile"
|
||||
"github.com/gogf/gf/v2/text/gstr"
|
||||
"github.com/gogf/gf/v2/util/gtag"
|
||||
"github.com/gogf/gf/v2/util/gutil"
|
||||
|
||||
"hotgo/internal/library/hggen/internal/utility/mlog"
|
||||
)
|
||||
|
||||
var (
|
||||
Tpl = cTpl{}
|
||||
)
|
||||
|
||||
type cTpl struct {
|
||||
g.Meta `name:"tpl" brief:"{cTplBrief}" dc:"{cTplDc}"`
|
||||
}
|
||||
|
||||
const (
|
||||
cTplBrief = `template parsing and building commands`
|
||||
cTplDc = `
|
||||
The "tpl" command is used for template parsing and building purpose.
|
||||
It can parse either template file or folder with multiple types of values support,
|
||||
like json/xml/yaml/toml/ini.
|
||||
`
|
||||
cTplParseBrief = `parse either template file or folder with multiple types of values`
|
||||
cTplParseEg = `
|
||||
gf tpl parse -p ./template -v values.json -r
|
||||
gf tpl parse -p ./template -v values.json -n *.tpl -r
|
||||
gf tpl parse -p ./template -v values.json -d '${,}}' -r
|
||||
gf tpl parse -p ./template -v values.json -o ./template.parsed
|
||||
`
|
||||
cTplSupportValuesFilePattern = `*.json,*.xml,*.yaml,*.yml,*.toml,*.ini`
|
||||
)
|
||||
|
||||
type (
|
||||
cTplParseInput struct {
|
||||
g.Meta `name:"parse" brief:"{cTplParseBrief}" eg:"{cTplParseEg}"`
|
||||
Path string `name:"path" short:"p" brief:"template file or folder path" v:"required"`
|
||||
Pattern string `name:"pattern" short:"n" brief:"template file pattern when path is a folder, default is:*" d:"*"`
|
||||
Recursive bool `name:"recursive" short:"c" brief:"recursively parsing files if path is folder, default is:true" d:"true"`
|
||||
Values string `name:"values" short:"v" brief:"template values file/folder, support file types like: json/xml/yaml/toml/ini" v:"required"`
|
||||
Output string `name:"output" short:"o" brief:"output file/folder path"`
|
||||
Delimiters string `name:"delimiters" short:"d" brief:"delimiters for template content parsing, default is:{{,}}" d:"{{,}}"`
|
||||
Replace bool `name:"replace" short:"r" brief:"replace original files" orphan:"true"`
|
||||
}
|
||||
cTplParseOutput struct{}
|
||||
)
|
||||
|
||||
func init() {
|
||||
gtag.Sets(g.MapStrStr{
|
||||
`cTplBrief`: cTplBrief,
|
||||
`cTplDc`: cTplDc,
|
||||
`cTplParseEg`: cTplParseEg,
|
||||
`cTplParseBrief`: cTplParseBrief,
|
||||
})
|
||||
}
|
||||
|
||||
func (c *cTpl) Parse(ctx context.Context, in cTplParseInput) (out *cTplParseOutput, err error) {
|
||||
if in.Output == "" && in.Replace == false {
|
||||
return nil, gerror.New(`parameter output and replace should not be both empty`)
|
||||
}
|
||||
delimiters := gstr.SplitAndTrim(in.Delimiters, ",")
|
||||
mlog.Debugf("delimiters input:%s, parsed:%#v", in.Delimiters, delimiters)
|
||||
if len(delimiters) != 2 {
|
||||
return nil, gerror.Newf(`invalid delimiters: %s`, in.Delimiters)
|
||||
}
|
||||
g.View().SetDelimiters(delimiters[0], delimiters[1])
|
||||
valuesMap, err := c.loadValues(ctx, in.Values)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(valuesMap) == 0 {
|
||||
return nil, gerror.Newf(`empty values loaded from values file/folder "%s"`, in.Values)
|
||||
}
|
||||
err = c.parsePath(ctx, valuesMap, in)
|
||||
if err == nil {
|
||||
mlog.Print("done!")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (c *cTpl) parsePath(ctx context.Context, values g.Map, in cTplParseInput) (err error) {
|
||||
if !gfile.Exists(in.Path) {
|
||||
return gerror.Newf(`path "%s" does not exist`, in.Path)
|
||||
}
|
||||
var (
|
||||
path string
|
||||
files []string
|
||||
relativePath string
|
||||
outputPath string
|
||||
)
|
||||
path = gfile.RealPath(in.Path)
|
||||
if gfile.IsDir(path) {
|
||||
files, err = gfile.ScanDirFile(path, in.Pattern, in.Recursive)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, file := range files {
|
||||
relativePath = gstr.Replace(file, path, "")
|
||||
if in.Output != "" {
|
||||
outputPath = gfile.Join(in.Output, relativePath)
|
||||
}
|
||||
if err = c.parseFile(ctx, file, outputPath, values, in); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
if in.Output != "" {
|
||||
outputPath = in.Output
|
||||
}
|
||||
err = c.parseFile(ctx, path, outputPath, values, in)
|
||||
return
|
||||
}
|
||||
|
||||
func (c *cTpl) parseFile(ctx context.Context, file string, output string, values g.Map, in cTplParseInput) (err error) {
|
||||
output = gstr.ReplaceByMap(output, g.MapStrStr{
|
||||
`\\`: `\`,
|
||||
`//`: `/`,
|
||||
})
|
||||
content, err := g.View().Parse(ctx, file, values)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if output != "" {
|
||||
mlog.Printf(`parse file "%s" to "%s"`, file, output)
|
||||
return gfile.PutContents(output, content)
|
||||
}
|
||||
if in.Replace {
|
||||
mlog.Printf(`parse and replace file "%s"`, file)
|
||||
return gfile.PutContents(file, content)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *cTpl) loadValues(ctx context.Context, valuesPath string) (data g.Map, err error) {
|
||||
if !gfile.Exists(valuesPath) {
|
||||
return nil, gerror.Newf(`values file/folder "%s" does not exist`, valuesPath)
|
||||
}
|
||||
var j *gjson.Json
|
||||
if gfile.IsDir(valuesPath) {
|
||||
var valueFiles []string
|
||||
valueFiles, err = gfile.ScanDirFile(valuesPath, cTplSupportValuesFilePattern, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
data = make(g.Map)
|
||||
for _, file := range valueFiles {
|
||||
if j, err = gjson.Load(file); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
gutil.MapMerge(data, j.Map())
|
||||
}
|
||||
return
|
||||
}
|
||||
if j, err = gjson.Load(valuesPath); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
data = j.Map()
|
||||
return
|
||||
}
|
||||
121
server/internal/library/hggen/internal/cmd/cmd_up.go
Normal file
121
server/internal/library/hggen/internal/cmd/cmd_up.go
Normal file
@@ -0,0 +1,121 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gfile"
|
||||
"github.com/gogf/gf/v2/os/gproc"
|
||||
"github.com/gogf/gf/v2/text/gstr"
|
||||
"github.com/gogf/gf/v2/util/gtag"
|
||||
"hotgo/internal/library/hggen/internal/utility/mlog"
|
||||
)
|
||||
|
||||
var (
|
||||
Up = cUp{}
|
||||
)
|
||||
|
||||
type cUp struct {
|
||||
g.Meta `name:"up" brief:"upgrade GoFrame version/tool to latest one in current project" eg:"{cUpEg}" `
|
||||
}
|
||||
|
||||
const (
|
||||
gfPackage = `github.com/gogf/gf/v2`
|
||||
cUpEg = `
|
||||
gf up
|
||||
gf up -a
|
||||
gf up -c
|
||||
gf up -f -c
|
||||
`
|
||||
)
|
||||
|
||||
func init() {
|
||||
gtag.Sets(g.MapStrStr{
|
||||
`cUpEg`: cUpEg,
|
||||
})
|
||||
}
|
||||
|
||||
type cUpInput struct {
|
||||
g.Meta `name:"up" config:"gfcli.up"`
|
||||
All bool `name:"all" short:"a" brief:"upgrade both version and cli, auto fix codes" orphan:"true"`
|
||||
Fix bool `name:"fix" short:"f" brief:"auto fix codes" orphan:"true"`
|
||||
Cli bool `name:"cli" short:"c" brief:"also upgrade CLI tool (not supported yet)" orphan:"true"`
|
||||
}
|
||||
|
||||
type cUpOutput struct{}
|
||||
|
||||
func (c cUp) Index(ctx context.Context, in cUpInput) (out *cUpOutput, err error) {
|
||||
defer mlog.Print(`done!`)
|
||||
|
||||
if in.All {
|
||||
in.Cli = true
|
||||
in.Fix = true
|
||||
}
|
||||
if err = c.doUpgradeVersion(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if in.Fix {
|
||||
if err = c.doAutoFixing(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
//if in.Cli {
|
||||
// if err = c.doUpgradeCLI(ctx); err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
//}
|
||||
return
|
||||
}
|
||||
|
||||
func (c cUp) doUpgradeVersion(ctx context.Context) (err error) {
|
||||
mlog.Print(`start upgrading version...`)
|
||||
|
||||
var (
|
||||
dir = gfile.Pwd()
|
||||
temp string
|
||||
path = gfile.Join(dir, "go.mod")
|
||||
)
|
||||
for {
|
||||
if gfile.Exists(path) {
|
||||
var packages []string
|
||||
err = gfile.ReadLines(path, func(line string) error {
|
||||
line = gstr.Trim(line)
|
||||
if gstr.HasPrefix(line, gfPackage) {
|
||||
pkg := gstr.Explode(" ", line)[0]
|
||||
packages = append(packages, pkg)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
for _, pkg := range packages {
|
||||
mlog.Printf(`upgrading %s`, pkg)
|
||||
command := fmt.Sprintf(`go get -u %s@latest`, pkg)
|
||||
if err = gproc.ShellRun(ctx, command); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
temp = gfile.Dir(dir)
|
||||
if temp == "" || temp == dir {
|
||||
return
|
||||
}
|
||||
dir = temp
|
||||
path = gfile.Join(dir, "go.mod")
|
||||
}
|
||||
}
|
||||
|
||||
func (c cUp) doUpgradeCLI(ctx context.Context) (err error) {
|
||||
mlog.Print(`start upgrading cli...`)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (c cUp) doAutoFixing(ctx context.Context) (err error) {
|
||||
mlog.Print(`start auto fixing...`)
|
||||
err = cFix{}.doFix()
|
||||
return
|
||||
}
|
||||
89
server/internal/library/hggen/internal/cmd/cmd_version.go
Normal file
89
server/internal/library/hggen/internal/cmd/cmd_version.go
Normal file
@@ -0,0 +1,89 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/gogf/gf/v2"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gbuild"
|
||||
"github.com/gogf/gf/v2/os/gfile"
|
||||
"github.com/gogf/gf/v2/text/gregex"
|
||||
"github.com/gogf/gf/v2/text/gstr"
|
||||
|
||||
"hotgo/internal/library/hggen/internal/utility/mlog"
|
||||
)
|
||||
|
||||
var (
|
||||
Version = cVersion{}
|
||||
)
|
||||
|
||||
type cVersion struct {
|
||||
g.Meta `name:"version" brief:"show version information of current binary"`
|
||||
}
|
||||
|
||||
type cVersionInput struct {
|
||||
g.Meta `name:"version"`
|
||||
}
|
||||
|
||||
type cVersionOutput struct{}
|
||||
|
||||
func (c cVersion) Index(ctx context.Context, in cVersionInput) (*cVersionOutput, error) {
|
||||
info := gbuild.Info()
|
||||
if info.Git == "" {
|
||||
info.Git = "none"
|
||||
}
|
||||
mlog.Printf(`GoFrame CLI Tool %s, https://goframe.org`, gf.VERSION)
|
||||
gfVersion, err := c.getGFVersionOfCurrentProject()
|
||||
if err != nil {
|
||||
gfVersion = err.Error()
|
||||
} else {
|
||||
gfVersion = gfVersion + " in current go.mod"
|
||||
}
|
||||
mlog.Printf(`GoFrame Version: %s`, gfVersion)
|
||||
mlog.Printf(`CLI Installed At: %s`, gfile.SelfPath())
|
||||
if info.GoFrame == "" {
|
||||
mlog.Print(`Current is a custom installed version, no installation information.`)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
mlog.Print(gstr.Trim(fmt.Sprintf(`
|
||||
CLI Built Detail:
|
||||
Go Version: %s
|
||||
GF Version: %s
|
||||
Git Commit: %s
|
||||
Build Time: %s
|
||||
`, info.Golang, info.GoFrame, info.Git, info.Time)))
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// getGFVersionOfCurrentProject checks and returns the GoFrame version current project using.
|
||||
func (c cVersion) getGFVersionOfCurrentProject() (string, error) {
|
||||
goModPath := gfile.Join(gfile.Pwd(), "go.mod")
|
||||
if gfile.Exists(goModPath) {
|
||||
lines := gstr.SplitAndTrim(gfile.GetContents(goModPath), "\n")
|
||||
for _, line := range lines {
|
||||
line = gstr.Trim(line)
|
||||
// Version 1.
|
||||
match, err := gregex.MatchString(`^github\.com/gogf/gf\s+(.+)$`, line)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if len(match) <= 1 {
|
||||
// Version > 1.
|
||||
match, err = gregex.MatchString(`^github\.com/gogf/gf/v\d\s+(.+)$`, line)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
if len(match) > 1 {
|
||||
return gstr.Trim(match[1]), nil
|
||||
}
|
||||
}
|
||||
|
||||
return "", gerror.New("cannot find goframe requirement in go.mod")
|
||||
} else {
|
||||
return "", gerror.New("cannot find go.mod")
|
||||
}
|
||||
}
|
||||
380
server/internal/library/hggen/internal/cmd/gendao/gendao.go
Normal file
380
server/internal/library/hggen/internal/cmd/gendao/gendao.go
Normal file
@@ -0,0 +1,380 @@
|
||||
package gendao
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/gogf/gf/v2/container/garray"
|
||||
"github.com/gogf/gf/v2/database/gdb"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gfile"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
"github.com/gogf/gf/v2/text/gregex"
|
||||
"github.com/gogf/gf/v2/text/gstr"
|
||||
"github.com/gogf/gf/v2/util/gtag"
|
||||
|
||||
"hotgo/internal/library/hggen/internal/utility/mlog"
|
||||
)
|
||||
|
||||
const (
|
||||
CGenDaoConfig = `gfcli.hggen.dao`
|
||||
CGenDaoUsage = `gf hggen dao [OPTION]`
|
||||
CGenDaoBrief = `automatically generate go files for dao/do/entity`
|
||||
CGenDaoEg = `
|
||||
gf hggen dao
|
||||
gf hggen dao -l "mysql:root:12345678@tcp(127.0.0.1:3306)/test"
|
||||
gf hggen dao -p ./model -g user-center -t user,user_detail,user_login
|
||||
gf hggen dao -r user_
|
||||
`
|
||||
|
||||
CGenDaoAd = `
|
||||
CONFIGURATION SUPPORT
|
||||
Options are also supported by configuration file.
|
||||
It's suggested using configuration file instead of command line arguments making producing.
|
||||
The configuration node name is "gfcli.hggen.dao", which also supports multiple databases, for example(config.yaml):
|
||||
gfcli:
|
||||
hggen:
|
||||
dao:
|
||||
- link: "mysql:root:12345678@tcp(127.0.0.1:3306)/test"
|
||||
tables: "order,products"
|
||||
jsonCase: "CamelLower"
|
||||
- link: "mysql:root:12345678@tcp(127.0.0.1:3306)/primary"
|
||||
path: "./my-app"
|
||||
prefix: "primary_"
|
||||
tables: "user, userDetail"
|
||||
`
|
||||
CGenDaoBriefPath = `directory path for generated files`
|
||||
CGenDaoBriefLink = `database configuration, the same as the ORM configuration of GoFrame`
|
||||
CGenDaoBriefTables = `generate models only for given tables, multiple table names separated with ','`
|
||||
CGenDaoBriefTablesEx = `generate models excluding given tables, multiple table names separated with ','`
|
||||
CGenDaoBriefPrefix = `add prefix for all table of specified link/database tables`
|
||||
CGenDaoBriefRemovePrefix = `remove specified prefix of the table, multiple prefix separated with ','`
|
||||
CGenDaoBriefStdTime = `use time.Time from stdlib instead of gtime.Time for generated time/date fields of tables`
|
||||
CGenDaoBriefWithTime = `add created time for auto produced go files`
|
||||
CGenDaoBriefGJsonSupport = `use gJsonSupport to use *gjson.Json instead of string for generated json fields of tables`
|
||||
CGenDaoBriefImportPrefix = `custom import prefix for generated go files`
|
||||
CGenDaoBriefDaoPath = `directory path for storing generated dao files under path`
|
||||
CGenDaoBriefDoPath = `directory path for storing generated do files under path`
|
||||
CGenDaoBriefEntityPath = `directory path for storing generated entity files under path`
|
||||
CGenDaoBriefOverwriteDao = `overwrite all dao files both inside/outside internal folder`
|
||||
CGenDaoBriefModelFile = `custom file name for storing generated model content`
|
||||
CGenDaoBriefModelFileForDao = `custom file name generating model for DAO operations like Where/Data. It's empty in default`
|
||||
CGenDaoBriefDescriptionTag = `add comment to description tag for each field`
|
||||
CGenDaoBriefNoJsonTag = `no json tag will be added for each field`
|
||||
CGenDaoBriefNoModelComment = `no model comment will be added for each field`
|
||||
CGenDaoBriefClear = `delete all generated go files that do not exist in database`
|
||||
CGenDaoBriefGroup = `
|
||||
specifying the configuration group name of database for generated ORM instance,
|
||||
it's not necessary and the default value is "default"
|
||||
`
|
||||
CGenDaoBriefJsonCase = `
|
||||
generated json tag case for model struct, cases are as follows:
|
||||
| Case | Example |
|
||||
|---------------- |--------------------|
|
||||
| Camel | AnyKindOfString |
|
||||
| CamelLower | anyKindOfString | default
|
||||
| Snake | any_kind_of_string |
|
||||
| SnakeScreaming | ANY_KIND_OF_STRING |
|
||||
| SnakeFirstUpper | rgb_code_md5 |
|
||||
| Kebab | any-kind-of-string |
|
||||
| KebabScreaming | ANY-KIND-OF-STRING |
|
||||
`
|
||||
CGenDaoBriefTplDaoIndexPath = `template file path for dao index file`
|
||||
CGenDaoBriefTplDaoInternalPath = `template file path for dao internal file`
|
||||
CGenDaoBriefTplDaoDoPathPath = `template file path for dao do file`
|
||||
CGenDaoBriefTplDaoEntityPath = `template file path for dao entity file`
|
||||
|
||||
tplVarTableName = `{TplTableName}`
|
||||
tplVarTableNameCamelCase = `{TplTableNameCamelCase}`
|
||||
tplVarTableNameCamelLowerCase = `{TplTableNameCamelLowerCase}`
|
||||
tplVarPackageImports = `{TplPackageImports}`
|
||||
tplVarImportPrefix = `{TplImportPrefix}`
|
||||
tplVarStructDefine = `{TplStructDefine}`
|
||||
tplVarColumnDefine = `{TplColumnDefine}`
|
||||
tplVarColumnNames = `{TplColumnNames}`
|
||||
tplVarGroupName = `{TplGroupName}`
|
||||
tplVarDatetimeStr = `{TplDatetimeStr}`
|
||||
tplVarCreatedAtDatetimeStr = `{TplCreatedAtDatetimeStr}`
|
||||
)
|
||||
|
||||
var (
|
||||
createdAt = gtime.Now()
|
||||
)
|
||||
|
||||
func init() {
|
||||
gtag.Sets(g.MapStrStr{
|
||||
`CGenDaoConfig`: CGenDaoConfig,
|
||||
`CGenDaoUsage`: CGenDaoUsage,
|
||||
`CGenDaoBrief`: CGenDaoBrief,
|
||||
`CGenDaoEg`: CGenDaoEg,
|
||||
`CGenDaoAd`: CGenDaoAd,
|
||||
`CGenDaoBriefPath`: CGenDaoBriefPath,
|
||||
`CGenDaoBriefLink`: CGenDaoBriefLink,
|
||||
`CGenDaoBriefTables`: CGenDaoBriefTables,
|
||||
`CGenDaoBriefTablesEx`: CGenDaoBriefTablesEx,
|
||||
`CGenDaoBriefPrefix`: CGenDaoBriefPrefix,
|
||||
`CGenDaoBriefRemovePrefix`: CGenDaoBriefRemovePrefix,
|
||||
`CGenDaoBriefStdTime`: CGenDaoBriefStdTime,
|
||||
`CGenDaoBriefWithTime`: CGenDaoBriefWithTime,
|
||||
`CGenDaoBriefDaoPath`: CGenDaoBriefDaoPath,
|
||||
`CGenDaoBriefDoPath`: CGenDaoBriefDoPath,
|
||||
`CGenDaoBriefEntityPath`: CGenDaoBriefEntityPath,
|
||||
`CGenDaoBriefGJsonSupport`: CGenDaoBriefGJsonSupport,
|
||||
`CGenDaoBriefImportPrefix`: CGenDaoBriefImportPrefix,
|
||||
`CGenDaoBriefOverwriteDao`: CGenDaoBriefOverwriteDao,
|
||||
`CGenDaoBriefModelFile`: CGenDaoBriefModelFile,
|
||||
`CGenDaoBriefModelFileForDao`: CGenDaoBriefModelFileForDao,
|
||||
`CGenDaoBriefDescriptionTag`: CGenDaoBriefDescriptionTag,
|
||||
`CGenDaoBriefNoJsonTag`: CGenDaoBriefNoJsonTag,
|
||||
`CGenDaoBriefNoModelComment`: CGenDaoBriefNoModelComment,
|
||||
`CGenDaoBriefClear`: CGenDaoBriefClear,
|
||||
`CGenDaoBriefGroup`: CGenDaoBriefGroup,
|
||||
`CGenDaoBriefJsonCase`: CGenDaoBriefJsonCase,
|
||||
`CGenDaoBriefTplDaoIndexPath`: CGenDaoBriefTplDaoIndexPath,
|
||||
`CGenDaoBriefTplDaoInternalPath`: CGenDaoBriefTplDaoInternalPath,
|
||||
`CGenDaoBriefTplDaoDoPathPath`: CGenDaoBriefTplDaoDoPathPath,
|
||||
`CGenDaoBriefTplDaoEntityPath`: CGenDaoBriefTplDaoEntityPath,
|
||||
})
|
||||
}
|
||||
|
||||
type (
|
||||
CGenDao struct{}
|
||||
CGenDaoInput struct {
|
||||
g.Meta `name:"dao" config:"{CGenDaoConfig}" usage:"{CGenDaoUsage}" brief:"{CGenDaoBrief}" eg:"{CGenDaoEg}" ad:"{CGenDaoAd}"`
|
||||
Path string `name:"path" short:"p" brief:"{CGenDaoBriefPath}" d:"internal"`
|
||||
Link string `name:"link" short:"l" brief:"{CGenDaoBriefLink}"`
|
||||
Tables string `name:"tables" short:"t" brief:"{CGenDaoBriefTables}"`
|
||||
TablesEx string `name:"tablesEx" short:"x" brief:"{CGenDaoBriefTablesEx}"`
|
||||
Group string `name:"group" short:"g" brief:"{CGenDaoBriefGroup}" d:"default"`
|
||||
Prefix string `name:"prefix" short:"f" brief:"{CGenDaoBriefPrefix}"`
|
||||
RemovePrefix string `name:"removePrefix" short:"r" brief:"{CGenDaoBriefRemovePrefix}"`
|
||||
JsonCase string `name:"jsonCase" short:"j" brief:"{CGenDaoBriefJsonCase}" d:"CamelLower"`
|
||||
ImportPrefix string `name:"importPrefix" short:"i" brief:"{CGenDaoBriefImportPrefix}"`
|
||||
DaoPath string `name:"daoPath" short:"d" brief:"{CGenDaoBriefDaoPath}" d:"dao"`
|
||||
DoPath string `name:"doPath" short:"o" brief:"{CGenDaoBriefDoPath}" d:"model/do"`
|
||||
EntityPath string `name:"entityPath" short:"e" brief:"{CGenDaoBriefEntityPath}" d:"model/entity"`
|
||||
TplDaoIndexPath string `name:"tplDaoIndexPath" short:"t1" brief:"{CGenDaoBriefTplDaoIndexPath}"`
|
||||
TplDaoInternalPath string `name:"tplDaoInternalPath" short:"t2" brief:"{CGenDaoBriefTplDaoInternalPath}"`
|
||||
TplDaoDoPath string `name:"tplDaoDoPath" short:"t3" brief:"{CGenDaoBriefTplDaoDoPathPath}"`
|
||||
TplDaoEntityPath string `name:"tplDaoEntityPath" short:"t4" brief:"{CGenDaoBriefTplDaoEntityPath}"`
|
||||
StdTime bool `name:"stdTime" short:"s" brief:"{CGenDaoBriefStdTime}" orphan:"true"`
|
||||
WithTime bool `name:"withTime" short:"w" brief:"{CGenDaoBriefWithTime}" orphan:"true"`
|
||||
GJsonSupport bool `name:"gJsonSupport" short:"n" brief:"{CGenDaoBriefGJsonSupport}" orphan:"true"`
|
||||
OverwriteDao bool `name:"overwriteDao" short:"v" brief:"{CGenDaoBriefOverwriteDao}" orphan:"true"`
|
||||
DescriptionTag bool `name:"descriptionTag" short:"c" brief:"{CGenDaoBriefDescriptionTag}" orphan:"true"`
|
||||
NoJsonTag bool `name:"noJsonTag" short:"k" brief:"{CGenDaoBriefNoJsonTag}" orphan:"true"`
|
||||
NoModelComment bool `name:"noModelComment" short:"m" brief:"{CGenDaoBriefNoModelComment}" orphan:"true"`
|
||||
Clear bool `name:"clear" short:"a" brief:"{CGenDaoBriefClear}" orphan:"true"`
|
||||
}
|
||||
CGenDaoOutput struct{}
|
||||
|
||||
CGenDaoInternalInput struct {
|
||||
CGenDaoInput
|
||||
DB gdb.DB
|
||||
TableNames []string
|
||||
NewTableNames []string
|
||||
ModName string // Module name of current golang project, which is used for import purpose.
|
||||
}
|
||||
)
|
||||
|
||||
func (c CGenDao) Dao(ctx context.Context, in CGenDaoInput) (out *CGenDaoOutput, err error) {
|
||||
g.Log().Warningf(ctx, "g.Cfg().Available(ctx):%v", g.Cfg().Available(ctx))
|
||||
if g.Cfg().Available(ctx) {
|
||||
v := g.Cfg().MustGet(ctx, CGenDaoConfig)
|
||||
if v.IsSlice() {
|
||||
for i := 0; i < len(v.Interfaces()); i++ {
|
||||
doGenDaoForArray(ctx, i, in)
|
||||
}
|
||||
} else {
|
||||
doGenDaoForArray(ctx, -1, in)
|
||||
}
|
||||
} else {
|
||||
doGenDaoForArray(ctx, -1, in)
|
||||
}
|
||||
mlog.Print("done!")
|
||||
return
|
||||
}
|
||||
|
||||
func DoGenDaoForArray(ctx context.Context, in CGenDaoInput) {
|
||||
doGenDaoForArray(ctx, -1, in)
|
||||
}
|
||||
|
||||
// doGenDaoForArray implements the "hggen dao" command for configuration array.
|
||||
func doGenDaoForArray(ctx context.Context, index int, in CGenDaoInput) {
|
||||
var (
|
||||
err error
|
||||
db gdb.DB
|
||||
modName string // Go module name, eg: github.com/gogf/gf.
|
||||
)
|
||||
if index >= 0 {
|
||||
err = g.Cfg().MustGet(
|
||||
ctx,
|
||||
fmt.Sprintf(`%s.%d`, CGenDaoConfig, index),
|
||||
).Scan(&in)
|
||||
if err != nil {
|
||||
mlog.Fatalf(`invalid configuration of "%s": %+v`, CGenDaoConfig, err)
|
||||
}
|
||||
}
|
||||
if dirRealPath := gfile.RealPath(in.Path); dirRealPath == "" {
|
||||
mlog.Fatalf(`path "%s" does not exist`, in.Path)
|
||||
}
|
||||
removePrefixArray := gstr.SplitAndTrim(in.RemovePrefix, ",")
|
||||
if in.ImportPrefix == "" {
|
||||
if !gfile.Exists("go.mod") {
|
||||
mlog.Fatal("go.mod does not exist in current working directory")
|
||||
}
|
||||
var (
|
||||
goModContent = gfile.GetContents("go.mod")
|
||||
match, _ = gregex.MatchString(`^module\s+(.+)\s*`, goModContent)
|
||||
)
|
||||
if len(match) > 1 {
|
||||
modName = gstr.Trim(match[1])
|
||||
} else {
|
||||
mlog.Fatal("module name does not found in go.mod")
|
||||
}
|
||||
}
|
||||
|
||||
// It uses user passed database configuration.
|
||||
if in.Link != "" {
|
||||
var tempGroup = gtime.TimestampNanoStr()
|
||||
gdb.AddConfigNode(tempGroup, gdb.ConfigNode{
|
||||
Link: in.Link,
|
||||
})
|
||||
if db, err = gdb.Instance(tempGroup); err != nil {
|
||||
mlog.Fatalf(`database initialization failed: %+v`, err)
|
||||
}
|
||||
} else {
|
||||
db = g.DB(in.Group)
|
||||
}
|
||||
if db == nil {
|
||||
mlog.Fatal(`database initialization failed, may be invalid database configuration`)
|
||||
}
|
||||
|
||||
var tableNames []string
|
||||
if in.Tables != "" {
|
||||
tableNames = gstr.SplitAndTrim(in.Tables, ",")
|
||||
} else {
|
||||
tableNames, err = db.Tables(context.TODO())
|
||||
if err != nil {
|
||||
mlog.Fatalf("fetching tables failed: %+v", err)
|
||||
}
|
||||
}
|
||||
// Table excluding.
|
||||
if in.TablesEx != "" {
|
||||
array := garray.NewStrArrayFrom(tableNames)
|
||||
for _, v := range gstr.SplitAndTrim(in.TablesEx, ",") {
|
||||
array.RemoveValue(v)
|
||||
}
|
||||
tableNames = array.Slice()
|
||||
}
|
||||
|
||||
// Generating dao & model go files one by one according to given table name.
|
||||
newTableNames := make([]string, len(tableNames))
|
||||
for i, tableName := range tableNames {
|
||||
newTableName := tableName
|
||||
for _, v := range removePrefixArray {
|
||||
newTableName = gstr.TrimLeftStr(newTableName, v, 1)
|
||||
}
|
||||
newTableName = in.Prefix + newTableName
|
||||
newTableNames[i] = newTableName
|
||||
}
|
||||
// Dao: index and internal.
|
||||
generateDao(ctx, CGenDaoInternalInput{
|
||||
CGenDaoInput: in,
|
||||
DB: db,
|
||||
TableNames: tableNames,
|
||||
NewTableNames: newTableNames,
|
||||
ModName: modName,
|
||||
})
|
||||
// Do.
|
||||
generateDo(ctx, CGenDaoInternalInput{
|
||||
CGenDaoInput: in,
|
||||
DB: db,
|
||||
TableNames: tableNames,
|
||||
NewTableNames: newTableNames,
|
||||
ModName: modName,
|
||||
})
|
||||
// Entity.
|
||||
generateEntity(ctx, CGenDaoInternalInput{
|
||||
CGenDaoInput: in,
|
||||
DB: db,
|
||||
TableNames: tableNames,
|
||||
NewTableNames: newTableNames,
|
||||
ModName: modName,
|
||||
})
|
||||
}
|
||||
|
||||
func getImportPartContent(source string, isDo bool) string {
|
||||
var (
|
||||
packageImportsArray = garray.NewStrArray()
|
||||
)
|
||||
|
||||
if isDo {
|
||||
packageImportsArray.Append(`"github.com/gogf/gf/v2/frame/g"`)
|
||||
}
|
||||
|
||||
// Time package recognition.
|
||||
if strings.Contains(source, "gtime.Time") {
|
||||
packageImportsArray.Append(`"github.com/gogf/gf/v2/os/gtime"`)
|
||||
} else if strings.Contains(source, "time.Time") {
|
||||
packageImportsArray.Append(`"time"`)
|
||||
}
|
||||
|
||||
// Json type.
|
||||
if strings.Contains(source, "gjson.Json") {
|
||||
packageImportsArray.Append(`"github.com/gogf/gf/v2/encoding/gjson"`)
|
||||
}
|
||||
|
||||
// Generate and write content to golang file.
|
||||
packageImportsStr := ""
|
||||
if packageImportsArray.Len() > 0 {
|
||||
packageImportsStr = fmt.Sprintf("import(\n%s\n)", packageImportsArray.Join("\n"))
|
||||
}
|
||||
return packageImportsStr
|
||||
}
|
||||
|
||||
func replaceDefaultVar(in CGenDaoInternalInput, origin string) string {
|
||||
var tplCreatedAtDatetimeStr string
|
||||
var tplDatetimeStr string = createdAt.String()
|
||||
if in.WithTime {
|
||||
tplCreatedAtDatetimeStr = fmt.Sprintf(`Created at %s`, tplDatetimeStr)
|
||||
}
|
||||
return gstr.ReplaceByMap(origin, g.MapStrStr{
|
||||
tplVarDatetimeStr: tplDatetimeStr,
|
||||
tplVarCreatedAtDatetimeStr: tplCreatedAtDatetimeStr,
|
||||
})
|
||||
}
|
||||
|
||||
func sortFieldKeyForDao(fieldMap map[string]*gdb.TableField) []string {
|
||||
names := make(map[int]string)
|
||||
for _, field := range fieldMap {
|
||||
names[field.Index] = field.Name
|
||||
}
|
||||
var (
|
||||
i = 0
|
||||
j = 0
|
||||
result = make([]string, len(names))
|
||||
)
|
||||
for {
|
||||
if len(names) == 0 {
|
||||
break
|
||||
}
|
||||
if val, ok := names[i]; ok {
|
||||
result[j] = val
|
||||
j++
|
||||
delete(names, i)
|
||||
}
|
||||
i++
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func getTemplateFromPathOrDefault(filePath string, def string) string {
|
||||
if filePath != "" {
|
||||
if contents := gfile.GetContents(filePath); contents != "" {
|
||||
return contents
|
||||
}
|
||||
}
|
||||
return def
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package gendao
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/gogf/gf/v2/os/gfile"
|
||||
|
||||
"hotgo/internal/library/hggen/internal/utility/mlog"
|
||||
"hotgo/internal/library/hggen/internal/utility/utils"
|
||||
)
|
||||
|
||||
func doClear(ctx context.Context, dirPath string) {
|
||||
files, err := gfile.ScanDirFile(dirPath, "*.go", true)
|
||||
if err != nil {
|
||||
mlog.Fatal(err)
|
||||
}
|
||||
for _, file := range files {
|
||||
if utils.IsFileDoNotEdit(file) {
|
||||
if err = gfile.Remove(file); err != nil {
|
||||
mlog.Print(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
228
server/internal/library/hggen/internal/cmd/gendao/gendao_dao.go
Normal file
228
server/internal/library/hggen/internal/cmd/gendao/gendao_dao.go
Normal file
@@ -0,0 +1,228 @@
|
||||
package gendao
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/gogf/gf/v2/database/gdb"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gfile"
|
||||
"github.com/gogf/gf/v2/text/gregex"
|
||||
"github.com/gogf/gf/v2/text/gstr"
|
||||
"github.com/olekukonko/tablewriter"
|
||||
|
||||
"hotgo/internal/library/hggen/internal/consts"
|
||||
"hotgo/internal/library/hggen/internal/utility/mlog"
|
||||
"hotgo/internal/library/hggen/internal/utility/utils"
|
||||
)
|
||||
|
||||
func generateDao(ctx context.Context, in CGenDaoInternalInput) {
|
||||
var (
|
||||
dirPathDao = gfile.Join(in.Path, in.DaoPath)
|
||||
dirPathDaoInternal = gfile.Join(dirPathDao, "internal")
|
||||
)
|
||||
if in.Clear {
|
||||
doClear(ctx, dirPathDao)
|
||||
}
|
||||
for i := 0; i < len(in.TableNames); i++ {
|
||||
generateDaoSingle(ctx, generateDaoSingleInput{
|
||||
CGenDaoInternalInput: in,
|
||||
TableName: in.TableNames[i],
|
||||
NewTableName: in.NewTableNames[i],
|
||||
DirPathDao: dirPathDao,
|
||||
DirPathDaoInternal: dirPathDaoInternal,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
type generateDaoSingleInput struct {
|
||||
CGenDaoInternalInput
|
||||
TableName string // TableName specifies the table name of the table.
|
||||
NewTableName string // NewTableName specifies the prefix-stripped name of the table.
|
||||
DirPathDao string
|
||||
DirPathDaoInternal string
|
||||
}
|
||||
|
||||
// generateDaoSingle generates the dao and model content of given table.
|
||||
func generateDaoSingle(ctx context.Context, in generateDaoSingleInput) {
|
||||
// Generating table data preparing.
|
||||
fieldMap, err := in.DB.TableFields(ctx, in.TableName)
|
||||
if err != nil {
|
||||
mlog.Fatalf(`fetching tables fields failed for table "%s": %+v`, in.TableName, err)
|
||||
}
|
||||
var (
|
||||
dirRealPath = gfile.RealPath(in.Path)
|
||||
tableNameCamelCase = gstr.CaseCamel(in.NewTableName)
|
||||
tableNameCamelLowerCase = gstr.CaseCamelLower(in.NewTableName)
|
||||
tableNameSnakeCase = gstr.CaseSnake(in.NewTableName)
|
||||
importPrefix = in.ImportPrefix
|
||||
)
|
||||
if importPrefix == "" {
|
||||
if dirRealPath == "" {
|
||||
dirRealPath = in.Path
|
||||
importPrefix = dirRealPath
|
||||
importPrefix = gstr.Trim(dirRealPath, "./")
|
||||
} else {
|
||||
importPrefix = gstr.Replace(dirRealPath, gfile.Pwd(), "")
|
||||
}
|
||||
importPrefix = gstr.Replace(importPrefix, gfile.Separator, "/")
|
||||
importPrefix = gstr.Join(g.SliceStr{in.ModName, importPrefix, in.DaoPath}, "/")
|
||||
importPrefix, _ = gregex.ReplaceString(`\/{2,}`, `/`, gstr.Trim(importPrefix, "/"))
|
||||
} else {
|
||||
importPrefix = gstr.Join(g.SliceStr{importPrefix, in.DaoPath}, "/")
|
||||
}
|
||||
|
||||
fileName := gstr.Trim(tableNameSnakeCase, "-_.")
|
||||
if len(fileName) > 5 && fileName[len(fileName)-5:] == "_test" {
|
||||
// Add suffix to avoid the table name which contains "_test",
|
||||
// which would make the go file a testing file.
|
||||
fileName += "_table"
|
||||
}
|
||||
|
||||
// dao - index
|
||||
generateDaoIndex(generateDaoIndexInput{
|
||||
generateDaoSingleInput: in,
|
||||
TableNameCamelCase: tableNameCamelCase,
|
||||
TableNameCamelLowerCase: tableNameCamelLowerCase,
|
||||
ImportPrefix: importPrefix,
|
||||
FileName: fileName,
|
||||
})
|
||||
|
||||
// dao - internal
|
||||
generateDaoInternal(generateDaoInternalInput{
|
||||
generateDaoSingleInput: in,
|
||||
TableNameCamelCase: tableNameCamelCase,
|
||||
TableNameCamelLowerCase: tableNameCamelLowerCase,
|
||||
ImportPrefix: importPrefix,
|
||||
FileName: fileName,
|
||||
FieldMap: fieldMap,
|
||||
})
|
||||
}
|
||||
|
||||
type generateDaoIndexInput struct {
|
||||
generateDaoSingleInput
|
||||
TableNameCamelCase string
|
||||
TableNameCamelLowerCase string
|
||||
ImportPrefix string
|
||||
FileName string
|
||||
}
|
||||
|
||||
func generateDaoIndex(in generateDaoIndexInput) {
|
||||
path := gfile.Join(in.DirPathDao, in.FileName+".go")
|
||||
if in.OverwriteDao || !gfile.Exists(path) {
|
||||
indexContent := gstr.ReplaceByMap(
|
||||
getTemplateFromPathOrDefault(in.TplDaoIndexPath, consts.TemplateGenDaoIndexContent),
|
||||
g.MapStrStr{
|
||||
tplVarImportPrefix: in.ImportPrefix,
|
||||
tplVarTableName: in.TableName,
|
||||
tplVarTableNameCamelCase: in.TableNameCamelCase,
|
||||
tplVarTableNameCamelLowerCase: in.TableNameCamelLowerCase,
|
||||
})
|
||||
indexContent = replaceDefaultVar(in.CGenDaoInternalInput, indexContent)
|
||||
if err := gfile.PutContents(path, strings.TrimSpace(indexContent)); err != nil {
|
||||
mlog.Fatalf("writing content to '%s' failed: %v", path, err)
|
||||
} else {
|
||||
utils.GoFmt(path)
|
||||
mlog.Print("generated:", path)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type generateDaoInternalInput struct {
|
||||
generateDaoSingleInput
|
||||
TableNameCamelCase string
|
||||
TableNameCamelLowerCase string
|
||||
ImportPrefix string
|
||||
FileName string
|
||||
FieldMap map[string]*gdb.TableField
|
||||
}
|
||||
|
||||
func generateDaoInternal(in generateDaoInternalInput) {
|
||||
path := gfile.Join(in.DirPathDaoInternal, in.FileName+".go")
|
||||
modelContent := gstr.ReplaceByMap(
|
||||
getTemplateFromPathOrDefault(in.TplDaoInternalPath, consts.TemplateGenDaoInternalContent),
|
||||
g.MapStrStr{
|
||||
tplVarImportPrefix: in.ImportPrefix,
|
||||
tplVarTableName: in.TableName,
|
||||
tplVarGroupName: in.Group,
|
||||
tplVarTableNameCamelCase: in.TableNameCamelCase,
|
||||
tplVarTableNameCamelLowerCase: in.TableNameCamelLowerCase,
|
||||
tplVarColumnDefine: gstr.Trim(generateColumnDefinitionForDao(in.FieldMap)),
|
||||
tplVarColumnNames: gstr.Trim(generateColumnNamesForDao(in.FieldMap)),
|
||||
})
|
||||
modelContent = replaceDefaultVar(in.CGenDaoInternalInput, modelContent)
|
||||
if err := gfile.PutContents(path, strings.TrimSpace(modelContent)); err != nil {
|
||||
mlog.Fatalf("writing content to '%s' failed: %v", path, err)
|
||||
} else {
|
||||
utils.GoFmt(path)
|
||||
mlog.Print("generated:", path)
|
||||
}
|
||||
}
|
||||
|
||||
// generateColumnNamesForDao generates and returns the column names assignment content of column struct
|
||||
// for specified table.
|
||||
func generateColumnNamesForDao(fieldMap map[string]*gdb.TableField) string {
|
||||
var (
|
||||
buffer = bytes.NewBuffer(nil)
|
||||
array = make([][]string, len(fieldMap))
|
||||
names = sortFieldKeyForDao(fieldMap)
|
||||
)
|
||||
for index, name := range names {
|
||||
field := fieldMap[name]
|
||||
array[index] = []string{
|
||||
" #" + gstr.CaseCamel(field.Name) + ":",
|
||||
fmt.Sprintf(` #"%s",`, field.Name),
|
||||
}
|
||||
}
|
||||
tw := tablewriter.NewWriter(buffer)
|
||||
tw.SetBorder(false)
|
||||
tw.SetRowLine(false)
|
||||
tw.SetAutoWrapText(false)
|
||||
tw.SetColumnSeparator("")
|
||||
tw.AppendBulk(array)
|
||||
tw.Render()
|
||||
namesContent := buffer.String()
|
||||
// Let's do this hack of table writer for indent!
|
||||
namesContent = gstr.Replace(namesContent, " #", "")
|
||||
buffer.Reset()
|
||||
buffer.WriteString(namesContent)
|
||||
return buffer.String()
|
||||
}
|
||||
|
||||
// generateColumnDefinitionForDao generates and returns the column names definition for specified table.
|
||||
func generateColumnDefinitionForDao(fieldMap map[string]*gdb.TableField) string {
|
||||
var (
|
||||
buffer = bytes.NewBuffer(nil)
|
||||
array = make([][]string, len(fieldMap))
|
||||
names = sortFieldKeyForDao(fieldMap)
|
||||
)
|
||||
for index, name := range names {
|
||||
var (
|
||||
field = fieldMap[name]
|
||||
comment = gstr.Trim(gstr.ReplaceByArray(field.Comment, g.SliceStr{
|
||||
"\n", " ",
|
||||
"\r", " ",
|
||||
}))
|
||||
)
|
||||
array[index] = []string{
|
||||
" #" + gstr.CaseCamel(field.Name),
|
||||
" # " + "string",
|
||||
" #" + fmt.Sprintf(`// %s`, comment),
|
||||
}
|
||||
}
|
||||
tw := tablewriter.NewWriter(buffer)
|
||||
tw.SetBorder(false)
|
||||
tw.SetRowLine(false)
|
||||
tw.SetAutoWrapText(false)
|
||||
tw.SetColumnSeparator("")
|
||||
tw.AppendBulk(array)
|
||||
tw.Render()
|
||||
defineContent := buffer.String()
|
||||
// Let's do this hack of table writer for indent!
|
||||
defineContent = gstr.Replace(defineContent, " #", "")
|
||||
buffer.Reset()
|
||||
buffer.WriteString(defineContent)
|
||||
return buffer.String()
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
package gendao
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gfile"
|
||||
"github.com/gogf/gf/v2/text/gregex"
|
||||
"github.com/gogf/gf/v2/text/gstr"
|
||||
|
||||
"hotgo/internal/library/hggen/internal/consts"
|
||||
"hotgo/internal/library/hggen/internal/utility/mlog"
|
||||
"hotgo/internal/library/hggen/internal/utility/utils"
|
||||
)
|
||||
|
||||
func generateDo(ctx context.Context, in CGenDaoInternalInput) {
|
||||
var dirPathDo = gfile.Join(in.Path, in.DoPath)
|
||||
if in.Clear {
|
||||
doClear(ctx, dirPathDo)
|
||||
}
|
||||
in.NoJsonTag = true
|
||||
in.DescriptionTag = false
|
||||
in.NoModelComment = false
|
||||
// Model content.
|
||||
for i, tableName := range in.TableNames {
|
||||
fieldMap, err := in.DB.TableFields(ctx, tableName)
|
||||
if err != nil {
|
||||
mlog.Fatalf("fetching tables fields failed for table '%s':\n%v", tableName, err)
|
||||
}
|
||||
var (
|
||||
newTableName = in.NewTableNames[i]
|
||||
doFilePath = gfile.Join(dirPathDo, gstr.CaseSnake(newTableName)+".go")
|
||||
structDefinition = generateStructDefinition(ctx, generateStructDefinitionInput{
|
||||
CGenDaoInternalInput: in,
|
||||
TableName: tableName,
|
||||
StructName: gstr.CaseCamel(newTableName),
|
||||
FieldMap: fieldMap,
|
||||
IsDo: true,
|
||||
})
|
||||
)
|
||||
// replace all types to interface{}.
|
||||
structDefinition, _ = gregex.ReplaceStringFuncMatch(
|
||||
"([A-Z]\\w*?)\\s+([\\w\\*\\.]+?)\\s+(//)",
|
||||
structDefinition,
|
||||
func(match []string) string {
|
||||
// If the type is already a pointer/slice/map, it does nothing.
|
||||
if !gstr.HasPrefix(match[2], "*") && !gstr.HasPrefix(match[2], "[]") && !gstr.HasPrefix(match[2], "map") {
|
||||
return fmt.Sprintf(`%s interface{} %s`, match[1], match[3])
|
||||
}
|
||||
return match[0]
|
||||
},
|
||||
)
|
||||
modelContent := generateDoContent(
|
||||
in,
|
||||
tableName,
|
||||
gstr.CaseCamel(newTableName),
|
||||
structDefinition,
|
||||
)
|
||||
err = gfile.PutContents(doFilePath, strings.TrimSpace(modelContent))
|
||||
if err != nil {
|
||||
mlog.Fatalf(`writing content to "%s" failed: %v`, doFilePath, err)
|
||||
} else {
|
||||
utils.GoFmt(doFilePath)
|
||||
mlog.Print("generated:", doFilePath)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func generateDoContent(in CGenDaoInternalInput, tableName, tableNameCamelCase, structDefine string) string {
|
||||
doContent := gstr.ReplaceByMap(
|
||||
getTemplateFromPathOrDefault(in.TplDaoDoPath, consts.TemplateGenDaoDoContent),
|
||||
g.MapStrStr{
|
||||
tplVarTableName: tableName,
|
||||
tplVarPackageImports: getImportPartContent(structDefine, true),
|
||||
tplVarTableNameCamelCase: tableNameCamelCase,
|
||||
tplVarStructDefine: structDefine,
|
||||
})
|
||||
doContent = replaceDefaultVar(in, doContent)
|
||||
return doContent
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package gendao
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gfile"
|
||||
"github.com/gogf/gf/v2/text/gstr"
|
||||
|
||||
"hotgo/internal/library/hggen/internal/consts"
|
||||
"hotgo/internal/library/hggen/internal/utility/mlog"
|
||||
"hotgo/internal/library/hggen/internal/utility/utils"
|
||||
)
|
||||
|
||||
func generateEntity(ctx context.Context, in CGenDaoInternalInput) {
|
||||
var dirPathEntity = gfile.Join(in.Path, in.EntityPath)
|
||||
if in.Clear {
|
||||
doClear(ctx, dirPathEntity)
|
||||
}
|
||||
// Model content.
|
||||
for i, tableName := range in.TableNames {
|
||||
fieldMap, err := in.DB.TableFields(ctx, tableName)
|
||||
if err != nil {
|
||||
mlog.Fatalf("fetching tables fields failed for table '%s':\n%v", tableName, err)
|
||||
}
|
||||
var (
|
||||
newTableName = in.NewTableNames[i]
|
||||
entityFilePath = gfile.Join(dirPathEntity, gstr.CaseSnake(newTableName)+".go")
|
||||
entityContent = generateEntityContent(
|
||||
in,
|
||||
newTableName,
|
||||
gstr.CaseCamel(newTableName),
|
||||
generateStructDefinition(ctx, generateStructDefinitionInput{
|
||||
CGenDaoInternalInput: in,
|
||||
TableName: tableName,
|
||||
StructName: gstr.CaseCamel(newTableName),
|
||||
FieldMap: fieldMap,
|
||||
IsDo: false,
|
||||
}),
|
||||
)
|
||||
)
|
||||
err = gfile.PutContents(entityFilePath, strings.TrimSpace(entityContent))
|
||||
if err != nil {
|
||||
mlog.Fatalf("writing content to '%s' failed: %v", entityFilePath, err)
|
||||
} else {
|
||||
utils.GoFmt(entityFilePath)
|
||||
mlog.Print("generated:", entityFilePath)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func generateEntityContent(in CGenDaoInternalInput, tableName, tableNameCamelCase, structDefine string) string {
|
||||
entityContent := gstr.ReplaceByMap(
|
||||
getTemplateFromPathOrDefault(in.TplDaoEntityPath, consts.TemplateGenDaoEntityContent),
|
||||
g.MapStrStr{
|
||||
tplVarTableName: tableName,
|
||||
tplVarPackageImports: getImportPartContent(structDefine, false),
|
||||
tplVarTableNameCamelCase: tableNameCamelCase,
|
||||
tplVarStructDefine: structDefine,
|
||||
})
|
||||
entityContent = replaceDefaultVar(in, entityContent)
|
||||
return entityContent
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
package gendao
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/gogf/gf/v2/database/gdb"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/text/gregex"
|
||||
"github.com/gogf/gf/v2/text/gstr"
|
||||
"github.com/olekukonko/tablewriter"
|
||||
)
|
||||
|
||||
type generateStructDefinitionInput struct {
|
||||
CGenDaoInternalInput
|
||||
TableName string // Table name.
|
||||
StructName string // Struct name.
|
||||
FieldMap map[string]*gdb.TableField // Table field map.
|
||||
IsDo bool // Is generating DTO struct.
|
||||
}
|
||||
|
||||
func generateStructDefinition(ctx context.Context, in generateStructDefinitionInput) string {
|
||||
buffer := bytes.NewBuffer(nil)
|
||||
array := make([][]string, len(in.FieldMap))
|
||||
names := sortFieldKeyForDao(in.FieldMap)
|
||||
for index, name := range names {
|
||||
field := in.FieldMap[name]
|
||||
array[index] = generateStructFieldDefinition(ctx, field, in)
|
||||
}
|
||||
tw := tablewriter.NewWriter(buffer)
|
||||
tw.SetBorder(false)
|
||||
tw.SetRowLine(false)
|
||||
tw.SetAutoWrapText(false)
|
||||
tw.SetColumnSeparator("")
|
||||
tw.AppendBulk(array)
|
||||
tw.Render()
|
||||
stContent := buffer.String()
|
||||
// Let's do this hack of table writer for indent!
|
||||
stContent = gstr.Replace(stContent, " #", "")
|
||||
stContent = gstr.Replace(stContent, "` ", "`")
|
||||
stContent = gstr.Replace(stContent, "``", "")
|
||||
buffer.Reset()
|
||||
buffer.WriteString(fmt.Sprintf("type %s struct {\n", in.StructName))
|
||||
if in.IsDo {
|
||||
buffer.WriteString(fmt.Sprintf("g.Meta `orm:\"table:%s, do:true\"`\n", in.TableName))
|
||||
}
|
||||
buffer.WriteString(stContent)
|
||||
buffer.WriteString("}")
|
||||
return buffer.String()
|
||||
}
|
||||
|
||||
// generateStructFieldForModel generates and returns the attribute definition for specified field.
|
||||
func generateStructFieldDefinition(
|
||||
ctx context.Context, field *gdb.TableField, in generateStructDefinitionInput,
|
||||
) []string {
|
||||
var (
|
||||
err error
|
||||
typeName string
|
||||
jsonTag = getJsonTagFromCase(field.Name, in.JsonCase)
|
||||
)
|
||||
typeName, err = in.DB.CheckLocalTypeForField(ctx, field.Type, nil)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
switch typeName {
|
||||
case gdb.LocalTypeDate, gdb.LocalTypeDatetime:
|
||||
if in.StdTime {
|
||||
typeName = "time.Time"
|
||||
} else {
|
||||
typeName = "*gtime.Time"
|
||||
}
|
||||
|
||||
case gdb.LocalTypeInt64Bytes:
|
||||
typeName = "int64"
|
||||
|
||||
case gdb.LocalTypeUint64Bytes:
|
||||
typeName = "uint64"
|
||||
|
||||
// Special type handle.
|
||||
case gdb.LocalTypeJson, gdb.LocalTypeJsonb:
|
||||
if in.GJsonSupport {
|
||||
typeName = "*gjson.Json"
|
||||
} else {
|
||||
typeName = "string"
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
tagKey = "`"
|
||||
result = []string{
|
||||
" #" + gstr.CaseCamel(field.Name),
|
||||
" #" + typeName,
|
||||
}
|
||||
descriptionTag = gstr.Replace(formatComment(field.Comment), `"`, `\"`)
|
||||
)
|
||||
|
||||
result = append(result, " #"+fmt.Sprintf(tagKey+`json:"%s"`, jsonTag))
|
||||
result = append(result, " #"+fmt.Sprintf(`description:"%s"`+tagKey, descriptionTag))
|
||||
result = append(result, " #"+fmt.Sprintf(`// %s`, formatComment(field.Comment)))
|
||||
|
||||
for k, v := range result {
|
||||
if in.NoJsonTag {
|
||||
v, _ = gregex.ReplaceString(`json:".+"`, ``, v)
|
||||
}
|
||||
if !in.DescriptionTag {
|
||||
v, _ = gregex.ReplaceString(`description:".*"`, ``, v)
|
||||
}
|
||||
if in.NoModelComment {
|
||||
v, _ = gregex.ReplaceString(`//.+`, ``, v)
|
||||
}
|
||||
result[k] = v
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// formatComment formats the comment string to fit the golang code without any lines.
|
||||
func formatComment(comment string) string {
|
||||
comment = gstr.ReplaceByArray(comment, g.SliceStr{
|
||||
"\n", " ",
|
||||
"\r", " ",
|
||||
})
|
||||
comment = gstr.Replace(comment, `\n`, " ")
|
||||
comment = gstr.Trim(comment)
|
||||
return comment
|
||||
}
|
||||
|
||||
// getJsonTagFromCase call gstr.Case* function to convert the s to specified case.
|
||||
func getJsonTagFromCase(str, caseStr string) string {
|
||||
switch gstr.ToLower(caseStr) {
|
||||
case gstr.ToLower("Camel"):
|
||||
return gstr.CaseCamel(str)
|
||||
|
||||
case gstr.ToLower("CamelLower"):
|
||||
return gstr.CaseCamelLower(str)
|
||||
|
||||
case gstr.ToLower("Kebab"):
|
||||
return gstr.CaseKebab(str)
|
||||
|
||||
case gstr.ToLower("KebabScreaming"):
|
||||
return gstr.CaseKebabScreaming(str)
|
||||
|
||||
case gstr.ToLower("Snake"):
|
||||
return gstr.CaseSnake(str)
|
||||
|
||||
case gstr.ToLower("SnakeFirstUpper"):
|
||||
return gstr.CaseSnakeFirstUpper(str)
|
||||
|
||||
case gstr.ToLower("SnakeScreaming"):
|
||||
return gstr.CaseSnakeScreaming(str)
|
||||
}
|
||||
return str
|
||||
}
|
||||
@@ -0,0 +1,277 @@
|
||||
package genservice
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/gogf/gf/v2/container/garray"
|
||||
"github.com/gogf/gf/v2/container/gset"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gfile"
|
||||
"github.com/gogf/gf/v2/os/gproc"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
"github.com/gogf/gf/v2/text/gregex"
|
||||
"github.com/gogf/gf/v2/text/gstr"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
"github.com/gogf/gf/v2/util/gtag"
|
||||
|
||||
"hotgo/internal/library/hggen/internal/utility/mlog"
|
||||
"hotgo/internal/library/hggen/internal/utility/utils"
|
||||
)
|
||||
|
||||
const (
|
||||
CGenServiceConfig = `gfcli.hggen.service`
|
||||
CGenServiceUsage = `gf hggen service [OPTION]`
|
||||
CGenServiceBrief = `parse struct and associated functions from packages to generate service go file`
|
||||
CGenServiceEg = `
|
||||
gf hggen service
|
||||
gf hggen service -f Snake
|
||||
`
|
||||
CGenServiceBriefSrcFolder = `source folder path to be parsed. default: internal/logic`
|
||||
CGenServiceBriefDstFolder = `destination folder path storing automatically generated go files. default: internal/service`
|
||||
CGenServiceBriefFileNameCase = `
|
||||
destination file name storing automatically generated go files, cases are as follows:
|
||||
| Case | Example |
|
||||
|---------------- |--------------------|
|
||||
| Lower | anykindofstring |
|
||||
| Camel | AnyKindOfString |
|
||||
| CamelLower | anyKindOfString |
|
||||
| Snake | any_kind_of_string | default
|
||||
| SnakeScreaming | ANY_KIND_OF_STRING |
|
||||
| SnakeFirstUpper | rgb_code_md5 |
|
||||
| Kebab | any-kind-of-string |
|
||||
| KebabScreaming | ANY-KIND-OF-STRING |
|
||||
`
|
||||
CGenServiceBriefWatchFile = `used in file watcher, it re-generates all service go files only if given file is under srcFolder`
|
||||
CGenServiceBriefStPattern = `regular expression matching struct name for generating service. default: ^s([A-Z]\\\\w+)$`
|
||||
CGenServiceBriefPackages = `produce go files only for given source packages`
|
||||
CGenServiceBriefImportPrefix = `custom import prefix to calculate import path for generated importing go file of logic`
|
||||
CGenServiceBriefClear = `delete all generated go files that are not used any further`
|
||||
)
|
||||
|
||||
func init() {
|
||||
gtag.Sets(g.MapStrStr{
|
||||
`CGenServiceConfig`: CGenServiceConfig,
|
||||
`CGenServiceUsage`: CGenServiceUsage,
|
||||
`CGenServiceBrief`: CGenServiceBrief,
|
||||
`CGenServiceEg`: CGenServiceEg,
|
||||
`CGenServiceBriefSrcFolder`: CGenServiceBriefSrcFolder,
|
||||
`CGenServiceBriefDstFolder`: CGenServiceBriefDstFolder,
|
||||
`CGenServiceBriefFileNameCase`: CGenServiceBriefFileNameCase,
|
||||
`CGenServiceBriefWatchFile`: CGenServiceBriefWatchFile,
|
||||
`CGenServiceBriefStPattern`: CGenServiceBriefStPattern,
|
||||
`CGenServiceBriefPackages`: CGenServiceBriefPackages,
|
||||
`CGenServiceBriefImportPrefix`: CGenServiceBriefImportPrefix,
|
||||
`CGenServiceBriefClear`: CGenServiceBriefClear,
|
||||
})
|
||||
}
|
||||
|
||||
type (
|
||||
CGenService struct{}
|
||||
CGenServiceInput struct {
|
||||
g.Meta `name:"service" config:"{CGenServiceConfig}" usage:"{CGenServiceUsage}" brief:"{CGenServiceBrief}" eg:"{CGenServiceEg}"`
|
||||
SrcFolder string `short:"s" name:"srcFolder" brief:"{CGenServiceBriefSrcFolder}" d:"internal/logic"`
|
||||
DstFolder string `short:"d" name:"dstFolder" brief:"{CGenServiceBriefDstFolder}" d:"internal/service"`
|
||||
DstFileNameCase string `short:"f" name:"dstFileNameCase" brief:"{CGenServiceBriefFileNameCase}" d:"Snake"`
|
||||
WatchFile string `short:"w" name:"watchFile" brief:"{CGenServiceBriefWatchFile}"`
|
||||
StPattern string `short:"a" name:"stPattern" brief:"{CGenServiceBriefStPattern}" d:"^s([A-Z]\\w+)$"`
|
||||
Packages []string `short:"p" name:"packages" brief:"{CGenServiceBriefPackages}"`
|
||||
ImportPrefix string `short:"i" name:"importPrefix" brief:"{CGenServiceBriefImportPrefix}"`
|
||||
Clear bool `short:"l" name:"clear" brief:"{CGenServiceBriefClear}" orphan:"true"`
|
||||
}
|
||||
CGenServiceOutput struct{}
|
||||
)
|
||||
|
||||
const (
|
||||
genServiceFileLockSeconds = 10
|
||||
)
|
||||
|
||||
func (c CGenService) Service(ctx context.Context, in CGenServiceInput) (out *CGenServiceOutput, err error) {
|
||||
// File lock to avoid multiple processes.
|
||||
var (
|
||||
flockFilePath = gfile.Temp("gf.cli.hggen.service.lock")
|
||||
flockContent = gfile.GetContents(flockFilePath)
|
||||
)
|
||||
if flockContent != "" {
|
||||
if gtime.Timestamp()-gconv.Int64(flockContent) < genServiceFileLockSeconds {
|
||||
// If another "hggen service" process is running, it just exits.
|
||||
mlog.Debug(`another "hggen service" process is running, exit`)
|
||||
return
|
||||
}
|
||||
}
|
||||
defer gfile.Remove(flockFilePath)
|
||||
_ = gfile.PutContents(flockFilePath, gtime.TimestampStr())
|
||||
|
||||
in.SrcFolder = gstr.TrimRight(in.SrcFolder, `\/`)
|
||||
in.SrcFolder = gstr.Replace(in.SrcFolder, "\\", "/")
|
||||
in.WatchFile = gstr.TrimRight(in.WatchFile, `\/`)
|
||||
in.WatchFile = gstr.Replace(in.WatchFile, "\\", "/")
|
||||
|
||||
// Watch file handling.
|
||||
if in.WatchFile != "" {
|
||||
// It works only if given WatchFile is in SrcFolder.
|
||||
var (
|
||||
watchFileDir = gfile.Dir(in.WatchFile)
|
||||
srcFolderDir = gfile.Dir(watchFileDir)
|
||||
)
|
||||
mlog.Debug("watchFileDir:", watchFileDir)
|
||||
mlog.Debug("logicFolderDir:", srcFolderDir)
|
||||
if !gstr.HasSuffix(gstr.Replace(srcFolderDir, `\`, `/`), in.SrcFolder) {
|
||||
mlog.Printf(`ignore watch file "%s", not in source path "%s"`, in.WatchFile, in.SrcFolder)
|
||||
return
|
||||
}
|
||||
var newWorkingDir = gfile.Dir(gfile.Dir(srcFolderDir))
|
||||
if err = gfile.Chdir(newWorkingDir); err != nil {
|
||||
mlog.Fatalf(`%+v`, err)
|
||||
}
|
||||
mlog.Debug("Chdir:", newWorkingDir)
|
||||
_ = gfile.Remove(flockFilePath)
|
||||
var command = fmt.Sprintf(
|
||||
`%s hggen service -packages=%s`,
|
||||
gfile.SelfName(), gfile.Basename(watchFileDir),
|
||||
)
|
||||
err = gproc.ShellRun(ctx, command)
|
||||
return
|
||||
}
|
||||
|
||||
if !gfile.Exists(in.SrcFolder) {
|
||||
mlog.Fatalf(`source folder path "%s" does not exist`, in.SrcFolder)
|
||||
}
|
||||
|
||||
if in.ImportPrefix == "" {
|
||||
if !gfile.Exists("go.mod") {
|
||||
mlog.Fatal("ImportPrefix is empty and go.mod does not exist in current working directory")
|
||||
}
|
||||
var (
|
||||
goModContent = gfile.GetContents("go.mod")
|
||||
match, _ = gregex.MatchString(`^module\s+(.+)\s*`, goModContent)
|
||||
)
|
||||
if len(match) > 1 {
|
||||
in.ImportPrefix = fmt.Sprintf(`%s/%s`, gstr.Trim(match[1]), gstr.Replace(in.SrcFolder, `\`, `/`))
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
isDirty bool // Temp boolean.
|
||||
files []string // Temp file array.
|
||||
fileContent string // Temp file content for handling go file.
|
||||
initImportSrcPackages []string // Used for generating logic.go.
|
||||
inputPackages = in.Packages // Custom packages.
|
||||
dstPackageName = gstr.ToLower(gfile.Basename(in.DstFolder)) // Package name for generated go files.
|
||||
generatedDstFilePathSet = gset.NewStrSet() // All generated file path set.
|
||||
)
|
||||
// The first level folders.
|
||||
srcFolderPaths, err := gfile.ScanDir(in.SrcFolder, "*", false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, srcFolderPath := range srcFolderPaths {
|
||||
if !gfile.IsDir(srcFolderPath) {
|
||||
continue
|
||||
}
|
||||
// Only retrieve sub files, no recursively.
|
||||
if files, err = gfile.ScanDir(srcFolderPath, "*.go", false); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(files) == 0 {
|
||||
continue
|
||||
}
|
||||
var (
|
||||
// StructName => FunctionDefinitions
|
||||
srcPkgInterfaceMap = make(map[string]*garray.StrArray)
|
||||
srcImportedPackages = garray.NewSortedStrArray().SetUnique(true)
|
||||
srcPackageName = gfile.Basename(srcFolderPath)
|
||||
ok bool
|
||||
dstFilePath = gfile.Join(in.DstFolder,
|
||||
c.getDstFileNameCase(srcPackageName, in.DstFileNameCase)+".go",
|
||||
)
|
||||
)
|
||||
generatedDstFilePathSet.Add(dstFilePath)
|
||||
for _, file := range files {
|
||||
fileContent = gfile.GetContents(file)
|
||||
// Calculate imported packages of source go files.
|
||||
err = c.calculateImportedPackages(fileContent, srcImportedPackages)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Calculate functions and interfaces for service generating.
|
||||
err = c.calculateInterfaceFunctions(in, fileContent, srcPkgInterfaceMap, dstPackageName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
initImportSrcPackages = append(
|
||||
initImportSrcPackages,
|
||||
fmt.Sprintf(`%s/%s`, in.ImportPrefix, srcPackageName),
|
||||
)
|
||||
// Ignore source packages if input packages given.
|
||||
if len(inputPackages) > 0 && !gstr.InArray(inputPackages, srcPackageName) {
|
||||
mlog.Debugf(
|
||||
`ignore source package "%s" as it is not in desired packages: %+v`,
|
||||
srcPackageName, inputPackages,
|
||||
)
|
||||
continue
|
||||
}
|
||||
// Generating service go file for logic.
|
||||
if ok, err = c.generateServiceFile(generateServiceFilesInput{
|
||||
CGenServiceInput: in,
|
||||
SrcStructFunctions: srcPkgInterfaceMap,
|
||||
SrcImportedPackages: srcImportedPackages.Slice(),
|
||||
SrcPackageName: srcPackageName,
|
||||
DstPackageName: dstPackageName,
|
||||
DstFilePath: dstFilePath,
|
||||
}); err != nil {
|
||||
return
|
||||
}
|
||||
if ok {
|
||||
isDirty = true
|
||||
}
|
||||
}
|
||||
|
||||
if in.Clear {
|
||||
files, err = gfile.ScanDirFile(in.DstFolder, "*.go", false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var relativeFilePath string
|
||||
for _, file := range files {
|
||||
relativeFilePath = gstr.SubStrFromR(file, in.DstFolder)
|
||||
if !generatedDstFilePathSet.Contains(relativeFilePath) && utils.IsFileDoNotEdit(relativeFilePath) {
|
||||
mlog.Printf(`remove no longer used service file: %s`, relativeFilePath)
|
||||
if err = gfile.Remove(file); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if isDirty {
|
||||
// Generate initialization go file.
|
||||
if len(initImportSrcPackages) > 0 {
|
||||
if err = c.generateInitializationFile(in, initImportSrcPackages); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Replace v1 to v2 for GoFrame.
|
||||
if err = c.replaceGeneratedServiceContentGFV2(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
mlog.Printf(`gofmt go files in "%s"`, in.DstFolder)
|
||||
utils.GoFmt(in.DstFolder)
|
||||
}
|
||||
|
||||
mlog.Print(`done!`)
|
||||
return
|
||||
}
|
||||
|
||||
func (c CGenService) replaceGeneratedServiceContentGFV2(in CGenServiceInput) (err error) {
|
||||
return gfile.ReplaceDirFunc(func(path, content string) string {
|
||||
if gstr.Contains(content, `"github.com/gogf/gf`) && !gstr.Contains(content, `"github.com/gogf/gf/v2`) {
|
||||
content = gstr.Replace(content, `"github.com/gogf/gf"`, `"github.com/gogf/gf/v2"`)
|
||||
content = gstr.Replace(content, `"github.com/gogf/gf/`, `"github.com/gogf/gf/v2/`)
|
||||
return content
|
||||
}
|
||||
return content
|
||||
}, in.DstFolder, "*.go", false)
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
package genservice
|
||||
|
||||
import (
|
||||
"go/parser"
|
||||
"go/token"
|
||||
|
||||
"github.com/gogf/gf/v2/container/garray"
|
||||
"github.com/gogf/gf/v2/text/gregex"
|
||||
"github.com/gogf/gf/v2/text/gstr"
|
||||
)
|
||||
|
||||
func (c CGenService) calculateImportedPackages(fileContent string, srcImportedPackages *garray.SortedStrArray) (err error) {
|
||||
f, err := parser.ParseFile(token.NewFileSet(), "", fileContent, parser.ImportsOnly)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, s := range f.Imports {
|
||||
if s.Path != nil {
|
||||
if s.Name != nil {
|
||||
// If it has alias, and it is not `_`.
|
||||
if pkgAlias := s.Name.String(); pkgAlias != "_" {
|
||||
srcImportedPackages.Add(pkgAlias + " " + s.Path.Value)
|
||||
}
|
||||
} else {
|
||||
// no alias
|
||||
srcImportedPackages.Add(s.Path.Value)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c CGenService) calculateInterfaceFunctions(
|
||||
in CGenServiceInput, fileContent string, srcPkgInterfaceMap map[string]*garray.StrArray, dstPackageName string,
|
||||
) (err error) {
|
||||
var (
|
||||
ok bool
|
||||
matches [][]string
|
||||
srcPkgInterfaceFuncArray *garray.StrArray
|
||||
)
|
||||
// calculate struct name and its functions according function definitions.
|
||||
matches, err = gregex.MatchAllString(`func \((.+?)\) ([\s\S]+?) {`, fileContent)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, match := range matches {
|
||||
var (
|
||||
structName string
|
||||
structMatch []string
|
||||
funcReceiver = gstr.Trim(match[1])
|
||||
receiverArray = gstr.SplitAndTrim(funcReceiver, " ")
|
||||
functionHead = gstr.Trim(gstr.Replace(match[2], "\n", ""))
|
||||
)
|
||||
if len(receiverArray) > 1 {
|
||||
structName = receiverArray[1]
|
||||
} else {
|
||||
structName = receiverArray[0]
|
||||
}
|
||||
structName = gstr.Trim(structName, "*")
|
||||
|
||||
// Case of:
|
||||
// Xxx(\n ctx context.Context, req *v1.XxxReq,\n) -> Xxx(ctx context.Context, req *v1.XxxReq)
|
||||
functionHead = gstr.Replace(functionHead, `,)`, `)`)
|
||||
functionHead, _ = gregex.ReplaceString(`\(\s+`, `(`, functionHead)
|
||||
functionHead, _ = gregex.ReplaceString(`\s{2,}`, ` `, functionHead)
|
||||
if !gstr.IsLetterUpper(functionHead[0]) {
|
||||
continue
|
||||
}
|
||||
// Match and pick the struct name from receiver.
|
||||
if structMatch, err = gregex.MatchString(in.StPattern, structName); err != nil {
|
||||
return err
|
||||
}
|
||||
if len(structMatch) < 1 {
|
||||
continue
|
||||
}
|
||||
structName = gstr.CaseCamel(structMatch[1])
|
||||
if srcPkgInterfaceFuncArray, ok = srcPkgInterfaceMap[structName]; !ok {
|
||||
srcPkgInterfaceMap[structName] = garray.NewStrArray()
|
||||
srcPkgInterfaceFuncArray = srcPkgInterfaceMap[structName]
|
||||
}
|
||||
srcPkgInterfaceFuncArray.Append(functionHead)
|
||||
}
|
||||
// calculate struct name according type definitions.
|
||||
matches, err = gregex.MatchAllString(`type (.+) struct\s*{`, fileContent)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, match := range matches {
|
||||
var (
|
||||
structName string
|
||||
structMatch []string
|
||||
)
|
||||
if structMatch, err = gregex.MatchString(in.StPattern, match[1]); err != nil {
|
||||
return err
|
||||
}
|
||||
if len(structMatch) < 1 {
|
||||
continue
|
||||
}
|
||||
structName = gstr.CaseCamel(structMatch[1])
|
||||
if srcPkgInterfaceFuncArray, ok = srcPkgInterfaceMap[structName]; !ok {
|
||||
srcPkgInterfaceMap[structName] = garray.NewStrArray()
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,199 @@
|
||||
package genservice
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/gogf/gf/v2/container/garray"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gfile"
|
||||
"github.com/gogf/gf/v2/text/gregex"
|
||||
"github.com/gogf/gf/v2/text/gstr"
|
||||
|
||||
"hotgo/internal/library/hggen/internal/consts"
|
||||
"hotgo/internal/library/hggen/internal/utility/mlog"
|
||||
"hotgo/internal/library/hggen/internal/utility/utils"
|
||||
)
|
||||
|
||||
type generateServiceFilesInput struct {
|
||||
CGenServiceInput
|
||||
DstFilePath string // Absolute file path for generated service go file.
|
||||
SrcStructFunctions map[string]*garray.StrArray
|
||||
SrcImportedPackages []string
|
||||
SrcPackageName string
|
||||
DstPackageName string
|
||||
}
|
||||
|
||||
func (c CGenService) generateServiceFile(in generateServiceFilesInput) (ok bool, err error) {
|
||||
var (
|
||||
generatedContent string
|
||||
allFuncArray = garray.NewStrArray() // Used for check whether interface dirty, going to change file content.
|
||||
importedPackagesContent = fmt.Sprintf(
|
||||
"import (\n%s\n)", gstr.Join(in.SrcImportedPackages, "\n"),
|
||||
)
|
||||
)
|
||||
generatedContent += gstr.ReplaceByMap(consts.TemplateGenServiceContentHead, g.MapStrStr{
|
||||
"{Imports}": importedPackagesContent,
|
||||
"{PackageName}": in.DstPackageName,
|
||||
})
|
||||
|
||||
// Type definitions.
|
||||
generatedContent += "type("
|
||||
generatedContent += "\n"
|
||||
for structName, funcArray := range in.SrcStructFunctions {
|
||||
allFuncArray.Append(funcArray.Slice()...)
|
||||
generatedContent += gstr.Trim(gstr.ReplaceByMap(consts.TemplateGenServiceContentInterface, g.MapStrStr{
|
||||
"{InterfaceName}": "I" + structName,
|
||||
"{FuncDefinition}": funcArray.Join("\n\t"),
|
||||
}))
|
||||
generatedContent += "\n"
|
||||
}
|
||||
generatedContent += ")"
|
||||
generatedContent += "\n"
|
||||
|
||||
// Generating variable and register definitions.
|
||||
var (
|
||||
variableContent string
|
||||
generatingInterfaceCheck string
|
||||
)
|
||||
// Variable definitions.
|
||||
for structName, _ := range in.SrcStructFunctions {
|
||||
generatingInterfaceCheck = fmt.Sprintf(`[^\w\d]+%s.I%s[^\w\d]`, in.DstPackageName, structName)
|
||||
if gregex.IsMatchString(generatingInterfaceCheck, generatedContent) {
|
||||
continue
|
||||
}
|
||||
variableContent += gstr.Trim(gstr.ReplaceByMap(consts.TemplateGenServiceContentVariable, g.MapStrStr{
|
||||
"{StructName}": structName,
|
||||
"{InterfaceName}": "I" + structName,
|
||||
}))
|
||||
variableContent += "\n"
|
||||
}
|
||||
if variableContent != "" {
|
||||
generatedContent += "var("
|
||||
generatedContent += "\n"
|
||||
generatedContent += variableContent
|
||||
generatedContent += ")"
|
||||
generatedContent += "\n"
|
||||
}
|
||||
// Variable register function definitions.
|
||||
for structName, _ := range in.SrcStructFunctions {
|
||||
generatingInterfaceCheck = fmt.Sprintf(`[^\w\d]+%s.I%s[^\w\d]`, in.DstPackageName, structName)
|
||||
if gregex.IsMatchString(generatingInterfaceCheck, generatedContent) {
|
||||
continue
|
||||
}
|
||||
generatedContent += gstr.Trim(gstr.ReplaceByMap(consts.TemplateGenServiceContentRegister, g.MapStrStr{
|
||||
"{StructName}": structName,
|
||||
"{InterfaceName}": "I" + structName,
|
||||
}))
|
||||
generatedContent += "\n\n"
|
||||
}
|
||||
|
||||
// Replace empty braces that have new line.
|
||||
generatedContent, _ = gregex.ReplaceString(`{[\s\t]+}`, `{}`, generatedContent)
|
||||
|
||||
// Remove package name calls of `dstPackageName` in produced codes.
|
||||
generatedContent, _ = gregex.ReplaceString(fmt.Sprintf(`\*{0,1}%s\.`, in.DstPackageName), ``, generatedContent)
|
||||
|
||||
// Write file content to disk.
|
||||
if gfile.Exists(in.DstFilePath) {
|
||||
if !utils.IsFileDoNotEdit(in.DstFilePath) {
|
||||
mlog.Printf(`ignore file as it is manually maintained: %s`, in.DstFilePath)
|
||||
return false, nil
|
||||
}
|
||||
if !c.isToGenerateServiceGoFile(in.DstPackageName, in.DstFilePath, allFuncArray) {
|
||||
mlog.Printf(`not dirty, ignore generating service go file: %s`, in.DstFilePath)
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
mlog.Printf(`generating service go file: %s`, in.DstFilePath)
|
||||
if err = gfile.PutContents(in.DstFilePath, generatedContent); err != nil {
|
||||
return true, err
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// isToGenerateServiceGoFile checks and returns whether the service content dirty.
|
||||
func (c CGenService) isToGenerateServiceGoFile(dstPackageName, filePath string, funcArray *garray.StrArray) bool {
|
||||
var (
|
||||
fileContent = gfile.GetContents(filePath)
|
||||
generatedFuncArray = garray.NewSortedStrArrayFrom(funcArray.Slice())
|
||||
contentFuncArray = garray.NewSortedStrArray()
|
||||
)
|
||||
if fileContent == "" {
|
||||
return true
|
||||
}
|
||||
matches, _ := gregex.MatchAllString(`\s+interface\s+{([\s\S]+?)}`, fileContent)
|
||||
for _, match := range matches {
|
||||
contentFuncArray.Append(gstr.SplitAndTrim(match[1], "\n")...)
|
||||
}
|
||||
if generatedFuncArray.Len() != contentFuncArray.Len() {
|
||||
mlog.Debugf(
|
||||
`dirty, generatedFuncArray.Len()[%d] != contentFuncArray.Len()[%d]`,
|
||||
generatedFuncArray.Len(), contentFuncArray.Len(),
|
||||
)
|
||||
return true
|
||||
}
|
||||
var funcDefinition string
|
||||
for i := 0; i < generatedFuncArray.Len(); i++ {
|
||||
funcDefinition, _ = gregex.ReplaceString(
|
||||
fmt.Sprintf(`\*{0,1}%s\.`, dstPackageName), ``, generatedFuncArray.At(i),
|
||||
)
|
||||
if funcDefinition != contentFuncArray.At(i) {
|
||||
mlog.Debugf(`dirty, %s != %s`, funcDefinition, contentFuncArray.At(i))
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (c CGenService) generateInitializationFile(in CGenServiceInput, importSrcPackages []string) (err error) {
|
||||
var (
|
||||
srcPackageName = gstr.ToLower(gfile.Basename(in.SrcFolder))
|
||||
srcFilePath = gfile.Join(in.SrcFolder, srcPackageName+".go")
|
||||
srcImports string
|
||||
generatedContent string
|
||||
)
|
||||
if !utils.IsFileDoNotEdit(srcFilePath) {
|
||||
mlog.Debugf(`ignore file as it is manually maintained: %s`, srcFilePath)
|
||||
return nil
|
||||
}
|
||||
for _, importSrcPackage := range importSrcPackages {
|
||||
srcImports += fmt.Sprintf(`%s_ "%s"%s`, "\t", importSrcPackage, "\n")
|
||||
}
|
||||
generatedContent = gstr.ReplaceByMap(consts.TemplateGenServiceLogicContent, g.MapStrStr{
|
||||
"{PackageName}": srcPackageName,
|
||||
"{Imports}": srcImports,
|
||||
})
|
||||
mlog.Printf(`generating init go file: %s`, srcFilePath)
|
||||
if err = gfile.PutContents(srcFilePath, generatedContent); err != nil {
|
||||
return err
|
||||
}
|
||||
utils.GoFmt(srcFilePath)
|
||||
return nil
|
||||
}
|
||||
|
||||
// getDstFileNameCase call gstr.Case* function to convert the s to specified case.
|
||||
func (c CGenService) getDstFileNameCase(str, caseStr string) string {
|
||||
switch gstr.ToLower(caseStr) {
|
||||
case gstr.ToLower("Lower"):
|
||||
return gstr.ToLower(str)
|
||||
|
||||
case gstr.ToLower("Camel"):
|
||||
return gstr.CaseCamel(str)
|
||||
|
||||
case gstr.ToLower("CamelLower"):
|
||||
return gstr.CaseCamelLower(str)
|
||||
|
||||
case gstr.ToLower("Kebab"):
|
||||
return gstr.CaseKebab(str)
|
||||
|
||||
case gstr.ToLower("KebabScreaming"):
|
||||
return gstr.CaseKebabScreaming(str)
|
||||
|
||||
case gstr.ToLower("SnakeFirstUpper"):
|
||||
return gstr.CaseSnakeFirstUpper(str)
|
||||
|
||||
case gstr.ToLower("SnakeScreaming"):
|
||||
return gstr.CaseSnakeScreaming(str)
|
||||
}
|
||||
return gstr.CaseSnake(str)
|
||||
}
|
||||
7
server/internal/library/hggen/internal/consts/consts.go
Normal file
7
server/internal/library/hggen/internal/consts/consts.go
Normal file
@@ -0,0 +1,7 @@
|
||||
package consts
|
||||
|
||||
const (
|
||||
// DoNotEditKey is used in generated files,
|
||||
// which marks the files will be overwritten by CLI tool.
|
||||
DoNotEditKey = `DO NOT EDIT`
|
||||
)
|
||||
@@ -0,0 +1,108 @@
|
||||
package consts
|
||||
|
||||
const TemplateGenDaoIndexContent = `
|
||||
// =================================================================================
|
||||
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
|
||||
// =================================================================================
|
||||
|
||||
package dao
|
||||
|
||||
import (
|
||||
"{TplImportPrefix}/internal"
|
||||
)
|
||||
|
||||
// internal{TplTableNameCamelCase}Dao is internal type for wrapping internal DAO implements.
|
||||
type internal{TplTableNameCamelCase}Dao = *internal.{TplTableNameCamelCase}Dao
|
||||
|
||||
// {TplTableNameCamelLowerCase}Dao is the data access object for table {TplTableName}.
|
||||
// You can define custom methods on it to extend its functionality as you wish.
|
||||
type {TplTableNameCamelLowerCase}Dao struct {
|
||||
internal{TplTableNameCamelCase}Dao
|
||||
}
|
||||
|
||||
var (
|
||||
// {TplTableNameCamelCase} is globally public accessible object for table {TplTableName} operations.
|
||||
{TplTableNameCamelCase} = {TplTableNameCamelLowerCase}Dao{
|
||||
internal.New{TplTableNameCamelCase}Dao(),
|
||||
}
|
||||
)
|
||||
|
||||
// Fill with you ideas below.
|
||||
|
||||
`
|
||||
|
||||
const TemplateGenDaoInternalContent = `
|
||||
// ==========================================================================
|
||||
// Code generated by GoFrame CLI tool. DO NOT EDIT. {TplCreatedAtDatetimeStr}
|
||||
// ==========================================================================
|
||||
|
||||
package internal
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/gogf/gf/v2/database/gdb"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
)
|
||||
|
||||
// {TplTableNameCamelCase}Dao is the data access object for table {TplTableName}.
|
||||
type {TplTableNameCamelCase}Dao struct {
|
||||
table string // table is the underlying table name of the DAO.
|
||||
group string // group is the database configuration group name of current DAO.
|
||||
columns {TplTableNameCamelCase}Columns // columns contains all the column names of Table for convenient usage.
|
||||
}
|
||||
|
||||
// {TplTableNameCamelCase}Columns defines and stores column names for table {TplTableName}.
|
||||
type {TplTableNameCamelCase}Columns struct {
|
||||
{TplColumnDefine}
|
||||
}
|
||||
|
||||
// {TplTableNameCamelLowerCase}Columns holds the columns for table {TplTableName}.
|
||||
var {TplTableNameCamelLowerCase}Columns = {TplTableNameCamelCase}Columns{
|
||||
{TplColumnNames}
|
||||
}
|
||||
|
||||
// New{TplTableNameCamelCase}Dao creates and returns a new DAO object for table data access.
|
||||
func New{TplTableNameCamelCase}Dao() *{TplTableNameCamelCase}Dao {
|
||||
return &{TplTableNameCamelCase}Dao{
|
||||
group: "{TplGroupName}",
|
||||
table: "{TplTableName}",
|
||||
columns: {TplTableNameCamelLowerCase}Columns,
|
||||
}
|
||||
}
|
||||
|
||||
// DB retrieves and returns the underlying raw database management object of current DAO.
|
||||
func (dao *{TplTableNameCamelCase}Dao) DB() gdb.DB {
|
||||
return g.DB(dao.group)
|
||||
}
|
||||
|
||||
// Table returns the table name of current dao.
|
||||
func (dao *{TplTableNameCamelCase}Dao) Table() string {
|
||||
return dao.table
|
||||
}
|
||||
|
||||
// Columns returns all column names of current dao.
|
||||
func (dao *{TplTableNameCamelCase}Dao) Columns() {TplTableNameCamelCase}Columns {
|
||||
return dao.columns
|
||||
}
|
||||
|
||||
// Group returns the configuration group name of database of current dao.
|
||||
func (dao *{TplTableNameCamelCase}Dao) Group() string {
|
||||
return dao.group
|
||||
}
|
||||
|
||||
// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation.
|
||||
func (dao *{TplTableNameCamelCase}Dao) Ctx(ctx context.Context) *gdb.Model {
|
||||
return dao.DB().Model(dao.table).Safe().Ctx(ctx)
|
||||
}
|
||||
|
||||
// Transaction wraps the transaction logic using function f.
|
||||
// It rollbacks the transaction and returns the error from function f if it returns non-nil error.
|
||||
// It commits the transaction and returns nil if function f returns nil.
|
||||
//
|
||||
// Note that, you should not Commit or Rollback the transaction in function f
|
||||
// as it is automatically handled by this function.
|
||||
func (dao *{TplTableNameCamelCase}Dao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
|
||||
return dao.Ctx(ctx).Transaction(ctx, f)
|
||||
}
|
||||
`
|
||||
@@ -0,0 +1,14 @@
|
||||
package consts
|
||||
|
||||
const TemplateGenDaoDoContent = `
|
||||
// =================================================================================
|
||||
// Code generated by GoFrame CLI tool. DO NOT EDIT. {TplCreatedAtDatetimeStr}
|
||||
// =================================================================================
|
||||
|
||||
package do
|
||||
|
||||
{TplPackageImports}
|
||||
|
||||
// {TplTableNameCamelCase} is the golang structure of table {TplTableName} for DAO operations like Where/Data.
|
||||
{TplStructDefine}
|
||||
`
|
||||
@@ -0,0 +1,14 @@
|
||||
package consts
|
||||
|
||||
const TemplateGenDaoEntityContent = `
|
||||
// =================================================================================
|
||||
// Code generated by GoFrame CLI tool. DO NOT EDIT. {TplCreatedAtDatetimeStr}
|
||||
// =================================================================================
|
||||
|
||||
package entity
|
||||
|
||||
{TplPackageImports}
|
||||
|
||||
// {TplTableNameCamelCase} is the golang structure for table {TplTableName}.
|
||||
{TplStructDefine}
|
||||
`
|
||||
@@ -0,0 +1,17 @@
|
||||
package consts
|
||||
|
||||
const TemplatePbEntityMessageContent = `
|
||||
// ==========================================================================
|
||||
// Code generated by GoFrame CLI tool. DO NOT EDIT.
|
||||
// ==========================================================================
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package {PackageName};
|
||||
|
||||
import "github.com/gogo/protobuf/gogoproto/gogo.proto";
|
||||
|
||||
{OptionContent}
|
||||
|
||||
{EntityMessage}
|
||||
`
|
||||
@@ -0,0 +1,35 @@
|
||||
package consts
|
||||
|
||||
const TemplateGenServiceContentHead = `
|
||||
// ================================================================================
|
||||
// Code generated by GoFrame CLI tool. DO NOT EDIT.
|
||||
// You can delete these comments if you wish manually maintain this interface file.
|
||||
// ================================================================================
|
||||
|
||||
package {PackageName}
|
||||
|
||||
{Imports}
|
||||
`
|
||||
|
||||
const TemplateGenServiceContentInterface = `
|
||||
{InterfaceName} interface {
|
||||
{FuncDefinition}
|
||||
}
|
||||
`
|
||||
|
||||
const TemplateGenServiceContentVariable = `
|
||||
local{StructName} {InterfaceName}
|
||||
`
|
||||
|
||||
const TemplateGenServiceContentRegister = `
|
||||
func {StructName}() {InterfaceName} {
|
||||
if local{StructName} == nil {
|
||||
panic("implement not found for interface {InterfaceName}, forgot register?")
|
||||
}
|
||||
return local{StructName}
|
||||
}
|
||||
|
||||
func Register{StructName}(i {InterfaceName}) {
|
||||
local{StructName} = i
|
||||
}
|
||||
`
|
||||
@@ -0,0 +1,13 @@
|
||||
package consts
|
||||
|
||||
const TemplateGenServiceLogicContent = `
|
||||
// ==========================================================================
|
||||
// Code generated by GoFrame CLI tool. DO NOT EDIT.
|
||||
// ==========================================================================
|
||||
|
||||
package {PackageName}
|
||||
|
||||
import(
|
||||
{Imports}
|
||||
)
|
||||
`
|
||||
1
server/internal/library/hggen/internal/packed/packed.go
Normal file
1
server/internal/library/hggen/internal/packed/packed.go
Normal file
@@ -0,0 +1 @@
|
||||
package packed
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user