打开/关闭菜单
打开/关闭外观设置菜单
打开/关闭个人菜单
未登录
未登录用户的IP地址会在进行任意编辑后公开展示。

Module:Heartrate:修订间差异

来自OTTOWiki
琪露若
琪露若留言 | 贡献 (woshishabi)
第1行: 第1行:
local p = {}
local p = {}
local util = require("libraryUtil")
local checkType = util.checkType


-- 验证URL格式的辅助函数
local function validateUrl(url)
    if type(url) ~= "string" or url == "" then
        return false, "URL不能为空"
    end
   
    -- 检查URL是否包含协议
    if not url:find("^https?://") then
        url = "https://" .. url
    end
   
    -- 基本URL格式验证
    if not url:match("^https?://[%w%.%-]+/") then
        return false, "URL格式无效: " .. url
    end
   
    return true, url
end
-- 主函数:获取心率数据
function p.getHeartRate(frame)
function p.getHeartRate(frame)
    -- 获取传入参数
     local args = frame.args
     local args = frame.args
     local apiUrl = args.url
     local apiUrl = args.url
      
      
     -- 验证URL参数
     -- 验证并规范化URL
     if not apiUrl or apiUrl == "" then
    local isValid, urlOrError = validateUrl(apiUrl)
         return "错误:缺少API URL参数"
     if not isValid then
         return "错误: " .. urlOrError
     end
     end
    apiUrl = urlOrError
   
    -- 使用ExternalData获取数据
    local data, errorInfo = mw.ext.ExternalData.get(apiUrl, {
        format = "json",
        nocache = args.nocache or false,  -- 可选的缓存控制
        timeout = 5  -- 5秒超时
    })
      
      
     -- 发起HTTP GET请求
     -- 处理获取数据时的错误
     local response
     if not data or errorInfo then
     local status, err = pcall(function()
        local errorMsg = "无法获取数据: "
         response = mw.ext.externaldata.getWebData {url = args.url}
       
        -- 解析ExternalData的错误信息
        if type(errorInfo) == "table" then
            if errorInfo.error then
                errorMsg = errorMsg .. errorInfo.error
            elseif errorInfo[1] then
                errorMsg = errorMsg .. table.concat(errorInfo, ", ")
            end
        else
            errorMsg = errorMsg .. (tostring(errorInfo) or "未知错误")
        end
       
        return "错误: " .. errorMsg
    end
   
    -- 安全解析JSON数据
     local jsonData
    local parseStatus, parseError = pcall(function()
         jsonData = mw.text.jsonDecode(data)
     end)
     end)
      
      
     -- 检查请求是否成功
    if not parseStatus then
     if not status or not response then
        return "错误: JSON解析失败 - " .. tostring(parseError)
         return "错误:API请求失败 - " .. (err or "未知错误")
    end
   
     -- 验证数据结构
     if type(jsonData) ~= "table" then
        return "错误: 返回的数据不是JSON对象"
    end
   
    -- 提取心率值(使用多级验证)
    if jsonData.message ~= "ok" then
         return "错误: API返回状态异常 - " .. (jsonData.message or "未知")
    end
   
    if type(jsonData.data) ~= "table" then
        return "错误: 缺少数据字段"
    end
   
    local heartRate = jsonData.data.heart_rate
    if type(heartRate) ~= "number" then
        return "错误: 心率值无效或缺失"
     end
     end
      
      
     if response.status ~= 200 then
    -- 返回有效的心率值
         return "错误:API返回HTTP状态码 " .. response.status
    return heartRate
end
 
-- 带格式化输出的版本
function p.formattedHeartRate(frame)
    local heartRate = p.getHeartRate(frame)
   
    -- 如果是数字则格式化,否则返回错误信息
     if type(heartRate) == "number" then
         return string.format("**心率: %d bpm**", heartRate)
    else
        return heartRate  -- 返回错误消息
     end
     end
