menu.lua 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. require("fwutils.webapi")
  2. -- CREATE TABLE `fw_menu` (
  3. -- `id` int NOT NULL AUTO_INCREMENT,
  4. -- `role_id` int DEFAULT NULL,
  5. -- `title` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  6. -- `path` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  7. -- `icon` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  8. -- `sort` int DEFAULT NULL,
  9. -- `parent_id` int DEFAULT NULL,
  10. -- `create_time` datetime DEFAULT NULL,
  11. -- `update_time` datetime DEFAULT NULL,
  12. -- `delete_time` datetime DEFAULT NULL,
  13. -- PRIMARY KEY (`id`)
  14. -- ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
  15. local M = {}
  16. function M.get_by_id(id,conn)
  17. local select = conn:select()
  18. select:table("fw_menu LEFT JOIN fw_role ON fw_menu.role_id = fw_role.id")
  19. select:field({
  20. "fw_menu.id",
  21. "fw_menu.title",
  22. "fw_menu.path",
  23. "fw_menu.icon",
  24. "fw_menu.sort",
  25. "fw_menu.parent_id",
  26. "fw_menu.create_time",
  27. "fw_menu.update_time",
  28. "fw_menu.delete_time",
  29. "fw_role.title as role_title",
  30. "fw_role.id as role_id",
  31. })
  32. select:where_i32("fw_menu.id","=",id)
  33. select:where_expression("AND fw_menu.delete_time IS NULL")
  34. select:limit(0,1)
  35. local result = select:query()
  36. if result:row_count() == 0 then
  37. return nil
  38. end
  39. local d = result:table()[1]
  40. return d
  41. end
  42. function M.add(data,conn)
  43. local insert = conn:insert()
  44. insert:table("fw_menu")
  45. insert:set_str("title",data.title)
  46. insert:set_str("path",data.path)
  47. insert:set_i32("role_id",data.role_id)
  48. if data.icon ~= nil then
  49. insert:set_str("icon",data.icon)
  50. end
  51. if data.sort ~= nil then
  52. insert:set_i32("sort",data.sort)
  53. end
  54. if data.parent_id ~= nil and data.parent_id ~= 0 then
  55. insert:set_i32("parent_id",data.parent_id)
  56. end
  57. insert:set_not_ppst("create_time","NOW()")
  58. local d = insert:exec()
  59. return d == 1
  60. end
  61. function M.update(data,conn)
  62. local update = conn:update()
  63. update:table("fw_menu")
  64. if data.title ~= nil then
  65. update:set_str("title",data.title)
  66. end
  67. if data.path ~= nil then
  68. update:set_str("path",data.path)
  69. end
  70. if data.role_id ~= nil then
  71. update:set_i32("role_id",data.role_id)
  72. end
  73. if data.icon ~= nil then
  74. update:set_str("icon",data.icon)
  75. end
  76. if data.sort ~= nil then
  77. update:set_i32("sort",data.sort)
  78. end
  79. if data.parent_id ~= nil then
  80. update:set_i32("parent_id",data.parent_id)
  81. end
  82. update:set("update_time=NOW()")
  83. update:where_i32("id","=",data.id)
  84. local d = update:exec()
  85. return d == 1
  86. end
  87. function M.delete(id,conn)
  88. local update = conn:update()
  89. update:table("fw_menu")
  90. update:set("delete_time=NOW()")
  91. update:where_i32("id","=",id)
  92. local d = update:exec()
  93. return d == 1
  94. end
  95. function M.list(search,limit,conn)
  96. if search.role_id == -1 then
  97. return {
  98. count = 0,
  99. data = {}
  100. }
  101. end
  102. return query_model_ex(conn,[=[
  103. fw_menu LEFT JOIN fw_role ON fw_menu.role_id = fw_role.id
  104. ]=],{
  105. "fw_menu.id",
  106. "fw_menu.title",
  107. "fw_menu.path",
  108. "fw_menu.icon",
  109. "fw_menu.sort",
  110. "fw_menu.parent_id",
  111. "fw_menu.create_time",
  112. "fw_menu.update_time",
  113. "fw_menu.delete_time",
  114. "fw_role.title as role_title",
  115. "fw_role.id as role_id",
  116. },limit.start,limit.length,function(sel)
  117. if search.role_id ~= nil and search.role_id ~= 0 then
  118. sel:where_i32("fw_menu.role_id","=",search.role_id)
  119. end
  120. sel:where_expression("AND fw_menu.delete_time IS NULL")
  121. end,function(sel_data)
  122. sel_data:orderby("fw_menu.sort DESC")
  123. end)
  124. end
  125. M.make_bytecode = function(role_id,conn)
  126. -- 查询菜单表
  127. local select = conn:select()
  128. select:table("fw_menu")
  129. select:where_expression("AND delete_time IS NULL")
  130. if role_id ~= nil then
  131. select:where_i32("role_id", "=", role_id)
  132. end
  133. local result = select:query()
  134. local bc = {}
  135. local items_by_id = {} -- 通过id快速查找菜单项:{id = {role_id, title, item, parent_id}}
  136. local items_with_parent = {} -- 存储有父级的菜单项
  137. -- 第一遍:读取所有菜单项并存储
  138. while result:next() do
  139. local id = result:get("id")
  140. local role_id = tostring(result:get("role_id"))
  141. local title = result:get("title")
  142. local path = result:get("path")
  143. local icon = result:get("icon")
  144. local sort = result:get("sort")
  145. local parent_id = result:get("parent_id")
  146. if not title or title == "" then
  147. goto continue
  148. end
  149. if bc[role_id] == nil then
  150. bc[role_id] = {}
  151. end
  152. local item = {
  153. path = path,
  154. icon = icon,
  155. sort = sort,
  156. }
  157. -- 存储所有菜单项信息
  158. items_by_id[id] = {
  159. role_id = role_id,
  160. title = title,
  161. item = item,
  162. parent_id = parent_id
  163. }
  164. -- 如果parent_id为空,则作为顶层菜单项
  165. if parent_id == nil or parent_id == 0 then
  166. bc[role_id][title] = item
  167. else
  168. -- 有父级,记录下来稍后处理
  169. table.insert(items_with_parent, {
  170. id = id,
  171. role_id = role_id,
  172. title = title,
  173. item = item,
  174. parent_id = parent_id
  175. })
  176. end
  177. ::continue::
  178. end
  179. -- 第二遍:处理有父级的菜单项,构建children结构
  180. for _, menu_item in ipairs(items_with_parent) do
  181. local parent_info = items_by_id[menu_item.parent_id]
  182. if parent_info then
  183. local parent_item = parent_info.item
  184. -- 如果父项还没有children表,创建它
  185. if not parent_item.children then
  186. parent_item.children = {}
  187. end
  188. -- 将子项添加到父项的children中
  189. parent_item.children[menu_item.title] = menu_item.item
  190. end
  191. end
  192. local code = "return " .. require("serpent").serialize(bc, {comment = false})
  193. utils.save_file(fw.website_dir().."/"..(fwutils_config.path.luabytecode:gsub("%.", "/")).."/menu_bc.lua",code)
  194. return true
  195. end
  196. M.bytecode = function(role_id)
  197. local menu_bc = require(fwutils_config.path.luabytecode..".menu_bc")
  198. return menu_bc[string.format("%d",role_id)]
  199. end
  200. return M