jindou 1 hónapja
commit
769d6bfd71
100 módosított fájl, 13388 hozzáadás és 0 törlés
  1. BIN
      doc/YF20260002-【调试宝TSB_V3.0_设计方案】.docx
  2. BIN
      doc/调试宝TSB_V3.0_设计方案 - UI.vsdx
  3. 106 0
      script/bq25895_test.lua
  4. 89 0
      script/hw_drv/lcd_drv.lua
  5. BIN
      script/images/1.png
  6. BIN
      script/images/232.png
  7. BIN
      script/images/4851.png
  8. BIN
      script/images/4g00.png
  9. BIN
      script/images/4g1.png
  10. BIN
      script/images/4g2.png
  11. BIN
      script/images/4g3.png
  12. BIN
      script/images/4g4.png
  13. BIN
      script/images/LoRa.png
  14. BIN
      script/images/MQTT.png
  15. BIN
      script/images/back1.png
  16. BIN
      script/images/bjrz.png
  17. BIN
      script/images/bjrz1.png
  18. BIN
      script/images/bjxx2.png
  19. BIN
      script/images/bmq.png
  20. BIN
      script/images/bsk2.png
  21. BIN
      script/images/dian1.png
  22. BIN
      script/images/dian2.png
  23. BIN
      script/images/dian3.png
  24. BIN
      script/images/dian4.png
  25. BIN
      script/images/gjb.png
  26. BIN
      script/images/hardware.png
  27. BIN
      script/images/help.png
  28. BIN
      script/images/home2.png
  29. BIN
      script/images/light.png
  30. BIN
      script/images/person3.png
  31. BIN
      script/images/rzjc.png
  32. BIN
      script/images/sbq.png
  33. BIN
      script/images/shutdown.png
  34. BIN
      script/images/sj.png
  35. BIN
      script/images/test1.png
  36. BIN
      script/images/test2.png
  37. BIN
      script/images/tq.png
  38. BIN
      script/images/up.png
  39. BIN
      script/images/up1.png
  40. BIN
      script/images/upgrade.png
  41. BIN
      script/images/wbjw.png
  42. BIN
      script/images/wifi.png
  43. BIN
      script/images/wifi0.png
  44. BIN
      script/images/wifi1.png
  45. BIN
      script/images/wifi2.png
  46. BIN
      script/images/wifi3.png
  47. BIN
      script/images/wifi4.png
  48. BIN
      script/images/wlan3.png
  49. BIN
      script/images/xd4.png
  50. BIN
      script/images/ywy.png
  51. 81 0
      script/main.lua
  52. 73 0
      script/multiple_uart.lua
  53. 246 0
      script/power_init.lua
  54. 242 0
      script/pwm_test.lua
  55. 40 0
      script/pwrkey.lua
  56. 163 0
      script/readme.md
  57. 72 0
      script/tp_key_drv/tp_drv.lua
  58. 178 0
      script/tsb_ui/tsb_232log_page.lua
  59. 178 0
      script/tsb_ui/tsb_485log_page.lua
  60. 324 0
      script/tsb_ui/tsb_bmq_page.lua
  61. 561 0
      script/tsb_ui/tsb_bsk_page.lua
  62. 281 0
      script/tsb_ui/tsb_channel_page.lua
  63. 344 0
      script/tsb_ui/tsb_common_page.lua
  64. 214 0
      script/tsb_ui/tsb_devinfo_page.lua
  65. 143 0
      script/tsb_ui/tsb_devlog_page.lua
  66. 335 0
      script/tsb_ui/tsb_firm_page.lua
  67. 511 0
      script/tsb_ui/tsb_game_page.lua
  68. 93 0
      script/tsb_ui/tsb_help_page.lua
  69. 306 0
      script/tsb_ui/tsb_home_page.lua
  70. 148 0
      script/tsb_ui/tsb_light_page.lua
  71. 143 0
      script/tsb_ui/tsb_log_page.lua
  72. 241 0
      script/tsb_ui/tsb_login_page.lua
  73. 289 0
      script/tsb_ui/tsb_lora_page.lua
  74. 440 0
      script/tsb_ui/tsb_mqtt_page.lua
  75. 235 0
      script/tsb_ui/tsb_reflash_page.lua
  76. 269 0
      script/tsb_ui/tsb_tq_page.lua
  77. 179 0
      script/tsb_ui/tsb_ui_main.lua
  78. 94 0
      script/tsb_ui/tsb_update_page.lua
  79. 429 0
      script/tsb_ui/tsb_upgrade_page.lua
  80. 143 0
      script/tsb_ui/tsb_waveform_page.lua
  81. 526 0
      script/tsb_ui/tsb_wavein_page.lua
  82. 270 0
      script/tsb_ui/tsb_waveout_page.lua
  83. 370 0
      script/tsb_ui/tsb_wlan_page.lua
  84. 340 0
      script/tsb_ui/tsb_ywy_1_page.lua
  85. 163 0
      script/tsb_ui/tsb_ywy_2_page.lua
  86. 146 0
      script/tsb_ui/tsb_ywy_page.lua
  87. 213 0
      script/uart485_test.lua
  88. 53 0
      script/uart_test.lua
  89. 516 0
      script/ui/all_component_page.lua
  90. 319 0
      script/ui/bar_page.lua
  91. 273 0
      script/ui/button_page.lua
  92. 333 0
      script/ui/chart_page.lua
  93. 332 0
      script/ui/container_page.lua
  94. 267 0
      script/ui/dropdown_page.lua
  95. 519 0
      script/ui/game_page.lua
  96. 158 0
      script/ui/home_page.lua
  97. 298 0
      script/ui/hzfont_page.lua
  98. 460 0
      script/ui/image_page.lua
  99. 392 0
      script/ui/input_page.lua
  100. 250 0
      script/ui/label_page.lua

BIN
doc/YF20260002-【调试宝TSB_V3.0_设计方案】.docx


BIN
doc/调试宝TSB_V3.0_设计方案 - UI.vsdx


+ 106 - 0
script/bq25895_test.lua

@@ -0,0 +1,106 @@
+--[[
+    通过UART接收上位机命令,进行I2C读写操作,并将结果通过UART返回
+    命令格式:
+    写操作:uart_down_wr|0xSLAVE_ADDR|0xREG_ADDR|0xVALUE\n
+    读操作:uart_down_rd|0xSLAVE_ADDR|0xREG_ADDR|0XNUM\n
+    响应格式:
+    写操作响应:uart_up_wr|0xRESULT\n (RESULT: 0x01成功, 0x00失败)
+    读操作响应:uart_up_rd|0xRESULT|0xVALUE\n (RESULT: 0x01成功, 0x00失败; VALUE: 读取的值)
+--]] 
+
+
+
+-- 定义I2C总线ID和I2C速度
+local i2c_id = 1
+i2c.setup(i2c_id, i2c.SLOW)
+
+
+local uart_id = 1 -- 根据实际设备选取不同的uart_id
+
+-- 初始化串口参数
+-- uart.setup(
+--     uart_id,--串口id
+--     115200,--波特率
+--     8,--数据位
+--     1--停止位
+-- )
+
+-- 收取数据会触发回调, 这里的"receive" 是固定值
+uart.on(uart_id, "receive", function(id, len)
+    -- 一次性读取所有串口缓存数据(避免循环冗余)
+    local data = uart.read(uart_id, len)
+    if not data or #data == 0 then
+        log.info("uart", "No data received")
+        return
+    end
+    log.info("uart", "Received raw data:", data)
+
+    -- 检查是否包含目标指令关键词
+    if string.find(data, "uart_down_wr") or string.find(data, "uart_down_rd") then
+        -- 按换行符分割数据,处理每一行指令
+        for line in string.gmatch(data, "([^\n]+)") do
+            log.info("uart", "Processing line:", line)
+            -- 分割指令各部分(去除首尾空格)
+            local parts = {}
+            for part in string.gmatch(line, "[^|]+") do
+                -- 去除每个部分的首尾空格
+                local trim_part = string.match(part, "^%s*(.-)%s*$")
+                table.insert(parts, trim_part)
+            end
+
+            -- 处理写操作:uart_down_wr|0x22|0x0a|0x01
+            if #parts >= 4 and parts[1] == "uart_down_wr" then
+                -- 十六进制解析
+                local slave_addr = tonumber(string.match(parts[2], "0x(%x+)"), 16) or 0
+                local reg_addr = tonumber(string.match(parts[3], "0x(%x+)"), 16) or 0
+                local value = tonumber(string.match(parts[4], "0x(%x+)"), 16) or 0
+
+                log.info("i2c write", "slave_addr=0x"..string.format("%02X", slave_addr), 
+                         "reg_addr=0x"..string.format("%02X", reg_addr), 
+                         "value=0x"..string.format("%02X", value))
+
+                -- 执行I2C写寄存器操作
+                local ret = i2c.writeReg(i2c_id, slave_addr, reg_addr, value)
+                local resp_code = ret and 0x01 or 0x00
+                -- 返回响应
+                uart.write(uart_id, string.format("uart_up_wr | 0x%02X\n", resp_code))
+
+            -- 处理读操作:uart_down_rd|0x22|0x0a|0XNUM(NUM为读取字节数,支持十进制/十六进制)
+            elseif #parts >= 4 and parts[1] == "uart_down_rd" then  -- 修改:至少4个部分(新增NUM参数)
+                -- 十六进制解析从机地址、寄存器地址
+                local slave_addr = tonumber(string.match(parts[2], "0x(%x+)"), 16) or 0
+                local reg_addr = tonumber(string.match(parts[3], "0x(%x+)"), 16) or 0
+                -- 解析读取字节数(兼容0x开头十六进制/纯十进制,比如0x01或1都表示1字节)
+                local read_len = nil
+                local num_str = parts[4]
+                -- 先尝试按十六进制解析(0x开头),否则按十进制解析
+                if string.find(num_str, "^0x") then
+                    read_len = tonumber(string.match(num_str, "0x(%x+)"), 16) or 1  -- 默认1字节
+                else
+                    read_len = tonumber(num_str) or 1  -- 默认1字节
+                end
+
+                log.info("i2c read", "slave_addr=0x"..string.format("%02X", slave_addr), 
+                         "reg_addr=0x"..string.format("%02X", reg_addr),
+                         "read_len="..read_len)
+
+                -- 执行I2C读寄存器操作(传入读取字节数参数)
+                local ret_val = i2c.readReg(i2c_id, slave_addr, reg_addr, read_len) or 0x00
+                -- 修复响应逻辑:ret_val可能是多字节,需统一转为十六进制字符串(兼容单/多字节)
+                local resp_code = (ret_val ~= nil and ret_val ~= 0x00) and 0x01 or 0x00
+                local ret_hex = ""
+                -- 处理多字节读取结果(按字节转为十六进制,用空格分隔)
+                if type(ret_val) == "string" then  -- 多数I2C库多字节返回字符串
+                    for i = 1, #ret_val do
+                        ret_hex = ret_hex .. string.format("0x%02X ", string.byte(ret_val, i))
+                    end
+                    ret_hex = string.sub(ret_hex, 1, -2)  -- 去掉最后一个空格
+                else  -- 单字节返回数值
+                    ret_hex = string.format("0x%02X", ret_val)
+                end
+                -- 返回响应(状态码+读取值)
+                uart.write(uart_id, string.format("uart_up_rd | 0x%02X | %s\n", resp_code, ret_hex))
+            end
+        end
+    end
+end)

+ 89 - 0
script/hw_drv/lcd_drv.lua

@@ -0,0 +1,89 @@
+--[[
+@module  lcd_drv
+@summary LCD显示驱动模块,基于lcd核心库
+@version 1.0
+@date    2026.02.05
+@author  江访
+@usage
+本模块为LCD显示驱动功能模块,主要功能包括:
+1、初始化 LCD屏幕;
+2、配置LCD显示参数和显示缓冲区;
+3、初始化AirUI;
+4、支持多种屏幕方向和分辨率设置;
+
+对外接口:
+1、lcd_drv.init():初始化LCD显示驱动
+]]
+
+
+local lcd_drv = {}
+
+--[[
+初始化LCD显示驱动;
+
+@api lcd_drv.init()
+@summary 配置并初始化LCD屏幕
+@return boolean 初始化成功返回true,失败返回false
+
+@usage
+-- 初始化LCD显示
+local result = lcd_drv.init()
+if result then
+    log.info("LCD初始化成功")
+else
+    log.error("LCD初始化失败")
+end
+]]
+
+function lcd_drv.init()
+    -- 开启屏幕供电
+    -- gpio.setup(141, 1)
+    local result = lcd.init("st7796",
+        {
+            pin_pwr = 2,       -- 背光控制引脚GPIO端口号
+            port = lcd.HWID_0, -- 驱动端口
+            pin_rst = 36,      -- lcd复位引脚
+            -- direction = 0,     -- lcd屏幕方向 0:0° 1:90° 2:180° 3:270°,屏幕方向和分辨率保存一致
+            -- w = 320,           -- lcd 水平分辨率
+            -- h = 480,           -- lcd 竖直分辨率
+            direction = 1,     -- lcd屏幕方向 0:0° 1:90° 2:180° 3:270°,屏幕方向和分辨率保存一致
+            w = 480,           -- lcd 水平分辨率
+            h = 320,           -- lcd 竖直分辨率
+            xoffset = 0,       -- x偏移(不同屏幕ic 不同屏幕方向会有差异)
+            yoffset = 0,       -- y偏移(不同屏幕ic 不同屏幕方向会有差异)
+        })
+
+    log.info("lcd.init", result)
+
+    if result then
+        -- 开启缓冲区, 刷屏速度会加快, 但也消耗2倍屏幕分辨率的内存
+        -- lcd.setupBuff(nil, true)
+        -- lcd.autoFlush(false)
+
+        -- 初始化AirUI
+        local width, height = lcd.getSize()
+        local result = airui.init(width, height)
+        if not result then
+            log.error("airui", "init failed")
+            return result
+        end
+
+        -- 加载字体
+        airui.font_load({
+            type = "hzfont",  -- 字体类型,hzfont
+            path = nil,       -- 字体路径,Air8000固件内置,无需填写
+            size = 14,        -- 默认字体大写
+            cache_size = 512, --
+            antialias = 4,    -- 字体抗锯齿等级,1-4级,级别越高抗锯齿效果越好,加载时间越长
+        })
+
+        -- 开启背光引脚供电
+        -- gpio.setup(1, 1)
+
+        return result
+    end
+
+    return result
+end
+
+return lcd_drv

BIN
script/images/1.png


BIN
script/images/232.png


BIN
script/images/4851.png


BIN
script/images/4g00.png


BIN
script/images/4g1.png


BIN
script/images/4g2.png


BIN
script/images/4g3.png


BIN
script/images/4g4.png


BIN
script/images/LoRa.png


BIN
script/images/MQTT.png


BIN
script/images/back1.png


BIN
script/images/bjrz.png


BIN
script/images/bjrz1.png


BIN
script/images/bjxx2.png


BIN
script/images/bmq.png


BIN
script/images/bsk2.png


BIN
script/images/dian1.png


BIN
script/images/dian2.png


BIN
script/images/dian3.png


BIN
script/images/dian4.png


BIN
script/images/gjb.png


BIN
script/images/hardware.png


BIN
script/images/help.png


BIN
script/images/home2.png


BIN
script/images/light.png


BIN
script/images/person3.png


BIN
script/images/rzjc.png


BIN
script/images/sbq.png


BIN
script/images/shutdown.png


BIN
script/images/sj.png


BIN
script/images/test1.png


BIN
script/images/test2.png


BIN
script/images/tq.png


BIN
script/images/up.png


BIN
script/images/up1.png


BIN
script/images/upgrade.png


BIN
script/images/wbjw.png


BIN
script/images/wifi.png


BIN
script/images/wifi0.png


BIN
script/images/wifi1.png


BIN
script/images/wifi2.png


BIN
script/images/wifi3.png


BIN
script/images/wifi4.png


BIN
script/images/wlan3.png


BIN
script/images/xd4.png


BIN
script/images/ywy.png


+ 81 - 0
script/main.lua

@@ -0,0 +1,81 @@
+--[[
+@module  main
+@summary exEasyUI组件演示主程序入口
+@version 1.0.0
+@date    2026.01.27
+@author  江访
+@usage
+本文件是exEasyUI演示程序的主入口,用于选择加载不同的UI组件演示模块。
+通过注释/取消注释require语句来运行不同的演示。
+]]
+
+--[[
+必须定义PROJECT和VERSION变量,Luatools工具会用到这两个变量,远程升级功能也会用到这两个变量
+PROJECT:项目名,ascii string类型
+        可以随便定义,只要不使用,就行
+VERSION:项目版本号,ascii string类型
+        如果使用合宙iot.openluat.com进行远程升级,必须按照"XXX.YYY.ZZZ"三段格式定义:
+            X、Y、Z各表示1位数字,三个X表示的数字可以相同,也可以不同,同理三个Y和三个Z表示的数字也是可以相同,可以不同
+            因为历史原因,YYY这三位数字必须存在,但是没有任何用处,可以一直写为000
+        如果不使用合宙iot.openluat.com进行远程升级,根据自己项目的需求,自定义格式即可
+]]
+
+-- main.lua - 程序入口文件
+
+-- 项目名称和版本定义
+PROJECT = "AirUI_demo" -- 项目名称,用于标识当前工程
+VERSION = "1.0.0"      -- 项目版本号
+
+-- 在日志中打印项目名和项目版本号
+log.info("ui_demo", PROJECT, VERSION)
+
+-- 设置日志输出风格为样式2(建议调试时开启)
+-- log.style(2)
+
+
+-- 如果内核固件支持errDump功能,此处进行配置,【强烈建议打开此处的注释】
+-- 因为此功能模块可以记录并且上传脚本在运行过程中出现的语法错误或者其他自定义的错误信息,可以初步分析一些设备运行异常的问题
+-- 以下代码是最基本的用法,更复杂的用法可以详细阅读API说明文档
+-- 启动errDump日志存储并且上传功能,600秒上传一次
+-- if errDump then
+--     errDump.config(true, 600)
+-- end
+
+
+-- 使用LuatOS开发的任何一个项目,都强烈建议使用远程升级FOTA功能
+-- 可以使用合宙的iot.openluat.com平台进行远程升级
+-- 也可以使用客户自己搭建的平台进行远程升级
+-- 远程升级的详细用法,可以参考fota的demo进行使用
+
+
+-- 启动一个循环定时器
+-- 每隔3秒钟打印一次总内存,实时的已使用内存,历史最高的已使用内存情况
+-- 方便分析内存使用是否有异常
+-- sys.timerLoopStart(function()
+--     log.info("mem.lua", rtos.meminfo())
+--     log.info("mem.sys", rtos.meminfo("sys"))
+-- end, 3000)
+
+-- gpio.setup(156,0)
+-- sys.timerLoopStart(function()
+--     gpio.toggle(156)
+-- end, 500)
+
+-- 加载显示驱动
+lcd_drv = require("lcd_drv")
+-- 加载触摸驱动
+tp_drv = require("tp_drv")
+
+require("pwrkey")
+
+-- require("multiple_uart")
+
+-- 引入演示模块(每次只选择一个运行)
+-- require("ui_main") --动态更新标签演示
+require("tsb_ui_main")
+
+
+-- 用户代码已结束
+-- 结尾总是这一句
+sys.run()
+-- sys.run()之后不要加任何语句!!!!!因为添加的任何语句都不会被执行

+ 73 - 0
script/multiple_uart.lua

@@ -0,0 +1,73 @@
+--[[
+@module  multiple_uart
+@summary 多串口功能模块
+@version 1.0
+@date    2025.09.23
+@author  魏健强
+@usage
+本demo演示的核心功能为:
+1.开启串口,配置波特率等参数;
+2.设置接收回调函数
+3.定时向串口发送数据
+]]
+-- 根据实际设备选取不同的uartid
+local uartid1 = 2  -- 第一个串口id
+local uartid2 = 11 -- 第二个串口id
+--local uartid2 = 3 --第三个串口id(Air780EGH用第三个串口,UART2已经用作通信主芯片和GNSS芯片之间的通信用)
+
+local function uart_send()
+    -- 循环两秒分别向两个串口发一次数据
+    while true do
+        sys.wait(5000)
+        uart.write(uartid1, "uart1 test data.")
+        uart.write(uartid2, "uart2 test data.")
+    end
+end
+
+local function uart_send_cb(id)
+    log.info("uart", id , "数据发送完成回调")
+end
+
+local function uart_cb(id, len)
+    local s = ""
+    repeat
+        s = uart.read(id, 128) -- 读取缓冲区中的数据,这里设置的一次读最多128字节
+        if #s > 0 then -- #s 是取字符串的长度
+            -- 关于收发hex值,请查阅 https://doc.openluat.com/article/583
+            log.info("uart", "receive", id, #s, s)
+            -- log.info("uart", "receive", id, #s, s:toHex()) --如果传输二进制/十六进制数据, 部分字符不可见, 不代表没收到
+        end
+    until s == ""
+end
+
+-- 初始化第一个串口
+uart.setup(
+    uartid1,--串口id
+    921600,--波特率
+    8,--数据位
+    1--停止位
+)
+
+-- 初始化第一个串口
+uart.setup(
+    uartid2,--串口id
+    921600,--波特率
+    8,--数据位
+    1--停止位
+)
+
+-- 第一个串口接收数据回调函数
+-- 收取数据会触发回调, 这里的"receive" 是固定值
+uart.on(uartid1, "receive", uart_cb)
+
+-- 第二个串口接收数据回调函数
+-- 收取数据会触发回调, 这里的"receive" 是固定值
+uart.on(uartid2, "receive", uart_cb)
+
+-- 发送数据完成会触发回调, 这里的"sent" 是固定值
+uart.on(uartid1, "sent", uart_send_cb)
+
+-- 发送数据完成会触发回调, 这里的"sent" 是固定值
+uart.on(uartid2, "sent", uart_send_cb)
+
+sys.taskInit(uart_send)

+ 246 - 0
script/power_init.lua

@@ -0,0 +1,246 @@
+local i2c_id = 1
+local ch224q_i2c_addr = 0x22  -- 受电分析芯片I2C地址
+local ch224q_i2c_reg1 = 0x09  -- 快充协议激活情况(只读)
+local ch224q_i2c_reg2 = 0x0A  -- 电压请求(只写,0:5V 1:9V 2:12V 3:15V 4:20V 5:28V)
+local ch224q_i2c_reg3 = 0x50  -- 最大电流参考值(只写,该寄存器仅PD协议有效)
+
+local bq25895_addr = 0x6A   -- 充电芯片I2C地址
+local bq25895_reg1 = 0x02   -- 控制ADC检测开关
+local bq25895_reg2 = 0x09   -- bit5位可以控制VSYS到VBAT的通路开关(默认0导通,1关闭)
+
+local reg_addr_ADCCTL = 0x02
+local reg_addr_BATV   = 0x0E
+local reg_addr_SYSV   = 0x0F
+local reg_addr_TSPCT  = 0x10
+local reg_addr_VBUSV  = 0x11
+local reg_addr_ICHGR  = 0x12
+local reg_addr_ICO    = 0x13
+
+local function get_value()
+    local ret_val_BATV = i2c.readReg(i2c_id, bq25895_addr, reg_addr_BATV, 1)
+    local ret_val_SYSV = i2c.readReg(i2c_id, bq25895_addr, reg_addr_SYSV, 1)
+    local ret_val_TSPCT = i2c.readReg(i2c_id, bq25895_addr, reg_addr_TSPCT, 1)
+    local ret_val_VBUSV = i2c.readReg(i2c_id, bq25895_addr, reg_addr_VBUSV, 1)
+    local ret_val_ICHGR = i2c.readReg(i2c_id, bq25895_addr, reg_addr_ICHGR, 1)
+    local ret_val_ICO = i2c.readReg(i2c_id, bq25895_addr, reg_addr_ICO, 1)
+
+    local byte_BATV = (ret_val_BATV == "") and 0x00 or string.byte(ret_val_BATV)
+    local byte_SYSV = (ret_val_SYSV == "") and 0x00 or string.byte(ret_val_SYSV)
+    local byte_TSPCT = (ret_val_TSPCT == "") and 0x00 or string.byte(ret_val_TSPCT)
+    local byte_VBUSV = (ret_val_VBUSV == "") and 0x00 or string.byte(ret_val_VBUSV)
+    local byte_ICHGR = (ret_val_ICHGR == "") and 0x00 or string.byte(ret_val_ICHGR)
+    local byte_ICO = (ret_val_ICO == "") and 0x00 or string.byte(ret_val_ICO)
+
+    local s_BATV = (ret_val_BATV == "") and "nil" or string.format("%02X", byte_BATV)
+    local s_SYSV = (ret_val_SYSV == "") and "nil" or string.format("%02X", byte_SYSV)
+    local s_TSPCT = (ret_val_TSPCT == "") and "nil" or string.format("%02X", byte_TSPCT)
+    local s_VBUSV = (ret_val_VBUSV == "") and "nil" or string.format("%02X", byte_VBUSV)
+    local s_ICHGR = (ret_val_ICHGR == "") and "nil" or string.format("%02X", byte_ICHGR)
+    local s_ICO = (ret_val_ICO == "") and "nil" or string.format("%02X", byte_ICO)
+
+
+    local value_BATV = (byte_BATV == 0x00) and 0x00 or ((byte_BATV & 0x7F) * 20 + 2304)
+    local value_SYSV = (byte_SYSV == 0x00) and 0x00 or ((byte_SYSV & 0x7F) * 20 + 2304)
+    local value_TSPCT = (byte_TSPCT == 0x00) and 0x00 or ((byte_TSPCT & 0x7F) * 0.465 + 21)
+    local value_VBUSV = (byte_VBUSV == 0x00) and 0x00 or ((byte_VBUSV & 0x7F) * 100 + 2600)
+    local value_ICHGR = (byte_ICHGR == 0x00) and 0x00 or ((byte_ICHGR & 0x7F) * 50)
+    local value_ICO = (byte_ICO == 0x00) and 0x00 or ((byte_ICO & 0x3F) * 50 + 100)
+
+    local value_Pin = 0
+    local s_Pin = "nil"
+    if (ret_val_VBUSV ~= "") and (ret_val_ICO ~= "") then
+        value_Pin = value_VBUSV * value_ICO / 1000
+        s_Pin = string.format("%.1fmW", value_Pin)
+    else
+        value_Pin = 0
+        s_Pin = "nil"
+    end
+
+    local value_Pchgr = 0
+    local s_Pchgr = "nil"
+    if (ret_val_BATV ~= "") and (ret_val_ICHGR ~= "") then
+        value_Pchgr = value_BATV * value_ICHGR / 1000
+        
+        s_Pchgr = string.format("%.1fmW", value_Pchgr)
+    else
+        value_Pchgr = 0
+        s_Pchgr = "nil"
+    end
+
+    local dbg_info_s1 = ""
+    dbg_info_s1 = string.format("%02X=%s, %02X=%s, %02X=%s, %02X=%s, %02X=%s, %02X=%s=%dmA\n", 
+                reg_addr_BATV, s_BATV,
+                reg_addr_SYSV, s_SYSV,
+                reg_addr_TSPCT, s_TSPCT,
+                reg_addr_VBUSV, s_VBUSV,
+                reg_addr_ICHGR, s_ICHGR,
+                reg_addr_ICO, s_ICO,value_ICO
+                )
+
+    dbg_info_s1 = dbg_info_s1 .."\n"
+
+    dbg_info_s1 = dbg_info_s1..string.format("iBat=%dmV;", value_BATV)
+    dbg_info_s1 = dbg_info_s1..string.format("Sys=%dmV;", value_SYSV)
+    dbg_info_s1 = dbg_info_s1..string.format("TS=%.2f%%;", value_TSPCT)
+    dbg_info_s1 = dbg_info_s1..string.format("Bus=%dmV;", value_VBUSV)
+    dbg_info_s1 = dbg_info_s1..string.format("Chg=%dmA;", value_ICHGR)
+
+    dbg_info_s1 = dbg_info_s1 .."\n"
+    -- dbg_info_s1 = dbg_info_s1.."iccid:"..(mobile.iccid() or "N/A")..";"
+    -- dbg_info_s1 = dbg_info_s1.."imei:"..(mobile.imei() or "N/A")..";\n"
+    -- dbg_info_s1 = dbg_info_s1.."csq:"..(mobile.csq() or "N/A")
+    -- dbg_info_s1 = dbg_info_s1..";rssi:"..(mobile.rssi() or "N/A")
+    -- dbg_info_s1 = dbg_info_s1..";rsrq:"..(mobile.rsrq() or "N/A")
+    -- dbg_info_s1 = dbg_info_s1..";rsrp:"..(mobile.rsrp() or "N/A")
+    -- dbg_info_s1 = dbg_info_s1..";snr:"..(mobile.snr() or "N/A")
+
+    uart.write(1, dbg_info_s1)
+end
+                              
+sys.taskInit(function()
+    sys.wait(200)
+    local result = i2c.setup(i2c_id,i2c.SLOW)
+    log.info("i2c 1", "setup", result)
+
+    -- local data1 = i2c.readReg(i2c_id, ch224q_i2c_addr, ch224q_i2c_reg1, 1)
+    -- local data2 = i2c.readReg(i2c_id, ch224q_i2c_addr, ch224q_i2c_reg3, 1)
+    -- local result1 = i2c.writeReg(i2c_id, ch224q_i2c_addr, ch224q_i2c_reg2, string.char(0x01))
+    -- if result1 then
+    --     uart.write(1, "成功写入数据")
+    -- else
+    --     uart.write(1, "写入数据失败")
+    -- end
+    -- log.info("i2c 请求电压",result1)
+
+    -- uart.write(1, "充电协议:"..data1:toHex())
+    -- uart.write(1, "可用最大电流:"..data2:toHex())
+
+    local reg2_data = i2c.readReg(i2c_id, bq25895_addr, bq25895_reg1, 1)
+    local reg2_temp = (reg2_data == "") and 0x00 or string.byte(reg2_data)
+    local reg2_data_result = reg2_temp | 0xC0
+    local reg2_result = i2c.writeReg(i2c_id, bq25895_addr, bq25895_reg1, string.char(reg2_data_result))
+
+    -- local reg02_data = i2c.readReg(i2c_id, bq25895_addr, bq25895_reg1, 1)
+    -- uart.write(1, "\nreg02:"..reg02_data:toHex().."\n")
+
+    local reg09_result = i2c.writeReg(i2c_id, bq25895_addr, bq25895_reg2, string.char(0x44))
+
+    while true do
+        sys.wait(3000)
+        for i = 0, 20 do
+        --     if i == 14 then -- 读取VBAT电压值
+        --         -- local reg09_data = i2c.readReg(i2c_id, bq25895_addr, bq25895_reg2, 1)
+        --         -- local reg09_data_temp = string.byte(reg2_data)
+        --         -- local reg09_data_result = 0x64
+        --         local reg09_result = i2c.writeReg(i2c_id, bq25895_addr, bq25895_reg2, string.char(0x64))
+        --         sys.wait(500)
+        --         local data = i2c.readReg(i2c_id, bq25895_addr, i, 1)
+        --         local voltage = string.toValue(data)
+        --         uart.write(1, "寄存器14状态,"..i..":"..data:toHex().." "..voltage.."\n")
+        --         local reg09_result = i2c.writeReg(i2c_id, bq25895_addr, bq25895_reg2, string.char(0x44))
+        --         sys.wait(500)
+        --     end
+            -- local data = i2c.readReg(i2c_id, bq25895_addr, i, 1)
+            -- uart.write(1, "寄存器状态,"..i..":"..data:toHex().."\n")
+        end
+        uart.write(1, "连通状态下:\n")
+        get_value()
+        -- sys.wait(1000)
+        -- local reg09_result = i2c.writeReg(i2c_id, bq25895_addr, bq25895_reg2, string.char(0x64))
+        -- sys.wait(5000)
+        -- uart.write(1, "断开状态下:\n")
+        -- get_value()
+        -- sys.wait(1000)
+        -- local reg09_result = i2c.writeReg(i2c_id, bq25895_addr, bq25895_reg2, string.char(0x44))
+        
+    end
+end
+)
+
+-- local bq25895_wrong = 0x0C
+-- local bq25895_wdt = 0x03
+-- local bq25895_wdt_reg = 0x07
+-- local reg02_addr = 0x02
+-- local reg0d_addr = 0x0d
+
+-- local wrong_state = i2c.readReg(i2c_id, bq25895_addr, bq25895_wrong, 1)
+-- uart.write(1, "错误寄存器状态:"..wrong_state:toHex())
+
+-- local wdt_reg_data = i2c.readReg(i2c_id, bq25895_addr, bq25895_wdt_reg, 1)
+-- local wdt_data = string.byte(wdt_reg_data)
+-- local wdt_data_result = wdt_data & ~(0x30)
+-- local wdt_result = i2c.writeReg(i2c_id, bq25895_addr, bq25895_wdt_reg, string.char(wdt_data_result))
+
+-- local reg2_data = i2c.readReg(i2c_id, bq25895_addr, reg02_addr, 1)
+-- local reg2_temp = string.byte(reg2_data)
+-- local reg2_data_result = (reg2_temp | 0xC0) & 0xFE
+-- local reg2_result = i2c.writeReg(i2c_id, bq25895_addr, reg02_addr, string.char(reg2_data_result))
+
+-- local reg02_data = i2c.readReg(i2c_id, bq25895_addr, reg02_addr, 1)
+-- uart.write(1, "reg02:"..reg02_data:toHex())
+
+-- local regd_data_result = 0x46
+-- local regd_result = i2c.writeReg(i2c_id, bq25895_addr, reg0d_addr, string.char(regd_data_result))
+
+
+-- function set_IINDPM(iindpm_setting)
+--     local IINDPM_REGISTER = 0x00  -- 输入电流限制寄存器REG00
+--     local IINLIM_MASK = 0x3F      -- IINLIM位掩码(Bit5~Bit0)
+--     local IINDPM_OFFSET = 0.100   -- 偏移量:100mA
+--     local IINDPM_SIZE = 0.050     -- 步长:50mA
+
+--     local reg_val = i2c.readReg(i2c_id, bq25895_addr, IINDPM_REGISTER, 1)
+    
+--     reg_val = string.byte(reg_val) 
+
+--     local reg_val_temp = reg_val & ~(0x3F)
+
+--     local iindpm = math.floor((iindpm_setting - IINDPM_OFFSET) / IINDPM_SIZE)
+
+--     local iindpm_temp = iindpm | reg_val_temp
+
+--     local write_ok = i2c.writeReg(i2c_id, bq25895_addr, IINDPM_REGISTER, string.char(iindpm_temp))
+
+--     -- 5. 结果反馈
+--     if write_ok then
+--         print(string.format("【成功】输入电流限制已设置为%.2fA(IINLIM值:0x%02X)", iindpm_setting, iindpm_temp))
+--         return true
+--     else
+--         print("【错误】写入REG00失败,配置未生效")
+--         return false
+--     end
+-- end
+
+-- -- 调用函数:设置输入电流限制为3.00A
+-- set_IINDPM(3.00)
+
+-- function set_ICHG(ichg_setting)
+--     local ICHG_REGISTER = 0X04
+--     local ICHG          = 0X7F
+--     local ICHG_OFFSET   = 0.000
+--     local ICHG_SIZE     = 0.064
+
+--     local reg_04 = i2c.readReg(i2c_id, bq25895_addr, ICHG_REGISTER, 1)
+    
+--     reg_04 = string.byte(reg_04) 
+
+--     local reg_04_temp = reg_04 & ~(0x7F)
+
+--     local ichg_temp = math.floor((ichg_setting - ICHG_OFFSET) / ICHG_SIZE)
+
+--     local ichg_num = ichg_temp | reg_04_temp
+
+--     local set_ok = i2c.writeReg(i2c_id, bq25895_addr, ICHG_REGISTER, string.char(ichg_num))
+
+--     -- 5. 结果反馈
+--     if set_ok then
+--         print(string.format("【成功】(寄存器ICHG值:0x%02X)", ichg_num))
+--         return true
+--     else
+--         print("【错误】写入REG04失败,配置未生效")
+--         return false
+--     end
+-- end
+
+
+-- set_ICHG(5.056)

+ 242 - 0
script/pwm_test.lua

@@ -0,0 +1,242 @@
+--[[
+@module  pwm_app
+@summary PWM 输出功能模块
+@version 1.0
+@date    2025.10.29
+@author  马梦阳
+@usage
+本功能模块演示的内容为:
+1. 旧风格 PWM 演示:
+    使用 pwm.open() 完成 PWM 通道的配置与启动
+    使用 pwm.close() 关闭 PWM 通道
+    旧风格 PWM 接口不支持单独配置和动态调整占空比和信号频率
+2. 新风格 PWM 演示:
+    使用 pwm.setup() 完成 PWM 通道的配置
+    使用 pwm.start() 启动 PWM 输出
+    使用 pwm.setDuty() 动态调整占空比
+    使用 pwm.setFreq() 动态调整信号频率
+    使用 pwm.stop() 停止 PWM 输出
+    新风格 PWM 接口支持在运行中动态调整占空比和信号频率
+3. 综合任务调度:顺序运行上述两种风格示例,并在关键节点进行日志输出
+
+注意事项:
+1. 本 demo 演示所使用的是 Air8000 模组的 PWM0 通道(GPIO21,PIN24);
+2. 该引脚需要通过 LuatIO 工具进行复用配置,pins_Air8000.json 文件即复用配置后生成的文件;
+3. 关于 LuatIO 工具的使用介绍以及如何生成 json 文件,请参考 https://docs.openluat.com/air780epm/common/luatio/;
+3. 将通过 LuatIO 工具配置好复用关系后生成的 json 文件与脚本文件一同烧录到模组中即可实现 PWM 输出功能;
+
+本文件没有对外接口,直接在 main.lua 中 require "pwm_app" 就可以加载运行;
+]]
+
+--[[
+旧风格 PWM 演示函数
+使用 pwm.open() 一次性完成配置和启动
+适合固定频率/占空比、无需中途调整的场景
+]]
+local function task1_old_pwm()
+    log.info("PWM", "旧风格 PWM 示例开始")
+
+    -- 选择 PWM 通道 4
+    -- 注意:本 demo 演示所使用的是 Air8000 模组的 PWM0 通道(GPIO21,PIN24);
+    -- 该引脚需要通过 LuatIO 工具进行复用配置,详细说明看最顶部的注意事项;
+    local pwm_channel = 0
+
+    -- 第一次输出:1 kHz,45% 占空比,分频精度 100
+    local pwm_success = pwm.open(pwm_channel, 1000, 45, 0, 100)
+    if pwm_success then
+        log.info("PWM", "PWM0 通道开启成功: 信号频率 1000 Hz, 分频精度 100, 占空比 45%")
+    else
+        log.info("PWM", "PWM0 通道开启失败")
+    end
+
+    -- 持续 1 s 后关闭
+    sys.wait(5000)
+    pwm.close(pwm_channel)
+    log.info("PWM", "PWM0 通道已关闭")
+
+    -- 增加 1 秒的间隔时间
+    sys.wait(2000)
+
+    -- 第二次输出:500 Hz,60% 占空比,分频精度 100
+    local pwm_success = pwm.open(pwm_channel, 500, 60, 0, 100)
+    if pwm_success then
+        log.info("PWM", "PWM0 通道开启成功: 信号频率 500 Hz, 分频精度 100, 占空比 60%")
+    else
+        log.info("PWM", "PWM0 通道开启失败")
+    end
+
+    -- 持续 2 s 后关闭
+    sys.wait(5000)
+    pwm.close(pwm_channel)
+    log.info("PWM", "PWM0 通道已关闭")
+
+    -- 增加 1 秒的间隔时间
+    sys.wait(2000)
+
+    -- 第三次输出:300 Hz,80% 占空比,分频精度 100
+    local pwm_success = pwm.open(pwm_channel, 300, 80, 0, 100)
+    if pwm_success then
+        log.info("PWM", "PWM0 通道开启成功: 信号频率 300 Hz, 分频精度 100, 占空比 80%")
+    else
+        log.info("PWM", "PWM0 通道开启失败")
+    end
+
+    -- 持续 3 s 后关闭
+    sys.wait(5000)
+    pwm.close(pwm_channel)
+    log.info("PWM", "PWM0 通道已关闭")
+
+    log.info("PWM", "旧风格 PWM 示例结束")
+end
+
+
+--[[
+新风格 PWM 演示函数
+使用 pwm.setup() 分步完成配置与启动,支持运行中动态修改频率和占空比
+适合需要实时调节输出参数的场景
+]]
+local function task2_new_pwm()
+    sys.wait(30000)
+    log.info("PWM", "新风格 PWM 示例开始")
+
+    -- 选择 PWM 通道 4
+    -- 注意:本 demo 演示所使用的是 Air8000 模组的 PWM0 通道(GPIO21,PIN24);
+    -- 该引脚需要通过 LuatIO 工具进行复用配置,详细说明看最顶部的注意事项;
+    local pwm_channel = 0
+
+    -- 配置 PWM 参数:频率 1000 Hz、占空比 50%、分频精度 100
+    local setup_success = pwm.setup(pwm_channel, 1000, 50, 0, 100)
+    if setup_success then
+        log.info("PWM", "PWM0 配置成功: 信号频率 1000 Hz, 分频精度 100, 占空比 50%")
+    else
+        log.info("PWM", "PWM0 配置失败")
+    end
+
+    -- 启动 PWM 输出
+    local pwm_success = pwm.start(pwm_channel)
+    if pwm_success then
+        log.info("PWM", "PWM0 启动成功")
+    else
+        log.info("PWM", "PWM0 启动失败")
+    end
+
+    -- 持续输出 2 秒
+    sys.wait(10000)
+
+    -- 动态调整占空比至 25%
+    local setduty_success = pwm.setDuty(pwm_channel, 25)
+    if setduty_success then
+        log.info("PWM", "PWM0 占空比更新为 25%")
+    else
+        log.info("PWM", "PWM0 占空比设置失败")
+    end
+
+    -- 持续输出 2 秒
+    sys.wait(10000)
+
+    -- 动态调整信号频率为 2000 Hz
+    -- local setfreq_success = pwm.setFreq(pwm_channel, 2000)
+    -- if setfreq_success then
+    --     log.info("PWM", "PWM0 频率更新为 2000 Hz")
+    -- else
+    --     log.error("PWM", "PWM0 频率设置失败")
+    -- end
+
+    -- -- 持续输出 2 秒
+    -- sys.wait(2000)
+
+    -- 停止 PWM 输出
+    local pwm_success = pwm.stop(pwm_channel)
+    if pwm_success then
+        log.info("PWM", "PWM0 停止成功")
+    else
+        log.info("PWM", "PWM0 停止失败")
+    end
+
+    log.info("PWM", "新风格 PWM 示例结束")
+end
+
+
+local function task3_pwm_test()
+    sys.wait(30000)
+    log.info("PWM", "输出0-5V变化电压测试")
+
+    -- 选择 PWM 通道 4
+    -- 注意:本 demo 演示所使用的是 Air8000 模组的 PWM0 通道(GPIO21,PIN24);
+    -- 该引脚需要通过 LuatIO 工具进行复用配置,详细说明看最顶部的注意事项;
+    local pwm_channel = 0
+
+    
+    -- 配置 PWM 参数:频率 1000 Hz、占空比 50%、分频精度 100
+    local setup_success = pwm.setup(pwm_channel, 1000, 100, 0, 100)
+    if setup_success then
+        log.info("PWM", "PWM0 配置成功: 信号频率 1000 Hz, 分频精度 100, 占空比 100%")
+    else
+        log.info("PWM", "PWM0 配置失败")
+    end
+    -- 启动 PWM 输出
+    local pwm_success = pwm.start(pwm_channel)
+    if pwm_success then
+        log.info("PWM", "PWM0 启动成功")
+    else
+        log.info("PWM", "PWM0 启动失败")
+    end
+
+    while true do
+        -- 持续输出 2 秒
+        sys.wait(1000)
+
+        -- 动态调整占空比至 25%
+        local setduty0_success = pwm.setDuty(pwm_channel, 0)
+        if setduty0_success then
+            log.info("PWM", "PWM0 占空比更新为 0%")
+        else
+            log.info("PWM", "PWM0 占空比设置失败")
+        end
+
+        sys.wait(1000)
+
+        local setduty5_success = pwm.setDuty(pwm_channel, 100)
+        if setduty5_success then
+            log.info("PWM", "PWM0 占空比更新为 100%")
+        else
+            log.info("PWM", "PWM0 占空比设置失败")
+        end
+
+    end
+
+    -- 停止 PWM 输出
+    local pwm_success = pwm.stop(pwm_channel)
+    if pwm_success then
+        log.info("PWM", "PWM0 停止成功")
+    else
+        log.info("PWM", "PWM0 停止失败")
+    end
+
+    log.info("PWM", "新风格 PWM 示例结束")
+end
+
+--[[
+主演示任务:
+顺序调用旧风格与新风格 PWM 示例函数
+并在两者之间插入 3 秒间隔方便区分新旧风格示例输出情况
+]]
+local function pwm_demo_task()
+    log.info("PWM", "PWM 综合演示任务开始")
+
+    -- 运行旧风格 PWM 示例
+    -- task1_old_pwm()
+
+    -- 间隔 3 秒
+    -- sys.wait(3000)
+
+    -- 运行新风格 PWM 示例
+    -- task2_new_pwm()
+    task3_pwm_test()
+
+    log.info("PWM", "PWM 综合演示任务结束")
+end
+
+-- 创建并启动一个 task
+-- 用于运行 pwm_demo_task 函数
+sys.taskInit(pwm_demo_task)

+ 40 - 0
script/pwrkey.lua

@@ -0,0 +1,40 @@
+local poweron_pin = 46    -- 赋值poweron引脚编号
+
+local power_off_flag = false  -- 是否正在关机
+
+local count=0    -- 五秒内短按三次关机
+
+local function pwrkeycb() 
+    log.info("poweron_key", gpio.get(poweron_pin))
+    if gpio.get(poweron_pin) == 0 then
+        count=count+1
+        sys.timerStart(function()
+            log.info("计数归零")
+            count=0
+        end, 5000)
+        if count>=3 then
+            power_off_flag = true
+            -- pm.shutdown() 
+        end
+    end
+end
+
+
+if poweron_pin ~= 255 then
+    gpio.setup(poweron_pin, pwrkeycb, gpio.PULLUP,gpio.BOTH)
+else
+    log.info("bsp not support")
+end
+
+
+
+sys.taskInit(function()
+    while true do
+        if power_off_flag then
+          sys.wait(1000)
+          pm.shutdown() 
+        end
+
+        sys.wait(100)
+    end
+end)

+ 163 - 0
script/readme.md

@@ -0,0 +1,163 @@
+# AirUI 演示系统
+
+## 一、功能模块介绍
+
+### 1.1 核心主程序模块
+
+1. **main.lua** - 主程序入口,负责系统初始化和任务调度
+2. **ui_main.lua** - AirUI 主程序,负责页面管理和主循环调度
+
+### 1.2 硬件驱动模块
+
+1. **lcd_drv.lua** - LCD 显示驱动模块,基于 lcd 核心库,支持 ST7796 屏幕
+2. **tp_drv.lua** - 触摸面板驱动模块,基于 tp 核心库,支持 GT911 触摸控制器
+
+### 1.3 演示页面模块
+
+1. **home_page.lua** - 主页模块,提供所有演示入口
+2. **all_component_page.lua** - 所有组件综合演示页面
+3. **label_page.lua** - 标签组件演示页面
+4. **button_page.lua** - 按钮组件演示页面
+5. **container_page.lua** - 容器组件演示页面
+6. **bar_page.lua** - 进度条组件演示页面
+7. **switch_page.lua** - 开关组件演示页面
+8. **dropdown_page.lua** - 下拉框组件演示页面
+9. **table_page.lua** - 表格组件演示页面
+10. **input_page.lua** - 输入框组件演示页面
+11. **msgbox_page.lua** - 消息框组件演示页面
+12. **image_page.lua** - 图片组件演示页面
+13. **tabview_page.lua** - 选项卡组件演示页面
+14. **win_page.lua** - 窗口组件演示页面
+15. **switch_page_demo.lua** - 页面切换演示
+16. **hzfont_page.lua** - 矢量字体(HZFont)演示页面
+17. **game_page.lua** - 俄罗斯方块游戏演示页面
+
+## 二、演示效果
+
+| 主页 | 选项卡 | 容器 | 窗口 |
+|------|--------------|------------|----------|
+| ![](https://docs.openluat.com/cdn/image/Air8000_AirUI_主页.png) | ![](https://docs.openluat.com/cdn/image/Air8000_AirUI_选项卡.png) | ![](https://docs.openluat.com/cdn/image/Air8000_AirUI_容器.png) | ![](https://docs.openluat.com/cdn/image/Air8000_AirUI_窗口.png) |
+
+| 下拉框 | 表格 | 进度条 | 输入框 |
+|----------|------------|------------|----------|
+| ![](https://docs.openluat.com/cdn/image/Air8000_AirUI_下拉框.png) | ![](https://docs.openluat.com/cdn/image/Air8000_AirUI_表格.png) | ![](https://docs.openluat.com/cdn/image/Air8000_AirUI_进度条.png) | ![](https://docs.openluat.com/cdn/image/Air8000_AirUI_输入框.png) |
+
+
+## 三、演示硬件环境
+
+### 3.1 实际设备演示说明
+
+- 演示所使用的是 Air8000 开发板
+- 其他组件演示,demo 所使用的固件是 LuatOS-SoC_V2024_Air8000_14.soc
+- 使用其他型号模块可以参考 [docs 文档](https://docs.openluat.com/)中对应型号的固件支持功能进行固件选择,按管脚说明进行接线和配置 lcd_drv.lua 和 tp_drv.lua 中的参数,然后进行烧录使用
+
+### 3.2 硬件清单
+
+- Air8000 开发板 × 1
+- AirLCD_1010 触摸配件板 × 1
+- TYPE-C 数据线 × 1
+
+### 3.3 接线配置
+
+- AirLCD_1010 触摸配件板插入到Air8000 开发板 四线SPI屏接口
+- Air8000 开发板 4G天线旁拨码开关打到 ON 位置,此时背光正常供电
+- Air8000 开发板 侧面供电开关打到 USB供电一端,开发板通过 TYPE-C USB 口供电
+
+
+#### 3.4 接线图
+![](https://docs.openLuat.com/cdn/image/Air8000开发板+屏幕.jpg)
+
+## 四、演示软件环境
+
+### 4.1 开发工具
+
+- [Luatools下载调试工具](https://docs.openluat.com/air8000/luatos/common/download/) - 固件烧录和代码调试
+
+### 4.2 内核固件
+
+- [点击下载Air8000最新版本内核固件](https://docs.openluat.com/air8000/luatos/firmware/),demo所使用的是LuatOS-SoC_V2024_Air8000 14/114号固件
+
+
+
+## 五、演示核心步骤
+
+### 5.1 硬件准备
+
+1. 将屏幕对准定位点插入
+2. Air8000 开发板侧面供电开关打到 USB供电一端
+3. 通过 TYPE-C USB 口供电
+
+### 5.2 软件配置
+
+在 `main.lua` 中选择要运行的演示模块:
+
+```lua
+-- 加载显示驱动
+lcd_drv = require("lcd_drv")
+-- 加载触摸驱动
+tp_drv = require("tp_drv")
+
+-- 引入演示模块(每次只选择一个运行)
+require("ui_main") --动态更新标签演示
+```
+
+### 5.3 初始化参数配置
+
+在对应的驱动文件中根据实际硬件调整硬件参数:
+
+- **lcd_drv.lua** - lcd显示驱动配置、AirUI初始化、hzfont初始化配置
+- **tp_key_drv.lua** - tp触摸驱动配置和初始化,触摸设备绑定AirUI
+
+### 5.4 软件烧录
+
+1. 使用 Luatools 烧录对应型号的最新内核固件
+2. 下载并烧录本项目所有脚本文件
+3. 将图片文件随脚本文件一起烧录到脚本分区
+4. 设备自动重启后开始运行
+5. [点击查看Luatools 下载和详细使用](https://docs.openluat.com/air8000/common/Luatools/)
+
+
+### 5.5 功能测试
+
+#### 5.5.1 主页面操作
+
+1. 设备启动后显示主页面,包含所有演示入口卡片
+2. 查看系统标题和版本信息
+3. 点击各功能卡片进入对应演示页面
+
+#### 5.5.2 组件演示页面
+
+1. 所有组件演示:一次性查看12个AirUI组件
+2. 标签组件:测试文本标签和图标标签
+3. 按钮组件:体验不同大小和样式的按钮
+4. 进度条组件:测试动画进度条和颜色自定义
+5. 输入框组件:测试文本输入和键盘弹出
+6. 消息框组件:体验多种消息框样式
+7. 游戏演示:玩俄罗斯方块游戏,支持触摸控制
+
+#### 5.5.3 字体演示页面
+
+1. 矢量字体页:查看高质量中文矢量字体显示
+2. 支持不同字体大小和颜色对比
+3. 中英文混合显示测试面
+
+
+### 5.6 预期效果
+
+- **系统启动**:正常初始化,显示主页面
+- **页面切换**:流畅的页面过渡效果
+- **组件交互**:所有 UI 组件响应灵敏
+- **字体显示**:各字体页面正常显示,动态调整功能正常
+- **触摸操作**:准确的触摸定位和事件响应
+
+### 5.7 故障排除
+
+1. **显示异常**:检查 LCD 接线,确认对应驱动文件中的硬件参数正确
+2. **触摸无响应**:检查 I2C 接线,确认触摸芯片型号配置正确
+3. **字体显示异常**:确认选择的字体驱动与固件匹配
+4. **图片无法显示**:确认图片文件已正确烧录到指定路径
+5. **系统卡顿**:调整 `ui_main.lua` 中的刷新率参数
+
+## 六、扩展开发
+
+本演示 demo 所有接口都在 [AirUI 核心库](https://docs.openluat.com/osapi/core/airui/)内有详细说明,如需实现更丰富的自定义功能可按接口说明实现。

+ 72 - 0
script/tp_key_drv/tp_drv.lua

@@ -0,0 +1,72 @@
+--[[
+@module  tp_drv
+@summary 触摸面板驱动模块,基于tp核心库
+@version 1.0
+@date    2026.02.05
+@author  江访
+@usage
+本模块为触摸面板驱动功能模块,主要功能包括:
+1、初始化GT911触摸控制器;
+2、配置I2C通信接口和触摸回调函数;
+3、发布触摸事件消息供UI系统处理;
+
+对外接口:
+1、tp_drv.init():初始化触摸面板驱动
+]]
+
+local tp_drv = {}
+
+
+--[[
+初始化触摸面板驱动;
+
+@api tp_drv.init()
+@summary 配置并初始化GT911触摸控制器
+@return boolean 初始化成功返回true,失败返回false
+
+@usage
+-- 初始化触摸面板
+local result = tp_drv.init()
+if result then
+    log.info("触摸面板初始化成功")
+else
+    log.error("触摸面板初始化失败")
+end
+]]
+
+local function tp_callback(tp_device, tp_data)
+    log.info("tp_drv tp_callback", tp_data[1].event, tp_data[1].x, tp_data[1].y)
+    --sys.publish("TP", tp_device, tp_data)
+end
+
+function tp_drv.init()
+    -- 开机I2C供电,触摸、摄像头和音频都是使用I2C0
+    -- gpio.setup(147, 1)
+    -- gpio.setup(164, 1)
+    -- 等待供电稳定
+    sys.wait(100)
+    -- 初始化硬件I2C
+    i2c.setup(0, i2c.SLOW) -- 初始化I2C 0,设置为低速模式
+
+    -- 此处触摸IC数据读取使用的是软件I2C接口
+    -- 参数说明:
+    -- "gt911": 触摸控制器型号
+    -- port: I2C接口对象
+    -- pin_rst: 复位引脚编号
+    -- pin_int: 中断引脚编号
+    -- w: 触摸面板宽度
+    -- h: 触摸面板高度
+    local result = tp.init("gt911", { port = 0, pin_rst = 0xff, pin_int = 21},tp_callback)
+
+    log.info("tp.init", result)
+
+    if not result then
+        log.error("ui_main", "触摸初始化失败")
+        return result
+    else
+        -- 绑定触摸设备到AirUI输入设备
+        return airui.indev_bind_touch(result)
+    end
+end
+
+return tp_drv

+ 178 - 0
script/tsb_ui/tsb_232log_page.lua

@@ -0,0 +1,178 @@
+--[[
+@module  tsb_232log_page        
+@summary 232日志页面
+@version 1.0
+@date    2026.03.17
+@author  李一玮
+@usage
+本文件是232日志页面,展示232日志的各种用法。
+]]
+
+local tsb_232log_page = {}
+
+-- 页面UI元素
+local main_container = nil
+local common_ui = require("tsb_common_page")
+
+-- 创建UI
+function tsb_232log_page.create_ui()
+    main_container = airui.container({
+        x = 0,
+        y = 0,
+        w = 480,
+        h = 320,
+        color = 0xF5F5F5,
+    })
+
+    --------------------- 标题栏 ------------------------
+    local title_bar = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 0,
+        w = 480,
+        h = 30,
+        color = 0xFFCCBC,
+    })
+
+    airui.label({
+        parent = title_bar,
+        text = "232监测界面",
+        x = 190,
+        y = 8,
+        w = 200,
+        h = 20,
+        font_size = 16,
+        color = 0xFFFFFF,
+    })
+
+    -- 标题栏公共信息展示
+    common_ui.add_battery_display(title_bar)
+    common_ui.create_back_button(title_bar, tsb_232log_page.cleanup)
+
+    -- 滚动容器
+    local scroll_container = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 30, 
+        w = 480,
+        h = 270,
+        color = 0xFFFFFF,
+    })
+
+    --------------------- 控制区 ------------------------
+    -- 波特率标签
+    airui.label({
+        parent = scroll_container,
+        text = "波特率:",
+        x = 5,
+        y = 16,
+        w = 60,
+        h = 30,
+        font_size = 15,
+    })
+
+    -- 波特率下拉框
+    local baudrate_dropdown = airui.dropdown({
+        parent = scroll_container,
+        x = 65,
+        y = 7,
+        w = 100,
+        h = 35,
+        options = {"2400", "4800", "9600", "19200", "38400", "57600", "115200"},
+        default_index = 2, -- 默认选择9600
+        on_change = function(self,idx)
+            log.info("485_baudrate", "选择了波特率:" .. self.options[idx + 1])
+        end
+    })
+
+
+    airui.label({
+        parent = scroll_container,
+        text = "推测:",
+        x = 180,
+        y = 16,
+        w = 40,
+        h = 30,
+        font_size = 15,
+    })
+
+    local baud_predict = airui.label({
+        parent = scroll_container,
+        text = "2400",
+        x = 220,
+        y = 15,
+        w = 50,
+        h = 20,
+        font_size = 15,
+    })
+
+
+    --------------------- 485日志显示 ------------------------
+    local log_container = airui.container({
+        parent = scroll_container,
+        x = 0,
+        y = 45,
+        w = 480,
+        h = 222,
+        color = 0xFFFFFF,
+    })
+
+    -- 日志内容显示
+    local log_content = airui.textarea({
+        parent = log_container,
+        x = 5,
+        y = 5,
+        w = 470,
+        h = 212,
+        text = "00 01 02 03 04 05 06 07\n" ..
+               "08 09 0A 0B 0C 0D 0E 0F\n" 
+    })
+
+    -- 开始监测按钮
+    local start_btn = airui.button({
+        parent = scroll_container,
+        x = 285,
+        y = 5,
+        w = 100,
+        h = 35,
+        text = "开始监测",
+        stype = { bg_color = 0x2B6FF1,border_color = 0x2B6FF1, text_color = 0xFFFFFF, radius = 8 },
+        on_click = function(self)
+            log.info("485_log", "开始监测按钮被点击")
+        end
+    })
+
+    -- 清空按钮
+    local clear_btn = airui.button({
+        parent = scroll_container,
+        x = 395,
+        y = 5,
+        w = 80,
+        h = 35,
+        text = "清空",
+        on_click = function(self)
+            log.info("485_log", "清空按钮被点击")
+            -- 清空日志内容
+            log_content:set_text("")
+        end
+    })
+    ---------------------------------------------------
+
+    -- 底部信息
+    common_ui.create_status_bar(main_container)
+end
+
+-- 初始化页面
+function tsb_232log_page.init(params)
+    tsb_232log_page.create_ui()
+end
+
+-- 清理页面
+function tsb_232log_page.cleanup()
+    if main_container then
+        main_container:destroy()
+        main_container = nil
+    end
+end
+
+return tsb_232log_page

+ 178 - 0
script/tsb_ui/tsb_485log_page.lua

@@ -0,0 +1,178 @@
+--[[
+@module  tsb_485log_page
+@summary 485日志页面
+@version 1.0
+@date    2026.03.04
+@author  李一玮
+@usage
+本文件是485日志页面,展示485日志的各种用法。
+]]
+
+local tsb_485log_page = {}
+
+-- 页面UI元素
+local main_container = nil
+local common_ui = require("tsb_common_page")
+
+-- 创建UI
+function tsb_485log_page.create_ui()
+    main_container = airui.container({
+        x = 0,
+        y = 0,
+        w = 480,
+        h = 320,
+        color = 0xF5F5F5,
+    })
+
+    --------------------- 标题栏 ------------------------
+    local title_bar = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 0,
+        w = 480,
+        h = 30,
+        color = 0xA5D6A7,
+    })
+
+    airui.label({
+        parent = title_bar,
+        text = "485监测界面",
+        x = 190,
+        y = 8,
+        w = 200,
+        h = 20,
+        font_size = 16,
+        color = 0xFFFFFF,
+    })
+
+    -- 标题栏公共信息展示
+    common_ui.add_battery_display(title_bar)
+    common_ui.create_back_button(title_bar, tsb_485log_page.cleanup)
+
+    -- 滚动容器
+    local scroll_container = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 30,
+        w = 480,
+        h = 270,
+        color = 0xFFFFFF,
+    })
+
+    --------------------- 控制区 ------------------------
+    -- 波特率标签
+    airui.label({
+        parent = scroll_container,
+        text = "波特率:",
+        x = 5,
+        y = 16,
+        w = 60,
+        h = 30,
+        font_size = 15,
+    })
+
+    -- 波特率下拉框
+    local baudrate_dropdown = airui.dropdown({
+        parent = scroll_container,
+        x = 65,
+        y = 7,
+        w = 100,
+        h = 35,
+        options = {"2400", "4800", "9600", "19200", "38400", "57600", "115200"},
+        default_index = 2, -- 默认选择9600
+        on_change = function(self,idx)
+            log.info("485_baudrate", "选择了波特率:" .. self.options[idx + 1])
+        end
+    })
+
+
+    airui.label({
+        parent = scroll_container,
+        text = "推测:",
+        x = 180,
+        y = 16,
+        w = 40,
+        h = 30,
+        font_size = 15,
+    })
+
+    local baud_predict = airui.label({
+        parent = scroll_container,
+        text = "2400",
+        x = 220,
+        y = 15,
+        w = 50,
+        h = 20,
+        font_size = 15,
+    })
+
+
+    --------------------- 485日志显示 ------------------------
+    local log_container = airui.container({
+        parent = scroll_container,
+        x = 0,
+        y = 45,
+        w = 480,
+        h = 222,
+        color = 0xFFFFFF,
+    })
+
+    -- 日志内容显示
+    local log_content = airui.textarea({
+        parent = log_container,
+        x = 5,
+        y = 5,
+        w = 470,
+        h = 212,
+        text = "00 01 02 03 04 05 06 07\n" ..
+               "08 09 0A 0B 0C 0D 0E 0F\n"
+    })
+
+    -- 开始监测按钮
+    local start_btn = airui.button({
+        parent = scroll_container,
+        x = 285,
+        y = 5,
+        w = 100,
+        h = 35,
+        text = "开始监测",
+        stype = { bg_color = 0x2B6FF1,border_color = 0x2B6FF1, text_color = 0xFFFFFF, radius = 8 },
+        on_click = function(self)
+            log.info("485_log", "开始监测按钮被点击")
+        end
+    })
+
+    -- 清空按钮
+    local clear_btn = airui.button({
+        parent = scroll_container,
+        x = 395,
+        y = 5,
+        w = 80,
+        h = 35,
+        text = "清空",
+        on_click = function(self)
+            log.info("485_log", "清空按钮被点击")
+            -- 清空日志内容
+            log_content:set_text("")
+        end
+    })
+    ---------------------------------------------------
+
+    -- 底部信息
+    common_ui.create_status_bar(main_container)
+end
+
+-- 初始化页面
+function tsb_485log_page.init(params)
+    tsb_485log_page.create_ui()
+end
+
+-- 清理页面
+function tsb_485log_page.cleanup()
+    if main_container then
+        main_container:destroy()
+        main_container = nil
+    end
+end
+
+return tsb_485log_page

+ 324 - 0
script/tsb_ui/tsb_bmq_page.lua

@@ -0,0 +1,324 @@
+--[[
+@module  tsb_bmq_page
+@summary 编码器演示页面
+@version 1.0
+@date    2026.03.04
+@author  李一玮
+@usage
+本文件是编码器演示页面,展示编码器的各种用法。
+]]
+
+local tsb_bmq_page = {}
+
+-- 页面UI元素
+local main_container = nil
+local common_ui = require("tsb_common_page")
+
+-- 创建UI
+function tsb_bmq_page.create_ui()
+    main_container = airui.container({
+        x = 0,
+        y = 0,
+        w = 480,
+        h = 320,
+        color = 0xF5F5F5,
+    })
+
+    --------------------- 标题栏 ------------------------
+    local title_bar = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 0,
+        w = 480,
+        h = 30,
+        color = 0xFF9800,
+    })
+
+    airui.label({
+        parent = title_bar,
+        text = "编码器",
+        x = 210,
+        y = 8,
+        w = 80,
+        h = 20,
+        font_size = 16,
+        color = 0xFFFFFF,
+    })
+    
+    -- 标题栏公共信息展示
+    common_ui.add_battery_display(title_bar)
+    common_ui.create_back_button(title_bar, tsb_bmq_page.cleanup)
+    ---------------------------------------------------
+
+    -- 滚动容器
+    local scroll_container = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 30,
+        w = 480,
+        h = 270,
+        color = 0xF5F5F5,
+    })
+
+    local keyboard1 = airui.keyboard({
+        x = 0,
+        y = 0,
+        w = 480,
+        h = 160,                        -- x, y, 键盘默认打开ALIGN_BOTTOM_MID,位置从中下方开始计算
+        mode = "numeric",               -- 键盘模式,可选 "text"/"upper"/"lower"/"numeric"
+        auto_hide = true,               -- 自动隐藏键盘
+        bg_color = 0xf1f1f1,            -- 键盘背景颜色为灰色,可选,不设置则透明
+        on_commit = function()          -- 确认事件回调,只有在按下确认键时才会触发
+            log.info("keyboard", "commit")
+        end
+    })
+
+    ------------------- 模拟编码器输入 ------------------
+    local bmq_input_container = airui.container({
+        parent = scroll_container,
+        x = 10,
+        y = 5,
+        w = 200,
+        h = 260,
+        color = 0xFFFFFF,
+        radius = 5,
+    })
+
+    airui.label({
+        parent = bmq_input_container,
+        text = "编码器信号输入",
+        x = 35,
+        y = 10,
+        w = 140,
+        h = 30,
+        font_size = 18,
+    })
+
+    airui.label({
+        parent = bmq_input_container,
+        text = "实时电平:",
+        x = 20,
+        y = 80,
+        w = 80,
+        h = 30,
+        font_size = 16,
+    })
+
+    local label_cur_vol = airui.label({
+        parent = bmq_input_container,
+        text = "高",
+        x = 100,
+        y = 80,
+        w = 80,
+        h = 30,
+        font_size = 16,
+    })
+
+    airui.label({
+        parent = bmq_input_container,
+        text = "检测脉冲数:",
+        x = 20,
+        y = 140,
+        w = 100,
+        h = 30,
+        font_size = 16,
+    })
+
+    local label_pulse_count = airui.label({
+        parent = bmq_input_container,
+        text = "12345",
+        x = 120,
+        y = 140,
+        w = 70,
+        h = 30,
+        font_size = 16,
+    })
+
+    local tax_serial_btn = airui.button({
+        parent = bmq_input_container,
+        x = 65,
+        y = 215,
+        w = 80,
+        h = 35,
+        text = "清零",
+        on_click = function(self)
+            log.info("button", "基本按钮被点击")
+            label_pulse_count:set_text("0")
+        end
+    })
+
+    ----------------------------------------------------
+
+    ------------------- 模拟编码器输出 ------------------
+    local bmq_output_container = airui.container({
+        parent = scroll_container,
+        x = 220,
+        y = 5,
+        w = 250,
+        h = 260,
+        color = 0xFFFFFF,
+        radius = 5,
+    })
+
+    airui.label({
+        parent = bmq_output_container,
+        text = "编码器信号输出",
+        x = 60,
+        y = 10,
+        w = 140,
+        h = 30,
+        font_size = 18,
+    })
+
+    -- 脉冲周期
+    airui.label({
+        parent = bmq_output_container,
+        text = "脉冲周期:",
+        x = 20,
+        y = 50,
+        w = 80,
+        h = 30,
+        font_size = 16,
+    })
+
+    local cycle_input = airui.textarea({
+        parent = bmq_output_container,
+        x = 100,
+        y = 40,
+        w = 60,
+        h = 35,
+        text = "5",
+        max_len = 5,
+        keyboard = keyboard1
+    })
+
+    airui.label({
+        parent = bmq_output_container,
+        text = "ms",
+        x = 165,
+        y = 50,
+        w = 30,
+        h = 30,
+        font_size = 16,
+    })
+
+    -- 电压幅度
+    airui.label({
+        parent = bmq_output_container,
+        text = "电压幅度:",
+        x = 20,
+        y = 90,
+        w = 80,
+        h = 30,
+        font_size = 16,
+    })
+
+    local voltage_input = airui.textarea({
+        parent = bmq_output_container,
+        x = 100,
+        y = 80,
+        w = 60,
+        h = 35,
+        text = "5",
+        max_len = 2,
+        keyboard = keyboard1
+    })
+
+    airui.label({
+        parent = bmq_output_container,
+        text = "V",
+        x = 170,
+        y = 90,
+        w = 30,
+        h = 30,
+        font_size = 16,
+    })
+
+    -- 当前电平
+    airui.label({
+        parent = bmq_output_container,
+        text = "当前电平:",
+        x = 20,
+        y = 130,
+        w = 80,
+        h = 30,
+        font_size = 16,
+    })
+
+    local label_output_level = airui.label({
+        parent = bmq_output_container,
+        text = "高",
+        x = 100,
+        y = 130,
+        w = 80,
+        h = 30,
+        font_size = 16,
+    })
+
+    -- 输出脉冲数
+    airui.label({
+        parent = bmq_output_container,
+        text = "输出脉冲数:",
+        x = 20,
+        y = 170,
+        w = 100,
+        h = 30,
+        font_size = 16,
+    })
+
+    local label_output_pulse = airui.label({
+        parent = bmq_output_container,
+        text = "0",
+        x = 120,
+        y = 170,
+        w = 80,
+        h = 30,
+        font_size = 16,
+    })
+
+    -- 按钮
+    local start_btn = airui.button({
+        parent = bmq_output_container,
+        x = 40,
+        y = 215,
+        w = 80,
+        h = 35,
+        text = "开始",
+        stype = { bg_color = 0x2B6FF1,border_color = 0x2B6FF1, text_color = 0xFFFFFF, radius = 8 },
+        on_click = function(self)
+            log.info("button", "开始按钮被点击")
+        end
+    })
+
+    local clear_btn = airui.button({
+        parent = bmq_output_container,
+        x = 130,
+        y = 215,
+        w = 80,
+        h = 35,
+        text = "清零",
+        on_click = function(self)
+            log.info("button", "清零按钮被点击")
+        end
+    })
+    ----------------------------------------------------
+
+
+    -- 底部信息
+    common_ui.create_status_bar(main_container)
+end
+
+-- 初始化页面
+function tsb_bmq_page.init(params)
+    tsb_bmq_page.create_ui()
+end
+
+-- 清理页面
+function tsb_bmq_page.cleanup()
+    if main_container then
+        main_container:destroy()
+        main_container = nil
+    end
+end
+
+return tsb_bmq_page

+ 561 - 0
script/tsb_ui/tsb_bsk_page.lua

@@ -0,0 +1,561 @@
+--[[
+@module  tsb_bsk_page
+@summary 报税口演示页面
+@version 1.0
+@date    2026.03.04
+@author  李一玮
+@usage
+本文件是报税口演示页面,展示报税口的各种用法。
+]]
+
+local tsb_bsk_page = {}
+
+-- 页面UI元素
+local main_container = nil
+local common_ui = require("tsb_common_page")
+
+-- 创建UI
+function tsb_bsk_page.create_ui()
+    main_container = airui.container({
+        x = 0,
+        y = 0,
+        w = 480,
+        h = 320,
+        color = 0xF5F5F5,
+    })
+    --------------------- 标题栏 ------------------------
+    local title_bar = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 0,
+        w = 480,
+        h = 30,
+        color = 0x007AFF,
+    })
+
+    airui.label({
+        parent = title_bar,
+        text = "报税口",
+        x = 210,
+        y = 8,
+        w = 80,
+        h = 20,
+        font_size = 16,
+        color = 0xFFFFFF,
+    })
+    
+    -- 标题栏公共信息展示
+    common_ui.add_battery_display(title_bar)
+    common_ui.create_back_button(title_bar, tsb_bsk_page.cleanup)
+
+    ---------------------------------------------------
+
+    -- 滚动容器
+    local scroll_container = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 30,
+        w = 480,
+        h = 270,
+        color = 0xF5F5F5,
+    })
+
+    local keyboard1 = airui.keyboard({
+        x = 0,
+        y = 0,
+        w = 480,
+        h = 160,                        -- x, y, 键盘默认打开ALIGN_BOTTOM_MID,位置从中下方开始计算
+        mode = "numeric",               -- 键盘模式,可选 "text"/"upper"/"lower"/"numeric"
+        auto_hide = true,               -- 自动隐藏键盘
+        bg_color = 0xf1f1f1,            -- 键盘背景颜色为灰色,可选,不设置则透明
+        on_commit = function()          -- 确认事件回调,只有在按下确认键时才会触发
+            log.info("keyboard", "commit")
+        end
+    })
+
+    --------------------- 接口号 ------------------------
+    airui.label({
+        parent = scroll_container,
+        text = "接口号:",
+        x = 5,
+        y = 17,
+        w = 55,
+        h = 20,
+        font_size = 15,
+    })
+
+    local tax_dropdown = airui.dropdown({
+        parent = scroll_container,
+        x = 60,
+        y = 7,
+        w = 55,
+        h = 35,
+        options = {"A", "B"},
+        default_index = 0,
+        on_change = function(self,idx)
+            -- local texts = {"选项1", "选项2", "选项3", "选项4", "选项5"}
+            -- selected_label1:set_text("当前选中: " .. texts[idx + 1])
+        end
+    })
+    ---------------------------------------------------
+
+    --------------------- 枪号 ------------------------
+    airui.label({
+        parent = scroll_container,
+        text = "枪号:",
+        x = 120,
+        y = 17,
+        w = 40,
+        h = 20,
+        font_size = 15,
+    })
+
+    local gunnum_input = airui.textarea({
+        parent = scroll_container,
+        x = 160,
+        y = 7,
+        w = 55,
+        h = 35,
+        text = "1",
+        -- placeholder = "...",
+        max_len = 1,
+        keyboard = keyboard1
+    })
+    ---------------------------------------------------
+
+    
+    --------------------- 新国标开关 -------------------
+    airui.label({
+        parent = scroll_container,
+        text = "新国标",
+        x = 217,
+        y = 17,
+        w = 50,
+        h = 20,
+        font_size = 15,
+    })
+
+    local switch_new_tax = airui.switch({
+        parent = scroll_container,
+        x = 267,
+        y = 12,
+        w = 50,
+        h = 25,
+        checked = false,
+        on_change = function(self)
+            log.info("NEW_TAX", self:get_state() and "开启" or "关闭")
+        end
+    })
+    ---------------------------------------------------
+
+    -------------------- 新国标报税口 ------------------
+    airui.label({
+        parent = scroll_container,
+        text = "新国标报税口",
+        x = 320,
+        y = 17,
+        w = 95,
+        h = 40,
+        font_size = 15,
+    })
+
+    local new_tax_num_input = airui.textarea({
+        parent = scroll_container,
+        x = 415,
+        y = 7,
+        w = 55,
+        h = 35,
+        text = "1",
+        -- placeholder = "...",
+        max_len = 1,
+        keyboard = keyboard1
+    })
+    ---------------------------------------------------
+
+    ----------------- 查询税控序列号区域 ---------------
+    local tax_serial_container = airui.container({
+        parent = scroll_container,
+        x = 10,
+        y = 50,
+        w = 160,
+        h = 210,
+        color = 0xFFFFFF,
+        radius = 5,
+    })
+
+    local tax_serial_btn = airui.button({
+        parent = tax_serial_container,
+        x = 20,
+        y = 12,
+        w = 120,
+        h = 35,
+        text = "查询税控序列号",
+        stype = { bg_color = 0x2B6FF1,border_color = 0x2B6FF1, text_color = 0xFFFFFF, radius = 8 },
+        on_click = function(self)
+            log.info("button", "基本按钮被点击")
+        end
+    })
+
+    -- 查询结果显示
+    airui.label({
+        parent = tax_serial_container,
+        text = "税控序列号:",
+        x = 10,
+        y = 60,
+        w = 120,
+        h = 20,
+        font_size = 14,
+    })
+
+    local label_tax_serial = airui.label({
+        parent = tax_serial_container,
+        text = "0123456789",
+        x = 10,
+        y = 80,
+        w = 150,
+        h = 20,
+        font_size = 14,
+    })
+
+    airui.label({
+        parent = tax_serial_container,
+        text = "厂家:",
+        x = 10,
+        y = 110,
+        w = 40,
+        h = 20,
+        font_size = 14,
+    })
+
+    local label_company = airui.label({
+        parent = tax_serial_container,
+        text = "拓盛",
+        x = 50,
+        y = 110,
+        w = 90,
+        h = 20,
+        font_size = 14,
+    })
+
+    airui.label({
+        parent = tax_serial_container,
+        text = "枪个数:",
+        x = 10,
+        y = 150,
+        w = 60,
+        h = 20,
+        font_size = 14,
+    })
+
+    local label_gunnum = airui.label({
+        parent = tax_serial_container,
+        text = "2",
+        x = 70,
+        y = 150,
+        w = 80,
+        h = 20,
+        font_size = 14,
+    })
+
+    airui.label({
+        parent = tax_serial_container,
+        text = "执行结果:",
+        x = 10,
+        y = 190,
+        w = 70,
+        h = 20,
+        font_size = 14,
+    })
+
+    local label_tax_serial_result = airui.label({
+        parent = tax_serial_container,
+        text = "执行成功",
+        x = 80,
+        y = 190,
+        w = 80,
+        h = 20,
+        font_size = 14,
+    })
+    ---------------------------------------------------
+
+    ----------------- 日累月累总累 ------------------
+    local tax_msg_container = airui.container({
+        parent = scroll_container,
+        x = 180,
+        y = 50,
+        w = 290,
+        h = 210,
+        color = 0xFFFFFF,
+        radius = 5,
+    })
+
+    local year_input = airui.textarea({
+        parent = tax_msg_container,
+        x = 10,
+        y = 7,
+        w = 70,
+        h = 35,
+        text = os.date('%Y'),
+        -- placeholder = "...",
+        max_len = 4,
+        keyboard = keyboard1
+    })
+
+    airui.label({
+        parent = tax_msg_container,
+        text = "年",
+        x = 85,
+        y = 18,
+        w = 20,
+        h = 20,
+        font_size = 15,
+    })
+
+    local month_dropdown = airui.dropdown({
+        parent = tax_msg_container,
+        x = 105,
+        y = 7,
+        w = 65,
+        h = 35,
+        options = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"},
+        default_index = 0,
+        on_change = function(self,idx)
+            -- local texts = {"选项1", "选项2", "选项3", "选项4", "选项5"}
+            -- selected_label1:set_text("当前选中: " .. texts[idx + 1])
+        end
+    })
+
+    airui.label({
+        parent = tax_msg_container,
+        text = "月",
+        x = 175,
+        y = 18,
+        w = 20,
+        h = 20,
+        font_size = 15,
+    })
+
+    local day_dropdown = airui.dropdown({
+        parent = tax_msg_container,
+        x = 195,
+        y = 7,
+        w = 65,
+        h = 35,
+        options = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13","14","15","16","17","18","19","20","21","22","23","24","25","26","27","28","29","30","31"},
+        default_index = 0,
+        on_change = function(self,idx)
+            -- local texts = {"选项1", "选项2", "选项3", "选项4", "选项5"}
+            -- selected_label1:set_text("当前选中: " .. texts[idx + 1])
+        end
+    })
+
+    airui.label({
+        parent = tax_msg_container,
+        text = "日",
+        x = 265,
+        y = 18,
+        w = 20,
+        h = 20,
+        font_size = 15,
+    })
+
+    
+
+    local check_total_btn = airui.button({
+        parent = tax_msg_container,
+        x = 10,
+        y = 50,
+        w = 120,
+        h = 35,
+        text = "查当次及总累",
+        stype = { bg_color = 0x2B6FF1,border_color = 0x2B6FF1, text_color = 0xFFFFFF, radius = 8 },
+        on_click = function(self)
+            log.info("button", "基本按钮被点击")
+        end
+    })
+
+    local check_day_btn = airui.button({
+        parent = tax_msg_container,
+        x = 140,
+        y = 50,
+        w = 60,
+        h = 35,
+        text = "查日累",
+        stype = { bg_color = 0x2B6FF1,border_color = 0x2B6FF1, text_color = 0xFFFFFF, radius = 8 },
+        on_click = function(self)
+            log.info("button", "基本按钮被点击")
+        end
+    })
+
+    local check_month_btn = airui.button({
+        parent = tax_msg_container,
+        x = 210,
+        y = 50,
+        w = 60,
+        h = 35,
+        text = "查月累",
+        stype = { bg_color = 0x2B6FF1,border_color = 0x2B6FF1, text_color = 0xFFFFFF, radius = 8 },
+        on_click = function(self)
+            log.info("button", "基本按钮被点击")
+        end
+    })
+
+
+    airui.label({
+        parent = tax_msg_container,
+        text = "金额:",
+        x = 10,
+        y = 100,
+        w = 50,
+        h = 20,
+        font_size = 14,
+    })
+
+    local label_money = airui.label({
+        parent = tax_msg_container,
+        text = "9999.99",
+        x = 50,
+        y = 100,
+        w = 70,
+        h = 20,
+        font_size = 14,
+    })
+
+    airui.label({
+        parent = tax_msg_container,
+        text = "油量:",
+        x = 10,
+        y = 120,
+        w = 50,
+        h = 20,
+        font_size = 14,
+    })
+
+    local label_oil = airui.label({
+        parent = tax_msg_container,
+        text = "9999.99",
+        x = 50,
+        y = 120,
+        w = 70,
+        h = 20,
+        font_size = 14,
+    })
+
+    airui.label({
+        parent = tax_msg_container,
+        text = "单价:",
+        x = 10,
+        y = 140,
+        w = 50,
+        h = 20,
+        font_size = 14,
+    })
+
+    local label_price = airui.label({
+        parent = tax_msg_container,
+        text = "99.99",
+        x = 50,
+        y = 140,
+        w = 50,
+        h = 20,
+        font_size = 14,
+    })
+
+    airui.label({
+        parent = tax_msg_container,
+        text = "是否密文:",
+        x = 10,
+        y = 160,
+        w = 70,
+        h = 20,
+        font_size = 14,
+    })
+
+    local label_encryption = airui.label({
+        parent = tax_msg_container,
+        text = "是",
+        x = 80,
+        y = 160,
+        w = 30,
+        h = 20,
+        font_size = 14,
+    })
+
+    airui.label({
+        parent = tax_msg_container,
+        text = "总金额",
+        x = 185,
+        y = 100,
+        w = 70,
+        h = 20,
+        font_size = 14,
+    })
+
+    local label_total_money = airui.label({
+        parent = tax_msg_container,
+        text = "1234567891234.99",
+        x = 140,
+        y = 120,
+        w = 150,
+        h = 30,
+        font_size = 14,
+    })
+
+    airui.label({
+        parent = tax_msg_container,
+        text = "总油量",
+        x = 185,
+        y = 140,
+        w = 70,
+        h = 20,
+        font_size = 14,
+    })
+
+    local label_total_oil = airui.label({
+        parent = tax_msg_container,
+        text = "1234567891234.99",
+        x = 140,
+        y = 160,
+        w = 150,
+        h = 30,
+        font_size = 14,
+    })
+
+    airui.label({
+        parent = tax_msg_container,
+        text = "执行结果:",
+        x = 10,
+        y = 190,
+        w = 70,
+        h = 20,
+        font_size = 14,
+    })
+
+    local label_check_result = airui.label({
+        parent = tax_msg_container,
+        text = "执行成功",
+        x = 80,
+        y = 190,
+        w = 120,
+        h = 20,
+        font_size = 14,
+    })
+
+    -- 底部信息栏
+    common_ui.create_status_bar(main_container)
+end
+
+-- 初始化页面
+function tsb_bsk_page.init(params)
+    tsb_bsk_page.create_ui()
+end
+
+-- 清理页面
+function tsb_bsk_page.cleanup()
+    if main_container then
+        main_container:destroy()
+        main_container = nil
+    end
+end
+
+return tsb_bsk_page

+ 281 - 0
script/tsb_ui/tsb_channel_page.lua

@@ -0,0 +1,281 @@
+--[[
+@module  tsb_channel_page
+@summary 信道切换页面
+@version 1.0
+@date    2026.03.05
+@author  李一玮
+@usage
+本文件是信道切换页面,展示信道切换的各种用法。
+]]
+
+local tsb_channel_page = {}
+
+-- 页面UI元素
+local main_container = nil
+local common_ui = require("tsb_common_page")
+
+-- 创建UI
+function tsb_channel_page.create_ui()
+    main_container = airui.container({
+        x = 0,
+        y = 0,
+        w = 480,
+        h = 320,
+        color = 0xF5F5F5,
+        color_opacity = 0
+    })
+
+    --------------------- 标题栏 ------------------------
+    local title_bar = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 0,
+        w = 480,
+        h = 30,
+        color = 0x7E57C2,
+    })
+
+    airui.label({
+        parent = title_bar,
+        text = "信道切换",
+        x = 190,
+        y = 8,
+        w = 100,
+        h = 20,
+        font_size = 16,
+        color = 0xFFFFFF,
+    })
+
+    
+    -- 标题栏公共信息展示
+    common_ui.add_battery_display(title_bar)
+    common_ui.create_back_button(title_bar, tsb_channel_page.cleanup)
+    ---------------------------------------------------
+
+    -- 滚动容器
+    local scroll_container = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 30,
+        w = 480,
+        h = 270,
+        color = 0xFFFFFF,
+        
+    })
+
+    local keyboard1 = airui.keyboard({
+        x = 0,
+        y = 0,
+        w = 480,
+        h = 160,                        -- x, y, 键盘默认打开ALIGN_BOTTOM_MID,位置从中下方开始计算
+        mode = "numeric",               -- 键盘模式,可选 "text"/"upper"/"lower"/"numeric"
+        auto_hide = true,               -- 自动隐藏键盘
+        bg_color = 0xf1f1f1,            -- 键盘背景颜色为灰色,可选,不设置则透明
+        on_commit = function()          -- 确认事件回调,只有在按下确认键时才会触发
+            log.info("keyboard", "commit")
+        end
+    })
+
+    local keyboard2 = airui.keyboard({
+        x = 0,
+        y = 0,
+        w = 480,
+        h = 160,                        -- x, y, 键盘默认打开ALIGN_BOTTOM_MID,位置从中下方开始计算
+        mode = "lower",               -- 键盘模式,可选 "text"/"upper"/"lower"/"numeric"
+        auto_hide = true,               -- 自动隐藏键盘
+        bg_color = 0xf1f1f1,            -- 键盘背景颜色为灰色,可选,不设置则透明
+        on_commit = function()          -- 确认事件回调,只有在按下确认键时才会触发
+            log.info("keyboard", "commit")
+        end
+    })
+
+    --------------------- 第一行控制区 ------------------------
+    -- 当前lora信道标签
+    airui.label({
+        parent = scroll_container,
+        text = "当前调试宝信道:",
+        x = 10,
+        y = 15,
+        w = 120,
+        h = 30,
+        font_size = 15,
+    })
+
+    -- 当前lora信道值
+    local current_channel_label = airui.label({
+        parent = scroll_container,
+        text = "1",
+        x = 135,
+        y = 15,
+        w = 30,
+        h = 30,
+        font_size = 15,
+    })
+
+    -- 设置lora信道标签
+    airui.label({
+        parent = scroll_container,
+        text = "设置调试宝信道:",
+        x = 180,
+        y = 15,
+        w = 130,
+        h = 30,
+        font_size = 15,
+    })
+
+    -- 设置lora信道下拉框
+    local channel_dropdown = airui.dropdown({
+        parent = scroll_container,
+        x = 310,
+        y = 8,
+        w = 70,
+        h = 30,
+        options = {"1", "2", "3", "4", "5", "6"},
+        default_index = 0, -- 默认选择1
+        on_change = function(self,idx)
+            log.info("mqtt_channel", "选择了信道:" .. self.options[idx + 1])
+        end
+    })
+
+
+    -- 目标设备类型标签
+    airui.label({
+        parent = scroll_container,
+        text = "目标设备类型:",
+        x = 10,
+        y = 60,
+        w = 100,
+        h = 30,
+        font_size = 15,
+    })
+
+    -- 目标设备类型下拉框
+    local device_type_dropdown = airui.dropdown({
+        parent = scroll_container,
+        x = 120,
+        y = 50,
+        w = 100,
+        h = 35,
+        options = {"路由器", "连接器"},
+        default_index = 0, -- 默认选择路由器
+        on_change = function(self,idx)
+            log.info("device_type", "选择了设备类型:" .. self.options[idx + 1])
+        end
+    })
+
+    airui.label({
+        parent = scroll_container,
+        text = "目标设备SN:",
+        x = 10,
+        y = 110,
+        w = 100,
+        h = 30,
+        font_size = 15,
+    })
+
+    -- 连接器SN输入框
+    local sn_input = airui.textarea({
+        parent = scroll_container,
+        x = 120,
+        y = 100,
+        w = 100,
+        h = 35,
+        text = "",
+        max_length = 5,
+        keyboard = keyboard1
+    })
+
+
+    airui.label({
+        parent = scroll_container,
+        text = "切换到信道:",
+        x = 10,
+        y = 160,
+        w = 100,
+        h = 20,
+        font_size = 15,
+    })
+
+    local channel1_dropdown = airui.dropdown({
+        parent = scroll_container,
+        x = 120,
+        y = 150,
+        w = 70,
+        h = 35,
+        options = {"1", "2", "3", "4", "5", "6"},
+        default_index = 0, -- 默认选择1
+        on_change = function(self,idx)
+            log.info("mqtt_channel", "选择了信道:" .. self.options[idx + 1])
+        end
+    })
+    ---------------------------------------------------
+
+
+    -- 新配置下发按钮
+    local new_config_btn = airui.button({
+        parent = scroll_container,
+        x = 30,
+        y = 200,
+        w = 100,
+        h = 35,
+        text = "指令下发",
+        --stype = { bg_color = 0x2B6FF1,border_color = 0x2B6FF1, text_color = 0xFFFFFF, radius = 8 },
+        on_click = function(self)
+            log.info("mqtt_config", "新配置下发按钮被点击")
+        end
+    })
+
+    -- 恢复默认配置按钮
+    -- local default_config_btn = airui.button({
+    --     parent = scroll_container,
+    --     x = 120,
+    --     y = 230,
+    --     w = 120,
+    --     h = 35,
+    --     text = "恢复默认配置",
+    --     on_click = function(self)
+    --         log.info("mqtt_config", "恢复默认配置按钮被点击")
+    --     end
+    -- })
+
+    -- 执行结果
+    airui.label({
+        parent = scroll_container,
+        text = "执行结果:",
+        x = 270,
+        y = 210,
+        w = 80,
+        h = 30,
+        font_size = 16,
+    })
+
+    -- 执行结果值
+    local result_label = airui.label({
+        parent = scroll_container,
+        text = "成功",
+        x = 350,
+        y = 210,    
+        w = 100,
+        h = 30,
+        font_size = 16,
+    })
+    ---------------------------------------------------
+
+    -- 底部信息
+    common_ui.create_status_bar(main_container)
+end
+
+-- 初始化页面
+function tsb_channel_page.init(params)
+    tsb_channel_page.create_ui()
+end
+
+-- 清理页面
+function tsb_channel_page.cleanup()
+    if main_container then
+        main_container:destroy()
+        main_container = nil
+    end
+end
+
+return tsb_channel_page

+ 344 - 0
script/tsb_ui/tsb_common_page.lua

@@ -0,0 +1,344 @@
+--[[
+@module  common_ui
+@summary 公共UI组件
+@version 1.0
+@date    2026.03.05
+@author  李一玮
+@usage
+本文件提供公共UI组件功能,如电量显示等。
+]]
+
+local common_ui = {}
+local time1_id = nil
+local show_charge_info = false  -- 控制显示哪个文本
+local switch_counter = 0  -- 计数器,用于控制文本切换频率
+local shutdown_msgbox = nil  -- 跟踪关机弹窗状态
+
+-- 在现有标题栏添加电量显示
+-- @param title_bar 标题栏容器对象
+-- @return battery_label 电量标签对象,用于后续更新
+function common_ui.add_battery_display(parent)
+    -- 电量图标
+    airui.image({
+        parent = parent,
+        x = 410,
+        y = 5,
+        w = 40,
+        h = 20,
+        src = "/luadb/dian3.png",
+        zoom = 200,
+    })
+
+    -- 电量值标签
+    local battery_label = airui.label({
+        parent = parent,
+        text = "70%",
+        x = 445,
+        y = 8,
+        w = 35,
+        h = 20,
+        font_size = 14,
+        color = 0xFFFFFF,
+    })
+
+    -- 信号图标
+    airui.image({
+        parent = parent,
+        x = 355,
+        y = 5,
+        w = 40,
+        h = 20,
+        src = "/luadb/4g3.png",
+        zoom = 160,
+    })
+
+    -- 信号值标签
+    local battery_label = airui.label({
+        parent = parent,
+        text = "4G",
+        x = 390,
+        y = 8,
+        w = 45,
+        h = 20,
+        font_size = 14,
+        color = 0xFFFFFF,
+    })
+
+    -- WIFI图标
+    airui.image({
+        parent = parent,
+        x = 330,
+        y = 5,
+        w = 40,
+        h = 20,
+        src = "/luadb/wifi3.png",
+        zoom = 150,
+    })
+
+    return battery_label
+end
+
+function common_ui.create_back_button(parent, cleanup_func)
+    -- local back_btn = airui.button({
+    --     parent = parent,
+    --     x = 10,
+    --     y = 3,
+    --     w = 45,
+    --     h = 25,
+    --     text = "返回",
+    --     on_click = function()
+    --         -- 调用当前页面的清理函数
+    --         if cleanup_func then
+    --             cleanup_func()
+    --         end
+    --         -- 返回上一页
+    --         go_back()
+    --     end
+    -- })
+
+    local back_img = airui.image({
+        parent = parent,
+        x = 5,
+        y = 4,
+        w = 20,
+        h = 25,                    
+        src = "/luadb/back1.png",
+        zoom = 256,
+        opacity = 255,
+        on_click = function()
+            -- 调用当前页面的清理函数
+            if cleanup_func then
+                cleanup_func()
+            end
+            -- 返回上一页
+            go_back()
+        end
+    })
+
+    local back_label = airui.label({
+        parent = parent,
+        text = "返回",
+        x = 22,
+        y = 9,
+        w = 45,
+        h = 20,
+        font_size = 15,
+        color = 0xFFFFFF,
+        on_click = function()
+            -- 调用当前页面的清理函数
+            if cleanup_func then
+                cleanup_func()
+            end
+            -- 返回上一页
+            go_back()
+        end
+    })
+
+    -- local home_btn = airui.button({
+    --     parent = parent,
+    --     x = 60,
+    --     y = 3,
+    --     w = 45,
+    --     h = 25,
+    --     text = "首页",
+    --     on_click = function()
+    --         if cleanup_func then
+    --             cleanup_func()
+    --         end
+    --         go_home()
+    --     end
+    -- })
+
+    local home_img = airui.image({
+        parent = parent,
+        x = 65,
+        y = 4,
+        w = 20,
+        h = 25,                    
+        src = "/luadb/home2.png",
+        zoom = 140,
+        opacity = 255,
+        on_click = function()
+            if cleanup_func then
+                cleanup_func()
+            end
+            go_home()
+        end
+    })
+
+    local home_label = airui.label({
+        parent = parent,
+        text = "首页",
+        x = 87,
+        y = 9,
+        w = 45,
+        h = 20,
+        font_size = 15,
+        color = 0xFFFFFF,
+        on_click = function()
+            if cleanup_func then
+                cleanup_func()
+            end
+            go_home()
+        end
+    })
+
+
+    return back_img
+
+    
+end
+
+function common_ui.add_background_png(parent)
+    local background_img = airui.image({
+        parent = parent,
+        x = 0,
+        y = 0,
+        w = 480,
+        h = 290,                    
+        src = "/luadb/1.png",
+        zoom = 256,
+        opacity = 255
+    })
+
+    return background_img
+end
+
+-- 创建底部信息栏
+-- @param main_container 主容器对象
+-- @return status_bar 底部信息栏容器对象
+function common_ui.create_status_bar(parent)
+    -- 底部信息
+    local status_bar = airui.container({
+        parent = parent,
+        x = 0,
+        y = 300,
+        w = 480,
+        h = 20,
+        color = 0xDFEAFF,
+    })
+
+    local version_charge_msg = airui.label({
+        parent = status_bar,
+        text = "TSB-3.0 v1.0.0",
+        x = 0,
+        y = 0,
+        w = 180,
+        h = 20,
+        font_size = 14,
+    })
+
+    local shutdown_image = airui.image({
+        parent = status_bar,
+        x = 422,
+        y = 0,
+        w = 30,
+        h = 20,                    
+        src = "/luadb/shutdown.png",
+        zoom = 200,
+        opacity = 255,
+        on_click = function(self)
+            common_ui.show_shutdown_confirm(status_bar)
+        end
+    })
+
+    local shutdwon_label = airui.label({
+        parent = status_bar,
+        text = "关机",
+        x = 445,
+        y = 2,
+        w = 30,
+        h = 18,
+        font_size = 14,
+        on_click = function(self)
+            common_ui.show_shutdown_confirm(status_bar)
+        end
+    })
+
+    local dynamic_label = airui.label({
+        parent = status_bar,
+        text = os.date("%Y-%m-%d %H:%M:%S"),
+        x = 170,
+        y = 0,
+        w = 180,
+        h = 20,
+        font_size = 14,
+    })
+
+    -- 先停止已存在的定时器,避免多个定时器同时运行
+    if time1_id then
+        sys.timerStop(time1_id)
+        time1_id = nil
+    end
+
+    -- 启动新的定时器
+    time1_id = sys.timerLoopStart(function()
+        local current_time = os.date("%Y-%m-%d %H:%M:%S")
+        -- 检查dynamic_label是否仍然存在
+        if dynamic_label then
+            dynamic_label:set_text(current_time)
+        else
+            -- 如果标签不存在,停止定时器
+            if time1_id then
+                sys.timerStop(time1_id)
+                time1_id = nil
+            end
+        end
+        
+        -- 每两次定时切换一次文本(即1800ms)
+        if version_charge_msg then
+            switch_counter = switch_counter + 1
+            if switch_counter >= 2 then
+                show_charge_info = not show_charge_info  -- 切换状态
+                if show_charge_info then
+                    version_charge_msg:set_text("充电中。。充电功率:7.5W")
+                else
+                    version_charge_msg:set_text("TSB-3.0 v1.0.0")
+                end
+                switch_counter = 0  -- 重置计数器
+            end
+        end
+    end, 900)  -- 每900ms更新一次时间
+    
+    return status_bar
+end
+
+-- 显示关机确认弹窗
+-- @param parent 父容器对象
+function common_ui.show_shutdown_confirm(parent)
+    -- 检查是否已经存在关机弹窗
+    if shutdown_msgbox then
+        log.info("shutdown", "关机弹窗已存在,不重复创建")
+        return
+    end
+    
+    shutdown_msgbox = airui.msgbox({
+        title = "系统提示",
+        text = "是否确认关机?",
+        buttons = { "否", "是" },
+        on_action = function(self, label)
+            if label == "是" then
+                -- 执行关机操作
+                log.info("shutdown", "用户确认关机")
+                pm.shutdown()
+            else
+                -- 取消关机操作
+                log.info("shutdown", "用户取消关机")
+            end
+            self:hide()
+            -- 重置弹窗状态
+            shutdown_msgbox = nil
+        end
+    })
+    shutdown_msgbox:show()
+end
+
+-- 清理函数,用于停止定时器
+function common_ui.cleanup()
+    if time1_id then
+        sys.timerStop(time1_id)
+        time1_id = nil
+    end
+end
+
+return common_ui

+ 214 - 0
script/tsb_ui/tsb_devinfo_page.lua

@@ -0,0 +1,214 @@
+--[[
+@module  tsb_devinfo_page
+@summary 设备信息页面
+@version 1.0
+@date    2026.03.04
+@author  李一玮
+@usage
+本文件是设备信息页面,展示设备的各种信息。
+]]
+
+local tsb_devinfo_page = {}
+
+-- 页面UI元素
+local main_container = nil
+local common_ui = require("tsb_common_page")
+
+-- 创建UI
+function tsb_devinfo_page.create_ui()
+    main_container = airui.container({
+        x = 0,
+        y = 0,
+        w = 480,
+        h = 320,
+        color = 0xF5F5F5,
+    })
+
+    --------------------- 标题栏 ------------------------
+    local title_bar = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 0,
+        w = 480,
+        h = 30,
+        color = 0xB3E5FC,
+    })
+
+    airui.label({
+        parent = title_bar,
+        text = "本机信息",
+        x = 200,
+        y = 8,
+        w = 80,
+        h = 20,
+        font_size = 16,
+        color = 0xFFFFFF,
+    })
+
+    -- 标题栏公共信息展示
+    common_ui.add_battery_display(title_bar)
+    common_ui.create_back_button(title_bar, tsb_devinfo_page.cleanup)
+    ---------------------------------------------------
+
+    -- 滚动容器
+    local scroll_container = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 30,
+        w = 480,
+        h = 270,
+        color = 0xFFFFFF,
+    })
+
+    --------------------- 设备信息展示 ------------------------
+    -- 程序版本
+    airui.label({
+        parent = scroll_container,
+        text = "程序版本:",
+        x = 20,
+        y = 20,
+        w = 100,
+        h = 30,
+        font_size = 16,
+    })
+
+    local version_label = airui.label({
+        parent = scroll_container,
+        text = "V1.0.0",
+        x = 120,
+        y = 20,
+        w = 200,
+        h = 30,
+        font_size = 16,
+        color = 0x666666,
+    })
+
+    -- 运行时间
+    airui.label({
+        parent = scroll_container,
+        text = "运行时间:",
+        x = 20,
+        y = 60,
+        w = 100,
+        h = 30,
+        font_size = 16,
+    })
+
+    local runtime_label = airui.label({
+        parent = scroll_container,
+        text = "00:00:00",
+        x = 120,
+        y = 60,
+        w = 200,
+        h = 30,
+        font_size = 16,
+        color = 0x666666,
+    })
+
+    -- 设备复位次数
+    airui.label({
+        parent = scroll_container,
+        text = "设备复位次数:",
+        x = 20,
+        y = 100,
+        w = 120,
+        h = 30,
+        font_size = 16,
+    })
+
+    local reset_count_label = airui.label({
+        parent = scroll_container,
+        text = "0",
+        x = 140,
+        y = 100,
+        w = 200,
+        h = 30,
+        font_size = 16,
+        color = 0x666666,
+    })
+
+    -- 设备SN
+    airui.label({
+        parent = scroll_container,
+        text = "设备SN:",
+        x = 20,
+        y = 140,
+        w = 100,
+        h = 30,
+        font_size = 16,
+    })
+
+    local device_sn_label = airui.label({
+        parent = scroll_container,
+        text = "SN001",
+        x = 120,
+        y = 140,
+        w = 200,
+        h = 30,
+        font_size = 16,
+        color = 0x666666,
+    })
+
+    -- IMEI
+    airui.label({
+        parent = scroll_container,
+        text = "IMEI:",
+        x = 20,
+        y = 180,
+        w = 100,
+        h = 30,
+        font_size = 16,
+    })
+
+    local imei_label = airui.label({
+        parent = scroll_container,
+        text = "123456789012345",
+        x = 120,
+        y = 180,
+        w = 300,
+        h = 30,
+        font_size = 16,
+        color = 0x666666,
+    })
+
+    -- ICCID
+    airui.label({
+        parent = scroll_container,
+        text = "ICCID:",
+        x = 20,
+        y = 220,
+        w = 100,
+        h = 30,
+        font_size = 16,
+    })
+
+    local iccid_label = airui.label({
+        parent = scroll_container,
+        text = "8986012345678901234",
+        x = 120,
+        y = 220,
+        w = 300,
+        h = 30,
+        font_size = 16,
+        color = 0x666666,
+    })
+    ---------------------------------------------------
+
+    -- 底部信息
+    common_ui.create_status_bar(main_container)
+end
+
+-- 初始化页面
+function tsb_devinfo_page.init(params)
+    tsb_devinfo_page.create_ui()
+end
+
+-- 清理页面
+function tsb_devinfo_page.cleanup()
+    if main_container then
+        main_container:destroy()
+        main_container = nil
+    end
+end
+
+return tsb_devinfo_page

+ 143 - 0
script/tsb_ui/tsb_devlog_page.lua

@@ -0,0 +1,143 @@
+--[[
+@module  tsb_devlog_page
+@summary 设备日志页面
+@version 1.0
+@date    2026.03.04
+@author  李一玮
+@usage
+本文件是设备日志页面,展示设备的日志信息。
+]]
+
+local tsb_devlog_page = {}
+
+-- 页面UI元素
+local main_container = nil
+local common_ui = require("tsb_common_page")
+
+-- 创建UI
+function tsb_devlog_page.create_ui()
+    main_container = airui.container({
+        x = 0,
+        y = 0,
+        w = 480,
+        h = 320,
+        color = 0xF5F5F5,
+    })
+
+    --------------------- 标题栏 ------------------------
+    local title_bar = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 0,
+        w = 480,
+        h = 30,
+        color = 0x82B1FF,
+    })
+
+    airui.label({
+        parent = title_bar,
+        text = "日志监测界面",
+        x = 190,
+        y = 8,
+        w = 200,
+        h = 20,
+        font_size = 16,
+        color = 0xFFFFFF,
+    })
+
+    -- 标题栏公共信息展示
+    common_ui.add_battery_display(title_bar)
+    common_ui.create_back_button(title_bar, tsb_devlog_page.cleanup)
+    ---------------------------------------------------
+
+    -- 滚动容器
+    local scroll_container = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 30,
+        w = 480,
+        h = 270,
+        color = 0xFFFFFF,
+    })
+
+    --------------------- 设备日志显示 ------------------------
+    local log_container = airui.container({
+        parent = scroll_container,
+        x = 0,
+        y = 50,
+        w = 480,
+        h = 215,
+        color = 0xFFFFFF,
+    })
+
+    -- 日志内容显示
+    local log_content = airui.textarea({
+        parent = log_container,
+        x = 5,
+        y = 5,
+        w = 470,
+        h = 205,
+        max_len = 10000,
+        text = "[2024-07-02 09:30:46] app start\n" ..
+               "[2024-07-02 09:30:47] init done\n" ..
+               "[2024-07-02 09:30:48] connect success\n" ..
+               "[2024-07-02 09:30:50] start monitor\n" ..
+               "[2024-07-02 09:31:00] detect device 1\n" ..
+               "[2024-07-02 09:31:10] detect device 2\n" ..
+               "[2024-07-02 09:31:20] upload success\n" ..
+               "[2024-07-02 09:31:30] system running\n" ..
+               "[2024-07-02 09:31:30] system status: normal\n",
+    })
+
+    --------------------- 控制按钮 ------------------------
+    -- 开始检测按钮
+    local start_btn = airui.button({
+        parent = scroll_container,
+        x = 10,
+        y = 10,
+        w = 100,
+        h = 35,
+        text = "开始检测",
+        stype = { bg_color = 0x2B6FF1,border_color = 0x2B6FF1, text_color = 0xFFFFFF, radius = 8 },
+        on_click = function(self)
+            log.info("devlog", "开始检测按钮被点击")
+        end
+    })
+
+    -- 清空按钮
+    local clear_btn = airui.button({
+        parent = scroll_container,
+        x = 120,
+        y = 10,
+        w = 80,
+        h = 35,
+        text = "清空",
+        on_click = function(self)
+            log.info("devlog", "清空按钮被点击")
+            -- 清空日志内容
+            log_content:set_text(" ")
+        end
+    })
+    ---------------------------------------------------
+
+    
+    ---------------------------------------------------
+
+    -- 底部信息
+    common_ui.create_status_bar(main_container)
+end
+
+-- 初始化页面
+function tsb_devlog_page.init(params)
+    tsb_devlog_page.create_ui()
+end
+
+-- 清理页面
+function tsb_devlog_page.cleanup()
+    if main_container then
+        main_container:destroy()
+        main_container = nil
+    end
+end
+
+return tsb_devlog_page

+ 335 - 0
script/tsb_ui/tsb_firm_page.lua

@@ -0,0 +1,335 @@
+--[[
+@module  tsb_firm_page
+@summary 固件下载页面
+@version 1.0
+@date    2026.03.05
+@author  李一玮
+@usage
+本文件是固件下载页面,展示固件下载的各种用法。
+]]
+
+local tsb_firm_page = {}
+
+-- 页面UI元素
+local main_container = nil
+local download_progress = 0
+local download_bar = nil
+local download_timer = nil
+local common_ui = require("tsb_common_page")
+
+
+-- 创建UI
+function tsb_firm_page.create_ui()
+    main_container = airui.container({
+        x = 0,
+        y = 0,
+        w = 480,
+        h = 320,
+        color = 0xF5F5F5,
+    })
+
+    --------------------- 标题栏 ------------------------
+    local title_bar = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 0,
+        w = 480,
+        h = 30,
+        color = 0x2196F3,
+    })
+
+    airui.label({
+        parent = title_bar,
+        text = "固件包下载",
+        x = 190,
+        y = 8,
+        w = 120,
+        h = 20,
+        font_size = 16,
+        color = 0xFFFFFF,
+    })
+
+
+    -- 标题栏公共信息展示
+    common_ui.add_battery_display(title_bar)
+    common_ui.create_back_button(title_bar, tsb_firm_page.cleanup)
+    ---------------------------------------------------
+
+    -- 滚动容器
+    local scroll_container = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 30,
+        w = 480,
+        h = 270,
+        color = 0xFFFFFF,
+    })
+
+    common_ui.add_battery_display(scroll_container)
+
+    --------------------- 第一行控制区 ------------------------
+    -- 设备类型标签
+    airui.label({
+        parent = scroll_container,
+        text = "设备类型:",
+        x = 10,
+        y = 18,
+        w = 80,
+        h = 30,
+        font_size = 16,
+    })
+
+    -- 设备类型下拉框
+    local device_type_dropdown = airui.dropdown({
+        parent = scroll_container,
+        x = 90,
+        y = 10,
+        w = 100,
+        h = 30,
+        options = {"0101", "0102", "0201", "0202", "0301", "0302", "0103", "0104", "0902", "0904"},
+        default_index = 0,
+        on_change = function(self,idx)
+            log.info("firm_device_type", "选择了设备类型:" .. self.options[idx + 1])
+        end
+    })
+
+    -- 固件类型标签
+    airui.label({
+        parent = scroll_container,
+        text = "固件类型:",
+        x = 230,
+        y = 18,
+        w = 80,
+        h = 30,
+        font_size = 16,
+    })
+
+    -- 固件类型下拉框
+    local firmware_type_dropdown = airui.dropdown({
+        parent = scroll_container,
+        x = 310,
+        y = 10,
+        w = 100,
+        h = 30,
+        options = {"产测", "app", "boot"},
+        default_index = 1, -- 默认选择app
+        on_change = function(self,idx)
+            log.info("firm_type", "选择了固件类型:" .. self.options[idx + 1])
+        end
+    })
+    ---------------------------------------------------
+
+    --------------------- 第二行控制区 ------------------------
+    -- 先声明开关变量
+    local flash_package_switch
+    local upgrade_package_switch
+
+    -- 刷机包标签
+    airui.label({
+        parent = scroll_container,
+        text = "刷机包",
+        x = 10,
+        y = 57,
+        w = 60,
+        h = 30,
+        font_size = 16,
+    })
+
+    -- 刷机包开关
+    flash_package_switch = airui.switch({
+        parent = scroll_container,
+        x = 70,
+        y = 55,
+        w = 50,
+        h = 20,
+        checked = true,
+        on_change = function(self)
+            local checked = self:get_state()
+            log.info("刷机包开关", checked and "开启" or "关闭")
+            -- 互斥逻辑:如果刷机包开启,则关闭升级包
+            if checked and upgrade_package_switch then
+                upgrade_package_switch:set_state(false)
+            end
+        end
+    })
+
+    -- 升级包标签
+    airui.label({
+        parent = scroll_container,
+        text = "升级包",
+        x = 140,
+        y = 57,
+        w = 60,
+        h = 30,
+        font_size = 16,
+    })
+
+    -- 升级包开关
+    upgrade_package_switch = airui.switch({
+        parent = scroll_container,
+        x = 200,
+        y = 55,
+        w = 50,
+        h = 20,
+        checked = false,
+        on_change = function(self)
+            local checked = self:get_state()
+            log.info("升级包开关", checked and "开启" or "关闭")
+            -- 互斥逻辑:如果升级包开启,则关闭刷机包
+            if checked and flash_package_switch then
+                flash_package_switch:set_state(false)
+            end
+        end
+    })
+    ---------------------------------------------------
+
+    --------------------- 第三行控制区 ------------------------
+    -- 固件版本标签
+    airui.label({
+        parent = scroll_container,
+        text = "固件版本",
+        x = 10,
+        y = 97,
+        w = 80,
+        h = 30,
+        font_size = 16,
+    })
+
+    -- 固件版本下拉框
+    local firmware_version_dropdown = airui.dropdown({
+        parent = scroll_container,
+        x = 90,
+        y = 90,
+        w = 150,
+        h = 30,
+        options = {"V1.0.0", "V1.1.0", "V2.0.0"}, -- 示例版本,实际可根据需要修改
+        default_index = 0,
+        on_change = function(self,idx)
+            log.info("firm_version", "选择了固件版本:" .. self.options[idx + 1])
+        end
+    })
+    ---------------------------------------------------
+
+    --------------------- 操作按钮区 -----------------------
+    -- 下载进度条
+    download_bar = airui.bar({
+        parent = scroll_container,
+        x = 5,
+        y = 240,
+        w = 470,
+        h = 20,
+        value = 0,
+        min = 0,
+        max = 100,
+        radius = 5,
+        indicator_color = 0x2196F3,
+        show_progress_text = true,
+        progress_text_format = "%d%%",
+    })
+
+    -- 下载固件包按钮
+    local download_btn = airui.button({
+        parent = scroll_container,
+        x = 170,
+        y = 140,
+        w = 150,
+        h = 40,
+        text = "下载固件包",
+        stype = { bg_color = 0x2B6FF1,border_color = 0x2B6FF1, text_color = 0xFFFFFF, radius = 8 },
+        on_click = function(self)
+            log.info("firm_download", "下载固件包按钮被点击")
+            -- 重置进度
+            download_bar:set_value(0, true)
+            
+            -- 开始下载动画
+            if download_timer then
+                sys.timerStop(download_timer)
+                download_timer = nil
+            end
+            
+            download_timer = sys.timerLoopStart(function()
+                local current = download_bar:get_value()
+                if current >= 100 then
+                    current = 0
+                else
+                    current = current + 5
+                end
+                download_bar:set_value(current, true) -- 启用动画
+                
+                if current >= 100 then
+                    sys.timerStop(download_timer)
+                    download_timer = nil
+                    -- 下载完成,显示消息框
+                    local msg = airui.msgbox({
+                        title = "系统提示",
+                        text = "下载完成",
+                        buttons = { "确定" },
+                        on_action = function(self, label)
+                            log.info("firm_download", "下载完成消息框被点击: " .. label)
+                            self:hide()
+                            download_bar:set_value(0, true)
+                        end
+                    })
+                    msg:show()
+                end
+            end, 200)
+        end
+    })
+
+    -- 去刷机按钮
+    local flash_btn = airui.button({
+        parent = scroll_container,
+        x = 30,
+        y = 190,
+        w = 150,
+        h = 40,
+        text = "去刷机",
+        on_click = function(self)
+            log.info("firm_flash_btn", "去刷机按钮被点击")
+            -- 跳转到刷机页面
+            --tsb_firm_page.cleanup()
+            show_page("tsb_reflash_page")
+        end
+    })
+
+    -- 去升级按钮
+    local upgrade_btn = airui.button({
+        parent = scroll_container,
+        x = 300,
+        y = 190,
+        w = 150,
+        h = 40,
+        text = "去升级",
+        on_click = function(self)
+            log.info("firm_upgrade_btn", "去升级按钮被点击")
+            -- 跳转到升级页面
+            --tsb_firm_page.cleanup()
+            show_page("tsb_upgrade_page")
+        end
+    })
+    ---------------------------------------------------
+
+    
+
+    -- 底部信息
+    common_ui.create_status_bar(main_container)
+end
+
+-- 初始化页面
+function tsb_firm_page.init(params)
+    tsb_firm_page.create_ui()
+end
+
+-- 清理页面
+function tsb_firm_page.cleanup()
+    if download_timer then
+        sys.timerStop(download_timer)
+        download_timer = nil
+    end
+    if main_container then
+        main_container:destroy()
+        main_container = nil
+    end
+end
+
+return tsb_firm_page

+ 511 - 0
script/tsb_ui/tsb_game_page.lua

@@ -0,0 +1,511 @@
+--[[
+@module  game_page
+@summary 俄罗斯方块游戏演示页面
+@version 1.0
+@date    2026.02.05
+@author  江访
+@usage
+本文件是俄罗斯方块游戏的演示页面。
+]]
+
+local game_page = {}
+
+-- 屏幕与棋盘参数
+local SCREEN_W, SCREEN_H = 480, 320 -- 横屏:480宽,320高
+local common_ui = require("tsb_common_page")
+local GRID_W, GRID_H = 15, 10   
+local CELL_SIZE = 20                -- 每格像素大小(20px)
+local BOARD_W = GRID_W * CELL_SIZE
+local BOARD_H = GRID_H * CELL_SIZE
+local BOARD_X = (SCREEN_W - BOARD_W) // 2 -- 水平居中
+local BOARD_Y = 100                        -- 棋盘左上角Y坐标
+
+-- 7 种俄罗斯方块颜色(RGB565格式)
+local COLORS = {
+    0x07FF, -- I (青色)
+    0x001F, -- J (蓝色)
+    0xFD20, -- L (橙色)
+    0xFFE0, -- O (黄色)
+    0x07E0, -- S (绿色)
+    0x8010, -- T (紫色)
+    0xF800, -- Z (红色)
+}
+
+-- 7 种形状(1 表示方块)
+local SHAPES = {
+    { { 1, 1, 1, 1 } },           -- I
+    { { 1, 0, 0 },   { 1, 1, 1 } }, -- J
+    { { 0, 0, 1 },   { 1, 1, 1 } }, -- L
+    { { 1, 1 },      { 1, 1 } },  -- O
+    { { 0, 1, 1 },   { 1, 1, 0 } }, -- S
+    { { 0, 1, 0 },   { 1, 1, 1 } }, -- T
+    { { 1, 1, 0 },   { 0, 1, 1 } }, -- Z
+}
+
+-- 游戏状态
+local grid     -- grid[y][x] = nil 或 颜色下标
+local curPiece -- {x, y, shape, color}
+local score = 0
+local gameOver = false
+local gameTimer = nil
+
+-- UI 控件
+local main_container
+local scoreLabel
+local statusLabel
+local leftBtn, rightBtn, rotateBtn, downBtn, restartBtn
+
+----------------------------------------------------------------
+-- 工具函数:网格与方块
+----------------------------------------------------------------
+local function initGrid()
+    grid = {}
+    for y = 1, GRID_H do
+        grid[y] = {}
+        for x = 1, GRID_W do
+            grid[y][x] = nil
+        end
+    end
+end
+
+local function rotateShape(shape)
+    local h, w = #shape, #shape[1]
+    local res = {}
+    for x = 1, w do
+        res[x] = {}
+        for y = 1, h do
+            res[x][y] = shape[h - y + 1][x]
+        end
+    end
+    return res
+end
+
+local function newPiece()
+    local idx = math.random(1, #SHAPES)
+    local shp = SHAPES[idx]
+    local pw  = #shp[1]
+    local px  = math.floor(GRID_W / 2) - math.floor(pw / 2) + 1
+    curPiece  = {
+        x = px,
+        y = 1,
+        shape = shp,
+        color = idx,
+    }
+end
+
+local function eachBlock(piece, cb)
+    local shape = piece.shape
+    for j = 1, #shape do
+        for i = 1, #shape[j] do
+            if shape[j][i] == 1 then
+                cb(piece.x + i - 1, piece.y + j - 1)
+            end
+        end
+    end
+end
+
+local function validPosition(piece)
+    local ok = true
+    eachBlock(piece, function(x, y)
+        if x < 1 or x > GRID_W or y < 1 or y > GRID_H then
+            ok = false
+            return
+        end
+        if grid[y][x] ~= nil then
+            ok = false
+            return
+        end
+    end)
+    return ok
+end
+
+local function mergePiece()
+    if not curPiece then return end
+    eachBlock(curPiece, function(x, y)
+        if y >= 1 and y <= GRID_H and x >= 1 and x <= GRID_W then
+            grid[y][x] = curPiece.color
+        end
+    end)
+end
+
+-- 返回本次消掉的行数
+local function clearLines()
+    local cleared = 0
+    for y = GRID_H, 1, -1 do
+        local full = true
+        for x = 1, GRID_W do
+            if grid[y][x] == nil then
+                full = false
+                break
+            end
+        end
+        if full then
+            cleared = cleared + 1
+            -- 下移
+            for yy = y, 2, -1 do
+                grid[yy] = grid[yy - 1]
+            end
+            local row = {}
+            for x = 1, GRID_W do row[x] = nil end
+            grid[1] = row
+            y = y + 1
+        end
+    end
+    if cleared > 0 then
+        score = score + cleared * 100
+    end
+    return cleared
+end
+
+----------------------------------------------------------------
+-- 绘制函数:使用lcd.fill绘制棋盘
+----------------------------------------------------------------
+local function drawCell(x, y, color)
+    local cx = BOARD_X + (x - 1) * CELL_SIZE
+    local cy = BOARD_Y + (y - 1) * CELL_SIZE
+    lcd.fill(cx, cy, cx + CELL_SIZE - 2, cy + CELL_SIZE - 2, color)
+end
+
+local function drawBoard()
+    -- 绘制棋盘背景
+    lcd.fill(BOARD_X, BOARD_Y, BOARD_X + BOARD_W - 1, BOARD_Y + BOARD_H - 1, 0x1082) -- 深灰色背景
+
+    -- 绘制固定的方块
+    for y = 1, GRID_H do
+        for x = 1, GRID_W do
+            local fixed = grid[y][x]
+            if fixed then
+                drawCell(x, y, COLORS[fixed])
+            else
+                -- 绘制空单元格(带边框效果)
+                local cx = BOARD_X + (x - 1) * CELL_SIZE
+                local cy = BOARD_Y + (y - 1) * CELL_SIZE
+                lcd.fill(cx, cy, cx + CELL_SIZE - 2, cy + CELL_SIZE - 2, 0x0841)         -- 更深的灰色
+                lcd.fill(cx + 1, cy + 1, cx + CELL_SIZE - 3, cy + CELL_SIZE - 3, 0x18C3) -- 浅灰色内框
+            end
+        end
+    end
+
+    -- 绘制当前方块
+    if curPiece then
+        eachBlock(curPiece, function(x, y)
+            if y >= 1 and y <= GRID_H and x >= 1 and x <= GRID_W then
+                drawCell(x, y, COLORS[curPiece.color])
+            end
+        end)
+    end
+
+    -- 绘制棋盘边框
+    lcd.fill(BOARD_X - 2, BOARD_Y - 2, BOARD_X + BOARD_W + 1, BOARD_Y - 1, 0xFFFF)                 -- 上边框
+    lcd.fill(BOARD_X - 2, BOARD_Y + BOARD_H, BOARD_X + BOARD_W + 1, BOARD_Y + BOARD_H + 1, 0xFFFF) -- 下边框
+    lcd.fill(BOARD_X - 2, BOARD_Y - 2, BOARD_X - 1, BOARD_Y + BOARD_H + 1, 0xFFFF)                 -- 左边框
+    lcd.fill(BOARD_X + BOARD_W, BOARD_Y - 2, BOARD_X + BOARD_W + 1, BOARD_Y + BOARD_H + 1, 0xFFFF) -- 右边框
+end
+
+----------------------------------------------------------------
+-- UI更新函数
+----------------------------------------------------------------
+local function updateScoreLabel()
+    if scoreLabel then
+        scoreLabel:set_text("分数: " .. tostring(score))
+    end
+end
+
+local function updateStatusLabel(extra)
+    if not statusLabel then return end
+    if gameOver then
+        statusLabel:set_text("游戏结束! 点击重新开始")
+    else
+        if extra and extra ~= "" then
+            statusLabel:set_text("俄罗斯方块 | " .. extra)
+        else
+            statusLabel:set_text("俄罗斯方块 | 使用按钮游玩")
+        end
+    end
+end
+
+local function redrawAll(extraStatus)
+    updateScoreLabel()
+    updateStatusLabel(extraStatus)
+    drawBoard()
+end
+
+----------------------------------------------------------------
+-- 控制逻辑
+----------------------------------------------------------------
+local function stepDown()
+    if gameOver or not curPiece then return end
+    local test = {
+        x = curPiece.x,
+        y = curPiece.y + 1,
+        shape = curPiece.shape,
+        color = curPiece.color,
+    }
+    if validPosition(test) then
+        curPiece = test
+        redrawAll()
+        return
+    end
+
+    -- 碰到底或碰到已固定方块
+    mergePiece()
+    local cleared = clearLines()
+    newPiece()
+    if not validPosition(curPiece) then
+        gameOver = true
+        redrawAll("游戏结束!")
+        if gameTimer then
+            sys.timerStop(gameTimer)
+            gameTimer = nil
+        end
+    else
+        if cleared > 0 then
+            redrawAll("消除了 " .. cleared .. " 行!")
+        else
+            redrawAll()
+        end
+    end
+end
+
+local function moveLeft()
+    if gameOver or not curPiece then return end
+    local test = {
+        x = curPiece.x - 1,
+        y = curPiece.y,
+        shape = curPiece.shape,
+        color = curPiece.color,
+    }
+    if validPosition(test) then
+        curPiece = test
+        redrawAll()
+    end
+end
+
+local function moveRight()
+    if gameOver or not curPiece then return end
+    local test = {
+        x = curPiece.x + 1,
+        y = curPiece.y,
+        shape = curPiece.shape,
+        color = curPiece.color,
+    }
+    if validPosition(test) then
+        curPiece = test
+        redrawAll()
+    end
+end
+
+local function softDrop()
+    if gameOver or not curPiece then return end
+    local test = {
+        x = curPiece.x,
+        y = curPiece.y + 1,
+        shape = curPiece.shape,
+        color = curPiece.color,
+    }
+    if validPosition(test) then
+        curPiece = test
+        redrawAll()
+    end
+end
+
+local function rotatePiece()
+    if gameOver or not curPiece then return end
+    local newShape = rotateShape(curPiece.shape)
+    local test = {
+        x = curPiece.x,
+        y = curPiece.y,
+        shape = newShape,
+        color = curPiece.color,
+    }
+    if validPosition(test) then
+        curPiece = test
+        redrawAll("旋转")
+    end
+end
+
+local function restartGame()
+    if gameTimer then
+        sys.timerStop(gameTimer)
+    end
+    
+    score = 0
+    gameOver = false
+    initGrid()
+    newPiece()
+    redrawAll("重新开始,分数: 0")
+    
+    -- 重新启动定时器
+    gameTimer = sys.timerLoopStart(stepDown, 400)
+end
+
+----------------------------------------------------------------
+-- 创建游戏UI
+----------------------------------------------------------------
+function game_page.create_ui()
+    -- 创建主容器
+    main_container = airui.container({
+        x = 0,
+        y = 0,
+        w = SCREEN_W,
+        h = SCREEN_H,
+        color = 0x0000, -- 黑色背景
+    })
+
+    -- 标题栏
+    local title_bar = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 0,
+        w = SCREEN_W,
+        h = 50,
+        color = 0x1E3A8A, -- 深蓝色
+    })
+
+    -- 游戏标题
+    airui.label({
+        parent = title_bar,
+        text = "俄罗斯方块",
+        x = 80,
+        y = 15,
+        w = 160,
+        h = 20,
+    })
+    
+    local battery_label = common_ui.add_battery_display(title_bar)
+    
+    -- 返回按钮
+    common_ui.create_back_button(title_bar, game_page.cleanup)
+
+    -- 分数标签
+    scoreLabel = airui.label({
+        parent = main_container,
+        text = "分数: 0",
+        x = 220,
+        y = 70,
+        w = 150,
+        h = 20,
+    })
+
+    -- 状态标签
+    statusLabel = airui.label({
+        parent = main_container,
+        text = "俄罗斯方块 | 使用按钮游玩",
+        x = 10,
+        y = 70,
+        w = SCREEN_W - 20,
+        h = 20,
+    })
+
+    -- 控制按钮区域
+    local btnY = BOARD_Y + BOARD_H + 10
+    local btnW, btnH, gap = 70, 30, 10
+
+    -- 计算按钮起始X坐标(居中显示)
+    local totalBtnWidth = btnW * 3 + gap * 2 -- 第一行3个按钮
+    local btnStartX = (SCREEN_W - totalBtnWidth) // 2
+
+    -- 第一行按钮
+    leftBtn = airui.button({
+        parent   = main_container,
+        x        = btnStartX,
+        y        = btnY,
+        w        = btnW,
+        h        = btnH,
+        text     = "左移",
+        on_click = function() moveLeft() end,
+    })
+
+    rightBtn = airui.button({
+        parent   = main_container,
+        x        = btnStartX + btnW + gap,
+        y        = btnY,
+        w        = btnW,
+        h        = btnH,
+        text     = "右移",
+        on_click = function() moveRight() end,
+    })
+
+    rotateBtn = airui.button({
+        parent   = main_container,
+        x        = btnStartX + 2 * (btnW + gap),
+        y        = btnY,
+        w        = btnW,
+        h        = btnH,
+        text     = "旋转",
+        on_click = function() rotatePiece() end,
+    })
+
+    -- 第二行按钮
+    btnY = btnY + btnH + gap
+
+    downBtn = airui.button({
+        parent   = main_container,
+        x        = btnStartX,
+        y        = btnY,
+        w        = btnW * 2 + gap, -- 稍宽一点
+        h        = btnH,
+        text     = "下落",
+        on_click = function() softDrop() end,
+    })
+
+    restartBtn = airui.button({
+        parent   = main_container,
+        x        = btnStartX + btnW * 2 + gap * 2,
+        y        = btnY,
+        w        = btnW,
+        h        = btnH,
+        text     = "重新开始",
+        on_click = function() restartGame() end,
+    })
+end
+
+----------------------------------------------------------------
+-- 页面生命周期函数
+----------------------------------------------------------------
+function game_page.init(params)
+    math.randomseed(os.time())
+    
+    -- 初始化游戏状态
+    initGrid()
+    newPiece()
+    
+    -- 创建UI
+    game_page.create_ui()
+    
+    -- 初始绘制
+    redrawAll("准备开始!")
+    
+    -- 启动定时器
+    gameTimer = sys.timerLoopStart(stepDown, 400)
+end
+
+function game_page.cleanup()
+    -- 停止定时器
+    if gameTimer then
+        sys.timerStop(gameTimer)
+        gameTimer = nil
+    end
+    
+    -- 清理UI
+    if main_container then
+        main_container:destroy()
+        main_container = nil
+    end
+    
+    -- 重置游戏状态
+    grid = nil
+    curPiece = nil
+    score = 0
+    gameOver = false
+    
+    leftBtn = nil
+    rightBtn = nil
+    rotateBtn = nil
+    downBtn = nil
+    restartBtn = nil
+    scoreLabel = nil
+    statusLabel = nil
+end
+
+return game_page

+ 93 - 0
script/tsb_ui/tsb_help_page.lua

@@ -0,0 +1,93 @@
+--[[
+@module  tsb_help_page         
+@summary 帮助页面
+@version 1.0
+@date    2026.03.17
+@author  李一玮
+@usage
+本文件是帮助页面,展示帮助的各种用法。
+]]
+
+local tsb_help_page  = {}
+
+-- 页面UI元素
+local main_container = nil
+local common_ui = require("tsb_common_page")
+
+-- 创建UI
+function tsb_help_page .create_ui()
+    main_container = airui.container({
+        x = 0,
+        y = 0,
+        w = 480,
+        h = 320,
+        color = 0xF5F5F5,
+    })
+
+    --------------------- 标题栏 ------------------------
+    local title_bar = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 0,
+        w = 480,
+        h = 30,
+        color = 0xCE93D8,
+    })
+
+    airui.label({
+        parent = title_bar,
+        text = "帮助界面",
+        x = 190,
+        y = 8,
+        w = 200,
+        h = 20,
+        font_size = 16,
+        color = 0xFFFFFF,
+    })
+
+    -- 标题栏公共信息展示
+    common_ui.add_battery_display(title_bar)
+    common_ui.create_back_button(title_bar, tsb_help_page .cleanup)
+
+    -- 滚动容器
+    local scroll_container = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 30,
+        w = 480,
+        h = 290,
+        color = 0xFFFFFF,
+    })
+
+    local hardware_img = airui.image({
+        parent = scroll_container,
+        x = 0,
+        y = 0,
+        w = 480,
+        h = 290,                    
+        src = "/luadb/hardware.png",
+        zoom = 145,
+        opacity = 255,
+    })
+
+    ---------------------------------------------------
+
+    -- 底部信息
+    --common_ui.create_status_bar(main_container)
+end
+
+-- 初始化页面
+function tsb_help_page .init(params)
+    tsb_help_page .create_ui()
+end
+
+-- 清理页面
+function tsb_help_page .cleanup()
+    common_ui.cleanup()
+    if main_container then
+        main_container:destroy()
+        main_container = nil
+    end
+end
+
+return tsb_help_page 

+ 306 - 0
script/tsb_ui/tsb_home_page.lua

@@ -0,0 +1,306 @@
+--[[
+@module  tsb_home_page
+@summary 调试宝主页
+@version 1.0
+@date    2026.03.04
+@author  李一玮
+@usage
+本文件是调试宝的主页,提供所有功能演示的入口。
+]]
+
+local tsb_home_page = {}
+
+-- 页面UI元素
+local main_container = nil
+local scroll_container = nil
+local common_ui = require("tsb_common_page")
+
+_G.current_tab = _G.current_tab or 0
+
+-- 全局变量:存储当前是否为游客模式
+local is_visitor_mode = false
+
+-- 选项卡分类
+local tab_names = {"常用功能", "目标设备监测", "目标设备管理", "本机设备管理"}
+
+-- 演示模块列表(按选项卡分类)
+local demos_by_tab = {
+    -- 常用功能
+    {
+        {name = "报税口", src = "/luadb/bsk2.png", page = "tsb_bsk_page", color = 0x007AFF},
+        {name = "液位仪", src = "/luadb/ywy.png", page = "tsb_ywy_page", color = 0x4CAF50},
+        {name = "提枪信号", src = "/luadb/tq.png", page = "tsb_tq_page", color = 0xF44336},
+        {name = "编码器", src = "/luadb/bmq.png", page = "tsb_bmq_page", color = 0xFF9800},
+        {name = "简易示波器", src = "/luadb/sbq.png", page = "tsb_waveform_page", color = 0xFFAB91},
+        {name = "帮助", src = "/luadb/help.png", page = "tsb_help_page", color = 0xCE93D8},
+    },
+    -- 目标设备监测
+    {
+        {name = "日志监测", src = "/luadb/rzjc.png", page = "tsb_devlog_page", color = 0x82B1FF},
+        {name = "485监测", src = "/luadb/4851.png", page = "tsb_485log_page", color = 0xA5D6A7},
+        {name = "232监测", src = "/luadb/232.png", page = "tsb_232log_page", color = 0xFFCCBC},
+        {name = "射频局域网监测", src = "/luadb/LoRa.png", page = "tsb_lora_page", color = 0xFFE082},
+        
+    },
+    -- 目标设备管理
+    {
+        {name = "固件包下载", src = "/luadb/gjb.png", page = "tsb_firm_page", color = 0x2196F3},
+        {name = "升级", src = "/luadb/upgrade.png", page = "tsb_upgrade_page", color = 0x66BB6A},
+        {name = "刷机", src = "/luadb/sj.png", page = "tsb_reflash_page", color = 0xF4511E},
+        {name = "MQTT配置", src = "/luadb/MQTT.png", page = "tsb_mqtt_page", color = 0xFFB74D},
+        {name = "信道切换", src = "/luadb/xd4.png", page = "tsb_channel_page", color = 0x7E57C2},
+    },
+    -- 本机设备管理
+    {
+        {name = "本机信息", src = "/luadb/bjxx2.png", page = "tsb_devinfo_page", color = 0xB3E5FC},
+        {name = "本机升级", src = "/luadb/up1.png", page = "tsb_update_page", color = 0xA5D6A7},
+        {name = "本机日志", src = "/luadb/bjrz1.png", page = "tsb_log_page", color = 0xFFCCBC},
+        {name = "亮度管理", src = "/luadb/light.png", page = "tsb_light_page", color = 0xF2E2C5},
+        {name = "网络设置", src = "/luadb/wlan3.png", page = "tsb_wlan_page", color = 0xCE93D8},
+    }
+}
+
+-- 游客模式演示模块列表(按选项卡分类)
+local demos_by_tab_visitor = {
+    -- 常用功能(全部保留)
+    {
+        {name = "报税口", src = "/luadb/bsk2.png", page = "tsb_bsk_page", color = 0x007AFF},
+        {name = "液位仪", src = "/luadb/ywy.png", page = "tsb_ywy_page", color = 0x4CAF50},
+        {name = "提枪信号", src = "/luadb/tq.png", page = "tsb_tq_page", color = 0xF44336},
+        {name = "编码器", src = "/luadb/bmq.png", page = "tsb_bmq_page", color = 0xFF9800},
+        {name = "简易示波器", src = "/luadb/sbq.png", page = "tsb_waveform_page", color = 0xFFAB91},
+        {name = "帮助", src = "/luadb/help.png", page = "tsb_help_page", color = 0xCE93D8},
+    },
+    -- 目标设备监测(只保留485监测)
+    {
+        {name = "485监测", src = "/luadb/4851.png", page = "tsb_485log_page", color = 0xA5D6A7},
+    },
+    -- 目标设备管理(全部隐藏)
+    {},
+    -- 本机设备管理(只保留本机信息和亮度管理)
+    {
+        {name = "本机信息", src = "/luadb/bjxx2.png", page = "tsb_devinfo_page", color = 0xB3E5FC},
+        {name = "亮度管理", src = "/luadb/light.png", page = "tsb_shutdown_page", color = 0xFFF4E2},
+    }
+}
+
+-- 创建主页UI
+function tsb_home_page.create_ui()
+    -- 创建主容器
+    main_container = airui.container({
+        x = 0,
+        y = 0,
+        w = 480,
+        h = 320,
+        color = 0xF8F9FA,
+    })
+
+    -- 标题栏
+    local title_bar = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 0,
+        w = 480,
+        h = 30,
+        color = 0x2E6EF4,
+    })
+
+    local battery_label = common_ui.add_battery_display(title_bar)
+
+    airui.label({
+        parent = title_bar,
+        text = "主界面",
+        x = 210,
+        y = 8,
+        w = 80,
+        h = 20,
+        font_size = 16,
+        color = 0xFFFFFF,
+    })
+
+    -- 返回按钮(仅首页的返回按钮没有调用common_page中的函数)
+    -- local back_btn = airui.button({
+    --     parent = title_bar,
+    --     x = 10,
+    --     y = 3,
+    --     w = 45,
+    --     h = 25,
+    --     text = "返回",
+        -- on_click = function()
+        --     tsb_home_page.cleanup()
+        --     go_back()
+        -- end
+    -- })
+
+    local back_img = airui.image({
+        parent = parent,
+        x = 5,
+        y = 4,
+        w = 20,
+        h = 25,                    
+        src = "/luadb/back1.png",
+        zoom = 256,
+        opacity = 255,
+        on_click = function()
+            tsb_home_page.cleanup()
+            go_back()
+        end
+    })
+
+    local back_label = airui.label({
+        parent = parent,
+        text = "返回",
+        x = 22,
+        y = 9,
+        w = 45,
+        h = 20,
+        font_size = 15,
+        color = 0xFFFFFF,
+        on_click = function()
+            tsb_home_page.cleanup()
+            go_back()
+        end
+    })
+
+    local person_img = airui.image({
+        parent = title_bar,
+        x = 70,
+        y = 3,
+        w = 20,
+        h = 25,                    
+        src = "/luadb/person3.png",
+        zoom = 170,
+        opacity = 255,
+    })
+
+    local person_msg = airui.label({
+        parent = title_bar,
+        text = is_visitor_mode and "游客模式" or "lyw...(管理员)",
+        x = 95,
+        y = 8,
+        w = 100,
+        h = 20,
+        font_size = 14,
+        color = 0xFFFFFF,
+    })
+
+    -- 滚动容器
+    scroll_container = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 30,
+        w = 480,
+        h = 270,
+        color = 0xF8F9FA,
+    })
+
+    -- 创建选项卡组件
+    local tabview = airui.tabview({
+        parent = scroll_container,
+        x = 0,
+        y = 0,
+        w = 480,
+        h = 270,
+        tabs = tab_names,
+        active = _G.current_tab,
+        page_style = {
+            tabbar_size = 20,
+            pad = { method = airui.TABVIEW_PAD_ALL, value = 5 },
+            bg_opa = 200, -- 设置背景透明度,0-255
+        },
+    })
+
+    -- 为每个选项卡添加内容
+    local demos_list = is_visitor_mode and demos_by_tab_visitor or demos_by_tab
+    for i, demos in ipairs(demos_list) do
+        local tab_content = tabview:get_content(i - 1)
+        if tab_content then
+            -- 创建网格布局的演示按钮
+            local button_width = 150
+            local button_height = 80
+            local columns = 3
+            local padding = 5
+            local y_offset = 10
+            
+            for j, demo in ipairs(demos) do
+                local col = (j - 1) % columns
+                local row = math.floor((j - 1) / columns)
+                
+                local x = padding + col * (button_width + padding)
+                local y = y_offset + row * (button_height + padding)
+                
+                -- 创建按钮容器(卡片样式)
+                local card = airui.container({
+                    parent = tab_content,
+                    x = x,
+                    y = y,
+                    w = button_width,
+                    h = button_height,
+                    color = demo.color,
+                    radius = 8,
+                })
+                
+                -- 图标或图片
+                if demo.src then
+                    -- 使用图片
+                    airui.image({
+                        parent = card,
+                        x = 5,
+                        y = 7,
+                        w = 50,
+                        h = 50,          
+                        src = demo.src,
+                        zoom = 200,
+                        opacity = 255,
+                    })
+                elseif demo.icon then
+                    -- 使用图标
+                    airui.label({
+                        parent = card,
+                        text = demo.icon,
+                        x = 15,
+                        y = 20,
+                        w = 40,
+                        h = 40,
+                        font_size = 24, -- 增大图标大小
+                    })
+                end
+                
+                -- 演示名称标签
+                airui.label({
+                    parent = card,
+                    text = demo.name,
+                    x = 50,
+                    y = 25,
+                    w = button_width - 60,
+                    h = 40,
+                    font_size = 14, -- 调整字体大小
+                    on_click = function()
+                        _G.current_tab = i - 1
+                        _G.show_page(demo.page)
+                    end
+                })
+            end
+        end
+    end
+
+    -- 底部状态栏
+    common_ui.create_status_bar(main_container)
+end
+
+-- 初始化页面
+function tsb_home_page.init(params)
+    -- 检查是否为游客模式
+    is_visitor_mode = params and params.visitor_mode or false
+    log.info("tsb_home_page", "初始化页面,游客模式:", is_visitor_mode)
+    tsb_home_page.create_ui()
+end
+
+-- 清理页面
+function tsb_home_page.cleanup()
+    -- 清理UI元素
+    main_container = nil
+    scroll_container = nil
+end
+
+return tsb_home_page

+ 148 - 0
script/tsb_ui/tsb_light_page.lua

@@ -0,0 +1,148 @@
+--[[
+@module  tsb_light_page
+@summary 亮度演示页面
+@version 1.0
+@date    2026.03.04
+@author  李一玮
+@usage
+本文件是亮度演示页面,展示亮度的各种用法。
+]]
+
+local tsb_light_page = {}
+
+-- 页面UI元素
+local main_container = nil
+local common_ui = require("tsb_common_page")
+
+-- 创建UI
+function tsb_light_page.create_ui()
+    main_container = airui.container({
+        x = 0,
+        y = 0,
+        w = 480,
+        h = 320,
+        color = 0xF5F5F5,
+    })
+
+    --------------------- 标题栏 ------------------------
+    local title_bar = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 0,
+        w = 480,
+        h = 30,
+        color = 0xF2E2C5,
+    })
+
+    airui.label({
+        parent = title_bar,
+        text = "亮度管理",
+        x = 190,
+        y = 8,
+        w = 100,
+        h = 20,
+        font_size = 16,
+        color = 0xFFFFFF,
+    })
+
+    -- 标题栏公共信息展示
+    common_ui.add_battery_display(title_bar)
+    common_ui.create_back_button(title_bar, tsb_light_page.cleanup)
+    ---------------------------------------------------
+
+    -- 滚动容器
+    local scroll_container = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 30,
+        w = 480,
+        h = 270,
+        color = 0xFFFFFF,
+    })
+
+    --------------------- 屏幕亮度控制 ------------------------
+    -- 亮度标签
+    airui.label({
+        parent = scroll_container,
+        text = "屏幕亮度控制",
+        x = 180,
+        y = 50,
+        w = 100,
+        h = 30,
+        font_size = 16,
+    })
+
+    -- 亮度进度条
+    local brightness_bar = airui.bar({
+        parent = scroll_container,
+        x = 20,
+        y = 90,
+        w = 440,
+        h = 20,
+        value = 50,
+        min = 10,
+        max = 100,
+        radius = 5,
+        show_progress_text = true,
+        indicator_color = 0x2196F3,
+        progress_text_format = "%d%%",
+    })
+
+    -- 亮度控制按钮
+    -- 降低亮度按钮
+    local decrease_brightness_btn = airui.button({
+        parent = scroll_container,
+        x = 100,
+        y = 140,
+        w = 110,
+        h = 40,
+        text = "降低亮度",
+        on_click = function(self)
+            local current = brightness_bar:get_value()
+            if current > 10 then
+                current = current - 10
+                brightness_bar:set_value(current, true)
+                brightness_value_label:set_text(current .. "%")
+                log.info("set_brightness", "亮度降低到:" .. current .. "%")
+            end
+        end
+    })
+
+    -- 提升亮度按钮
+    local increase_brightness_btn = airui.button({
+        parent = scroll_container,
+        x = 280,
+        y = 140,
+        w = 110,
+        h = 40,
+        text = "提升亮度",
+        on_click = function(self)
+            local current = brightness_bar:get_value()
+            if current < 100 then
+                current = current + 10
+                brightness_bar:set_value(current, true)
+                brightness_value_label:set_text(current .. "%")
+                log.info("set_brightness", "亮度提升到:" .. current .. "%")
+            end
+        end
+    })
+    ---------------------------------------------------
+
+    -- 底部信息
+    common_ui.create_status_bar(main_container)
+end
+
+-- 初始化页面
+function tsb_light_page.init(params)
+    tsb_light_page.create_ui()
+end
+
+-- 清理页面
+function tsb_light_page.cleanup()
+    if main_container then
+        main_container:destroy()
+        main_container = nil
+    end
+end
+
+return tsb_light_page

+ 143 - 0
script/tsb_ui/tsb_log_page.lua

@@ -0,0 +1,143 @@
+--[[
+@module  tsb_log_page
+@summary 本机日志页面
+@version 1.0
+@date    2026.03.04
+@author  李一玮
+@usage
+本文件是设备日志页面,展示设备的日志信息。
+]]
+
+local tsb_log_page = {}
+
+-- 页面UI元素
+local main_container = nil
+local common_ui = require("tsb_common_page")
+
+-- 创建UI
+function tsb_log_page.create_ui()
+    main_container = airui.container({
+        x = 0,
+        y = 0,
+        w = 480,
+        h = 320,
+        color = 0xF5F5F5,
+    })
+
+    --------------------- 标题栏 ------------------------
+    local title_bar = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 0,
+        w = 480,
+        h = 30,
+        color = 0xFFCCBC,
+    })
+
+    airui.label({
+        parent = title_bar,
+        text = "本机日志",
+        x = 190,
+        y = 8,
+        w = 200,
+        h = 20,
+        font_size = 16,
+        color = 0xFFFFFF,
+    })
+
+    -- 标题栏公共信息展示
+    common_ui.add_battery_display(title_bar)
+    common_ui.create_back_button(title_bar, tsb_log_page.cleanup)
+    ---------------------------------------------------
+
+    -- 滚动容器
+    local scroll_container = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 30,
+        w = 480,
+        h = 270,
+        color = 0xFFFFFF,
+    })
+
+    --------------------- 设备日志显示 ------------------------
+    local log_container = airui.container({
+        parent = scroll_container,
+        x = 0,
+        y = 50,
+        w = 480,
+        h = 215,
+        color = 0xFFFFFF,
+    })
+
+    -- 日志内容显示
+    local log_content = airui.textarea({
+        parent = log_container,
+        x = 5,
+        y = 5,
+        w = 470,
+        h = 205,
+        max_len = 10000,
+        text = "[2024-07-02 09:30:46] app start\n" ..
+               "[2024-07-02 09:30:47] init done\n" ..
+               "[2024-07-02 09:30:48] connect success\n" ..
+               "[2024-07-02 09:30:50] start monitor\n" ..
+               "[2024-07-02 09:31:00] detect device 1\n" ..
+               "[2024-07-02 09:31:10] detect device 2\n" ..
+               "[2024-07-02 09:31:20] upload success\n" ..
+               "[2024-07-02 09:31:30] system running\n" ..
+               "[2024-07-02 09:31:30] system status: normal\n",
+    })
+
+    --------------------- 控制按钮 ------------------------
+    -- 开始检测按钮
+    local start_btn = airui.button({
+        parent = scroll_container,
+        x = 10,
+        y = 10,
+        w = 120,
+        h = 35,
+        text = "查看本机日志",
+        --stype = { bg_color = 0x2B6FF1,border_color = 0x2B6FF1, text_color = 0xFFFFFF, radius = 8 },
+        on_click = function(self)
+            log.info("devlog", "开始检测按钮被点击")
+        end
+    })
+
+    -- 清空按钮
+    -- local clear_btn = airui.button({
+    --     parent = scroll_container,
+    --     x = 120,
+    --     y = 10,
+    --     w = 80,
+    --     h = 35,
+    --     text = "清空",
+    --     on_click = function(self)
+    --         log.info("devlog", "清空按钮被点击")
+    --         -- 清空日志内容
+    --         log_content:set_text(" ")
+    --     end
+    -- })
+    ---------------------------------------------------
+
+    
+    ---------------------------------------------------
+
+    -- 底部信息
+    common_ui.create_status_bar(main_container)
+end
+
+-- 初始化页面
+function tsb_log_page.init(params)
+    tsb_log_page.create_ui()
+end
+
+-- 清理页面
+function tsb_log_page.cleanup()
+    if main_container then
+        main_container:destroy()
+        main_container = nil
+    end
+end
+
+return tsb_log_page

+ 241 - 0
script/tsb_ui/tsb_login_page.lua

@@ -0,0 +1,241 @@
+--[[
+@module     tsb_login_page
+@summary    调试宝登录页面
+@version    1.0
+@date       2026.03.04
+@author     李一玮
+@usage      本文件是调试宝登录页面,展示调试宝登录的各种用法。
+]]
+
+local tsb_login_page = {}
+
+----------------------------------------------------------------
+-- 页面UI元素
+----------------------------------------------------------------
+local main_container   = nil
+local scroll_container = nil
+local common_ui = require("tsb_common_page")
+
+----------------------------------------------------------------
+-- 创建UI
+----------------------------------------------------------------
+function tsb_login_page.create_ui()
+    main_container = airui.container({
+        parent = airui.screen,
+        x = 0,
+        y = 0,
+        w = 480,
+        h = 320,
+        color = 0xFFFFFF,
+    })
+ 
+    -- 标题栏
+    local title_bar = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 0,
+        w = 480,
+        h = 30,
+        color = 0x007AFF,
+    })
+
+
+    common_ui.add_battery_display(title_bar)
+
+    -- 滚动容器
+    scroll_container = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 30,
+        w = 480,
+        h = 290,
+        color = 0xFFFFFF,
+    })
+
+    common_ui.add_background_png(scroll_container)
+
+    local welcome_msg = airui.label({
+        parent = scroll_container,
+        text = "欢迎登录调试宝55号",
+        x = 170,
+        y = 70,
+        w = 180,
+        h = 30,
+        font_size = 16,
+        color = 0x000000
+    })
+
+    -- 注册虚拟键盘,先创建再在 textarea 配置里复用
+    local keyboard1 = airui.keyboard({
+        x = 0,
+        y = 0,
+        w = 480,
+        h = 160,                        -- x, y, 键盘默认打开ALIGN_BOTTOM_MID,位置从中下方开始计算
+        mode = "numeric",               -- 键盘模式,可选 "text"/"upper"/"lower"/"numeric"
+        auto_hide = true,               -- 自动隐藏键盘
+        bg_color = 0xf1f1f1,            -- 键盘背景颜色为灰色,可选,不设置则透明
+        on_commit = function()          -- 确认事件回调,只有在按下确认键时才会触发
+            log.info("keyboard", "commit")
+        end
+    })
+
+    local form_container = airui.container({
+        parent = scroll_container,
+        x = 135,
+        y = 100,
+        w = 220,
+        h = 140,
+        color = 0xFFFFFF,
+        color_opacity = 0,
+    })
+
+    -- 账号输入
+    airui.label({
+        parent = form_container,
+        text = "账号",
+        x = 0,
+        y = 7,
+        w = 60,
+        h = 30,
+        font_size = 14,
+        color = 0x6D7278
+    })
+
+    local name_input = airui.textarea({
+        parent = form_container,
+        x = 33,
+        y = 0,
+        w = 180,
+        h = 30,
+        text = "",
+        placeholder = "请输入账号",
+        max_len = 20,
+        keyboard = keyboard1
+    })
+
+    -- 密码输入
+    airui.label({
+        parent = form_container,
+        text = "密码",
+        x = 0,
+        y = 49,
+        w = 60,
+        h = 30,
+        font_size = 14,
+        color = 0x6D7278
+    })
+
+    local email_input = airui.textarea({
+        parent = form_container,
+        x = 33,
+        y = 42,
+        w = 180,
+        h = 30,
+        text = "",
+        placeholder = "请输入密码",
+        max_len = 50,
+        keyboard = keyboard1
+    })
+
+    -- 登录按钮
+    local submit_btn = airui.button({
+        parent = form_container,
+        x = 3,
+        y = 90,
+        w = 100,
+        h = 35,
+        text = "登录",
+        stype = { bg_color = 0x2B6FF1,border_color = 0x2B6FF1, text_color = 0xFFFFFF, radius = 8 },
+        on_click = function(self)
+            local name = name_input:get_text()
+            local email = email_input:get_text()
+            
+            _G.show_page("tsb_home_page")
+
+            -- if name == "" or email == "" then
+            --     local msg = airui.msgbox({
+            --         text = "请填写完整信息",
+            --         buttons = { "确定" },
+            --         on_action = function(self, label)
+            --             if label == "确定" then
+            --                 self:hide()
+            --             end
+            --         end
+            --     })
+            --     msg:show()
+            -- else
+            --     local msg = airui.msgbox({
+            --         text = "登录成功!\n姓名: " .. name .. "\n邮箱: " .. email,
+            --         buttons = { "确定" },
+            --         on_action = function(self, label)
+            --             if label == "确定" then
+            --                 self:hide()
+            --             end
+            --         end
+            --     })
+            --     msg:show()
+            -- end
+        end
+    })
+
+    local visitor_btn = airui.button({
+        parent = form_container,
+        x = 112,
+        y = 90,
+        w = 100,
+        h = 35,
+        text = "游客模式",
+        on_click = function(self)
+            log.info("button", "游客模式按钮被点击")
+            _G.show_page("tsb_home_page", { visitor_mode = true })
+        end
+    })
+
+    local basic_image = airui.image({
+        parent = scroll_container,
+        x = 11,
+        y = 6,
+        w = 120,
+        h = 40,                    
+        src = "/luadb/wbjw.png",
+        zoom = 100,
+        -- on_click = function(self)
+        --     log.info("image", "基本图片被点击")
+        --     local msg = airui.msgbox({
+        --         text = "基本图片被点击",
+        --         buttons = { "确定" },
+        --         timeout = 1500,
+        --         on_action = function(self, label)
+        --             self:hide()
+        --         end
+        --     })
+        --     msg:show()
+        -- end
+    })
+
+    _G.current_tab = 0
+
+    -- 底部信息栏
+    common_ui.create_status_bar(main_container)
+end
+
+----------------------------------------------------------------
+-- 初始化页面
+----------------------------------------------------------------
+function tsb_login_page.init(params)
+    tsb_login_page.create_ui()
+end
+
+----------------------------------------------------------------
+-- 清理页面
+----------------------------------------------------------------
+function tsb_login_page.cleanup()
+    if main_container then
+        main_container:destroy()
+        main_container   = nil
+        scroll_container = nil
+        --sys.timerStop(time1_id)
+    end
+end
+
+return tsb_login_page

+ 289 - 0
script/tsb_ui/tsb_lora_page.lua

@@ -0,0 +1,289 @@
+--[[
+@module  tsb_lora_page
+@summary 无线局域网监测演示页面
+@version 1.0
+@date    2026.03.04
+@author  李一玮
+@usage
+本文件是LORA信号检测演示页面,展示LORA信号的各种用法。
+]]
+
+local tsb_lora_page = {}
+
+-- 页面UI元素
+local main_container = nil
+local common_ui = require("tsb_common_page")
+
+-- 创建UI
+function tsb_lora_page.create_ui()
+    main_container = airui.container({
+        x = 0,
+        y = 0,
+        w = 480,
+        h = 320,
+        color = 0xF5F5F5,
+    })
+
+    --------------------- 标题栏 ------------------------
+    local title_bar = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 0,
+        w = 480,
+        h = 30,
+        color = 0xFFE082,
+    })
+
+    airui.label({
+        parent = title_bar,
+        text = "射频局域网监测",
+        x = 180,
+        y = 8,
+        w = 200,
+        h = 20,
+        font_size = 16,
+        color = 0xFFFFFF,
+    })
+
+    -- 标题栏公共信息展示
+    common_ui.add_battery_display(title_bar)
+    common_ui.create_back_button(title_bar, tsb_lora_page.cleanup)
+    ---------------------------------------------------
+
+
+
+    -- 滚动容器
+    local scroll_container = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 30,
+        w = 480,
+        h = 290,
+        color = 0xFFFFFF,
+    })
+
+    local keyboard1 = airui.keyboard({
+        x = 0,
+        y = 0,
+        w = 480,
+        h = 160,                        -- x, y, 键盘默认打开ALIGN_BOTTOM_MID,位置从中下方开始计算
+        mode = "numeric",               -- 键盘模式,可选 "text"/"upper"/"lower"/"numeric"
+        auto_hide = true,               -- 自动隐藏键盘
+        bg_color = 0xf1f1f1,            -- 键盘背景颜色为灰色,可选,不设置则透明
+        on_commit = function()          -- 确认事件回调,只有在按下确认键时才会触发
+            log.info("keyboard", "commit")
+        end
+    })
+
+    --------------------- 第一行控制区 ------------------------
+    -- 当前lora信道标签
+    airui.label({
+        parent = scroll_container,
+        text = "当前lora信道",
+        x = 10,
+        y = 12,
+        w = 100,
+        h = 30,
+        font_size = 14,
+    })
+
+    -- 当前lora信道值
+    local current_channel_label = airui.label({
+        parent = scroll_container,
+        text = "1",
+        x = 110,
+        y = 12,
+        w = 30,
+        h = 30,
+        font_size = 14,
+    })
+
+    -- 设置lora信道标签
+    airui.label({
+        parent = scroll_container,
+        text = "设置lora信道",
+        x = 130,
+        y = 12,
+        w = 100,
+        h = 30,
+        font_size = 14,
+    })
+
+    -- 设置lora信道下拉框
+    local channel_dropdown = airui.dropdown({
+        parent = scroll_container,
+        x = 230,
+        y = 7,
+        w = 80,
+        h = 30,
+        options = {"1", "2", "3", "4", "5", "6"},
+        default_index = 0, -- 默认选择1
+        on_change = function(self,idx)
+            log.info("lora_channel", "选择了信道:" .. self.options[idx + 1])
+        end
+    })
+
+    -- 开始监测按钮
+    local start_btn = airui.button({
+        parent = scroll_container,
+        x = 320,
+        y = 5,
+        w = 80,
+        h = 30,
+        text = "开始监测",
+        stype = { bg_color = 0x2B6FF1,border_color = 0x2B6FF1, text_color = 0xFFFFFF, radius = 8 },
+        on_click = function(self)
+            log.info("lora_monitor", "开始监测按钮被点击")
+        end
+    })
+
+    -- 重置按钮
+    local reset_btn = airui.button({
+        parent = scroll_container,
+        x = 405,
+        y = 5,
+        w = 60,
+        h = 30,
+        text = "重置",
+        on_click = function(self)
+            log.info("lora_monitor", "重置按钮被点击")
+        end
+    })
+    ---------------------------------------------------
+
+    --------------------- 第二行控制区 ------------------------
+    -- 监测设备类型标签
+    airui.label({
+        parent = scroll_container,
+        text = "监测设备类型",
+        x = 10,
+        y = 53,
+        w = 100,
+        h = 30,
+        font_size = 14,
+    })
+
+    -- 监测设备类型下拉框
+    local device_type_dropdown = airui.dropdown({
+        parent = scroll_container,
+        x = 110,
+        y = 45,
+        w = 100,
+        h = 30,
+        options = {"路由器", "连接器", "全部设备"},
+        default_index = 0, -- 默认选择路由器
+        on_change = function(self,idx)
+            log.info("device_type", "选择了设备类型:" .. self.options[idx + 1])
+        end
+    })
+
+    -- 连接器SN标签
+    airui.label({
+        parent = scroll_container,
+        text = "连接器SN",
+        x = 220,
+        y = 53,
+        w = 80,
+        h = 30,
+        font_size = 14,
+    })
+
+    -- 连接器SN输入框
+    local sn_input = airui.textarea({
+        parent = scroll_container,
+        x = 290,
+        y = 45,
+        w = 80,
+        h = 30,
+        text = "",
+        max_length = 5,
+        keyboard = keyboard1
+    })
+
+    -- 上传服务器标签
+    airui.label({
+        parent = scroll_container,
+        text = "上传",
+        x = 380,
+        y = 50,
+        w = 60,
+        h = 30,
+        font_size = 14,
+    })
+
+    -- 上传服务器开关
+    local upload_switch = airui.switch({
+        parent = scroll_container,
+        x = 415,
+        y = 45,
+        w = 50,
+        h = 25,
+        checked = true,
+        on_change = function(self, checked)
+            log.info("upload_switch", "上传服务器:" .. (checked and "开启" or "关闭"))
+        end
+    })
+    ---------------------------------------------------
+
+    --------------------- 表格区域 ------------------------
+    -- 创建表格
+    local lora_table = airui.table({
+        parent = scroll_container,
+        x = 0,
+        y = 80,
+        w = 480,
+        h = 210,
+        rows = 11, -- 10行数据 + 表头
+        cols = 9,
+        col_width = {70, 80, 90, 70, 70, 100, 100, 70, 150}, -- 调整列宽以适应内容
+        border_color = 0xFFE082,
+    })
+
+    -- 设置表头
+    local headers = {"序号", "发送方", "连接器SN", "信号", "版本", "一级类型", "二级类型", "数据", "时间"}
+    for i, header in ipairs(headers) do
+        lora_table:set_cell_text(0, i-1, header)
+    end
+
+    -- 示例数据
+    local lora_data = {
+        {"1", "设备1", "12345", "-65", "v1.0", "路由器", "A型", "00 01 02", "2024/07/02 09:30:46"},
+        {"2", "设备2", "67890", "-70", "v1.1", "连接器", "B型", "03 04 05", "2024/07/02 09:31:00"},
+        {"3", "设备3", "54321", "-60", "v1.0", "路由器", "A型", "06 07 08", "2024/07/02 09:32:15"},
+        {"4", "设备4", "09876", "-75", "v1.1", "连接器", "C型", "09 0A 0B", "2024/07/02 09:33:30"},
+        {"5", "设备5", "13579", "-68", "v1.0", "路由器", "B型", "0C 0D 0E", "2024/07/02 09:34:45"},
+        {"6", "设备6", "24680", "-72", "v1.1", "连接器", "A型", "0F 10 11", "2024/07/02 09:35:00"},
+        {"7", "设备7", "97531", "-63", "v1.0", "路由器", "C型", "12 13 14", "2024/07/02 09:36:15"},
+        {"8", "设备8", "86420", "-69", "v1.1", "连接器", "B型", "15 16 17", "2024/07/02 09:37:30"},
+        {"9", "设备9", "12457", "-66", "v1.0", "路由器", "A型", "18 19 1A", "2024/07/02 09:38:45"},
+        {"10", "设备10", "36925", "-71", "v1.1", "连接器", "C型", "1B 1C 1D", "2024/07/02 09:39:00"},
+    }
+
+    -- 填充表格数据
+    for i, data in ipairs(lora_data) do
+        for j, value in ipairs(data) do
+            lora_table:set_cell_text(i, j-1, value)
+        end
+    end
+    ---------------------------------------------------
+
+    -- 底部信息
+    --common_ui.create_status_bar(main_container)
+end
+
+-- 初始化页面
+function tsb_lora_page.init(params)
+    tsb_lora_page.create_ui()
+end
+
+-- 清理页面
+function tsb_lora_page.cleanup()
+    -- 停止定时器
+    common_ui.cleanup()
+    if main_container then
+        main_container:destroy()
+        main_container = nil
+    end
+end
+
+return tsb_lora_page

+ 440 - 0
script/tsb_ui/tsb_mqtt_page.lua

@@ -0,0 +1,440 @@
+--[[
+@module  tsb_mqtt_page
+@summary MQTT配置页面
+@version 1.0
+@date    2026.03.05
+@author  李一玮
+@usage
+本文件是MQTT配置页面,展示MQTT配置的各种用法。
+]]
+
+local tsb_mqtt_page = {}
+
+-- 页面UI元素
+local main_container = nil
+local common_ui = require("tsb_common_page")
+
+-- 创建UI
+function tsb_mqtt_page.create_ui()
+    main_container = airui.container({
+        x = 0,
+        y = 0,
+        w = 480,
+        h = 320,
+        color = 0xFFFFFF,
+        color_opacity = 0
+    })
+
+    --------------------- 标题栏 ------------------------
+    local title_bar = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 0,
+        w = 480,
+        h = 30,
+        color = 0xFFB74D,
+    })
+
+    airui.label({
+        parent = title_bar,
+        text = "MQTT配置",
+        x = 195,
+        y = 8,
+        w = 100,
+        h = 20,
+        font_size = 16,
+        color = 0xFFFFFF,
+    })
+
+    
+    -- 标题栏公共信息展示
+    common_ui.add_battery_display(title_bar)
+    common_ui.create_back_button(title_bar, tsb_mqtt_page.cleanup)
+    ---------------------------------------------------
+
+    -- 滚动容器
+    local scroll_container = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 30,
+        w = 480,
+        h = 260,
+        color = 0xFFFFFF,
+        
+    })
+
+    local keyboard1 = airui.keyboard({
+        x = 0,
+        y = 0,
+        w = 480,
+        h = 160,                        -- x, y, 键盘默认打开ALIGN_BOTTOM_MID,位置从中下方开始计算
+        mode = "numeric",               -- 键盘模式,可选 "text"/"upper"/"lower"/"numeric"
+        auto_hide = true,               -- 自动隐藏键盘
+        bg_color = 0xf1f1f1,            -- 键盘背景颜色为灰色,可选,不设置则透明
+        on_commit = function()          -- 确认事件回调,只有在按下确认键时才会触发
+            log.info("keyboard", "commit")
+        end
+    })
+
+    local keyboard2 = airui.keyboard({
+        x = 0,
+        y = 0,
+        w = 480,
+        h = 160,                        -- x, y, 键盘默认打开ALIGN_BOTTOM_MID,位置从中下方开始计算
+        mode = "lower",               -- 键盘模式,可选 "text"/"upper"/"lower"/"numeric"
+        auto_hide = true,               -- 自动隐藏键盘
+        bg_color = 0xf1f1f1,            -- 键盘背景颜色为灰色,可选,不设置则透明
+        on_commit = function()          -- 确认事件回调,只有在按下确认键时才会触发
+            log.info("keyboard", "commit")
+        end
+    })
+
+    --------------------- 第一行控制区 ------------------------
+    -- 当前lora信道标签
+    airui.label({
+        parent = scroll_container,
+        text = "当前lora信道",
+        x = 10,
+        y = 10,
+        w = 100,
+        h = 30,
+        font_size = 14,
+    })
+
+    -- 当前lora信道值
+    local current_channel_label = airui.label({
+        parent = scroll_container,
+        text = "1",
+        x = 110,
+        y = 10,
+        w = 30,
+        h = 30,
+        font_size = 14,
+    })
+
+    -- 设置lora信道标签
+    airui.label({
+        parent = scroll_container,
+        text = "设置lora信道",
+        x = 150,
+        y = 10,
+        w = 100,
+        h = 30,
+        font_size = 14,
+    })
+
+    -- 设置lora信道下拉框
+    local channel_dropdown = airui.dropdown({
+        parent = scroll_container,
+        x = 250,
+        y = 3,
+        w = 70,
+        h = 30,
+        options = {"1", "2", "3", "4", "5", "6"},
+        default_index = 0, -- 默认选择1
+        on_change = function(self,idx)
+            log.info("mqtt_channel", "选择了信道:" .. self.options[idx + 1])
+        end
+    })
+    ---------------------------------------------------
+
+    --------------------- 输入框区域 ------------------------
+    -- 左侧输入框容器
+    local left_container = airui.container({
+        parent = scroll_container,
+        x = 10,
+        y = 40,
+        w = 230,
+        h = 230,
+        color = 0xFFFFFF,
+    })
+
+    -- 左侧第一组:一级设备类型
+    airui.label({
+        parent = left_container,
+        text = "一级设备类型:",
+        x = 0,
+        y = 0,
+        w = 100,
+        h = 20,
+        font_size = 14,
+    })
+    local device_type_input = airui.textarea({
+        parent = left_container,
+        x = 0,
+        y = 20,
+        w = 220,
+        h = 30,
+        text = "",
+        keyboard = keyboard1
+    })
+
+    -- 左侧第二组:一级设备SN
+    airui.label({
+        parent = left_container,
+        text = "一级设备SN:",
+        x = 0,
+        y = 55,
+        w = 100,
+        h = 20,
+        font_size = 14,
+    })
+    local device_sn_input = airui.textarea({
+        parent = left_container,
+        x = 0,
+        y = 75,
+        w = 220,
+        h = 30,
+        text = "",
+        keyboard = keyboard1,
+    })
+
+    -- 左侧第三组:目标设备类型
+    airui.label({
+        parent = left_container,
+        text = "目标设备类型:",
+        x = 0,
+        y = 110,
+        w = 100,
+        h = 20,
+        font_size = 14,
+    })
+    local target_type_input = airui.textarea({
+        parent = left_container,
+        x = 0,
+        y = 130,
+        w = 220,
+        h = 30,
+        text = "",
+        keyboard = keyboard1,
+    })
+
+    -- 左侧第四组:目标设备SN
+    airui.label({
+        parent = left_container,
+        text = "目标设备SN",
+        x = 0,
+        y = 165,
+        w = 100,
+        h = 20,
+        font_size = 14,
+    })
+    local target_sn_input = airui.textarea({
+        parent = left_container,
+        x = 0,
+        y = 185,
+        w = 220,
+        h = 30,
+        text = "",
+        keyboard = keyboard1,
+    })
+
+    -- 右侧输入框容器
+    local right_container = airui.container({
+        parent = scroll_container,
+        x = 240,
+        y = 40,
+        w = 230,
+        h = 230,
+        color = 0xFFFFFF,
+    })
+
+    -- 右侧第一组:服务器地址
+    airui.label({
+        parent = right_container,
+        text = "服务器地址:",
+        x = 0,
+        y = 0,
+        w = 100,
+        h = 20,
+        font_size = 14,
+    })
+    local server_addr_input = airui.textarea({
+        parent = right_container,
+        x = 0,
+        y = 20,
+        w = 220,
+        h = 30,
+        text = "",
+        keyboard = keyboard2,
+    })
+
+    -- 右侧第二组:服务器端口
+    airui.label({
+        parent = right_container,
+        text = "服务器端口:",
+        x = 0,
+        y = 55,
+        w = 100,
+        h = 20,
+        font_size = 14,
+    })
+    local server_port_input = airui.textarea({
+        parent = right_container,
+        x = 0,
+        y = 75,
+        w = 220,
+        h = 30,
+        text = "",
+        keyboard = keyboard1,
+    })
+
+    -- 右侧第三组:服务器用户名
+    airui.label({
+        parent = right_container,
+        text = "服务器用户名:",
+        x = 0,
+        y = 110,
+        w = 100,
+        h = 20,
+        font_size = 14,
+    })
+    local server_user_input = airui.textarea({
+        parent = right_container,
+        x = 0,
+        y = 130,
+        w = 220,
+        h = 30,
+        text = "",
+        keyboard = keyboard2,
+    })
+
+    -- 右侧第四组:服务器密码
+    airui.label({
+        parent = right_container,
+        text = "服务器密码:",
+        x = 0,
+        y = 165,
+        w = 100,
+        h = 20,
+        font_size = 14,
+    })
+    local server_pass_input = airui.textarea({
+        parent = right_container,
+        x = 0,
+        y = 185,
+        w = 220,
+        h = 30,
+        text = "",
+        keyboard = keyboard2,
+    })
+    ---------------------------------------------------
+
+    --------------------- 提示信息 ------------------------
+    airui.label({
+        parent = scroll_container,
+        text = "一级设备SN和目标设备SN同时写1代表全量配置(仅LORA模式)",
+        x = 10,
+        y = 280,
+        w = 460,
+        h = 20,
+        font_size = 12,
+        color = 0x757575,
+    })
+    ---------------------------------------------------
+
+    --------------------- 控制按钮区 ------------------------
+    -- 串口发送标签
+    airui.label({
+        parent = scroll_container,
+        text = "串口发送",
+        x = 15,
+        y = 312,
+        w = 80,
+        h = 30,
+        font_size = 14,
+    })
+
+    -- 串口发送开关
+    local serial_switch = airui.switch({
+        parent = scroll_container,
+        x = 80,
+        y = 310,
+        w = 50,
+        h = 20,
+        checked = false,
+        on_change = function(self)
+            log.info("UART SEND", self:get_state() and "开启" or "关闭")
+        end
+    })
+
+    -- 串口发送提示信息
+    airui.label({
+        parent = scroll_container,
+        text = "默认为LORA模式,可选串口发送",
+        x = 140,
+        y = 312,
+        w = 200,
+        h = 20,
+        font_size = 12,
+        color = 0x757575,
+    })
+
+    -- 新配置下发按钮
+    local new_config_btn = airui.button({
+        parent = scroll_container,
+        x = 10,
+        y = 340,
+        w = 100,
+        h = 35,
+        text = "新配置下发",
+        stype = { bg_color = 0x2B6FF1,border_color = 0x2B6FF1, text_color = 0xFFFFFF, radius = 8 },
+        on_click = function(self)
+            log.info("mqtt_config", "新配置下发按钮被点击")
+        end
+    })
+
+    -- 恢复默认配置按钮
+    local default_config_btn = airui.button({
+        parent = scroll_container,
+        x = 120,
+        y = 340,
+        w = 120,
+        h = 35,
+        text = "恢复默认配置",
+        on_click = function(self)
+            log.info("mqtt_config", "恢复默认配置按钮被点击")
+        end
+    })
+
+    -- 执行结果
+    airui.label({
+        parent = scroll_container,
+        text = "执行结果:",
+        x = 300,
+        y = 347,
+        w = 80,
+        h = 30,
+        font_size = 16,
+    })
+
+    -- 执行结果值
+    local result_label = airui.label({
+        parent = scroll_container,
+        text = "成功",
+        x = 380,
+        y = 347,
+        w = 100,
+        h = 30,
+        font_size = 16,
+    })
+    ---------------------------------------------------
+
+    -- 底部信息
+    common_ui.create_status_bar(main_container)
+end
+
+-- 初始化页面
+function tsb_mqtt_page.init(params)
+    tsb_mqtt_page.create_ui()
+end
+
+-- 清理页面
+function tsb_mqtt_page.cleanup()
+    if main_container then
+        main_container:destroy()
+        main_container = nil
+    end
+end
+
+return tsb_mqtt_page

+ 235 - 0
script/tsb_ui/tsb_reflash_page.lua

@@ -0,0 +1,235 @@
+--[[
+@module  tsb_reflash_page
+@summary 刷机页面
+@version 1.0
+@date    2026.03.05
+@author  李一玮
+@usage
+本文件是刷机页面,展示刷机的各种用法。
+]]
+
+local tsb_reflash_page = {}
+
+-- 页面UI元素
+local main_container = nil
+local common_ui = require("tsb_common_page")
+
+-- 创建UI
+function tsb_reflash_page.create_ui()
+    main_container = airui.container({
+        x = 0,
+        y = 0,
+        w = 480,
+        h = 320,
+        color = 0xF5F5F5,
+    })
+
+    --------------------- 标题栏 ------------------------
+    local title_bar = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 0,
+        w = 480,
+        h = 30,
+        color = 0xF4511E,
+    })
+
+    airui.label({
+        parent = title_bar,
+        text = "刷机界面",
+        x = 200,
+        y = 8,
+        w = 80,
+        h = 20,
+        font_size = 16,
+        color = 0xFFFFFF,
+    })
+
+    -- 标题栏公共信息展示
+    common_ui.add_battery_display(title_bar)
+    common_ui.create_back_button(title_bar, tsb_reflash_page.cleanup)
+    ---------------------------------------------------
+
+    -- 滚动容器
+    local scroll_container = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 30,
+        w = 480,
+        h = 270,
+        color = 0xFFFFFF,
+    })
+
+    --------------------- 第一行控制区 ------------------------
+    -- 设备类型标签
+    airui.label({
+        parent = scroll_container,
+        text = "设备类型:",
+        x = 30,
+        y = 32,
+        w = 80,
+        h = 30,
+        font_size = 16,
+    })
+
+    -- 设备类型下拉框
+    local device_type_dropdown = airui.dropdown({
+        parent = scroll_container,
+        x = 108,
+        y = 25,
+        w = 100,
+        h = 30,
+        options = {"0101", "0102", "0201", "0202", "0301", "0302", "0103", "0104", "0902", "0904"},
+        default_index = 0,
+        on_change = function(self,idx)
+            log.info("reflash_device_type", "选择了设备类型:" .. self.options[idx + 1])
+        end
+    })
+
+    -- 固件类型标签
+    airui.label({
+        parent = scroll_container,
+        text = "固件类型:",
+        x = 255,
+        y = 32,
+        w = 80,
+        h = 30,
+        font_size = 16,
+    })
+
+    -- 固件类型下拉框
+    local firmware_type_dropdown = airui.dropdown({
+        parent = scroll_container,
+        x = 330,
+        y = 25,
+        w = 100,
+        h = 30,
+        options = {"产测", "app", "boot"},
+        default_index = 1, -- 默认选择app
+        on_change = function(self,idx)
+            log.info("reflash_firm_type", "选择了固件类型:" .. self.options[idx + 1])
+        end
+    })
+    ---------------------------------------------------
+
+    --------------------- 第二行控制区 ------------------------
+    -- 提示信息容器
+    local info_container = airui.container({
+        parent = scroll_container,
+        x = 10,
+        y = 90,
+        w = 300,
+        h = 150,
+        color = 0xF5F5F5,
+        radius = 5,
+    })
+
+    -- 提示信息标题
+    airui.label({
+        parent = info_container,
+        text = "固件信息:",
+        x = 10,
+        y = 10,
+        w = 280,
+        h = 20,
+        font_size = 15,
+        color = 0xF4511E,
+    })
+
+    -- 设备类型信息
+    airui.label({
+        parent = info_container,
+        text = "设备类型:0102",
+        x = 10,
+        y = 40,
+        w = 280,
+        h = 20,
+        font_size = 14,
+        color = 0x666666,
+    })
+
+    -- 固件类型信息
+    airui.label({
+        parent = info_container,
+        text = "固件类型:app",
+        x = 10,
+        y = 60,
+        w = 280,
+        h = 20,
+        font_size = 14,
+        color = 0x666666,
+    })
+
+    -- 包版本信息
+    airui.label({
+        parent = info_container,
+        text = "包版本:01023049",
+        x = 10,
+        y = 80,
+        w = 280,
+        h = 20,
+        font_size = 14,
+        color = 0x666666,
+    })
+
+    -- 包大小信息
+    airui.label({
+        parent = info_container,
+        text = "包大小:150084字节",
+        x = 150,
+        y = 80,
+        w = 140,
+        h = 20,
+        font_size = 14,
+        color = 0x666666,
+    })
+
+    -- 操作按钮区
+    -- 开始刷机按钮
+    local start_reflash_btn = airui.button({
+        parent = scroll_container,
+        x = 335,
+        y = 110,
+        w = 120,
+        h = 35,
+        text = "开始刷机",
+        stype = { bg_color = 0x2B6FF1,border_color = 0x2B6FF1, text_color = 0xFFFFFF, radius = 8 },
+        on_click = function(self)
+            log.info("reflash_start", "开始刷机按钮被点击")
+        end
+    })
+
+    -- 停止按钮
+    local stop_btn = airui.button({
+        parent = scroll_container,
+        x = 335,
+        y = 180,
+        w = 120,
+        h = 35,
+        text = "停止",
+        on_click = function(self)
+            log.info("reflash_stop", "停止按钮被点击")
+        end
+    })
+    ---------------------------------------------------
+
+    -- 底部信息
+    common_ui.create_status_bar(main_container)
+end
+
+-- 初始化页面
+function tsb_reflash_page.init(params)
+    tsb_reflash_page.create_ui()
+end
+
+-- 清理页面
+function tsb_reflash_page.cleanup()
+    -- 停止定时器
+    common_ui.cleanup()
+    if main_container then
+        main_container:destroy()
+        main_container = nil
+    end
+end
+
+return tsb_reflash_page

+ 269 - 0
script/tsb_ui/tsb_tq_page.lua

@@ -0,0 +1,269 @@
+--[[
+@module  tsb_tq_page
+@summary 提枪信号演示页面
+@version 1.0
+@date    2026.03.04
+@author  李一玮
+@usage
+本文件是提枪信号演示页面,展示提枪信号的各种用法。
+]]
+
+local tsb_tq_page = {}
+
+-- 页面UI元素
+local main_container = nil
+local common_ui = require("tsb_common_page")
+
+-- 创建UI
+function tsb_tq_page.create_ui()
+    main_container = airui.container({
+        x = 0,
+        y = 0,
+        w = 480,
+        h = 320,
+        color = 0xF5F5F5,
+    })
+
+    --------------------- 标题栏 ------------------------
+    local title_bar = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 0,
+        w = 480,
+        h = 30,
+        color = 0xF44336,
+    })
+
+    airui.label({
+        parent = title_bar,
+        text = "提枪信号",
+        x = 200,
+        y = 8,
+        w = 80,
+        h = 20,
+        font_size = 16,
+        color = 0xFFFFFF,
+    })
+
+    -- 标题栏公共信息展示
+    common_ui.add_battery_display(title_bar)
+    common_ui.create_back_button(title_bar, tsb_tq_page.cleanup)
+    ---------------------------------------------------
+
+    -- 滚动容器
+    local scroll_container = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 30,
+        w = 480,
+        h = 270,
+        color = 0xF5F5F5,
+    })
+
+    local keyboard1 = airui.keyboard({
+        x = 0,
+        y = 0,
+        w = 480,
+        h = 160,                        -- x, y, 键盘默认打开ALIGN_BOTTOM_MID,位置从中下方开始计算
+        mode = "numeric",               -- 键盘模式,可选 "text"/"upper"/"lower"/"numeric"
+        auto_hide = true,               -- 自动隐藏键盘
+        bg_color = 0xf1f1f1,            -- 键盘背景颜色为灰色,可选,不设置则透明
+        on_commit = function()          -- 确认事件回调,只有在按下确认键时才会触发
+            log.info("keyboard", "commit")
+        end
+    })
+
+    ------------------- 提枪信号输入 ------------------
+    local tq_input_container = airui.container({
+        parent = scroll_container,
+        x = 10,
+        y = 5,
+        w = 200,
+        h = 260,
+        color = 0xFFFFFF,
+        radius = 5,
+    })
+
+    airui.label({
+        parent = tq_input_container,
+        text = "提枪信号输入",
+        x = 35,
+        y = 10,
+        w = 140,
+        h = 30,
+        font_size = 18,
+    })
+
+    airui.label({
+        parent = tq_input_container,
+        text = "油枪状态:",
+        x = 20,
+        y = 80,
+        w = 80,
+        h = 30,
+        font_size = 16,
+    })
+
+    local label_cur_vol = airui.label({
+        parent = tq_input_container,
+        text = "抬枪",
+        x = 100,
+        y = 80,
+        w = 60,
+        h = 30,
+        font_size = 16,
+    })
+
+    airui.label({
+        parent = tq_input_container,
+        text = "实时电压:",
+        x = 20,
+        y = 140,
+        w = 100,
+        h = 30,
+        font_size = 16,
+    })
+
+    local label_pulse_count = airui.label({
+        parent = tq_input_container,
+        text = "5.0V",
+        x = 100,
+        y = 140,
+        w = 70,
+        h = 30,
+        font_size = 16,
+    })
+    ----------------------------------------------------
+
+    ------------------- 提枪信号输出 ------------------
+    local tq_output_container = airui.container({
+        parent = scroll_container,
+        x = 220,
+        y = 5,
+        w = 250,
+        h = 260,
+        color = 0xFFFFFF,
+        radius = 5,
+    })
+
+    airui.label({
+        parent = tq_output_container,
+        text = "提枪信号输出",
+        x = 60,
+        y = 10,
+        w = 140,
+        h = 30,
+        font_size = 18,
+    })
+
+    -- 输出电压
+    airui.label({
+        parent = tq_output_container,
+        text = "输出电压:",
+        x = 20,
+        y = 80,
+        w = 80,
+        h = 30,
+        font_size = 16,
+    })
+
+    local voltage_output = airui.textarea({
+        parent = tq_output_container,
+        x = 100,
+        y = 72,
+        w = 60,
+        h = 35,
+        text = "5",
+        max_len = 2,
+        keyboard = keyboard1
+    })
+
+    airui.label({
+        parent = tq_output_container,
+        text = "V",
+        x = 165,
+        y = 80,
+        w = 30,
+        h = 30,
+        font_size = 16,
+    })
+
+    --------------------- 新国标开关 -------------------
+    airui.label({
+        parent = tq_output_container,
+        text = "周期输出:",
+        x = 20,
+        y = 140,
+        w = 80,
+        h = 20,
+        font_size = 16,
+    })
+
+    local switch_tq = airui.switch({
+        parent = tq_output_container,
+        x = 100,
+        y = 133,
+        w = 55,
+        h = 25,
+        checked = false,
+        on_change = function(self)
+            log.info("NEW_TAX", self:get_state() and "开启" or "关闭")
+        end
+    })
+
+    airui.label({
+        parent = tq_output_container,
+        text = "开启后,提枪信号将按照3s的周期切换输出上面设置的电压和0V。",
+        x = 20,
+        y = 170,
+        w = 200,
+        h = 40,
+        font_size = 12,
+        color = 0x757575,
+    })
+
+    -- 按钮
+    local start_btn = airui.button({
+        parent = tq_output_container,   
+        x = 40,
+        y = 215,    
+        w = 80,
+        h = 35,
+        text = "开始",
+        stype = { bg_color = 0x2B6FF1,border_color = 0x2B6FF1, text_color = 0xFFFFFF, radius = 8 },
+        on_click = function(self)
+            log.info("button", "开始按钮被点击")
+        end
+    })
+
+    local stop_btn = airui.button({
+        parent = tq_output_container,   
+        x = 130,
+        y = 215,
+        w = 80,
+        h = 35,
+        text = "停止",
+        on_click = function(self)
+            log.info("button", "停止按钮被点击")
+        end
+    })
+    ----------------------------------------------------
+
+    -- 底部信息
+    common_ui.create_status_bar(main_container)
+end
+
+-- 初始化页面
+function tsb_tq_page.init(params)
+    tsb_tq_page.create_ui()
+end
+
+-- 清理页面
+function tsb_tq_page.cleanup()
+    if main_container then
+        main_container:destroy()
+        main_container = nil
+    end
+end
+
+return tsb_tq_page

+ 179 - 0
script/tsb_ui/tsb_ui_main.lua

@@ -0,0 +1,179 @@
+--[[
+@module  ui_main
+@summary 调试宝UI主程序,负责页面管理和主循环
+@version 1.0
+@date    2026.03.04
+@author  李一玮
+@usage
+本文件管理所有调试宝UI页面,包括主页和各个演示页面。
+]]
+
+require("tsb_login_page")
+require("tsb_home_page")
+require("tsb_bsk_page")
+require("tsb_tq_page")
+require("tsb_bmq_page")
+require("tsb_ywy_page")
+require("tsb_lora_page")
+require("tsb_devlog_page")
+require("tsb_485log_page")
+require("tsb_mqtt_page")
+require("tsb_firm_page")
+require("tsb_upgrade_page")
+require("tsb_reflash_page")
+require("tsb_light_page")
+require("tsb_devinfo_page")
+require("tsb_update_page")
+require("tsb_wlan_page")
+require("tsb_game_page")
+require("tsb_wavein_page")
+require("tsb_waveout_page")
+require("tsb_ywy_1_page")
+require("tsb_ywy_2_page")
+require("tsb_232log_page")
+require("tsb_channel_page")
+require("tsb_log_page")
+require("tsb_help_page")
+require("tsb_waveform_page")
+
+
+
+-- 当前显示的页面
+local current_page = nil
+local page_stack = {} -- 页面,用于返回功能
+-- local frame_time = 20 -- 主循环刷新间隔,单位ms
+
+
+-- 页面定义
+local pages = {
+    tsb_login_page  = "tsb_login_page",                 -- 调试宝登录页面
+    tsb_home_page   = "tsb_home_page",                  -- 调试宝主界面
+    tsb_bsk_page    = "tsb_bsk_page",                   -- 报税口页面
+    tsb_tq_page     = "tsb_tq_page",                    -- 提枪信号页面
+    tsb_bmq_page    = "tsb_bmq_page",                   -- 编码器页面
+    tsb_ywy_page    = "tsb_ywy_page",                   -- 液位仪页面
+    tsb_lora_page   = "tsb_lora_page",                  -- 无线局域网监测页面
+    tsb_devlog_page = "tsb_devlog_page",                -- 设备日志监测页面
+    tsb_485log_page = "tsb_485log_page",                -- 485日志监测页面
+    tsb_mqtt_page   = "tsb_mqtt_page",                  -- MQTT配置页面
+    tsb_firm_page   = "tsb_firm_page",                  -- 固件包下载页面
+    tsb_upgrade_page = "tsb_upgrade_page",              -- 升级演示页面
+    tsb_reflash_page = "tsb_reflash_page",              -- 刷机页面
+    tsb_light_page   = "tsb_light_page",                -- 亮度页面   
+    tsb_devinfo_page = "tsb_devinfo_page",              -- 设备信息页面 
+    tsb_update_page  = "tsb_update_page",               -- 更新页面
+    tsb_wlan_page    = "tsb_wlan_page",                 -- 网络配置页面
+    tsb_wavein_page  = "tsb_wavein_page",               -- 波形输入页面
+    tsb_waveout_page = "tsb_waveout_page",             -- 波形输出页面
+    tsb_ywy_1_page   = "tsb_ywy_1_page",                -- 液位仪页面1
+    tsb_ywy_2_page   = "tsb_ywy_2_page",                -- 液位仪页面2
+    tsb_232log_page  = "tsb_232log_page",               -- 232日志监测页面
+    tsb_channel_page = "tsb_channel_page",              -- 信道切换页面
+    tsb_log_page     = "tsb_log_page",                  -- 本机日志页面
+    tsb_help_page    = "tsb_help_page",                 -- 帮助页面
+    tsb_waveform_page = "tsb_waveform_page",            -- 波形页面
+    -- tsb_game_page    = "tsb_game_page",                   -- 游戏页面
+}
+
+-- 显示指定页面
+local function show_page(page_name, params)
+    -- 保存当前页面
+    if not params or not (params.from_back or params.from_home) then
+        if current_page then
+            table.insert(page_stack, {
+                name = current_page.name,
+                instance = current_page.instance
+            })
+        end
+    end
+
+    -- 清理当前页面
+    if current_page and current_page.instance.cleanup then
+        current_page.instance.cleanup()
+    end
+
+    -- 加载新页面
+    local module_name = pages[page_name]
+    if not module_name then
+        log.error("tsb_ui_main", "页面不存在:", page_name)
+        return false
+    end
+
+    local page_module = require(module_name)
+
+    -- 初始化页面
+    if page_module.init then
+        page_module.init(params)
+    end
+
+    -- 更新当前页面信息
+    current_page = {
+        name = page_name,
+        module = module_name,
+        instance = page_module
+    }
+
+    log.info("tsb_ui_main", "切换到页面:", page_name)
+    return true
+end
+
+-- 返回上一个页面
+local function go_back()
+    if #page_stack > 0 then
+        local prev_page = table.remove(page_stack)
+        if prev_page.instance and prev_page.instance.show then
+            prev_page.instance.show()
+            current_page = prev_page
+            log.info("tsb_ui_main", "返回页面:", prev_page.name)
+            return true
+        else
+            return show_page(prev_page.name, { from_back = true })
+        end
+    else
+        return show_page("tsb_login_page", { from_back = true })
+    end
+end
+
+-- 返回到首页面
+local function go_home()
+    -- 先判断是否已在首页
+    if current_page and current_page.name == "tsb_home_page" then
+        log.info("tsb_ui_main", "当前已在首页,无需跳转")
+        return true
+    end
+
+    -- 清空页面栈
+    page_stack = {}
+
+    -- 调用show_page,用from_home标识
+    return show_page("tsb_home_page", { from_home = true })
+end
+
+-- 主任务函数
+local function tsb_ui_main_task()
+
+    -- 3V3供电使能
+    gpio.setup(153,1, gpio.PULLUP)
+    -- 10V供电使能
+    gpio.setup(147,1, gpio.PULLUP)
+
+    -- 开启屏幕供电
+    gpio.setup(31,0) 
+    gpio.set(31,0)
+
+    -- 初始化硬件
+    lcd_drv.init()
+    tp_drv.init()
+
+    -- 显示主页
+    show_page("tsb_login_page")
+    
+end
+
+-- 全局函数,方便页面调用
+_G.show_page = show_page
+_G.go_back = go_back
+_G.go_home = go_home
+
+-- 启动UI主任务
+sys.taskInit(tsb_ui_main_task)

+ 94 - 0
script/tsb_ui/tsb_update_page.lua

@@ -0,0 +1,94 @@
+--[[
+@module  tsb_update_page
+@summary 更新页面
+@version 1.0
+@date    2026.03.04
+@author  李一玮
+@usage
+本文件是更新页面,展示更新的各种用法。
+]]
+
+local tsb_update_page = {}
+
+-- 页面UI元素
+local main_container = nil
+local common_ui = require("tsb_common_page")
+
+-- 创建UI
+function tsb_update_page.create_ui()
+    main_container = airui.container({
+        x = 0,
+        y = 0,
+        w = 480,
+        h = 320,
+        color = 0xF5F5F5,
+    })
+
+    --------------------- 标题栏 ------------------------
+    local title_bar = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 0,
+        w = 480,
+        h = 30,
+        color = 0xA5D6A7,
+    })
+
+    airui.label({
+        parent = title_bar,
+        text = "本机升级",
+        x = 200,
+        y = 8,
+        w = 80,
+        h = 20,
+        font_size = 16,
+        color = 0xFFFFFF,
+    })
+
+    -- 标题栏公共信息展示
+    common_ui.add_battery_display(title_bar)
+    common_ui.create_back_button(title_bar, tsb_update_page.cleanup)
+    ---------------------------------------------------
+
+    -- 滚动容器
+    local scroll_container = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 30,
+        w = 480,
+        h = 270,
+        color = 0xFFFFFF,
+    })
+
+    --------------------- 检查更新 -----------------------
+    local update_btn = airui.button({
+        parent = scroll_container,
+        x = 15,
+        y = 15,
+        w = 120,
+        h = 40,
+        text = "检查设备更新",
+        on_click = function()
+            log.info("检查设备更新")
+        end
+    })
+
+
+    -- 底部信息
+    common_ui.create_status_bar(main_container)
+end
+
+-- 初始化页面
+function tsb_update_page.init(params)
+    tsb_update_page.create_ui()
+end
+
+-- 清理页面
+function tsb_update_page.cleanup()
+    if main_container then
+        main_container:destroy()
+        main_container = nil
+    end
+end
+
+return tsb_update_page

+ 429 - 0
script/tsb_ui/tsb_upgrade_page.lua

@@ -0,0 +1,429 @@
+--[[
+@module  tsb_upgrade_page
+@summary 升级演示页面
+@version 1.0
+@date    2026.03.05
+@author  李一玮
+@usage
+本文件是升级演示页面,展示升级演示的各种用法。
+]]
+
+local tsb_upgrade_page = {}
+
+-- 页面UI元素
+local main_container = nil
+local common_ui = require("tsb_common_page")
+
+-- 创建UI
+function tsb_upgrade_page.create_ui()
+    main_container = airui.container({
+        x = 0,
+        y = 0,
+        w = 480,
+        h = 320,
+        color = 0xF5F5F5,
+    })
+
+    --------------------- 标题栏 ------------------------
+    local title_bar = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 0,
+        w = 480,
+        h = 30,
+        color = 0x66BB6A,
+    })
+
+    airui.label({
+        parent = title_bar,
+        text = "升级界面",
+        x = 200,
+        y = 8,
+        w = 80,
+        h = 20,
+        font_size = 16,
+        color = 0xFFFFFF,
+    })
+
+    -- 标题栏公共信息展示
+    common_ui.add_battery_display(title_bar)
+    common_ui.create_back_button(title_bar, tsb_upgrade_page.cleanup)
+    ---------------------------------------------------
+
+    -- 滚动容器
+    local scroll_container = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 30,
+        w = 480,
+        h = 270,
+        color = 0xFFFFFF,
+    })
+
+    local keyboard1 = airui.keyboard({
+        x = 0,
+        y = 0,
+        w = 480,
+        h = 160,                        -- x, y, 键盘默认打开ALIGN_BOTTOM_MID,位置从中下方开始计算
+        mode = "numeric",               -- 键盘模式,可选 "text"/"upper"/"lower"/"numeric"
+        auto_hide = true,               -- 自动隐藏键盘
+        bg_color = 0xf1f1f1,            -- 键盘背景颜色为灰色,可选,不设置则透明
+        on_commit = function()          -- 确认事件回调,只有在按下确认键时才会触发
+            log.info("keyboard", "commit")
+        end
+    })
+
+    -- 设备类型标签
+    airui.label({
+        parent = scroll_container,
+        text = "设备类型:",
+        x = 10,
+        y = 12,
+        w = 80,
+        h = 30,
+        font_size = 16,
+    })
+
+    -- 设备类型下拉框
+    local device_type_dropdown = airui.dropdown({
+        parent = scroll_container,
+        x = 90,
+        y = 5,
+        w = 100,
+        h = 30,
+        options = {"0101", "0102", "0201", "0202", "0301", "0302", "0103", "0104", "0902", "0904"},
+        default_index = 0,
+        on_change = function(self,idx)
+            log.info("upgrade_device_type", "选择了设备类型:" .. self.options[idx + 1])
+        end
+    })
+
+    -- 当前lora信道标签
+    airui.label({
+        parent = scroll_container,
+        text = "当前lora信道:",
+        x = 255,
+        y = 12,
+        w = 120,
+        h = 30,
+        font_size = 16,
+    })
+
+    -- 当前lora信道值
+    local current_channel_label = airui.label({
+        parent = scroll_container,
+        text = "1",
+        x = 400,
+        y = 12,
+        w = 30,
+        h = 30,
+        font_size = 16,
+    })
+
+    airui.label({
+        parent = scroll_container,
+        text = "设置lora信道:",
+        x = 255,
+        y = 50,
+        w = 120,
+        h = 30,
+        font_size = 16,
+    })
+
+    -- 设置lora信道下拉框
+    local channel_dropdown = airui.dropdown({
+        parent = scroll_container,
+        x = 380,
+        y = 45,
+        w = 70,
+        h = 30,
+        options = {"1", "2", "3", "4", "5", "6"},
+        default_index = 0, -- 默认选择1
+        on_change = function(self,idx)
+            log.info("mqtt_channel", "选择了信道:" .. self.options[idx + 1])
+        end
+    })
+
+    -- 设备SN标签
+    airui.label({
+        parent = scroll_container,
+        text = "设备SN:",
+        x = 10,
+        y = 50,
+        w = 70,
+        h = 30,
+        font_size = 16,
+    })
+
+    -- 设备SN输入框
+    local device_sn_input = airui.textarea({
+        parent = scroll_container,
+        x = 90,
+        y = 40,
+        w = 100,
+        h = 35,
+        text = "",
+        keyboard = keyboard1
+    })
+    ---------------------------------------------------
+
+    -- 先声明开关变量
+    local target_upgrade_switch
+    local broadcast_upgrade_switch
+
+    -- 定向升级标签
+    airui.label({
+        parent = scroll_container,
+        text = "定向升级",
+        x = 10,
+        y = 92,
+        w = 70,
+        h = 30,
+        font_size = 16,
+    })
+
+    -- 定向升级开关
+    target_upgrade_switch = airui.switch({
+        parent = scroll_container,
+        x = 80,
+        y = 87,
+        w = 55,
+        h = 25,
+        checked = true, -- 默认定向升级开
+        on_change = function(self)
+            local checked = self:get_state()
+            log.info("定向升级开关", checked and "开启" or "关闭")
+            -- 互斥逻辑:如果定向升级开启,则关闭广播升级
+            if checked and broadcast_upgrade_switch then
+                broadcast_upgrade_switch:set_state(false)
+            end
+        end
+    })
+
+    -- 广播升级标签
+    airui.label({
+        parent = scroll_container,
+        text = "广播升级",
+        x = 160,
+        y = 92,
+        w = 70,
+        h = 30,
+        font_size = 16,
+    })
+
+    -- 广播升级开关
+    broadcast_upgrade_switch = airui.switch({
+        parent = scroll_container,
+        x = 230,
+        y = 87,
+        w = 55,
+        h = 25,
+        checked = false, -- 默认广播升级关
+        on_change = function(self)
+            local checked = self:get_state()
+            log.info("广播升级开关", checked and "开启" or "关闭")
+            -- 互斥逻辑:如果广播升级开启,则关闭定向升级
+            if checked and target_upgrade_switch then
+                target_upgrade_switch:set_state(false)
+            end
+        end
+    })
+    ---------------------------------------------------
+
+    --------------------- 第四行控制区 ------------------------
+    -- 提示信息容器
+    local info_container = airui.container({
+        parent = scroll_container,
+        x = 10,
+        y = 130,
+        w = 250,
+        h = 130,
+        color = 0xF5F5F5,
+        radius = 5,
+    })
+
+    -- 提示信息
+    airui.label({
+        parent = info_container,
+        text = "提示信息:",
+        x = 10,
+        y = 10,
+        w = 230,
+        h = 20,
+        font_size = 15,
+        color = 0x66BB6A,
+    })
+
+    airui.label({
+        parent = info_container,
+        text = "1. 确保设备已连接到网络",
+        x = 10,
+        y = 40,
+        w = 230,
+        h = 20,
+        font_size = 12,
+        color = 0x666666,
+    })
+
+    airui.label({
+        parent = info_container,
+        text = "2. 选择正确的设备类型和SN",
+        x = 10,
+        y = 60,
+        w = 230,
+        h = 20,
+        font_size = 12,
+        color = 0x666666,
+    })
+
+    airui.label({
+        parent = info_container,
+        text = "3. 选择升级方式(定向或广播)",
+        x = 10,
+        y = 80,
+        w = 230,
+        h = 20,
+        font_size = 12,
+        color = 0x666666,
+    })
+
+    airui.label({
+        parent = info_container,
+        text = "4. ......",
+        x = 10,
+        y = 100,
+        w = 230,
+        h = 20,
+        font_size = 12,
+        color = 0x666666,
+    })
+
+    -- 操作按钮区
+    -- 开始升级按钮
+    local start_upgrade_btn = airui.button({
+        parent = scroll_container,
+        x = 300,
+        y = 140,
+        w = 150,
+        h = 30,
+        text = "开始升级",
+        stype = { bg_color = 0x2B6FF1,border_color = 0x2B6FF1, text_color = 0xFFFFFF, radius = 8 },
+        on_click = function(self)
+            log.info("upgrade_start", "开始升级按钮被点击")
+        end
+    })
+
+    -- 停止升级按钮
+    local stop_upgrade_btn = airui.button({
+        parent = scroll_container,
+        x = 300,
+        y = 180,
+        w = 150,
+        h = 30,
+        text = "停止升级",
+        on_click = function(self)
+            log.info("upgrade_stop", "停止升级按钮被点击")
+        end
+    })
+
+    -- 查看升级状态按钮
+    local check_status_btn = airui.button({
+        parent = scroll_container,
+        x = 300,
+        y = 220,
+        w = 150,
+        h = 30,
+        text = "查看升级状态",
+        on_click = function(self)
+            log.info("upgrade_check", "查看升级状态按钮被点击")
+            -- 弹出新窗口显示升级状态表格
+            local status_window = airui.container({
+                x = 20,
+                y = 35,
+                w = 440,
+                h = 255,
+                color = 0xFFFFFF,
+                radius = 5,
+                border_width = 2,
+                border_color = 0x66BB6A,
+            })
+
+            -- 窗口标题
+            airui.label({
+                parent = status_window,
+                text = "升级状态",
+                x = 190,
+                y = 15,
+                w = 80,
+                h = 30,
+                font_size = 16,
+                color = 0x66BB6A,--0xE91E63
+            })
+
+            -- 创建表格
+            local status_table = airui.table({
+                parent = status_window,
+                x = 10,
+                y = 40,
+                w = 420,
+                h = 200,
+                row_count = 6,
+                col_count = 5,
+                col_width = {70, 120, 120, 120, 120},
+            })
+
+            -- 设置表头
+            local headers = {"序号", "设备类型", "设备SN", "软件版本", "升级状态"}
+            for i, header in ipairs(headers) do
+                status_table:set_cell_text(0, i-1, header)
+            end
+
+            -- 示例数据
+            local status_data = {
+                {"1", "0101", "SN001", "V1.0.0", "升级中"},
+                {"2", "0202", "SN002", "V1.1.0", "已完成"},
+                {"3", "0201", "SN003", "V1.0.0", "失败"},
+            }
+
+            -- 填充表格数据
+            for i, data in ipairs(status_data) do
+                for j, value in ipairs(data) do
+                    status_table:set_cell_text(i, j-1, value)
+                end
+            end
+
+
+            -- 关闭按钮
+            local close_btn = airui.button({
+                parent = status_window,
+                x = 390,
+                y = 5,
+                w = 40,
+                h = 25,
+                text = "关闭",
+                on_click = function(self)
+                    status_window:destroy()
+                end
+            })
+        end
+    })
+    ---------------------------------------------------
+
+    -- 底部信息
+    common_ui.create_status_bar(main_container)
+end
+
+-- 初始化页面
+function tsb_upgrade_page.init(params)
+    tsb_upgrade_page.create_ui()
+end
+
+-- 清理页面
+function tsb_upgrade_page.cleanup()
+    if main_container then
+        main_container:destroy()
+        main_container = nil
+    end
+end
+
+return tsb_upgrade_page

+ 143 - 0
script/tsb_ui/tsb_waveform_page.lua

@@ -0,0 +1,143 @@
+--[[
+@module  tsb_waveform_page        
+@summary 简易示波器页面
+@version 1.0
+@date    2026.03.17
+@author  李一玮
+@usage
+本文件是简易示波器页面,展示232日志的各种用法。
+]]
+
+local tsb_waveform_page = {}
+
+-- 页面UI元素
+local main_container = nil
+local common_ui = require("tsb_common_page")
+
+-- 创建UI
+function tsb_waveform_page.create_ui()
+    main_container = airui.container({
+        x = 0,
+        y = 0,
+        w = 480,
+        h = 320,
+        color = 0xF5F5F5,
+    })
+
+    --------------------- 标题栏 ------------------------
+    local title_bar = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 0,
+        w = 480,
+        h = 30,
+        color = 0xFFAB91,
+    })
+
+    airui.label({
+        parent = title_bar,
+        text = "简易示波器",
+        x = 190,
+        y = 8,
+        w = 200,
+        h = 20,
+        font_size = 16,
+        color = 0xFFFFFF,
+    })
+
+    -- 标题栏公共信息展示
+    common_ui.add_battery_display(title_bar)
+    common_ui.create_back_button(title_bar, tsb_waveform_page.cleanup)
+
+    -- 滚动容器
+    local scroll_container = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 30, 
+        w = 480,
+        h = 270,
+        color = 0xFFFFFF,
+    })
+
+    -- 创建两个容器卡片
+    local card_width = 140
+    local card_height = 80
+    local padding = 20
+    local y_offset = 20
+
+    -- 示波器输入卡片
+    local input_card = airui.container({
+        parent = scroll_container,
+        x = padding,
+        y = y_offset,
+        w = card_width,
+        h = card_height,
+        color = 0xFFD93D,
+        radius = 8,
+    })
+
+    -- 示波器输入标题
+    airui.label({
+        parent = input_card,
+        text = "波形输入",
+        x = 10,
+        y = 10,
+        w = card_width - 20,
+        h = 30,
+        font_size = 16,
+        color = 0x000000,
+    })
+
+    -- 点击事件
+    input_card:set_on_click(function()
+        log.info("waveform_page", "点击示波器输入卡片")
+        _G.show_page("tsb_wavein_page")
+    end)
+
+    -- 示波器输出卡片
+    local output_card = airui.container({
+        parent = scroll_container,
+        x = padding * 2 + card_width,
+        y = y_offset,
+        w = card_width,
+        h = card_height,
+        color = 0x72DDF7,
+        radius = 8,
+    })
+
+    -- 示波器输出标题
+    airui.label({
+        parent = output_card,
+        text = "波形输出",
+        x = 10,
+        y = 10,
+        w = card_width - 20,
+        h = 30,
+        font_size = 16,
+        color = 0x000000,
+    })
+
+    -- 点击事件
+    output_card:set_on_click(function()
+        log.info("waveform_page", "点击示波器输出卡片")
+        _G.show_page("tsb_waveout_page")
+    end)
+
+    -- 底部信息
+    common_ui.create_status_bar(main_container)
+end
+
+-- 初始化页面
+function tsb_waveform_page.init(params)
+    tsb_waveform_page.create_ui()
+end
+
+-- 清理页面
+function tsb_waveform_page.cleanup()
+    if main_container then
+        main_container:destroy()
+        main_container = nil
+    end
+end
+
+return tsb_waveform_page

+ 526 - 0
script/tsb_ui/tsb_wavein_page.lua

@@ -0,0 +1,526 @@
+--[[
+@module  tsb_wavein_page
+@summary 波形输入页面
+@version 1.0
+@date    2026.03.18
+@author  李一玮
+@usage
+本文件是波形输入页面,展示波形数据和控制功能。
+]]
+
+local tsb_wavein_page = {}
+
+-- 页面UI元素
+local main_container = nil
+local scroll_container = nil
+local chart_timer = nil          -- 数据推送定时器ID
+local page_active = false        -- 页面是否活跃,用于定时器安全
+local common_ui = require("tsb_common_page")
+
+local chart = nil              -- 图表对象
+local freq_label = nil         -- 频率显示标签
+local vmax_label = nil         -- 电压最大值标签
+local vmin_label = nil         -- 电压最小值标签
+local trigger_threshold_input = nil -- 触发阈值输入框
+local trigger_type_btn = nil   -- 触发类型按钮
+local trigger_mode_btn = nil   -- 触发方式按钮
+
+-- 控制参数
+local time_scale = "100ms"     -- 时间档位
+local vertical_scale = "1V"     -- 垂直档位
+local trigger_threshold = "0"   -- 触发阈值
+local trigger_type = "上升沿"   -- 触发类型:上升沿、下降沿、双边沿
+local trigger_mode = "自动"     -- 触发方式:自动、普通、单次
+
+-- 创建数字键盘
+local function create_numeric_keyboard()
+    return airui.keyboard({
+        x = 0,
+        y = 0,
+        w = 480,
+        h = 220,
+        mode = "numeric",
+        auto_hide = true,
+        bg_color = 0xf1f1f1,
+        on_commit = function()
+            log.info("keyboard", "commit")
+        end
+    })
+end
+
+-- 创建UI
+function tsb_wavein_page.create_ui()
+    main_container = airui.container({
+        x = 0,
+        y = 0,
+        w = 480,
+        h = 320,
+        color = 0xF5F5F5,
+    })
+
+    --------------------- 标题栏 ------------------------
+    local title_bar = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 0,
+        w = 480,
+        h = 30,
+        color = 0xFFD93D,
+    })
+
+    airui.label({
+        parent = title_bar,
+        text = "波形输入",
+        x = 200,
+        y = 8,
+        w = 80,
+        h = 20,
+        font_size = 16,
+        color = 0xFFFFFF,
+    })
+    
+    -- 标题栏公共信息展示
+    common_ui.add_battery_display(title_bar)
+    common_ui.create_back_button(title_bar, tsb_wavein_page.cleanup)
+    ---------------------------------------------------
+
+    -- 主容器
+    scroll_container = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 30,
+        w = 480,
+        h = 270,
+        color = 0xFFFFFF,
+    })
+
+    -- 图表区域(左上方)
+    local chart_container = airui.container({
+        parent = scroll_container,
+        x = 10,
+        y = 10,
+        w = 320,
+        h = 200,
+        color = 0xFFFFFF,
+        radius = 8,
+        border_width = 1,
+        border_color = 0xDDDDDD,
+    })
+
+    chart = airui.chart({
+        parent = chart_container,
+        x = 10,
+        y = 10,
+        w = 300,
+        h = 180,
+        y_min = 0,
+        y_max = 100,
+        point_count = 100,              -- 增加点数以适应宽屏
+        update_mode = "shift",           -- 滚动模式
+        line_color = 0x00b4ff,
+        line_width = 2,
+        hdiv = 5,
+        vdiv = 4,
+    })
+
+    -- 预置一组初始值(平滑过渡)
+    chart:set_values(1, {50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 68, 66, 64, 62, 60, 58, 56, 54, 52, 50, 48, 46, 44, 42, 40, 38, 36, 34, 32, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50})
+
+    -- 控制区域(右侧)
+    local control_container = airui.container({
+        parent = scroll_container,
+        x = 340,
+        y = 10,
+        w = 130,
+        h = 155,
+        color = 0xFFFFFF,
+        radius = 8,
+        border_width = 1,
+        border_color = 0xDDDDDD,
+    })
+
+    local control_y = 10
+
+    -- 时间档位
+    airui.label({
+        parent = control_container,
+        text = "时间档位",
+        x = 10,
+        y = control_y,
+        w = 110,
+        h = 20,
+        font_size = 12,
+        color = 0x333333,
+    })
+    airui.dropdown({
+        parent = control_container,
+        x = 10,
+        y = control_y + 20,
+        w = 100,
+        h = 25,
+        options = {"1s", "500ms", "200ms", "100ms", "50ms", "20ms", "10ms", "5ms", "2ms", "1ms", "500us"},
+        default_index = 3, -- 默认100ms
+        on_change = function(self, idx)
+            local options = {"1s", "500ms", "200ms", "100ms", "50ms", "20ms", "10ms", "5ms", "2ms", "1ms", "500us"}
+            time_scale = options[idx + 1]
+            log.info("chart", "时间档位: " .. time_scale)
+        end
+    })
+    control_y = control_y + 50
+
+    -- 垂直档位
+    airui.label({
+        parent = control_container,
+        text = "垂直档位",
+        x = 10,
+        y = control_y,
+        w = 110,
+        h = 20,
+        font_size = 12,
+        color = 0x333333,
+    })
+    airui.dropdown({
+        parent = control_container,
+        x = 10,
+        y = control_y + 20,
+        w = 100,
+        h = 25,
+        options = {"10V", "5V", "2V", "1V", "500mv", "200mv"},
+        default_index = 3, -- 默认1V
+        on_change = function(self, idx)
+            local options = {"10V", "5V", "2V", "1V", "500mv", "200mv"}
+            vertical_scale = options[idx + 1]
+            log.info("chart", "垂直档位: " .. vertical_scale)
+        end
+    })
+    control_y = control_y + 50
+
+    -- 水平偏移
+    airui.label({
+        parent = control_container,
+        text = "水平偏移",
+        x = 10,
+        y = control_y,
+        w = 110,
+        h = 20,
+        font_size = 12,
+        color = 0x333333,
+    })
+    local h_offset_container = airui.container({
+        parent = control_container,
+        x = 10,
+        y = control_y + 20,
+        w = 110,
+        h = 25,
+        color = 0xFFFFFF,
+        radius = 4,
+    })
+    airui.button({
+        parent = h_offset_container,
+        text = "←",
+        x = 5,
+        y = 2,
+        w = 40,
+        h = 20,
+        on_click = function()
+            log.info("chart", "水平偏移左")
+        end
+    })
+    airui.button({
+        parent = h_offset_container,
+        text = "→",
+        x = 60,
+        y = 2,
+        w = 40,
+        h = 20,
+        on_click = function()
+            log.info("chart", "水平偏移右")
+        end
+    })
+    control_y = control_y + 50
+
+    -- 垂直偏移
+    airui.label({
+        parent = control_container,
+        text = "垂直偏移",
+        x = 10,
+        y = control_y,
+        w = 110,
+        h = 20,
+        font_size = 12,
+        color = 0x333333,
+    })
+    local v_offset_container = airui.container({
+        parent = control_container,
+        x = 10,
+        y = control_y + 20,
+        w = 110,
+        h = 25,
+        color = 0xFFFFFF,
+        radius = 4,
+    })
+    airui.button({
+        parent = v_offset_container,
+        text = "↑",
+        x = 5,
+        y = 2,
+        w = 40,
+        h = 20,
+        on_click = function()
+            log.info("chart", "垂直偏移上")
+        end
+    })
+    control_y = control_y + 35
+    airui.button({
+        parent = v_offset_container,
+        text = "↓",
+        x = 60,
+        y = 2,
+        w = 40,
+        h = 20,
+        on_click = function()
+            log.info("chart", "垂直偏移下")
+        end
+    })
+
+    -- 触发控制区域
+    local trigger_container = airui.container({
+        parent = scroll_container,
+        x = 340,
+        y = 170,
+        w = 130,
+        h = 90,
+        color = 0xFFFFFF,
+        radius = 8,
+        border_width = 1,
+        border_color = 0xDDDDDD,
+    })
+
+    -- 触发阈值
+    airui.label({
+        parent = trigger_container,
+        text = "触发阈值",
+        x = 10,
+        y = 5,
+        w = 60,
+        h = 20,
+        font_size = 12,
+        color = 0x333333,
+    })
+    trigger_threshold_input = airui.textarea({
+        parent = trigger_container,
+        x = 10,
+        y = 25,
+        w = 70,
+        h = 25,
+        text = "500",
+        max_len = 5,
+        keyboard = create_numeric_keyboard()
+    })
+    airui.label({
+        parent = trigger_container,
+        text = "mv",
+        x = 90,
+        y = 30,
+        w = 30,
+        h = 20,
+        font_size = 12,
+        color = 0x333333,
+    })
+
+    -- 触发类型
+    trigger_type_btn = airui.button({
+        parent = trigger_container,
+        text = "上升沿",
+        x = 10,
+        y = 55,
+        w = 55,
+        h = 25,
+        font_size = 10,
+        on_click = function(self)
+            if trigger_type == "上升沿" then
+                trigger_type = "下降沿"
+            elseif trigger_type == "下降沿" then
+                trigger_type = "双边沿"
+            else
+                trigger_type = "上升沿"
+            end
+            self:set_text(trigger_type)
+            log.info("chart", "触发类型: " .. trigger_type)
+        end
+    })
+
+    -- 触发方式
+    trigger_mode_btn = airui.button({
+        parent = trigger_container,
+        text = "自动",
+        x = 70,
+        y = 55,
+        w = 50,
+        h = 25,
+        font_size = 10,
+        on_click = function(self)
+            if trigger_mode == "自动" then
+                trigger_mode = "普通"
+            elseif trigger_mode == "普通" then
+                trigger_mode = "单次"
+            else
+                trigger_mode = "自动"
+            end
+            self:set_text(trigger_mode)
+            log.info("chart", "触发方式: " .. trigger_mode)
+        end
+    })
+
+    -- 信息显示区域(图表下方)
+    local info_container = airui.container({
+        parent = scroll_container,
+        x = 10,
+        y = 220,
+        w = 320,
+        h = 40,
+        color = 0xFFFFFF,
+        radius = 8,
+        border_width = 1,
+        border_color = 0xDDDDDD,
+    })
+
+    airui.label({
+        parent = info_container,
+        text = "频率:",
+        x = 5,
+        y = 10,
+        w = 40,
+        h = 20,
+        font_size = 13,
+        color = 0x333333,
+    })
+    freq_label = airui.label({
+        parent = info_container,
+        text = "10.0 Hz",
+        x = 40,
+        y = 10,
+        w = 60,
+        h = 20,
+        font_size = 13,
+        color = 0x333333,
+    })
+
+    airui.label({
+        parent = info_container,
+        text = "V大:",
+        x = 110,
+        y = 10,
+        w = 60,
+        h = 20,
+        font_size = 13,
+        color = 0x333333,
+    })
+    vmax_label = airui.label({
+        parent = info_container,
+        text = "80.0 mV",
+        x = 140,
+        y = 10,
+        w = 65,
+        h = 20,
+        font_size = 13,
+        color = 0x333333,
+    })
+
+    airui.label({
+        parent = info_container,
+        text = "V小:",
+        x = 220,
+        y = 10,
+        w = 80,
+        h = 20,
+        font_size = 13,
+        color = 0x333333,
+    })
+    vmin_label = airui.label({
+        parent = info_container,
+        text = "20.0 mV",
+        x = 250,
+        y = 10,
+        w = 65, 
+        h = 20,
+        font_size = 13,
+        color = 0x333333,
+    })
+
+    -- 底部信息
+    common_ui.create_status_bar(main_container)
+end
+
+-- 定时器回调:模拟10Hz数据推送
+local function chart_timer_cb()
+    if not page_active then
+        return      -- 页面已销毁,不再更新
+    end
+
+    -- 简单的正弦波模拟
+    local tick = _G.__chart_tick or 0
+    tick = tick + 1
+    _G.__chart_tick = tick
+
+    local base = 50 + 30 * math.sin(tick * 0.1)
+    local noise = math.random(-3, 3)
+    local value = math.floor(base + noise + 0.5)
+    -- 限制范围
+    if value < 0 then value = 0 end
+    if value > 100 then value = 100 end
+
+    if chart then
+        chart:push(1, value)
+    end
+
+    -- 每50个周期更新一次信息显示
+    if tick % 50 == 0 then
+        if freq_label then
+            freq_label:set_text("10.0 Hz")
+        end
+        if vmax_label then
+            vmax_label:set_text("80.0 mV")
+        end
+        if vmin_label then
+            vmin_label:set_text("20.0 mV")
+        end
+        log.info("chart", "running 10Hz, sample=", value)
+    end
+end
+
+-- 初始化页面
+function tsb_wavein_page.init(params)
+    tsb_wavein_page.create_ui()
+    page_active = true
+
+    -- 启动定时器(100ms = 10Hz)
+    if chart_timer then
+        sys.timerStop(chart_timer)
+    end
+    chart_timer = sys.timerLoopStart(chart_timer_cb, 100)
+end
+
+-- 清理页面
+function tsb_wavein_page.cleanup()
+    page_active = false
+    if chart_timer then
+        sys.timerStop(chart_timer)
+        chart_timer = nil
+    end
+
+    if main_container then
+        main_container:destroy()
+        main_container = nil
+        scroll_container = nil
+        chart = nil
+        freq_label = nil
+        vmax_label = nil
+        vmin_label = nil
+        trigger_threshold_input = nil
+        trigger_type_btn = nil
+        trigger_mode_btn = nil
+    end
+end
+
+return tsb_wavein_page

+ 270 - 0
script/tsb_ui/tsb_waveout_page.lua

@@ -0,0 +1,270 @@
+--[[
+@module  tsb_waveout_page
+@summary 波形输出页面
+@version 1.0
+@date    2026.03.18
+@author  李一玮
+@usage
+本文件是波形输出页面,用于配置和控制波形输出。
+]]
+
+local tsb_waveout_page = {}
+
+-- 页面UI元素
+local main_container = nil
+local common_ui = require("tsb_common_page")
+
+-- 配置参数
+local wave_type = "正弦波"      -- 波形类型
+local amplitude = "5.0"         -- 幅度(V)
+local frequency = "1000"        -- 频率(Hz)
+local duty_cycle = "50"         -- 占空比(%)
+local is_running = false         -- 是否正在运行
+
+-- 创建数字键盘
+local function create_numeric_keyboard()
+    return airui.keyboard({
+        x = 0,
+        y = 0,
+        w = 480,
+        h = 160,
+        mode = "numeric",
+        auto_hide = true,
+        bg_color = 0xf1f1f1,
+        on_commit = function()
+            log.info("keyboard", "commit")
+        end
+    })
+end
+
+-- 创建UI
+function tsb_waveout_page.create_ui()
+    main_container = airui.container({
+        x = 0,
+        y = 0,
+        w = 480,
+        h = 320,
+        color = 0xF5F5F5,
+    })
+
+    --------------------- 标题栏 ------------------------
+    local title_bar = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 0,
+        w = 480,
+        h = 30,
+        color = 0x72DDF7,
+    })
+
+    airui.label({
+        parent = title_bar,
+        text = "波形输出",
+        x = 200,
+        y = 8,
+        w = 80,
+        h = 20,
+        font_size = 16,
+        color = 0xFFFFFF,
+    })
+
+    -- 标题栏公共信息展示
+    common_ui.add_battery_display(title_bar)
+    common_ui.create_back_button(title_bar, tsb_waveout_page.cleanup)
+    ---------------------------------------------------
+
+    -- 主容器
+    local scroll_container = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 30,
+        w = 480,
+        h = 270,
+        color = 0xF5F5F5,
+    })
+
+    -- 配置容器
+    local config_container = airui.container({
+        parent = scroll_container,
+        x = 20,
+        y = 20,
+        w = 440,
+        h = 180,
+        color = 0xFFFFFF,
+        radius = 8,
+        border_width = 1,
+        border_color = 0xDDDDDD,
+    })
+
+    local config_y = 20
+
+    -- 波形类型
+    airui.label({
+        parent = config_container,
+        text = "波形类型",
+        x = 20,
+        y = config_y,
+        w = 80,
+        h = 25,
+        font_size = 14,
+        color = 0x333333,
+    })
+    local wave_type_dropdown = airui.dropdown({
+        parent = config_container,
+        x = 100,
+        y = config_y-8,
+        w = 100,
+        h = 35,
+        options = {"正弦波", "方波", "三角波", "锯齿波"},
+        default_index = 0,
+        on_change = function(self, idx)
+            local options = {"正弦波", "方波", "三角波", "锯齿波"}
+            wave_type = options[idx + 1]
+            log.info("waveout", "波形类型: " .. wave_type)
+        end
+    })
+    config_y = config_y + 40
+
+    -- 幅度(峰峰值)
+    airui.label({
+        parent = config_container,
+        text = "幅度 (V)",
+        x = 20,
+        y = config_y,
+        w = 80,
+        h = 35,
+        font_size = 14,
+        color = 0x333333,
+    })
+    local amplitude_input = airui.textarea({
+        parent = config_container,
+        x = 100,
+        y = config_y-8,
+        w = 100,
+        h = 35,
+        text = "5.0",
+        max_len = 5,
+        keyboard = create_numeric_keyboard()
+    })
+    config_y = config_y + 40
+
+    -- 频率
+    airui.label({
+        parent = config_container,
+        text = "频率 (Hz)",
+        x = 20,
+        y = config_y,
+        w = 80,
+        h = 25,
+        font_size = 14,
+        color = 0x333333,
+    })
+    local frequency_input = airui.textarea({
+        parent = config_container,
+        x = 100,
+        y = config_y-8,
+        w = 100,
+        h = 35,
+        text = "1000",
+        max_len = 6,
+        keyboard = create_numeric_keyboard()
+    })
+    config_y = config_y + 40
+
+    -- 占空比(仅方波可用)
+    airui.label({
+        parent = config_container,
+        text = "占空比 (%)",
+        x = 20,
+        y = config_y,
+        w = 80,
+        h = 25,
+        font_size = 14,
+        color = 0x333333,
+    })
+    local duty_cycle_input = airui.textarea({
+        parent = config_container,
+        x = 100,
+        y = config_y-8,
+        w = 100,
+        h = 35,
+        text = "50",
+        max_len = 3,
+        keyboard = create_numeric_keyboard()
+    })
+
+    -- 控制按钮区域
+    local button_container = airui.container({
+        parent = scroll_container,
+        x = 20,
+        y = 210,
+        w = 440,
+        h = 40,
+        color = 0xF5F5F5,
+    })
+
+    -- 开始按钮
+    local start_btn = airui.button({
+        parent = button_container,
+        text = "开始",
+        x = 100,
+        y = 0,
+        w = 100,
+        h = 35,
+        color = 0x4CAF50,
+        text_color = 0xFFFFFF,
+        stype = { bg_color = 0x2B6FF1,border_color = 0x2B6FF1, text_color = 0xFFFFFF, radius = 8 },
+        on_click = function(self)
+            if not is_running then
+                is_running = true
+                self:set_text("运行中")
+                self:set_color(0xFF9800)
+                -- 获取配置参数
+                amplitude = amplitude_input:get_text()
+                frequency = frequency_input:get_text()
+                duty_cycle = duty_cycle_input:get_text()
+                log.info("waveout", "开始输出波形", wave_type, amplitude, frequency, duty_cycle)
+                -- 这里可以添加实际的波形输出代码
+            end
+        end
+    })
+
+    -- 停止按钮
+    local stop_btn = airui.button({
+        parent = button_container,
+        text = "停止",
+        x = 240,
+        y = 0,
+        w = 100,
+        h = 35,
+        color = 0xF44336,
+        text_color = 0xFFFFFF,
+        on_click = function(self)
+            if is_running then
+                is_running = false
+                start_btn:set_text("开始")
+                start_btn:set_color(0x4CAF50)
+                log.info("waveout", "停止输出波形")
+                -- 这里可以添加停止波形输出的代码
+            end
+        end
+    })
+
+    -- 底部信息
+    common_ui.create_status_bar(main_container)
+end
+
+-- 初始化页面
+function tsb_waveout_page.init(params)
+    tsb_waveout_page.create_ui()
+end
+
+-- 清理页面
+function tsb_waveout_page.cleanup()
+    if main_container then
+        main_container:destroy()
+        main_container = nil
+    end
+end
+
+return tsb_waveout_page

+ 370 - 0
script/tsb_ui/tsb_wlan_page.lua

@@ -0,0 +1,370 @@
+--[[
+@module  tsb_wlan_page
+@summary 网络配置页面
+@version 1.0
+@date    2026.03.17
+@author  李一玮
+@usage
+本文件是网络配置页面,展示网络配置的各种用法。
+]]
+
+local tsb_wlan_page = {}
+
+-- 页面UI元素
+local main_container = nil
+local common_ui = require("tsb_common_page")
+
+-- 创建UI
+function tsb_wlan_page.create_ui()
+    main_container = airui.container({
+        x = 0,
+        y = 0,
+        w = 480,
+        h = 320,
+        color = 0xFFFFFF,
+    })
+
+    --------------------- 标题栏 ------------------------
+    local title_bar = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 0,
+        w = 480,
+        h = 30,
+        color = 0xCE93D8,
+    })
+
+    airui.label({
+        parent = title_bar,
+        text = "网络设置",
+        x = 200,
+        y = 10,
+        w = 80,
+        h = 20,
+        font_size = 16,
+        color = 0xFFFFFF,
+    })
+
+    -- 标题栏公共信息展示
+    common_ui.add_battery_display(title_bar)
+    common_ui.create_back_button(title_bar, tsb_wlan_page.cleanup)
+    ---------------------------------------------------
+
+    -- 滚动容器
+    local scroll_container = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 30,
+        w = 480,
+        h = 260,
+        color = 0xFFFFFF,
+    })
+
+    local keyboard1 = airui.keyboard({
+        x = 0,
+        y = 0,
+        w = 480,
+        h = 160,                        -- x, y, 键盘默认打开ALIGN_BOTTOM_MID,位置从中下方开始计算
+        mode = "lower",               -- 键盘模式,可选 "text"/"upper"/"lower"/"numeric"
+        auto_hide = true,               -- 自动隐藏键盘
+        bg_color = 0xf1f1f1,            -- 键盘背景颜色为灰色,可选,不设置则透明
+        on_commit = function()          -- 确认事件回调,只有在按下确认键时才会触发
+            log.info("keyboard", "commit")
+        end
+    })
+
+    --------------------- 4G网络配置 ------------------------
+    -- 4G网络容器
+    local network4g_container = airui.container({
+        parent = scroll_container,
+        x = 20,
+        y = 10,
+        w = 440,
+        h = 80,
+        color = 0xF5F5F5,
+        radius = 8,
+    })
+
+    -- 4G网络标题
+    airui.label({
+        parent = network4g_container,
+        text = "4G网络配置",
+        x = 10,
+        y = 10,
+        w = 120,
+        h = 30,
+        font_size = 16,
+        color = 0xCE93D8,
+    })
+
+    -- 4G开关标签
+    airui.label({
+        parent = network4g_container,
+        text = "4G网络:",
+        x = 10,
+        y = 40,
+        w = 80,
+        h = 30,
+        font_size = 14,
+    })
+
+    -- 4G开关状态
+    local network4g_status = airui.label({
+        parent = network4g_container,
+        text = "开启",
+        x = 80,
+        y = 40,
+        w = 60,
+        h = 30,
+        font_size = 14,
+        color = 0x4CAF50,
+    })
+
+    -- 4G开关按钮
+    local network4g_switch = airui.button({
+        parent = network4g_container,
+        x = 350,
+        y = 40,
+        w = 80,
+        h = 30,
+        text = "关闭",
+        on_click = function(self)
+            local current_status = network4g_status:get_text()
+            if current_status == "开启" then
+                network4g_status:set_text("关闭")
+                network4g_status:set_color(0xF44336)
+                self:set_text("开启")
+                log.info("set_4g", "关闭4G网络")
+                -- 这里可以添加关闭4G网络的逻辑
+            else
+                network4g_status:set_text("开启")
+                network4g_status:set_color(0x4CAF50)
+                self:set_text("关闭")
+                log.info("set_4g", "开启4G网络")
+                -- 这里可以添加开启4G网络的逻辑
+            end
+        end
+    })
+    ---------------------------------------------------
+
+    --------------------- WIFI配置 ------------------------
+    -- WIFI配置容器
+    local wifi_container = airui.container({
+        parent = scroll_container,
+        x = 20,
+        y = 100,
+        w = 440,
+        h = 160,
+        color = 0xF5F5F5,
+        radius = 8,
+    })
+
+    -- WIFI配置标题
+    airui.label({
+        parent = wifi_container,
+        text = "WIFI配置",
+        x = 10,
+        y = 10,
+        w = 100,
+        h = 30,
+        font_size = 16,
+        color = 0xCE93D8,
+    })
+
+    -- WIFI开关标签
+    airui.label({
+        parent = wifi_container,
+        text = "WIFI:",
+        x = 10,
+        y = 40,
+        w = 60,
+        h = 30,
+        font_size = 14,
+    })
+
+    -- WIFI开关状态
+    local wifi_status = airui.label({
+        parent = wifi_container,
+        text = "开启",
+        x = 80,
+        y = 40,
+        w = 60,
+        h = 30,
+        font_size = 14,
+        color = 0x4CAF50,
+    })
+
+    -- WIFI开关按钮
+    local wifi_switch = airui.button({
+        parent = wifi_container,
+        x = 350,
+        y = 40,
+        w = 80,
+        h = 30,
+        text = "关闭",
+        on_click = function(self)
+            local current_status = wifi_status:get_text()
+            if current_status == "开启" then
+                wifi_status:set_text("关闭")
+                wifi_status:set_color(0xF44336)
+                self:set_text("开启")
+                log.info("set_wifi", "关闭WIFI")
+                -- 这里可以添加关闭WIFI的逻辑
+            else
+                wifi_status:set_text("开启")
+                wifi_status:set_color(0x4CAF50)
+                self:set_text("关闭")
+                log.info("set_wifi", "开启WIFI")
+                -- 这里可以添加开启WIFI的逻辑
+            end
+        end
+    })
+
+    -- WIFI名称标签
+    airui.label({
+        parent = wifi_container,
+        text = "WIFI名称:",
+        x = 10,
+        y = 80,
+        w = 100,
+        h = 30,
+        font_size = 14,
+    })
+
+    -- WIFI名称输入框
+    local wifi_name_input = airui.textarea({
+        parent = wifi_container,
+        x = 110,
+        y = 80,
+        w = 200,
+        h = 30,
+        text = "",
+        keyboard = keyboard1
+    })
+
+    -- WIFI密码标签
+    airui.label({
+        parent = wifi_container,
+        text = "WIFI密码:",
+        x = 10,
+        y = 120,
+        w = 100,
+        h = 30,
+        font_size = 14,
+    })
+
+    -- WIFI密码输入框
+    local wifi_password_input = airui.textarea({
+        parent = wifi_container,
+        x = 110,
+        y = 120,
+        w = 200,
+        h = 30,
+        text = "",
+        keyboard = keyboard1
+    })
+
+    -- 连接按钮
+    local connect_wifi_btn = airui.button({
+        parent = wifi_container,
+        x = 320,
+        y = 90,
+        w = 100,
+        h = 40,
+        text = "连接",
+        on_click = function(self)
+            local wifi_name = wifi_name_input:get_text()
+            local wifi_password = wifi_password_input:get_text()
+            log.info("set_wifi", "连接WIFI:" .. wifi_name)
+            -- 这里可以添加连接WIFI的逻辑
+        end
+    })
+    ---------------------------------------------------
+
+    --------------------- 网络状态 ------------------------
+    -- 网络状态容器
+    local network_status_container = airui.container({
+        parent = scroll_container,
+        x = 20,
+        y = 280,
+        w = 440,
+        h = 100,
+        color = 0xF5F5F5,
+        radius = 8,
+    })
+
+    -- 网络状态标题
+    airui.label({
+        parent = network_status_container,
+        text = "网络状态",
+        x = 10,
+        y = 10,
+        w = 100,
+        h = 30,
+        font_size = 16,
+        color = 0xCE93D8,
+    })
+
+    -- IP地址标签
+    airui.label({
+        parent = network_status_container,
+        text = "IP地址:",
+        x = 10,
+        y = 40,
+        w = 80,
+        h = 30,
+        font_size = 14,
+    })
+
+    -- IP地址值
+    airui.label({
+        parent = network_status_container,
+        text = "192.168.1.100",
+        x = 100,
+        y = 40,
+        w = 200,
+        h = 30,
+        font_size = 14,
+    })
+
+    -- 信号强度标签
+    airui.label({
+        parent = network_status_container,
+        text = "信号强度:",
+        x = 10,
+        y = 70,
+        w = 80,
+        h = 30,
+        font_size = 14,
+    })
+
+    -- 信号强度值
+    airui.label({
+        parent = network_status_container,
+        text = "90%",
+        x = 100,
+        y = 70,
+        w = 50,
+        h = 30,
+        font_size = 14,
+    })
+    ---------------------------------------------------
+
+    -- 底部信息
+    common_ui.create_status_bar(main_container)
+end
+
+-- 初始化页面
+function tsb_wlan_page.init(params)
+    tsb_wlan_page.create_ui()
+end
+
+-- 清理页面
+function tsb_wlan_page.cleanup()
+    if main_container then
+        main_container:destroy()
+        main_container = nil
+    end
+end
+
+return tsb_wlan_page

+ 340 - 0
script/tsb_ui/tsb_ywy_1_page.lua

@@ -0,0 +1,340 @@
+--[[
+@module  tsb_ywy_1_page
+@summary 液位仪查询演示页面
+@version 1.0
+@date    2026.03.16
+@author  李一玮
+@usage
+    本文件是液位仪查询演示页面,展示液位仪查询的各种用法。
+]]
+
+local tsb_ywy_1_page = {}
+local common_ui = require("tsb_common_page")
+
+-- 页面UI元素
+local main_container = nil
+
+-- 创建UI
+function tsb_ywy_1_page.create_ui()
+    main_container = airui.container({
+        x = 0,
+        y = 0,
+        w = 480,
+        h = 320,
+        color = 0xF5F5F5,
+    })
+
+    --------------------- 标题栏 ------------------------
+    local title_bar = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 0,
+        w = 480,
+        h = 30,
+        color = 0x4CAF50,
+    })
+
+    airui.label({
+        parent = title_bar,
+        text = "液位仪查询",
+        x = 200,
+        y = 8,
+        w = 120,
+        h = 20,
+        font_size = 16,
+        color = 0xFFFFFF,
+    })
+
+    -- 标题栏公共信息展示
+    common_ui.add_battery_display(title_bar)
+    common_ui.create_back_button(title_bar, tsb_ywy_1_page.cleanup)
+    ---------------------------------------------------
+
+    -- 滚动容器
+    local scroll_container = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 30,
+        w = 480,
+        h = 290,
+        color = 0xFFFFFF,
+    })
+
+    ------------------- 分页内容区 ------------------------
+    --液位仪查询页面
+    local query_page = airui.container({
+        parent = scroll_container,
+        x = 0,
+        y = 0,
+        w = 480,
+        h = 290,
+        color = 0xFFFFFF,--0xE8F5E9
+    })
+
+    --------------------- 总罐数和查询按钮 ------------------------
+    local top_container = airui.container({
+        parent = query_page,
+        x = 0,
+        y = 5,
+        w = 480,
+        h = 40,
+        color = 0xFFFFFF,
+    })
+
+    -- 总罐数标签
+    airui.label({
+        parent = top_container,
+        text = "总罐数",
+        x = 10,
+        y = 10,
+        w = 60,
+        h = 30,
+        font_size = 15,
+    })
+
+    -- 总罐数值
+    local total_tanks_label = airui.label({
+        parent = top_container,
+        text = "12",
+        x = 70,
+        y = 10,
+        w = 40,
+        h = 30,
+        font_size = 15,
+    })
+
+    -- 单位标签
+    airui.label({
+        parent = top_container,
+        text = "个",
+        x = 100,
+        y = 10,
+        w = 20,
+        h = 30,
+        font_size = 15,
+    })
+
+    -- A口查询按钮
+    local a_query_btn = airui.button({
+        parent = top_container,
+        x = 210,
+        y = 1,
+        w = 80,
+        h = 30,
+        text = "A口查询",
+        on_click = function(self)
+            log.info("ywy_query", "A口查询按钮被点击")
+        end
+    })
+
+    -- B口查询按钮
+    local b_query_btn = airui.button({
+        parent = top_container,
+        x = 300,
+        y = 1,
+        w = 80,
+        h = 30,
+        text = "B口查询",
+        on_click = function(self)
+            log.info("ywy_query", "B口查询按钮被点击")
+        end
+    })
+
+    -- 485查询按钮
+    local rs485_query_btn = airui.button({
+        parent = top_container,
+        x = 390,
+        y = 1,
+        w = 80,
+        h = 30,
+        text = "485查询",
+        on_click = function(self)
+            log.info("ywy_query", "485查询按钮被点击")
+        end
+    })
+    -------------------------------------------------
+
+    ------------------- 表格区域 ------------------------
+    local table_container = airui.container({
+        parent = query_page,
+        x = 0,
+        y = 40,
+        w = 480,
+        h = 220,
+        color = 0xE8F5E9,
+    })
+
+    -- 创建表格
+    local tank_table = airui.table({
+        parent = table_container,
+        x = 0,
+        y = 0,
+        w = 480,
+        h = 220,
+        rows = 11, -- 10个罐 + 表头
+        cols = 10,
+        col_width = {70, 100, 100, 100, 70, 70, 70, 80, 70, 150}, -- 调整列宽以适应内容,确保表头横向显示
+        border_color = 0x4CAF50,
+    })
+
+    -- 设置表头
+    local headers = {"罐号", "油水体积1", "油水体积2", "剩余体积", "油高", "水高", "温度", "水体积", "串口", "读取时间"}
+    for i, header in ipairs(headers) do
+        tank_table:set_cell_text(0, i-1, header)
+    end
+
+    -- 示例数据
+    local tank_data = {
+        {"1", "14919.52", "14767.34", "12080.47", "16577.25", "0.00", "28.50", "0.00", "A口", "2024/07/02 09:30:46"},
+        {"2", "20292.46", "20085.48", "6707.53", "22547.17", "0.00", "28.50", "0.00", "A口", "2024/07/02 09:30:46"},
+        {"3", "10936.19", "10824.64", "16063.80", "12151.32", "0.00", "28.50", "0.00", "A口", "2024/07/02 09:30:46"},
+        {"4", "22748.73", "22516.69", "4251.26", "25276.37", "0.00", "28.50", "0.00", "A口", "2024/07/02 09:30:46"},
+        {"5", "7282.67", "7208.38", "19717.32", "8091.85", "0.00", "28.50", "0.00", "A口", "2024/07/02 09:30:46"},
+        {"6", "14497.98", "14350.10", "12502.01", "16108.87", "0.00", "28.50", "0.00", "A口", "2024/07/02 09:30:46"},
+        {"7", "1984.31", "1964.07", "25015.68", "2204.79", "0.00", "28.50", "0.00", "A口", "2024/07/02 09:30:46"},
+        {"8", "9565.87", "9468.30", "17434.12", "10628.75", "0.00", "28.50", "0.00", "A口", "2024/07/02 09:30:46"},
+        {"9", "15678.90", "15432.10", "11234.56", "17890.12", "0.00", "28.50", "0.00", "A口", "2024/07/02 09:30:46"},
+        {"10", "8765.43", "8654.32", "18976.54", "9876.54", "0.00", "28.50", "0.00", "A口", "2024/07/02 09:30:46"},
+    }
+
+    -- 填充表格数据
+    for i, data in ipairs(tank_data) do
+        for j, value in ipairs(data) do
+            tank_table:set_cell_text(i, j-1, value)
+        end
+    end
+    -------------------------------------------------
+
+    ------------------- 执行结果和日志按钮 ------------------------
+    local bottom_container = airui.container({
+        parent = query_page,
+        x = 0,
+        y = 260,
+        w = 480,
+        h = 30,
+        color = 0xFFFFFF,
+    })
+
+    -- 执行结果标签
+    airui.label({
+        parent = bottom_container,
+        text = "执行结果:",
+        x = 10,
+        y = 10,
+        w = 80,
+        h = 20,
+        font_size = 15,
+    })
+
+    -- 执行结果值
+    local result_label = airui.label({
+        parent = bottom_container,
+        text = "执行成功",
+        x = 90,
+        y = 10,
+        w = 100,
+        h = 20,
+        font_size = 15,
+    })
+
+
+    -- 日志窗口
+    local log_window = airui.container({
+        parent = scroll_container,
+        x = 20,
+        y = 5,
+        w = 440,
+        h = 250,
+        color = 0xF1F8E9,
+        radius = 0,
+    })
+
+    -- 日志窗口标题栏
+    local log_title_bar = airui.container({
+        parent = log_window,
+        x = 0,
+        y = 0,
+        w = 440,
+        h = 30,
+        color = 0x4CAF50,
+    })
+
+    airui.label({
+        parent = log_title_bar,
+        text = "原始日志",
+        x = 10,
+        y = 8,
+        w = 150,
+        h = 20,
+        font_size = 15,
+        color = 0xFFFFFF,
+    })
+
+    -- 关闭按钮
+    local close_btn = airui.button({
+        parent = log_title_bar,
+        x = 408,
+        y = 2,
+        w = 30,
+        h = 28,
+        text = "X",
+        on_click = function(self)
+            log_window:hide()
+        end
+    })
+
+    -- 日志内容区域
+    local log_content = airui.textarea({
+        parent = log_window,
+        x = 10,
+        y = 40,
+        w = 420,
+        h = 200,
+        text = "00 01 02 03 04 05 06 07\n" ..
+               "08 09 0A 0B 0C 0D 0E 0F\n" ..
+               "10 11 12 13 14 15 16 17\n" ..
+               "18 19 1A 1B 1C 1D 1E 1F\n" ..
+               "20 21 22 23 24 25 26 27\n" ..
+               "28 29 2A 2B 2C 2D 2E 2F\n" ..
+               "30 31 32 33 34 35 36 37\n" ..
+               "38 39 3A 3B 3C 3D 3E 3F",
+    })
+
+    log_window:hide()
+
+    -- 查看原始日志按钮
+    local log_btn = airui.button({
+        parent = bottom_container,
+        x = 375,
+        y = 1,
+        w = 100,
+        h = 27,
+        text = "查看原始日志",
+        on_click = function(self)
+            log.info("ywy_query", "查看原始日志按钮被点击")
+            -- 显示日志窗口
+            log_window:open()
+        end
+    })
+    ---------------------------------------------------
+
+    -- 底部信息
+    --common_ui.create_status_bar(main_container)
+end
+
+-- 初始化页面
+function tsb_ywy_1_page.init(params)
+    tsb_ywy_1_page.create_ui()
+end
+
+-- 清理页面
+function tsb_ywy_1_page.cleanup()
+    -- 停止定时器
+    common_ui.cleanup()
+    if main_container then
+        main_container:destroy()
+        main_container = nil
+    end
+end
+
+return tsb_ywy_1_page

+ 163 - 0
script/tsb_ui/tsb_ywy_2_page.lua

@@ -0,0 +1,163 @@
+--[[
+@module  tsb_ywy_2_page
+@summary 液位仪透传页面
+@version 1.0
+@date    2026.03.16
+@author  李一玮
+@usage
+本文件是液位仪透传页面,展示液位仪的透传功能。
+]]
+
+local tsb_ywy_2_page = {}
+local common_ui = require("tsb_common_page")
+
+-- 页面UI元素
+local main_container = nil
+
+-- 创建UI
+function tsb_ywy_2_page.create_ui()
+    main_container = airui.container({
+        x = 0,
+        y = 0,
+        w = 480,
+        h = 320,
+        color = 0xF5F5F5,
+    })
+
+    --------------------- 标题栏 ------------------------
+    local title_bar = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 0,
+        w = 480,
+        h = 30,
+        color = 0x4CAF50,
+    })
+
+    airui.label({
+        parent = title_bar,
+        text = "液位仪透传",
+        x = 200,
+        y = 8,
+        w = 120,
+        h = 20,
+        font_size = 16,
+        color = 0xFFFFFF,
+    })
+
+    -- 标题栏公共信息展示
+    common_ui.add_battery_display(title_bar)
+    common_ui.create_back_button(title_bar, tsb_ywy_2_page.cleanup)
+    ---------------------------------------------------
+
+    -- 滚动容器
+    local scroll_container = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 30,
+        w = 480,
+        h = 290,
+        color = 0xFFFFFF,--0xF5F5F5
+    })
+    ---------------------------------------------------
+
+    --------------------- 分页内容区 ------------------------
+    -- 液位仪透传页面
+    local passthrough_page = airui.container({
+        parent = scroll_container,
+        x = 0,
+        y = 0,
+        w = 480,
+        h = 290,
+        color = 0xF0F7E8,--0xF1F8E9
+    })
+
+    --------------------- A口接收数据 ------------------------
+    -- A口标签
+    airui.label({
+        parent = passthrough_page,
+        text = "A口接收数据",
+        x = 65,
+        y = 10,
+        w = 120,
+        h = 20,
+        font_size = 16,
+    })
+
+    -- A口数据容器
+    local a_port_container = airui.container({
+        parent = passthrough_page,
+        x = 2,
+        y = 30,
+        w = 240,
+        h = 250,
+        color = 0xFFFFFF,
+    })
+
+    -- A口数据显示
+    local a_port_data = airui.textarea({
+        parent = a_port_container,
+        x = 5,
+        y = 5,
+        w = 230,
+        h = 245,
+        text = "00 01 02 03 04 05 06 07\n" ..
+               "08 09 0A 0B 0C 0D 0E 0F\n" 
+    })
+    ---------------------------------------------------
+
+    --------------------- B口接收数据 ------------------------
+    -- B口标签
+    airui.label({
+        parent = passthrough_page,
+        text = "B口接收数据",
+        x = 310,
+        y = 10,
+        w = 120,
+        h = 20,
+        font_size = 16,
+    })
+
+    -- B口数据容器
+    local b_port_container = airui.container({
+        parent = passthrough_page,
+        x = 238,
+        y = 30,
+        w = 240,
+        h = 250,
+        color = 0xFFFFFF,
+    })
+
+    -- B口数据显示
+    local b_port_data = airui.textarea({
+        parent = b_port_container,
+        x = 5,
+        y = 5,
+        w = 230,
+        h = 245,
+        text = "40 41 42 43 44 45 46 47\n" ..
+               "48 49 4A 4B 4C 4D 4E 4F\n"
+    })
+    ---------------------------------------------------
+
+    -- 底部信息
+    --common_ui.create_status_bar(main_container)
+end
+
+-- 初始化页面
+function tsb_ywy_2_page.init(params)
+    tsb_ywy_2_page.create_ui()
+end
+
+-- 清理页面
+function tsb_ywy_2_page.cleanup()
+    -- 停止定时器
+    common_ui.cleanup()
+    if main_container then
+        main_container:destroy()
+        main_container = nil
+    end
+end
+
+
+return tsb_ywy_2_page

+ 146 - 0
script/tsb_ui/tsb_ywy_page.lua

@@ -0,0 +1,146 @@
+--[[
+@module  tsb_ywy_page
+@summary 液位仪演示页面
+@version 1.0
+@date    2026.02.05
+@author  江访
+@usage
+本文件是液位仪演示页面,展示液位仪的各种用法。
+]]
+
+local tsb_ywy_page = {}
+local common_ui = require("tsb_common_page")
+
+-- 页面UI元素
+local main_container = nil
+
+-- 创建UI
+function tsb_ywy_page.create_ui()
+    main_container = airui.container({
+        x = 0,
+        y = 0,
+        w = 480,
+        h = 320,
+        color = 0xF5F5F5,
+    })
+
+    --------------------- 标题栏 ------------------------
+    local title_bar = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 0,
+        w = 480,
+        h = 30,
+        color = 0x4CAF50,
+    })
+
+    airui.label({
+        parent = title_bar,
+        text = "液位仪",
+        x = 210,
+        y = 8,
+        w = 80,
+        h = 20,
+        font_size = 16,
+        color = 0xFFFFFF,
+    })
+
+    -- 标题栏公共信息展示
+    common_ui.add_battery_display(title_bar)
+    common_ui.create_back_button(title_bar, tsb_ywy_page.cleanup)
+    ---------------------------------------------------
+
+    -- 滚动容器
+    local scroll_container = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 30,
+        w = 480,
+        h = 270,
+        color = 0xFFFFFF,
+    })
+
+    --------------------- 第一排控制区 ------------------------
+    local control_container = airui.container({
+        parent = scroll_container,
+        x = 0,
+        y = 0,
+        w = 480,
+        h = 80,
+        color = 0xFFFFFF,
+    })
+
+    -- 波特率标签
+    airui.label({
+        parent = control_container,
+        text = "波特率:",
+        x = 10,
+        y = 28,
+        w = 60,
+        h = 30,
+        font_size = 15,
+    })
+
+    -- 波特率下拉框
+    local baudrate_dropdown = airui.dropdown({
+        parent = control_container,
+        x = 70,
+        y = 20,
+        w = 120,
+        h = 35,
+        options = {"2400", "4800", "9600", "19200", "38400", "57600", "115200"},
+        default_index = 2, -- 默认选择9600
+        on_change = function(self,idx)
+            log.info("baudrate", "选择了波特率:" .. self.options[idx + 1])
+        end
+    })
+
+    -- 液位仪查询按钮
+    local query_btn = airui.button({
+        parent = control_container,
+        x = 220,
+        y = 20,
+        w = 100,
+        h = 35,
+        text = "液位仪查询",
+        on_click = function(self)
+            log.info("ywy_page", "点击液位仪查询按钮")
+            _G.show_page("tsb_ywy_1_page")
+        end
+    })
+
+    -- 液位仪透传按钮
+    local passthrough_btn = airui.button({
+        parent = control_container,
+        x = 340,
+        y = 20,
+        w = 100,
+        h = 35,
+        text = "液位仪透传",
+        on_click = function(self)
+            log.info("ywy_page", "点击液位仪透传按钮")
+            _G.show_page("tsb_ywy_2_page")
+        end
+    })
+    ---------------------------------------------------
+
+    -- 底部信息
+    common_ui.create_status_bar(main_container)
+end
+
+-- 初始化页面
+function tsb_ywy_page.init(params)
+    tsb_ywy_page.create_ui()
+end
+
+-- 清理页面
+function tsb_ywy_page.cleanup()
+    -- 停止定时器
+    common_ui.cleanup()
+    if main_container then
+        main_container:destroy()
+        main_container = nil
+    end
+end
+
+return tsb_ywy_page

+ 213 - 0
script/uart485_test.lua

@@ -0,0 +1,213 @@
+--[[
+@module  485_uart
+@summary 485串口功能模块
+@version 1.0
+@date    2025.09.23
+@author  魏健强
+@usage
+本demo演示的核心功能为:
+1.开启串口,配置波特率等参数;
+2.设置接收回调函数
+3.定时向串口发送数据
+]]
+local uartid = 12        -- 根据实际设备选取不同的uartid
+local uart485Pin = 141    -- 用于控制485接收和发送的使能引脚(根据实际设备选取不同引脚)
+
+local rdbuf = ""      -- 全局接收缓存,用于拼接分包数据
+
+-- 协议格式
+local FRAME_HEAD = "\xFE\xFE"  -- 帧头(2字节)
+local FRAME_HEAD_LEN = 12      --- 帧头长度12字节
+local CHECK_FIELD_LEN = 2      -- CRC校验位占2字节
+
+
+local function head_paser(data)
+    local netHeader = {pro_ver=0,msg_id=0,msg_type1=0,msg_type2=0,msg_len=0}
+    local nextpos = 1
+
+    if #data <FRAME_HEAD_LEN then return false,nil end
+
+
+    nextpos, netHeader.head = pack.unpack(data, "<H", nextpos)      -- 校验帧头
+    if netHeader.head ~= 0xFEFE then
+        log.info("net","error","帧头错误,应为:FEFE,实际为:", string.format("0x%04X",netHeader.head))
+        return false,nil
+    end
+
+    nextpos, netHeader.pro_ver   = pack.unpack(data, "b", nextpos)    -- 获取协议版本
+    nextpos, netHeader.msg_id    = pack.unpack(data, "<I", nextpos)    -- 获取消息序列号
+    nextpos, netHeader.msg_type1 = pack.unpack(data, "b", nextpos)    -- 获取一级消息类型
+    nextpos, netHeader.msg_type2 = pack.unpack(data, "<H", nextpos)    -- 获取二级消息类型
+    nextpos, netHeader.msg_len   = pack.unpack(data, "<H", nextpos)    -- 校验帧长
+
+
+    -- log.info("head_paser", "解析帧头成功", 
+    --     "协议版本", netHeader.pro_ver,
+    --     "消息ID", netHeader.msg_id,
+    --     "数据长度N", netHeader.msg_len)
+
+    return true, netHeader
+end
+
+local function parse(data)
+    if not data or #data == 0 then
+        return false, data, nil
+    end
+
+    log.info("parse", "开始解析数据", data:toHex())
+    -- 步骤1:查找帧头FE FE的位置
+    local head_pos = string.find(data, FRAME_HEAD, 1, true)
+    if not head_pos then
+        log.warn("parse", "未找到帧头FE FE,缓存长度:", #data)
+        return false, data, nil  -- 无帧头,返回原缓存
+    end
+
+    -- 步骤2:清理帧头前的无效数据(比如乱码、残留字节)
+    local remain_buf = string.sub(data, head_pos)
+    log.info("parse", "找到帧头,清理无效数据后缓存长度:", #remain_buf)
+
+    -- 步骤3:判断是否够帧头长度(12字节),不够则返回等待后续数据
+    if #remain_buf < FRAME_HEAD_LEN then
+        log.warn("parse", "缓存仅"..#remain_buf.."字节,不足帧头12字节,等待分包")
+        return false, remain_buf, nil
+    end
+
+    -- 步骤4:解析帧头,获取数据长度N
+    local head_ok, netHeader = head_paser(remain_buf)
+    if not head_ok then
+        log.error("parse", "帧头解析失败,丢弃当前帧头,继续查找下一个")
+        -- 跳过当前错误帧头,从下一个字节继续解析(避免死循环)
+        return true, string.sub(remain_buf, 2), nil
+    end
+
+    -- 步骤5:计算完整帧总长度 = 帧头(12) + 数据长度(N)
+    local frame_total_len = FRAME_HEAD_LEN + netHeader.msg_len
+    log.info("parse", "计算完整帧长度:", frame_total_len, "(帧头12 + 数据"..netHeader.msg_len.." + CRC2)")
+
+    -- 步骤6:判断缓存是否够完整帧长度,不够则返回等待分包
+    if #remain_buf < frame_total_len then
+        log.warn("parse", "缓存仅"..#remain_buf.."字节,不足完整帧"..frame_total_len.."字节,等待分包")
+        return false, remain_buf, nil
+    end
+
+    -- 步骤7:提取完整帧,剩余数据留待下次解析
+    local full_frame = string.sub(remain_buf, 1, frame_total_len)  -- 完整帧
+    local unproc_buf = string.sub(remain_buf, frame_total_len + 1) -- 剩余未解析数据
+
+    log.info("parse", "提取完整帧,长度:", #full_frame, "十六进制:", full_frame:toHex())
+    return true, unproc_buf, full_frame
+end
+
+local function proc(data)
+    if not data or #data == 0 then return end
+    
+    -- 步骤1:追加新数据到全局缓存
+    rdbuf = rdbuf .. data
+    log.info("proc", "全局缓存总长度:", #rdbuf)
+
+    local result, unproc_buf, full_frame
+    unproc_buf = rdbuf
+
+    -- 步骤2:循环解析所有完整帧(处理黏包)
+    while true do
+        -- 调用parse解析,返回:是否继续、剩余缓存、完整帧
+        result, unproc_buf, full_frame = parse(unproc_buf)
+        
+        -- 解析出完整帧则发布事件
+        if full_frame then
+            sys.publish("UART_485_RECIVE", full_frame)
+        end
+
+        -- 终止条件:无剩余数据/解析失败/无完整帧
+        if not result or not unproc_buf or unproc_buf == "" then
+            break
+        end
+    end
+
+    -- 步骤3:更新全局缓存为未解析的剩余数据
+    rdbuf = unproc_buf or ""
+    log.info("proc", "解析完成,剩余缓存长度:", #rdbuf)
+end
+
+
+local function uart_cb(id, len)
+    local data = ""
+    repeat
+        data = uart.read(id, 1024)  -- 一次读取最多1024字节
+        if not data or #data == 0 then break end
+        
+        -- 打印十六进制(二进制数据必须看十六进制,字符打印会乱码)
+        log.info("uart_cb", "接收数据长度:", #data)
+        --log.info("uart_cb", "接收数据,长度:", #data, "十六进制:", data:toHex())
+        
+        -- 处理数据(拼接+解析)
+        proc(data)
+    until data == ""
+end
+
+
+sys.subscribe("UART_485_RECIVE", function(full_frame)
+    if not full_frame or #full_frame == 0 then return end
+
+    -- 解析帧头(再次确认,可选)
+    local head_ok, netHeader = head_paser(full_frame)
+    if not head_ok then
+        log.error("业务解析", "帧头解析失败")
+        return
+    end
+
+    local data_part = string.sub(full_frame, FRAME_HEAD_LEN + 1, #full_frame - CHECK_FIELD_LEN)
+    
+    local crc_data_part = string.sub(full_frame, 1, #full_frame - CHECK_FIELD_LEN)
+
+    local crc_str = string.sub(full_frame, #full_frame - CHECK_FIELD_LEN + 1, #full_frame)
+
+    local _, recv_crc = pack.unpack(crc_str, "<H", 1)  -- 第一个返回值是nextpos,无用;第二个是CRC数值
+
+    local calc_crc = crypto.crc16("IBM", crc_data_part)
+
+    log.info("业务解析", 
+        "接收CRC数值:", recv_crc, "十六进制:", string.format("0x%04X", recv_crc),
+        "计算CRC数值:", calc_crc, "十六进制:", string.format("0x%04X", calc_crc))
+
+    if recv_crc ~= calc_crc then
+        log.error("业务解析", "CRC校验失败!")
+        return  -- 校验失败,放弃处理该帧
+    end
+    log.info("业务解析", "CRC校验通过")
+
+    -- 7. 校验通过后处理业务逻辑(示例:根据消息类型分支处理)
+    log.info("业务解析完成", 
+        "一级消息类型:", netHeader.msg_type1,
+        "二级消息类型:", netHeader.msg_type2,
+        "消息ID:", netHeader.msg_id)
+    
+    -- 示例:根据不同消息类型处理数据
+    if netHeader.msg_type1 == 0x02 and netHeader.msg_type2 == 0x2002 then
+        log.info("业务解析", "处理控制类指令,数据:", data_part:toHex())
+        sys.publish("UART_485_RECIVE_CONTROL", data_part)
+    -- elseif netHeader.msg_type1 == 0x02 then
+    --     log.info("业务解析", "处理数据上报指令,数据:", data_part:toHex())
+
+    end
+end)
+
+-- local function uart_send()
+--     -- 循环两秒向串口发一次数据
+--     while true do
+--         sys.wait(2000)
+--         uart.write(uartid, "test data.")
+--     end
+-- end
+
+--初始化
+gpio.setup(3,0)
+uart.setup(uartid, 115200, 8, 1, uart.NONE, uart.LSB, 1024, uart485Pin, 0, 20000)
+
+-- 收取数据会触发回调, 这里的"receive" 是固定值
+uart.on(uartid, "receive", uart_cb)
+
+-- 发送数据完成会触发回调, 这里的"sent" 是固定值
+uart.on(uartid, "sent", uart_send_cb)
+
+--sys.taskInit(uart_send)

+ 53 - 0
script/uart_test.lua

@@ -0,0 +1,53 @@
+--[[
+@module  simple_uart
+@summary 简易串口功能模块
+@version 1.0
+@date    2025.09.23
+@author  魏健强
+@usage
+本demo演示的核心功能为:
+1.开启串口,配置波特率等参数;
+2.设置接收回调函数
+3.定时向串口发送数据
+]]
+local uartid = 1 -- 根据实际设备选取不同的uartid
+
+local function uart_send()
+    -- 循环两秒向串口发一次数据
+    while true do
+        sys.wait(2000)
+        uart.write(uartid, "test data.")
+    end
+end
+
+local function uart_send_cb(id)
+    log.info("uart", id , "数据发送完成回调")
+end
+
+local function uart_cb(id, len)
+  local s = ""
+    repeat
+        s = uart.read(id, 128) -- 读取缓冲区中的数据,这里设置的一次读最多128字节
+        if #s > 0 then -- #s 是取字符串的长度
+            -- 关于收发hex值,请查阅 https://doc.openluat.com/article/583
+            log.info("uart", "receive", id, #s, s)
+            uart.write(uartid, s)
+            -- log.info("uart", "receive", id, #s, s:toHex()) --如果传输二进制/十六进制数据, 部分字符不可见, 不代表没收到
+        end
+    until s == ""
+end
+--初始化
+uart.setup(
+    uartid,--串口id
+    115200,--波特率
+    8,--数据位
+    1--停止位
+)
+
+-- 收取数据会触发回调, 这里的"receive" 是固定值
+uart.on(uartid, "receive", uart_cb)
+
+-- 发送数据完成会触发回调, 这里的"sent" 是固定值
+uart.on(uartid, "sent", uart_send_cb)
+
+sys.taskInit(uart_send)

+ 516 - 0
script/ui/all_component_page.lua

@@ -0,0 +1,516 @@
+--[[
+@module  all_component_page
+@summary 所有组件演示页面
+@version 1.0
+@date    2026.02.05
+@author  江访
+@usage
+本文件是所有组件的综合演示页面,展示AirUI所有组件的用法。
+]]
+
+local all_component_page = {}
+
+-- 页面UI元素
+local main_container = nil
+
+-- 创建UI
+function all_component_page.create_ui()
+    -- 创建主容器
+    main_container = airui.container({
+        x = 0,
+        y = 0,
+        w = 320,
+        h = 480,
+        color = 0xF5F5F5,
+        color_opacity = 255,   -- v1.0.3 新增
+    })
+
+    -- 标题栏
+    local title_bar = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 0,
+        w = 320,
+        h = 50,
+        color = 0x007AFF,
+    })
+
+    airui.label({
+        parent = title_bar,
+        text = "所有组件演示",
+        x = 10,
+        y = 15,
+        w = 200,
+        h = 20,
+        font_size = 16,         -- v1.0.1 改为 font_size
+        color = 0xFFFFFF,
+    })
+
+    -- 返回按钮
+    local back_btn = airui.button({
+        parent = title_bar,
+        x = 250,
+        y = 10,
+        w = 60,
+        h = 30,
+        text = "返回",
+        on_click = function(self)   -- v1.0.3 支持 self 参数
+            go_back()
+        end
+    })
+
+        -- 注册虚拟键盘,先创建再在 textarea 配置里复用
+    local keyboard1 = airui.keyboard({
+        x = 0,
+        y = 0,
+        w = 320,
+        h = 220,                        -- x, y, 键盘默认打开ALIGN_BOTTOM_MID,位置从中下方开始计算
+        mode = "text",                  -- 键盘模式,可选 "text"/"upper"/"lower"/"numeric"
+        auto_hide = true,               -- 自动隐藏键盘
+        bg_color = 0xf1f1f1,            -- 键盘背景颜色为灰色,可选,不设置则透明
+        on_commit = function()          -- 确认事件回调,只有在按下确认键时才会触发
+            log.info("keyboard", "commit")
+        end
+    })
+
+    -- 滚动容器
+    local scroll_container = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 60,
+        w = 320,
+        h = 370,
+        color = 0xF5F5F5,
+    })
+
+    -- 组件展示区域
+    local y_offset = 10
+
+    -- 1. 标签组件
+    airui.label({
+        parent = scroll_container,
+        text = "1. 标签组件 (Label)",
+        x = 10,
+        y = y_offset,
+        w = 300,
+        h = 20,
+        font_size = 14,
+    })
+
+    local demo_label = airui.label({
+        parent = scroll_container,
+        text = "这是一个标签",
+        x = 20,
+        y = y_offset + 30,
+        w = 120,
+        h = 30,
+        font_size = 14,
+        on_click = function(self)
+            self:set_text("标签被点击")   -- v1.0.3 使用 self
+        end
+    })
+
+    y_offset = y_offset + 70
+
+    -- 2. 按钮组件
+    airui.label({
+        parent = scroll_container,
+        text = "2. 按钮组件 (Button)",
+        x = 10,
+        y = y_offset,
+        w = 300,
+        h = 20,
+        font_size = 14,
+    })
+
+    local demo_button = airui.button({
+        parent = scroll_container,
+        x = 20,
+        y = y_offset + 30,
+        w = 100,
+        h = 40,
+        text = "点击我",
+        on_click = function(self)
+            log.info("all_component", "按钮被点击")
+        end
+    })
+
+    y_offset = y_offset + 80
+
+    -- 3. 容器组件
+    airui.label({
+        parent = scroll_container,
+        text = "3. 容器组件 (Container)",
+        x = 10,
+        y = y_offset,
+        w = 300,
+        h = 20,
+        font_size = 14,
+    })
+
+    local demo_container = airui.container({
+        parent = scroll_container,
+        x = 20,
+        y = y_offset + 30,
+        w = 280,
+        h = 60,
+        color = 0xE3F2FD,
+        radius = 8,
+    })
+
+    airui.label({
+        parent = demo_container,
+        text = "容器内的标签",
+        x = 10,
+        y = 20,
+        w = 120,
+        h = 20,
+        font_size = 14,
+    })
+
+    y_offset = y_offset + 100
+
+    -- 4. 进度条组件
+    airui.label({
+        parent = scroll_container,
+        text = "4. 进度条组件 (Progress Bar)",
+        x = 10,
+        y = y_offset,
+        w = 300,
+        h = 20,
+        font_size = 14,
+    })
+
+    local demo_bar = airui.bar({
+        parent = scroll_container,
+        x = 20,
+        y = y_offset + 30,
+        w = 200,
+        h = 20,
+        value = 65,
+        indicator_color = 0x4CAF50,
+        show_progress_text = true,           -- v1.0.3 新增
+        progress_text_format = "%d%%",       -- v1.0.3 新增
+    })
+
+    y_offset = y_offset + 60
+
+    -- 5. 开关组件
+    airui.label({
+        parent = scroll_container,
+        text = "5. 开关组件 (Switch)",
+        x = 10,
+        y = y_offset,
+        w = 300,
+        h = 20,
+        font_size = 14,
+    })
+
+    local demo_switch = airui.switch({
+        parent = scroll_container,
+        x = 20,
+        y = y_offset + 30,
+        w = 60,
+        h = 30,
+        checked = true,
+        on_change = function(self)           -- v1.0.3 回调参数为 self
+            log.info("all_component", "开关状态: " .. tostring(self:get_state()))
+        end
+    })
+
+    y_offset = y_offset + 70
+
+    -- 6. 下拉框组件
+    airui.label({
+        parent = scroll_container,
+        text = "6. 下拉框组件 (Dropdown)",
+        x = 10,
+        y = y_offset,
+        w = 300,
+        h = 20,
+        font_size = 14,
+    })
+
+    local demo_dropdown = airui.dropdown({
+        parent = scroll_container,
+        x = 20,
+        y = y_offset + 30,
+        w = 150,
+        h = 35,
+        options = { "选项1", "选项2", "选项3" },
+        default_index = 0,
+        on_change = function(idx)   -- 回调参数为索引(0起始)
+            log.info("all_component", "选择了选项: " .. (idx + 1))
+        end
+    })
+
+    y_offset = y_offset + 75
+
+    -- 7. 表格组件
+    airui.label({
+        parent = scroll_container,
+        text = "7. 表格组件 (Table)",
+        x = 10,
+        y = y_offset,
+        w = 300,
+        h = 20,
+        font_size = 14,
+    })
+
+    local demo_table = airui.table({
+        parent = scroll_container,
+        x = 20,
+        y = y_offset + 30,
+        w = 280,
+        h = 80,
+        rows = 3,
+        cols = 3,
+        col_width = { 80, 80, 80 },
+        border_color = 0x607D8B,
+    })
+
+    demo_table:set_cell_text(0, 0, "姓名")
+    demo_table:set_cell_text(0, 1, "年龄")
+    demo_table:set_cell_text(0, 2, "城市")
+    demo_table:set_cell_text(1, 0, "张三")
+    demo_table:set_cell_text(1, 1, "25")
+    demo_table:set_cell_text(1, 2, "北京")
+
+    y_offset = y_offset + 120
+
+    -- 8. 输入框组件
+    airui.label({
+        parent = scroll_container,
+        text = "8. 输入框组件 (Textarea)",
+        x = 10,
+        y = y_offset,
+        w = 300,
+        h = 20,
+        font_size = 14,
+    })
+
+    local demo_textarea = airui.textarea({
+        parent = scroll_container,
+        x = 20,
+        y = y_offset + 30,
+        w = 150,
+        h = 60,
+        placeholder = "请输入文本...",
+        max_len = 50,
+        keyboard = keyboard1
+    })
+
+    y_offset = y_offset + 100
+
+    -- 9. 消息框组件(按钮演示)
+    airui.label({
+        parent = scroll_container,
+        text = "9. 消息框组件 (Msgbox)",
+        x = 10,
+        y = y_offset,
+        w = 300,
+        h = 20,
+        font_size = 14,
+    })
+
+    local demo_msgbox_btn = airui.button({
+        parent = scroll_container,
+        x = 20,
+        y = y_offset + 30,
+        w = 120,
+        h = 40,
+        text = "显示消息",
+        on_click = function(self)
+            local msg = airui.msgbox({
+                text = "这是一个消息框",
+                buttons = { "确定" },
+                on_action = function(self, label)
+                    if label == "确定" then
+                        self:hide()
+                    end
+                end
+            })
+            msg:show()
+        end
+    })
+
+    y_offset = y_offset + 80
+
+    -- 10. 图片组件(需要图片文件)
+    airui.label({
+        parent = scroll_container,
+        text = "10. 图片组件 (Image)",
+        x = 10,
+        y = y_offset,
+        w = 300,
+        h = 20,
+        font_size = 14,
+    })
+
+    -- 假设有图片文件
+    local demo_image = airui.image({
+        parent = scroll_container,
+        x = 20,
+        y = y_offset + 30,
+        w = 80,
+        h = 80,
+        src = "/luadb/logo.jpg",
+        on_click = function(self)
+            log.info("all_component", "图片被点击")
+        end
+    })
+
+    y_offset = y_offset + 120
+
+    -- 11. 选项卡组件
+    airui.label({
+        parent = scroll_container,
+        text = "11. 选项卡组件 (Tabview)",
+        x = 10,
+        y = y_offset,
+        w = 300,
+        h = 20,
+        font_size = 14,
+    })
+
+    local demo_tabview = airui.tabview({
+        parent = scroll_container,
+        x = 20,
+        y = y_offset + 30,
+        w = 280,
+        h = 150,
+        tabs = { "标签1", "标签2" },
+        active = 0,
+    })
+
+    -- 获取页面内容并添加标签
+    local tab1_content = demo_tabview:get_content(0)
+    if tab1_content then
+        airui.label({
+            parent = tab1_content,
+            text = "标签1内容",
+            x = 20,
+            y = 20,
+            w = 240,
+            h = 30,
+            font_size = 14,
+        })
+    end
+
+    y_offset = y_offset + 190
+
+    -- 12. 窗口组件
+    airui.label({
+        parent = scroll_container,
+        text = "12. 窗口组件 (Window)",
+        x = 10,
+        y = y_offset,
+        w = 300,
+        h = 20,
+        font_size = 14,
+    })
+
+    local demo_window_btn = airui.button({
+        parent = scroll_container,
+        x = 20,
+        y = y_offset + 30,
+        w = 120,
+        h = 40,
+        text = "打开窗口",
+        on_click = function(self)
+            local win = airui.win({
+                parent = airui.screen,
+                title = "演示窗口",
+                x = 60,
+                y = 120,
+                w = 200,
+                h = 250,
+                close_btn = true,
+                auto_center = false,
+                -- on_close 在 v1.0.3 无效,v1.0.4 修复
+            })
+
+            win:add_content(airui.label({
+                text = "窗口内容演示",
+                x = 20,
+                y = 20,
+                w = 160,
+                h = 30,
+                font_size = 14,
+            }))
+
+            win:add_content(airui.button({
+                text = "关闭",
+                x = 60,
+                y = 70,
+                w = 80,
+                h = 40,
+                on_click = function(self)
+                    win:close()
+                end
+            }))
+        end
+    })
+
+    y_offset = y_offset + 80
+
+    -- 组件总数显示
+    airui.label({
+        parent = scroll_container,
+        text = "共展示12个AirUI组件",
+        x = 10,
+        y = y_offset + 20,
+        w = 300,
+        h = 20,
+        font_size = 14,
+    })
+
+    -- 交互提示
+    local interact_label = airui.label({
+        parent = scroll_container,
+        text = "提示: 点击各个组件查看交互效果",
+        x = 10,
+        y = y_offset + 50,
+        w = 300,
+        h = 20,
+        font_size = 14,
+    })
+
+    -- 组件计数
+    local component_count = 12
+    local count_label = airui.label({
+        parent = scroll_container,
+        text = "组件总数: " .. component_count,
+        x = 10,
+        y = y_offset + 80,
+        w = 300,
+        h = 20,
+        font_size = 14,
+    })
+
+    -- 底部信息
+    airui.label({
+        parent = main_container,
+        text = "AirUI组件综合演示",
+        x = 10,
+        y = 440,
+        w = 300,
+        h = 20,
+        font_size = 14,
+    })
+end
+
+-- 初始化页面
+function all_component_page.init(params)
+    all_component_page.create_ui()
+end
+
+-- 清理页面
+function all_component_page.cleanup()
+    if main_container then
+        main_container:destroy()
+        main_container = nil
+    end
+end
+
+return all_component_page

+ 319 - 0
script/ui/bar_page.lua

@@ -0,0 +1,319 @@
+--[[
+@module  bar_page
+@summary 进度条组件演示页面
+@version 1.0
+@date    2026.02.05
+@author  江访
+@usage
+本文件是进度条组件的演示页面,展示进度条的各种用法。
+]]
+
+local bar_page = {}
+
+-- 页面UI元素
+local main_container = nil
+local progress_value = 0
+local value_label
+local update_timer
+local animated_bar
+
+-- 创建UI
+function bar_page.create_ui()
+    -- 创建主容器
+    main_container = airui.container({
+        x = 0,
+        y = 0,
+        w = 320,
+        h = 480,
+        color = 0xF5F5F5,
+    })
+
+    -- 标题栏
+    local title_bar = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 0,
+        w = 320,
+        h = 50,
+        color = 0x9C27B0,
+    })
+
+    airui.label({
+        parent = title_bar,
+        text = "进度条组件演示",
+        x = 10,
+        y = 15,
+        w = 200,
+        h = 20,
+        font_size = 16,
+        color = 0xFFFFFF,
+    })
+
+    -- 返回按钮
+    local back_btn = airui.button({
+        parent = title_bar,
+        x = 250,
+        y = 10,
+        w = 60,
+        h = 30,
+        text = "返回",
+        on_click = function(self)
+            go_back()
+        end
+    })
+
+    -- 滚动容器
+    local scroll_container = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 60,
+        w = 320,
+        h = 370,
+        color = 0xF5F5F5,
+    })
+
+    -- 示例1: 基本进度条
+    airui.label({
+        parent = scroll_container,
+        text = "示例1: 基本进度条",
+        x = 10,
+        y = 10,
+        w = 300,
+        h = 20,
+        font_size = 14,
+    })
+
+    local basic_bar = airui.bar({
+        parent = scroll_container,
+        x = 20,
+        y = 40,
+        w = 280,
+        h = 20,
+        value = 30,
+        min = 0,
+        max = 100,
+        radius = 10,
+        indicator_color = 0x4CAF50,
+    })
+
+    -- 示例2: 带边框的进度条
+    airui.label({
+        parent = scroll_container,
+        text = "示例2: 带边框进度条",
+        x = 10,
+        y = 80,
+        w = 300,
+        h = 20,
+        font_size = 14,
+    })
+
+    local bordered_bar = airui.bar({
+        parent = scroll_container,
+        x = 20,
+        y = 110,
+        w = 280,
+        h = 25,
+        value = 50,
+        min = 0,
+        max = 100,
+        radius = 12,
+        border_width = 2,
+        border_color = 0x9C27B0,
+        indicator_color = 0x9C27B0,
+        bg_color = 0xF3E5F5,
+    })
+
+    -- 示例3: 动画进度条
+    airui.label({
+        parent = scroll_container,
+        text = "示例3: 动画进度条",
+        x = 10,
+        y = 150,
+        w = 300,
+        h = 20,
+        font_size = 14,
+    })
+
+    -- 显示当前值
+    value_label = airui.label({
+        parent = scroll_container,
+        text = "当前值: 0%",
+        x = 210,
+        y = 225,
+        w = 90,
+        h = 30,
+        font_size = 14,
+    })
+
+    animated_bar = airui.bar({
+        parent = scroll_container,
+        x = 20,
+        y = 180,
+        w = 280,
+        h = 25,
+        value = 0,
+        min = 0,
+        max = 100,
+        radius = 12,
+        indicator_color = 0x2196F3,
+        show_progress_text = true,           -- v1.0.3 新增
+        progress_text_format = "%d%%",
+    })
+
+    -- 控制按钮
+    local start_btn = airui.button({
+        parent = scroll_container,
+        x = 20,
+        y = 220,
+        w = 80,
+        h = 40,
+        text = "开始",
+        on_click = function(self)
+            if update_timer then
+                sys.timerStop(update_timer)
+                update_timer = nil
+                self:set_text("开始")
+            else
+                self:set_text("停止")
+                update_timer = sys.timerLoopStart(function()
+                    local current = animated_bar:get_value()
+                    if current >= 100 then
+                        current = 0
+                    else
+                        current = current + 5
+                    end
+                    animated_bar:set_value(current, true) -- 启用动画
+                    value_label:set_text("当前值: "..current.."%")
+                    progress_value = current
+
+                    if current >= 100 then
+                        sys.timerStop(update_timer)
+                        update_timer = nil
+                        self:set_text("开始")
+                    end
+                end, 200)
+            end
+        end
+    })
+
+    local reset_btn = airui.button({
+        parent = scroll_container,
+        x = 120,
+        y = 220,
+        w = 80,
+        h = 40,
+        text = "重置",
+        on_click = function(self)
+            if update_timer then
+                sys.timerStop(update_timer)
+                update_timer = nil
+                start_btn:set_text("开始")
+            end
+            animated_bar:set_value(0, true)
+        end
+    })
+
+    -- 示例4: 不同颜色进度条
+    airui.label({
+        parent = scroll_container,
+        text = "示例4: 不同颜色进度条",
+        x = 10,
+        y = 280,
+        w = 300,
+        h = 20,
+        font_size = 14,
+    })
+
+    local color_bar = airui.bar({
+        parent = scroll_container,
+        x = 20,
+        y = 310,
+        w = 280,
+        h = 20,
+        value = 75,
+        min = 0,
+        max = 100,
+        radius = 10,
+        indicator_color = 0xFF5722,
+    })
+
+    -- 颜色选择
+    local color_btn1 = airui.button({
+        parent = scroll_container,
+        x = 20,
+        y = 340,
+        w = 60,
+        h = 30,
+        text = "红色",
+        on_click = function(self)
+            color_bar:set_indicator_color(0xF44336)
+        end
+    })
+
+    local color_btn2 = airui.button({
+        parent = scroll_container,
+        x = 90,
+        y = 340,
+        w = 60,
+        h = 30,
+        text = "绿色",
+        on_click = function(self)
+            color_bar:set_indicator_color(0x4CAF50)
+        end
+    })
+
+    local color_btn3 = airui.button({
+        parent = scroll_container,
+        x = 160,
+        y = 340,
+        w = 60,
+        h = 30,
+        text = "蓝色",
+        on_click = function(self)
+            color_bar:set_indicator_color(0x2196F3)
+        end
+    })
+
+    local color_btn4 = airui.button({
+        parent = scroll_container,
+        x = 230,
+        y = 340,
+        w = 60,
+        h = 30,
+        text = "紫色",
+        on_click = function(self)
+            color_bar:set_indicator_color(0x9C27B0)
+        end
+    })
+
+    -- 底部信息
+    airui.label({
+        parent = main_container,
+        text = "提示: 进度条支持动画和颜色自定义",
+        x = 10,
+        y = 440,
+        w = 300,
+        h = 20,
+        font_size = 14,
+    })
+end
+
+-- 初始化页面
+function bar_page.init(params)
+    progress_value = 0
+    bar_page.create_ui()
+end
+
+-- 清理页面
+function bar_page.cleanup()
+    if update_timer then
+        sys.timerStop(update_timer)
+        update_timer = nil
+    end
+    if main_container then
+        main_container:destroy()
+        main_container = nil
+    end
+end
+
+return bar_page

+ 273 - 0
script/ui/button_page.lua

@@ -0,0 +1,273 @@
+--[[
+@module  button_page
+@summary 按钮组件演示页面
+@version 1.0
+@date    2026.02.05
+@author  江访
+@usage
+本文件是按钮组件的演示页面,展示按钮的各种用法。
+]]
+
+local button_page = {}
+
+-- 页面UI元素
+local main_container = nil
+
+-- 创建UI
+function button_page.create_ui()
+    -- 创建主容器
+    main_container = airui.container({
+        x = 0,
+        y = 0,
+        w = 320,
+        h = 480,
+        color = 0xF5F5F5,
+    })
+
+    -- 标题栏
+    local title_bar = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 0,
+        w = 320,
+        h = 50,
+        color = 0xF44336,
+    })
+
+    airui.label({
+        parent = title_bar,
+        text = "按钮组件演示",
+        x = 10,
+        y = 15,
+        w = 200,
+        h = 20,
+        font_size = 16,
+        color = 0xFFFFFF,
+    })
+
+    -- 返回按钮
+    local back_btn = airui.button({
+        parent = title_bar,
+        x = 250,
+        y = 10,
+        w = 60,
+        h = 30,
+        text = "返回",
+        on_click = function(self)
+            go_back()
+        end
+    })
+
+    -- 滚动容器
+    local scroll_container = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 60,
+        w = 320,
+        h = 370,
+        color = 0xF5F5F5,
+    })
+
+    -- 示例1: 基本按钮
+    airui.label({
+        parent = scroll_container,
+        text = "示例1: 基本按钮",
+        x = 10,
+        y = 10,
+        w = 300,
+        h = 20,
+        font_size = 14,
+    })
+
+    local basic_btn = airui.button({
+        parent = scroll_container,
+        x = 20,
+        y = 40,
+        w = 120,
+        h = 40,
+        text = "点击我",
+        on_click = function(self)
+            log.info("button", "基本按钮被点击")
+        end
+    })
+
+    -- 示例2: 不同大小的按钮
+    airui.label({
+        parent = scroll_container,
+        text = "示例2: 不同大小的按钮",
+        x = 10,
+        y = 100,
+        w = 300,
+        h = 20,
+        font_size = 14,
+    })
+
+    local small_btn = airui.button({
+        parent = scroll_container,
+        x = 20,
+        y = 130,
+        w = 80,
+        h = 30,
+        text = "小按钮",
+        on_click = function(self)
+            log.info("button", "小按钮被点击")
+        end
+    })
+
+    local large_btn = airui.button({
+        parent = scroll_container,
+        x = 120,
+        y = 125,
+        w = 180,
+        h = 40,
+        text = "大按钮",
+        on_click = function(self)
+            log.info("button", "大按钮被点击")
+        end
+    })
+
+    -- 示例3: 动态更新文本
+    local dynamic_label = airui.label({
+        parent = scroll_container,
+        text = "示例3: 动态更新文本",
+        x = 10,
+        y = 190,
+        w = 300,
+        h = 20,
+        font_size = 14,
+    })
+
+    local click_count = 0
+    local dynamic_btn = airui.button({
+        parent = scroll_container,
+        x = 20,
+        y = 220,
+        w = 140,
+        h = 40,
+        text = "点击计数: 0",
+        on_click = function(self)
+            click_count = click_count + 1
+            self:set_text("点击计数: " .. click_count)   -- v1.0.3 使用 self
+            dynamic_label:set_text("示例3: 动态更新文本")
+        end
+    })
+
+    -- 示例4: 按钮组
+    airui.label({
+        parent = scroll_container,
+        text = "示例4: 按钮组",
+        x = 10,
+        y = 280,
+        w = 300,
+        h = 20,
+        font_size = 14,
+    })
+
+    local btn_container = airui.container({
+        parent = scroll_container,
+        x = 20,
+        y = 310,
+        w = 280,
+        h = 60,
+        color = 0xE0E0E0,
+        radius = 5,
+    })
+
+    local btn1 = airui.button({
+        parent = btn_container,
+        x = 10,
+        y = 10,
+        w = 80,
+        h = 40,
+        text = "选项1",
+        on_click = function(self)
+            log.info("button", "选项1被选中")
+        end
+    })
+
+    local btn2 = airui.button({
+        parent = btn_container,
+        x = 100,
+        y = 10,
+        w = 80,
+        h = 40,
+        text = "选项2",
+        on_click = function(self)
+            log.info("button", "选项2被选中")
+        end
+    })
+
+    local btn3 = airui.button({
+        parent = btn_container,
+        x = 190,
+        y = 10,
+        w = 80,
+        h = 40,
+        text = "选项3",
+        on_click = function(self)
+            log.info("button", "选项3被选中")
+        end
+    })
+
+    -- 示例5: 销毁按钮
+    airui.label({
+        parent = scroll_container,
+        text = "示例5: 销毁按钮",
+        x = 10,
+        y = 390,
+        w = 300,
+        h = 20,
+        font_size = 14,
+    })
+
+    local toggle_btn = airui.button({
+        parent = scroll_container,
+        x = 20,
+        y = 420,
+        w = 120,
+        h = 40,
+        text = "可点击",
+        on_click = function(self)
+            log.info("button", "按钮被点击")
+        end
+    })
+
+    local disable_btn = airui.button({
+        parent = scroll_container,
+        x = 160,
+        y = 420,
+        w = 120,
+        h = 40,
+        text = "销毁可点击",
+        on_click = function(self)
+            toggle_btn:destroy()
+            log.info("button", "已销毁可点击按钮")
+        end
+    })
+
+    -- 底部信息
+    airui.label({
+        parent = main_container,
+        text = "提示: 按钮支持点击事件和动态更新",
+        x = 10,
+        y = 440,
+        w = 300,
+        h = 20,
+        font_size = 14,
+    })
+end
+
+-- 初始化页面
+function button_page.init(params)
+    button_page.create_ui()
+end
+
+-- 清理页面
+function button_page.cleanup()
+    if main_container then
+        main_container:destroy()
+        main_container = nil
+    end
+end
+
+return button_page

+ 333 - 0
script/ui/chart_page.lua

@@ -0,0 +1,333 @@
+--[[
+@module  chart_page
+@summary 图表组件演示页面
+@version 1.0
+@date    2026.03.02
+@author  自动生成
+@usage
+本文件是图表组件的演示页面,展示图表的各种用法。
+注意:需要确保 airui.chart 组件可用。
+]]
+
+local chart_page = {}
+
+----------------------------------------------------------------
+-- 页面UI元素
+----------------------------------------------------------------
+local main_container   = nil
+local scroll_container = nil
+local chart_timer      = nil          -- 数据推送定时器ID
+local page_active      = false        -- 页面是否活跃,用于定时器安全
+
+local value_text       = nil          -- 显示当前数值
+local point_text       = nil          -- 显示按下的点索引
+local chart            = nil          -- 图表对象
+
+----------------------------------------------------------------
+-- 辅助函数:创建带标题的容器
+----------------------------------------------------------------
+local function create_demo_container(parent, title, x, y, width, height)
+    local container = airui.container({
+        parent = parent,
+        x = x,
+        y = y,
+        w = width,
+        h = height,
+        color = 0xFFFFFF,
+        radius = 8,
+    })
+
+    airui.label({
+        parent = container,
+        text = title,
+        x = 10,
+        y = 5,
+        w = width - 20,
+        h = 25,
+        color = 0x333333,
+        font_size = 14,
+    })
+
+    return container
+end
+
+----------------------------------------------------------------
+-- 创建UI
+----------------------------------------------------------------
+function chart_page.create_ui()
+    main_container = airui.container({
+        parent = airui.screen,
+        x = 0,
+        y = 0,
+        w = 320,
+        h = 480,
+        color = 0xF5F5F5,
+    })
+
+    -- 标题栏
+    local title_bar = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 0,
+        w = 320,
+        h = 50,
+        color = 0x9C27B0,          -- 紫色,与其他页面区分
+    })
+
+    airui.label({
+        parent = title_bar,
+        text = "图表组件演示",
+        x = 10,
+        y = 15,
+        w = 200,
+        h = 20,
+        font_size = 16,
+        color = 0xFFFFFF,
+    })
+
+    -- 返回按钮
+    local back_btn = airui.button({
+        parent = title_bar,
+        x = 250,
+        y = 10,
+        w = 60,
+        h = 30,
+        text = "返回",
+        on_click = function(self)
+            go_back()
+        end
+    })
+
+    -- 滚动容器(确保所有内容可滚动)
+    scroll_container = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 50,
+        w = 320,
+        h = 420,                    -- 留出底部空间
+        color = 0xF5F5F5,
+    })
+
+    local current_y = 10
+
+    --------------------------------------------------------------------
+    -- 示例说明
+    --------------------------------------------------------------------
+    airui.label({
+        parent = scroll_container,
+        text = "图表组件演示 (10Hz 模拟数据)",
+        x = 10,
+        y = current_y,
+        w = 300,
+        h = 20,
+        font_size = 14,
+        color = 0x333333,
+    })
+    current_y = current_y + 25
+
+    --------------------------------------------------------------------
+    -- 数值显示区域
+    --------------------------------------------------------------------
+    local info_container = airui.container({
+        parent = scroll_container,
+        x = 10,
+        y = current_y,
+        w = 300,
+        h = 40,
+        color = 0xEEEEEE,
+        radius = 4,
+    })
+    current_y = current_y + 45
+
+    value_text = airui.label({
+        parent = info_container,
+        text = "当前值: 50",
+        x = 10,
+        y = 10,
+        w = 140,
+        h = 20,
+        font_size = 14,
+        color = 0x333333,
+    })
+
+    point_text = airui.label({
+        parent = info_container,
+        text = "按下点: -1",
+        x = 160,
+        y = 10,
+        w = 130,
+        h = 20,
+        font_size = 14,
+        color = 0x333333,
+    })
+
+    --------------------------------------------------------------------
+    -- 图表组件
+    --------------------------------------------------------------------
+    local chart_container = create_demo_container(scroll_container, "实时曲线", 10, current_y, 300, 200)
+    current_y = current_y + 200 + 10
+
+    chart = airui.chart({
+        parent = chart_container,
+        x = 10,
+        y = 30,
+        w = 280,
+        h = 150,
+        y_min = 0,
+        y_max = 100,
+        point_count = 30,               -- 减少点数以适应窄屏
+        update_mode = "shift",           -- 滚动模式
+        line_color = 0x00b4ff,
+        line_width = 2,
+        hdiv = 5,
+        vdiv = 4,
+        on_point = function(self)
+            if point_text then
+                local idx = self:get_pressed_point()
+                point_text:set_text("按下点: " .. tostring(idx))
+                log.info("chart", "pressed index", idx)
+            end
+        end
+    })
+
+    -- 预置一组初始值(平滑过渡)
+    chart:set_values({50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 68, 66, 64, 62, 60, 58, 56, 54, 52, 50})
+
+    --------------------------------------------------------------------
+    -- 控制按钮区域
+    --------------------------------------------------------------------
+    local control_container = create_demo_container(scroll_container, "控制面板", 10, current_y, 300, 100)
+    current_y = current_y + 100 + 10
+
+    local mode = "shift"
+    local btn_mode = airui.button({
+        parent = control_container,
+        text = "模式: shift",
+        x = 20,
+        y = 30,
+        w = 120,
+        h = 35,
+        on_click = function(self)
+            if mode == "shift" then
+                mode = "circular"
+                chart:set_update_mode("circular")
+                self:set_text("模式: circular")
+            else
+                mode = "shift"
+                chart:set_update_mode("shift")
+                self:set_text("模式: shift")
+            end
+            log.info("chart", "update_mode ->", mode)
+        end
+    })
+
+    local btn_clear = airui.button({
+        parent = control_container,
+        text = "清除",
+        x = 160,
+        y = 30,
+        w = 120,
+        h = 35,
+        on_click = function(self)
+            chart:clear(50)
+            if value_text then
+                value_text:set_text("当前值: 50")
+            end
+            log.info("chart", "clear to 50")
+        end
+    })
+
+    local btn_color = airui.button({
+        parent = control_container,
+        text = "随机颜色",
+        x = 20,
+        y = 70,
+        w = 120,
+        h = 35,
+        on_click = function(self)
+            local color = math.random(0, 0xFFFFFF)
+            chart:set_line_color(color)
+            log.info("chart", "set line color", string.format("%06X", color))
+        end
+    })
+
+    --------------------------------------------------------------------
+    -- 底部提示
+    --------------------------------------------------------------------
+    airui.label({
+        parent = main_container,
+        text = "提示: 点击曲线可查看数据点索引",
+        x = 10,
+        y = 450,
+        w = 300,
+        h = 20,
+        color = 0x666666,
+        font_size = 12,
+    })
+end
+
+----------------------------------------------------------------
+-- 定时器回调:模拟10Hz数据推送
+----------------------------------------------------------------
+local function chart_timer_cb()
+    if not page_active then
+        return      -- 页面已销毁,不再更新
+    end
+
+    -- 简单的三角波模拟
+    local tick = _G.__chart_tick or 0
+    tick = tick + 1
+    _G.__chart_tick = tick
+
+    local base = 50 + 30 * math.sin(tick * 0.1)
+    local noise = math.random(-3, 3)
+    local value = math.floor(base + noise + 0.5)
+    -- 限制范围
+    if value < 0 then value = 0 end
+    if value > 100 then value = 100 end
+
+    if chart and value_text then
+        chart:push(value)
+        value_text:set_text("当前值: " .. tostring(value))
+    end
+
+    if tick % 50 == 0 then
+        log.info("chart", "running 10Hz, sample=", value)
+    end
+end
+
+----------------------------------------------------------------
+-- 初始化页面
+----------------------------------------------------------------
+function chart_page.init(params)
+    chart_page.create_ui()
+    page_active = true
+
+    -- 启动定时器(100ms = 10Hz)
+    if chart_timer then
+        sys.timerStop(chart_timer)
+    end
+    chart_timer = sys.timerLoopStart(chart_timer_cb, 100)
+end
+
+----------------------------------------------------------------
+-- 清理页面
+----------------------------------------------------------------
+function chart_page.cleanup()
+    page_active = false
+    if chart_timer then
+        sys.timerStop(chart_timer)
+        chart_timer = nil
+    end
+
+    if main_container then
+        main_container:destroy()
+        main_container = nil
+        scroll_container = nil
+        value_text = nil
+        point_text = nil
+        chart = nil
+    end
+end
+
+return chart_page

+ 332 - 0
script/ui/container_page.lua

@@ -0,0 +1,332 @@
+--[[
+@module  container_page
+@summary 容器组件演示页面
+@version 1.0
+@date    2026.02.05
+@author  江访
+@usage
+本文件是容器组件的演示页面,展示容器的各种用法。
+]]
+
+local container_page = {}
+
+-- 页面UI元素
+local main_container = nil
+
+-- 创建UI
+function container_page.create_ui()
+    -- 创建主容器
+    main_container = airui.container({
+        x = 0,
+        y = 0,
+        w = 320,
+        h = 480,
+        color = 0xF5F5F5,
+    })
+
+    -- 标题栏
+    local title_bar = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 0,
+        w = 320,
+        h = 50,
+        color = 0xFF9800,
+    })
+
+    airui.label({
+        parent = title_bar,
+        text = "容器组件演示",
+        x = 10,
+        y = 15,
+        w = 200,
+        h = 20,
+        font_size = 16,
+        color = 0xFFFFFF,
+    })
+
+    -- 返回按钮
+    local back_btn = airui.button({
+        parent = title_bar,
+        x = 250,
+        y = 10,
+        w = 60,
+        h = 30,
+        text = "返回",
+        on_click = function(self)
+            go_back()
+        end
+    })
+
+    -- 滚动容器
+    local scroll_container = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 60,
+        w = 320,
+        h = 370,
+        color = 0xF5F5F5,
+    })
+
+    -- 示例1: 基本容器
+    airui.label({
+        parent = scroll_container,
+        text = "示例1: 基本容器",
+        x = 10,
+        y = 10,
+        w = 300,
+        h = 20,
+        font_size = 14,
+    })
+
+    local basic_container = airui.container({
+        parent = scroll_container,
+        x = 20,
+        y = 40,
+        w = 280,
+        h = 80,
+        color = 0xE3F2FD,
+        radius = 8,
+    })
+
+    airui.label({
+        parent = basic_container,
+        text = "这是一个容器",
+        x = 10,
+        y = 10,
+        w = 260,
+        h = 20,
+        font_size = 14,
+    })
+
+    airui.label({
+        parent = basic_container,
+        text = "容器可以作为其他组件的父容器",
+        x = 10,
+        y = 40,
+        w = 260,
+        h = 20,
+        font_size = 14,
+    })
+
+    -- 示例2: 圆角容器
+    airui.label({
+        parent = scroll_container,
+        text = "示例2: 圆角容器",
+        x = 10,
+        y = 130,
+        w = 300,
+        h = 20,
+        font_size = 14,
+    })
+
+    local rounded_container = airui.container({
+        parent = scroll_container,
+        x = 20,
+        y = 160,
+        w = 280,
+        h = 80,
+        color = 0xFFEBEE,
+        radius = 20,
+    })
+
+    airui.label({
+        parent = rounded_container,
+        text = "圆角半径: 20",
+        x = 10,
+        y = 30,
+        w = 260,
+        h = 20,
+        font_size = 14,
+    })
+
+    -- 示例3: 嵌套容器
+    airui.label({
+        parent = scroll_container,
+        text = "示例3: 嵌套容器",
+        x = 10,
+        y = 250,
+        w = 300,
+        h = 20,
+        font_size = 14,
+    })
+
+    local parent_container = airui.container({
+        parent = scroll_container,
+        x = 20,
+        y = 280,
+        w = 280,
+        h = 120,
+        color = 0xE8F5E8,
+        radius = 10,
+    })
+
+    local child1 = airui.container({
+        parent = parent_container,
+        x = 10,
+        y = 10,
+        w = 120,
+        h = 50,
+        color = 0xC8E6C9,
+        radius = 5,
+    })
+
+    airui.label({
+        parent = child1,
+        text = "子容器1",
+        x = 10,
+        y = 15,
+        w = 100,
+        h = 20,
+        font_size = 14,
+    })
+
+    local child2 = airui.container({
+        parent = parent_container,
+        x = 150,
+        y = 10,
+        w = 120,
+        h = 50,
+        color = 0xA5D6A7,
+        radius = 5,
+    })
+
+    airui.label({
+        parent = child2,
+        text = "子容器2",
+        x = 10,
+        y = 15,
+        w = 100,
+        h = 20,
+        font_size = 14,
+    })
+
+    -- 示例4: 动态显示/隐藏
+    airui.label({
+        parent = scroll_container,
+        text = "示例4: 显示/隐藏容器",
+        x = 10,
+        y = 410,
+        w = 300,
+        h = 20,
+        font_size = 14,
+    })
+
+    local toggle_container = airui.container({
+        parent = scroll_container,
+        x = 20,
+        y = 440,
+        w = 160,
+        h = 60,
+        color = 0xE1BEE7,
+        radius = 8,
+    })
+
+    airui.label({
+        parent = toggle_container,
+        text = "可隐藏的容器",
+        x = 10,
+        y = 20,
+        w = 140,
+        h = 20,
+        font_size = 14,
+    })
+
+    local toggle_btn = airui.button({
+        parent = scroll_container,
+        x = 190,
+        y = 450,
+        w = 100,
+        h = 40,
+        text = "隐藏",
+        on_click = function(self)
+            if toggle_container then
+                toggle_container:hide()
+            end
+        end
+    })
+
+    -- 示例5: 动态改变颜色
+    airui.label({
+        parent = scroll_container,
+        text = "示例5: 动态改变颜色",
+        x = 10,
+        y = 510,
+        w = 300,
+        h = 20,
+        font_size = 14,
+    })
+
+    local color_container = airui.container({
+        parent = scroll_container,
+        x = 20,
+        y = 540,
+        w = 280,
+        h = 80,
+        color = 0x2196F3,
+        radius = 8,
+    })
+
+    airui.label({
+        parent = color_container,
+        text = "点击按钮改变颜色",
+        x = 10,
+        y = 30,
+        w = 260,
+        h = 20,
+        font_size = 14,
+    })
+
+    local color_btn = airui.button({
+        parent = scroll_container,
+        x = 20,
+        y = 630,
+        w = 130,
+        h = 40,
+        text = "随机颜色",
+        on_click = function(self)
+            local colors = {0xFF5722, 0x4CAF50, 0x9C27B0, 0xFF9800, 0x00BCD4}
+            local random_color = colors[math.random(1, #colors)]
+            color_container:set_color(random_color)
+        end
+    })
+
+    local reset_btn = airui.button({
+        parent = scroll_container,
+        x = 170,
+        y = 630,
+        w = 130,
+        h = 40,
+        text = "重置颜色",
+        on_click = function(self)
+            color_container:set_color(0x2196F3)
+        end
+    })
+
+    -- 底部信息
+    airui.label({
+        parent = main_container,
+        text = "提示: 容器是布局的基础组件",
+        x = 10,
+        y = 440,
+        w = 300,
+        h = 20,
+        font_size = 14,
+    })
+end
+
+-- 初始化页面
+function container_page.init(params)
+    math.randomseed(os.time())
+    container_page.create_ui()
+end
+
+-- 清理页面
+function container_page.cleanup()
+    if main_container then
+        main_container:destroy()
+        main_container = nil
+    end
+end
+
+return container_page

+ 267 - 0
script/ui/dropdown_page.lua

@@ -0,0 +1,267 @@
+--[[
+@module  dropdown_page
+@summary 下拉框组件演示页面
+@version 1.0
+@date    2026.02.05
+@author  江访
+@usage
+本文件是下拉框组件的演示页面,展示下拉框的各种用法。
+]]
+
+local dropdown_page = {}
+
+-- 页面UI元素
+local main_container = nil
+
+-- 创建UI
+function dropdown_page.create_ui()
+    -- 创建主容器
+    main_container = airui.container({
+        x = 0,
+        y = 0,
+        w = 320,
+        h = 480,
+        color = 0xF5F5F5,
+    })
+
+    -- 标题栏
+    local title_bar = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 0,
+        w = 320,
+        h = 50,
+        color = 0x795548,
+    })
+
+    airui.label({
+        parent = title_bar,
+        text = "下拉框组件演示",
+        x = 10,
+        y = 15,
+        w = 200,
+        h = 20,
+        font_size = 16,
+        color = 0xFFFFFF,
+    })
+
+    -- 返回按钮
+    local back_btn = airui.button({
+        parent = title_bar,
+        x = 250,
+        y = 10,
+        w = 60,
+        h = 30,
+        text = "返回",
+        on_click = function(self)
+            go_back()
+        end
+    })
+
+    -- 滚动容器
+    local scroll_container = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 60,
+        w = 320,
+        h = 370,
+        color = 0xF5F5F5,
+    })
+
+    -- 示例1: 基本下拉框
+    airui.label({
+        parent = scroll_container,
+        text = "示例1: 基本下拉框",
+        x = 10,
+        y = 10,
+        w = 300,
+        h = 20,
+        font_size = 14,
+    })
+
+    -- 显示选中项
+    local selected_label1 = airui.label({
+        parent = scroll_container,
+        text = "当前选中: 选项1",
+        x = 230,
+        y = 45,
+        w = 80,
+        h = 50,
+        font_size = 14,
+    })
+
+    local basic_dropdown = airui.dropdown({
+        parent = scroll_container,
+        x = 20,
+        y = 40,
+        w = 200,
+        h = 40,
+        options = {"选项1", "选项2", "选项3", "选项4", "选项5"},
+        default_index = 0,
+        on_change = function(self,idx)
+            local texts = {"选项1", "选项2", "选项3", "选项4", "选项5"}
+            selected_label1:set_text("当前选中: " .. texts[idx + 1])
+        end
+    })
+
+    -- 示例2: 下拉框组
+    airui.label({
+        parent = scroll_container,
+        text = "示例2: 下拉框组",
+        x = 10,
+        y = 110,
+        w = 300,
+        h = 20,
+        font_size = 14,
+    })
+
+    local dropdown_container = airui.container({
+        parent = scroll_container,
+        x = 20,
+        y = 140,
+        w = 280,
+        h = 150,
+        color = 0xEFEBE9,
+        radius = 8,
+    })
+
+    -- 城市选择
+    airui.label({
+        parent = dropdown_container,
+        text = "城市:",
+        x = 10,
+        y = 20,
+        w = 60,
+        h = 20,
+        font_size = 14,
+    })
+
+    local city_dropdown = airui.dropdown({
+        parent = dropdown_container,
+        x = 80,
+        y = 15,
+        w = 180,
+        h = 30,
+        options = {"北京", "上海", "广州", "深圳", "杭州", "南京", "成都"},
+        default_index = 0,
+    })
+
+    -- 区县选择
+    airui.label({
+        parent = dropdown_container,
+        text = "区县:",
+        x = 10,
+        y = 60,
+        w = 60,
+        h = 20,
+        font_size = 14,
+    })
+
+    local district_dropdown = airui.dropdown({
+        parent = dropdown_container,
+        x = 80,
+        y = 55,
+        w = 180,
+        h = 30,
+        options = {"请先选择城市"},
+        default_index = 0,
+    })
+
+    -- 联动选择按钮
+    local select_btn = airui.button({
+        parent = dropdown_container,
+        x = 80,
+        y = 100,
+        w = 180,
+        h = 35,
+        text = "确认选择",
+        on_click = function(self)
+            local city_idx = city_dropdown:get_selected()
+            local district_idx = district_dropdown:get_selected()
+            local cities = {"北京", "上海", "广州", "深圳", "杭州", "南京", "成都"}
+            log.info("dropdown", "选择了城市: " .. cities[city_idx + 1])
+        end
+    })
+
+    -- 示例3: 获取选中值
+    airui.label({
+        parent = scroll_container,
+        text = "示例3: 获取选中值",
+        x = 10,
+        y = 310,
+        w = 300,
+        h = 20,
+        font_size = 14,
+    })
+
+    local value_dropdown = airui.dropdown({
+        parent = scroll_container,
+        x = 20,
+        y = 340,
+        w = 180,
+        h = 40,
+        options = {"红色", "绿色", "蓝色", "黄色", "紫色"},
+        default_index = 2,
+    })
+
+    local get_btn = airui.button({
+        parent = scroll_container,
+        x = 210,
+        y = 340,
+        w = 80,
+        h = 40,
+        text = "获取",
+        on_click = function(self)
+            local idx = value_dropdown:get_selected()
+            local colors = {"红色", "绿色", "蓝色", "黄色", "紫色"}
+            local msg = airui.msgbox({
+                text = "当前选中: " .. colors[idx + 1],
+                buttons = {"确定"},
+                timeout = 2000,
+                on_action = function(self, label)
+                    self:hide()
+                end
+            })
+            msg:show()
+        end
+    })
+
+    -- 设置选中项
+    local set_btn = airui.button({
+        parent = scroll_container,
+        x = 20,
+        y = 390,
+        w = 180,
+        h = 40,
+        text = "设置为黄色",
+        on_click = function(self)
+            value_dropdown:set_selected(3) -- 黄色是第4项,索引为3
+        end
+    })
+
+    -- 底部信息
+    airui.label({
+        parent = main_container,
+        text = "提示: 下拉框支持选项选择和联动",
+        x = 10,
+        y = 440,
+        w = 300,
+        h = 20,
+        font_size = 14,
+    })
+end
+
+-- 初始化页面
+function dropdown_page.init(params)
+    dropdown_page.create_ui()
+end
+
+-- 清理页面
+function dropdown_page.cleanup()
+    if main_container then
+        main_container:destroy()
+        main_container = nil
+    end
+end
+
+return dropdown_page

+ 519 - 0
script/ui/game_page.lua

@@ -0,0 +1,519 @@
+--[[
+@module  game_page
+@summary 俄罗斯方块游戏演示页面
+@version 1.0
+@date    2026.02.05
+@author  江访
+@usage
+本文件是俄罗斯方块游戏的演示页面。
+]]
+
+local game_page = {}
+
+-- 屏幕与棋盘参数(适配480*320竖屏)
+local SCREEN_W, SCREEN_H = 320, 480 -- 竖屏:320宽,480高
+local GRID_W, GRID_H = 10, 15       -- 调整为10列15行以适应竖屏
+local CELL_SIZE = 20                -- 每格像素大小(20px)
+local BOARD_W = GRID_W * CELL_SIZE
+local BOARD_H = GRID_H * CELL_SIZE
+local BOARD_X = (SCREEN_W - BOARD_W) // 2 -- 水平居中
+local BOARD_Y = 100                        -- 棋盘左上角Y坐标
+
+-- 7 种俄罗斯方块颜色(RGB565格式)
+local COLORS = {
+    0x07FF, -- I (青色)
+    0x001F, -- J (蓝色)
+    0xFD20, -- L (橙色)
+    0xFFE0, -- O (黄色)
+    0x07E0, -- S (绿色)
+    0x8010, -- T (紫色)
+    0xF800, -- Z (红色)
+}
+
+-- 7 种形状(1 表示方块)
+local SHAPES = {
+    { { 1, 1, 1, 1 } },           -- I
+    { { 1, 0, 0 },   { 1, 1, 1 } }, -- J
+    { { 0, 0, 1 },   { 1, 1, 1 } }, -- L
+    { { 1, 1 },      { 1, 1 } },  -- O
+    { { 0, 1, 1 },   { 1, 1, 0 } }, -- S
+    { { 0, 1, 0 },   { 1, 1, 1 } }, -- T
+    { { 1, 1, 0 },   { 0, 1, 1 } }, -- Z
+}
+
+-- 游戏状态
+local grid     -- grid[y][x] = nil 或 颜色下标
+local curPiece -- {x, y, shape, color}
+local score = 0
+local gameOver = false
+local gameTimer = nil
+
+-- UI 控件
+local main_container
+local scoreLabel
+local statusLabel
+local leftBtn, rightBtn, rotateBtn, downBtn, restartBtn
+
+----------------------------------------------------------------
+-- 工具函数:网格与方块
+----------------------------------------------------------------
+local function initGrid()
+    grid = {}
+    for y = 1, GRID_H do
+        grid[y] = {}
+        for x = 1, GRID_W do
+            grid[y][x] = nil
+        end
+    end
+end
+
+local function rotateShape(shape)
+    local h, w = #shape, #shape[1]
+    local res = {}
+    for x = 1, w do
+        res[x] = {}
+        for y = 1, h do
+            res[x][y] = shape[h - y + 1][x]
+        end
+    end
+    return res
+end
+
+local function newPiece()
+    local idx = math.random(1, #SHAPES)
+    local shp = SHAPES[idx]
+    local pw  = #shp[1]
+    local px  = math.floor(GRID_W / 2) - math.floor(pw / 2) + 1
+    curPiece  = {
+        x = px,
+        y = 1,
+        shape = shp,
+        color = idx,
+    }
+end
+
+local function eachBlock(piece, cb)
+    local shape = piece.shape
+    for j = 1, #shape do
+        for i = 1, #shape[j] do
+            if shape[j][i] == 1 then
+                cb(piece.x + i - 1, piece.y + j - 1)
+            end
+        end
+    end
+end
+
+local function validPosition(piece)
+    local ok = true
+    eachBlock(piece, function(x, y)
+        if x < 1 or x > GRID_W or y < 1 or y > GRID_H then
+            ok = false
+            return
+        end
+        if grid[y][x] ~= nil then
+            ok = false
+            return
+        end
+    end)
+    return ok
+end
+
+local function mergePiece()
+    if not curPiece then return end
+    eachBlock(curPiece, function(x, y)
+        if y >= 1 and y <= GRID_H and x >= 1 and x <= GRID_W then
+            grid[y][x] = curPiece.color
+        end
+    end)
+end
+
+-- 返回本次消掉的行数
+local function clearLines()
+    local cleared = 0
+    for y = GRID_H, 1, -1 do
+        local full = true
+        for x = 1, GRID_W do
+            if grid[y][x] == nil then
+                full = false
+                break
+            end
+        end
+        if full then
+            cleared = cleared + 1
+            -- 下移
+            for yy = y, 2, -1 do
+                grid[yy] = grid[yy - 1]
+            end
+            local row = {}
+            for x = 1, GRID_W do row[x] = nil end
+            grid[1] = row
+            y = y + 1
+        end
+    end
+    if cleared > 0 then
+        score = score + cleared * 100
+    end
+    return cleared
+end
+
+----------------------------------------------------------------
+-- 绘制函数:使用lcd.fill绘制棋盘
+----------------------------------------------------------------
+local function drawCell(x, y, color)
+    local cx = BOARD_X + (x - 1) * CELL_SIZE
+    local cy = BOARD_Y + (y - 1) * CELL_SIZE
+    lcd.fill(cx, cy, cx + CELL_SIZE - 2, cy + CELL_SIZE - 2, color)
+end
+
+local function drawBoard()
+    -- 绘制棋盘背景
+    lcd.fill(BOARD_X, BOARD_Y, BOARD_X + BOARD_W - 1, BOARD_Y + BOARD_H - 1, 0x1082) -- 深灰色背景
+
+    -- 绘制固定的方块
+    for y = 1, GRID_H do
+        for x = 1, GRID_W do
+            local fixed = grid[y][x]
+            if fixed then
+                drawCell(x, y, COLORS[fixed])
+            else
+                -- 绘制空单元格(带边框效果)
+                local cx = BOARD_X + (x - 1) * CELL_SIZE
+                local cy = BOARD_Y + (y - 1) * CELL_SIZE
+                lcd.fill(cx, cy, cx + CELL_SIZE - 2, cy + CELL_SIZE - 2, 0x0841)         -- 更深的灰色
+                lcd.fill(cx + 1, cy + 1, cx + CELL_SIZE - 3, cy + CELL_SIZE - 3, 0x18C3) -- 浅灰色内框
+            end
+        end
+    end
+
+    -- 绘制当前方块
+    if curPiece then
+        eachBlock(curPiece, function(x, y)
+            if y >= 1 and y <= GRID_H and x >= 1 and x <= GRID_W then
+                drawCell(x, y, COLORS[curPiece.color])
+            end
+        end)
+    end
+
+    -- 绘制棋盘边框
+    lcd.fill(BOARD_X - 2, BOARD_Y - 2, BOARD_X + BOARD_W + 1, BOARD_Y - 1, 0xFFFF)                 -- 上边框
+    lcd.fill(BOARD_X - 2, BOARD_Y + BOARD_H, BOARD_X + BOARD_W + 1, BOARD_Y + BOARD_H + 1, 0xFFFF) -- 下边框
+    lcd.fill(BOARD_X - 2, BOARD_Y - 2, BOARD_X - 1, BOARD_Y + BOARD_H + 1, 0xFFFF)                 -- 左边框
+    lcd.fill(BOARD_X + BOARD_W, BOARD_Y - 2, BOARD_X + BOARD_W + 1, BOARD_Y + BOARD_H + 1, 0xFFFF) -- 右边框
+end
+
+----------------------------------------------------------------
+-- UI更新函数
+----------------------------------------------------------------
+local function updateScoreLabel()
+    if scoreLabel then
+        scoreLabel:set_text("分数: " .. tostring(score))
+    end
+end
+
+local function updateStatusLabel(extra)
+    if not statusLabel then return end
+    if gameOver then
+        statusLabel:set_text("游戏结束! 点击重新开始")
+    else
+        if extra and extra ~= "" then
+            statusLabel:set_text("俄罗斯方块 | " .. extra)
+        else
+            statusLabel:set_text("俄罗斯方块 | 使用按钮游玩")
+        end
+    end
+end
+
+local function redrawAll(extraStatus)
+    updateScoreLabel()
+    updateStatusLabel(extraStatus)
+    drawBoard()
+end
+
+----------------------------------------------------------------
+-- 控制逻辑
+----------------------------------------------------------------
+local function stepDown()
+    if gameOver or not curPiece then return end
+    local test = {
+        x = curPiece.x,
+        y = curPiece.y + 1,
+        shape = curPiece.shape,
+        color = curPiece.color,
+    }
+    if validPosition(test) then
+        curPiece = test
+        redrawAll()
+        return
+    end
+
+    -- 碰到底或碰到已固定方块
+    mergePiece()
+    local cleared = clearLines()
+    newPiece()
+    if not validPosition(curPiece) then
+        gameOver = true
+        redrawAll("游戏结束!")
+        if gameTimer then
+            sys.timerStop(gameTimer)
+            gameTimer = nil
+        end
+    else
+        if cleared > 0 then
+            redrawAll("消除了 " .. cleared .. " 行!")
+        else
+            redrawAll()
+        end
+    end
+end
+
+local function moveLeft()
+    if gameOver or not curPiece then return end
+    local test = {
+        x = curPiece.x - 1,
+        y = curPiece.y,
+        shape = curPiece.shape,
+        color = curPiece.color,
+    }
+    if validPosition(test) then
+        curPiece = test
+        redrawAll()
+    end
+end
+
+local function moveRight()
+    if gameOver or not curPiece then return end
+    local test = {
+        x = curPiece.x + 1,
+        y = curPiece.y,
+        shape = curPiece.shape,
+        color = curPiece.color,
+    }
+    if validPosition(test) then
+        curPiece = test
+        redrawAll()
+    end
+end
+
+local function softDrop()
+    if gameOver or not curPiece then return end
+    local test = {
+        x = curPiece.x,
+        y = curPiece.y + 1,
+        shape = curPiece.shape,
+        color = curPiece.color,
+    }
+    if validPosition(test) then
+        curPiece = test
+        redrawAll()
+    end
+end
+
+local function rotatePiece()
+    if gameOver or not curPiece then return end
+    local newShape = rotateShape(curPiece.shape)
+    local test = {
+        x = curPiece.x,
+        y = curPiece.y,
+        shape = newShape,
+        color = curPiece.color,
+    }
+    if validPosition(test) then
+        curPiece = test
+        redrawAll("旋转")
+    end
+end
+
+local function restartGame()
+    if gameTimer then
+        sys.timerStop(gameTimer)
+    end
+    
+    score = 0
+    gameOver = false
+    initGrid()
+    newPiece()
+    redrawAll("重新开始,分数: 0")
+    
+    -- 重新启动定时器
+    gameTimer = sys.timerLoopStart(stepDown, 400)
+end
+
+----------------------------------------------------------------
+-- 创建游戏UI
+----------------------------------------------------------------
+function game_page.create_ui()
+    -- 创建主容器
+    main_container = airui.container({
+        x = 0,
+        y = 0,
+        w = SCREEN_W,
+        h = SCREEN_H,
+        color = 0x0000, -- 黑色背景
+    })
+
+    -- 标题栏
+    local title_bar = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 0,
+        w = SCREEN_W,
+        h = 50,
+        color = 0x1E3A8A, -- 深蓝色
+    })
+
+    -- 返回按钮
+    local back_btn = airui.button({
+        parent = title_bar,
+          x = 250,
+        y = 10,
+        w = 60,
+        h = 30,
+        text = "返回",
+        on_click = function()
+            game_page.cleanup()
+            go_back()
+        end
+    })
+
+    -- 游戏标题
+    airui.label({
+        parent = title_bar,
+        text = "俄罗斯方块",
+        x = 80,
+        y = 15,
+        w = 160,
+        h = 20,
+    })
+
+    -- 分数标签
+    scoreLabel = airui.label({
+        parent = main_container,
+        text = "分数: 0",
+        x = 220,
+        y = 70,
+        w = 150,
+        h = 20,
+    })
+
+    -- 状态标签
+    statusLabel = airui.label({
+        parent = main_container,
+        text = "俄罗斯方块 | 使用按钮游玩",
+        x = 10,
+        y = 70,
+        w = SCREEN_W - 20,
+        h = 20,
+    })
+
+    -- 控制按钮区域
+    local btnY = BOARD_Y + BOARD_H + 10
+    local btnW, btnH, gap = 70, 30, 10
+
+    -- 计算按钮起始X坐标(居中显示)
+    local totalBtnWidth = btnW * 3 + gap * 2 -- 第一行3个按钮
+    local btnStartX = (SCREEN_W - totalBtnWidth) // 2
+
+    -- 第一行按钮
+    leftBtn = airui.button({
+        parent   = main_container,
+        x        = btnStartX,
+        y        = btnY,
+        w        = btnW,
+        h        = btnH,
+        text     = "左移",
+        on_click = function() moveLeft() end,
+    })
+
+    rightBtn = airui.button({
+        parent   = main_container,
+        x        = btnStartX + btnW + gap,
+        y        = btnY,
+        w        = btnW,
+        h        = btnH,
+        text     = "右移",
+        on_click = function() moveRight() end,
+    })
+
+    rotateBtn = airui.button({
+        parent   = main_container,
+        x        = btnStartX + 2 * (btnW + gap),
+        y        = btnY,
+        w        = btnW,
+        h        = btnH,
+        text     = "旋转",
+        on_click = function() rotatePiece() end,
+    })
+
+    -- 第二行按钮
+    btnY = btnY + btnH + gap
+
+    downBtn = airui.button({
+        parent   = main_container,
+        x        = btnStartX,
+        y        = btnY,
+        w        = btnW * 2 + gap, -- 稍宽一点
+        h        = btnH,
+        text     = "下落",
+        on_click = function() softDrop() end,
+    })
+
+    restartBtn = airui.button({
+        parent   = main_container,
+        x        = btnStartX + btnW * 2 + gap * 2,
+        y        = btnY,
+        w        = btnW,
+        h        = btnH,
+        text     = "重新开始",
+        on_click = function() restartGame() end,
+    })
+end
+
+----------------------------------------------------------------
+-- 页面生命周期函数
+----------------------------------------------------------------
+function game_page.init(params)
+    math.randomseed(os.time())
+    
+    -- 初始化游戏状态
+    initGrid()
+    newPiece()
+    
+    -- 创建UI
+    game_page.create_ui()
+    
+    -- 初始绘制
+    redrawAll("准备开始!")
+    
+    -- 启动定时器
+    gameTimer = sys.timerLoopStart(stepDown, 400)
+end
+
+function game_page.cleanup()
+    -- 停止定时器
+    if gameTimer then
+        sys.timerStop(gameTimer)
+        gameTimer = nil
+    end
+    
+    -- 清理UI
+    if main_container then
+        main_container:destroy()
+        main_container = nil
+    end
+    
+    -- 重置游戏状态
+    grid = nil
+    curPiece = nil
+    score = 0
+    gameOver = false
+    
+    leftBtn = nil
+    rightBtn = nil
+    rotateBtn = nil
+    downBtn = nil
+    restartBtn = nil
+    scoreLabel = nil
+    statusLabel = nil
+end
+
+return game_page

+ 158 - 0
script/ui/home_page.lua

@@ -0,0 +1,158 @@
+--[[
+@module  home_page
+@summary AirUI演示系统主页
+@version 1.0
+@date    2026.02.05
+@author  江访
+@usage
+本文件是AirUI演示系统的主页,提供所有功能演示的入口。
+]]
+
+local home_page = {}
+
+-- 页面UI元素
+local main_container = nil
+local scroll_container = nil
+
+-- 演示模块列表
+local demos = {
+    -- AirUI组件演示
+    {name = "所有组件演示", icon = airui.SYMBOL_OK, page = "all_component", color = 0x007AFF},
+    {name = "标签组件", icon = airui.SYMBOL_REFRESH, page = "label", color = 0x4CAF50},
+    {name = "按钮组件", icon = airui.SYMBOL_LOOP, page = "button", color = 0xF44336},
+    {name = "容器组件", icon = airui.SYMBOL_SD_CARD, page = "container", color = 0xFF9800},
+    {name = "进度条组件", icon = airui.SYMBOL_SHUFFLE, page = "bar", color = 0x9C27B0},
+    {name = "开关组件", icon = airui.SYMBOL_COPY, page = "switch", color = 0x00BCD4},
+    {name = "下拉框组件", icon = airui.SYMBOL_DOWN, page = "dropdown", color = 0x795548},
+    {name = "表格组件", icon = airui.SYMBOL_LIST, page = "table", color = 0x607D8B},
+    {name = "输入框组件", icon = airui.SYMBOL_EDIT, page = "input", color = 0x3F51B5},
+    {name = "消息框组件", icon = airui.SYMBOL_CALL, page = "msgbox", color = 0xE91E63},
+    {name = "图片组件", icon = airui.SYMBOL_IMAGE, page = "image", color = 0x8BC34A},
+    {name = "选项卡组件", icon = airui.SYMBOL_PASTE, page = "tabview", color = 0xFF5722},
+    {name = "窗口组件", icon = airui.SYMBOL_BELL, page = "win", color = 0x009688},
+    {name = "页面切换演示", icon = airui.SYMBOL_LEFT, page = "switch_page_demo", color = 0x673AB7},
+    {name = "矢量字体演示", icon = airui.SYMBOL_EYE_OPEN, page = "hzfont", color = 0x2196F3},
+    {name = "俄罗斯方块游戏", icon = airui.SYMBOL_WARNING, page = "game", color = 0xFF4081},
+}
+
+-- 创建主页UI
+function home_page.create_ui()
+    -- 创建主容器
+    main_container = airui.container({
+        x = 0,
+        y = 0,
+        w = 320,
+        h = 480,
+        color = 0xF8F9FA,
+    })
+
+    -- 标题栏
+    local title_bar = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 0,
+        w = 320,
+        h = 50,
+        color = 0x007AFF,
+    })
+
+    airui.label({
+        parent = title_bar,
+        text = "AirUI演示系统",
+        x = 10,
+        y = 20,
+        w = 300,
+        h = 30,
+    })
+
+    -- 滚动容器
+    scroll_container = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 60,
+        w = 320,
+        h = 360,
+        color = 0xF8F9FA,
+    })
+
+    -- 创建网格布局的演示按钮
+    local button_width = 140
+    local button_height = 70
+    local columns = 2
+    local padding = 10
+    local y_offset = 0
+    
+    for i, demo in ipairs(demos) do
+        local col = (i - 1) % columns
+        local row = math.floor((i - 1) / columns)
+        
+        local x = padding + col * (button_width + padding)
+        local y = y_offset + row * (button_height + padding)
+        
+        -- 创建按钮容器(卡片样式)
+        local card = airui.container({
+            parent = scroll_container,
+            x = x,
+            y = y,
+            w = button_width,
+            h = button_height,
+            color = demo.color,
+            radius = 8,
+        })
+        
+        -- 图标标签
+        airui.label({
+            parent = card,
+            text = demo.icon,
+            x = 10,
+            y = 15,
+            w = 30,
+            h = 50,
+        })
+        
+        -- 演示名称标签
+        airui.label({
+            parent = card,
+            text = demo.name,
+            x = 50,
+            y = 15,
+            w = button_width - 60,
+            h = 50,
+            on_click = function()
+            _G.show_page(demo.page) end
+        })
+    end
+
+    -- 底部状态栏
+    local status_bar = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 440,
+        w = 320,
+        h = 40,
+        color = 0xCFCFCF,
+    })
+
+    airui.label({
+        parent = status_bar,
+        text = string.format("共%d个演示 - AirUI v1.0.3", #demos),
+        x = 10,
+        y = 12,
+        w = 300,
+        h = 16,
+    })
+end
+
+-- 初始化页面
+function home_page.init(params)
+    home_page.create_ui()
+end
+
+-- 清理页面
+function home_page.cleanup()
+    -- 清理UI元素
+    main_container = nil
+    scroll_container = nil
+end
+
+return home_page

+ 298 - 0
script/ui/hzfont_page.lua

@@ -0,0 +1,298 @@
+--[[
+@module     hzfont_page
+@summary    矢量字体演示页面
+@version    1.0
+@date       2026.01.30
+@author     江访
+@usage      本文件是矢量字体的演示页面,展示中文字体的各种用法。
+]]
+
+local hzfont_page = {}
+
+----------------------------------------------------------------
+-- 页面UI元素
+----------------------------------------------------------------
+local main_container = nil
+local current_font = nil
+
+----------------------------------------------------------------
+-- 辅助函数:创建带标题的容器
+----------------------------------------------------------------
+local function create_demo_container(parent, title, x, y, width, height)
+    local container = airui.container({
+        parent = parent,
+        x = x,
+        y = y,
+        w = width,
+        h = height,
+        color = 0xFFFFFF,
+        radius = 8,
+    })
+
+    airui.label({
+        parent = container,
+        text = title,
+        x = 10,
+        y = 5,
+        w = width - 20,
+        h = 25,
+        color = 0x333333,
+        font_size = 14,
+    })
+
+    return container
+end
+
+----------------------------------------------------------------
+-- 创建UI
+----------------------------------------------------------------
+function hzfont_page.create_ui()
+    main_container = airui.container({
+        x = 0,
+        y = 0,
+        w = 320,
+        h = 480,
+        color = 0xF5F5F5,
+    })
+
+    -- 标题栏
+    local title_bar = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 0,
+        w = 320,
+        h = 50,
+        color = 0x2196F3,
+    })
+
+    airui.label({
+        parent = title_bar,
+        text = "矢量字体演示",
+        x = 10,
+        y = 15,
+        w = 200,
+        h = 20,
+        font_size = 16,
+        color = 0xFFFFFF,
+    })
+
+    -- 返回按钮
+    local back_btn = airui.button({
+        parent = title_bar,
+        x = 250,
+        y = 10,
+        w = 60,
+        h = 30,
+        text = "返回",
+        on_click = function(self)
+            go_back()
+        end
+    })
+
+    -- 滚动容器
+    local scroll_container = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 60,
+        w = 320,
+        h = 370,
+        color = 0xF5F5F5,
+    })
+
+    local current_y = 10
+
+    --------------------------------------------------------------------
+    -- 示例1: 基本中文显示
+    --------------------------------------------------------------------
+    local demo1_container = create_demo_container(scroll_container, "示例1: 基本中文显示", 10, current_y, 300, 80)
+    current_y = current_y + 80 + 10
+
+    airui.label({
+        parent = demo1_container,
+        text = "你好,世界!",
+        x = 20,
+        y = 30,
+        w = 260,
+        h = 40,
+        color = 0x333333,
+        font_size = 18,
+    })
+
+    --------------------------------------------------------------------
+    -- 示例2: 长文本中文显示
+    --------------------------------------------------------------------
+    local demo2_container = create_demo_container(scroll_container, "示例2: 长文本中文", 10, current_y, 300, 100)
+    current_y = current_y + 100 + 10
+
+    local long_text = "矢量字体支持高质量的中文显示,可以在不同分辨率下保持清晰,提供更好的视觉体验。"
+    airui.label({
+        parent = demo2_container,
+        text = long_text,
+        x = 20,
+        y = 30,
+        w = 260,
+        h = 60,
+        color = 0x333333,
+        font_size = 14,
+    })
+
+    --------------------------------------------------------------------
+    -- 示例3: 中英文混合
+    --------------------------------------------------------------------
+    local demo3_container = create_demo_container(scroll_container, "示例3: 中英文混合", 10, current_y, 300, 80)
+    current_y = current_y + 80 + 10
+
+    airui.label({
+        parent = demo3_container,
+        text = "中文 Chinese 混合 Mixed 文本 Text",
+        x = 20,
+        y = 30,
+        w = 260,
+        h = 40,
+        color = 0x333333,
+        font_size = 16,
+    })
+
+    --------------------------------------------------------------------
+    -- 示例4: 常用汉字显示
+    --------------------------------------------------------------------
+    local demo4_container = create_demo_container(scroll_container, "示例4: 常用汉字", 10, current_y, 300, 80)
+    current_y = current_y + 80 + 10
+
+    airui.label({
+        parent = demo4_container,
+        text = "天地玄黄 宇宙洪荒 日月盈昃 辰宿列张",
+        x = 20,
+        y = 30,
+        w = 260,
+        h = 40,
+        color = 0x333333,
+        font_size = 16,
+    })
+
+    --------------------------------------------------------------------
+    -- 示例5: 数字和标点
+    --------------------------------------------------------------------
+    local demo5_container = create_demo_container(scroll_container, "示例5: 数字标点", 10, current_y, 300, 100)
+    current_y = current_y + 100 + 10
+
+    airui.label({
+        parent = demo5_container,
+        text = "数字: 1234567890\n标点: ,。!?;:\"'()【】《》",
+        x = 20,
+        y = 30,
+        w = 260,
+        h = 60,
+        color = 0x333333,
+        font_size = 14,
+    })
+
+    --------------------------------------------------------------------
+    -- 示例6: 字体大小对比
+    --------------------------------------------------------------------
+    local demo7_container = create_demo_container(scroll_container, "示例6: 字体大小对比", 10, current_y, 300, 120)
+    current_y = current_y + 120 + 10
+
+    airui.label({
+        parent = demo7_container,
+        text = "12px - 小号字体",
+        x = 20,
+        y = 30,
+        w = 260,
+        h = 30,
+        color = 0x333333,
+        font_size = 12,
+    })
+
+    airui.label({
+        parent = demo7_container,
+        text = "16px - 中号字体",
+        x = 20,
+        y = 55,
+        w = 260,
+        h = 30,
+        color = 0x333333,
+        font_size = 16,
+    })
+
+    airui.label({
+        parent = demo7_container,
+        text = "20px - 大号字体",
+        x = 20,
+        y = 80,
+        w = 260,
+        h = 30,
+        color = 0x333333,
+        font_size = 20,
+    })
+
+    --------------------------------------------------------------------
+    -- 示例7: 字体颜色对比
+    --------------------------------------------------------------------
+    local demo8_container = create_demo_container(scroll_container, "示例7: 字体颜色对比", 10, current_y, 300, 100)
+
+    airui.label({
+        parent = demo8_container,
+        text = "红色字体",
+        x = 20,
+        y = 30,
+        w = 260,
+        h = 30,
+        color = 0xFF0000,
+        font_size = 16,
+    })
+
+    airui.label({
+        parent = demo8_container,
+        text = "绿色字体",
+        x = 20,
+        y = 55,
+        w = 260,
+        h = 30,
+        color = 0x00FF00,
+        font_size = 16,
+    })
+
+    airui.label({
+        parent = demo8_container,
+        text = "蓝色字体",
+        x = 20,
+        y = 80,
+        w = 260,
+        h = 30,
+        color = 0x0000FF,
+        font_size = 16,
+    })
+
+    -- 底部信息
+    airui.label({
+        parent = main_container,
+        text = "提示: 矢量字体支持高质量中文显示",
+        x = 10,
+        y = 440,
+        w = 300,
+        h = 20,
+        color = 0x666666,
+        font_size = 12,
+    })
+end
+
+----------------------------------------------------------------
+-- 初始化页面
+----------------------------------------------------------------
+function hzfont_page.init(params)
+    hzfont_page.create_ui()
+end
+
+----------------------------------------------------------------
+-- 清理页面
+----------------------------------------------------------------
+function hzfont_page.cleanup()
+    if main_container then
+        main_container:destroy()
+        main_container = nil
+    end
+    current_font = nil
+end
+
+return hzfont_page

+ 460 - 0
script/ui/image_page.lua

@@ -0,0 +1,460 @@
+--[[
+@module     image_page
+@summary    图片组件演示页面
+@version    1.0
+@date       2026.01.30
+@author     江访
+@usage      本文件是图片组件的演示页面,展示图片的各种用法。
+            注意:需要确保图片文件存在于设备中。
+]]
+
+local image_page = {}
+
+----------------------------------------------------------------
+-- 页面UI元素
+----------------------------------------------------------------
+local main_container   = nil
+local scroll_container = nil
+
+----------------------------------------------------------------
+-- 辅助函数:创建带标题的容器
+----------------------------------------------------------------
+local function create_demo_container(parent, title, x, y, width, height)
+    local container = airui.container({
+        parent = parent,
+        x = x,
+        y = y,
+        w = width,
+        h = height,
+        color = 0xFFFFFF,
+        radius = 8,
+    })
+
+    airui.label({
+        parent = container,
+        text = title,
+        x = 10,
+        y = 5,
+        w = width - 20,
+        h = 25,
+        color = 0x333333,
+        font_size = 14,
+    })
+
+    return container
+end
+
+----------------------------------------------------------------
+-- 辅助函数:创建控制面板
+----------------------------------------------------------------
+local function create_control_panel(parent, title, x, y, width, height)
+    local panel = airui.container({
+        parent = parent,
+        x = x,
+        y = y,
+        w = width,
+        h = height,
+        color = 0xF8F9FA,
+        radius = 6,
+    })
+
+    airui.label({
+        parent = panel,
+        text = title,
+        x = 8,
+        y = 5,
+        w = width - 16,
+        h = 20,
+        color = 0x666666,
+        font_size = 12,
+    })
+
+    return panel
+end
+
+----------------------------------------------------------------
+-- 创建UI
+----------------------------------------------------------------
+function image_page.create_ui()
+    main_container = airui.container({
+        parent = airui.screen,
+        x = 0,
+        y = 0,
+        w = 320,
+        h = 480,
+        color = 0xF5F5F5,
+    })
+
+    -- 标题栏
+    local title_bar = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 0,
+        w = 320,
+        h = 50,
+        color = 0x8BC34A,
+    })
+
+    airui.label({
+        parent = title_bar,
+        text = "图片组件演示",
+        x = 10,
+        y = 15,
+        w = 200,
+        h = 20,
+        font_size = 16,
+        color = 0xFFFFFF,
+    })
+
+    -- 返回按钮
+    local back_btn = airui.button({
+        parent = title_bar,
+        x = 250,
+        y = 10,
+        w = 60,
+        h = 30,
+        text = "返回",
+        on_click = function(self)
+            go_back()
+        end
+    })
+
+    -- 滚动容器
+    scroll_container = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 50,
+        w = 320,
+        h = 430,
+        color = 0xF5F5F5,
+    })
+
+    local current_y = 10
+
+    --------------------------------------------------------------------
+    -- 示例1: 基本图片显示
+    --------------------------------------------------------------------
+    local demo1_container = create_demo_container(scroll_container, "示例1: 基本图片显示", 10, current_y, 300, 180)
+    current_y = current_y + 180 + 10
+
+    airui.label({
+        parent = demo1_container,
+        text = "显示静态图片,支持JPG和PNG格式",
+        x = 10,
+        y = 35,
+        w = 280,
+        h = 20,
+        color = 0x666666,
+        font_size = 12,
+    })
+
+    local basic_image = airui.image({
+        parent = demo1_container,
+        x = 20,
+        y = 60,
+        w = 120,
+        h = 100,
+        src = "/luadb/test1.png",
+        on_click = function(self)
+            log.info("image", "基本图片被点击")
+            local msg = airui.msgbox({
+                text = "基本图片被点击",
+                buttons = { "确定" },
+                timeout = 1500,
+                on_action = function(self, label)
+                    self:hide()
+                end
+            })
+            msg:show()
+        end
+    })
+
+    airui.label({
+        parent = demo1_container,
+        text = "尺寸: 120x100",
+        x = 150,
+        y = 70,
+        w = 140,
+        h = 20,
+        color = 0x333333,
+        font_size = 12,
+    })
+
+    airui.label({
+        parent = demo1_container,
+        text = "格式: PNG",
+        x = 150,
+        y = 95,
+        w = 140,
+        h = 20,
+        color = 0x333333,
+        font_size = 12,
+    })
+
+    airui.label({
+        parent = demo1_container,
+        text = "支持点击事件",
+        x = 150,
+        y = 120,
+        w = 140,
+        h = 20,
+        color = 0x333333,
+        font_size = 12,
+    })
+
+    --------------------------------------------------------------------
+    -- 示例2: 图片透明度控制
+    --------------------------------------------------------------------
+    local demo2_container = create_demo_container(scroll_container, "示例2: 图片透明度控制", 10, current_y, 300, 200)
+    current_y = current_y + 200 + 10
+
+    local png_image = airui.image({
+        parent = demo2_container,
+        x = 20,
+        y = 40,
+        w = 100,
+        h = 100,
+        src = "/luadb/test2.png",
+        zoom = 256,
+        opacity = 255,
+    })
+
+    local opacity_panel = create_control_panel(demo2_container, "透明度控制", 130, 40, 160, 150)
+
+    local opacity_label = airui.label({
+        parent = opacity_panel,
+        text = "当前: 255",
+        x = 10,
+        y = 25,
+        w = 140,
+        h = 20,
+        color = 0x333333,
+        font_size = 12,
+    })
+
+    local opacity_buttons = {
+        { text = "100%", value = 255 },
+        { text = "75%",  value = 191 },
+        { text = "50%",  value = 127 },
+        { text = "25%",  value = 64 },
+    }
+
+    for i, btn_info in ipairs(opacity_buttons) do
+        airui.button({
+            parent = opacity_panel,
+            x = 10 + ((i - 1) % 2) * 70,
+            y = 50 + math.floor((i - 1) / 2) * 30,
+            w = 60,
+            h = 25,
+            text = btn_info.text,
+            on_click = function(self)
+                local opacity_value = btn_info.value
+                png_image:set_opacity(opacity_value)
+                opacity_label:set_text("当前: " .. opacity_value)
+                local percent = math.floor((opacity_value / 255) * 100)
+                log.info("image", "透明度设置为: " .. percent .. "%")
+            end
+        })
+    end
+
+    --------------------------------------------------------------------
+    -- 示例3: 图片缩放控制
+    --------------------------------------------------------------------
+    local demo3_container = create_demo_container(scroll_container, "示例3: 图片缩放控制", 10, current_y, 300, 200)
+    current_y = current_y + 200 + 10
+
+    local zoom_image = airui.image({
+        parent = demo3_container,
+        x = 20,
+        y = 40,
+        w = 120,
+        h = 120,
+        src = "/luadb/test1.png",
+        zoom = 256,
+    })
+
+    local zoom_panel = create_control_panel(demo3_container, "缩放控制", 150, 40, 140, 150)
+
+    local zoom_label = airui.label({
+        parent = zoom_panel,
+        text = "当前: 100%",
+        x = 10,
+        y = 25,
+        w = 120,
+        h = 20,
+        color = 0x333333,
+        font_size = 12,
+    })
+
+    local zoom_buttons = {
+        { text = "50%",  value = 128 },
+        { text = "100%", value = 256 },
+        { text = "150%", value = 384 },
+        { text = "200%", value = 512 },
+    }
+
+    for i, btn_info in ipairs(zoom_buttons) do
+        airui.button({
+            parent = zoom_panel,
+            x = 10 + ((i - 1) % 2) * 55,
+            y = 50 + math.floor((i - 1) / 2) * 30,
+            w = 50,
+            h = 25,
+            text = btn_info.text,
+            on_click = function(self)
+                local zoom_value = btn_info.value
+                zoom_image:set_zoom(zoom_value)
+                local percent = math.floor((zoom_value / 256) * 100)
+                zoom_label:set_text("当前: " .. percent .. "%")
+                log.info("image", "缩放设置为: " .. percent .. "%")
+            end
+        })
+    end
+
+    --------------------------------------------------------------------
+    -- 示例4: 图片切换演示
+    --------------------------------------------------------------------
+    local demo4_container = create_demo_container(scroll_container, "示例4: 图片切换演示", 10, current_y, 300, 180)
+    current_y = current_y + 180 + 10
+
+    local image_index   = 1
+    local image_paths   = { "/luadb/test1.png", "/luadb/test2.png" }
+    local image_names   = { "测试图片1", "测试图片2" }
+
+    local switch_image = airui.image({
+        parent = demo4_container,
+        x = 20,
+        y = 40,
+        w = 120,
+        h = 100,
+        src = image_paths[1],
+    })
+
+    local image_info_label = airui.label({
+        parent = demo4_container,
+        text = "当前: " .. image_names[1],
+        x = 150,
+        y = 50,
+        w = 140,
+        h = 20,
+        color = 0x333333,
+        font_size = 12,
+    })
+
+    local switch_btn = airui.button({
+        parent = demo4_container,
+        x = 150,
+        y = 80,
+        w = 100,
+        h = 35,
+        text = "切换图片",
+        on_click = function(self)
+            image_index = image_index % #image_paths + 1
+            switch_image:set_src(image_paths[image_index])
+            image_info_label:set_text("当前: " .. image_names[image_index])
+            log.info("image", "切换到图片: " .. image_names[image_index])
+
+            local msg = airui.msgbox({
+                text = "已切换到: " .. image_names[image_index],
+                buttons = { "确定" },
+                timeout = 1000,
+                on_action = function(self, label)
+                    self:hide()
+                end
+            })
+            msg:show()
+        end
+    })
+
+    --------------------------------------------------------------------
+    -- 示例5: 动态创建图片
+    --------------------------------------------------------------------
+    local demo5_container = create_demo_container(scroll_container, "示例5: 动态创建图片", 10, current_y, 300, 200)
+
+    airui.label({
+        parent = demo5_container,
+        text = "动态创建和销毁图片",
+        x = 10,
+        y = 30,
+        w = 280,
+        h = 20,
+        color = 0x666666,
+        font_size = 12,
+    })
+
+    local dynamic_images = {}
+    local img_positions = { {x = 20, y = 60}, {x = 90, y = 60}, {x = 160, y = 60} }
+
+    airui.button({
+        parent = demo5_container,
+        x = 20,
+        y = 130,
+        w = 100,
+        h = 35,
+        text = "创建图片",
+        on_click = function(self)
+            local count = #dynamic_images + 1
+            if count <= 3 then
+                local pos = img_positions[count]
+                local img = airui.image({
+                    parent = demo5_container,
+                    x = pos.x,
+                    y = pos.y,
+                    w = 50,
+                    h = 50,
+                    src = "/luadb/test1.png",
+                })
+                table.insert(dynamic_images, img)
+                log.info("image", "创建第 " .. count .. " 张图片")
+            end
+        end
+    })
+
+    airui.button({
+        parent = demo5_container,
+        x = 170,
+        y = 130,
+        w = 100,
+        h = 35,
+        text = "清除图片",
+        on_click = function(self)
+            for _, img in ipairs(dynamic_images) do
+                img:destroy()
+            end
+            dynamic_images = {}
+            log.info("image", "清除所有动态图片")
+        end
+    })
+
+    -- 底部提示
+    airui.label({
+        parent = main_container,
+        text = "提示: 支持PNG透明度、图片缩放、点击事件等功能",
+        x = 10,
+        y = 450,
+        w = 300,
+        h = 20,
+        color = 0x666666,
+        font_size = 12,
+    })
+end
+
+----------------------------------------------------------------
+-- 初始化页面
+----------------------------------------------------------------
+function image_page.init(params)
+    image_page.create_ui()
+end
+
+----------------------------------------------------------------
+-- 清理页面
+----------------------------------------------------------------
+function image_page.cleanup()
+    if main_container then
+        main_container:destroy()
+        main_container   = nil
+        scroll_container = nil
+    end
+end
+
+return image_page

+ 392 - 0
script/ui/input_page.lua

@@ -0,0 +1,392 @@
+--[[
+@module  input_page
+@summary 输入框组件演示页面
+@version 1.0
+@date    2026.02.05
+@author  江访
+@usage
+本文件是输入框组件的演示页面,展示输入框的各种用法。
+]]
+
+local input_page = {}
+
+-- 页面UI元素
+local main_container = nil
+
+-- 创建UI
+function input_page.create_ui()
+    main_container = airui.container({
+        x = 0,
+        y = 0,
+        w = 320,
+        h = 480,
+        color = 0xF5F5F5,
+    })
+
+    -- 标题栏
+    local title_bar = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 0,
+        w = 320,
+        h = 50,
+        color = 0x3F51B5,
+    })
+
+    -- 注册虚拟键盘,先创建再在 textarea 配置里复用
+    local keyboard1 = airui.keyboard({
+        x = 0,
+        y = 0,
+        w = 320,
+        h = 220,                        -- x, y, 键盘默认打开ALIGN_BOTTOM_MID,位置从中下方开始计算
+        mode = "text",                  -- 键盘模式,可选 "text"/"upper"/"lower"/"numeric"
+        auto_hide = true,               -- 自动隐藏键盘
+        bg_color = 0xf1f1f1,            -- 键盘背景颜色为灰色,可选,不设置则透明
+        on_commit = function()          -- 确认事件回调,只有在按下确认键时才会触发
+            log.info("keyboard", "commit")
+        end
+    })
+
+    local keyboard2 = airui.keyboard({
+        x = 0,
+        y = 0,
+        w = 320,
+        h = 220,                        -- x, y, 键盘默认打开ALIGN_BOTTOM_MID,位置从中下方开始计算
+        mode = "numeric",               -- 键盘模式,可选 "text"/"upper"/"lower"/"numeric"
+        auto_hide = true,               -- 自动隐藏键盘
+        bg_color = 0xf1f1f1,            -- 键盘背景颜色为灰色,可选,不设置则透明
+        on_commit = function()          -- 确认事件回调,只有在按下确认键时才会触发
+            log.info("keyboard", "commit")
+        end
+    })
+
+    local keyboard3 = airui.keyboard({
+        x = 0,
+        y = 0,
+        w = 320,
+        h = 220,                        -- x, y, 键盘默认打开ALIGN_BOTTOM_MID,位置从中下方开始计算
+        mode = "lower",                 -- 键盘模式,可选 "text"/"upper"/"lower"/"numeric"
+        auto_hide = true,               -- 自动隐藏键盘
+        bg_color = 0xf1f1f1,            -- 键盘背景颜色为灰色,可选,不设置则透明
+        on_commit = function()          -- 确认事件回调,只有在按下确认键时才会触发
+            log.info("keyboard", "commit")
+        end
+    })
+
+    airui.label({
+        parent = title_bar,
+        text = "输入框组件演示",
+        x = 10,
+        y = 15,
+        w = 200,
+        h = 20,
+        font_size = 16,
+        color = 0xFFFFFF,
+    })
+
+    -- 返回按钮
+    local back_btn = airui.button({
+        parent = title_bar,
+        x = 250,
+        y = 10,
+        w = 60,
+        h = 30,
+        text = "返回",
+        on_click = function(self)
+            go_back()
+        end
+    })
+
+    -- 滚动容器
+    local scroll_container = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 60,
+        w = 320,
+        h = 370,
+        color = 0xF5F5F5,
+    })
+
+    -- 示例1: 基本输入框
+    airui.label({
+        parent = scroll_container,
+        text = "示例1: 基本输入框",
+        x = 10,
+        y = 10,
+        w = 300,
+        h = 20,
+        font_size = 14,
+    })
+
+    -- 创建键盘并关联输入框(v1.0.3 推荐内嵌键盘配置)
+    local basic_input = airui.textarea({
+        parent = scroll_container,
+        x = 20,
+        y = 40,
+        w = 280,
+        h = 100,
+        text = "",
+        placeholder = "请输入文本...",
+        max_len = 100,
+        keyboard = keyboard1
+
+    })
+
+    -- 示例2: 带默认值的输入框
+    airui.label({
+        parent = scroll_container,
+        text = "示例2: 带默认值",
+        x = 10,
+        y = 160,
+        w = 300,
+        h = 20,
+        font_size = 14,
+    })
+
+    local default_input = airui.textarea({
+        parent = scroll_container,
+        x = 20,
+        y = 190,
+        w = 280,
+        h = 60,
+        text = "默认文本",
+        placeholder = "请输入...",
+        max_len = 50,
+        keyboard = keyboard1
+    })
+
+    -- 示例3: 数字输入框
+    airui.label({
+        parent = scroll_container,
+        text = "示例3: 数字输入框",
+        x = 10,
+        y = 270,
+        w = 300,
+        h = 20,
+        font_size = 14,
+    })
+
+    local number_input = airui.textarea({
+        parent = scroll_container,
+        x = 20,
+        y = 300,
+        w = 280,
+        h = 60,
+        text = "",
+        placeholder = "请输入数字...",
+        max_len = 20,
+        keyboard = keyboard2
+    })
+
+    airui.label({
+        parent = scroll_container,
+        text = "(使用数字键盘)",
+        x = 20,
+        y = 365,
+        w = 280,
+        h = 20,
+        font_size = 12,
+        color = 0x666666,
+    })
+
+    -- 示例4: 表单输入
+    airui.label({
+        parent = scroll_container,
+        text = "示例4: 表单输入",
+        x = 10,
+        y = 400,
+        w = 300,
+        h = 20,
+        font_size = 14,
+    })
+
+    local form_container = airui.container({
+        parent = scroll_container,
+        x = 20,
+        y = 430,
+        w = 280,
+        h = 150,
+        color = 0xE8EAF6,
+        radius = 8,
+    })
+
+    -- 姓名输入
+    airui.label({
+        parent = form_container,
+        text = "姓名:",
+        x = 10,
+        y = 20,
+        w = 60,
+        h = 20,
+        font_size = 14,
+    })
+
+    local name_input = airui.textarea({
+        parent = form_container,
+        x = 80,
+        y = 15,
+        w = 180,
+        h = 30,
+        text = "",
+        placeholder = "请输入姓名",
+        max_len = 20,
+        keyboard = keyboard1
+    })
+
+    -- 邮箱输入
+    airui.label({
+        parent = form_container,
+        text = "邮箱:",
+        x = 10,
+        y = 60,
+        w = 60,
+        h = 20,
+        font_size = 14,
+    })
+
+    local email_input = airui.textarea({
+        parent = form_container,
+        x = 80,
+        y = 55,
+        w = 180,
+        h = 30,
+        text = "",
+        placeholder = "请输入邮箱",
+        max_len = 50,
+        keyboard = keyboard1
+    })
+
+    -- 提交按钮
+    local submit_btn = airui.button({
+        parent = form_container,
+        x = 80,
+        y = 100,
+        w = 120,
+        h = 35,
+        text = "提交",
+        on_click = function(self)
+            local name = name_input:get_text()
+            local email = email_input:get_text()
+
+            if name == "" or email == "" then
+                local msg = airui.msgbox({
+                    text = "请填写完整信息",
+                    buttons = { "确定" },
+                    on_action = function(self, label)
+                        if label == "确定" then
+                            self:hide()
+                        end
+                    end
+                })
+                msg:show()
+            else
+                local msg = airui.msgbox({
+                    text = "提交成功!\n姓名: " .. name .. "\n邮箱: " .. email,
+                    buttons = { "确定" },
+                    on_action = function(self, label)
+                        if label == "确定" then
+                            self:hide()
+                        end
+                    end
+                })
+                msg:show()
+            end
+        end
+    })
+
+    -- 示例5: 输入框控制
+    airui.label({
+        parent = scroll_container,
+        text = "示例5: 输入框控制",
+        x = 10,
+        y = 600,
+        w = 300,
+        h = 20,
+        font_size = 14,
+    })
+
+    local control_input = airui.textarea({
+        parent = scroll_container,
+        x = 20,
+        y = 630,
+        w = 200,
+        h = 60,
+        text = "可控制的输入框",
+        placeholder = "请输入...",
+        max_len = 50,
+        keyboard = keyboard1
+    })
+
+    -- 控制按钮
+    local clear_btn = airui.button({
+        parent = scroll_container,
+        x = 230,
+        y = 630,
+        w = 70,
+        h = 30,
+        text = "清空",
+        on_click = function(self)
+            control_input:set_text("")
+        end
+    })
+
+    local get_btn = airui.button({
+        parent = scroll_container,
+        x = 230,
+        y = 670,
+        w = 70,
+        h = 30,
+        text = "获取",
+        on_click = function(self)
+            local text = control_input:get_text()
+            local msg = airui.msgbox({
+                text = "当前内容: " .. text,
+                buttons = { "确定" },
+                timeout = 2000,
+                on_action = function(self, label)
+                    self:hide()
+                end
+            })
+            msg:show()
+        end
+    })
+
+    -- 设置光标位置
+    local cursor_btn = airui.button({
+        parent = scroll_container,
+        x = 20,
+        y = 700,
+        w = 130,
+        h = 35,
+        text = "光标到开头",
+        on_click = function(self)
+            control_input:set_cursor(0)
+        end
+    })
+
+    -- 底部信息
+    airui.label({
+        parent = main_container,
+        text = "提示: 输入框支持文本监听和控制",
+        x = 10,
+        y = 440,
+        w = 300,
+        h = 20,
+        font_size = 14,
+    })
+end
+
+-- 初始化页面
+function input_page.init(params)
+    input_page.create_ui()
+end
+
+-- 清理页面
+function input_page.cleanup()
+    if main_container then
+        main_container:destroy()
+        main_container = nil
+    end
+end
+
+return input_page

+ 250 - 0
script/ui/label_page.lua

@@ -0,0 +1,250 @@
+--[[
+@module  label_page
+@summary 标签组件演示页面
+@version 1.0
+@date    2026.02.05
+@author  江访
+@usage
+本文件是标签组件的演示页面,展示标签的各种用法。
+]]
+
+local label_page = {}
+
+-- 页面UI元素
+local main_container = nil
+local current_font = nil
+
+-- 创建UI
+function label_page.create_ui()
+    main_container = airui.container({
+        x = 0,
+        y = 0,
+        w = 320,
+        h = 480,
+        color = 0xF5F5F5,
+    })
+
+    -- 标题栏
+    local title_bar = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 0,
+        w = 320,
+        h = 50,
+        color = 0x4CAF50,
+    })
+
+    airui.label({
+        parent = title_bar,
+        text = "标签组件演示",
+        x = 10,
+        y = 15,
+        w = 200,
+        h = 20,
+        font_size = 16,
+        color = 0xFFFFFF,
+    })
+
+    -- 返回按钮
+    local back_btn = airui.button({
+        parent = title_bar,
+        x = 250,
+        y = 10,
+        w = 60,
+        h = 30,
+        text = "返回",
+        on_click = function(self)
+            go_back()
+        end
+    })
+
+    -- 滚动容器
+    local scroll_container = airui.container({
+        parent = main_container,
+        x = 0,
+        y = 60,
+        w = 320,
+        h = 370,
+        color = 0xF5F5F5,
+    })
+
+    -- 示例1: 基本文本标签
+    airui.label({
+        parent = scroll_container,
+        text = "示例1: 基本文本标签",
+        x = 10,
+        y = 10,
+        w = 300,
+        h = 20,
+        font_size = 14,
+    })
+
+    local label1 = airui.label({
+        parent = scroll_container,
+        text = "这是一个文本标签",
+        x = 20,
+        y = 40,
+        w = 280,
+        h = 30,
+        font_size = 14,
+    })
+
+    -- 示例2: 图标标签(使用符号)
+    airui.label({
+        parent = scroll_container,
+        text = "示例2: 图标标签",
+        x = 10,
+        y = 80,
+        w = 300,
+        h = 20,
+        font_size = 14,
+    })
+
+    local icon_label = airui.label({
+        parent = scroll_container,
+        symbol = airui.SYMBOL_SETTINGS,                     -- 使用符号字符串
+        x = 20,
+        y = 115,
+        w = 40,
+        h = 40,
+        font_size = 24,
+        on_click = function(self)
+            log.info("label", "图标标签被点击")
+        end
+    })
+
+    airui.label({
+        parent = scroll_container,
+        text = "点击图标",
+        x = 70,
+        y = 120,
+        w = 100,
+        h = 30,
+        font_size = 14,
+    })
+
+    -- 示例3: 动态更新文本
+    airui.label({
+        parent = scroll_container,
+        text = "示例3: 动态更新文本",
+        x = 10,
+        y = 160,
+        w = 300,
+        h = 20,
+        font_size = 14,
+    })
+
+    local dynamic_label = airui.label({
+        parent = scroll_container,
+        text = "初始文本",
+        x = 20,
+        y = 190,
+        w = 200,
+        h = 30,
+        font_size = 14,
+    })
+
+    local update_btn = airui.button({
+        parent = scroll_container,
+        x = 230,
+        y = 185,
+        w = 70,
+        h = 40,
+        text = "更新",
+        on_click = function(self)
+            local current_time = os.date("%H:%M:%S")
+            dynamic_label:set_text("时间: " .. current_time)
+        end
+    })
+
+    -- 示例4: 多行文本
+    airui.label({
+        parent = scroll_container,
+        text = "示例4: 多行文本",
+        x = 10,
+        y = 240,
+        w = 300,
+        h = 20,
+        font_size = 14,
+    })
+
+    local multiline_label = airui.label({
+        parent = scroll_container,
+        text = "这是一个多行文本标签,可以显示较长的文本内容。标签支持自动换行功能。",
+        x = 20,
+        y = 270,
+        w = 280,
+        h = 60,
+        font_size = 14,
+    })
+
+    -- 示例5: 不同字体大小和颜色
+    airui.label({
+        parent = scroll_container,
+        text = "示例5: 不同字体大小和颜色",
+        x = 10,
+        y = 330,
+        w = 300,
+        h = 20,
+        font_size = 14,
+    })
+
+    local size_label1 = airui.label({
+        parent = scroll_container,
+        text = "12px 红色",
+        x = 20,
+        y = 360,
+        w = 100,
+        h = 30,
+        font_size = 12,
+        color = 0xFF0000,
+    })
+
+    local size_label2 = airui.label({
+        parent = scroll_container,
+        text = "16px 绿色",
+        x = 130,
+        y = 360,
+        w = 100,
+        h = 30,
+        font_size = 16,
+        color = 0x00FF00,
+    })
+
+    local size_label3 = airui.label({
+        parent = scroll_container,
+        text = "20px 蓝色",
+        x = 240,
+        y = 360,
+        w = 60,
+        h = 50,
+        font_size = 20,
+        color = 0x0000FF,
+    })
+
+    -- 底部信息
+    airui.label({
+        parent = main_container,
+        text = "提示: 点击标签可以触发事件",
+        x = 10,
+        y = 440,
+        w = 300,
+        h = 20,
+        font_size = 14,
+    })
+end
+
+-- 初始化页面
+function label_page.init(params)
+    label_page.create_ui()
+end
+
+-- 清理页面
+function label_page.cleanup()
+    if main_container then
+        main_container:destroy()
+        main_container = nil
+    end
+end
+
+return label_page

Nem az összes módosított fájl került megjelenítésre, mert túl sok fájl változott