Skip to content

Commit 02f5d6f

Browse files
authored
增加同步API功能 (#1811)
* feature:新增同步API功能
1 parent 227755b commit 02f5d6f

File tree

14 files changed

+635
-28
lines changed

14 files changed

+635
-28
lines changed

server/api/v1/system/sys_api.go

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,94 @@ func (s *SystemApiApi) CreateApi(c *gin.Context) {
4545
response.OkWithMessage("创建成功", c)
4646
}
4747

48+
// SyncApi
49+
// @Tags SysApi
50+
// @Summary 同步API
51+
// @Security ApiKeyAuth
52+
// @accept application/json
53+
// @Produce application/json
54+
// @Success 200 {object} response.Response{msg=string} "同步API"
55+
// @Router /api/syncApi [get]
56+
func (s *SystemApiApi) SyncApi(c *gin.Context) {
57+
newApis, deleteApis, ignoreApis, err := apiService.SyncApi()
58+
if err != nil {
59+
global.GVA_LOG.Error("同步失败!", zap.Error(err))
60+
response.FailWithMessage("同步失败", c)
61+
return
62+
}
63+
response.OkWithData(gin.H{
64+
"newApis": newApis,
65+
"deleteApis": deleteApis,
66+
"ignoreApis": ignoreApis,
67+
}, c)
68+
}
69+
70+
// GetApiGroups
71+
// @Tags SysApi
72+
// @Summary 获取API分组
73+
// @Security ApiKeyAuth
74+
// @accept application/json
75+
// @Produce application/json
76+
// @Success 200 {object} response.Response{msg=string} "获取API分组"
77+
// @Router /api/getApiGroups [post]
78+
func (s *SystemApiApi) GetApiGroups(c *gin.Context) {
79+
groups, err := apiService.GetApiGroups()
80+
if err != nil {
81+
global.GVA_LOG.Error("获取失败!", zap.Error(err))
82+
response.FailWithMessage("获取失败", c)
83+
return
84+
}
85+
response.OkWithData(groups, c)
86+
}
87+
88+
// IgnoreApi
89+
// @Tags IgnoreApi
90+
// @Summary 忽略API
91+
// @Security ApiKeyAuth
92+
// @accept application/json
93+
// @Produce application/json
94+
// @Success 200 {object} response.Response{msg=string} "同步API"
95+
// @Router /api/ignoreApi [post]
96+
func (s *SystemApiApi) IgnoreApi(c *gin.Context) {
97+
var ignoreApi system.SysIgnoreApi
98+
err := c.ShouldBindJSON(&ignoreApi)
99+
if err != nil {
100+
response.FailWithMessage(err.Error(), c)
101+
return
102+
}
103+
err = apiService.IgnoreApi(ignoreApi)
104+
if err != nil {
105+
global.GVA_LOG.Error("忽略失败!", zap.Error(err))
106+
response.FailWithMessage("忽略失败", c)
107+
return
108+
}
109+
response.Ok(c)
110+
}
111+
112+
// EnterSyncApi
113+
// @Tags SysApi
114+
// @Summary 确认同步API
115+
// @Security ApiKeyAuth
116+
// @accept application/json
117+
// @Produce application/json
118+
// @Success 200 {object} response.Response{msg=string} "确认同步API"
119+
// @Router /api/enterSyncApi [post]
120+
func (s *SystemApiApi) EnterSyncApi(c *gin.Context) {
121+
var syncApi systemRes.SysSyncApis
122+
err := c.ShouldBindJSON(&syncApi)
123+
if err != nil {
124+
response.FailWithMessage(err.Error(), c)
125+
return
126+
}
127+
err = apiService.EnterSyncApi(syncApi)
128+
if err != nil {
129+
global.GVA_LOG.Error("忽略失败!", zap.Error(err))
130+
response.FailWithMessage("忽略失败", c)
131+
return
132+
}
133+
response.Ok(c)
134+
}
135+
48136
// DeleteApi
49137
// @Tags SysApi
50138
// @Summary 删除api

server/global/global.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package global
22

33
import (
4+
"github.com/gin-gonic/gin"
45
"github.com/qiniu/qmgo"
56
"sync"
67

@@ -29,9 +30,9 @@ var (
2930
GVA_LOG *zap.Logger
3031
GVA_Timer timer.Timer = timer.NewTimerTask()
3132
GVA_Concurrency_Control = &singleflight.Group{}
32-
33-
BlackCache local_cache.Cache
34-
lock sync.RWMutex
33+
GVA_ROUTERS gin.RoutesInfo
34+
BlackCache local_cache.Cache
35+
lock sync.RWMutex
3536
)
3637

3738
// GetGlobalDBByDBName 通过名称获取db list中的db

server/initialize/gorm.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ func RegisterTables() {
3333
err := db.AutoMigrate(
3434

3535
system.SysApi{},
36+
system.SysIgnoreApi{},
3637
system.SysUser{},
3738
system.SysBaseMenu{},
3839
system.JwtBlacklist{},

server/initialize/router.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,8 @@ func Routers() *gin.Engine {
103103
// 注册业务路由
104104
initBizRouter(PrivateGroup, PublicGroup)
105105

106+
global.GVA_ROUTERS = Router.Routes()
107+
106108
global.GVA_LOG.Info("router register success")
107109
return Router
108110
}

server/model/common/response/response.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ func OkWithMessage(message string, c *gin.Context) {
3535
}
3636

3737
func OkWithData(data interface{}, c *gin.Context) {
38-
Result(SUCCESS, data, "查询成功", c)
38+
Result(SUCCESS, data, "成功", c)
3939
}
4040

4141
func OkWithDetailed(data interface{}, message string, c *gin.Context) {
Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package response
22

3-
import "github.com/flipped-aurora/gin-vue-admin/server/model/system"
3+
import (
4+
"github.com/flipped-aurora/gin-vue-admin/server/model/system"
5+
)
46

57
type SysAPIResponse struct {
68
Api system.SysApi `json:"api"`
@@ -9,3 +11,8 @@ type SysAPIResponse struct {
911
type SysAPIListResponse struct {
1012
Apis []system.SysApi `json:"apis"`
1113
}
14+
15+
type SysSyncApis struct {
16+
NewApis []system.SysApi `json:"newApis"`
17+
DeleteApis []system.SysApi `json:"deleteApis"`
18+
}

server/model/system/sys_api.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,14 @@ type SysApi struct {
1515
func (SysApi) TableName() string {
1616
return "sys_apis"
1717
}
18+
19+
type SysIgnoreApi struct {
20+
global.GVA_MODEL
21+
Path string `json:"path" gorm:"comment:api路径"` // api路径
22+
Method string `json:"method" gorm:"default:POST;comment:方法"` // 方法:创建POST(默认)|查看GET|更新PUT|删除DELETE
23+
Flag bool `json:"flag" gorm:"-"` // 是否忽略
24+
}
25+
26+
func (SysIgnoreApi) TableName() string {
27+
return "sys_ignore_apis"
28+
}

server/router/system/sys_api.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ func (s *ApiRouter) InitApiRouter(Router *gin.RouterGroup, RouterPub *gin.Router
1515
apiPublicRouterWithoutRecord := RouterPub.Group("api")
1616
apiRouterApi := v1.ApiGroupApp.SystemApiGroup.SystemApiApi
1717
{
18+
apiRouter.GET("getApiGroups", apiRouterApi.GetApiGroups) // 获取路由组
19+
apiRouter.GET("syncApi", apiRouterApi.SyncApi) // 同步Api
20+
apiRouter.POST("ignoreApi", apiRouterApi.IgnoreApi) // 忽略Api
21+
apiRouter.POST("enterSyncApi", apiRouterApi.EnterSyncApi) // 确认同步Api
1822
apiRouter.POST("createApi", apiRouterApi.CreateApi) // 创建Api
1923
apiRouter.POST("deleteApi", apiRouterApi.DeleteApi) // 删除Api
2024
apiRouter.POST("getApiById", apiRouterApi.GetApiById) // 获取单条Api消息

server/service/system/sys_api.go

Lines changed: 108 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,10 @@ package system
33
import (
44
"errors"
55
"fmt"
6-
76
"github.com/flipped-aurora/gin-vue-admin/server/global"
87
"github.com/flipped-aurora/gin-vue-admin/server/model/common/request"
98
"github.com/flipped-aurora/gin-vue-admin/server/model/system"
10-
9+
systemRes "github.com/flipped-aurora/gin-vue-admin/server/model/system/response"
1110
"gorm.io/gorm"
1211
)
1312

@@ -28,6 +27,112 @@ func (apiService *ApiService) CreateApi(api system.SysApi) (err error) {
2827
return global.GVA_DB.Create(&api).Error
2928
}
3029

30+
func (apiService *ApiService) GetApiGroups() (groups []string, err error) {
31+
err = global.GVA_DB.Model(&system.SysApi{}).Select("DISTINCT api_group").Pluck("api_group", &groups).Error
32+
return
33+
}
34+
35+
func (apiService *ApiService) SyncApi() (newApis, deleteApis, ignoreApis []system.SysApi, err error) {
36+
newApis = make([]system.SysApi, 0)
37+
deleteApis = make([]system.SysApi, 0)
38+
ignoreApis = make([]system.SysApi, 0)
39+
var apis []system.SysApi
40+
err = global.GVA_DB.Find(&apis).Error
41+
if err != nil {
42+
return
43+
}
44+
var ignores []system.SysIgnoreApi
45+
err = global.GVA_DB.Find(&ignores).Error
46+
if err != nil {
47+
return
48+
}
49+
50+
for i := range ignores {
51+
ignoreApis = append(ignoreApis, system.SysApi{
52+
Path: ignores[i].Path,
53+
Description: "",
54+
ApiGroup: "",
55+
Method: ignores[i].Method,
56+
})
57+
}
58+
59+
var cacheApis []system.SysApi
60+
for i := range global.GVA_ROUTERS {
61+
ignoresFlag := false
62+
for j := range ignores {
63+
if ignores[j].Path == global.GVA_ROUTERS[i].Path && ignores[j].Method == global.GVA_ROUTERS[i].Method {
64+
ignoresFlag = true
65+
}
66+
}
67+
if !ignoresFlag {
68+
cacheApis = append(cacheApis, system.SysApi{
69+
Path: global.GVA_ROUTERS[i].Path,
70+
Method: global.GVA_ROUTERS[i].Method,
71+
})
72+
}
73+
}
74+
75+
//对比数据库中的api和内存中的api,如果数据库中的api不存在于内存中,则把api放入删除数组,如果内存中的api不存在于数据库中,则把api放入新增数组
76+
for i := range cacheApis {
77+
var flag bool
78+
// 如果存在于内存不存在于api数组中
79+
for j := range apis {
80+
if cacheApis[i].Path == apis[j].Path && cacheApis[i].Method == apis[j].Method {
81+
flag = true
82+
}
83+
}
84+
if !flag {
85+
newApis = append(newApis, system.SysApi{
86+
Path: cacheApis[i].Path,
87+
Description: "",
88+
ApiGroup: "",
89+
Method: cacheApis[i].Method,
90+
})
91+
}
92+
}
93+
94+
for i := range apis {
95+
var flag bool
96+
// 如果存在于api数组不存在于内存
97+
for j := range cacheApis {
98+
if cacheApis[j].Path == apis[i].Path && cacheApis[j].Method == apis[i].Method {
99+
flag = true
100+
}
101+
}
102+
if !flag {
103+
deleteApis = append(deleteApis, apis[i])
104+
}
105+
}
106+
return
107+
}
108+
109+
func (apiService *ApiService) IgnoreApi(ignoreApi system.SysIgnoreApi) (err error) {
110+
if ignoreApi.Flag {
111+
return global.GVA_DB.Create(&ignoreApi).Error
112+
}
113+
return global.GVA_DB.Unscoped().Delete(&ignoreApi, "path = ? AND method = ?", ignoreApi.Path, ignoreApi.Method).Error
114+
}
115+
116+
func (apiService *ApiService) EnterSyncApi(syncApis systemRes.SysSyncApis) (err error) {
117+
return global.GVA_DB.Transaction(func(tx *gorm.DB) error {
118+
var txErr error
119+
if syncApis.NewApis != nil && len(syncApis.NewApis) > 0 {
120+
txErr = tx.Create(&syncApis.NewApis).Error
121+
if txErr != nil {
122+
return txErr
123+
}
124+
}
125+
for i := range syncApis.DeleteApis {
126+
CasbinServiceApp.ClearCasbin(1, syncApis.DeleteApis[i].Path, syncApis.DeleteApis[i].Method)
127+
txErr = tx.Delete(&system.SysApi{}, "path = ? AND method = ?", syncApis.DeleteApis[i].Path, syncApis.DeleteApis[i].Method).Error
128+
if txErr != nil {
129+
return txErr
130+
}
131+
}
132+
return nil
133+
})
134+
}
135+
31136
//@author: [piexlmax](https://github.com/piexlmax)
32137
//@function: DeleteApi
33138
//@description: 删除基础api
@@ -44,9 +149,7 @@ func (apiService *ApiService) DeleteApi(api system.SysApi) (err error) {
44149
if err != nil {
45150
return err
46151
}
47-
if !CasbinServiceApp.ClearCasbin(1, entity.Path, entity.Method) {
48-
return errors.New("ClearCasbin 失败")
49-
}
152+
CasbinServiceApp.ClearCasbin(1, entity.Path, entity.Method)
50153
return nil
51154
}
52155

server/source/system/api.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ func (i *initApi) InitializeData(ctx context.Context) (context.Context, error) {
6363
{ApiGroup: "api", Method: "POST", Path: "/api/getAllApis", Description: "获取所有api"},
6464
{ApiGroup: "api", Method: "POST", Path: "/api/getApiById", Description: "获取api详细信息"},
6565
{ApiGroup: "api", Method: "DELETE", Path: "/api/deleteApisByIds", Description: "批量删除api"},
66+
{ApiGroup: "api", Method: "GET", Path: "/api/syncApi", Description: "获取待同步API"},
67+
{ApiGroup: "api", Method: "GET", Path: "/api/getApiGroups", Description: "获取路由组"},
68+
{ApiGroup: "api", Method: "POST", Path: "/api/enterSyncApi", Description: "确认同步API"},
69+
{ApiGroup: "api", Method: "POST", Path: "/api/ignoreApi", Description: "忽略API"},
6670

6771
{ApiGroup: "角色", Method: "POST", Path: "/authority/copyAuthority", Description: "拷贝角色"},
6872
{ApiGroup: "角色", Method: "POST", Path: "/authority/createAuthority", Description: "创建角色"},
@@ -145,7 +149,7 @@ func (i *initApi) InitializeData(ctx context.Context) (context.Context, error) {
145149
{ApiGroup: "断点续传(插件版)", Method: "GET", Path: "/simpleUploader/mergeFileMd5", Description: "上传完成合并文件"},
146150

147151
{ApiGroup: "email", Method: "POST", Path: "/email/emailTest", Description: "发送测试邮件"},
148-
{ApiGroup: "email", Method: "POST", Path: "/email/emailSend", Description: "发送邮件示例"},
152+
{ApiGroup: "email", Method: "POST", Path: "/email/sendEmail", Description: "发送邮件"},
149153

150154
{ApiGroup: "按钮权限", Method: "POST", Path: "/authorityBtn/setAuthorityBtn", Description: "设置按钮权限"},
151155
{ApiGroup: "按钮权限", Method: "POST", Path: "/authorityBtn/getAuthorityBtn", Description: "获取已有按钮权限"},

0 commit comments

Comments
 (0)