a158 8 月之前
父節點
當前提交
593a262c1b

+ 24 - 24
target/cache.lua

@@ -6,35 +6,35 @@ local cjson = require("cjson")
 
 M.start = function(dirpath)
     local storage = localstorage.new()
-    fw.set_ptr("localstorage_cache",storage:self())
+    fw.set_ptr("alocalstorage_cache",storage:self())
     if storage:open(dirpath) == false then
         return false,storage:last_error()
-    end
+    end                                                                                 
     return true
 end
 
-M.close = function()
-    localstorage.new(localstorage_cache):close()
-end
-M.get = function(key)
-    return localstorage.new(localstorage_cache):read(key)
-end
-M.get_json = function(key)
-    local value = M.get(key)
-    if value then
-        return cjson.decode(value)
-    end
-    return nil
-end
-M.set = function(key,value)
-    localstorage.new(localstorage_cache):write(key,value)
-end
-M.set_json = function(key,value)
-    M.set(key,cjson.encode(value))
-end
-M.del = function(key)
-    localstorage.new(localstorage_cache):del(key)
-end
+-- M.close = function()
+--     localstorage.new(localstorage_cache):close()
+-- end
+-- M.get = function(key)
+--     return localstorage.new(localstorage_cache):read(key)
+-- end
+-- M.get_json = function(key)
+--     local value = M.get(key)
+--     if value then
+--         return cjson.decode(value)
+--     end
+--     return nil
+-- end
+-- M.set = function(key,value)
+--     localstorage.new(localstorage_cache):write(key,value)
+-- end
+-- M.set_json = function(key,value)
+--     M.set(key,cjson.encode(value))
+-- end
+-- M.del = function(key)
+--     localstorage.new(localstorage_cache):del(key)
+-- end
 return M
 
 

+ 18 - 14
target/fwutils/develop/controll/menu.lua

@@ -1,13 +1,14 @@
 local fwutils_config = require("fwutils.config")
 local develop_menu = require("fwutils.develop.function.menu")
 
-local function get_by_id()
+local M = {}
+M.get_by_id = function()
 
     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()
+M.add = function()
     local data = pjson()
     local conn = mysql.new(_G[fwutils_config.db.mysql_pool_name]):get()
     if develop_menu.add(data,conn) then
@@ -16,7 +17,7 @@ local function add()
         error("")
     end
 end
-local function update()
+M.update = function()
     local data = pjson()
     local conn = mysql.new(_G[fwutils_config.db.mysql_pool_name]):get()
     if develop_menu.update(data,conn) then
@@ -25,7 +26,7 @@ local function update()
         error("")
     end
 end
-local function delete()
+M.delete = function()
     local data = pjson()
     local conn = mysql.new(_G[fwutils_config.db.mysql_pool_name]):get()
     if develop_menu.delete(data.id,conn) then
@@ -34,23 +35,26 @@ local function delete()
         error("")
     end
 end
-local function list()
+M.list = function()
     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()
+M.refresh = function()
     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,
-})
+M.exec = function()
+    exec({
+    get_by_id = M.get_by_id,
+    list = M.list,
+    add = M.add,
+    update = M.update,
+    delete = M.delete,
+    refresh = M.refresh,
+    })
+end
+return M

+ 13 - 6
target/fwutils/develop/controll/role.lua

@@ -2,12 +2,19 @@ require("app.app")
 
 local fwutils_config = require("fwutils.config")
 local develop_role = require("fwutils.develop.function.role")
-local function list()
+
+
+local M = {}
+M.list = function()
     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)
+    succ(develop_role.list(data.search,data.limit,conn))
+    
 end
-exec({
-    list = list,
-})
+M.exec = function()
+    exec({
+        list = M.list,
+    })
+end
+
+return M

+ 18 - 14
target/fwutils/develop/controll/role_permissions.lua

@@ -3,12 +3,13 @@ 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 M = {}
+M.get_by_id = function()
     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()
+M.add = function()
     local data = pjson()
     local conn = mysql.new(_G[fwutils_config.db.mysql_pool_name]):get()
     if develop_role_permissions.add(data,conn) then
@@ -17,7 +18,7 @@ local function add()
         error("")
     end
 end
-local function update()
+M.update = function()
     local data = pjson()
     local conn = mysql.new(_G[fwutils_config.db.mysql_pool_name]):get()
     if develop_role_permissions.update(data,conn) then
@@ -26,7 +27,7 @@ local function update()
         error("")
     end
 end
