Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
飞鱼0526
gin-vue-admin
提交
dcba0898
G
gin-vue-admin
项目概览
飞鱼0526
/
gin-vue-admin
与 Fork 源项目一致
Fork自
FLIPPED-AURORA / gin-vue-admin
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
G
gin-vue-admin
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
dcba0898
编写于
7月 12, 2021
作者:
Mr.奇淼(
浏览文件
操作
浏览文件
下载
差异文件
Merge remote-tracking branch 'origin/gva_gormv2_dev' into gva_gormv2_dev
上级
74263748
60c74bc9
变更
11
显示空白变更内容
内联
并排
Showing
11 changed file
with
256 addition
and
15 deletion
+256
-15
server/api/v1/sys_auto_code.go
server/api/v1/sys_auto_code.go
+49
-2
server/model/request/sys_autocode.go
server/model/request/sys_autocode.go
+8
-0
server/model/sys_auto_code.go
server/model/sys_auto_code.go
+1
-1
server/model/sys_autocode_history.go
server/model/sys_autocode_history.go
+14
-0
server/router/sys_auto_code.go
server/router/sys_auto_code.go
+2
-0
server/service/sys_api.go
server/service/sys_api.go
+4
-0
server/service/sys_auto_code.go
server/service/sys_auto_code.go
+59
-10
server/service/sys_autocode_history.go
server/service/sys_autocode_history.go
+75
-0
server/service/sys_initdb.go
server/service/sys_initdb.go
+1
-0
server/utils/file_operations.go
server/utils/file_operations.go
+4
-0
server/utils/injectionCode.go
server/utils/injectionCode.go
+39
-2
未找到文件。
server/api/v1/sys_auto_code.go
浏览文件 @
dcba0898
...
...
@@ -5,6 +5,7 @@ import (
"fmt"
"gin-vue-admin/global"
"gin-vue-admin/model"
"gin-vue-admin/model/request"
"gin-vue-admin/model/response"
"gin-vue-admin/service"
"gin-vue-admin/utils"
...
...
@@ -15,6 +16,49 @@ import (
"go.uber.org/zap"
)
// @Tags AutoCode
// @Summary 查询回滚记录
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body request.SysAutoHistory true "查询回滚记录"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /autoCode/preview [post]
func
GetSysHistory
(
c
*
gin
.
Context
)
{
var
search
request
.
SysAutoHistory
_
=
c
.
ShouldBindJSON
(
&
search
)
err
,
list
,
total
:=
service
.
GetSysHistoryPage
(
search
.
PageInfo
)
if
err
!=
nil
{
global
.
GVA_LOG
.
Error
(
"获取失败!"
,
zap
.
Any
(
"err"
,
err
))
response
.
FailWithMessage
(
"获取失败"
,
c
)
}
else
{
response
.
OkWithDetailed
(
response
.
PageResult
{
List
:
list
,
Total
:
total
,
Page
:
search
.
Page
,
PageSize
:
search
.
PageSize
,
},
"获取成功"
,
c
)
}
}
// @Tags AutoCode
// @Summary 回滚
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body request.AutoHistoryByID true "回滚自动生成代码"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"回滚成功"}"
// @Router /autoCode/preview [post]
func
RollBack
(
c
*
gin
.
Context
)
{
var
id
request
.
AutoHistoryByID
_
=
c
.
ShouldBindJSON
(
&
id
)
if
err
:=
service
.
RollBack
(
id
.
ID
);
err
!=
nil
{
response
.
FailWithMessage
(
err
.
Error
(),
c
)
return
}
response
.
OkWithMessage
(
"回滚成功"
,
c
)
}
// @Tags AutoCode
// @Summary 预览创建后的代码
// @Security ApiKeyAuth
...
...
@@ -54,15 +98,18 @@ func CreateTemp(c *gin.Context) {
response
.
FailWithMessage
(
err
.
Error
(),
c
)
return
}
var
apiIds
[]
uint
if
a
.
AutoCreateApiToSql
{
if
err
:=
service
.
AutoCreateApi
(
&
a
);
err
!=
nil
{
if
ids
,
err
:=
service
.
AutoCreateApi
(
&
a
);
err
!=
nil
{
global
.
GVA_LOG
.
Error
(
"自动化创建失败!请自行清空垃圾数据!"
,
zap
.
Any
(
"err"
,
err
))
c
.
Writer
.
Header
()
.
Add
(
"success"
,
"false"
)
c
.
Writer
.
Header
()
.
Add
(
"msg"
,
url
.
QueryEscape
(
"自动化创建失败!请自行清空垃圾数据!"
))
return
}
else
{
apiIds
=
ids
}
}
err
:=
service
.
CreateTemp
(
a
)
err
:=
service
.
CreateTemp
(
a
,
apiIds
...
)
if
err
!=
nil
{
if
errors
.
Is
(
err
,
model
.
AutoMoveErr
)
{
c
.
Writer
.
Header
()
.
Add
(
"success"
,
"false"
)
...
...
server/model/request/sys_autocode.go
浏览文件 @
dcba0898
package
request
type
SysAutoHistory
struct
{
PageInfo
}
type
AutoHistoryByID
struct
{
ID
uint
`json:"id"`
}
type
DBReq
struct
{
Database
string
`json:"database" gorm:"column:database"`
}
...
...
server/model/sys_auto_code.go
浏览文件 @
dcba0898
server/model/sys_autocode_history.go
0 → 100644
浏览文件 @
dcba0898
package
model
import
"gin-vue-admin/global"
// 自动迁移代码记录,用于回滚,重放使用
type
SysAutoCodeHistory
struct
{
global
.
GVA_MODEL
TableName
string
AutoCodeMeta
string
`gorm:"type:text"`
// 其他meta信息 path;path
InjectionMeta
string
`gorm:"type:text"`
// 注入的内容 RouterPath@functionName@RouterString;
ApiIDs
string
// api表注册内容
Flag
int
// 表示对应状态 0 代表创建, 1 代表回滚 ...
}
server/router/sys_auto_code.go
浏览文件 @
dcba0898
...
...
@@ -8,6 +8,8 @@ import (
func
InitAutoCodeRouter
(
Router
*
gin
.
RouterGroup
)
{
AutoCodeRouter
:=
Router
.
Group
(
"autoCode"
)
{
AutoCodeRouter
.
POST
(
"getSysHistory"
,
v1
.
GetSysHistory
)
// 获取回滚记录分页
AutoCodeRouter
.
POST
(
"rollback"
,
v1
.
RollBack
)
// 回滚
AutoCodeRouter
.
POST
(
"preview"
,
v1
.
PreviewTemp
)
// 获取自动创建代码预览
AutoCodeRouter
.
POST
(
"createTemp"
,
v1
.
CreateTemp
)
// 创建自动化代码
AutoCodeRouter
.
GET
(
"getTables"
,
v1
.
GetTables
)
// 获取对应数据库的表
...
...
server/service/sys_api.go
浏览文件 @
dcba0898
...
...
@@ -141,3 +141,7 @@ func DeleteApisByIds(ids request.IdsReq) (err error) {
err
=
global
.
GVA_DB
.
Delete
(
&
[]
model
.
SysApi
{},
"id in ?"
,
ids
.
Ids
)
.
Error
return
err
}
func
DeleteApiByIds
(
ids
[]
string
)
(
err
error
)
{
return
global
.
GVA_DB
.
Delete
(
model
.
SysApi
{},
ids
)
.
Error
}
server/service/sys_auto_code.go
浏览文件 @
dcba0898
...
...
@@ -2,6 +2,7 @@ package service
import
(
"errors"
"fmt"
"gin-vue-admin/global"
"gin-vue-admin/model"
"gin-vue-admin/model/request"
...
...
@@ -9,6 +10,7 @@ import (
"io/ioutil"
"os"
"path/filepath"
"strconv"
"strings"
"text/template"
...
...
@@ -98,7 +100,7 @@ func PreviewTemp(autoCode model.AutoCodeStruct) (map[string]string, error) {
//@param: model.AutoCodeStruct
//@return: err error
func
CreateTemp
(
autoCode
model
.
AutoCodeStruct
)
(
err
error
)
{
func
CreateTemp
(
autoCode
model
.
AutoCodeStruct
,
ids
...
uint
)
(
err
error
)
{
dataList
,
fileList
,
needMkdir
,
err
:=
getNeedList
(
&
autoCode
)
if
err
!=
nil
{
return
err
...
...
@@ -125,6 +127,13 @@ func CreateTemp(autoCode model.AutoCodeStruct) (err error) {
return
}
}()
bf
:=
strings
.
Builder
{}
idBf
:=
strings
.
Builder
{}
injectionCodeMeta
:=
strings
.
Builder
{}
for
_
,
id
:=
range
ids
{
idBf
.
WriteString
(
strconv
.
Itoa
(
int
(
id
)))
idBf
.
WriteString
(
";"
)
}
if
autoCode
.
AutoMoveFile
{
// 判断是否需要自动转移
for
index
,
_
:=
range
dataList
{
addAutoMoveFile
(
&
dataList
[
index
])
...
...
@@ -146,18 +155,51 @@ func CreateTemp(autoCode model.AutoCodeStruct) (err error) {
if
err
!=
nil
{
return
err
}
injectionCodeMeta
.
WriteString
(
fmt
.
Sprintf
(
"%s@%s@%s"
,
initializeGormFilePath
,
"MysqlTables"
,
"model."
+
autoCode
.
StructName
+
"{},"
))
injectionCodeMeta
.
WriteString
(
";"
)
injectionCodeMeta
.
WriteString
(
fmt
.
Sprintf
(
"%s@%s@%s"
,
initializeRouterFilePath
,
"Routers"
,
"router.Init"
+
autoCode
.
StructName
+
"Router(PrivateGroup)"
))
// 保存生成信息
for
_
,
data
:=
range
dataList
{
if
len
(
data
.
autoMoveFilePath
)
!=
0
{
bf
.
WriteString
(
data
.
autoMoveFilePath
)
bf
.
WriteString
(
";"
)
}
}
if
global
.
GVA_CONFIG
.
AutoCode
.
TransferRestart
{
go
func
()
{
_
=
utils
.
Reload
()
}()
}
return
errors
.
New
(
"创建代码成功并移动文件成功"
)
//
return errors.New("创建代码成功并移动文件成功")
}
else
{
// 打包
if
err
:
=
utils
.
ZipFiles
(
"./ginvueadmin.zip"
,
fileList
,
"."
,
"."
);
err
!=
nil
{
if
err
=
utils
.
ZipFiles
(
"./ginvueadmin.zip"
,
fileList
,
"."
,
"."
);
err
!=
nil
{
return
err
}
}
if
autoCode
.
TableName
!=
""
{
err
=
CreateAutoCodeHistory
(
bf
.
String
(),
injectionCodeMeta
.
String
(),
autoCode
.
TableName
,
idBf
.
String
(),
)
}
else
{
err
=
CreateAutoCodeHistory
(
bf
.
String
(),
injectionCodeMeta
.
String
(),
autoCode
.
StructName
,
idBf
.
String
(),
)
}
if
err
!=
nil
{
return
err
}
if
autoCode
.
AutoMoveFile
{
return
errors
.
New
(
"创建代码成功并移动文件成功"
)
}
return
nil
}
//@author: [piexlmax](https://github.com/piexlmax)
...
...
@@ -215,6 +257,10 @@ func GetColumn(tableName string, dbName string) (err error, Columns []request.Co
return
err
,
Columns
}
func
DropTable
(
tableName
string
)
error
{
return
global
.
GVA_DB
.
Exec
(
"DROP TABLE "
+
tableName
)
.
Error
}
//@author: [SliverHorn](https://github.com/SliverHorn)
//@author: [songzhibin97](https://github.com/songzhibin97)
//@function: addAutoMoveFile
...
...
@@ -267,7 +313,7 @@ func addAutoMoveFile(data *tplData) {
//@param: a *model.AutoCodeStruct
//@return: err error
func
AutoCreateApi
(
a
*
model
.
AutoCodeStruct
)
(
err
error
)
{
func
AutoCreateApi
(
a
*
model
.
AutoCodeStruct
)
(
ids
[]
uint
,
err
error
)
{
var
apiList
=
[]
model
.
SysApi
{
{
Path
:
"/"
+
a
.
Abbreviation
+
"/"
+
"create"
+
a
.
StructName
,
...
...
@@ -307,17 +353,20 @@ func AutoCreateApi(a *model.AutoCodeStruct) (err error) {
},
}
err
=
global
.
GVA_DB
.
Transaction
(
func
(
tx
*
gorm
.
DB
)
error
{
for
_
,
v
:=
range
apiList
{
var
api
model
.
SysApi
if
errors
.
Is
(
tx
.
Where
(
"path = ? AND method = ?"
,
v
.
Path
,
v
.
Method
)
.
First
(
&
api
)
.
Error
,
gorm
.
ErrRecordNotFound
)
{
if
err
:
=
tx
.
Create
(
&
v
)
.
Error
;
err
!=
nil
{
// 遇到错误时回滚事务
if
err
=
tx
.
Create
(
&
v
)
.
Error
;
err
!=
nil
{
// 遇到错误时回滚事务
return
err
}
else
{
ids
=
append
(
ids
,
v
.
ID
)
}
}
}
return
nil
})
return
err
return
ids
,
err
}
func
getNeedList
(
autoCode
*
model
.
AutoCodeStruct
)
(
dataList
[]
tplData
,
fileList
[]
string
,
needMkdir
[]
string
,
err
error
)
{
...
...
@@ -361,10 +410,10 @@ func getNeedList(autoCode *model.AutoCodeStruct) (dataList []tplData, fileList [
firstDot
:=
strings
.
Index
(
origFileName
,
"."
)
if
firstDot
!=
-
1
{
var
fileName
string
if
origFileName
[
firstDot
:
]
!=
".go"
{
fileName
=
autoCode
.
PackageName
+
origFileName
[
firstDot
:
]
}
else
{
fileName
=
autoCode
.
HumpPackageName
+
origFileName
[
firstDot
:
]
if
origFileName
[
firstDot
:
]
!=
".go"
{
fileName
=
autoCode
.
PackageName
+
origFileName
[
firstDot
:
]
}
else
{
fileName
=
autoCode
.
HumpPackageName
+
origFileName
[
firstDot
:
]
}
dataList
[
index
]
.
autoCodePath
=
filepath
.
Join
(
autoPath
,
trimBase
[
:
lastSeparator
],
autoCode
.
PackageName
,
...
...
server/service/sys_autocode_history.go
0 → 100644
浏览文件 @
dcba0898
package
service
import
(
"errors"
"gin-vue-admin/global"
"gin-vue-admin/model"
"gin-vue-admin/model/request"
"gin-vue-admin/utils"
"strings"
"go.uber.org/zap"
)
// CreateAutoCodeHistory RouterPath : RouterPath@RouterString;RouterPath2@RouterString2
func
CreateAutoCodeHistory
(
autoCodeMeta
string
,
injectionMeta
string
,
tableName
string
,
apiIds
string
)
error
{
return
global
.
GVA_DB
.
Create
(
&
model
.
SysAutoCodeHistory
{
AutoCodeMeta
:
autoCodeMeta
,
InjectionMeta
:
injectionMeta
,
TableName
:
tableName
,
ApiIDs
:
apiIds
,
})
.
Error
}
// RollBack 回滚
func
RollBack
(
id
uint
)
error
{
md
:=
model
.
SysAutoCodeHistory
{}
if
err
:=
global
.
GVA_DB
.
First
(
&
md
,
id
)
.
Error
;
err
!=
nil
{
return
err
}
// 清除API表
err
:=
DeleteApiByIds
(
strings
.
Split
(
md
.
ApiIDs
,
";"
))
if
err
!=
nil
{
global
.
GVA_LOG
.
Error
(
"ClearTag DeleteApiByIds:"
,
zap
.
Error
(
err
))
}
// 获取全部表名
err
,
dbNames
:=
GetTables
(
global
.
GVA_CONFIG
.
Mysql
.
Dbname
)
if
err
!=
nil
{
global
.
GVA_LOG
.
Error
(
"ClearTag GetTables:"
,
zap
.
Error
(
err
))
}
// 删除表
for
_
,
name
:=
range
dbNames
{
if
strings
.
Contains
(
strings
.
ToUpper
(
strings
.
Replace
(
name
.
TableName
,
"_"
,
""
,
-
1
)),
strings
.
ToUpper
(
md
.
TableName
))
{
// 删除表
if
err
=
DropTable
(
name
.
TableName
);
err
!=
nil
{
global
.
GVA_LOG
.
Error
(
"ClearTag DropTable:"
,
zap
.
Error
(
err
))
}
}
}
// 删除文件
for
_
,
path
:=
range
strings
.
Split
(
md
.
AutoCodeMeta
,
";"
)
{
_
=
utils
.
DeLFile
(
path
)
}
// 清除注入
for
_
,
v
:=
range
strings
.
Split
(
md
.
InjectionMeta
,
";"
)
{
// RouterPath@functionName@RouterString
meta
:=
strings
.
Split
(
v
,
"@"
)
if
len
(
meta
)
!=
3
{
return
errors
.
New
(
"split InjectionMeta Err"
)
}
_
=
utils
.
AutoClearCode
(
meta
[
0
],
meta
[
2
])
}
md
.
Flag
=
1
return
global
.
GVA_DB
.
Save
(
&
md
)
.
Error
}
func
GetSysHistoryPage
(
info
request
.
PageInfo
)
(
err
error
,
list
interface
{},
total
int64
)
{
limit
:=
info
.
PageSize
offset
:=
info
.
PageSize
*
(
info
.
Page
-
1
)
db
:=
global
.
GVA_DB
var
fileLists
[]
model
.
SysAutoCodeHistory
err
=
db
.
Find
(
&
fileLists
)
.
Count
(
&
total
)
.
Error
err
=
db
.
Limit
(
limit
)
.
Offset
(
offset
)
.
Order
(
"updated_at desc"
)
.
Find
(
&
fileLists
)
.
Error
return
err
,
fileLists
,
total
}
server/service/sys_initdb.go
浏览文件 @
dcba0898
...
...
@@ -131,6 +131,7 @@ func InitDB(conf request.InitDB) error {
model
.
ExaSimpleUploader
{},
model
.
ExaCustomer
{},
model
.
SysOperationRecord
{},
model
.
SysAutoCodeHistory
{},
)
if
err
!=
nil
{
global
.
GVA_DB
=
nil
...
...
server/utils/file_operations.go
浏览文件 @
dcba0898
...
...
@@ -42,6 +42,10 @@ Redirect:
return
os
.
Rename
(
src
,
dst
)
}
func
DeLFile
(
filePath
string
)
error
{
return
os
.
RemoveAll
(
filePath
)
}
//@author: [songzhibin97](https://github.com/songzhibin97)
//@function: TrimSpace
//@description: 去除结构体空格
...
...
server/utils/injectionCode.go
浏览文件 @
dcba0898
package
utils
import
(
"errors"
"fmt"
"go/ast"
"go/parser"
...
...
@@ -15,9 +16,18 @@ import (
//@param: filepath string, funcName string, codeData string
//@return: error
const
(
startComment
=
"Code generated by gin-vue-admin Begin; DO NOT EDIT."
endComment
=
"Code generated by gin-vue-admin End; DO NOT EDIT."
)
//@author: [LeonardWang](https://github.com/WangLeonard)
//@function: AutoInjectionCode
//@description: 向文件中固定注释位置写入代码
//@param: filepath string, funcName string, codeData string
//@return: error
func
AutoInjectionCode
(
filepath
string
,
funcName
string
,
codeData
string
)
error
{
startComment
:=
"Code generated by gin-vue-admin Begin; DO NOT EDIT."
endComment
:=
"Code generated by gin-vue-admin End; DO NOT EDIT."
srcData
,
err
:=
ioutil
.
ReadFile
(
filepath
)
if
err
!=
nil
{
return
err
...
...
@@ -141,3 +151,30 @@ func checkExist(srcData *[]byte, startPos int, endPos int, blockStmt *ast.BlockS
}
return
false
}
func
AutoClearCode
(
filepath
string
,
codeData
string
)
error
{
srcData
,
err
:=
ioutil
.
ReadFile
(
filepath
)
if
err
!=
nil
{
return
err
}
srcData
,
err
=
cleanCode
(
codeData
,
string
(
srcData
))
if
err
!=
nil
{
return
err
}
return
ioutil
.
WriteFile
(
filepath
,
srcData
,
0600
)
}
func
cleanCode
(
clearCode
string
,
srcData
string
)
([]
byte
,
error
)
{
bf
:=
make
([]
rune
,
0
,
1024
)
for
i
,
v
:=
range
srcData
{
if
v
==
'\n'
{
if
strings
.
TrimSpace
(
string
(
bf
))
==
clearCode
{
return
append
([]
byte
(
srcData
[
:
i
-
len
(
bf
)]),
[]
byte
(
srcData
[
i
+
1
:
])
...
),
nil
}
bf
=
(
bf
)[
:
0
]
continue
}
bf
=
append
(
bf
,
v
)
}
return
[]
byte
(
srcData
),
errors
.
New
(
"未找到内容"
)
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录