sys_apis.go 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. package system
  2. import (
  3. "go_server/model/common"
  4. "gorm.io/gorm"
  5. "strings"
  6. )
  7. // generateApiName 根据路径自动生成有意义的中文接口名称
  8. // 路径格式: /admin/api/{group}/{module}/{action}
  9. func generateApiName(path string) string {
  10. groupMap := map[string]string{
  11. "sys": "系统",
  12. "app": "应用",
  13. "daytask": "日任务",
  14. "login": "登录",
  15. }
  16. moduleMap := map[string]string{
  17. // sys 模块
  18. "user": "管理员",
  19. "role": "角色",
  20. "menu": "菜单",
  21. "apis": "API权限",
  22. "dictionary": "字典",
  23. "file": "文件",
  24. "sign": "签名",
  25. "auto": "代码生成",
  26. "db": "数据库",
  27. // app 模块
  28. "magic_asset": "资产",
  29. "magic_asset_bill": "资产账单",
  30. "magic_asset_rw_callback_log": "充提回调日志",
  31. "magic_asset_rw_record": "充提记录",
  32. "magic_stake_product": "质押产品",
  33. "magic_stake_queue_info": "质押队列",
  34. "magic_stake_user_current_ops_record": "质押操作记录",
  35. "magic_stake_user_current_order": "质押订单",
  36. "magic_user": "用户",
  37. "magic_user_action_log": "用户行为日志",
  38. "magic_user_logs": "用户日志",
  39. "magic_user_profit": "用户收益",
  40. "magic_user_profit_record": "收益记录",
  41. "magic_user_quota": "用户配额",
  42. "node_banner": "节点Banner",
  43. "node_info": "节点信息",
  44. "node_order": "节点订单",
  45. "node_order_payments": "节点支付",
  46. "promotion_upgrade_level": "晋级推广",
  47. "sys_coin": "币种配置",
  48. "sys_i18n": "国际化",
  49. "sys_job": "定时任务",
  50. "sys_level_config": "等级配置",
  51. "sys_sign_config": "签到配置",
  52. "sys_stake_period_job": "质押周期",
  53. "magic_extra_stake_order": "额外质押订单",
  54. "magic_extra_stake_order_ops_record": "额外质押操作",
  55. // daytask 模块
  56. "user_social": "社交账号",
  57. "user_payment": "收款方式",
  58. "user_level": "用户等级",
  59. "recharge_order": "充值订单",
  60. "payment_channel": "支付渠道",
  61. "task_category": "任务分类",
  62. "task": "任务",
  63. "task_step": "任务步骤",
  64. "task_example": "审核样例",
  65. "user_task": "用户任务",
  66. "withdraw_order": "提现订单",
  67. "balance_log": "资金流水",
  68. "notice": "公告",
  69. "banner": "Banner",
  70. "help_category": "帮助分类",
  71. "help": "帮助中心",
  72. "customer_service": "客服配置",
  73. "material": "素材",
  74. "material_group": "素材分组",
  75. "music_group": "歌单分组",
  76. "music": "歌曲",
  77. "admin": "管理员",
  78. "config": "系统配置",
  79. "operation_log": "操作日志",
  80. "daily_stats": "每日统计",
  81. }
  82. actionMap := map[string]string{
  83. "get": "获取详情",
  84. "find": "查询列表",
  85. "create": "创建",
  86. "update": "修改",
  87. "delete": "删除",
  88. "set": "修改配置",
  89. "setUser": "修改用户",
  90. "tree": "树形结构",
  91. "info": "个人信息",
  92. "logs": "操作日志",
  93. "audit": "审核",
  94. "pay": "支付",
  95. "comment": "评论",
  96. "cancel": "取消",
  97. "dbs": "数据库列表",
  98. "tbs": "表列表",
  99. "cols": "字段列表",
  100. "upload": "上传文件",
  101. "oss/auth": "OSS授权",
  102. "server/code": "生成代码",
  103. "server/rollback": "回滚代码",
  104. "model/auto": "同步模型",
  105. "getGoogleKey": "获取Google密钥",
  106. "cancelGoogleKey": "取消Google密钥",
  107. "replaceGoogleKey": "重置Google密钥",
  108. "generateCaptcha": "生成验证码",
  109. "check": "验证登录",
  110. "in": "登录",
  111. "wallet/info": "钱包信息",
  112. "get_by_group": "按分组查询",
  113. "summary": "数据概览",
  114. }
  115. // 路径格式: /admin/api/{group}/{module}/{action}
  116. // Trim("/") 后 Split 得到: ["admin", "api", "group", "module", "action"]
  117. // 索引: 0 1 2 3 4
  118. parts := strings.Split(strings.Trim(path, "/"), "/")
  119. groupName := ""
  120. moduleName := ""
  121. actionName := ""
  122. if len(parts) >= 3 {
  123. groupName = groupMap[parts[2]]
  124. }
  125. if len(parts) >= 4 {
  126. moduleName = moduleMap[parts[3]]
  127. if moduleName == "" {
  128. moduleName = parts[3]
  129. }
  130. }
  131. if len(parts) >= 5 {
  132. // 优先尝试双段 action,如 oss/auth、server/code
  133. if len(parts) >= 6 {
  134. doubleKey := parts[4] + "/" + parts[5]
  135. if v, ok := actionMap[doubleKey]; ok {
  136. actionName = v
  137. }
  138. }
  139. if actionName == "" {
  140. actionName = actionMap[parts[4]]
  141. }
  142. if actionName == "" {
  143. actionName = parts[4]
  144. }
  145. }
  146. if groupName != "" && moduleName != "" && actionName != "" {
  147. return groupName + "-" + moduleName + "-" + actionName
  148. }
  149. if moduleName != "" && actionName != "" {
  150. return moduleName + "-" + actionName
  151. }
  152. return "待设置"
  153. }
  154. // BatchUpdateApiNames 批量将 name="待设置" 的接口更新为有意义的中文名称
  155. func (s *Apis) BatchUpdateApiNames(db *gorm.DB) error {
  156. var apis []Apis
  157. if err := db.Where("name = ?", "待设置").Find(&apis).Error; err != nil {
  158. return err
  159. }
  160. for _, api := range apis {
  161. name := generateApiName(api.Path)
  162. if name == "待设置" {
  163. continue
  164. }
  165. if err := db.Exec(
  166. "UPDATE "+s.TableName()+" SET name = ? WHERE id = ? AND deleted_at IS NULL",
  167. name, api.ID,
  168. ).Error; err != nil {
  169. return err
  170. }
  171. }
  172. return nil
  173. }
  174. type Apis struct {
  175. common.GormFullModel
  176. ParentId int64 `json:"parentId" gorm:"column:parent_id;comment:上级接口Id"`
  177. Group string `json:"group" gorm:"column:group;type:varchar(50);comment:分组名称"`
  178. Name string `json:"name" gorm:"column:name;type:varchar(50);comment:接口名称"`
  179. Method string `json:"method" gorm:"column:method;type:varchar(20);comment:请求方法"`
  180. Path string `json:"path" gorm:"column:path;type:varchar(80);comment:接口全路径;unique"`
  181. }
  182. func (*Apis) TableName() string {
  183. return common.ModelPrefix + "apis"
  184. }
  185. func NewApis() *Apis {
  186. return &Apis{}
  187. }
  188. func (*Apis) Comment() string {
  189. return "api权限表"
  190. }
  191. func (s *Apis) FindOrCreateAuth(db *gorm.DB, path, method string) (*Apis, error) {
  192. if err := db.Where("path", path).First(&s).Error; err != nil {
  193. if !strings.Contains(path, "*") {
  194. pathList := strings.Split(path, "/")
  195. if len(pathList) > 2 {
  196. s.Group = pathList[2]
  197. }
  198. s.ParentId = 1
  199. s.Path = path
  200. s.Method = method
  201. s.Name = generateApiName(path)
  202. if err := db.Create(&s).Error; err != nil {
  203. return s, err
  204. }
  205. }
  206. return s, err
  207. }
  208. return s, nil
  209. }
  210. type ApiNode struct {
  211. Id int64 `json:"id"`
  212. ParentId int64 `json:"parentId"`
  213. Group string `json:"group"`
  214. Name string `json:"name"`
  215. Method string `json:"method"`
  216. Path string `json:"path"`
  217. Children []*ApiNode `json:"children"`
  218. }
  219. func (s *Apis) GetUserTree(db *gorm.DB, ids []string) ([]ApiNode, error) {
  220. menusNodeTree := make([]ApiNode, 0) // 根节点
  221. // 所有节点
  222. allMenus := make([]Apis, 0)
  223. if err := db.Model(&Apis{}).
  224. Where("id in (?)", ids).
  225. Find(&allMenus).Error; err != nil {
  226. return menusNodeTree, err
  227. }
  228. for _, m := range allMenus {
  229. childMenus := make([]*ApiNode, 0)
  230. if m.ParentId == 0 {
  231. rootNode := ApiNode{
  232. Id: m.ID,
  233. ParentId: m.ParentId,
  234. Group: m.Group,
  235. Name: m.Name,
  236. Method: m.Method,
  237. Path: m.Path,
  238. Children: childMenus,
  239. }
  240. menusNodeTree = append(menusNodeTree, rootNode)
  241. }
  242. }
  243. for i, _ := range menusNodeTree {
  244. s.walk(allMenus, &menusNodeTree[i])
  245. }
  246. return menusNodeTree, nil
  247. }
  248. // MenuTree 系统递归树[满足无限层级递归]
  249. func (s *Apis) SysTree(db *gorm.DB) ([]ApiNode, error) {
  250. menusNodeTree := make([]ApiNode, 0) // 根节点
  251. // 所有节点
  252. allMenus := make([]Apis, 0)
  253. if err := db.Model(&Apis{}).Where("1=1").Find(&allMenus).Error; err != nil {
  254. return menusNodeTree, err
  255. }
  256. for _, m := range allMenus {
  257. childMenus := make([]*ApiNode, 0)
  258. if m.ParentId == 0 {
  259. rootNode := ApiNode{
  260. Id: m.ID,
  261. ParentId: m.ParentId,
  262. Name: m.Name,
  263. Group: m.Group,
  264. Method: m.Method,
  265. Path: m.Path,
  266. Children: childMenus,
  267. }
  268. menusNodeTree = append(menusNodeTree, rootNode)
  269. }
  270. }
  271. for i, _ := range menusNodeTree {
  272. s.walk(allMenus, &menusNodeTree[i])
  273. }
  274. return menusNodeTree, nil
  275. }
  276. // 递归组装菜单树(根节点)
  277. func (s *Apis) walk(allMenus []Apis, rootNode *ApiNode) {
  278. // 列出所有下级子目录
  279. nodes := s.childrenList(allMenus, rootNode.Id)
  280. if len(nodes) == 0 {
  281. return
  282. }
  283. // 遍历这些文件
  284. for _, m := range nodes {
  285. newNode := ApiNode{
  286. Id: m.Id,
  287. ParentId: m.ParentId,
  288. Group: m.Group,
  289. Name: m.Name,
  290. Method: m.Method,
  291. Path: m.Path,
  292. Children: nil,
  293. }
  294. s.walk(allMenus, &newNode)
  295. rootNode.Children = append(rootNode.Children, &newNode)
  296. }
  297. return
  298. }
  299. // 获得子节点列表
  300. func (s *Apis) childrenList(allMenus []Apis, pId int64) (menusNodeTree []ApiNode) {
  301. for _, m := range allMenus {
  302. if m.ParentId == pId {
  303. rootNode := ApiNode{
  304. Id: m.ID,
  305. ParentId: m.ParentId,
  306. Name: m.Name,
  307. Group: m.Group,
  308. Method: m.Method,
  309. Path: m.Path,
  310. Children: nil,
  311. }
  312. menusNodeTree = append(menusNodeTree, rootNode)
  313. }
  314. }
  315. return
  316. }