Module:Heartrate:修订间差异
来自OTTOWiki
更多操作
小 |
|||
第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 | ||
if not | local isValid, urlOrError = validateUrl(apiUrl) | ||
return " | 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秒超时 | |||
}) | |||
-- | -- 处理获取数据时的错误 | ||
local | if not data or errorInfo then | ||
local | 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) | end) | ||
-- | if not parseStatus then | ||
if | return "错误: JSON解析失败 - " .. tostring(parseError) | ||
return " | 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 | -- 返回有效的心率值 | ||
return " | 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) | |||
if type(heartRate) ~= "number" then | |||
return heartRate -- 返回错误消息 | |||
if | |||
return | |||
end | end | ||
local status, color | |||
if | 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 | else | ||
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