2
0

sys_api.go 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  1. package system
  2. import (
  3. "errors"
  4. "fmt"
  5. "strings"
  6. "github.com/flipped-aurora/gin-vue-admin/server/global"
  7. "github.com/flipped-aurora/gin-vue-admin/server/model/common/request"
  8. "github.com/flipped-aurora/gin-vue-admin/server/model/system"
  9. systemRes "github.com/flipped-aurora/gin-vue-admin/server/model/system/response"
  10. "gorm.io/gorm"
  11. )
  12. //@author: [piexlmax](https://github.com/piexlmax)
  13. //@function: CreateApi
  14. //@description: 新增基础api
  15. //@param: api model.SysApi
  16. //@return: err error
  17. type ApiService struct{}
  18. var ApiServiceApp = new(ApiService)
  19. func (apiService *ApiService) CreateApi(api system.SysApi) (err error) {
  20. if !errors.Is(global.GVA_DB.Where("path = ? AND method = ?", api.Path, api.Method).First(&system.SysApi{}).Error, gorm.ErrRecordNotFound) {
  21. return errors.New("存在相同api")
  22. }
  23. return global.GVA_DB.Create(&api).Error
  24. }
  25. func (apiService *ApiService) GetApiGroups() (groups []string, groupApiMap map[string]string, err error) {
  26. var apis []system.SysApi
  27. err = global.GVA_DB.Find(&apis).Error
  28. if err != nil {
  29. return
  30. }
  31. groupApiMap = make(map[string]string, 0)
  32. for i := range apis {
  33. pathArr := strings.Split(apis[i].Path, "/")
  34. newGroup := true
  35. for i2 := range groups {
  36. if groups[i2] == apis[i].ApiGroup {
  37. newGroup = false
  38. }
  39. }
  40. if newGroup {
  41. groups = append(groups, apis[i].ApiGroup)
  42. }
  43. groupApiMap[pathArr[1]] = apis[i].ApiGroup
  44. }
  45. return
  46. }
  47. func (apiService *ApiService) SyncApi() (newApis, deleteApis, ignoreApis []system.SysApi, err error) {
  48. newApis = make([]system.SysApi, 0)
  49. deleteApis = make([]system.SysApi, 0)
  50. ignoreApis = make([]system.SysApi, 0)
  51. var apis []system.SysApi
  52. err = global.GVA_DB.Find(&apis).Error
  53. if err != nil {
  54. return
  55. }
  56. var ignores []system.SysIgnoreApi
  57. err = global.GVA_DB.Find(&ignores).Error
  58. if err != nil {
  59. return
  60. }
  61. for i := range ignores {
  62. ignoreApis = append(ignoreApis, system.SysApi{
  63. Path: ignores[i].Path,
  64. Description: "",
  65. ApiGroup: "",
  66. Method: ignores[i].Method,
  67. })
  68. }
  69. var cacheApis []system.SysApi
  70. for i := range global.GVA_ROUTERS {
  71. ignoresFlag := false
  72. for j := range ignores {
  73. if ignores[j].Path == global.GVA_ROUTERS[i].Path && ignores[j].Method == global.GVA_ROUTERS[i].Method {
  74. ignoresFlag = true
  75. }
  76. }
  77. if !ignoresFlag {
  78. cacheApis = append(cacheApis, system.SysApi{
  79. Path: global.GVA_ROUTERS[i].Path,
  80. Method: global.GVA_ROUTERS[i].Method,
  81. })
  82. }
  83. }
  84. //对比数据库中的api和内存中的api,如果数据库中的api不存在于内存中,则把api放入删除数组,如果内存中的api不存在于数据库中,则把api放入新增数组
  85. for i := range cacheApis {
  86. var flag bool
  87. // 如果存在于内存不存在于api数组中
  88. for j := range apis {
  89. if cacheApis[i].Path == apis[j].Path && cacheApis[i].Method == apis[j].Method {
  90. flag = true
  91. }
  92. }
  93. if !flag {
  94. newApis = append(newApis, system.SysApi{
  95. Path: cacheApis[i].Path,
  96. Description: "",
  97. ApiGroup: "",
  98. Method: cacheApis[i].Method,
  99. })
  100. }
  101. }
  102. for i := range apis {
  103. var flag bool
  104. // 如果存在于api数组不存在于内存
  105. for j := range cacheApis {
  106. if cacheApis[j].Path == apis[i].Path && cacheApis[j].Method == apis[i].Method {
  107. flag = true
  108. }
  109. }
  110. if !flag {
  111. deleteApis = append(deleteApis, apis[i])
  112. }
  113. }
  114. return
  115. }
  116. func (apiService *ApiService) IgnoreApi(ignoreApi system.SysIgnoreApi) (err error) {
  117. if ignoreApi.Flag {
  118. return global.GVA_DB.Create(&ignoreApi).Error
  119. }
  120. return global.GVA_DB.Unscoped().Delete(&ignoreApi, "path = ? AND method = ?", ignoreApi.Path, ignoreApi.Method).Error
  121. }
  122. func (apiService *ApiService) EnterSyncApi(syncApis systemRes.SysSyncApis) (err error) {
  123. return global.GVA_DB.Transaction(func(tx *gorm.DB) error {
  124. var txErr error
  125. if len(syncApis.NewApis) > 0 {
  126. txErr = tx.Create(&syncApis.NewApis).Error
  127. if txErr != nil {
  128. return txErr
  129. }
  130. }
  131. for i := range syncApis.DeleteApis {
  132. CasbinServiceApp.ClearCasbin(1, syncApis.DeleteApis[i].Path, syncApis.DeleteApis[i].Method)
  133. txErr = tx.Delete(&system.SysApi{}, "path = ? AND method = ?", syncApis.DeleteApis[i].Path, syncApis.DeleteApis[i].Method).Error
  134. if txErr != nil {
  135. return txErr
  136. }
  137. }
  138. return nil
  139. })
  140. }
  141. //@author: [piexlmax](https://github.com/piexlmax)
  142. //@function: DeleteApi
  143. //@description: 删除基础api
  144. //@param: api model.SysApi
  145. //@return: err error
  146. func (apiService *ApiService) DeleteApi(api system.SysApi) (err error) {
  147. var entity system.SysApi
  148. err = global.GVA_DB.First(&entity, "id = ?", api.ID).Error // 根据id查询api记录
  149. if errors.Is(err, gorm.ErrRecordNotFound) { // api记录不存在
  150. return err
  151. }
  152. err = global.GVA_DB.Delete(&entity).Error
  153. if err != nil {
  154. return err
  155. }
  156. CasbinServiceApp.ClearCasbin(1, entity.Path, entity.Method)
  157. return nil
  158. }
  159. //@author: [piexlmax](https://github.com/piexlmax)
  160. //@function: GetAPIInfoList
  161. //@description: 分页获取数据,
  162. //@param: api model.SysApi, info request.PageInfo, order string, desc bool
  163. //@return: list interface{}, total int64, err error
  164. func (apiService *ApiService) GetAPIInfoList(api system.SysApi, info request.PageInfo, order string, desc bool) (list interface{}, total int64, err error) {
  165. limit := info.PageSize
  166. offset := info.PageSize * (info.Page - 1)
  167. db := global.GVA_DB.Model(&system.SysApi{})
  168. var apiList []system.SysApi
  169. if api.Path != "" {
  170. db = db.Where("path LIKE ?", "%"+api.Path+"%")
  171. }
  172. if api.Description != "" {
  173. db = db.Where("description LIKE ?", "%"+api.Description+"%")
  174. }
  175. if api.Method != "" {
  176. db = db.Where("method = ?", api.Method)
  177. }
  178. if api.ApiGroup != "" {
  179. db = db.Where("api_group = ?", api.ApiGroup)
  180. }
  181. err = db.Count(&total).Error
  182. if err != nil {
  183. return apiList, total, err
  184. }
  185. db = db.Limit(limit).Offset(offset)
  186. OrderStr := "id desc"
  187. if order != "" {
  188. orderMap := make(map[string]bool, 5)
  189. orderMap["id"] = true
  190. orderMap["path"] = true
  191. orderMap["api_group"] = true
  192. orderMap["description"] = true
  193. orderMap["method"] = true
  194. if !orderMap[order] {
  195. err = fmt.Errorf("非法的排序字段: %v", order)
  196. return apiList, total, err
  197. }
  198. OrderStr = order
  199. if desc {
  200. OrderStr = order + " desc"
  201. }
  202. }
  203. err = db.Order(OrderStr).Find(&apiList).Error
  204. return apiList, total, err
  205. }
  206. //@author: [piexlmax](https://github.com/piexlmax)
  207. //@function: GetAllApis
  208. //@description: 获取所有的api
  209. //@return: apis []model.SysApi, err error
  210. func (apiService *ApiService) GetAllApis(authorityID uint) (apis []system.SysApi, err error) {
  211. parentAuthorityID, err := AuthorityServiceApp.GetParentAuthorityID(authorityID)
  212. if err != nil {
  213. return nil, err
  214. }
  215. err = global.GVA_DB.Order("id desc").Find(&apis).Error
  216. if parentAuthorityID == 0 || !global.GVA_CONFIG.System.UseStrictAuth {
  217. return
  218. }
  219. paths := CasbinServiceApp.GetPolicyPathByAuthorityId(authorityID)
  220. // 挑选 apis里面的path和method也在paths里面的api
  221. var authApis []system.SysApi
  222. for i := range apis {
  223. for j := range paths {
  224. if paths[j].Path == apis[i].Path && paths[j].Method == apis[i].Method {
  225. authApis = append(authApis, apis[i])
  226. }
  227. }
  228. }
  229. return authApis, err
  230. }
  231. //@author: [piexlmax](https://github.com/piexlmax)
  232. //@function: GetApiById
  233. //@description: 根据id获取api
  234. //@param: id float64
  235. //@return: api model.SysApi, err error
  236. func (apiService *ApiService) GetApiById(id int) (api system.SysApi, err error) {
  237. err = global.GVA_DB.First(&api, "id = ?", id).Error
  238. return
  239. }
  240. //@author: [piexlmax](https://github.com/piexlmax)
  241. //@function: UpdateApi
  242. //@description: 根据id更新api
  243. //@param: api model.SysApi
  244. //@return: err error
  245. func (apiService *ApiService) UpdateApi(api system.SysApi) (err error) {
  246. var oldA system.SysApi
  247. err = global.GVA_DB.First(&oldA, "id = ?", api.ID).Error
  248. if oldA.Path != api.Path || oldA.Method != api.Method {
  249. var duplicateApi system.SysApi
  250. if ferr := global.GVA_DB.First(&duplicateApi, "path = ? AND method = ?", api.Path, api.Method).Error; ferr != nil {
  251. if !errors.Is(ferr, gorm.ErrRecordNotFound) {
  252. return ferr
  253. }
  254. } else {
  255. if duplicateApi.ID != api.ID {
  256. return errors.New("存在相同api路径")
  257. }
  258. }
  259. }
  260. if err != nil {
  261. return err
  262. }
  263. err = CasbinServiceApp.UpdateCasbinApi(oldA.Path, api.Path, oldA.Method, api.Method)
  264. if err != nil {
  265. return err
  266. }
  267. return global.GVA_DB.Save(&api).Error
  268. }
  269. //@author: [piexlmax](https://github.com/piexlmax)
  270. //@function: DeleteApisByIds
  271. //@description: 删除选中API
  272. //@param: apis []model.SysApi
  273. //@return: err error
  274. func (apiService *ApiService) DeleteApisByIds(ids request.IdsReq) (err error) {
  275. return global.GVA_DB.Transaction(func(tx *gorm.DB) error {
  276. var apis []system.SysApi
  277. err = tx.Find(&apis, "id in ?", ids.Ids).Error
  278. if err != nil {
  279. return err
  280. }
  281. err = tx.Delete(&[]system.SysApi{}, "id in ?", ids.Ids).Error
  282. if err != nil {
  283. return err
  284. }
  285. for _, sysApi := range apis {
  286. CasbinServiceApp.ClearCasbin(1, sysApi.Path, sysApi.Method)
  287. }
  288. return err
  289. })
  290. }