← 返回

应用详情

📦

天气

版本 v7981 · 2.3 KB
ID: weather_m3
⬇ 下载 CIP 🔍 返回列表
📝 应用描述
高级的天气apt
📋 详细信息
应用ID weather_m3
名称 天气
版本 v7981
文件大小 2.3 KB
上传时间 2026-07-31 11:32:37
状态 ✅ 已启用
权限 network, storage, network_external
允许主机 api.sloe.de5.net
💡 界面预览 (main.lua)
📄 Lua 源码
local primary = "#A961D3"
local onSurface = "#1C1B1E"
local outline = "#79747E"

local function urlencode(str)
  if not str then return "" end
  local result = ""
  for i = 1, #str do
    local c = str:sub(i, i)
    if c:match("[a-zA-Z0-9_.-]") then
      result = result .. c
    else
      result = result .. string.format("%%%02X", string.byte(c))
    end
  end
  return result
end

local function getWeather(city)
  if city == "" then
    app.toast("请输入城市名称")
    return
  end
  app.set_visible("loading_view", true)
  app.set_visible("weather_card", false)
  app.set_visible("forecast_section", false)
  app.set_visible("hourly_section", false)
  app.set_visible("error_view", false)
  local encoded = urlencode(city)
  local url = "http://api.sloe.de5.net/weather/?city=" .. encoded .. "&n=1&num=14"
  app.http_get(url, function(body, err)
    app.set_visible("loading_view", false)
    if err then
      app.set_visible("error_view", true)
      app.set_text("error_text", "网络请求失败: " .. err)
      return
    end
    if not body or body == "" then
      app.set_visible("error_view", true)
      app.set_text("error_text", "未获取到数据")
      return
    end
    local data = app.json_decode(body)
    if not data then
      app.set_visible("error_view", true)
      app.set_text("error_text", "数据解析失败")
      return
    end
    if data.code ~= 0 then
      app.set_visible("error_view", true)
      app.set_text("error_text", data.msg or "请求失败")
      return
    end
    local info = data.data
    local result = info.result
    local cond = result.condition
    local aqi = result.aqi
    local days = result.forecastDayList
    local hours = result.forecastHourList
    local altert = result.altertMsg
    app.set_text("weather_city", info.city)
    app.set_text("weather_temp", cond.ftemp .. "°")
    app.set_text("weather_condition", cond.fcondition)
    app.set_text("weather_humidity", cond.fhumidity .. "%")
    app.set_text("weather_wind", cond.fwind_dir .. " " .. cond.fwind_level .. "级")
    app.set_text("weather_aqi", aqi.value .. " " .. aqi.level)
    app.set_text("weather_sun", cond.fsun_rise .. " / " .. cond.fsun_down)
    app.set_text("weather_feel", cond.freal_feel .. "° / UV " .. cond.fuvi)
    if altert then
      app.set_text("weather_altert", altert.date .. " " .. altert.weekInfo .. " " .. altert.time)
    end
    app.set_visible("weather_card", true)
    if days and #days > 0 then
      app.set_visible("forecast_section", true)
      for i = 1, 7 do
        local id = "forecast_" .. i
        if i <= #days then
          local day = days[i]
          local dateStr = day.fpredict_date:sub(6)
          app.set_text(id, dateStr .. " " .. day.fcondition_day .. " " .. day.ftemp_low .. "~" .. day.ftemp_high .. "°")
          app.set_visible(id, true)
        else
          app.set_visible(id, false)
        end
      end
    end
    if hours and #hours > 0 then
      app.set_visible("hourly_section", true)
      for i = 1, 12 do
        local id = "hourly_" .. i
        if i <= #hours then
          local hour = hours[i]
          app.set_text(id, hour.hour .. ":00 " .. hour.tmp .. "° " .. hour.dayDesc)
          app.set_visible(id, true)
        else
          app.set_visible(id, false)
        end
      end
    end
    app.storage_set("last_city", city)
  end)
end

local function loadLastCity()
  local last = app.storage_get("last_city")
  if last and last ~= "" then
    app.set_text("city_input", last)
    app.delay(300, function()
      getWeather(last)
    end)
  end
end

local children = {}

table.insert(children, ui.text({
  text = "天气",
  size = 28,
  color = primary,
  center = true,
  margin = 16
}))