-local function delete()
+M.delete = function()
     local data = pjson()
     local conn = mysql.new(_G[fwutils_config.db.mysql_pool_name]):get()
     if develop_role_permissions.delete(data.id,conn) then
@@ -35,23 +36,26 @@ local function delete()
         error("")
     end
 end
-local function list()
+M.list = function()
     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()
+M.refresh = function()
     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,
-})
+M.exec = function()
+    exec({
+        get_by_id = M.get_by_id,
+        list = M.list,
+        add = M.add,
+        update = M.update,
+        delete = M.delete,
+        refresh = M.refresh,
+    })
+end
+return M

+ 18 - 14
target/fwutils/develop/controll/template.lua

@@ -3,12 +3,13 @@ require("app.app")
 local fwutils_config = require("fwutils.config")
 local develop_template = require("fwutils.develop.function.template")
 
-local function get_by_id()
+local M = {}
+M.get_by_id = function()
     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()
+M.add = function()
     local data = pjson()
     local conn = mysql.new(_G[fwutils_config.db.mysql_pool_name]):get()
     if develop_template.add(data,conn) then
@@ -17,7 +18,7 @@ local function add()
         error("")
     end
 end
-local function update()
+M.update = function()
     local data = pjson()
     local conn = mysql.new(_G[fwutils_config.db.mysql_pool_name]):get()
     if develop_template.update(data,conn) then
@@ -26,7 +27,7 @@ local function update()
         error("")
     end
 end
-local function delete()
+M.delete = function()
     local data = pjson()
     local conn = mysql.new(_G[fwutils_config.db.mysql_pool_name]):get()
     if develop_template.delete(data.id,conn) then
@@ -35,23 +36,26 @@ local function delete()
         error("")
     end
 end
-local function list()
+M.list = function()
     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()
+M.refresh = function()
     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,
-})
+M.exec = function()
+    exec({
+        get_by_id = M.get_by_id,
+        list = M.list,
+        add = M.add,
+        update = M.update,
+        delete = M.delete,
+        refresh = M.refresh,
+    })
+end
+return M

+ 264 - 1
target/fwutils/develop/function/template.lua

@@ -8,7 +8,16 @@ require("fwutils.webapi")
 --   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 = {}
+local M = {
+    cfg = nil,
+    template_engine_bc_this_role = nil
+}
+-- 允许的扩展名
+local allowed_extensions = {
+    "shtml",
+    "html",
+    "js"
+}
 
 function M.get_by_id(id,conn)
     local select = conn:select()
@@ -98,5 +107,259 @@ function M.list(search,limit,conn)
         sel_data:orderby("fw_template.enable DESC")
     end)
 end
