Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
FLIPPED-AURORA
gin-vue-admin
提交
e37fdb07
G
gin-vue-admin
项目概览
FLIPPED-AURORA
/
gin-vue-admin
大约 1 年 前同步成功
通知
332
Star
18154
Fork
5505
代码
文件
提交
分支
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,发现更多精彩内容 >>
提交
e37fdb07
编写于
7月 20, 2021
作者:
S
songzhibin97
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'master' into develop
上级
ab2dd0c3
ea693efc
变更
25
显示空白变更内容
内联
并排
Showing
25 changed file
with
559 addition
and
37 deletion
+559
-37
server/api/v1/sys_auto_code.go
server/api/v1/sys_auto_code.go
+89
-2
server/global/global.go
server/global/global.go
+1
-1
server/go.mod
server/go.mod
+1
-5
server/initialize/gorm.go
server/initialize/gorm.go
+1
-1
server/initialize/redis.go
server/initialize/redis.go
+4
-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
+18
-0
server/router/sys_auto_code.go
server/router/sys_auto_code.go
+9
-5
server/service/jwt_black_list.go
server/service/jwt_black_list.go
+5
-3
server/service/sys_api.go
server/service/sys_api.go
+4
-0
server/service/sys_auto_code.go
server/service/sys_auto_code.go
+71
-10
server/service/sys_autocode_history.go
server/service/sys_autocode_history.go
+87
-0
server/service/sys_initdb.go
server/service/sys_initdb.go
+1
-0
server/source/api.go
server/source/api.go
+4
-0
server/source/authorities_menus.go
server/source/authorities_menus.go
+2
-0
server/source/casbin.go
server/source/casbin.go
+4
-0
server/source/menu.go
server/source/menu.go
+2
-0
server/utils/file_operations.go
server/utils/file_operations.go
+4
-0
server/utils/injectionCode.go
server/utils/injectionCode.go
+39
-2
web/Dockerfile
web/Dockerfile
+1
-2
web/public/index.html
web/public/index.html
+1
-1
web/src/api/autoCode.js
web/src/api/autoCode.js
+32
-0
web/src/view/systemTools/autoCode/index.vue
web/src/view/systemTools/autoCode/index.vue
+11
-2
web/src/view/systemTools/autoCodeAdmin/index.vue
web/src/view/systemTools/autoCodeAdmin/index.vue
+159
-0
未找到文件。
server/api/v1/sys_auto_code.go
浏览文件 @
e37fdb07
...
...
@@ -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,89 @@ import (
"go.uber.org/zap"
)
// @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/delSysHistory [post]
func
DelSysHistory
(
c
*
gin
.
Context
)
{
var
id
request
.
AutoHistoryByID
_
=
c
.
ShouldBindJSON
(
&
id
)
err
:=
service
.
DeletePage
(
id
.
ID
)
if
err
!=
nil
{
global
.
GVA_LOG
.
Error
(
"获取失败!"
,
zap
.
Any
(
"err"
,
err
))
response
.
FailWithMessage
(
"获取失败"
,
c
)
}
response
.
OkWithMessage
(
"删除成功"
,
c
)
}
// @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/getSysHistory [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/rollback [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
// @accept application/json
// @Produce application/json
// @Param data body request.AutoHistoryByID true "获取meta信息"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /autoCode/getMeta [post]
func
GetMeta
(
c
*
gin
.
Context
)
{
var
id
request
.
AutoHistoryByID
_
=
c
.
ShouldBindJSON
(
&
id
)
if
v
,
err
:=
service
.
GetMeta
(
id
.
ID
);
err
!=
nil
{
response
.
FailWithMessage
(
err
.
Error
(),
c
)
return
}
else
{
response
.
OkWithDetailed
(
gin
.
H
{
"meta"
:
v
},
"获取成功"
,
c
)
}
}
// @Tags AutoCode
// @Summary 预览创建后的代码
// @Security ApiKeyAuth
...
...
@@ -54,15 +138,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/global/global.go
浏览文件 @
e37fdb07
...
...
@@ -9,7 +9,7 @@ import (
"gin-vue-admin/config"
"github.com/go-redis/redis"
"github.com/go-redis/redis
/v8
"
"github.com/spf13/viper"
"gorm.io/gorm"
)
...
...
server/go.mod
浏览文件 @
e37fdb07
...
...
@@ -20,8 +20,8 @@ require (
github.com/go-openapi/swag v0.19.8 // indirect
github.com/go-playground/validator/v10 v10.3.0 // indirect
github.com/go-redis/redis v6.15.7+incompatible
github.com/go-redis/redis/v8 v8.11.0
github.com/go-sql-driver/mysql v1.5.0
github.com/golang/protobuf v1.4.2 // indirect
github.com/gookit/color v1.3.1
github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869 // indirect
github.com/jordan-wright/email v0.0.0-20200824153738-3f5bafa1cd84
...
...
@@ -31,8 +31,6 @@ require (
github.com/mailru/easyjson v0.7.1 // indirect
github.com/mitchellh/mapstructure v1.2.2 // indirect
github.com/mojocn/base64Captcha v1.3.1
github.com/onsi/ginkgo v1.7.0 // indirect
github.com/onsi/gomega v1.4.3 // indirect
github.com/pelletier/go-toml v1.6.0 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/qiniu/api.v7/v7 v7.4.1
...
...
@@ -52,10 +50,8 @@ require (
go.uber.org/zap v1.10.0
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 // indirect
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
golang.org/x/tools v0.0.0-20200324003944-a576cf524670 // indirect
google.golang.org/protobuf v1.24.0 // indirect
gopkg.in/ini.v1 v1.55.0 // indirect
gopkg.in/yaml.v2 v2.3.0 // indirect
gorm.io/driver/mysql v1.0.1
gorm.io/gorm v1.20.7
)
server/initialize/gorm.go
浏览文件 @
e37fdb07
...
...
@@ -48,7 +48,7 @@ func MysqlTables(db *gorm.DB) {
model
.
ExaSimpleUploader
{},
model
.
ExaCustomer
{},
model
.
SysOperationRecord
{},
model
.
SysAutoCodeHistory
{},
// Code generated by gin-vue-admin Begin; DO NOT EDIT.
// Code generated by gin-vue-admin End; DO NOT EDIT.
)
...
...
server/initialize/redis.go
浏览文件 @
e37fdb07
package
initialize
import
(
"context"
"gin-vue-admin/global"
"github.com/go-redis/redis"
"github.com/go-redis/redis/v8"
"go.uber.org/zap"
)
...
...
@@ -13,7 +15,7 @@ func Redis() {
Password
:
redisCfg
.
Password
,
// no password set
DB
:
redisCfg
.
DB
,
// use default DB
})
pong
,
err
:=
client
.
Ping
()
.
Result
()
pong
,
err
:=
client
.
Ping
(
context
.
Background
()
)
.
Result
()
if
err
!=
nil
{
global
.
GVA_LOG
.
Error
(
"redis connect ping failed, err:"
,
zap
.
Any
(
"err"
,
err
))
}
else
{
...
...
server/model/request/sys_autocode.go
浏览文件 @
e37fdb07
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
浏览文件 @
e37fdb07
server/model/sys_autocode_history.go
0 → 100644
浏览文件 @
e37fdb07
package
model
import
"gin-vue-admin/global"
// 自动迁移代码记录,用于回滚,重放使用
type
SysAutoCodeHistory
struct
{
global
.
GVA_MODEL
TableName
string
`json:"tableName"`
RequestMeta
string
`gorm:"type:text" json:"requestMeta,omitempty"`
// 前端传入的结构化信息
AutoCodePath
string
`gorm:"type:text" json:"autoCodePath,omitempty"`
// 其他meta信息 path;path
InjectionMeta
string
`gorm:"type:text" json:"injectionMeta,omitempty"`
// 注入的内容 RouterPath@functionName@RouterString;
StructName
string
`json:"structName"`
StructCNName
string
`json:"structCNName"`
ApiIDs
string
`json:"apiIDs,omitempty"`
// api表注册内容
Flag
int
`json:"flag"`
// 表示对应状态 0 代表创建, 1 代表回滚 ...
}
server/router/sys_auto_code.go
浏览文件 @
e37fdb07
...
...
@@ -8,6 +8,10 @@ import (
func
InitAutoCodeRouter
(
Router
*
gin
.
RouterGroup
)
{
AutoCodeRouter
:=
Router
.
Group
(
"autoCode"
)
{
AutoCodeRouter
.
POST
(
"delSysHistory"
,
v1
.
DelSysHistory
)
// 删除回滚记录
AutoCodeRouter
.
POST
(
"getMeta"
,
v1
.
GetMeta
)
// 根据id获取meta信息
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/jwt_black_list.go
浏览文件 @
e37fdb07
package
service
import
(
"context"
"errors"
"gin-vue-admin/global"
"gin-vue-admin/model"
"gorm.io/gorm"
"time"
"gorm.io/gorm"
)
//@author: [piexlmax](https://github.com/piexlmax)
...
...
@@ -38,7 +40,7 @@ func IsBlacklist(jwt string) bool {
//@return: err error, redisJWT string
func
GetRedisJWT
(
userName
string
)
(
err
error
,
redisJWT
string
)
{
redisJWT
,
err
=
global
.
GVA_REDIS
.
Get
(
userName
)
.
Result
()
redisJWT
,
err
=
global
.
GVA_REDIS
.
Get
(
context
.
Background
(),
userName
)
.
Result
()
return
err
,
redisJWT
}
...
...
@@ -51,6 +53,6 @@ func GetRedisJWT(userName string) (err error, redisJWT string) {
func
SetRedisJWT
(
jwt
string
,
userName
string
)
(
err
error
)
{
// 此处过期时间等于jwt过期时间
timer
:=
time
.
Duration
(
global
.
GVA_CONFIG
.
JWT
.
ExpiresTime
)
*
time
.
Second
err
=
global
.
GVA_REDIS
.
Set
(
userName
,
jwt
,
timer
)
.
Err
()
err
=
global
.
GVA_REDIS
.
Set
(
context
.
Background
(),
userName
,
jwt
,
timer
)
.
Err
()
return
err
}
server/service/sys_api.go
浏览文件 @
e37fdb07
...
...
@@ -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
浏览文件 @
e37fdb07
package
service
import
(
"encoding/json"
"errors"
"fmt"
"gin-vue-admin/global"
"gin-vue-admin/model"
"gin-vue-admin/model/request"
...
...
@@ -9,6 +11,7 @@ import (
"io/ioutil"
"os"
"path/filepath"
"strconv"
"strings"
"text/template"
...
...
@@ -98,11 +101,12 @@ 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
}
meta
,
_
:=
json
.
Marshal
(
autoCode
)
// 写入文件前,先创建文件夹
if
err
=
utils
.
CreateDir
(
needMkdir
...
);
err
!=
nil
{
return
err
...
...
@@ -125,6 +129,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 +157,61 @@ 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
.
AutoMoveFile
||
autoCode
.
AutoCreateApiToSql
{
if
autoCode
.
TableName
!=
""
{
err
=
CreateAutoCodeHistory
(
string
(
meta
),
autoCode
.
StructName
,
autoCode
.
Description
,
bf
.
String
(),
injectionCodeMeta
.
String
(),
autoCode
.
TableName
,
idBf
.
String
(),
)
}
else
{
err
=
CreateAutoCodeHistory
(
string
(
meta
),
autoCode
.
StructName
,
autoCode
.
Description
,
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 +269,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 +325,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 +365,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 +422,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
浏览文件 @
e37fdb07
package
service
import
(
"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
(
meta
,
structName
,
structCNName
,
autoCodePath
string
,
injectionMeta
string
,
tableName
string
,
apiIds
string
)
error
{
return
global
.
GVA_DB
.
Create
(
&
model
.
SysAutoCodeHistory
{
RequestMeta
:
meta
,
AutoCodePath
:
autoCodePath
,
InjectionMeta
:
injectionMeta
,
StructName
:
structName
,
StructCNName
:
structCNName
,
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
.
AutoCodePath
,
";"
)
{
_
=
utils
.
DeLFile
(
path
)
}
// 清除注入
for
_
,
v
:=
range
strings
.
Split
(
md
.
InjectionMeta
,
";"
)
{
// RouterPath@functionName@RouterString
meta
:=
strings
.
Split
(
v
,
"@"
)
if
len
(
meta
)
==
3
{
_
=
utils
.
AutoClearCode
(
meta
[
0
],
meta
[
2
])
}
}
md
.
Flag
=
1
return
global
.
GVA_DB
.
Save
(
&
md
)
.
Error
}
func
GetMeta
(
id
uint
)
(
string
,
error
)
{
var
meta
string
return
meta
,
global
.
GVA_DB
.
Model
(
model
.
SysAutoCodeHistory
{})
.
Select
(
"request_meta"
)
.
First
(
&
meta
,
id
)
.
Error
}
// GetSysHistoryPage 获取系统历史数据
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"
)
.
Select
(
"id,created_at,updated_at,struct_name,struct_cn_name,flag,table_name"
)
.
Find
(
&
fileLists
)
.
Error
return
err
,
fileLists
,
total
}
// DeletePage 删除历史数据
func
DeletePage
(
id
uint
)
error
{
return
global
.
GVA_DB
.
Delete
(
model
.
SysAutoCodeHistory
{},
id
)
.
Error
}
server/service/sys_initdb.go
浏览文件 @
e37fdb07
...
...
@@ -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/source/api.go
浏览文件 @
e37fdb07
...
...
@@ -86,6 +86,10 @@ var apis = []model.SysApi{
{
global
.
GVA_MODEL
{
ID
:
83
,
CreatedAt
:
time
.
Now
(),
UpdatedAt
:
time
.
Now
()},
"/excel/exportExcel"
,
"导出excel"
,
"excel"
,
"POST"
},
{
global
.
GVA_MODEL
{
ID
:
84
,
CreatedAt
:
time
.
Now
(),
UpdatedAt
:
time
.
Now
()},
"/excel/downloadTemplate"
,
"下载excel模板"
,
"excel"
,
"GET"
},
{
global
.
GVA_MODEL
{
ID
:
85
,
CreatedAt
:
time
.
Now
(),
UpdatedAt
:
time
.
Now
()},
"/api/deleteApisByIds"
,
"批量删除api"
,
"api"
,
"DELETE"
},
{
global
.
GVA_MODEL
{
ID
:
86
,
CreatedAt
:
time
.
Now
(),
UpdatedAt
:
time
.
Now
()},
"/autoCode/getSysHistory"
,
"查询回滚记录"
,
"autoCode"
,
"POST"
},
{
global
.
GVA_MODEL
{
ID
:
87
,
CreatedAt
:
time
.
Now
(),
UpdatedAt
:
time
.
Now
()},
"/autoCode/rollback"
,
"回滚自动生成代码"
,
"autoCode"
,
"POST"
},
{
global
.
GVA_MODEL
{
ID
:
88
,
CreatedAt
:
time
.
Now
(),
UpdatedAt
:
time
.
Now
()},
"/autoCode/getMeta"
,
"获取meta信息"
,
"autoCode"
,
"POST"
},
{
global
.
GVA_MODEL
{
ID
:
89
,
CreatedAt
:
time
.
Now
(),
UpdatedAt
:
time
.
Now
()},
"/autoCode/delSysHistory"
,
"删除回滚记录"
,
"autoCode"
,
"POST"
},
}
//@author: [SliverHorn](https://github.com/SliverHorn)
...
...
server/source/authorities_menus.go
浏览文件 @
e37fdb07
...
...
@@ -39,6 +39,8 @@ var authorityMenus = []AuthorityMenus{
{
"888"
,
21
},
{
"888"
,
22
},
{
"888"
,
23
},
{
"888"
,
24
},
{
"888"
,
25
},
{
"8881"
,
1
},
{
"8881"
,
2
},
{
"8881"
,
8
},
...
...
server/source/casbin.go
浏览文件 @
e37fdb07
...
...
@@ -86,6 +86,10 @@ var carbines = []gormadapter.CasbinRule{
{
PType
:
"p"
,
V0
:
"888"
,
V1
:
"/excel/exportExcel"
,
V2
:
"POST"
},
{
PType
:
"p"
,
V0
:
"888"
,
V1
:
"/excel/downloadTemplate"
,
V2
:
"GET"
},
{
PType
:
"p"
,
V0
:
"888"
,
V1
:
"/api/deleteApisByIds"
,
V2
:
"DELETE"
},
{
PType
:
"p"
,
V0
:
"888"
,
V1
:
"/autoCode/getSysHistory"
,
V2
:
"POST"
},
{
PType
:
"p"
,
V0
:
"888"
,
V1
:
"/autoCode/rollback"
,
V2
:
"POST"
},
{
PType
:
"p"
,
V0
:
"888"
,
V1
:
"/autoCode/getMeta"
,
V2
:
"POST"
},
{
PType
:
"p"
,
V0
:
"888"
,
V1
:
"/autoCode/delSysHistory"
,
V2
:
"POST"
},
{
PType
:
"p"
,
V0
:
"8881"
,
V1
:
"/base/login"
,
V2
:
"POST"
},
{
PType
:
"p"
,
V0
:
"8881"
,
V1
:
"/user/register"
,
V2
:
"POST"
},
{
PType
:
"p"
,
V0
:
"8881"
,
V1
:
"/api/createApi"
,
V2
:
"POST"
},
...
...
server/source/menu.go
浏览文件 @
e37fdb07
...
...
@@ -37,6 +37,8 @@ var menus = []model.SysBaseMenu{
{
GVA_MODEL
:
global
.
GVA_MODEL
{
ID
:
21
,
CreatedAt
:
time
.
Now
(),
UpdatedAt
:
time
.
Now
()},
MenuLevel
:
0
,
Hidden
:
false
,
ParentId
:
"9"
,
Path
:
"simpleUploader"
,
Name
:
"simpleUploader"
,
Component
:
"view/example/simpleUploader/simpleUploader"
,
Sort
:
6
,
Meta
:
model
.
Meta
{
Title
:
"断点续传(插件版)"
,
Icon
:
"upload"
}},
{
GVA_MODEL
:
global
.
GVA_MODEL
{
ID
:
22
,
CreatedAt
:
time
.
Now
(),
UpdatedAt
:
time
.
Now
()},
MenuLevel
:
0
,
ParentId
:
"0"
,
Path
:
"https://www.gin-vue-admin.com"
,
Name
:
"https://www.gin-vue-admin.com"
,
Hidden
:
false
,
Component
:
"/"
,
Sort
:
0
,
Meta
:
model
.
Meta
{
Title
:
"官方网站"
,
Icon
:
"s-home"
}},
{
GVA_MODEL
:
global
.
GVA_MODEL
{
ID
:
23
,
CreatedAt
:
time
.
Now
(),
UpdatedAt
:
time
.
Now
()},
MenuLevel
:
0
,
ParentId
:
"0"
,
Path
:
"state"
,
Name
:
"state"
,
Hidden
:
false
,
Component
:
"view/system/state.vue"
,
Sort
:
6
,
Meta
:
model
.
Meta
{
Title
:
"服务器状态"
,
Icon
:
"cloudy"
}},
{
GVA_MODEL
:
global
.
GVA_MODEL
{
ID
:
24
,
CreatedAt
:
time
.
Now
(),
UpdatedAt
:
time
.
Now
()},
MenuLevel
:
0
,
ParentId
:
"14"
,
Path
:
"autoCodeAdmin"
,
Name
:
"autoCodeAdmin"
,
Hidden
:
false
,
Component
:
"view/systemTools/autoCodeAdmin/index.vue"
,
Sort
:
1
,
Meta
:
model
.
Meta
{
Title
:
"自动化代码管理"
,
Icon
:
"s-finance"
}},
{
GVA_MODEL
:
global
.
GVA_MODEL
{
ID
:
25
,
CreatedAt
:
time
.
Now
(),
UpdatedAt
:
time
.
Now
()},
MenuLevel
:
0
,
ParentId
:
"14"
,
Path
:
"autoCodeEdit/:id"
,
Name
:
"autoCodeEdit"
,
Hidden
:
true
,
Component
:
"view/systemTools/autoCode/index.vue"
,
Sort
:
0
,
Meta
:
model
.
Meta
{
Title
:
"自动化代码(复用)"
,
Icon
:
"s-finance"
}},
}
//@author: [SliverHorn](https://github.com/SliverHorn)
...
...
server/utils/file_operations.go
浏览文件 @
e37fdb07
...
...
@@ -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
浏览文件 @
e37fdb07
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
(
"未找到内容"
)
}
web/Dockerfile
浏览文件 @
e37fdb07
...
...
@@ -3,8 +3,7 @@ FROM node:12.16.1
WORKDIR
/gva_web/
COPY
. .
RUN
npm
install
-g
cnpm
--registry
=
https://registry.npm.taobao.org
RUN
cnpm
install
||
npm
install
RUN
npm
install
RUN
npm run build
FROM
nginx:alpine
...
...
web/public/index.html
浏览文件 @
e37fdb07
...
...
@@ -8,7 +8,7 @@
<meta
name=
"viewport"
content=
"width=device-width,initial-scale=1.0"
>
<link
rel=
"icon"
href=
"<%= BASE_URL %>favicon.ico"
>
<title><
%=
htmlWebpackPlugin.options.title
%
></title>
<
%
if
(
process.env.NODE_ENV
!=='
development
'){
%
>
<
%
if
(
process.env.NODE_ENV
!=='
development
'
&&
htmlWebpackPlugin.options.cdns
){
%
>
<
%
htmlWebpackPlugin.options.cdns.forEach
(
function
(
item
){
if
(
item.js
){
%
>
<script
type=
"text/javascript"
src=
"<%= item.js %>"
></script>
<
%
}
})
%
>
...
...
web/src/api/autoCode.js
浏览文件 @
e37fdb07
...
...
@@ -60,3 +60,35 @@ export const getColumn = (params) => {
params
})
}
export
const
getSysHistory
=
(
data
)
=>
{
return
service
({
url
:
'
/autoCode/getSysHistory
'
,
method
:
'
post
'
,
data
})
}
export
const
rollback
=
(
data
)
=>
{
return
service
({
url
:
'
/autoCode/rollback
'
,
method
:
'
post
'
,
data
})
}
export
const
getMeta
=
(
data
)
=>
{
return
service
({
url
:
'
/autoCode/getMeta
'
,
method
:
'
post
'
,
data
})
}
export
const
delSysHistory
=
(
data
)
=>
{
return
service
({
url
:
'
/autoCode/delSysHistory
'
,
method
:
'
post
'
,
data
})
}
web/src/view/systemTools/autoCode/index.vue
浏览文件 @
e37fdb07
...
...
@@ -165,7 +165,7 @@ const fieldTemplate = {
import
FieldDialog
from
'
@/view/systemTools/autoCode/component/fieldDialog.vue
'
import
PreviewCodeDialg
from
'
@/view/systemTools/autoCode/component/previewCodeDialg.vue
'
import
{
toUpperCase
,
toHump
,
toSQLLine
}
from
'
@/utils/stringFun
'
import
{
createTemp
,
getDB
,
getTable
,
getColumn
,
preview
}
from
'
@/api/autoCode
'
import
{
createTemp
,
getDB
,
getTable
,
getColumn
,
preview
,
getMeta
}
from
'
@/api/autoCode
'
import
{
getDict
}
from
'
@/utils/dictionary
'
export
default
{
...
...
@@ -223,6 +223,10 @@ export default {
created
()
{
this
.
getDb
()
this
.
setFdMap
()
const
id
=
this
.
$route
.
params
.
id
if
(
id
)
{
this
.
getAutoCodeJson
(
id
)
}
},
methods
:
{
editAndAddField
(
item
)
{
...
...
@@ -305,7 +309,6 @@ export default {
return
false
}
this
.
form
.
humpPackageName
=
toSQLLine
(
this
.
form
.
packageName
)
debugger
if
(
isPreview
)
{
const
data
=
await
preview
(
this
.
form
)
this
.
preViewCode
=
data
.
data
.
autoCode
...
...
@@ -396,6 +399,12 @@ export default {
this
.
fdMap
[
item
.
label
]
=
fdtype
})
})
},
async
getAutoCodeJson
(
id
)
{
const
res
=
await
getMeta
({
id
:
Number
(
id
)
})
if
(
res
.
code
===
0
)
{
this
.
form
=
JSON
.
parse
(
res
.
data
.
meta
)
}
}
}
}
...
...
web/src/view/systemTools/autoCodeAdmin/index.vue
0 → 100644
浏览文件 @
e37fdb07
<
template
>
<div>
<div
class=
"search-term"
>
<el-form
:inline=
"true"
:model=
"searchInfo"
class=
"demo-form-inline"
>
<el-form-item
label=
"表名"
>
<el-input
v-model=
"searchInfo.tableName"
placeholder=
"表名"
/>
</el-form-item>
<el-form-item
label=
"结构体名称"
>
<el-input
v-model=
"searchInfo.structName"
placeholder=
"结构体名称"
/>
</el-form-item>
<el-form-item>
<el-button
size=
"mini"
type=
"primary"
icon=
"el-icon-plus"
@
click=
"goAutoCode(null)"
>
新增
</el-button>
</el-form-item>
</el-form>
</div>
<el-table
:data=
"tableData"
border
stripe
>
<el-table-column
type=
"selection"
width=
"55"
/>
<el-table-column
label=
"id"
width=
"60"
prop=
"ID"
/>
<el-table-column
label=
"日期"
width=
"180"
>
<template
slot-scope=
"scope"
>
{{
scope
.
row
.
CreatedAt
|
formatDate
}}
</
template
>
</el-table-column>
<el-table-column
label=
"结构体名"
min-width=
"150"
prop=
"structName"
/>
<el-table-column
label=
"结构体描述"
min-width=
"150"
prop=
"structCNName"
/>
<el-table-column
label=
"表名称"
min-width=
"150"
prop=
"tableName"
/>
<el-table-column
label=
"回滚标记"
min-width=
"150"
prop=
"flag"
>
<
template
slot-scope=
"scope"
>
<el-tag
v-if=
"scope.row.flag"
type=
"danger"
size=
"mini"
effect=
"dark"
>
已回滚
</el-tag>
<el-tag
v-else
size=
"mini"
type=
"success"
effect=
"dark"
>
未回滚
</el-tag>
</
template
>
</el-table-column>
<el-table-column
label=
"操作"
min-width=
"180"
>
<
template
slot-scope=
"scope"
>
<div>
<el-button
size=
"mini"
type=
"primary"
:disabled=
"scope.row.flag === 1"
@
click=
"rollback(scope.row)"
>
回滚
</el-button>
<el-button
size=
"mini"
type=
"success"
@
click=
"goAutoCode(scope.row)"
>
复用
</el-button>
<el-button
size=
"mini"
type=
"danger"
@
click=
"deleteRow(scope.row)"
>
删除
</el-button>
</div>
</
template
>
</el-table-column>
</el-table>
<el-pagination
:current-page=
"page"
:page-size=
"pageSize"
:page-sizes=
"[10, 30, 50, 100]"
:style=
"{float:'right',padding:'20px'}"
:total=
"total"
layout=
"total, sizes, prev, pager, next, jumper"
@
current-change=
"handleCurrentChange"
@
size-change=
"handleSizeChange"
/>
</div>
</template>
<
script
>
// 获取列表内容封装在mixins内部 getTableData方法 初始化已封装完成 条件搜索时候 请把条件安好后台定制的结构体字段 放到 this.searchInfo 中即可实现条件搜索
import
{
getSysHistory
,
rollback
,
delSysHistory
}
from
'
@/api/autoCode.js
'
import
{
formatTimeToStr
}
from
'
@/utils/date
'
import
infoList
from
'
@/mixins/infoList
'
export
default
{
name
:
'
Api
'
,
filters
:
{
formatDate
:
function
(
time
)
{
if
(
time
!==
null
&&
time
!==
''
)
{
var
date
=
new
Date
(
time
)
return
formatTimeToStr
(
date
,
'
yyyy-MM-dd hh:mm:ss
'
)
}
else
{
return
''
}
},
formatBoolean
:
function
(
bool
)
{
if
(
bool
!==
null
)
{
return
bool
?
'
是
'
:
'
否
'
}
else
{
return
''
}
}
},
mixins
:
[
infoList
],
data
()
{
return
{
listApi
:
getSysHistory
}
},
created
()
{
this
.
getTableData
()
},
methods
:
{
async
deleteRow
(
row
)
{
this
.
$confirm
(
'
此操作将删除本历史, 是否继续?
'
,
'
提示
'
,
{
confirmButtonText
:
'
确定
'
,
cancelButtonText
:
'
取消
'
,
type
:
'
warning
'
}).
then
(
async
()
=>
{
const
res
=
await
delSysHistory
({
id
:
Number
(
row
.
ID
)
})
if
(
res
.
code
===
0
)
{
this
.
$message
.
success
(
'
删除成功
'
)
this
.
getTableData
()
}
})
},
async
rollback
(
row
)
{
this
.
$confirm
(
'
此操作将删除自动创建的文件和api, 是否继续?
'
,
'
提示
'
,
{
confirmButtonText
:
'
确定
'
,
cancelButtonText
:
'
取消
'
,
type
:
'
warning
'
}).
then
(
async
()
=>
{
const
res
=
await
rollback
({
id
:
Number
(
row
.
ID
)
})
if
(
res
.
code
===
0
)
{
this
.
$message
.
success
(
'
回滚成功
'
)
this
.
getTableData
()
}
})
},
goAutoCode
(
row
)
{
if
(
row
)
{
this
.
$router
.
push
({
name
:
'
autoCodeEdit
'
,
params
:
{
id
:
row
.
ID
}})
}
else
{
this
.
$router
.
push
({
name
:
'
autoCode
'
})
}
}
}
}
</
script
>
<
style
scoped
lang=
"scss"
>
.button-box
{
padding
:
10px
20px
;
.el-button
{
float
:
right
;
}
}
.el-tag--mini
{
margin-left
:
5px
;
}
.warning
{
color
:
#dc143c
;
}
</
style
>
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录