mirror of
https://gitee.com/dromara/mayfly-go
synced 2025-11-03 16:00:25 +08:00
fix: 机器文件内容写入导致内容清空、feat: ioc支持根据类型注入
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
# 🌈mayfly-go
|
# 🌈Dromara mayfly-go
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="./README_EN.md">English</a> |
|
<a href="./README_EN.md">English</a> |
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# 🌈mayfly-go
|
# 🌈Dromara mayfly-go
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="./README.md">中文介绍</a> |
|
<a href="./README.md">中文介绍</a> |
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
"jsencrypt": "^3.3.2",
|
"jsencrypt": "^3.3.2",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"mitt": "^3.0.1",
|
"mitt": "^3.0.1",
|
||||||
"monaco-editor": "^0.52.0",
|
"monaco-editor": "^0.52.2",
|
||||||
"monaco-sql-languages": "^0.12.2",
|
"monaco-sql-languages": "^0.12.2",
|
||||||
"monaco-themes": "^0.4.4",
|
"monaco-themes": "^0.4.4",
|
||||||
"nprogress": "^0.2.0",
|
"nprogress": "^0.2.0",
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<el-form-item>
|
<el-form-item>
|
||||||
<template #label>
|
<template #label>
|
||||||
<el-space :size="4">
|
<el-space :size="4">
|
||||||
<span>{{ `${item?.label}` }}</span>
|
<span>{{ `${$t(item?.label)}` }}</span>
|
||||||
<el-tooltip v-if="item.tooltip" :content="item?.tooltip" placement="top">
|
<el-tooltip v-if="item.tooltip" :content="item?.tooltip" placement="top">
|
||||||
<SvgIcon name="QuestionFilled" />
|
<SvgIcon name="QuestionFilled" />
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
@@ -21,8 +21,8 @@
|
|||||||
</GridItem>
|
</GridItem>
|
||||||
<GridItem suffix>
|
<GridItem suffix>
|
||||||
<div class="operation">
|
<div class="operation">
|
||||||
<el-button type="primary" :icon="Search" @click="search" plain> 搜索 </el-button>
|
<el-button type="primary" :icon="Search" @click="search" plain> {{ $t('common.search') }} </el-button>
|
||||||
<el-button :icon="Delete" @click="reset"> 重置 </el-button>
|
<el-button :icon="Delete" @click="reset"> {{ $t('common.reset') }} </el-button>
|
||||||
<el-button v-if="showCollapse" type="primary" link class="search-isOpen" @click="collapsed = !collapsed">
|
<el-button v-if="showCollapse" type="primary" link class="search-isOpen" @click="collapsed = !collapsed">
|
||||||
{{ collapsed ? '展开' : '合并' }}
|
{{ collapsed ? '展开' : '合并' }}
|
||||||
<el-icon class="el-icon--right">
|
<el-icon class="el-icon--right">
|
||||||
|
|||||||
@@ -31,10 +31,10 @@
|
|||||||
<!-- 按钮 -->
|
<!-- 按钮 -->
|
||||||
<div class="search-buttons">
|
<div class="search-buttons">
|
||||||
<el-button class="terminal-search-button search-button-prev" type="primary" size="small" @click="searchKeywords(false)">
|
<el-button class="terminal-search-button search-button-prev" type="primary" size="small" @click="searchKeywords(false)">
|
||||||
{{ $t('components.terminal.previous') }}}}
|
{{ $t('components.terminal.previous') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button class="terminal-search-button search-button-next" type="primary" size="small" @click="searchKeywords(true)">
|
<el-button class="terminal-search-button search-button-next" type="primary" size="small" @click="searchKeywords(true)">
|
||||||
{{ $t('components.terminal.next') }}}}
|
{{ $t('components.terminal.next') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button class="terminal-search-button search-button-next" type="primary" size="small" @click="closeSearch">
|
<el-button class="terminal-search-button search-button-next" type="primary" size="small" @click="closeSearch">
|
||||||
{{ $t('components.terminal.close') }}
|
{{ $t('components.terminal.close') }}
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ export default {
|
|||||||
previousStep: 'Previous Step',
|
previousStep: 'Previous Step',
|
||||||
nextStep: 'Next Step',
|
nextStep: 'Next Step',
|
||||||
copy: 'Copy',
|
copy: 'Copy',
|
||||||
|
search: 'Search',
|
||||||
pleaseInput: 'Please enter {label}',
|
pleaseInput: 'Please enter {label}',
|
||||||
pleaseSelect: 'Please select {label}',
|
pleaseSelect: 'Please select {label}',
|
||||||
formValidationError: 'Please check the form',
|
formValidationError: 'Please check the form',
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ export default {
|
|||||||
previousStep: '上一步',
|
previousStep: '上一步',
|
||||||
nextStep: '下一步',
|
nextStep: '下一步',
|
||||||
copy: '复制',
|
copy: '复制',
|
||||||
|
search: '搜索',
|
||||||
pleaseInput: '请输入{label}',
|
pleaseInput: '请输入{label}',
|
||||||
pleaseSelect: '请选择{label}',
|
pleaseSelect: '请选择{label}',
|
||||||
formValidationError: '信息填写有误,请检查',
|
formValidationError: '信息填写有误,请检查',
|
||||||
|
|||||||
@@ -123,7 +123,7 @@ export class DbInst {
|
|||||||
},
|
},
|
||||||
kind: monaco.languages.CompletionItemKind.File,
|
kind: monaco.languages.CompletionItemKind.File,
|
||||||
detail: tableComment,
|
detail: tableComment,
|
||||||
insertText: dbDialect.quoteIdentifier(tableName) + ' ',
|
insertText: dbDialect.quoteIdentifier(tableName),
|
||||||
range,
|
range,
|
||||||
sortText: 300 + index + '',
|
sortText: 300 + index + '',
|
||||||
});
|
});
|
||||||
@@ -147,7 +147,7 @@ export class DbInst {
|
|||||||
},
|
},
|
||||||
kind: monaco.languages.CompletionItemKind.Property,
|
kind: monaco.languages.CompletionItemKind.Property,
|
||||||
detail: '', // 不显示detail, 否则选中时备注等会被遮挡
|
detail: '', // 不显示detail, 否则选中时备注等会被遮挡
|
||||||
insertText: dbDialect.quoteIdentifier(fieldName) + ' ', // create_time
|
insertText: dbDialect.quoteIdentifier(fieldName), // create_time
|
||||||
range,
|
range,
|
||||||
sortText: 100 + index + '', // 使用表字段声明顺序排序,排序需为字符串类型
|
sortText: 100 + index + '', // 使用表字段声明顺序排序,排序需为字符串类型
|
||||||
});
|
});
|
||||||
@@ -819,7 +819,7 @@ export function registerDbCompletionItemProvider(dbId: number, db: string, dbs:
|
|||||||
},
|
},
|
||||||
kind: monaco.languages.CompletionItemKind.File,
|
kind: monaco.languages.CompletionItemKind.File,
|
||||||
detail: tableComment,
|
detail: tableComment,
|
||||||
insertText: dbDialect.quoteIdentifier(tableName) + ' ',
|
insertText: dbDialect.quoteIdentifier(tableName),
|
||||||
range,
|
range,
|
||||||
sortText: 300 + index + '',
|
sortText: 300 + index + '',
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -32,8 +32,8 @@ require (
|
|||||||
github.com/tidwall/gjson v1.18.0
|
github.com/tidwall/gjson v1.18.0
|
||||||
github.com/veops/go-ansiterm v0.0.5
|
github.com/veops/go-ansiterm v0.0.5
|
||||||
go.mongodb.org/mongo-driver v1.16.0 // mongo
|
go.mongodb.org/mongo-driver v1.16.0 // mongo
|
||||||
golang.org/x/crypto v0.30.0 // ssh
|
golang.org/x/crypto v0.31.0 // ssh
|
||||||
golang.org/x/oauth2 v0.23.0
|
golang.org/x/oauth2 v0.24.0
|
||||||
golang.org/x/sync v0.10.0
|
golang.org/x/sync v0.10.0
|
||||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1
|
gopkg.in/natefinch/lumberjack.v2 v2.2.1
|
||||||
gopkg.in/yaml.v3 v3.0.1
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
|
|||||||
@@ -61,10 +61,6 @@ type fileAppImpl struct {
|
|||||||
base.AppImpl[*entity.File, repository.File]
|
base.AppImpl[*entity.File, repository.File]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *fileAppImpl) InjectFileRepo(repo repository.File) {
|
|
||||||
f.Repo = repo
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *fileAppImpl) Upload(ctx context.Context, fileKey string, filename string, r io.Reader) (string, error) {
|
func (f *fileAppImpl) Upload(ctx context.Context, fileKey string, filename string, r io.Reader) (string, error) {
|
||||||
var err error
|
var err error
|
||||||
fileKey, writer, saveFileFunc, err := f.NewWriter(ctx, fileKey, filename)
|
fileKey, writer, saveFileFunc, err := f.NewWriter(ctx, fileKey, filename)
|
||||||
|
|||||||
@@ -42,11 +42,6 @@ type procdefAppImpl struct {
|
|||||||
|
|
||||||
var _ (Procdef) = (*procdefAppImpl)(nil)
|
var _ (Procdef) = (*procdefAppImpl)(nil)
|
||||||
|
|
||||||
// 注入repo
|
|
||||||
func (p *procdefAppImpl) InjectProcdefRepo(procdefRepo repository.Procdef) {
|
|
||||||
p.Repo = procdefRepo
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *procdefAppImpl) GetPageList(condition *entity.Procdef, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error) {
|
func (p *procdefAppImpl) GetPageList(condition *entity.Procdef, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error) {
|
||||||
return p.Repo.GetPageList(condition, pageParam, toEntity, orderBy...)
|
return p.Repo.GetPageList(condition, pageParam, toEntity, orderBy...)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,11 +51,6 @@ type procinstAppImpl struct {
|
|||||||
|
|
||||||
var _ (Procinst) = (*procinstAppImpl)(nil)
|
var _ (Procinst) = (*procinstAppImpl)(nil)
|
||||||
|
|
||||||
// 注入repo
|
|
||||||
func (p *procinstAppImpl) InjectProcinstRepo(procinstRepo repository.Procinst) {
|
|
||||||
p.Repo = procinstRepo
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *procinstAppImpl) GetPageList(condition *entity.ProcinstQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error) {
|
func (p *procinstAppImpl) GetPageList(condition *entity.ProcinstQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error) {
|
||||||
return p.Repo.GetPageList(condition, pageParam, toEntity, orderBy...)
|
return p.Repo.GetPageList(condition, pageParam, toEntity, orderBy...)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,11 +69,6 @@ type machineAppImpl struct {
|
|||||||
|
|
||||||
var _ (Machine) = (*machineAppImpl)(nil)
|
var _ (Machine) = (*machineAppImpl)(nil)
|
||||||
|
|
||||||
// 注入MachineRepo
|
|
||||||
func (m *machineAppImpl) InjectMachineRepo(repo repository.Machine) {
|
|
||||||
m.Repo = repo
|
|
||||||
}
|
|
||||||
|
|
||||||
// 分页获取机器信息列表
|
// 分页获取机器信息列表
|
||||||
func (m *machineAppImpl) GetMachineList(condition *entity.MachineQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error) {
|
func (m *machineAppImpl) GetMachineList(condition *entity.MachineQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error) {
|
||||||
return m.GetRepo().GetMachineList(condition, pageParam, toEntity, orderBy...)
|
return m.GetRepo().GetMachineList(condition, pageParam, toEntity, orderBy...)
|
||||||
|
|||||||
@@ -36,11 +36,6 @@ type machineCmdConfAppImpl struct {
|
|||||||
|
|
||||||
var _ (MachineCmdConf) = (*machineCmdConfAppImpl)(nil)
|
var _ (MachineCmdConf) = (*machineCmdConfAppImpl)(nil)
|
||||||
|
|
||||||
// 注入MachineCmdConfRepo
|
|
||||||
func (m *machineCmdConfAppImpl) InjectMachineCmdConfRepo(repo repository.MachineCmdConf) {
|
|
||||||
m.Repo = repo
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *machineCmdConfAppImpl) SaveCmdConf(ctx context.Context, cmdConfParam *dto.SaveMachineCmdConf) error {
|
func (m *machineCmdConfAppImpl) SaveCmdConf(ctx context.Context, cmdConfParam *dto.SaveMachineCmdConf) error {
|
||||||
cmdConf := cmdConfParam.CmdConf
|
cmdConf := cmdConfParam.CmdConf
|
||||||
|
|
||||||
|
|||||||
@@ -51,11 +51,6 @@ type machineCronJobAppImpl struct {
|
|||||||
|
|
||||||
var _ (MachineCronJob) = (*machineCronJobAppImpl)(nil)
|
var _ (MachineCronJob) = (*machineCronJobAppImpl)(nil)
|
||||||
|
|
||||||
// 注入MachineCronJobRepo
|
|
||||||
func (m *machineCronJobAppImpl) InjectMachineCronJobRepo(repo repository.MachineCronJob) {
|
|
||||||
m.Repo = repo
|
|
||||||
}
|
|
||||||
|
|
||||||
// 分页获取机器脚本任务列表
|
// 分页获取机器脚本任务列表
|
||||||
func (m *machineCronJobAppImpl) GetPageList(condition *entity.MachineCronJob, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error) {
|
func (m *machineCronJobAppImpl) GetPageList(condition *entity.MachineCronJob, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error) {
|
||||||
return m.GetRepo().GetPageList(condition, pageParam, toEntity, orderBy...)
|
return m.GetRepo().GetPageList(condition, pageParam, toEntity, orderBy...)
|
||||||
|
|||||||
@@ -279,12 +279,15 @@ func (m *machineFileAppImpl) WriteFileContent(ctx context.Context, opParam *dto.
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
f, err := sftpCli.OpenFile(path, os.O_WRONLY|os.O_TRUNC|os.O_CREATE|os.O_RDWR)
|
f, err := sftpCli.OpenFile(path, os.O_RDWR)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return mi, err
|
return mi, err
|
||||||
}
|
}
|
||||||
|
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
f.Write(content)
|
if _, err := f.Write(content); err != nil {
|
||||||
|
return mi, err
|
||||||
|
}
|
||||||
return mi, err
|
return mi, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,11 +26,6 @@ type machineScriptAppImpl struct {
|
|||||||
machineApp Machine `inject:"MachineApp"`
|
machineApp Machine `inject:"MachineApp"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// 注入MachineScriptRepo
|
|
||||||
func (m *machineScriptAppImpl) InjectMachineScriptRepo(repo repository.MachineScript) {
|
|
||||||
m.Repo = repo
|
|
||||||
}
|
|
||||||
|
|
||||||
const Common_Script_Machine_Id = 9999999
|
const Common_Script_Machine_Id = 9999999
|
||||||
|
|
||||||
// 分页获取机器脚本信息列表
|
// 分页获取机器脚本信息列表
|
||||||
|
|||||||
@@ -42,11 +42,6 @@ type machineTermOpAppImpl struct {
|
|||||||
fileApp fileapp.File `inject:"FileApp"`
|
fileApp fileapp.File `inject:"FileApp"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// 注入MachineTermOpRepo
|
|
||||||
func (m *machineTermOpAppImpl) InjectMachineTermOpRepo(repo repository.MachineTermOp) {
|
|
||||||
m.Repo = repo
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *machineTermOpAppImpl) TermConn(ctx context.Context, cli *mcm.Cli, wsConn *websocket.Conn, rows, cols int) error {
|
func (m *machineTermOpAppImpl) TermConn(ctx context.Context, cli *mcm.Cli, wsConn *websocket.Conn, rows, cols int) error {
|
||||||
var recorder *mcm.Recorder
|
var recorder *mcm.Recorder
|
||||||
var termOpRecord *entity.MachineTermOp
|
var termOpRecord *entity.MachineTermOp
|
||||||
|
|||||||
@@ -40,11 +40,6 @@ type mongoAppImpl struct {
|
|||||||
tagApp tagapp.TagTree `inject:"TagTreeApp"`
|
tagApp tagapp.TagTree `inject:"TagTreeApp"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// 注入MongoRepo
|
|
||||||
func (d *mongoAppImpl) InjectMongoRepo(repo repository.Mongo) {
|
|
||||||
d.Repo = repo
|
|
||||||
}
|
|
||||||
|
|
||||||
// 分页获取数据库信息列表
|
// 分页获取数据库信息列表
|
||||||
func (d *mongoAppImpl) GetPageList(condition *entity.MongoQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error) {
|
func (d *mongoAppImpl) GetPageList(condition *entity.MongoQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error) {
|
||||||
return d.GetRepo().GetList(condition, pageParam, toEntity, orderBy...)
|
return d.GetRepo().GetList(condition, pageParam, toEntity, orderBy...)
|
||||||
|
|||||||
@@ -60,11 +60,6 @@ type redisAppImpl struct {
|
|||||||
resourceAuthCertApp tagapp.ResourceAuthCert `inject:"ResourceAuthCertApp"`
|
resourceAuthCertApp tagapp.ResourceAuthCert `inject:"ResourceAuthCertApp"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// 注入RedisRepo
|
|
||||||
func (r *redisAppImpl) InjectRedisRepo(repo repository.Redis) {
|
|
||||||
r.Repo = repo
|
|
||||||
}
|
|
||||||
|
|
||||||
// 分页获取redis列表
|
// 分页获取redis列表
|
||||||
func (r *redisAppImpl) GetPageList(condition *entity.RedisQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error) {
|
func (r *redisAppImpl) GetPageList(condition *entity.RedisQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error) {
|
||||||
return r.GetRepo().GetRedisList(condition, pageParam, toEntity, orderBy...)
|
return r.GetRepo().GetRedisList(condition, pageParam, toEntity, orderBy...)
|
||||||
|
|||||||
@@ -28,11 +28,6 @@ type accountAppImpl struct {
|
|||||||
accountRoleRepo repository.AccountRole `inject:"AccountRoleRepo"`
|
accountRoleRepo repository.AccountRole `inject:"AccountRoleRepo"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// 注入AccountRepo
|
|
||||||
func (a *accountAppImpl) InjectAccountRepo(repo repository.Account) {
|
|
||||||
a.Repo = repo
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *accountAppImpl) GetPageList(condition *entity.AccountQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error) {
|
func (a *accountAppImpl) GetPageList(condition *entity.AccountQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error) {
|
||||||
return a.GetRepo().GetPageList(condition, pageParam, toEntity)
|
return a.GetRepo().GetPageList(condition, pageParam, toEntity)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,10 +31,6 @@ type configAppImpl struct {
|
|||||||
base.AppImpl[*entity.Config, repository.Config]
|
base.AppImpl[*entity.Config, repository.Config]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *configAppImpl) InjectConfigRepo(repo repository.Config) {
|
|
||||||
a.Repo = repo
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *configAppImpl) GetPageList(condition *entity.Config, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error) {
|
func (a *configAppImpl) GetPageList(condition *entity.Config, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error) {
|
||||||
return a.GetRepo().GetPageList(condition, pageParam, toEntity)
|
return a.GetRepo().GetPageList(condition, pageParam, toEntity)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,11 +41,6 @@ type resourceAppImpl struct {
|
|||||||
|
|
||||||
var _ (Resource) = (*resourceAppImpl)(nil)
|
var _ (Resource) = (*resourceAppImpl)(nil)
|
||||||
|
|
||||||
// 注入ResourceRepo
|
|
||||||
func (r *resourceAppImpl) InjectResourceRepo(repo repository.Resource) {
|
|
||||||
r.Repo = repo
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *resourceAppImpl) Save(ctx context.Context, resource *entity.Resource) error {
|
func (r *resourceAppImpl) Save(ctx context.Context, resource *entity.Resource) error {
|
||||||
// 更新操作
|
// 更新操作
|
||||||
if resource.Id != 0 {
|
if resource.Id != 0 {
|
||||||
|
|||||||
@@ -52,10 +52,6 @@ type roleAppImpl struct {
|
|||||||
|
|
||||||
var _ (Role) = (*roleAppImpl)(nil)
|
var _ (Role) = (*roleAppImpl)(nil)
|
||||||
|
|
||||||
func (r *roleAppImpl) InjectRoleRepo(repo repository.Role) {
|
|
||||||
r.Repo = repo
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *roleAppImpl) GetPageList(condition *entity.RoleQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error) {
|
func (m *roleAppImpl) GetPageList(condition *entity.RoleQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error) {
|
||||||
return m.GetRepo().GetPageList(condition, pageParam, toEntity, orderBy...)
|
return m.GetRepo().GetPageList(condition, pageParam, toEntity, orderBy...)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,11 +54,6 @@ type resourceAuthCertAppImpl struct {
|
|||||||
tagTreeApp TagTree `inject:"TagTreeApp"`
|
tagTreeApp TagTree `inject:"TagTreeApp"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// 注入Repo
|
|
||||||
func (r *resourceAuthCertAppImpl) InjectResourceAuthCertRepo(resourceAuthCertRepo repository.ResourceAuthCert) {
|
|
||||||
r.Repo = resourceAuthCertRepo
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *resourceAuthCertAppImpl) RelateAuthCert(ctx context.Context, params *dto.RelateAuthCert) error {
|
func (r *resourceAuthCertAppImpl) RelateAuthCert(ctx context.Context, params *dto.RelateAuthCert) error {
|
||||||
resourceCode := params.ResourceCode
|
resourceCode := params.ResourceCode
|
||||||
resourceType := int8(params.ResourceType)
|
resourceType := int8(params.ResourceType)
|
||||||
|
|||||||
@@ -26,11 +26,6 @@ type resourceOpLogAppImpl struct {
|
|||||||
|
|
||||||
var _ (ResourceOpLog) = (*resourceOpLogAppImpl)(nil)
|
var _ (ResourceOpLog) = (*resourceOpLogAppImpl)(nil)
|
||||||
|
|
||||||
// 注入ResourceOpLogRepo
|
|
||||||
func (rol *resourceOpLogAppImpl) InjectResourceOpLogRepo(resourceOpLogRepo repository.ResourceOpLog) {
|
|
||||||
rol.Repo = resourceOpLogRepo
|
|
||||||
}
|
|
||||||
|
|
||||||
func (rol *resourceOpLogAppImpl) AddResourceOpLog(ctx context.Context, codePath string) error {
|
func (rol *resourceOpLogAppImpl) AddResourceOpLog(ctx context.Context, codePath string) error {
|
||||||
loginAccount := contextx.GetLoginAccount(ctx)
|
loginAccount := contextx.GetLoginAccount(ctx)
|
||||||
if loginAccount == nil {
|
if loginAccount == nil {
|
||||||
|
|||||||
@@ -74,11 +74,6 @@ type tagTreeAppImpl struct {
|
|||||||
|
|
||||||
var _ (TagTree) = (*tagTreeAppImpl)(nil)
|
var _ (TagTree) = (*tagTreeAppImpl)(nil)
|
||||||
|
|
||||||
// 注入TagTreeRepo
|
|
||||||
func (p *tagTreeAppImpl) InjectTagTreeRepo(tagTreeRepo repository.TagTree) {
|
|
||||||
p.Repo = tagTreeRepo
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *tagTreeAppImpl) SaveTag(ctx context.Context, pid uint64, tag *entity.TagTree) error {
|
func (p *tagTreeAppImpl) SaveTag(ctx context.Context, pid uint64, tag *entity.TagTree) error {
|
||||||
accountId := contextx.GetLoginAccount(ctx).Id
|
accountId := contextx.GetLoginAccount(ctx).Id
|
||||||
// 新建项目树节点信息
|
// 新建项目树节点信息
|
||||||
|
|||||||
@@ -42,11 +42,6 @@ type tagTreeRelateAppImpl struct {
|
|||||||
|
|
||||||
var _ (TagTreeRelate) = (*tagTreeRelateAppImpl)(nil)
|
var _ (TagTreeRelate) = (*tagTreeRelateAppImpl)(nil)
|
||||||
|
|
||||||
// 注入TagTreeRelateRepo
|
|
||||||
func (p *tagTreeRelateAppImpl) InjectTagTreeRelateRepo(tagTreeRelateRepo repository.TagTreeRelate) {
|
|
||||||
p.Repo = tagTreeRelateRepo
|
|
||||||
}
|
|
||||||
|
|
||||||
func (tr *tagTreeRelateAppImpl) RelateTag(ctx context.Context, relateType entity.TagRelateType, relateId uint64, tagCodePaths ...string) error {
|
func (tr *tagTreeRelateAppImpl) RelateTag(ctx context.Context, relateType entity.TagRelateType, relateId uint64, tagCodePaths ...string) error {
|
||||||
if hasConflictPath(tagCodePaths) {
|
if hasConflictPath(tagCodePaths) {
|
||||||
return errorx.NewBizI(ctx, imsg.ErrConflictingCodePath)
|
return errorx.NewBizI(ctx, imsg.ErrConflictingCodePath)
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ type App[T model.ModelI] interface {
|
|||||||
|
|
||||||
// 基础application接口实现
|
// 基础application接口实现
|
||||||
type AppImpl[T model.ModelI, R Repo[T]] struct {
|
type AppImpl[T model.ModelI, R Repo[T]] struct {
|
||||||
Repo R // repo接口
|
Repo R `inject:"T"` // repo接口, 根据类型进行注入
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取repo
|
// 获取repo
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package ioc
|
package ioc
|
||||||
|
|
||||||
|
import "reflect"
|
||||||
|
|
||||||
type ComponentOption func(component *Component)
|
type ComponentOption func(component *Component)
|
||||||
|
|
||||||
// 组件名
|
// 组件名
|
||||||
@@ -13,6 +15,8 @@ func WithComponentName(name string) ComponentOption {
|
|||||||
type Component struct {
|
type Component struct {
|
||||||
Name string // 组件名
|
Name string // 组件名
|
||||||
|
|
||||||
|
Type reflect.Type // 组件类型
|
||||||
|
|
||||||
Value any // 组件实例
|
Value any // 组件实例
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,11 @@ import (
|
|||||||
"golang.org/x/sync/errgroup"
|
"golang.org/x/sync/errgroup"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
InjectTag = "inject"
|
||||||
|
ByTypeComponentName = "T" // 根据类型注入的组件名
|
||||||
|
)
|
||||||
|
|
||||||
// 容器
|
// 容器
|
||||||
type Container struct {
|
type Container struct {
|
||||||
mu sync.RWMutex
|
mu sync.RWMutex
|
||||||
@@ -34,22 +39,25 @@ func (c *Container) Register(bean any, opts ...ComponentOption) {
|
|||||||
component := NewComponent(bean, opts...)
|
component := NewComponent(bean, opts...)
|
||||||
|
|
||||||
componentName := component.Name
|
componentName := component.Name
|
||||||
cType := structx.IndirectType(reflect.TypeOf(component.Value))
|
cType := reflect.TypeOf(component.Value)
|
||||||
|
indirectCType := structx.IndirectType(cType)
|
||||||
// 组件名为空,则取组件类型名称作为组件名
|
// 组件名为空,则取组件类型名称作为组件名
|
||||||
if componentName == "" {
|
if componentName == "" {
|
||||||
componentName = cType.Name()
|
componentName = indirectCType.Name()
|
||||||
component.Name = componentName
|
component.Name = componentName
|
||||||
}
|
}
|
||||||
|
|
||||||
|
component.Type = cType
|
||||||
|
|
||||||
if _, ok := c.components[componentName]; ok {
|
if _, ok := c.components[componentName]; ok {
|
||||||
logx.Warnf("组件名[%s]已经注册至容器, 重复注册...", componentName)
|
logx.Warnf("the component name [%s] has been registered to the container. Repeat the registration...", componentName)
|
||||||
}
|
}
|
||||||
|
|
||||||
logx.Debugf("ioc register : %s = %s.%s", componentName, cType.PkgPath(), cType.Name())
|
logx.Debugf("ioc register : %s = %s.%s", componentName, indirectCType.PkgPath(), indirectCType.Name())
|
||||||
c.components[componentName] = component
|
c.components[componentName] = component
|
||||||
}
|
}
|
||||||
|
|
||||||
// 注册对象实例的字段含有inject:"xxx"标签或者Setter方法,则注入对应组件实例
|
// Inject 注册对象实例的字段含有注入标签或者Setter方法,则注入对应组件实例
|
||||||
func (c *Container) Inject(obj any) error {
|
func (c *Container) Inject(obj any) error {
|
||||||
objValue := reflect.ValueOf(obj)
|
objValue := reflect.ValueOf(obj)
|
||||||
if structx.Indirect(objValue).Kind() != reflect.Struct {
|
if structx.Indirect(objValue).Kind() != reflect.Struct {
|
||||||
@@ -106,49 +114,101 @@ func (c *Container) Get(name string) (any, error) {
|
|||||||
return component.Value, nil
|
return component.Value, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// 根据实例字段的inject:"xxx"标签进行依赖注入
|
// GetByType 根据组件实例类型获取组件实例
|
||||||
|
func (c *Container) GetByType(fieldType reflect.Type) (any, error) {
|
||||||
|
c.mu.RLock()
|
||||||
|
defer c.mu.RUnlock()
|
||||||
|
|
||||||
|
for _, component := range c.components {
|
||||||
|
if component.Type.AssignableTo(fieldType) {
|
||||||
|
return component.Value, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, errors.New("component type not found: " + fmt.Sprintf("%s.%s", fieldType.PkgPath(), fieldType.Name()))
|
||||||
|
}
|
||||||
|
|
||||||
|
// injectWithField 根据实例字段的inject:"xxx"或injectByType:""标签进行依赖注入
|
||||||
func (c *Container) injectWithField(objValue reflect.Value) error {
|
func (c *Container) injectWithField(objValue reflect.Value) error {
|
||||||
objValue = structx.Indirect(objValue)
|
objValue = structx.Indirect(objValue)
|
||||||
objType := objValue.Type()
|
objType := objValue.Type()
|
||||||
|
|
||||||
|
logx.Debugf("start ioc inject with field: %s.%s", objType.PkgPath(), objType.Name())
|
||||||
|
|
||||||
for i := 0; i < objType.NumField(); i++ {
|
for i := 0; i < objType.NumField(); i++ {
|
||||||
field := objType.Field(i)
|
field := objType.Field(i)
|
||||||
|
fieldValue := objValue.Field(i)
|
||||||
|
|
||||||
componentName, ok := field.Tag.Lookup("inject")
|
// 检查字段是否是通过组合包含在当前结构体中的,即嵌套结构体
|
||||||
|
if field.Anonymous && structx.IndirectType(field.Type).Kind() == reflect.Struct {
|
||||||
|
c.injectWithField(fieldValue)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
componentName, ok := field.Tag.Lookup(InjectTag)
|
||||||
if !ok {
|
if !ok {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
// inject tag字段名为空则默认为字段名
|
|
||||||
if componentName == "" {
|
|
||||||
componentName = field.Name
|
|
||||||
}
|
|
||||||
|
|
||||||
injectInfo := fmt.Sprintf("ioc field inject [%s -> %s.%s#%s]", componentName, objType.PkgPath(), objType.Name(), field.Name)
|
// 如果组件名为指定的根据类型注入值,则根据类型注入
|
||||||
logx.Debugf(injectInfo)
|
if componentName == ByTypeComponentName {
|
||||||
|
if err := c.injectByType(objType, field, fieldValue); err != nil {
|
||||||
component, err := c.Get(componentName)
|
return err
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("%s error: %s", injectInfo, err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
// 判断字段类型与需要注入的组件类型是否为可赋值关系
|
|
||||||
componentType := reflect.TypeOf(component)
|
|
||||||
if !componentType.AssignableTo(field.Type) {
|
|
||||||
componentType = structx.IndirectType(componentType)
|
|
||||||
return fmt.Errorf("%s error: 注入类型不一致(期望类型->%s.%s, 组件类型->%s.%s)", injectInfo, field.Type.PkgPath(), field.Type.Name(), componentType.PkgPath(), componentType.Name())
|
|
||||||
}
|
|
||||||
|
|
||||||
fieldValue := objValue.Field(i)
|
|
||||||
if !fieldValue.IsValid() || !fieldValue.CanSet() {
|
|
||||||
// 不可导出变量处理
|
|
||||||
fieldPtrValue := reflect.NewAt(fieldValue.Type(), fieldValue.Addr().UnsafePointer())
|
|
||||||
fieldValue = fieldPtrValue.Elem()
|
|
||||||
if !fieldValue.IsValid() || !fieldValue.CanSet() {
|
|
||||||
return fmt.Errorf("%s error: 字段无效或为不可导出类型", injectInfo)
|
|
||||||
}
|
}
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
fieldValue.Set(reflect.ValueOf(component))
|
if err := c.injectByName(objType, field, fieldValue, componentName); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// injectByName 根据实例组件名进行依赖注入
|
||||||
|
func (c *Container) injectByName(structType reflect.Type, field reflect.StructField, fieldValue reflect.Value, componentName string) error {
|
||||||
|
// inject tag字段名为空则默认为字段名
|
||||||
|
if componentName == "" {
|
||||||
|
componentName = field.Name
|
||||||
|
}
|
||||||
|
|
||||||
|
injectInfo := fmt.Sprintf("ioc field inject [%s -> %s.%s#%s]", componentName, structType.PkgPath(), structType.Name(), field.Name)
|
||||||
|
logx.Debugf(injectInfo)
|
||||||
|
|
||||||
|
component, err := c.Get(componentName)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("%s error: %s", injectInfo, err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
// 判断字段类型与需要注入的组件类型是否为可赋值关系
|
||||||
|
componentType := reflect.TypeOf(component)
|
||||||
|
if !componentType.AssignableTo(field.Type) {
|
||||||
|
indirectComponentType := structx.IndirectType(componentType)
|
||||||
|
return fmt.Errorf("%s error: injection types are inconsistent(Expected type -> %s.%s, Component type -> %s.%s)", injectInfo, field.Type.PkgPath(), field.Type.Name(), indirectComponentType.PkgPath(), indirectComponentType.Name())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := setFieldValue(fieldValue, component); err != nil {
|
||||||
|
return fmt.Errorf("%s error: %s", injectInfo, err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// injectByType 根据实例类型进行依赖注入
|
||||||
|
func (c *Container) injectByType(structType reflect.Type, field reflect.StructField, fieldValue reflect.Value) error {
|
||||||
|
fieldType := field.Type
|
||||||
|
|
||||||
|
injectInfo := fmt.Sprintf("ioc field inject by type [%s.%s -> %s.%s#%s]", fieldType.PkgPath(), fieldType.Name(), structType.PkgPath(), structType.Name(), field.Name)
|
||||||
|
logx.Debugf(injectInfo)
|
||||||
|
|
||||||
|
component, err := c.GetByType(fieldType)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("%s error: %s", injectInfo, err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := setFieldValue(fieldValue, component); err != nil {
|
||||||
|
return fmt.Errorf("%s error: %s", injectInfo, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@@ -174,7 +234,7 @@ func (c *Container) injectWithMethod(objValue reflect.Value) error {
|
|||||||
logx.Debugf(injectInfo)
|
logx.Debugf(injectInfo)
|
||||||
|
|
||||||
if method.Type.NumIn() != 2 {
|
if method.Type.NumIn() != 2 {
|
||||||
logx.Warnf("%s error: 方法入参不为1个, 无法进行注入", injectInfo)
|
logx.Warnf("%s error: the method cannot be injected if it does not have one parameter", injectInfo)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -188,7 +248,7 @@ func (c *Container) injectWithMethod(objValue reflect.Value) error {
|
|||||||
expectedComponentType := method.Type.In(1)
|
expectedComponentType := method.Type.In(1)
|
||||||
if !componentType.AssignableTo(expectedComponentType) {
|
if !componentType.AssignableTo(expectedComponentType) {
|
||||||
componentType = structx.IndirectType(componentType)
|
componentType = structx.IndirectType(componentType)
|
||||||
return fmt.Errorf("%s error: 注入类型不一致(期望类型->%s.%s, 组件类型->%s.%s)", injectInfo, expectedComponentType.PkgPath(), expectedComponentType.Name(), componentType.PkgPath(), componentType.Name())
|
return fmt.Errorf("%s error: injection types are inconsistent(Expected type -> %s.%s, Component type -> %s.%s)", injectInfo, expectedComponentType.PkgPath(), expectedComponentType.Name(), componentType.PkgPath(), componentType.Name())
|
||||||
}
|
}
|
||||||
|
|
||||||
method.Func.Call([]reflect.Value{objValue, reflect.ValueOf(component)})
|
method.Func.Call([]reflect.Value{objValue, reflect.ValueOf(component)})
|
||||||
@@ -196,3 +256,17 @@ func (c *Container) injectWithMethod(objValue reflect.Value) error {
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func setFieldValue(fieldValue reflect.Value, component any) error {
|
||||||
|
if !fieldValue.IsValid() || !fieldValue.CanSet() {
|
||||||
|
// 不可导出变量处理
|
||||||
|
fieldPtrValue := reflect.NewAt(fieldValue.Type(), fieldValue.Addr().UnsafePointer())
|
||||||
|
fieldValue = fieldPtrValue.Elem()
|
||||||
|
if !fieldValue.IsValid() || !fieldValue.CanSet() {
|
||||||
|
return errors.New("the field is invalid or a non-exportable type")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fieldValue.Set(reflect.ValueOf(component))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user