+-- 更新
+M.make_bytecode = function(conn)
+    -- 查询权限表
+    local select = conn:select()
+    select:table("fw_template")
+    select:where_i32("enable","=",1)
+    local result = select:query()
+    local bc = {
+        public = {}
+    }
+    while result:next() do
+        local id = result:get("id")
+        local role_id = string.format("%d",result:get("role_id"))
+        local key = result:get("key")
+        local value = result:get("value")
+
+
+        if bc[role_id] == nil then
+            bc[role_id] = {}
+        end
+        if role_id == "0" then
+            bc["public"][key] = value
+        else
+            bc[role_id][key] = value
+        end
+    end
+    local code = "return " .. require("serpent").serialize(bc, {comment = false})
+    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,functions)
+
+    local function has_ext(ext)
+        for _, v in ipairs(allowed_extensions) do
+            if v == ext then
+                return true
+            end
+        end
+        return false
+    end
+
+
+    M.cfg = __cfg
+    M.template_engine_bc_this_role = {
+        template = {
+            private = {},
+            public = {}
+        },
+    }
+
+
+    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()..M.cfg.filepath())
+        if static_content == nil or static_content == "" then
+            return false
+        end
+    else
+        -- 无需替换的扩展名
+        return false
+    end 
+    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)
+    if replaced then
+        static_content = content
+    end
+    -- 执行函数
+    static_content, n = static_content:gsub("%${<<<%s*(.-)%s*>>>}", function(code)
+        -- 尝试编译代码(Lua 5.2+ 使用 load;Lua 5.1 可用 loadstring)
+        local env = {}
+        _G["engine"] = M
+        local env = require("fwutils.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
+        -- 使用 pcall 安全执行代码块
+        local status, result = pcall(chunk)
+        if not status then 
+            fw.throw_string(result)
+        end
+        -- 如果代码没有返回值,则替换为空字符串,否则转换成字符串返回
+        return tostring(result)
+    end)
+
+    if n > 0 then
+        replaced = true
+    end
+ 
+    if replaced then
+        if  ext == "shtml" or ext == "html" then
+            response.header("Content-Type","text/html")
+        elseif ext == "js" then
+            response.header("Content-Type","application/javascript")
+        end
+        response.send(static_content)
+        return true
+    end
+    return false
+end
+M.replace = function (content)
+    if content == nil or content == "" then
+        return false 
+    end
+    -- 支持多级kvs替换,如 ${people.age}
+    local function flatten_kvs(tbl, prefix, out)
+        if tbl == nil then
+            return {}
+        end
+        out = out or {}
+        prefix = prefix or ""
+        for k, v in pairs(tbl) do
+            local key = prefix ~= "" and (prefix .. "." .. k) or k
+            if type(v) == "table" then
+                flatten_kvs(v, key, out)
+            else
+                out[key] = v
+            end
+        end
+        return out
+    end
+
+    -- 先提取 content 中所有需要替换的占位符
+    -- 需要正确处理 ${<<<...>>>} 块:块内部的 ${...} 需要替换,但块本身不替换
+    local placeholders = {}
+    
+    -- 第一步:提取所有 ${<<<...>>>} 块,临时替换它们,并收集所有占位符
+    local blocks = {}
+    local block_index = 0
+    local temp_content = content:gsub("%${<<<%s*(.-)%s*>>>}", function(block_content)
+        block_index = block_index + 1
+        local placeholder = "${__TEMP_BLOCK_" .. block_index .. "__}"
+        -- 收集块内部的 ${...} 占位符
+        for ph in string.gmatch(block_content, "%${([^}]+)}") do
+            placeholders[ph] = true
+        end
+        blocks[block_index] = {
+            placeholder = placeholder,
+            content = block_content
+        }
+        return placeholder
+    end)
+    
+    -- 第二步:提取外部(不在 ${<<<...>>>} 块中)的 ${...} 占位符
+    for placeholder in string.gmatch(temp_content, "%${([^}]+)}") do
+        -- 忽略临时占位符
+        if not placeholder:match("^__TEMP_BLOCK_%d+__$") then
+            placeholders[placeholder] = true
+        end
+    end
+
+    -- print("PLACEHOLDERS:",cjson.encode(placeholders))
+    
+    -- 如果没有任何占位符,直接返回
+    if next(placeholders) == nil then
+        return false
+    end
+
+    -- 合并所有数据源到一个查找表中(只 flatten 一次)
+    local value_map = {}
+    
+    -- 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(M.template_engine_bc_this_role["template"]["private"])
+    for k, v in pairs(flat_kvs) do
+        value_map[k] = v
+    end
+    -- REQUEST
+    flat_kvs = flatten_kvs(request.gets(), "request")
+    for k, v in pairs(flat_kvs) do
+        value_map[k] = v
+    end
+    -- TOKEN
+    flat_kvs = flatten_kvs(M.cfg.user_data(), "token")
+    for k, v in pairs(flat_kvs) do
+        value_map[k] = v
+    end
+
+    -- 转义函数:将 Lua 模式特殊字符转义为字面匹配
+    local function escape_pattern(str)
+        return str:gsub("([%^%$%(%)%%%.%[%]%*%+%-%?])", "%%%1")
+    end
+    
+    -- 第三步:先处理 ${<<<...>>>} 块内部的占位符
+    local replaced = false
+    for i, block in ipairs(blocks) do
+        local block_content = block.content
+        for placeholder, _ in pairs(placeholders) do
+            if value_map[placeholder] ~= nil then
+                local escaped_placeholder = escape_pattern(placeholder)
+                local new_content, count = string.gsub(block_content, "%${" .. escaped_placeholder .. "}", tostring(value_map[placeholder]))
+                if count > 0 then
+                    block_content = new_content
+                    replaced = true
+                end
+            end
+        end
+        blocks[i].processed_content = block_content
+    end
+    
+    -- 第四步:替换外部的 ${...} 占位符(在临时内容中,此时块已被替换为临时占位符)
+    local n = 0
+    for placeholder, _ in pairs(placeholders) do
+        if value_map[placeholder] ~= nil then
+            local escaped_placeholder = escape_pattern(placeholder)
+            temp_content, n = string.gsub(temp_content, "%${" .. escaped_placeholder .. "}", tostring(value_map[placeholder]))
+            if n > 0 then
+                replaced = true
+            end
+        end
+    end
+    
+    -- 第五步:恢复 ${<<<...>>>} 块(使用处理后的内容)
+    for i, block in ipairs(blocks) do
+        local processed_block = "${<<<" .. blocks[i].processed_content .. ">>>}"
+        temp_content = temp_content:gsub(block.placeholder:gsub("([%^%$%(%)%%%.%[%]%*%+%-%?])", "%%%1"), processed_block)
+    end
+    content = temp_content
+
+    if replaced then
+        return true, content
+    end
+    return false
+end
+
+-- 检查内容中是否有TOKEN变量
+-- @return boolean
+M.hasToken = function()
+    if M.static_content == nil or M.static_content == "" then
+        return false
+    end
+    return M.static_content:match("%${token%.") ~= nil
+end
 
 return M

+ 13 - 1
target/fwutils/init.lua

@@ -1,4 +1,3 @@
-local mysql_pool = require("mysql.pool")
 local fw = require("fastweb")
 local utils = require("utils")
 
@@ -13,6 +12,19 @@ M.initialization = function(conn)
         return false,err
     end
 
+    --生成字节码
+    local module_menu = require("fwutils.develop.function.menu")
+    local module_acl = require("fwutils.develop.function.role_permissions")
+    local module_template = require("fwutils.develop.function.template")
+    if not module_menu.make_bytecode(nil,conn) then
+        return false,"menu bytecode generation failed"
+    end
+    if not module_acl.make_bytecode(nil,conn) then
+        return false,"acl bytecode generation failed"
+    end
+    if not module_template.make_bytecode(conn) then
+        return false,"template bytecode generation failed"
+    end
     return true
 end
 M.__get_guest_role_id = function(mysql_conn)

+ 0 - 274
target/fwutils/template_engine.lua

@@ -1,274 +0,0 @@
-local utils = require("utils")
-local fw = require("fastweb")
-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 M = {
-    cfg = nil,
-    template_engine_bc_this_role = nil
-}
-
--- 更新
-M.update = function(conn)
-    -- 查询权限表
-    local select = conn:select()
-    select:table("fw_template")
-    select:where_i32("enable","=",1)
-    local result = select:query()
-    local bc = {
-        public = {}
-    }
-    while result:next() do
-        local id = result:get("id")
-        local role_id = string.format("%d",result:get("role_id"))
-        local key = result:get("key")
-        local value = result:get("value")
-
-
-        if bc[role_id] == nil then
-            bc[role_id] = {}
-        end
-        if role_id == "0" then
-            bc["public"][key] = value
-        else
-            bc[role_id][key] = value
-        end
-    end
-    local code = "return " .. require("serpent").serialize(bc, {comment = false})
-    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,functions)
-
-    local function has_ext(ext)
-        for _, v in ipairs(allowed_extensions) do
-            if v == ext then
-                return true
-            end
-        end
-        return false
-    end
-
-
-    M.cfg = __cfg
-    M.template_engine_bc_this_role = {
-        template = {
-            private = {},
-            public = {}
-        },
-    }
-
-
-    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()..M.cfg.filepath())
-        if static_content == nil or static_content == "" then
-            return false
-        end
-    else
-        -- 无需替换的扩展名
-        return false
-    end 
-    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)
-    if replaced then
-        static_content = content
-    end
-    -- 执行函数
-    static_content, n = static_content:gsub("%${<<<%s*(.-)%s*>>>}", function(code)
-        -- 尝试编译代码(Lua 5.2+ 使用 load;Lua 5.1 可用 loadstring)
-        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
-        -- 使用 pcall 安全执行代码块
-        local status, result = pcall(chunk)
-        if not status then 
-            fw.throw_string(result)
-        end
-        -- 如果代码没有返回值,则替换为空字符串,否则转换成字符串返回
-        return tostring(result)
-    end)
-
-    if n > 0 then
-        replaced = true
-    end
- 
-    if replaced then
-        if  ext == "shtml" or ext == "html" then
-            response.header("Content-Type","text/html")
-        elseif ext == "js" then
-            response.header("Content-Type","application/javascript")
-        end
-        response.send(static_content)
-        return true
-    end
-    return false
-end
-M.replace = function (content)
-    if content == nil or content == "" then
-        return false 
-    end
-    -- 支持多级kvs替换,如 ${people.age}
-    local function flatten_kvs(tbl, prefix, out)
-        if tbl == nil then
-            return {}
-        end
-        out = out or {}
-        prefix = prefix or ""
-        for k, v in pairs(tbl) do
-            local key = prefix ~= "" and (prefix .. "." .. k) or k
-            if type(v) == "table" then
-                flatten_kvs(v, key, out)
-            else
-                out[key] = v
-            end
-        end
-        return out
-    end
-
-    -- 先提取 content 中所有需要替换的占位符
-    -- 需要正确处理 ${<<<...>>>} 块:块内部的 ${...} 需要替换,但块本身不替换
-    local placeholders = {}
-    
-    -- 第一步:提取所有 ${<<<...>>>} 块,临时替换它们,并收集所有占位符
-    local blocks = {}
-    local block_index = 0
-    local temp_content = content:gsub("%${<<<%s*(.-)%s*>>>}", function(block_content)
-        block_index = block_index + 1
-        local placeholder = "${__TEMP_BLOCK_" .. block_index .. "__}"
-        -- 收集块内部的 ${...} 占位符
-        for ph in string.gmatch(block_content, "%${([^}]+)}") do
-            placeholders[ph] = true
-        end
-        blocks[block_index] = {
-            placeholder = placeholder,
-            content = block_content
-        }
-        return placeholder
-    end)
-    
-    -- 第二步:提取外部(不在 ${<<<...>>>} 块中)的 ${...} 占位符
-    for placeholder in string.gmatch(temp_content, "%${([^}]+)}") do
-        -- 忽略临时占位符
-        if not placeholder:match("^__TEMP_BLOCK_%d+__$") then
-            placeholders[placeholder] = true
-        end
-    end
-
-    -- print("PLACEHOLDERS:",cjson.encode(placeholders))
-    
-    -- 如果没有任何占位符,直接返回
-    if next(placeholders) == nil then
-        return false
-    end
-
-    -- 合并所有数据源到一个查找表中(只 flatten 一次)
-    local value_map = {}
-    
-    -- 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(M.template_engine_bc_this_role["template"]["private"])
-    for k, v in pairs(flat_kvs) do
-        value_map[k] = v
-    end
-    -- REQUEST
-    flat_kvs = flatten_kvs(request.gets(), "request")
-    for k, v in pairs(flat_kvs) do
-        value_map[k] = v
-    end
-    -- TOKEN
-    flat_kvs = flatten_kvs(M.cfg.user_data(), "token")
-    for k, v in pairs(flat_kvs) do
-        value_map[k] = v
-    end
-
-    -- 转义函数:将 Lua 模式特殊字符转义为字面匹配
-    local function escape_pattern(str)
-        return str:gsub("([%^%$%(%)%%%.%[%]%*%+%-%?])", "%%%1")
-    end
-    
-    -- 第三步:先处理 ${<<<...>>>} 块内部的占位符
-    local replaced = false
-    for i, block in ipairs(blocks) do
-        local block_content = block.content
-        for placeholder, _ in pairs(placeholders) do
-            if value_map[placeholder] ~= nil then
-                local escaped_placeholder = escape_pattern(placeholder)
-                local new_content, count = string.gsub(block_content, "%${" .. escaped_placeholder .. "}", tostring(value_map[placeholder]))
-                if count > 0 then
-                    block_content = new_content
-                    replaced = true
-                end
-            end
-        end
-        blocks[i].processed_content = block_content
-    end
-    
-    -- 第四步:替换外部的 ${...} 占位符(在临时内容中,此时块已被替换为临时占位符)
-    local n = 0
-    for placeholder, _ in pairs(placeholders) do
-        if value_map[placeholder] ~= nil then
-            local escaped_placeholder = escape_pattern(placeholder)
-            temp_content, n = string.gsub(temp_content, "%${" .. escaped_placeholder .. "}", tostring(value_map[placeholder]))
-            if n > 0 then
-                replaced = true
-            end
-        end
-    end
-    
-    -- 第五步:恢复 ${<<<...>>>} 块(使用处理后的内容)
-    for i, block in ipairs(blocks) do
-        local processed_block = "${<<<" .. blocks[i].processed_content .. ">>>}"
-        temp_content = temp_content:gsub(block.placeholder:gsub("([%^%$%(%)%%%.%[%]%*%+%-%?])", "%%%1"), processed_block)
-    end
-    content = temp_content
-
-    if replaced then
-        return true, content
-    end
-    return false
-end
-
--- 检查内容中是否有TOKEN变量
--- @return boolean
-M.hasToken = function()
-    if M.static_content == nil or M.static_content == "" then
-        return false
-    end
-    return M.static_content:match("%${token%.") ~= nil
-end
-
-return M