end
-- 带状态指示的版本
function p.heartRateWithStatus(frame)
    local heartRate = p.getHeartRate(frame)
      
      
    -- 解析JSON数据
     if type(heartRate) ~= "number" then
    local jsonData
         return heartRate  -- 返回错误消息
    status, jsonData = pcall(mw.text.jsonDecode, response.body)
     if not status or type(jsonData) ~= "table" then
         return "错误:JSON解析失败"
     end
     end
      
      
     -- 验证数据结构并提取心率值
     local status, color
     if jsonData.message == "ok"  
     if heartRate < 60 then
        and type(jsonData.data) == "table"  
        status = "偏低"
         and type(jsonData.data.heart_rate) == "number" then
        color = "#3498db" -- 蓝色
          
    elseif heartRate >= 60 and heartRate <= 100 then
         return jsonData.data.heart_rate
        status = "正常"
         color = "#2ecc71" -- 绿色
    elseif heartRate > 100 and heartRate <= 120 then
         status = "偏高"
         color = "#f39c12"  -- 橙色
     else
     else
         return "错误:无效的数据结构"
         status = "过高!"
        color = "#e74c3c"  -- 红色
     end
     end
   
    return string.format(
        '<span style="font-weight:bold; color:%s">%d bpm (%s)</span>',
        color, heartRate, status
    )
end
end


return p
return p

2025年6月20日 (五) 11:30的版本

local p = {}
local util = require("libraryUtil")
local checkType = util.checkType

-- 验证URL格式的辅助函数
local function validateUrl(url)
    if type(url) ~= "string" or url == "" then
        return false, "URL不能为空"
    end
    
    -- 检查URL是否包含协议
    if not url:find("^https?://") then
        url = "https://" .. url
    end
    
    -- 基本URL格式验证
    if not url:match("^https?://[%w%.%-]+/") then
        return false, "URL格式无效: " .. url
    end
    
    return true, url
end

-- 主函数:获取心率数据
function p.getHeartRate(frame)
    local args = frame.args
    local apiUrl = args.url
    
    -- 验证并规范化URL
    local isValid, urlOrError = validateUrl(apiUrl)
    if not isValid then
        return "错误: " .. urlOrError
    end
    apiUrl = urlOrError
    
    -- 使用ExternalData获取数据
    local data, errorInfo = mw.ext.ExternalData.get(apiUrl, {
        format = "json",
        nocache = args.nocache or false,  -- 可选的缓存控制
        timeout = 5  -- 5秒超时
    })
    
    -- 处理获取数据时的错误
    if not data or errorInfo then
        local errorMsg = "无法获取数据: "
        
        -- 解析ExternalData的错误信息
        if type(errorInfo) == "table" then
            if errorInfo.error then
                errorMsg = errorMsg .. errorInfo.error
            elseif errorInfo[1] then
                errorMsg = errorMsg .. table.concat(errorInfo, ", ")
            end
        else
            errorMsg = errorMsg .. (tostring(errorInfo) or "未知错误")
        end
        
        return "错误: " .. errorMsg
    end
    
    -- 安全解析JSON数据
    local jsonData
    local parseStatus, parseError = pcall(function()
        jsonData = mw.text.jsonDecode(data)
    end)
    
    if not parseStatus then
        return "错误: JSON解析失败 - " .. tostring(parseError)
    end
    
    -- 验证数据结构
    if type(jsonData) ~= "table" then
        return "错误: 返回的数据不是JSON对象"
    end
    
    -- 提取心率值(使用多级验证)
    if jsonData.message ~= "ok" then
        return "错误: API返回状态异常 - " .. (jsonData.message or "未知")
    end
    
    if type(jsonData.data) ~= "table" then
        return "错误: 缺少数据字段"
    end
    
    local heartRate = jsonData.data.heart_rate
    if type(heartRate) ~= "number" then
        return "错误: 心率值无效或缺失"
    end
    
    -- 返回有效的心率值
    return heartRate
end

-- 带格式化输出的版本
function p.formattedHeartRate(frame)
    local heartRate = p.getHeartRate(frame)
    
    -- 如果是数字则格式化,否则返回错误信息
    if type(heartRate) == "number" then
        return string.format("**心率: %d bpm**", heartRate)
    else
        return heartRate  -- 返回错误消息
    end
end

-- 带状态指示的版本
function p.heartRateWithStatus(frame)
    local heartRate = p.getHeartRate(frame)
    
    if type(heartRate) ~= "number" then
        return heartRate  -- 返回错误消息
    end
    
    local status, color
    if heartRate < 60 then
        status = "偏低"
        color = "#3498db"  -- 蓝色
    elseif heartRate >= 60 and heartRate <= 100 then
        status = "正常"
        color = "#2ecc71"  -- 绿色
    elseif heartRate > 100 and heartRate <= 120 then
        status = "偏高"
        color = "#f39c12"  -- 橙色
    else
        status = "过高!"
        color = "#e74c3c"  -- 红色
    end
    
    return string.format(
        '<span style="font-weight:bold; color:%s">%d bpm (%s)</span>',
        color, heartRate, status
    )
end

return p