local searchRow = ui.list({
  children = {
    ui.input({
      id = "city_input",
      hint = "输入城市名称",
      text = "",
      single_line = true,
      input_type = "text",
      max_length = 50,
      margin = 8,
      on_submit = function(value)
        if value and value ~= "" then
          getWeather(value)
        end
      end
    }),
    ui.button({
      text = "查询",
      margin = 8,
      on_click = function()
        local city = app.get_text("city_input")
        if city and city ~= "" then
          getWeather(city)
        else
          app.toast("请输入城市名称")
        end
      end
    })
  }
})
table.insert(children, searchRow)

table.insert(children, ui.text({
  id = "loading_view",
  text = "查询中...",
  center = true,
  margin = 20,
  color = primary,
  visible = false
}))

table.insert(children, ui.text({
  id = "error_view",
  text = "",
  center = true,
  margin = 20,
  color = "#D32F2F",
  visible = false
}))

local weatherCard = ui.list({
  id = "weather_card",
  visible = false,
  children = {
    ui.text({
      id = "weather_city",
      text = "--",
      size = 24,
      color = onSurface,
      center = true,
      margin = 4
    }),
    ui.text({
      id = "weather_altert",
      text = "",
      size = 12,
      color = outline,
      center = true,
      margin = 2
    }),
    ui.text({
      id = "weather_temp",
      text = "--°",
      size = 56,
      color = primary,
      center = true,
      margin = 2
    }),
    ui.text({
      id = "weather_condition",
      text = "--",
      size = 18,
      color = onSurface,
      center = true,
      margin = 4
    }),
    ui.list({
      children = {
        ui.text({
          id = "weather_humidity",
          text = "--",
          size = 14,
          color = outline,
          center = true,
          margin = 2
        }),
        ui.text({
          id = "weather_wind",
          text = "--",
          size = 14,
          color = outline,
          center = true,
          margin = 2
        }),
        ui.text({
          id = "weather_aqi",
          text = "--",
          size = 14,
          color = outline,
          center = true,
          margin = 2
        })
      }
    }),
    ui.list({
      children = {
        ui.text({
          id = "weather_feel",
          text = "--",
          size = 14,
          color = outline,
          center = true,
          margin = 2
        }),
        ui.text({
          id = "weather_sun",
          text = "--",
          size = 14,
          color = outline,
          center = true,
          margin = 2
        })
      }
    })
  }
})
table.insert(children, weatherCard)

table.insert(children, ui.text({
  id = "forecast_title",
  text = "7天预报",
  size = 18,
  color = onSurface,
  center = true,
  margin = 8,
  visible = false
}))

local forecastRow1 = ui.list({
  children = {}
})
local forecastRow2 = ui.list({
  children = {}
})
for i = 1, 7 do
  local id = "forecast_" .. i
  local item = ui.text({
    id = id,
    text = "",
    size = 13,
    color = onSurface,
    center = true,
    margin = 2,
    visible = false
  })
  if i <= 4 then
    table.insert(forecastRow1.children, item)
  else
    table.insert(forecastRow2.children, item)
  end
end
table.insert(children, forecastRow1)
table.insert(children, forecastRow2)

table.insert(children, ui.text({
  id = "hourly_title",
  text = "12小时预报",
  size = 18,
  color = onSurface,
  center = true,
  margin = 8,
  visible = false
}))

local hourlyRow1 = ui.list({
  children = {}
})
local hourlyRow2 = ui.list({
  children = {}
})
local hourlyRow3 = ui.list({
  children = {}
})
for i = 1, 12 do
  local id = "hourly_" .. i
  local item = ui.text({
    id = id,
    text = "",
    size = 12,
    color = outline,
    center = true,
    margin = 2,
    visible = false
  })
  if i <= 4 then
    table.insert(hourlyRow1.children, item)
  elseif i <= 8 then
    table.insert(hourlyRow2.children, item)
  else
    table.insert(hourlyRow3.children, item)
  end
end
table.insert(children, hourlyRow1)
table.insert(children, hourlyRow2)
table.insert(children, hourlyRow3)

table.insert(children, ui.button({
  text = "刷新",
  margin = 12,
  on_click = function()
    local city = app.get_text("city_input")
    if city and city ~= "" then
      getWeather(city)
    else
      app.toast("请先输入城市名称")
    end
  end
}))

loadLastCity()

return ui.page({
  title = "天气",
  children = children
})
⬇ 下载 CIP 文件 🔍 返回列表