主要修改开发模块
This commit is contained in:
101
target/aliyun/oss.lua
Normal file
101
target/aliyun/oss.lua
Normal file
@@ -0,0 +1,101 @@
|
||||
local aliyun_oss = require("aliyunoss")
|
||||
local fw = require("fastweb")
|
||||
local utils = require("utils")
|
||||
local M = {}
|
||||
-- 文件扩展名与目录的映射
|
||||
M.ext_dirpath = {
|
||||
images = {
|
||||
"jpg",
|
||||
"jpeg",
|
||||
"png",
|
||||
"gif",
|
||||
"bmp",
|
||||
"webp",
|
||||
"svg",
|
||||
"ico",
|
||||
"tif",
|
||||
"tiff",
|
||||
},
|
||||
videos = {
|
||||
"mp4",
|
||||
"avi",
|
||||
"mov",
|
||||
"wmv",
|
||||
"flv"
|
||||
},
|
||||
audio = {
|
||||
"mp3",
|
||||
"wav",
|
||||
"ogg",
|
||||
"aac",
|
||||
"m4a",
|
||||
"wma"
|
||||
},
|
||||
documents = {
|
||||
"pdf",
|
||||
"doc",
|
||||
"docx",
|
||||
"xls",
|
||||
"xlsx",
|
||||
"ppt",
|
||||
"pptx"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function M.upload_file(config,remote_dir,local_filepath,auto_remove)
|
||||
|
||||
if not utils.exists_file(local_filepath) then
|
||||
return false,"文件不存在,local_filepath: "..local_filepath
|
||||
end
|
||||
local ext = utils.ext(local_filepath)
|
||||
local filename = fw.make_software_guid().."."..ext
|
||||
|
||||
local dirpath = ""
|
||||
|
||||
for dir, ext_list in pairs(M.ext_dirpath) do
|
||||
for _, ext_type_ext in ipairs(ext_list) do
|
||||
if ext_type_ext == ext then
|
||||
dirpath = dir
|
||||
break
|
||||
end
|
||||
end
|
||||
if dirpath ~= "" then
|
||||
break
|
||||
end
|
||||
end
|
||||
if dirpath == "" then
|
||||
return false,"不支持的文件格式,ext: "..ext
|
||||
end
|
||||
|
||||
if remote_dir == nil or remote_dir == "" then
|
||||
remote_dir = ""
|
||||
else
|
||||
remote_dir = remote_dir.."/"
|
||||
end
|
||||
|
||||
local cos_filepath = remote_dir .. dirpath.."/"..filename
|
||||
local oss = aliyun_oss.new()
|
||||
|
||||
|
||||
local result = oss:upfile(
|
||||
config.endpoint,
|
||||
config.access_key_id,
|
||||
config.access_key_secret,
|
||||
config.bucket_name,
|
||||
cos_filepath,
|
||||
local_filepath,
|
||||
""
|
||||
)
|
||||
if result == "" then
|
||||
if auto_remove then
|
||||
utils.delete_file(local_filepath)
|
||||
end
|
||||
return true,cos_filepath
|
||||
end
|
||||
return false,result
|
||||
end
|
||||
|
||||
|
||||
|
||||
return M
|
||||
@@ -1,117 +0,0 @@
|
||||
local utils = require("utils")
|
||||
local fw = require("fastweb")
|
||||
local config = require("fwutils.config")
|
||||
local M = {}
|
||||
|
||||
|
||||
-- 更新
|
||||
M.update = function(role_id,conn)
|
||||
-- 查询权限表
|
||||
local select = conn:select()
|
||||
select:table("fw_role_permissions")
|
||||
select:where_expression("AND delete_time IS NULL")
|
||||
if role_id ~= nil then
|
||||
select:where_i32("role_id", "=", role_id)
|
||||
end
|
||||
local result = select:query()
|
||||
|
||||
|
||||
local bc = {}
|
||||
|
||||
while result:next() do
|
||||
local id = result:get("id")
|
||||
local path = result:get("path")
|
||||
local role_id = tostring(result:get("role_id"))
|
||||
local action = result:get("action")
|
||||
local desc = result:get("desc")
|
||||
local create_time = result:get("create_time")
|
||||
local update_time = result:get("update_time")
|
||||
local delete_time = result:get("delete_time")
|
||||
-- local public = result:get("public")
|
||||
|
||||
if bc[role_id] == nil then
|
||||
bc[role_id] = {}
|
||||
end
|
||||
if bc[role_id]["public"] == nil then
|
||||
bc[role_id]["public"] = {}
|
||||
end
|
||||
if bc[role_id]["private"] == nil then
|
||||
bc[role_id]["private"] = {}
|
||||
end
|
||||
-- 处理 action 字段,将其切分为表或空表
|
||||
local actions_tbl = {}
|
||||
if action and action ~= "" then
|
||||
for act in string.gmatch(action, "([^,]+)") do
|
||||
table.insert(actions_tbl, act)
|
||||
end
|
||||
end
|
||||
|
||||
local item = {
|
||||
create_time = create_time,
|
||||
update_time = update_time,
|
||||
delete_time = delete_time,
|
||||
action = actions_tbl,
|
||||
desc = desc,
|
||||
}
|
||||
-- if public == 1 then
|
||||
-- bc[role_id]["public"][path] = item
|
||||
-- else
|
||||
-- bc[role_id]["private"][path] = item
|
||||
-- end
|
||||
bc[role_id][path] = item
|
||||
end
|
||||
local code = "return " .. require("serpent").serialize(bc, {comment = false})
|
||||
utils.save_file(fw.website_dir().."/"..(config.path.luabytecode:gsub("%.", "/")).."/acl_bc.lua",code)
|
||||
return true
|
||||
end
|
||||
-- 匹配
|
||||
M.match = function(cfg)
|
||||
|
||||
local function match_path(path, patterns)
|
||||
|
||||
-- print("[match_path] path:",path)
|
||||
for pattern, v in pairs(patterns) do
|
||||
|
||||
-- 如果是正则(以^开头),用string.match,否则精确匹配
|
||||
if string.sub(pattern, 1, 1) == "^" then
|
||||
|
||||
if string.match(path, pattern) then
|
||||
-- print("[TRUE] pattern:",pattern,",path:",path)
|
||||
return true, v
|
||||
-- else
|
||||
-- print("[FALSE] pattern:",pattern,",path:",path)
|
||||
end
|
||||
else
|
||||
if path == pattern then
|
||||
return true, v
|
||||
end
|
||||
end
|
||||
end
|
||||
return false, nil
|
||||
end
|
||||
-- 检查action
|
||||
local function check_action(actions,action)
|
||||
if actions == nil or #actions == 0 then
|
||||
return true
|
||||
end
|
||||
|
||||
for _,v in pairs(actions) do
|
||||
if v == action then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false, "action not match"
|
||||
end
|
||||
local role_id_str = string.format("%d",cfg.role_id())
|
||||
local acl_bc = require(config.path.luabytecode..".acl_bc")
|
||||
if acl_bc[role_id_str] == nil then
|
||||
return false,"role id("..role_id_str..") acl not found"
|
||||
end
|
||||
local result, item = match_path(cfg.filepath(), acl_bc[role_id_str])
|
||||
if result then
|
||||
return check_action(item.action,cfg.action())
|
||||
end
|
||||
return false,"path("..cfg.filepath()..") acl not found"
|
||||
end
|
||||
|
||||
return M
|
||||
@@ -1,9 +1,12 @@
|
||||
return {
|
||||
-- 服务器ID,如果REDIS或MYSQL与其它服务公用必须更改此参数,要求唯一
|
||||
server_id = "TEACHER_1234567890",
|
||||
server_id = "TEACHER_1",
|
||||
|
||||
path = {
|
||||
luabytecode = "cache.fw.luabytecode"
|
||||
-- 字节码路径
|
||||
luabytecode = "cache.fw.luabytecode",
|
||||
-- 开发接口路径
|
||||
develop_api = "/app/controll/develop/"
|
||||
},
|
||||
token = {
|
||||
-- 超时时间
|
||||
|
||||
56
target/fwutils/develop/controll/menu.lua
Normal file
56
target/fwutils/develop/controll/menu.lua
Normal file
@@ -0,0 +1,56 @@
|
||||
local fwutils_config = require("fwutils.config")
|
||||
local develop_menu = require("fwutils.develop.function.menu")
|
||||
|
||||
local function get_by_id()
|
||||
|
||||
local conn = mysql.new(_G[fwutils_config.db.mysql_pool_name]):get()
|
||||
succ(develop_menu.get_by_id(pint("id"),conn))
|
||||
end
|
||||
|
||||
local function add()
|
||||
local data = pjson()
|
||||
local conn = mysql.new(_G[fwutils_config.db.mysql_pool_name]):get()
|
||||
if develop_menu.add(data,conn) then
|
||||
succ({})
|
||||
else
|
||||
error("")
|
||||
end
|
||||
end
|
||||
local function update()
|
||||
local data = pjson()
|
||||
local conn = mysql.new(_G[fwutils_config.db.mysql_pool_name]):get()
|
||||
if develop_menu.update(data,conn) then
|
||||
succ({})
|
||||
else
|
||||
error("")
|
||||
end
|
||||
end
|
||||
local function delete()
|
||||
local data = pjson()
|
||||
local conn = mysql.new(_G[fwutils_config.db.mysql_pool_name]):get()
|
||||
if develop_menu.delete(data.id,conn) then
|
||||
succ({})
|
||||
else
|
||||
error("")
|
||||
end
|
||||
end
|
||||
local function list()
|
||||
local data = pjson()
|
||||
local conn = mysql.new(_G[fwutils_config.db.mysql_pool_name]):get()
|
||||
local d = develop_menu.list(data.search,data.limit,conn)
|
||||
succ(d)
|
||||
end
|
||||
local function refresh()
|
||||
local module_menu = require("fwutils.develop.function.menu")
|
||||
local conn = mysql.new(_G[fwutils_config.db.mysql_pool_name]):get()
|
||||
module_menu.make_bytecode(nil,conn)
|
||||
succ({})
|
||||
end
|
||||
exec({
|
||||
get_by_id = get_by_id,
|
||||
list = list,
|
||||
add = add,
|
||||
update = update,
|
||||
delete = delete,
|
||||
refresh = refresh,
|
||||
})
|
||||
13
target/fwutils/develop/controll/role.lua
Normal file
13
target/fwutils/develop/controll/role.lua
Normal file
@@ -0,0 +1,13 @@
|
||||
require("app.app")
|
||||
|
||||
local fwutils_config = require("fwutils.config")
|
||||
local develop_role = require("fwutils.develop.function.role")
|
||||
local function list()
|
||||
local data = pjson()
|
||||
local conn = mysql.new(_G[fwutils_config.db.mysql_pool_name]):get()
|
||||
local d = develop_role.list(data.search,data.limit,conn)
|
||||
succ(d)
|
||||
end
|
||||
exec({
|
||||
list = list,
|
||||
})
|
||||
57
target/fwutils/develop/controll/role_permissions.lua
Normal file
57
target/fwutils/develop/controll/role_permissions.lua
Normal file
@@ -0,0 +1,57 @@
|
||||
require("app.app")
|
||||
|
||||
local fwutils_config = require("fwutils.config")
|
||||
local develop_role_permissions = require("fwutils.develop.function.role_permissions")
|
||||
|
||||
local function get_by_id()
|
||||
local conn = mysql.new(_G[fwutils_config.db.mysql_pool_name]):get()
|
||||
succ(develop_role_permissions.get_by_id(pint("id"),conn))
|
||||
end
|
||||
|
||||
local function add()
|
||||
local data = pjson()
|
||||
local conn = mysql.new(_G[fwutils_config.db.mysql_pool_name]):get()
|
||||
if develop_role_permissions.add(data,conn) then
|
||||
succ({})
|
||||
else
|
||||
error("")
|
||||
end
|
||||
end
|
||||
local function update()
|
||||
local data = pjson()
|
||||
local conn = mysql.new(_G[fwutils_config.db.mysql_pool_name]):get()
|
||||
if develop_role_permissions.update(data,conn) then
|
||||
succ({})
|
||||
else
|
||||
error("")
|
||||
end
|
||||
end
|
||||
local function delete()
|
||||
local data = pjson()
|
||||
local conn = mysql.new(_G[fwutils_config.db.mysql_pool_name]):get()
|
||||
if develop_role_permissions.delete(data.id,conn) then
|
||||
succ({})
|
||||
else
|
||||
error("")
|
||||
end
|
||||
end
|
||||
local function list()
|
||||
local data = pjson()
|
||||
local conn = mysql.new(_G[fwutils_config.db.mysql_pool_name]):get()
|
||||
local d = develop_role_permissions.list(data.search,data.limit,conn)
|
||||
succ(d)
|
||||
end
|
||||
local function refresh()
|
||||
local module_acl = require("fwutils.develop.function.role_permissions")
|
||||
local conn = mysql.new(_G[fwutils_config.db.mysql_pool_name]):get()
|
||||
module_acl.make_bytecode(nil,conn)
|
||||
succ({})
|
||||
end
|
||||
exec({
|
||||
get_by_id = get_by_id,
|
||||
list = list,
|
||||
add = add,
|
||||
update = update,
|
||||
delete = delete,
|
||||
refresh = refresh,
|
||||
})
|
||||
57
target/fwutils/develop/controll/template.lua
Normal file
57
target/fwutils/develop/controll/template.lua
Normal file
@@ -0,0 +1,57 @@
|
||||
require("app.app")
|
||||
|
||||
local fwutils_config = require("fwutils.config")
|
||||
local develop_template = require("fwutils.develop.function.template")
|
||||
|
||||
local function get_by_id()
|
||||
local conn = mysql.new(_G[fwutils_config.db.mysql_pool_name]):get()
|
||||
succ(develop_template.get_by_id(pint("id"),conn))
|
||||
end
|
||||
|
||||
local function add()
|
||||
local data = pjson()
|
||||
local conn = mysql.new(_G[fwutils_config.db.mysql_pool_name]):get()
|
||||
if develop_template.add(data,conn) then
|
||||
succ({})
|
||||
else
|
||||
error("")
|
||||
end
|
||||
end
|
||||
local function update()
|
||||
local data = pjson()
|
||||
local conn = mysql.new(_G[fwutils_config.db.mysql_pool_name]):get()
|
||||
if develop_template.update(data,conn) then
|
||||
succ({})
|
||||
else
|
||||
error("")
|
||||
end
|
||||
end
|
||||
local function delete()
|
||||
local data = pjson()
|
||||
local conn = mysql.new(_G[fwutils_config.db.mysql_pool_name]):get()
|
||||
if develop_template.delete(data.id,conn) then
|
||||
succ({})
|
||||
else
|
||||
error("")
|
||||
end
|
||||
end
|
||||
local function list()
|
||||
local data = pjson()
|
||||
local conn = mysql.new(_G[fwutils_config.db.mysql_pool_name]):get()
|
||||
local d = develop_template.list(data.search,data.limit,conn)
|
||||
succ(d)
|
||||
end
|
||||
local function refresh()
|
||||
local module_template = require("fwutils.template_engine")
|
||||
local conn = mysql.new(_G[fwutils_config.db.mysql_pool_name]):get()
|
||||
module_template.update(conn)
|
||||
succ()
|
||||
end
|
||||
exec({
|
||||
get_by_id = get_by_id,
|
||||
list = list,
|
||||
add = add,
|
||||
update = update,
|
||||
delete = delete,
|
||||
refresh = refresh,
|
||||
})
|
||||
214
target/fwutils/develop/function/menu.lua
Normal file
214
target/fwutils/develop/function/menu.lua
Normal file
@@ -0,0 +1,214 @@
|
||||
require("fwutils.webapi")
|
||||
-- CREATE TABLE `fw_menu` (
|
||||
-- `id` int NOT NULL AUTO_INCREMENT,
|
||||
-- `role_id` int DEFAULT NULL,
|
||||
-- `title` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
-- `path` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
-- `icon` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
-- `sort` int DEFAULT NULL,
|
||||
-- `parent_id` int DEFAULT NULL,
|
||||
-- `create_time` datetime DEFAULT NULL,
|
||||
-- `update_time` datetime DEFAULT NULL,
|
||||
-- `delete_time` datetime DEFAULT NULL,
|
||||
-- PRIMARY KEY (`id`)
|
||||
-- ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
local M = {}
|
||||
|
||||
function M.get_by_id(id,conn)
|
||||
local select = conn:select()
|
||||
select:table("fw_menu LEFT JOIN fw_role ON fw_menu.role_id = fw_role.id")
|
||||
select:field({
|
||||
"fw_menu.id",
|
||||
"fw_menu.title",
|
||||
"fw_menu.path",
|
||||
"fw_menu.icon",
|
||||
"fw_menu.sort",
|
||||
"fw_menu.parent_id",
|
||||
"fw_menu.create_time",
|
||||
"fw_menu.update_time",
|
||||
"fw_menu.delete_time",
|
||||
"fw_role.title as role_title",
|
||||
"fw_role.id as role_id",
|
||||
})
|
||||
select:where_i32("fw_menu.id","=",id)
|
||||
select:where_expression("AND fw_menu.delete_time IS NULL")
|
||||
select:limit(0,1)
|
||||
local result = select:query()
|
||||
if result:row_count() == 0 then
|
||||
return nil
|
||||
end
|
||||
local d = result:table()[1]
|
||||
return d
|
||||
end
|
||||
function M.add(data,conn)
|
||||
local insert = conn:insert()
|
||||
insert:table("fw_menu")
|
||||
insert:set_str("title",data.title)
|
||||
insert:set_str("path",data.path)
|
||||
insert:set_i32("role_id",data.role_id)
|
||||
if data.icon ~= nil then
|
||||
insert:set_str("icon",data.icon)
|
||||
end
|
||||
if data.sort ~= nil then
|
||||
insert:set_i32("sort",data.sort)
|
||||
end
|
||||
if data.parent_id ~= nil and data.parent_id ~= 0 then
|
||||
insert:set_i32("parent_id",data.parent_id)
|
||||
end
|
||||
insert:set_not_ppst("create_time","NOW()")
|
||||
local d = insert:exec()
|
||||
return d == 1
|
||||
end
|
||||
function M.update(data,conn)
|
||||
local update = conn:update()
|
||||
update:table("fw_menu")
|
||||
if data.title ~= nil then
|
||||
update:set_str("title",data.title)
|
||||
end
|
||||
if data.path ~= nil then
|
||||
update:set_str("path",data.path)
|
||||
end
|
||||
if data.role_id ~= nil then
|
||||
update:set_i32("role_id",data.role_id)
|
||||
end
|
||||
if data.icon ~= nil then
|
||||
update:set_str("icon",data.icon)
|
||||
end
|
||||
if data.sort ~= nil then
|
||||
update:set_i32("sort",data.sort)
|
||||
end
|
||||
if data.parent_id ~= nil then
|
||||
update:set_i32("parent_id",data.parent_id)
|
||||
end
|
||||
update:set("update_time=NOW()")
|
||||
update:where_i32("id","=",data.id)
|
||||
local d = update:exec()
|
||||
return d == 1
|
||||
end
|
||||
function M.delete(id,conn)
|
||||
local update = conn:update()
|
||||
update:table("fw_menu")
|
||||
update:set("delete_time=NOW()")
|
||||
update:where_i32("id","=",id)
|
||||
local d = update:exec()
|
||||
return d == 1
|
||||
end
|
||||
function M.list(search,limit,conn)
|
||||
if search.role_id == -1 then
|
||||
return {
|
||||
count = 0,
|
||||
data = {}
|
||||
}
|
||||
end
|
||||
return query_model_ex(conn,[=[
|
||||
fw_menu LEFT JOIN fw_role ON fw_menu.role_id = fw_role.id
|
||||
]=],{
|
||||
"fw_menu.id",
|
||||
"fw_menu.title",
|
||||
"fw_menu.path",
|
||||
"fw_menu.icon",
|
||||
"fw_menu.sort",
|
||||
"fw_menu.parent_id",
|
||||
"fw_menu.create_time",
|
||||
"fw_menu.update_time",
|
||||
"fw_menu.delete_time",
|
||||
"fw_role.title as role_title",
|
||||
"fw_role.id as role_id",
|
||||
},limit.start,limit.length,function(sel)
|
||||
|
||||
if search.role_id ~= nil and search.role_id ~= 0 then
|
||||
sel:where_i32("fw_menu.role_id","=",search.role_id)
|
||||
end
|
||||
sel:where_expression("AND fw_menu.delete_time IS NULL")
|
||||
end,function(sel_data)
|
||||
sel_data:orderby("fw_menu.sort DESC")
|
||||
end)
|
||||
end
|
||||
M.make_bytecode = function(role_id,conn)
|
||||
-- 查询菜单表
|
||||
local select = conn:select()
|
||||
select:table("fw_menu")
|
||||
select:where_expression("AND delete_time IS NULL")
|
||||
if role_id ~= nil then
|
||||
select:where_i32("role_id", "=", role_id)
|
||||
end
|
||||
local result = select:query()
|
||||
|
||||
local bc = {}
|
||||
local items_by_id = {} -- 通过id快速查找菜单项:{id = {role_id, title, item, parent_id}}
|
||||
local items_with_parent = {} -- 存储有父级的菜单项
|
||||
|
||||
-- 第一遍:读取所有菜单项并存储
|
||||
while result:next() do
|
||||
local id = result:get("id")
|
||||
local role_id = tostring(result:get("role_id"))
|
||||
local title = result:get("title")
|
||||
local path = result:get("path")
|
||||
local icon = result:get("icon")
|
||||
local sort = result:get("sort")
|
||||
local parent_id = result:get("parent_id")
|
||||
|
||||
if not title or title == "" then
|
||||
goto continue
|
||||
end
|
||||
|
||||
if bc[role_id] == nil then
|
||||
bc[role_id] = {}
|
||||
end
|
||||
|
||||
local item = {
|
||||
path = path,
|
||||
icon = icon,
|
||||
sort = sort,
|
||||
}
|
||||
|
||||
-- 存储所有菜单项信息
|
||||
items_by_id[id] = {
|
||||
role_id = role_id,
|
||||
title = title,
|
||||
item = item,
|
||||
parent_id = parent_id
|
||||
}
|
||||
|
||||
-- 如果parent_id为空,则作为顶层菜单项
|
||||
if parent_id == nil or parent_id == 0 then
|
||||
bc[role_id][title] = item
|
||||
else
|
||||
-- 有父级,记录下来稍后处理
|
||||
table.insert(items_with_parent, {
|
||||
id = id,
|
||||
role_id = role_id,
|
||||
title = title,
|
||||
item = item,
|
||||
parent_id = parent_id
|
||||
})
|
||||
end
|
||||
|
||||
::continue::
|
||||
end
|
||||
|
||||
-- 第二遍:处理有父级的菜单项,构建children结构
|
||||
for _, menu_item in ipairs(items_with_parent) do
|
||||
local parent_info = items_by_id[menu_item.parent_id]
|
||||
if parent_info then
|
||||
local parent_item = parent_info.item
|
||||
|
||||
-- 如果父项还没有children表,创建它
|
||||
if not parent_item.children then
|
||||
parent_item.children = {}
|
||||
end
|
||||
|
||||
-- 将子项添加到父项的children中
|
||||
parent_item.children[menu_item.title] = menu_item.item
|
||||
end
|
||||
end
|
||||
|
||||
local code = "return " .. require("serpent").serialize(bc, {comment = false})
|
||||
utils.save_file(fw.website_dir().."/"..(fwutils_config.path.luabytecode:gsub("%.", "/")).."/menu_bc.lua",code)
|
||||
return true
|
||||
end
|
||||
M.bytecode = function(role_id)
|
||||
local menu_bc = require(fwutils_config.path.luabytecode..".menu_bc")
|
||||
return menu_bc[string.format("%d",role_id)]
|
||||
end
|
||||
return M
|
||||
22
target/fwutils/develop/function/role.lua
Normal file
22
target/fwutils/develop/function/role.lua
Normal file
@@ -0,0 +1,22 @@
|
||||
require("fwutils.webapi")
|
||||
-- CREATE TABLE `fw_role` (
|
||||
-- `id` int NOT NULL AUTO_INCREMENT,
|
||||
-- `title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '名称',
|
||||
-- `sort` int DEFAULT NULL COMMENT '排序',
|
||||
-- `desc` varchar(1024) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '描述',
|
||||
-- `create_time` datetime DEFAULT NULL COMMENT '创建时间',
|
||||
-- `default_filepath` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '默认页面',
|
||||
-- PRIMARY KEY (`id`)
|
||||
-- ) ENGINE=InnoDB AUTO_INCREMENT=100 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
local M = {}
|
||||
|
||||
|
||||
|
||||
function M.list(search,limit,conn)
|
||||
return query_model_ex(conn,"fw_role",{},limit.start,limit.length,function(sel)
|
||||
end,function(sel_data)
|
||||
sel_data:orderby("`sort` DESC")
|
||||
end)
|
||||
end
|
||||
|
||||
return M
|
||||
224
target/fwutils/develop/function/role_permissions.lua
Normal file
224
target/fwutils/develop/function/role_permissions.lua
Normal file
@@ -0,0 +1,224 @@
|
||||
require("fwutils.webapi")
|
||||
-- CREATE TABLE `fw_role_permissions` (
|
||||
-- `id` int NOT NULL AUTO_INCREMENT,
|
||||
-- `path` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '路径',
|
||||
-- `role_id` int DEFAULT NULL COMMENT '角色',
|
||||
-- `action` varchar(2048) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '动作',
|
||||
-- `desc` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '描述',
|
||||
-- `create_time` datetime DEFAULT NULL COMMENT '创建时间',
|
||||
-- `update_time` datetime DEFAULT NULL COMMENT '更新时间',
|
||||
-- `delete_time` datetime DEFAULT NULL COMMENT '删除时间',
|
||||
-- PRIMARY KEY (`id`),
|
||||
-- UNIQUE KEY `path` (`path`,`role_id`)
|
||||
-- ) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='Fastweb-角色访问权限';
|
||||
local M = {}
|
||||
|
||||
M.get_by_id = function(id,conn)
|
||||
local select = conn:select()
|
||||
select:table("fw_role_permissions LEFT JOIN fw_role ON fw_role_permissions.role_id = fw_role.id")
|
||||
select:field({
|
||||
"fw_role_permissions.id",
|
||||
"fw_role_permissions.path",
|
||||
"fw_role_permissions.role_id",
|
||||
"fw_role_permissions.action",
|
||||
"fw_role_permissions.`desc`",
|
||||
"fw_role_permissions.create_time",
|
||||
"fw_role_permissions.update_time",
|
||||
"fw_role_permissions.delete_time",
|
||||
"fw_role.title as role_title",
|
||||
"fw_role.id as role_id",
|
||||
})
|
||||
select:where_i32("fw_role_permissions.id","=",id)
|
||||
select:where_expression("AND fw_role_permissions.delete_time IS NULL")
|
||||
select:limit(0,1)
|
||||
local result = select:query()
|
||||
if result:row_count() == 0 then
|
||||
return nil
|
||||
end
|
||||
local d = result:table()[1]
|
||||
return d
|
||||
end
|
||||
M.add = function(data,conn)
|
||||
local insert = conn:insert()
|
||||
insert:table("fw_role_permissions")
|
||||
insert:set_str("path",data.path)
|
||||
insert:set_i32("role_id",data.role_id)
|
||||
if data.action ~= nil then
|
||||
insert:set_str("action",data.action)
|
||||
end
|
||||
if data.desc ~= nil then
|
||||
insert:set_str("`desc`",data.desc)
|
||||
end
|
||||
insert:set_not_ppst("create_time","NOW()")
|
||||
local d = insert:exec()
|
||||
return d == 1
|
||||
end
|
||||
M.update = function(data,conn)
|
||||
local update = conn:update()
|
||||
update:table("fw_role_permissions")
|
||||
if data.path ~= nil then
|
||||
update:set_str("path",data.path)
|
||||
end
|
||||
if data.action ~= nil then
|
||||
update:set_str("action",data.action)
|
||||
end
|
||||
if data.desc ~= nil then
|
||||
update:set_str("`desc`",data.desc)
|
||||
end
|
||||
if data.role_id ~= nil then
|
||||
update:set_i32("role_id",data.role_id)
|
||||
end
|
||||
update:set("update_time=NOW()")
|
||||
update:where_i32("id","=",data.id)
|
||||
local d = update:exec()
|
||||
return d == 1
|
||||
end
|
||||
M.delete = function(id,conn)
|
||||
local update = conn:update()
|
||||
update:table("fw_role_permissions")
|
||||
update:set("delete_time=NOW()")
|
||||
update:where_i32("id","=",id)
|
||||
local d = update:exec()
|
||||
return d == 1
|
||||
end
|
||||
M.list = function(search,limit,conn)
|
||||
if search.role_id == -1 then
|
||||
return {
|
||||
count = 0,
|
||||
data = {}
|
||||
}
|
||||
end
|
||||
return query_model_ex(conn,[=[
|
||||
fw_role_permissions LEFT JOIN fw_role ON fw_role_permissions.role_id = fw_role.id
|
||||
]=],{
|
||||
"fw_role_permissions.id",
|
||||
"fw_role_permissions.path",
|
||||
"fw_role_permissions.role_id",
|
||||
"fw_role_permissions.action",
|
||||
"fw_role_permissions.`desc`",
|
||||
"fw_role_permissions.create_time",
|
||||
"fw_role_permissions.update_time",
|
||||
"fw_role_permissions.delete_time",
|
||||
"fw_role.title as role_title",
|
||||
"fw_role.id as role_id",
|
||||
},limit.start,limit.length,function(sel)
|
||||
|
||||
if search.role_id ~= nil and search.role_id ~= 0 then
|
||||
sel:where_i32("fw_role_permissions.role_id","=",search.role_id)
|
||||
end
|
||||
sel:where_expression("AND fw_role_permissions.delete_time IS NULL")
|
||||
end,function(sel_data)
|
||||
sel_data:orderby("fw_role_permissions.create_time DESC")
|
||||
end)
|
||||
end
|
||||
-- 更新
|
||||
M.make_bytecode = function(role_id,conn)
|
||||
-- 查询权限表
|
||||
local select = conn:select()
|
||||
select:table("fw_role_permissions")
|
||||
select:where_expression("AND delete_time IS NULL")
|
||||
if role_id ~= nil then
|
||||
select:where_i32("role_id", "=", role_id)
|
||||
end
|
||||
local result = select:query()
|
||||
|
||||
|
||||
local bc = {}
|
||||
|
||||
while result:next() do
|
||||
local id = result:get("id")
|
||||
local path = result:get("path")
|
||||
local role_id = tostring(result:get("role_id"))
|
||||
local action = result:get("action")
|
||||
local desc = result:get("desc")
|
||||
local create_time = result:get("create_time")
|
||||
local update_time = result:get("update_time")
|
||||
local delete_time = result:get("delete_time")
|
||||
-- local public = result:get("public")
|
||||
|
||||
if bc[role_id] == nil then
|
||||
bc[role_id] = {}
|
||||
end
|
||||
if bc[role_id]["public"] == nil then
|
||||
bc[role_id]["public"] = {}
|
||||
end
|
||||
if bc[role_id]["private"] == nil then
|
||||
bc[role_id]["private"] = {}
|
||||
end
|
||||
-- 处理 action 字段,将其切分为表或空表
|
||||
local actions_tbl = {}
|
||||
if action and action ~= "" then
|
||||
for act in string.gmatch(action, "([^,]+)") do
|
||||
table.insert(actions_tbl, act)
|
||||
end
|
||||
end
|
||||
|
||||
local item = {
|
||||
create_time = create_time,
|
||||
update_time = update_time,
|
||||
delete_time = delete_time,
|
||||
action = actions_tbl,
|
||||
desc = desc,
|
||||
}
|
||||
-- if public == 1 then
|
||||
-- bc[role_id]["public"][path] = item
|
||||
-- else
|
||||
-- bc[role_id]["private"][path] = item
|
||||
-- end
|
||||
bc[role_id][path] = item
|
||||
end
|
||||
local code = "return " .. require("serpent").serialize(bc, {comment = false})
|
||||
utils.save_file(fw.website_dir().."/"..(fwutils_config.path.luabytecode:gsub("%.", "/")).."/acl_bc.lua",code)
|
||||
return true
|
||||
end
|
||||
-- 匹配
|
||||
M.match = function(cfg)
|
||||
|
||||
local function match_path(path, patterns)
|
||||
|
||||
-- print("[match_path] path:",path)
|
||||
for pattern, v in pairs(patterns) do
|
||||
|
||||
-- 如果是正则(以^开头),用string.match,否则精确匹配
|
||||
if string.sub(pattern, 1, 1) == "^" then
|
||||
|
||||
if string.match(path, pattern) then
|
||||
-- print("[TRUE] pattern:",pattern,",path:",path)
|
||||
return true, v
|
||||
-- else
|
||||
-- print("[FALSE] pattern:",pattern,",path:",path)
|
||||
end
|
||||
else
|
||||
if path == pattern then
|
||||
return true, v
|
||||
end
|
||||
end
|
||||
end
|
||||
return false, nil
|
||||
end
|
||||
-- 检查action
|
||||
local function check_action(actions,action)
|
||||
if actions == nil or #actions == 0 then
|
||||
return true
|
||||
end
|
||||
|
||||
for _,v in pairs(actions) do
|
||||
if v == action then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false, "action not match"
|
||||
end
|
||||
local role_id_str = string.format("%d",cfg.role_id())
|
||||
local acl_bc = require(fwutils_config.path.luabytecode..".acl_bc")
|
||||
if acl_bc[role_id_str] == nil then
|
||||
return false,"role id("..role_id_str..") acl not found"
|
||||
end
|
||||
local result, item = match_path(cfg.filepath(), acl_bc[role_id_str])
|
||||
if result then
|
||||
return check_action(item.action,cfg.action())
|
||||
end
|
||||
return false,"path("..cfg.filepath()..") acl not found"
|
||||
end
|
||||
|
||||
return M
|
||||
102
target/fwutils/develop/function/template.lua
Normal file
102
target/fwutils/develop/function/template.lua
Normal file
@@ -0,0 +1,102 @@
|
||||
require("fwutils.webapi")
|
||||
-- CREATE TABLE `fw_template` (
|
||||
-- `id` int NOT NULL AUTO_INCREMENT,
|
||||
-- `role_id` int DEFAULT NULL,
|
||||
-- `key` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
-- `value` varchar(2048) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
-- `enable` tinyint NOT NULL COMMENT '是否启用',
|
||||
-- PRIMARY KEY (`id`),
|
||||
-- UNIQUE KEY `role_id` (`role_id`,`key`)
|
||||
-- ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='Fastweb-关键词模板';
|
||||
local M = {}
|
||||
|
||||
function M.get_by_id(id,conn)
|
||||
local select = conn:select()
|
||||
select:table("fw_template LEFT JOIN fw_role ON fw_template.role_id = fw_role.id")
|
||||
select:field({
|
||||
"fw_template.id",
|
||||
"fw_template.role_id",
|
||||
"fw_template.`key`",
|
||||
"fw_template.value",
|
||||
"fw_template.enable",
|
||||
"fw_role.title as role_title",
|
||||
})
|
||||
select:where_i32("fw_template.id","=",id)
|
||||
|
||||
select:limit(0,1)
|
||||
local result = select:query()
|
||||
if result:row_count() == 0 then
|
||||
return nil
|
||||
end
|
||||
local d = result:table()[1]
|
||||
return d
|
||||
end
|
||||
function M.add(data,conn)
|
||||
local insert = conn:insert()
|
||||
insert:table("fw_template")
|
||||
|
||||
if data.role_id ~= nil and data.role_id ~= cjson.null then
|
||||
insert:set_i32("role_id",data.role_id)
|
||||
end
|
||||
if data.key ~= nil then
|
||||
insert:set_str("`key`",data.key)
|
||||
end
|
||||
if data.value ~= nil then
|
||||
insert:set_str("value",data.value)
|
||||
end
|
||||
if data.enable ~= nil then
|
||||
insert:set_i32("enable",data.enable)
|
||||
end
|
||||
local d = insert:exec()
|
||||
return d == 1
|
||||
end
|
||||
function M.update(data,conn)
|
||||
local update = conn:update()
|
||||
update:table("fw_template")
|
||||
|
||||
if data.role_id ~= nil then
|
||||
update:set_i32("role_id",data.role_id)
|
||||
end
|
||||
if data.key ~= nil then
|
||||
update:set_str("`key`",data.key)
|
||||
end
|
||||
if data.value ~= nil then
|
||||
update:set_str("value",data.value)
|
||||
end
|
||||
if data.enable ~= nil then
|
||||
update:set_i32("enable",data.enable)
|
||||
end
|
||||
update:where_i32("id","=",data.id)
|
||||
local d = update:exec()
|
||||
return d == 1
|
||||
end
|
||||
function M.delete(id,conn)
|
||||
local del = conn:delete()
|
||||
del:table("fw_template")
|
||||
del:where_i32("id","=",id)
|
||||
local d = del:exec()
|
||||
return d == 1
|
||||
end
|
||||
function M.list(search,limit,conn)
|
||||
|
||||
return query_model_ex(conn,[=[
|
||||
fw_template LEFT JOIN fw_role ON fw_template.role_id = fw_role.id
|
||||
]=],{
|
||||
"fw_template.id",
|
||||
"fw_template.role_id",
|
||||
"fw_template.`key`",
|
||||
"fw_template.value",
|
||||
"fw_template.enable",
|
||||
"fw_role.title as role_title",
|
||||
"fw_role.id as role_id",
|
||||
},limit.start,limit.length,function(sel)
|
||||
|
||||
if search.role_id ~= nil and search.role_id ~= -1 then
|
||||
sel:where_i32("fw_template.role_id","=",search.role_id)
|
||||
end
|
||||
end,function(sel_data)
|
||||
sel_data:orderby("fw_template.enable DESC")
|
||||
end)
|
||||
end
|
||||
|
||||
return M
|
||||
154
target/fwutils/funs.lua
Normal file
154
target/fwutils/funs.lua
Normal file
@@ -0,0 +1,154 @@
|
||||
local M = {}
|
||||
|
||||
|
||||
M.file_get_contents = function(filepath)
|
||||
|
||||
local file, errmsg = io.open(fw.website_dir()..filepath, "r")
|
||||
if not file then
|
||||
fw.throw_string(errmsg)
|
||||
end
|
||||
local content = file:read("*a")
|
||||
if content == nil or content == "" then
|
||||
print("file_get_contents error: ",filepath)
|
||||
return ""
|
||||
end
|
||||
local replaced,c2 = engine.replace(content)
|
||||
if replaced then
|
||||
return c2
|
||||
end
|
||||
return content
|
||||
end
|
||||
M.menu_top = function()
|
||||
-- 当前请求路径
|
||||
local request_path = request.filepath() or ""
|
||||
-- 取配置
|
||||
local menuData = require("fwutils.develop.function.menu").bytecode(string.format("%d",engine.cfg.role_id()))
|
||||
if not menuData then
|
||||
return "<!-- no menu config -->"
|
||||
end
|
||||
|
||||
-- 提取并排序主菜单
|
||||
local menuItems = {}
|
||||
for name, item in pairs(menuData) do
|
||||
table.insert(menuItems, {
|
||||
name = name,
|
||||
item = item,
|
||||
sort = item.sort or 0
|
||||
})
|
||||
end
|
||||
table.sort(menuItems, function(a, b)
|
||||
return a.sort > b.sort
|
||||
end)
|
||||
|
||||
local html = [[
|
||||
|
||||
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
|
||||
]]
|
||||
|
||||
-- 渲染主菜单
|
||||
for _, entry in ipairs(menuItems) do
|
||||
local name = entry.name
|
||||
local item = entry.item
|
||||
local icon = item.icon or ""
|
||||
local path = item.path or "#"
|
||||
local activeClass = ""
|
||||
|
||||
if item.children then
|
||||
-- 有子菜单
|
||||
local isMegamenu = item.megamenu and " dropdown-megamenu" or ""
|
||||
|
||||
-- 检查子菜单是否有激活
|
||||
local hasActiveChild = false
|
||||
local children = {}
|
||||
for childName, childItem in pairs(item.children) do
|
||||
table.insert(children, {
|
||||
name = childName,
|
||||
item = childItem,
|
||||
sort = childItem.sort or 0
|
||||
})
|
||||
if not hasActiveChild and (request_path == (childItem.path or "")) then
|
||||
hasActiveChild = true
|
||||
end
|
||||
end
|
||||
table.sort(children, function(a, b)
|
||||
return a.sort > b.sort
|
||||
end)
|
||||
|
||||
-- 父菜单激活:当前页面是父菜单path,或是任一子菜单path
|
||||
if request_path == path or hasActiveChild then
|
||||
activeClass = "active-link"
|
||||
end
|
||||
|
||||
html = html .. [[
|
||||
<li class="nav-item dropdown ]] .. activeClass .. [[">
|
||||
<a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
|
||||
<i class="]] .. icon .. [["></i> ]] .. name .. [[
|
||||
</a>
|
||||
<ul class="dropdown-menu]] .. isMegamenu .. [[">
|
||||
]]
|
||||
|
||||
-- 渲染子菜单
|
||||
for _, child in ipairs(children) do
|
||||
local childName = child.name
|
||||
local childItem = child.item
|
||||
local childPath = childItem.path or "#"
|
||||
|
||||
-- 子菜单不设置激活样式
|
||||
html = html .. [[
|
||||
<li>
|
||||
<a class="dropdown-item" href="]] .. childPath .. [[">
|
||||
<span>]] .. childName .. [[</span>
|
||||
</a>
|
||||
</li>
|
||||
]]
|
||||
end
|
||||
|
||||
html = html .. [[
|
||||
</ul>
|
||||
</li>
|
||||
]]
|
||||
else
|
||||
-- 没有子菜单
|
||||
-- 简单的“当前页面是否激活”检查
|
||||
if request_path == path then
|
||||
activeClass = "active-link"
|
||||
end
|
||||
html = html .. [[
|
||||
<li class="nav-item ]] .. activeClass .. [[">
|
||||
<a class="nav-link" href="]] .. path .. [[">
|
||||
<i class="]] .. icon .. [["></i> ]] .. name .. [[
|
||||
</a>
|
||||
</li>
|
||||
]]
|
||||
end
|
||||
end
|
||||
|
||||
html = html .. [[
|
||||
</ul>
|
||||
]]
|
||||
|
||||
return [=[
|
||||
<nav class="navbar navbar-expand-lg">
|
||||
<div class="container">
|
||||
<div class="offcanvas offcanvas-end" id="MobileMenu">
|
||||
<div class="offcanvas-header">
|
||||
<h5 class="offcanvas-title semibold">Navigation</h5>
|
||||
<button type="button" class="btn btn-danger btn-sm ms-auto" data-bs-dismiss="offcanvas">
|
||||
<i class="icon-clear"></i>
|
||||
</button>
|
||||
</div>
|
||||
]=]..html..[[
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
]]
|
||||
end
|
||||
M.regist = function(env)
|
||||
for key, value in pairs(M) do
|
||||
if type(value) == "function" and key ~= "functions" and key ~= "get_all_functions" then
|
||||
env[key] = value
|
||||
end
|
||||
end
|
||||
return env
|
||||
end
|
||||
return M
|
||||
@@ -16,7 +16,9 @@ M.initialization = function(conn)
|
||||
return true
|
||||
end
|
||||
M.__get_guest_role_id = function(mysql_conn)
|
||||
local ppst = mysql_conn:setsql("SELECT * FROM fw_role WHERE guest = 1")
|
||||
local config = require("fwutils.config")
|
||||
local ppst = mysql_conn:setsql("SELECT * FROM fw_role WHERE guest = 1 AND server_id = ?")
|
||||
ppst:set_str(1,config.server_id)
|
||||
local result = ppst:query()
|
||||
if result:row_count() ~= 1 then
|
||||
return false,"role guest not found"
|
||||
@@ -26,7 +28,7 @@ M.__get_guest_role_id = function(mysql_conn)
|
||||
local bc = {
|
||||
GUEST_ROLE_ID = result:get("id"),
|
||||
}
|
||||
local config = require("fwutils.config")
|
||||
|
||||
local code = "return " .. require("serpent").serialize(bc, {comment = false})
|
||||
utils.save_file(fw.website_dir().."/"..(config.path.luabytecode:gsub("%.", "/")).."/fwcache.lua",code)
|
||||
return true
|
||||
|
||||
@@ -1,104 +0,0 @@
|
||||
local fw = require("fastweb")
|
||||
local config = require("fwutils.config")
|
||||
local M = {}
|
||||
-- CREATE TABLE `fw_menu` (
|
||||
-- `id` int NOT NULL AUTO_INCREMENT,
|
||||
-- `role_id` int DEFAULT NULL,
|
||||
-- `title` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
-- `path` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
-- `icon` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
-- `sort` int DEFAULT NULL,
|
||||
-- `parent_id` int DEFAULT NULL,
|
||||
-- PRIMARY KEY (`id`)
|
||||
-- ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- 更新
|
||||
M.update = function(role_id,conn)
|
||||
-- 查询菜单表
|
||||
local select = conn:select()
|
||||
select:table("fw_menu")
|
||||
select:where_expression("AND delete_time IS NULL")
|
||||
if role_id ~= nil then
|
||||
select:where_i32("role_id", "=", role_id)
|
||||
end
|
||||
local result = select:query()
|
||||
|
||||
local bc = {}
|
||||
local items_by_id = {} -- 通过id快速查找菜单项:{id = {role_id, title, item, parent_id}}
|
||||
local items_with_parent = {} -- 存储有父级的菜单项
|
||||
|
||||
-- 第一遍:读取所有菜单项并存储
|
||||
while result:next() do
|
||||
local id = result:get("id")
|
||||
local role_id = tostring(result:get("role_id"))
|
||||
local title = result:get("title")
|
||||
local path = result:get("path")
|
||||
local icon = result:get("icon")
|
||||
local sort = result:get("sort")
|
||||
local parent_id = result:get("parent_id")
|
||||
|
||||
if not title or title == "" then
|
||||
goto continue
|
||||
end
|
||||
|
||||
if bc[role_id] == nil then
|
||||
bc[role_id] = {}
|
||||
end
|
||||
|
||||
local item = {
|
||||
path = path,
|
||||
icon = icon,
|
||||
sort = sort,
|
||||
}
|
||||
|
||||
-- 存储所有菜单项信息
|
||||
items_by_id[id] = {
|
||||
role_id = role_id,
|
||||
title = title,
|
||||
item = item,
|
||||
parent_id = parent_id
|
||||
}
|
||||
|
||||
-- 如果parent_id为空,则作为顶层菜单项
|
||||
if parent_id == nil or parent_id == 0 then
|
||||
bc[role_id][title] = item
|
||||
else
|
||||
-- 有父级,记录下来稍后处理
|
||||
table.insert(items_with_parent, {
|
||||
id = id,
|
||||
role_id = role_id,
|
||||
title = title,
|
||||
item = item,
|
||||
parent_id = parent_id
|
||||
})
|
||||
end
|
||||
|
||||
::continue::
|
||||
end
|
||||
|
||||
-- 第二遍:处理有父级的菜单项,构建children结构
|
||||
for _, menu_item in ipairs(items_with_parent) do
|
||||
local parent_info = items_by_id[menu_item.parent_id]
|
||||
if parent_info then
|
||||
local parent_item = parent_info.item
|
||||
|
||||
-- 如果父项还没有children表,创建它
|
||||
if not parent_item.children then
|
||||
parent_item.children = {}
|
||||
end
|
||||
|
||||
-- 将子项添加到父项的children中
|
||||
parent_item.children[menu_item.title] = menu_item.item
|
||||
end
|
||||
end
|
||||
|
||||
local code = "return " .. require("serpent").serialize(bc, {comment = false})
|
||||
utils.save_file(fw.website_dir().."/"..(config.path.luabytecode:gsub("%.", "/")).."/menu_bc.lua",code)
|
||||
return true
|
||||
end
|
||||
M.get = function(role_id)
|
||||
local menu_bc = require(config.path.luabytecode..".menu_bc")
|
||||
return menu_bc[string.format("%d",role_id)]
|
||||
end
|
||||
|
||||
return M
|
||||
@@ -4,186 +4,18 @@ local config = require("fwutils.config")
|
||||
local request = require("fastweb.request")
|
||||
local response = require("fastweb.response")
|
||||
local cjson = require("cjson")
|
||||
local funs = require("fwutils.funs")
|
||||
-- 允许的扩展名
|
||||
local allowed_extensions = {
|
||||
"shtml",
|
||||
"html",
|
||||
"js"
|
||||
}
|
||||
local template_engine_bc_this_role = nil
|
||||
local cfg = nil
|
||||
local M = {
|
||||
cfg = nil,
|
||||
template_engine_bc_this_role = nil
|
||||
}
|
||||
|
||||
local M = {}
|
||||
|
||||
function file_get_contents(filepath)
|
||||
|
||||
local file, errmsg = io.open(fw.website_dir()..filepath, "r")
|
||||
if not file then
|
||||
err.server(errmsg)
|
||||
end
|
||||
local content = file:read("*a")
|
||||
if content == nil or content == "" then
|
||||
print("file_get_contents error: ",filepath)
|
||||
return ""
|
||||
end
|
||||
local replaced,c2 = M.replace(content)
|
||||
if replaced then
|
||||
return c2
|
||||
end
|
||||
return content
|
||||
end
|
||||
function menu_top()
|
||||
-- 当前请求路径
|
||||
local request_path = request.filepath() or ""
|
||||
-- 取配置
|
||||
local menuData = require("fwutils.menu").get(string.format("%d",cfg.role_id()))
|
||||
if not menuData then
|
||||
return "<!-- no menu config -->"
|
||||
end
|
||||
|
||||
-- 提取并排序主菜单
|
||||
local menuItems = {}
|
||||
for name, item in pairs(menuData) do
|
||||
table.insert(menuItems, {
|
||||
name = name,
|
||||
item = item,
|
||||
sort = item.sort or 0
|
||||
})
|
||||
end
|
||||
table.sort(menuItems, function(a, b)
|
||||
return a.sort > b.sort
|
||||
end)
|
||||
|
||||
local html = [[
|
||||
|
||||
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
|
||||
]]
|
||||
|
||||
-- 渲染主菜单
|
||||
for _, entry in ipairs(menuItems) do
|
||||
local name = entry.name
|
||||
local item = entry.item
|
||||
local icon = item.icon or ""
|
||||
local path = item.path or "#"
|
||||
local activeClass = ""
|
||||
|
||||
if item.children then
|
||||
-- 有子菜单
|
||||
local isMegamenu = item.megamenu and " dropdown-megamenu" or ""
|
||||
|
||||
-- 检查子菜单是否有激活
|
||||
local hasActiveChild = false
|
||||
local children = {}
|
||||
for childName, childItem in pairs(item.children) do
|
||||
table.insert(children, {
|
||||
name = childName,
|
||||
item = childItem,
|
||||
sort = childItem.sort or 0
|
||||
})
|
||||
if not hasActiveChild and (request_path == (childItem.path or "")) then
|
||||
hasActiveChild = true
|
||||
end
|
||||
end
|
||||
table.sort(children, function(a, b)
|
||||
return a.sort > b.sort
|
||||
end)
|
||||
|
||||
-- 父菜单激活:当前页面是父菜单path,或是任一子菜单path
|
||||
if request_path == path or hasActiveChild then
|
||||
activeClass = "active-link"
|
||||
end
|
||||
|
||||
html = html .. [[
|
||||
<li class="nav-item dropdown ]] .. activeClass .. [[">
|
||||
<a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
|
||||
<i class="]] .. icon .. [["></i> ]] .. name .. [[
|
||||
</a>
|
||||
<ul class="dropdown-menu]] .. isMegamenu .. [[">
|
||||
]]
|
||||
|
||||
-- 渲染子菜单
|
||||
for _, child in ipairs(children) do
|
||||
local childName = child.name
|
||||
local childItem = child.item
|
||||
local childPath = childItem.path or "#"
|
||||
|
||||
-- 子菜单不设置激活样式
|
||||
html = html .. [[
|
||||
<li>
|
||||
<a class="dropdown-item" href="]] .. childPath .. [[">
|
||||
<span>]] .. childName .. [[</span>
|
||||
</a>
|
||||
</li>
|
||||
]]
|
||||
end
|
||||
|
||||
html = html .. [[
|
||||
</ul>
|
||||
</li>
|
||||
]]
|
||||
else
|
||||
-- 没有子菜单
|
||||
-- 简单的“当前页面是否激活”检查
|
||||
if request_path == path then
|
||||
activeClass = "active-link"
|
||||
end
|
||||
html = html .. [[
|
||||
<li class="nav-item ]] .. activeClass .. [[">
|
||||
<a class="nav-link" href="]] .. path .. [[">
|
||||
<i class="]] .. icon .. [["></i> ]] .. name .. [[
|
||||
</a>
|
||||
</li>
|
||||
]]
|
||||
end
|
||||
end
|
||||
|
||||
html = html .. [[
|
||||
</ul>
|
||||
]]
|
||||
|
||||
return [=[
|
||||
<nav class="navbar navbar-expand-lg">
|
||||
<div class="container">
|
||||
<div class="offcanvas offcanvas-end" id="MobileMenu">
|
||||
<div class="offcanvas-header">
|
||||
<h5 class="offcanvas-title semibold">Navigation</h5>
|
||||
<button type="button" class="btn btn-danger btn-sm ms-auto" data-bs-dismiss="offcanvas">
|
||||
<i class="icon-clear"></i>
|
||||
</button>
|
||||
</div>
|
||||
]=]..html..[[
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
]]
|
||||
end
|
||||
function template(filepath)
|
||||
local path = "/public/user/template/"..config.agent[user_agent_id()].template.."/"..filepath
|
||||
return file_get_contents(path)
|
||||
end
|
||||
|
||||
function teacher_photos()
|
||||
require("app.app")
|
||||
local agent_id = user_agent_id()
|
||||
local teacher = require("app.function.teacher")
|
||||
local teacher_info = teacher.get_by_id(pint("id"))
|
||||
if teacher_info == nil then
|
||||
return ""
|
||||
end
|
||||
local photos = cjson.decode(teacher_info.photo)
|
||||
local content = "<div><div class='home-img'><img src='".. teacher_info.avatar.."' class='img-fluid bg-img' alt=''></div></div>"
|
||||
for i,v in ipairs(photos) do
|
||||
if type(v) == "string" then
|
||||
content = content..[[<div>
|
||||
<div class="home-img">
|
||||
<img src="]]..v..[[" class="img-fluid bg-img" alt="">
|
||||
</div>
|
||||
</div>
|
||||
]]
|
||||
end
|
||||
end
|
||||
return content
|
||||
end
|
||||
-- 更新
|
||||
M.update = function(conn)
|
||||
-- 查询权限表
|
||||
@@ -211,14 +43,14 @@ M.update = function(conn)
|
||||
end
|
||||
end
|
||||
local code = "return " .. require("serpent").serialize(bc, {comment = false})
|
||||
utils.save_file(fw.website_dir().."/"..(config.path.luabytecode:gsub("%.", "/")).."/template_engine_bc.lua",code)
|
||||
utils.save_file(fw.website_dir().."/"..(fwutils_config.path.luabytecode:gsub("%.", "/")).."/template_engine_bc.lua",code)
|
||||
return true
|
||||
end
|
||||
-- 处理
|
||||
-- @param static_content 静态内容
|
||||
-- @param cfg 配置
|
||||
-- @return 是否替换(TRUE则不需要继续处理,FALSE则继续处理)
|
||||
M.handle = function(__cfg)
|
||||
M.handle = function(__cfg,functions)
|
||||
|
||||
local function has_ext(ext)
|
||||
for _, v in ipairs(allowed_extensions) do
|
||||
@@ -230,8 +62,8 @@ M.handle = function(__cfg)
|
||||
end
|
||||
|
||||
|
||||
cfg = __cfg
|
||||
template_engine_bc_this_role = {
|
||||
M.cfg = __cfg
|
||||
M.template_engine_bc_this_role = {
|
||||
template = {
|
||||
private = {},
|
||||
public = {}
|
||||
@@ -239,14 +71,14 @@ M.handle = function(__cfg)
|
||||
}
|
||||
|
||||
|
||||
local ext = utils.ext(cfg.filepath())
|
||||
local ext = utils.ext(M.cfg.filepath())
|
||||
local static_content = nil
|
||||
if ext ~= nil then
|
||||
if not has_ext(ext) then
|
||||
return false
|
||||
end
|
||||
-- 读取资源文件
|
||||
static_content = utils.read_file(fw.website_dir()..cfg.filepath())
|
||||
static_content = utils.read_file(fw.website_dir()..M.cfg.filepath())
|
||||
if static_content == nil or static_content == "" then
|
||||
return false
|
||||
end
|
||||
@@ -254,9 +86,9 @@ M.handle = function(__cfg)
|
||||
-- 无需替换的扩展名
|
||||
return false
|
||||
end
|
||||
local template_engine_bc = require(config.path.luabytecode..".template_engine_bc")
|
||||
template_engine_bc_this_role["template"]["private"] = template_engine_bc[string.format("%d",cfg.role_id())]
|
||||
template_engine_bc_this_role["template"]["public"] = template_engine_bc["public"]
|
||||
local template_engine_bc = require(fwutils_config.path.luabytecode..".template_engine_bc")
|
||||
M.template_engine_bc_this_role["template"]["private"] = template_engine_bc[string.format("%d",M.cfg.role_id())]
|
||||
M.template_engine_bc_this_role["template"]["public"] = template_engine_bc["public"]
|
||||
|
||||
|
||||
local replaced,content = M.replace(static_content)
|
||||
@@ -266,7 +98,14 @@ M.handle = function(__cfg)
|
||||
-- 执行函数
|
||||
static_content, n = static_content:gsub("%${<<<%s*(.-)%s*>>>}", function(code)
|
||||
-- 尝试编译代码(Lua 5.2+ 使用 load;Lua 5.1 可用 loadstring)
|
||||
local chunk, errmsg = load(code)
|
||||
local env = {}
|
||||
_G["engine"] = M
|
||||
local env = funs.regist(env)
|
||||
if functions ~= nil then
|
||||
env = functions.regist(env)
|
||||
end
|
||||
env["_G"] = _G
|
||||
local chunk, errmsg = load(code,nil,nil,env)
|
||||
if not chunk then
|
||||
fw.throw_string(errmsg)
|
||||
end
|
||||
@@ -356,12 +195,12 @@ M.replace = function (content)
|
||||
local value_map = {}
|
||||
|
||||
-- PUBLIC
|
||||
local flat_kvs = flatten_kvs(template_engine_bc_this_role["template"]["public"])
|
||||
local flat_kvs = flatten_kvs(M.template_engine_bc_this_role["template"]["public"])
|
||||
for k, v in pairs(flat_kvs) do
|
||||
value_map[k] = v
|
||||
end
|
||||
-- PRIVATE
|
||||
flat_kvs = flatten_kvs(template_engine_bc_this_role["template"]["private"])
|
||||
flat_kvs = flatten_kvs(M.template_engine_bc_this_role["template"]["private"])
|
||||
for k, v in pairs(flat_kvs) do
|
||||
value_map[k] = v
|
||||
end
|
||||
@@ -371,7 +210,7 @@ M.replace = function (content)
|
||||
value_map[k] = v
|
||||
end
|
||||
-- TOKEN
|
||||
flat_kvs = flatten_kvs(cfg.user_data(), "token")
|
||||
flat_kvs = flatten_kvs(M.cfg.user_data(), "token")
|
||||
for k, v in pairs(flat_kvs) do
|
||||
value_map[k] = v
|
||||
end
|
||||
|
||||
117
target/fwutils/webapi.lua
Normal file
117
target/fwutils/webapi.lua
Normal file
@@ -0,0 +1,117 @@
|
||||
cjson = require("cjson")
|
||||
fw = require("fastweb")
|
||||
request = require("fastweb.request")
|
||||
response = require("fastweb.response")
|
||||
utils = require("utils")
|
||||
mysql = require("mysql.pool")
|
||||
fwutils_config = require("fwutils.config")
|
||||
-- 执行
|
||||
function exec(map)
|
||||
local action = param("action")
|
||||
if action == nil or action == "" then
|
||||
fw.throw_string("action is required")
|
||||
return
|
||||
end
|
||||
if map[action] == nil then
|
||||
fw.throw_string("action `"..action.."()` not found")
|
||||
return
|
||||
end
|
||||
map[action]()
|
||||
end
|
||||
-- 标准回复
|
||||
function reply(code,msg,data)
|
||||
local body = cjson.encode({
|
||||
code = code,
|
||||
msg = msg,
|
||||
data = data
|
||||
})
|
||||
response.header("Content-Type","application/json")
|
||||
response.send(body)
|
||||
end
|
||||
-- 回复JSON
|
||||
function reply_json(data)
|
||||
response.header("Content-Type","application/json")
|
||||
response.send(cjson.encode(data))
|
||||
end
|
||||
|
||||
-- 快速回复-错误
|
||||
function error(msg)
|
||||
reply(201,msg)
|
||||
end
|
||||
-- 快速回复-成功
|
||||
function succ(data)
|
||||
reply(200,"",data)
|
||||
end
|
||||
-- 取请求参数(无参抛异常)
|
||||
function param_trw(name)
|
||||
return request.param(name,true)
|
||||
end
|
||||
-- 取请求参数
|
||||
function param(name)
|
||||
return request.param(name,false)
|
||||
end
|
||||
|
||||
|
||||
function pint(name)
|
||||
local result = utils.tointeger(param_trw(name))
|
||||
if result == nil then
|
||||
fw.throw_string("Parameters require integers,name:"..name..",value:"..param_trw(name))
|
||||
else
|
||||
return result
|
||||
end
|
||||
end
|
||||
function pnum(name)
|
||||
local result = tonumber(param_trw(name))
|
||||
if result == nil then
|
||||
fw.throw_string("Parameters require number,name:"..name..",value:"..param_trw(name))
|
||||
else
|
||||
return result
|
||||
end
|
||||
end
|
||||
function pstr(name)
|
||||
return param_trw(name)
|
||||
end
|
||||
function pjson()
|
||||
return cjson.decode(request.body())
|
||||
end
|
||||
-- 查询模型
|
||||
function query_model_ex(conn,table,field,start,length,callback_gen,callback_data,callback_count,distinct)
|
||||
local sel_data = conn:select()
|
||||
local sel_count = conn:select()
|
||||
|
||||
sel_data:table(table)
|
||||
sel_data:field(field)
|
||||
if start ~= nil and length ~= nil then
|
||||
sel_data:limit(start,length)
|
||||
end
|
||||
|
||||
sel_count:table(table)
|
||||
|
||||
|
||||
if distinct == nil then
|
||||
sel_count:field({"COUNT(1)"})
|
||||
else
|
||||
sel_count:field(distinct)
|
||||
end
|
||||
|
||||
if callback_gen ~= nil then
|
||||
callback_gen(sel_data)
|
||||
callback_gen(sel_count)
|
||||
end
|
||||
if callback_data ~= nil then
|
||||
callback_data(sel_data)
|
||||
end
|
||||
if callback_count ~= nil then
|
||||
callback_count(sel_count)
|
||||
end
|
||||
|
||||
|
||||
local result_count = sel_count:query()
|
||||
result_count:next()
|
||||
|
||||
local data = {
|
||||
count = result_count:get(1),
|
||||
data = sel_data:query():table()
|
||||
}
|
||||
return data
|
||||
end
|
||||
@@ -75,8 +75,17 @@ M.copy_file = function(src, dst, replace)
|
||||
return true
|
||||
end
|
||||
-- 取路径文件名(带扩展名)
|
||||
M.filename = function(filepath)
|
||||
return string.match(filepath,"[^/]+$")
|
||||
M.filename = function(filepath, have_ext)
|
||||
local filename = string.match(filepath, "[^/]+$")
|
||||
if have_ext == false then
|
||||
local name = string.match(filename, "^(.*)%.") -- get name before last dot
|
||||
if name ~= nil then
|
||||
return name
|
||||
else
|
||||
return filename -- no extension
|
||||
end
|
||||
end
|
||||
return filename
|
||||
end
|
||||
-- 删除文件
|
||||
M.delete_file = function(filepath)
|
||||
|
||||
Reference in New Issue
Block a user