#include "GUI_tjc_hmi.h"
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdlib.h>

#include "proto_modbus_lib.h"

#include "bsp_w25q.h" // 添加Flash操作
#include "bsp_W5500.h"
#include "bsp_uart.h"
#include "bsp_DS1302.h"
#include "bsp_buzzer.h"

#include "app_leakage.h"
#include "app_com.h"
#include "app.h"
/*串口发送缓冲区*/
#define HMI_TX_BUFFER_NUM (4096)
/*字符发送拼接 缓冲区*/
#define GUI_TJC_HMI_TEXT_BUFFER_NUM (256)

/*帧头*/
#define HMI_PROTO_FRAME_HEADER1 (0xAA)
#define HMI_PROTO_FRAME_HEADER2 (0x55)
/*操作*/
#define HMI_PROTO_CMD_GET (0x03) /*获取数据数据*/
#define HMI_PROTO_CMD_SET (0x10) /*设置信息*/
/*界面*/
#define HMI_PROTO_GUI_MAIN (0x10)          /*主界面          */
#define HMI_PROTO_GUI_CURR_ALARM (0x11)    /*实时报警界面    */
#define HMI_PROTO_GUI_DETAIL_MAIN (0x12)   /*主界面_详细信息 */
#define HMI_PROTO_GUI_LOGIN (0x13)         /*登录界面        */
#define HMI_PROTO_GUI_HISTORY_ALARM (0x14) /*历史报警界面    */
#define HMI_PROTO_GUI_TCP_CONFIG (0x15)    /*网络配置界面    */
#define HMI_PROTO_GUI_DEVICE_CONFIG (0x16) /*设备配置界面    */
#define HMI_PROTO_GUI_HELP (0x17)          /*帮助界面        */
#define HMI_PROTO_GUI_TIME (0x18)          /*时间设置界面*/

/*界面ID*/
#define GUI_MAIN (10)          /*主界面*/
#define GUI_CURR_ALARM (11)    /*实时报警界面*/
#define GUI_DETALL_MAIN (12)   /*主界面_详细信息*/
#define GUI_LOGIN (13)         /*登陆界面*/
#define GUI_HISTORY_ALARM (14) /*历史报警界面*/
#define GUI_TCP_CONFIG (15)    /*网络配置界面*/
#define GUI_DEVICE_CONFIG (16) /*设备配置界面*/
#define GUI_TIME (18)          /*时间设置界面*/

#define HMI_PROTO_ASCII_RX_DELINITER (0xAA) /*接收分隔符*/

#define HMI_PROTO_ASCII_TX_DELINITER (0xFF)  /*发送分隔符*/
#define HMI_PROTO_ASCII_TX_DELINITER_NUM (3) /*发送分隔符数量*/

#define W25Q32_PASSWORD_ADDR (W25Q32_USER_DATA_ADDR) /*密码存储地址*/

static void gui_tjc_hmi_init(void);
static void gui_tjc_hmi_communication_data_analysis(u8 *p_data, u16 len, void *rx_uart);
static void gui_tjc_hmi_all_page_index_clear(void);
/*串口发送缓冲区*/
static u8 hmi_tx_buffer[HMI_TX_BUFFER_NUM];
/*字符发送拼接 缓冲区*/
static char gui_tjc_hmi_text_buffer[GUI_TJC_HMI_TEXT_BUFFER_NUM];
/*设备缓冲区*/
app_leakage_sub_device_flash_data_t temp_buffer[APP_LEAKAGE_SUB_DEVICE_NUM];
/*字符名称 端口号*/
static char *hmi_proto_string_com[] =
    {
        "COM1",
        "COM2",
        "COM3",
        "COM4"};

/*字符名称 波特率*/
static char *hmi_proto_string_baudrate[] =
    {
        "2400",
        "4800",
        "9600",
        "115200",
};

static bsp_uart_t *p_rx_uart = NULL;

gui_tjc_hmi_t tjc_hmi =
    {
        .all_page_index_clear = gui_tjc_hmi_all_page_index_clear,
        .init = gui_tjc_hmi_init,
};

gui_tjc_hmi_t *p_tjc_hmi = &tjc_hmi;

static void gui_tjc_hmi_class_update(void)
{
    gui_tjc_hmi_all_page_index_clear();
    leakage.class_update();
    app_com.class_update();
}

/*屏幕协议初始化*/
static void gui_tjc_hmi_init(void)
{
    com_uart1.rx_data_analysis = gui_tjc_hmi_communication_data_analysis;
}

/*发送接口*/
static void gui_tjc_hmi_data_send(u8 *p_data, u16 len)
{
    if (p_rx_uart != NULL)
    {
        p_rx_uart->send(p_rx_uart, p_data, len);
    }
}

static void gui_tjc_hmi_read_password_from_w25q(void)
{
    /*直接读取4字节密码*/
    w25q32.read(W25Q32_PASSWORD_ADDR, p_tjc_hmi->password, 4);

    /*检查数据有效性，如果全部为0xFF，说明是首次使用，清空密码*/
    if (p_tjc_hmi->password[0] == 0xFF &&
        p_tjc_hmi->password[1] == 0xFF &&
        p_tjc_hmi->password[2] == 0xFF &&
        p_tjc_hmi->password[3] == 0xFF)
    {
        memset(p_tjc_hmi->password, 0, 4);
    }
}

/*将密码保存到W25Q32*/
static void gui_tjc_hmi_save_password_to_w25q(void)
{
    u32 erase_addr = W25Q32_PASSWORD_ADDR & ~(W25Q32_SECTOR_SIZE - 1);
    w25q32_sector_erase(erase_addr);
    /*将4字节密码写入W25Q32*/
    w25q32.write(W25Q32_PASSWORD_ADDR, p_tjc_hmi->password, 4);
}

/* 将设备信息从app_leakage保存到W25Q32 */
static void gui_tjc_hmi_save_device_info_to_w25q(void)
{
    /* 从app_leakage结构体复制到临时缓冲区 */
    for (int i = 0; i < APP_LEAKAGE_SUB_DEVICE_NUM; i++)
    {
        temp_buffer[i] = leakage.sub_device_data[i].flash_data;
    }

    /* 添加Flash擦除操作 - 必须擦除后才能写入 */
    u32 erase_addr = W25Q32_DEVICE_INFO_ADDR;

    /* 确保地址是4K对齐（W25Q32_SECTOR_SIZE = 4096） */
    erase_addr &= ~(W25Q32_SECTOR_SIZE - 1);

    /* 擦除整个扇区 */
    w25q32_sector_erase(erase_addr);

    /* 一次性写入所有设备信息 */
    w25q32.write(W25Q32_DEVICE_INFO_ADDR,
                 (uint8_t *)temp_buffer,
                 DEVICE_INFO_STORAGE_SIZE);
}

/* 将当前W5500的网络配置保存到W25Q32 */
static void gui_tjc_hmi_save_network_config_to_w25q(void)
{
    u16 i;
    network_config_t config;
    memcpy(config.ip, W5500.IP_Addr, 4);
    memcpy(config.mask, W5500.Sub_Mask, 4);
    memcpy(config.gateway, W5500.Gateway_IP, 4);
    for (i = 0; i < NETWORK_PORT_NUM; i++)
    {
        config.port[i] = (W5500.W5500_Class[i].ConfigData.Port[0] << 8) |
                         W5500.W5500_Class[i].ConfigData.Port[1];
    }

    /* 擦除整个扇区（4K对齐） */
    u32 erase_addr = W25Q32_NETWORK_CONFIG_ADDR & ~(W25Q32_SECTOR_SIZE - 1);
    w25q32_sector_erase(erase_addr);

    /* 写入配置数据 */
    w25q32.write(W25Q32_NETWORK_CONFIG_ADDR, (uint8_t *)&config, sizeof(config));
}

/*解析网络函数*/
static void parse_ip_string(u8 *str, u8 len, u8 *ip)
{
    u8 i = 0, part = 0, val = 0;
    while (i < len)
    {
        if (str[i] == '.')
        {
            ip[part++] = val;
            val = 0;
        }
        else if (str[i] >= '0' && str[i] <= '9')
        {
            val = val * 10 + (str[i] - '0');
        }
        i++;
    }
    ip[part] = val; // 最后一个部分
}

static void gui_tjc_hmi_all_page_index_clear(void)
{
    memset(&p_tjc_hmi->page, 0, sizeof(gui_tjc_hmi_page_t));
}

/*设置对应的控件
x：第几行
y：第几个
buffer：写入的buffer
format：格式化输入
...：不定长
*/
static u16 gui_tjc_hmi_tx_text_display(u16 z, u16 x, u16 y, char *buffer, const char *format, ...)
{
    u16 i, len;
    s16 state;
    va_list arg;

    /*清空缓冲区*/
    memset(gui_tjc_hmi_text_buffer, 0, sizeof(gui_tjc_hmi_text_buffer));

    va_start(arg, format);
    /*格式化转成字符串*/
    state = vsnprintf(gui_tjc_hmi_text_buffer, GUI_TJC_HMI_TEXT_BUFFER_NUM, format, arg);
    if (-1 == state || state > GUI_TJC_HMI_TEXT_BUFFER_NUM)
    {
        va_end(arg);
        printf("Length REEOR");
        return 0;
    }

    /*拼接字符串*/
    sprintf(buffer, "t%d_%d_%d.txt=\"%s\"", z, x, y, gui_tjc_hmi_text_buffer);
    len = strlen(buffer);
    for (i = 0; i < HMI_PROTO_ASCII_TX_DELINITER_NUM; i++)
    {
        buffer[len + i] = HMI_PROTO_ASCII_TX_DELINITER;
    }
    va_end(arg);
    return len + 3;
}

/*主界面响应*/
static void gui_tjc_hmi_main_send(u8 cmd, u8 opa, u8 *p_data)
{
/*每页显示的区域数量*/
#define MAIN_PAGE_SUB_DEVICE_NUM (4)

    u16 len = 0, i, j, x, y, index;
    u8 page_num, remain_region_num;

    memset(hmi_tx_buffer, 0, sizeof(hmi_tx_buffer));

    /*计算页面数量*/
    page_num = leakage.region_num / MAIN_PAGE_SUB_DEVICE_NUM;
    remain_region_num = leakage.region_num % MAIN_PAGE_SUB_DEVICE_NUM; /*剩余区域数量*/
    if (remain_region_num > 0)
    {
        page_num++;
    }

    len += gui_tjc_hmi_tx_text_display(GUI_MAIN, 0, 3,
                                       (char *)&hmi_tx_buffer[len],
                                       "%d/%d",
                                       p_tjc_hmi->page.main_index + 1, page_num);

    char time[20];
    sprintf(time, "20%d-%02d-%02d %02d:%02d:%02d",
            DS1302.Time.Year,
            DS1302.Time.Month,
            DS1302.Time.Day,
            DS1302.Time.Hour,
            DS1302.Time.Minute,
            DS1302.Time.Second);
    len += gui_tjc_hmi_tx_text_display(GUI_MAIN, 0, 0, (char *)&hmi_tx_buffer[len], "%s", time);

    /*IP地址*/
    len += gui_tjc_hmi_tx_text_display(GUI_MAIN, 0, 1, (char *)&hmi_tx_buffer[len],
                                       "%d.%d.%d.%d:%d,%d,%d,%d",
                                       W5500.IP_Addr[0],
                                       W5500.IP_Addr[1],
                                       W5500.IP_Addr[2],
                                       W5500.IP_Addr[3],
                                       (W5500.W5500_Class[0].ConfigData.Port[0] << 8) | (W5500.W5500_Class[0].ConfigData.Port[1]),
                                       (W5500.W5500_Class[1].ConfigData.Port[0] << 8) | (W5500.W5500_Class[1].ConfigData.Port[1]),
                                       (W5500.W5500_Class[2].ConfigData.Port[0] << 8) | (W5500.W5500_Class[2].ConfigData.Port[1]),
                                       (W5500.W5500_Class[3].ConfigData.Port[0] << 8) | (W5500.W5500_Class[3].ConfigData.Port[1]));

    /*蜂鸣器状态*/
    u8 buzzer_state = (buzzer.p_flash_data->sw == USR_ENABLE) ? 11 : 13;
    /*构造 "sw0.val=x" 指令（x 为 0 或 1）*/
    len += sprintf((char *)&hmi_tx_buffer[len], "p4.pic=%d", buzzer_state);
    for (u8 i = 0; i < 3; i++)
    {
        hmi_tx_buffer[len + i] = 0xFF;
    }
    len += 3;
    /*软件版本号*/
    len += gui_tjc_hmi_tx_text_display(GUI_MAIN, 0, 2, (char *)&hmi_tx_buffer[len],
                                       "%s", SwVersion);

    if (HMI_PROTO_CMD_GET == cmd) /*获取数据*/
    {
        switch (opa)
        {
        case 0x01: /*读取区域信息*/
        {
            if (leakage.region_num == 0)
            {
                for (j = 0; j < MAIN_PAGE_SUB_DEVICE_NUM; j++)
                {
                    for (y = 0; y < 5; y++)
                    {
                        len += gui_tjc_hmi_tx_text_display(GUI_MAIN, j + 1, y + 1, (char *)&hmi_tx_buffer[len], "");
                    }
                }
                break;
            }

            if (p_tjc_hmi->page.main_index == page_num - 1 && remain_region_num > 0) /*显示剩余区域*/
            {
                for (j = 0; j < remain_region_num; j++)
                {
                    index = p_tjc_hmi->page.main_index * MAIN_PAGE_SUB_DEVICE_NUM + j;
                    x = j;
                    /*名称*/
                    y = 0;
                    len += gui_tjc_hmi_tx_text_display(GUI_MAIN, x + 1, y + 1, (char *)&hmi_tx_buffer[len], "%s", leakage.region_data[index].name);
                    /*区域内设备总数量*/
                    y = 1;
                    len += gui_tjc_hmi_tx_text_display(GUI_MAIN, x + 1, y + 1, (char *)&hmi_tx_buffer[len], "%d", leakage.region_data[index].sub_device_num);
                    /*漏液数量*/
                    y = 2;
                    if (leakage.region_data[index].leakage_num == 0)
                    {
                        len += gui_tjc_hmi_tx_text_display(GUI_MAIN, x + 1, y + 1, (char *)&hmi_tx_buffer[len], "%s", "Normal");
                    }
                    else
                    {
                        len += gui_tjc_hmi_tx_text_display(GUI_MAIN, x + 1, y + 1, (char *)&hmi_tx_buffer[len], "%d", leakage.region_data[index].leakage_num);
                    }
                    /*断带*/
                    y = 3;
                    if (leakage.region_data[index].open_num == 0)
                    {
                        len += gui_tjc_hmi_tx_text_display(GUI_MAIN, x + 1, y + 1, (char *)&hmi_tx_buffer[len], "%s", "Normal");
                    }
                    else
                    {
                        len += gui_tjc_hmi_tx_text_display(GUI_MAIN, x + 1, y + 1, (char *)&hmi_tx_buffer[len], "%d", leakage.region_data[index].open_num);
                    }
                    /*通讯*/
                    y = 4;
                    if (leakage.region_data[index].time_out_num == 0)
                    {
                        len += gui_tjc_hmi_tx_text_display(GUI_MAIN, x + 1, y + 1, (char *)&hmi_tx_buffer[len], "%s", "Normal");
                    }
                    else
                    {
                        len += gui_tjc_hmi_tx_text_display(GUI_MAIN, x + 1, y + 1, (char *)&hmi_tx_buffer[len], "%d", leakage.region_data[index].time_out_num);
                    }
                }
                // 清除多余列的所有行（设置为空字符串）
                for (j = remain_region_num; j < MAIN_PAGE_SUB_DEVICE_NUM; j++)
                {
                    for (y = 0; y < 5; y++) // 共有5行数据
                    {
                        len += gui_tjc_hmi_tx_text_display(GUI_MAIN, j + 1, y + 1, (char *)&hmi_tx_buffer[len], "");
                    }
                }
            }
            else
            {
                for (j = 0; j < MAIN_PAGE_SUB_DEVICE_NUM; j++)
                {
                    index = p_tjc_hmi->page.main_index * MAIN_PAGE_SUB_DEVICE_NUM + j;
                    x = j;
                    /*名称*/
                    y = 0;
                    len += gui_tjc_hmi_tx_text_display(GUI_MAIN, x + 1, y + 1, (char *)&hmi_tx_buffer[len], "%s", leakage.region_data[index].name);
                    /*区域内设备总数量*/
                    y = 1;
                    len += gui_tjc_hmi_tx_text_display(GUI_MAIN, x + 1, y + 1, (char *)&hmi_tx_buffer[len], "%d", leakage.region_data[index].sub_device_num);
                    /*漏液数量*/
                    y = 2;
                    if (leakage.region_data[index].leakage_num == 0)
                    {
                        len += gui_tjc_hmi_tx_text_display(GUI_MAIN, x + 1, y + 1, (char *)&hmi_tx_buffer[len], "%s", "Normal");
                    }
                    else
                    {
                        len += gui_tjc_hmi_tx_text_display(GUI_MAIN, x + 1, y + 1, (char *)&hmi_tx_buffer[len], "%d", leakage.region_data[index].leakage_num);
                    }
                    /*断带*/
                    y = 3;
                    if (leakage.region_data[index].open_num == 0)
                    {
                        len += gui_tjc_hmi_tx_text_display(GUI_MAIN, x + 1, y + 1, (char *)&hmi_tx_buffer[len], "%s", "Normal");
                    }
                    else
                    {
                        len += gui_tjc_hmi_tx_text_display(GUI_MAIN, x + 1, y + 1, (char *)&hmi_tx_buffer[len], "%d", leakage.region_data[index].open_num);
                    }
                    /*通讯*/
                    y = 4;
                    if (leakage.region_data[index].time_out_num == 0)
                    {
                        len += gui_tjc_hmi_tx_text_display(GUI_MAIN, x + 1, y + 1, (char *)&hmi_tx_buffer[len], "%s", "Normal");
                    }
                    else
                    {
                        len += gui_tjc_hmi_tx_text_display(GUI_MAIN, x + 1, y + 1, (char *)&hmi_tx_buffer[len], "%d", leakage.region_data[index].time_out_num);
                    }
                }
            }
        }
        break;
        case 0x03: /*翻页*/
        {
            if (0x01 == p_data[0])
            {
                if (page_num - 1 <= p_tjc_hmi->page.main_index)
                {
                    p_tjc_hmi->page.main_index = 0;
                }
                else
                {
                    p_tjc_hmi->page.main_index++;
                }
            }
            else
            {

                if (0 == p_tjc_hmi->page.main_index)
                {
                    p_tjc_hmi->page.main_index = page_num - 1;
                }
                else
                {
                    p_tjc_hmi->page.main_index--;
                }
            }
        }
        default:
            return;
        }
        len = strlen((char *)hmi_tx_buffer);
        gui_tjc_hmi_data_send(hmi_tx_buffer, len);
    }
    else if (HMI_PROTO_CMD_SET == cmd) /*设置*/
    {
        switch (opa)
        {
        case 0x01: /*蜂鸣器开关*/
        {
            if (0x01 == p_data[0])
            {
                /*01打开蜂鸣器*/
                buzzer.set.enable();
            }
            else
            {
                /*00关闭蜂鸣器*/
                buzzer.set.disable();
            }
        }
        default:
            return;
        }
        len = strlen((char *)hmi_tx_buffer);
        gui_tjc_hmi_data_send(hmi_tx_buffer, len);
    }
}

/*实时报警响应*/
static void gui_tjc_hmi_curr_alarm_send(u8 cmd, u8 opa, u8 *p_data)
{
/*每页显示的报警设备数量*/
#define REAL_ALARM_PAGE_NUM (4)
    u16 len = 0, i, j, x, y, device_index, ch, index;
    u8 page_num, remain_alrm_device_num, display_count;
    u8 alarm_device_count;
    u8 alarm_device_index[APP_LEAKAGE_SUB_DEVICE_NUM];

    memset(hmi_tx_buffer, 0, sizeof(hmi_tx_buffer));

    /*计算报警设备数量*/
    alarm_device_count = 0;
    j = 0;
    for (i = 0; i < APP_LEAKAGE_SUB_DEVICE_NUM; i++)
    {
        if (ENABLE != leakage.sub_device_data[i].flash_data.state)
        {
            continue;
        }

        if (UNBLOCKED != leakage.sub_device_data[i].shield)
        {
            continue;
        }

        for (ch = 0; ch < APP_LEAKAGE_SUB_DEVICE_CH_NUM; ch++)
        {
            u16 ch_state = leakage.sub_device_data[i].ch_data[ch].state;
            if (ch_state & (APP_LEAKAGE_SUB_DEVICE_STATE_TIME_OUT | APP_LEAKAGE_SUB_DEVICE_STATE_OPEN | APP_LEAKAGE_SUB_DEVICE_STATE_LEAKAGE))
            {
                alarm_device_index[alarm_device_count] = i;
                alarm_device_count++;
                break;
            }
        }
    }

    /*计算页面数量*/
    page_num = alarm_device_count / REAL_ALARM_PAGE_NUM;
    remain_alrm_device_num = alarm_device_count % REAL_ALARM_PAGE_NUM;
    if (remain_alrm_device_num > 0)
    {
        page_num++;
    }

    if (page_num == 0)
    {
        page_num = 1;
    }
    if (p_tjc_hmi->page.real_alarm_index >= page_num)
    {
        p_tjc_hmi->page.real_alarm_index = page_num - 1;
    }
    len += gui_tjc_hmi_tx_text_display(GUI_CURR_ALARM, 0, 0,
                                       (char *)&hmi_tx_buffer[len],
                                       "%d/%d",
                                       p_tjc_hmi->page.real_alarm_index + 1, page_num);

    if (HMI_PROTO_CMD_GET == cmd) /*获取数据*/
    {
        switch (opa)
        {
        case 0x01: /*获取实时报警信息*/
        {
            if (alarm_device_count == 0)
            {
                for (i = 0; i < REAL_ALARM_PAGE_NUM; i++)
                {
                    x = i;
                    len += gui_tjc_hmi_tx_text_display(GUI_CURR_ALARM, x + 1, 1, (char *)&hmi_tx_buffer[len], ""); // 区域名
                    len += gui_tjc_hmi_tx_text_display(GUI_CURR_ALARM, x + 1, 2, (char *)&hmi_tx_buffer[len], ""); // 设备ID
                    len += gui_tjc_hmi_tx_text_display(GUI_CURR_ALARM, x + 1, 3, (char *)&hmi_tx_buffer[len], ""); // 设备名称
                    len += gui_tjc_hmi_tx_text_display(GUI_CURR_ALARM, x + 1, 4, (char *)&hmi_tx_buffer[len], ""); // 通讯状态
                    for (ch = 0; ch < APP_LEAKAGE_SUB_DEVICE_CH_NUM; ch++)
                    {
                        len += gui_tjc_hmi_tx_text_display(GUI_CURR_ALARM, x + 1, 5 + (ch * 3), (char *)&hmi_tx_buffer[len], "");
                        len += gui_tjc_hmi_tx_text_display(GUI_CURR_ALARM, x + 1, 6 + (ch * 3), (char *)&hmi_tx_buffer[len], "");
                        len += gui_tjc_hmi_tx_text_display(GUI_CURR_ALARM, x + 1, 7 + (ch * 3), (char *)&hmi_tx_buffer[len], "");
                    }
                }
            }
            else
            {
                if (p_tjc_hmi->page.real_alarm_index == page_num - 1 && remain_alrm_device_num > 0)
                {
                    for (j = 0; j < remain_alrm_device_num; j++)
                    {
                        index = p_tjc_hmi->page.real_alarm_index * REAL_ALARM_PAGE_NUM + j;
                        device_index = alarm_device_index[index];
                        x = j;

                        /*区域名称*/
                        y = 0;
                        len += gui_tjc_hmi_tx_text_display(GUI_CURR_ALARM, x + 1, y + 1, (char *)&hmi_tx_buffer[len], "%s", leakage.sub_device_data[device_index].flash_data.region_name);

                        /*设备ID*/
                        y = 1;
                        len += gui_tjc_hmi_tx_text_display(GUI_CURR_ALARM, x + 1, y + 1, (char *)&hmi_tx_buffer[len], "%d", leakage.sub_device_data[device_index].flash_data.modbus_id);

                        /*设备名称*/
                        y = 2;
                        len += gui_tjc_hmi_tx_text_display(GUI_CURR_ALARM, x + 1, y + 1, (char *)&hmi_tx_buffer[len], "%s", leakage.sub_device_data[device_index].flash_data.device_name);

                        /*通讯状态*/
                        y = 3;
                        u16 comm_state = 0;
                        for (ch = 0; ch < APP_LEAKAGE_SUB_DEVICE_CH_NUM; ch++)
                        {
                            if (leakage.sub_device_data[device_index].ch_data[ch].state & APP_LEAKAGE_SUB_DEVICE_STATE_TIME_OUT)
                            {
                                comm_state = APP_LEAKAGE_SUB_DEVICE_STATE_TIME_OUT;
                                break;
                            }
                        }
                        if (comm_state & APP_LEAKAGE_SUB_DEVICE_STATE_TIME_OUT)
                        {
                            len += gui_tjc_hmi_tx_text_display(GUI_CURR_ALARM, x + 1, y + 1, (char *)&hmi_tx_buffer[len], "通讯异常");
                        }
                        else
                        {
                            len += gui_tjc_hmi_tx_text_display(GUI_CURR_ALARM, x + 1, y + 1, (char *)&hmi_tx_buffer[len], "通讯正常");
                        }

                        /*通道状态*/
                        for (ch = 0; ch < APP_LEAKAGE_SUB_DEVICE_USE_CH_NUM; ch++)
                        {
                            u16 ch_state = leakage.sub_device_data[device_index].ch_data[ch].state;
                            u16 ch_distance = leakage.sub_device_data[device_index].ch_data[ch].distance;

                            y = 4 + (ch * 3);
                            if (comm_state & APP_LEAKAGE_SUB_DEVICE_STATE_TIME_OUT)
                            {
                                len += gui_tjc_hmi_tx_text_display(GUI_CURR_ALARM, x + 1, y + 1, (char *)&hmi_tx_buffer[len], "-");
                            }
                            else if (ch_state & APP_LEAKAGE_SUB_DEVICE_STATE_LEAKAGE)
                            {
                                len += gui_tjc_hmi_tx_text_display(GUI_CURR_ALARM, x + 1, y + 1, (char *)&hmi_tx_buffer[len], "漏液");
                            }
                            else
                            {
                                len += gui_tjc_hmi_tx_text_display(GUI_CURR_ALARM, x + 1, y + 1, (char *)&hmi_tx_buffer[len], "正常");
                            }

                            y = 5 + (ch * 3);
                            if (comm_state & APP_LEAKAGE_SUB_DEVICE_STATE_TIME_OUT)
                            {
                                len += gui_tjc_hmi_tx_text_display(GUI_CURR_ALARM, x + 1, y + 1, (char *)&hmi_tx_buffer[len], "-");
                            }
                            else if (ch_state & APP_LEAKAGE_SUB_DEVICE_STATE_OPEN)
                            {
                                len += gui_tjc_hmi_tx_text_display(GUI_CURR_ALARM, x + 1, y + 1, (char *)&hmi_tx_buffer[len], "断带");
                            }
                            else
                            {
                                len += gui_tjc_hmi_tx_text_display(GUI_CURR_ALARM, x + 1, y + 1, (char *)&hmi_tx_buffer[len], "正常");
                            }

                            y = 6 + (ch * 3);
                            if (comm_state & APP_LEAKAGE_SUB_DEVICE_STATE_TIME_OUT)
                            {
                                len += gui_tjc_hmi_tx_text_display(GUI_CURR_ALARM, x + 1, y + 1, (char *)&hmi_tx_buffer[len], "-");
                            }
                            else if (ch_state & APP_LEAKAGE_SUB_DEVICE_STATE_LEAKAGE)
                            {
                                len += gui_tjc_hmi_tx_text_display(GUI_CURR_ALARM, x + 1, y + 1, (char *)&hmi_tx_buffer[len], "%.2f", ch_distance / LEAKAGE_MULTIPLE);
                            }
                            else
                            {
                                len += gui_tjc_hmi_tx_text_display(GUI_CURR_ALARM, x + 1, y + 1, (char *)&hmi_tx_buffer[len], "0");
                            }
                        }
                    }
                }
                else
                {
                    for (j = 0; j < REAL_ALARM_PAGE_NUM; j++)
                    {
                        index = p_tjc_hmi->page.real_alarm_index * REAL_ALARM_PAGE_NUM + j;
                        device_index = alarm_device_index[index];

                        x = j;

                        /*区域名称*/
                        y = 0;
                        len += gui_tjc_hmi_tx_text_display(GUI_CURR_ALARM, x + 1, y + 1, (char *)&hmi_tx_buffer[len], "%s", leakage.sub_device_data[device_index].flash_data.region_name);

                        /*设备ID*/
                        y = 1;
                        len += gui_tjc_hmi_tx_text_display(GUI_CURR_ALARM, x + 1, y + 1, (char *)&hmi_tx_buffer[len], "%d", leakage.sub_device_data[device_index].flash_data.modbus_id);

                        /*设备名称*/
                        y = 2;
                        len += gui_tjc_hmi_tx_text_display(GUI_CURR_ALARM, x + 1, y + 1, (char *)&hmi_tx_buffer[len], "%s", leakage.sub_device_data[device_index].flash_data.device_name);

                        /*通讯状态*/
                        y = 3;
                        u16 comm_state = 0;
                        for (ch = 0; ch < APP_LEAKAGE_SUB_DEVICE_CH_NUM; ch++)
                        {
                            if (leakage.sub_device_data[device_index].ch_data[ch].state & APP_LEAKAGE_SUB_DEVICE_STATE_TIME_OUT)
                            {
                                comm_state = APP_LEAKAGE_SUB_DEVICE_STATE_TIME_OUT;
                                break;
                            }
                        }
                        if (comm_state & APP_LEAKAGE_SUB_DEVICE_STATE_TIME_OUT)
                        {
                            len += gui_tjc_hmi_tx_text_display(GUI_CURR_ALARM, x + 1, y + 1, (char *)&hmi_tx_buffer[len], "通讯异常");
                        }
                        else
                        {
                            len += gui_tjc_hmi_tx_text_display(GUI_CURR_ALARM, x + 1, y + 1, (char *)&hmi_tx_buffer[len], "通讯正常");
                        }

                        /*通道状态*/
                        for (ch = 0; ch < APP_LEAKAGE_SUB_DEVICE_USE_CH_NUM; ch++)
                        {
                            u16 ch_state = leakage.sub_device_data[device_index].ch_data[ch].state;
                            u16 ch_distance = leakage.sub_device_data[device_index].ch_data[ch].distance;

                            y = 4 + (ch * 3);
                            if (comm_state & APP_LEAKAGE_SUB_DEVICE_STATE_TIME_OUT)
                            {
                                len += gui_tjc_hmi_tx_text_display(GUI_CURR_ALARM, x + 1, y + 1, (char *)&hmi_tx_buffer[len], "-");
                            }
                            else if (ch_state & APP_LEAKAGE_SUB_DEVICE_STATE_LEAKAGE)
                            {
                                len += gui_tjc_hmi_tx_text_display(GUI_CURR_ALARM, x + 1, y + 1, (char *)&hmi_tx_buffer[len], "漏液");
                            }
                            else
                            {
                                len += gui_tjc_hmi_tx_text_display(GUI_CURR_ALARM, x + 1, y + 1, (char *)&hmi_tx_buffer[len], "正常");
                            }

                            y = 5 + (ch * 3);
                            if (comm_state & APP_LEAKAGE_SUB_DEVICE_STATE_TIME_OUT)
                            {
                                len += gui_tjc_hmi_tx_text_display(GUI_CURR_ALARM, x + 1, y + 1, (char *)&hmi_tx_buffer[len], "-");
                            }
                            else if (ch_state & APP_LEAKAGE_SUB_DEVICE_STATE_OPEN)
                            {
                                len += gui_tjc_hmi_tx_text_display(GUI_CURR_ALARM, x + 1, y + 1, (char *)&hmi_tx_buffer[len], "断带");
                            }
                            else
                            {
                                len += gui_tjc_hmi_tx_text_display(GUI_CURR_ALARM, x + 1, y + 1, (char *)&hmi_tx_buffer[len], "正常");
                            }

                            y = 6 + (ch * 3);
                            if (comm_state & APP_LEAKAGE_SUB_DEVICE_STATE_TIME_OUT)
                            {
                                len += gui_tjc_hmi_tx_text_display(GUI_CURR_ALARM, x + 1, y + 1, (char *)&hmi_tx_buffer[len], "-");
                            }
                            else if (ch_state & APP_LEAKAGE_SUB_DEVICE_STATE_LEAKAGE)
                            {
                                len += gui_tjc_hmi_tx_text_display(GUI_CURR_ALARM, x + 1, y + 1, (char *)&hmi_tx_buffer[len], "%.2f", ch_distance / LEAKAGE_MULTIPLE);
                            }
                            else
                            {
                                len += gui_tjc_hmi_tx_text_display(GUI_CURR_ALARM, x + 1, y + 1, (char *)&hmi_tx_buffer[len], "0");
                            }
                        }
                    }
                }
                for (; j < REAL_ALARM_PAGE_NUM; j++)
                {
                    x = j;
                    len += gui_tjc_hmi_tx_text_display(GUI_CURR_ALARM, x + 1, 1, (char *)&hmi_tx_buffer[len], ""); // 区域名
                    len += gui_tjc_hmi_tx_text_display(GUI_CURR_ALARM, x + 1, 2, (char *)&hmi_tx_buffer[len], ""); // 设备ID
                    len += gui_tjc_hmi_tx_text_display(GUI_CURR_ALARM, x + 1, 3, (char *)&hmi_tx_buffer[len], ""); // 设备名称
                    len += gui_tjc_hmi_tx_text_display(GUI_CURR_ALARM, x + 1, 4, (char *)&hmi_tx_buffer[len], ""); // 通讯状态
                    for (ch = 0; ch < APP_LEAKAGE_SUB_DEVICE_CH_NUM; ch++)
                    {
                        len += gui_tjc_hmi_tx_text_display(GUI_CURR_ALARM, x + 1, 5 + (ch * 3), (char *)&hmi_tx_buffer[len], "");
                        len += gui_tjc_hmi_tx_text_display(GUI_CURR_ALARM, x + 1, 6 + (ch * 3), (char *)&hmi_tx_buffer[len], "");
                        len += gui_tjc_hmi_tx_text_display(GUI_CURR_ALARM, x + 1, 7 + (ch * 3), (char *)&hmi_tx_buffer[len], "");
                    }
                }
            }
        }
        break;
        case 0x03: /*翻页*/
        {
            if (0x01 == p_data[0])
            {
                if (page_num - 1 <= p_tjc_hmi->page.real_alarm_index)
                {
                    p_tjc_hmi->page.real_alarm_index = 0;
                }
                else
                {
                    p_tjc_hmi->page.real_alarm_index++;
                }
            }
            else
            {

                if (0 == p_tjc_hmi->page.real_alarm_index)
                {
                    p_tjc_hmi->page.real_alarm_index = page_num - 1;
                }
                else
                {
                    p_tjc_hmi->page.real_alarm_index--;
                }
            }
        }
        default:
            return;
        }
        len = strlen((char *)hmi_tx_buffer);
        gui_tjc_hmi_data_send(hmi_tx_buffer, len);
    }
    else if (HMI_PROTO_CMD_SET == cmd) /*设置*/
    {
        switch (opa)
        {
        case 0x01:
        {
        }
        break;
        case 0x02:
        {
        }
        break;
        default:
            return;
        }
        len = strlen((char *)hmi_tx_buffer);
        gui_tjc_hmi_data_send(hmi_tx_buffer, len);
    }
}
/*主界面详情*/
static void gui_tjc_hmi_detail_main_send(u8 cmd, u8 opa, u8 *p_data)
{
#define DETAIL_MAIN_NUM (4) /* 每页显示4个设备 */

    u16 len = 0, i, sub_device_index, ch, x, y, index;
    u8 page_num = 0, remain_device_num, display_count;
    u8 region_idx; /* 区域索引 */
    app_leakage_region_data_class_t *region_data;

    memset(hmi_tx_buffer, 0, sizeof(hmi_tx_buffer));

    region_idx = p_tjc_hmi->page.deliniter_main_index;
    if (region_idx >= leakage.region_num)
        return;

    region_data = &leakage.region_data[region_idx];

    /* 计算详情页面数量：每页显示4个设备 */
    page_num = region_data->sub_device_num / DETAIL_MAIN_NUM;
    remain_device_num = region_data->sub_device_num % DETAIL_MAIN_NUM;
    if (remain_device_num > 0)
    {
        page_num++;
    }
    /*页数*/
    len += gui_tjc_hmi_tx_text_display(GUI_DETALL_MAIN, 0, 0,
                                       (char *)&hmi_tx_buffer[len],
                                       "%d/%d",
                                       p_tjc_hmi->page.detail_main_index + 1, page_num);

    if (HMI_PROTO_CMD_GET == cmd) /* 获取数据 */
    {
        switch (opa)
        {
        case 0x01: /* 获取设备详情信息 */
        {
            u8 relative_region_idx = p_data[0];
            if (relative_region_idx < 1 || relative_region_idx > 4)
                return;

            /* 计算全局区域索引 */
            region_idx = p_tjc_hmi->page.main_index * 4 + (relative_region_idx - 1);
            if (region_idx >= leakage.region_num)
                return;

            /* 切换区域时重置详情页码 */
            if (region_idx != p_tjc_hmi->page.deliniter_main_index)
                p_tjc_hmi->page.detail_main_index = 0;

            p_tjc_hmi->page.deliniter_main_index = region_idx;
            region_data = &leakage.region_data[region_idx];

            /* 计算页面参数 */
            page_num = region_data->sub_device_num / DETAIL_MAIN_NUM;
            remain_device_num = region_data->sub_device_num % DETAIL_MAIN_NUM;
            if (remain_device_num > 0)
                page_num++;
            if (page_num == 0)
                page_num = 1;

            u8 start_index = p_tjc_hmi->page.detail_main_index * DETAIL_MAIN_NUM;
            display_count = (p_tjc_hmi->page.detail_main_index == page_num - 1 && remain_device_num > 0)
                                ? remain_device_num
                                : DETAIL_MAIN_NUM;

            for (i = 0; i < display_count; i++)
            {
                index = start_index + i;
                if (index >= region_data->sub_device_num)
                    break;
                sub_device_index = region_data->sub_device_index[index];
                x = i;

                /* 设备ID: t(x+1)_1 */
                y = 0;
                len += gui_tjc_hmi_tx_text_display(GUI_DETALL_MAIN, x + 1, y + 1,
                                                   (char *)&hmi_tx_buffer[len],
                                                   "ID:%d",
                                                   leakage.sub_device_data[sub_device_index].flash_data.modbus_id);

                /* 设备名称: t(x+1)_2 */
                y = 1;
                len += gui_tjc_hmi_tx_text_display(GUI_DETALL_MAIN, x + 1, y + 1,
                                                   (char *)&hmi_tx_buffer[len],
                                                   "%s",
                                                   leakage.sub_device_data[sub_device_index].flash_data.device_name);

                /* 通讯状态: t(x+1)_3 */
                y = 2;
                u8 comm_state = 0;
                for (ch = 0; ch < APP_LEAKAGE_SUB_DEVICE_CH_NUM; ch++)
                {
                    if (leakage.sub_device_data[sub_device_index].ch_data[ch].state &
                        APP_LEAKAGE_SUB_DEVICE_STATE_TIME_OUT)
                    {
                        comm_state = 1;
                        break;
                    }
                }
                if (leakage.sub_device_data[sub_device_index].shield == UNBLOCKED)
                {
                    if (comm_state)
                    {
                        len += gui_tjc_hmi_tx_text_display(GUI_DETALL_MAIN, x + 1, y + 1,
                                                           (char *)&hmi_tx_buffer[len],
                                                           "通讯异常");
                    }
                    else
                    {
                        len += gui_tjc_hmi_tx_text_display(GUI_DETALL_MAIN, x + 1, y + 1,
                                                           (char *)&hmi_tx_buffer[len],
                                                           "通讯正常");
                    }
                }
                else
                {
                    len += gui_tjc_hmi_tx_text_display(GUI_DETALL_MAIN, x + 1, y + 1,
                                                       (char *)&hmi_tx_buffer[len],
                                                       "正常");
                }

                /* 通道1-4状态 */
                for (ch = 0; ch < APP_LEAKAGE_SUB_DEVICE_USE_CH_NUM; ch++)
                {
                    u16 ch_state = leakage.sub_device_data[sub_device_index].ch_data[ch].state;
                    u16 ch_distance = leakage.sub_device_data[sub_device_index].ch_data[ch].distance;

                    /* 漏液状态 */
                    y = 3 + (ch * 3);
                    if (leakage.sub_device_data[sub_device_index].shield == UNBLOCKED)
                    {

                        if (comm_state)
                        {
                            len += gui_tjc_hmi_tx_text_display(GUI_DETALL_MAIN, x + 1, y + 1,
                                                               (char *)&hmi_tx_buffer[len],
                                                               "-");
                        }
                        else if (ch_state & APP_LEAKAGE_SUB_DEVICE_STATE_LEAKAGE)
                        {
                            len += gui_tjc_hmi_tx_text_display(GUI_DETALL_MAIN, x + 1, y + 1,
                                                               (char *)&hmi_tx_buffer[len],
                                                               "漏液");
                        }
                        else
                        {
                            len += gui_tjc_hmi_tx_text_display(GUI_DETALL_MAIN, x + 1, y + 1,
                                                               (char *)&hmi_tx_buffer[len],
                                                               "正常");
                        }
                    }
                    else
                    {
                        len += gui_tjc_hmi_tx_text_display(GUI_DETALL_MAIN, x + 1, y + 1,
                                                           (char *)&hmi_tx_buffer[len],
                                                           "正常");
                    }

                    /* 断带状态 */
                    y = 4 + (ch * 3);
                    if (leakage.sub_device_data[sub_device_index].shield == UNBLOCKED)
                    {
                        if (comm_state)
                        {
                            len += gui_tjc_hmi_tx_text_display(GUI_DETALL_MAIN, x + 1, y + 1,
                                                               (char *)&hmi_tx_buffer[len],
                                                               "-");
                        }
                        else if (ch_state & APP_LEAKAGE_SUB_DEVICE_STATE_OPEN)
                        {
                            len += gui_tjc_hmi_tx_text_display(GUI_DETALL_MAIN, x + 1, y + 1,
                                                               (char *)&hmi_tx_buffer[len],
                                                               "断带");
                        }
                        else
                        {
                            len += gui_tjc_hmi_tx_text_display(GUI_DETALL_MAIN, x + 1, y + 1,
                                                               (char *)&hmi_tx_buffer[len],
                                                               "正常");
                        }
                    }
                    else
                    {
                        len += gui_tjc_hmi_tx_text_display(GUI_DETALL_MAIN, x + 1, y + 1,
                                                           (char *)&hmi_tx_buffer[len],
                                                           "正常");
                    }

                    /* 漏液位置 */
                    y = 5 + (ch * 3);
                    if (leakage.sub_device_data[sub_device_index].shield == UNBLOCKED)
                    {
                        if (comm_state)
                        {
                            len += gui_tjc_hmi_tx_text_display(GUI_DETALL_MAIN, x + 1, y + 1,
                                                               (char *)&hmi_tx_buffer[len],
                                                               "-");
                        }
                        else if (ch_state & APP_LEAKAGE_SUB_DEVICE_STATE_LEAKAGE)
                        {
                            len += gui_tjc_hmi_tx_text_display(GUI_DETALL_MAIN, x + 1, y + 1,
                                                               (char *)&hmi_tx_buffer[len],
                                                               "%.2f",
                                                               ch_distance / LEAKAGE_MULTIPLE);
                        }
                        else
                        {
                            len += gui_tjc_hmi_tx_text_display(GUI_DETALL_MAIN, x + 1, y + 1,
                                                               (char *)&hmi_tx_buffer[len],
                                                               "0");
                        }
                    }
                    else
                    {
                        len += gui_tjc_hmi_tx_text_display(GUI_DETALL_MAIN, x + 1, y + 1,
                                                           (char *)&hmi_tx_buffer[len],
                                                           "0");
                    }
                }
                /* 屏蔽状态显示: t(x+1)_16 */
                y = 15; // 第16列对应y=15
                if (leakage.sub_device_data[sub_device_index].shield == BLOCKED)
                {
                    len += gui_tjc_hmi_tx_text_display(GUI_DETALL_MAIN, x + 1, y + 1, (char *)&hmi_tx_buffer[len], "禁用中");
                }
                else
                {
                    len += gui_tjc_hmi_tx_text_display(GUI_DETALL_MAIN, x + 1, y + 1, (char *)&hmi_tx_buffer[len], "启用中");
                }
            }

            /*清空未使用的*/
            for (; i < DETAIL_MAIN_NUM; i++)
            {
                x = i;
                len += gui_tjc_hmi_tx_text_display(GUI_DETALL_MAIN, x + 1, 1, (char *)&hmi_tx_buffer[len], "");
                len += gui_tjc_hmi_tx_text_display(GUI_DETALL_MAIN, x + 1, 2, (char *)&hmi_tx_buffer[len], "");
                len += gui_tjc_hmi_tx_text_display(GUI_DETALL_MAIN, x + 1, 3, (char *)&hmi_tx_buffer[len], "");
                for (ch = 0; ch < APP_LEAKAGE_SUB_DEVICE_CH_NUM; ch++)
                {
                    len += gui_tjc_hmi_tx_text_display(GUI_DETALL_MAIN, x + 1, 4 + (ch * 3), (char *)&hmi_tx_buffer[len], "");
                    len += gui_tjc_hmi_tx_text_display(GUI_DETALL_MAIN, x + 1, 5 + (ch * 3), (char *)&hmi_tx_buffer[len], "");
                    len += gui_tjc_hmi_tx_text_display(GUI_DETALL_MAIN, x + 1, 6 + (ch * 3), (char *)&hmi_tx_buffer[len], "");
                }
                len += gui_tjc_hmi_tx_text_display(GUI_DETALL_MAIN, x + 1, 16, (char *)&hmi_tx_buffer[len], "");
            }
        }
        break;

        case 0x03: /* 翻页 */
        {

            //                /*重新计算页数*/
            //                page_num = region_data->sub_device_num / DETAIL_MAIN_NUM;
            //                remain_device_num = region_data->sub_device_num % DETAIL_MAIN_NUM;
            //                if (remain_device_num > 0) page_num++;
            //                if (page_num == 0) page_num = 1;

            if (0x01 == p_data[0]) /* 下一页 */
            {
                if (page_num - 1 <= p_tjc_hmi->page.detail_main_index)
                {
                    p_tjc_hmi->page.detail_main_index = 0;
                }
                else
                {
                    p_tjc_hmi->page.detail_main_index++;
                }
            }
            else /* 上一页 */
            {
                if (0 == p_tjc_hmi->page.detail_main_index)
                {
                    p_tjc_hmi->page.detail_main_index = page_num - 1;
                }
                else
                {
                    p_tjc_hmi->page.detail_main_index--;
                }
            }
            return;
        }
        break;

        default:
            return;
        }

        len = strlen((char *)hmi_tx_buffer);
        gui_tjc_hmi_data_send(hmi_tx_buffer, len);
    }
    else if (HMI_PROTO_CMD_SET == cmd) /* 设置命令 */
    {
        switch (opa)
        {
        case 0x01: /* */
        {
            u8 len_id = 0;
            u8 device_id = 0;

            p_data = p_data + 3; /*将ID:偏移出去*/
            /* 解析设备ID：从p_data[0]开始，直到遇到分隔符 */
            while (p_data[len_id] != HMI_PROTO_ASCII_RX_DELINITER)
            {
                if (p_data[len_id] < '0' || p_data[len_id] > '9')
                {
                    return; /* 非法字符 */
                }
                len_id++;
                if (len_id > 3)
                { /* ID最多3位数字(0-255) */
                    return;
                }
            }
            if (len_id == 0)
            {
                return; /* ID不能为空 */
            }

            /* 将ASCII数字串转换为数值 */
            char id_str[4] = {0}; /* 最多3位数字加'\0' */
            memcpy(id_str, p_data, len_id);
            id_str[len_id] = '\0';
            int temp_id = atoi(id_str);
            if (temp_id < 0 || temp_id > 255)
            {
                return; /* ID超出范围 */
            }
            device_id = (u8)temp_id;

            /* 检查操作码及其后的分隔符 */
            u8 op_index = len_id + 1;    /* 操作码位置 */
            u8 delim_index = len_id + 2; /* 操作码后的分隔符位置 */
            if (p_data[delim_index] != HMI_PROTO_ASCII_RX_DELINITER)
            {
                return;
            }
            u8 operation = p_data[op_index]; /* 操作码直接作为数值 */

            /* 遍历所有使能的设备，查找匹配的modbus_id */
            u8 found = 0;
            for (u8 i = 0; i < APP_LEAKAGE_SUB_DEVICE_NUM; i++)
            {
                if (leakage.sub_device_data[i].flash_data.state == ENABLE &&
                    leakage.sub_device_data[i].flash_data.modbus_id == device_id)
                {
                    if (operation == 0x01)
                    {
                        leakage.sub_device_data[i].shield = BLOCKED; /* 屏蔽 */
                    }
                    else if (operation == 0x02)
                    {
                        leakage.sub_device_data[i].shield = UNBLOCKED; /* 恢复 */
                    }
                    else
                    {
                        return;
                    }
                    found = 1;
                    break;
                }
            }
            if (found)
            {
                /*将修改后的设备信息保存到 Flash*/
                gui_tjc_hmi_save_device_info_to_w25q();
            }
            return;
        }
        break;

        default:
            return;
        }
    }
}
/*登录界面*/
static void gui_tjc_hmi_login_send(u8 cmd, u8 opa, u8 *p_data)
{
    u16 len = 0, i;

    if (HMI_PROTO_CMD_GET == cmd) /* 获取数据 */
    {
        switch (opa)
        {
        case 0x01: /* 读取flash中存储的密码 */
        {
            gui_tjc_hmi_read_password_from_w25q();
            memset(hmi_tx_buffer, 0, sizeof(hmi_tx_buffer));
            /* 将密码数值以连续数字形式发送到控件 t22_1 */
            len = gui_tjc_hmi_tx_text_display(GUI_LOGIN, 22, 1, (char *)hmi_tx_buffer,
                                              "%d%d%d%d",
                                              p_tjc_hmi->password[0],
                                              p_tjc_hmi->password[1],
                                              p_tjc_hmi->password[2],
                                              p_tjc_hmi->password[3]);
            gui_tjc_hmi_data_send(hmi_tx_buffer, len);
            return; /* 直接返回，避免外层重复发送 */
        }
        break;
        case 0x02: /* 无操作 */
        default:
            return;
        }
    }
    else if (HMI_PROTO_CMD_SET == cmd) /* 设置数据 */
    {
        switch (opa)
        {
        case 0x01: /* 将密码存入flash */
        {
            /* 将ASCII码转换为数值（'0'~'9'） */
            for (i = 0; i < 4; i++)
            {
                if (p_data[i] >= '0' && p_data[i] <= '9')
                {
                    p_tjc_hmi->password[i] = p_data[i] - '0';
                }
                else
                {
                    p_tjc_hmi->password[i] = 0; /* 非法字符时清零 */
                }
            }
            /* 保存到W25Q32 */
            gui_tjc_hmi_save_password_to_w25q();
            /* 设置命令无需响应，直接返回 */
            return;
        }
        break;
        case 0x02: /* 无操作 */
        default:
            return;
        }
    }
}

/*历史报警界面*/
static void gui_tjc_hmi_history_alarm_send(u8 cmd, u8 opa, u8 *p_data)
{
#define HISTORY_ALARM_PER_PAGE (15) /* 每页15条历史报警数据 */
    u16 len = 0, i, j;
    u8 page_num, remain_records, display_count;
    u32 total_records, start_index, record_index = 0;
    app_leakage_history_alarm_t history_record;
    char time_str[20];
    char alarm_type_str[20];

    /* 获取总记录数 */
    total_records = leakage.history_metadata.total_records;

    /* 计算页面数量 */
    page_num = total_records / HISTORY_ALARM_PER_PAGE;
    remain_records = total_records % HISTORY_ALARM_PER_PAGE;
    if (remain_records > 0)
    {
        page_num++;
    }

    memset(hmi_tx_buffer, 0, sizeof(hmi_tx_buffer));

    /*页数*/
    len += gui_tjc_hmi_tx_text_display(GUI_HISTORY_ALARM, 0, 0,
                                       (char *)&hmi_tx_buffer[len],
                                       "%d/%d",
                                       p_tjc_hmi->page.history_alarm_index + 1, page_num == 0 ? 1 : page_num);

    if (HMI_PROTO_CMD_GET == cmd) /* 获取数据 */
    {
        switch (opa)
        {
        case 0x01: /* 读取历史报警信息 */
        {
            /* 获取当前页码对应的记录 */
            u8 current_page = p_tjc_hmi->page.history_alarm_index;

            /* 计算起始记录索引（按时间倒序显示，最新的在前面） */
            start_index = current_page * HISTORY_ALARM_PER_PAGE;

            /* 计算本页显示记录数 */
            if (current_page == page_num - 1 && remain_records > 0)
            {
                display_count = remain_records;
            }
            else
            {
                display_count = HISTORY_ALARM_PER_PAGE;
            }

            if (total_records == 0) /*没有需要显示的信息*/
            {
                display_count = 0;
            }

            /* 显示历史报警记录 */
            for (i = 0; i < display_count; i++)
            {
                /* 计算记录索引（从最新的开始） */
                if (total_records > start_index + i)
                {
                    record_index = total_records - 1 - (start_index + i);
                }
                else
                {
                    break;
                }

                /* 读取历史报警记录 */
                if (history.read_history(record_index, &history_record))
                {
                    u8 com_time_out_flag = 0;
                    if (history_record.alarm_type == APP_LEAKAGE_SUB_DEVICE_STATE_TIME_OUT)
                    {
                        com_time_out_flag = 1;
                    }
                    /* 区域名: t(i+1)_1 */
                    len += gui_tjc_hmi_tx_text_display(GUI_HISTORY_ALARM, i + 1, 1,
                                                       (char *)&hmi_tx_buffer[len],
                                                       "%s",
                                                       history_record.region_name);

                    /* 设备ID: t(i+1)_2 */
                    len += gui_tjc_hmi_tx_text_display(GUI_HISTORY_ALARM, i + 1, 2,
                                                       (char *)&hmi_tx_buffer[len],
                                                       "%d",
                                                       history_record.device_id);

                    if (com_time_out_flag)
                    {
                        /*通道信息：t(i+1)_3*/
                        len += gui_tjc_hmi_tx_text_display(GUI_HISTORY_ALARM, i + 1, 3,
                                                           (char *)&hmi_tx_buffer[len],
                                                           "-");
                    }
                    else
                    {
                        /*通道信息：t(i+1)_3*/
                        len += gui_tjc_hmi_tx_text_display(GUI_HISTORY_ALARM, i + 1, 3,
                                                           (char *)&hmi_tx_buffer[len],
                                                           "%d",
                                                           history_record.channel + 1);
                    }

                    /* 报警类型: t(i+1)_4 */
                    alarm_type_str[0] = '\0';
                    if (history_record.alarm_type == APP_LEAKAGE_SUB_DEVICE_STATE_LEAKAGE)
                        strcat(alarm_type_str, "漏液");
                    else if (history_record.alarm_type == APP_LEAKAGE_SUB_DEVICE_STATE_OPEN)
                        strcat(alarm_type_str, "断带");
                    else if (history_record.alarm_type == APP_LEAKAGE_SUB_DEVICE_STATE_TIME_OUT)
                    {
                        strcat(alarm_type_str, "通讯异常");
                    }

                    len += gui_tjc_hmi_tx_text_display(GUI_HISTORY_ALARM, i + 1, 4,
                                                       (char *)&hmi_tx_buffer[len],
                                                       "%s",
                                                       alarm_type_str);

                    /* 设备名称: t(i+1)_5 */
                    len += gui_tjc_hmi_tx_text_display(GUI_HISTORY_ALARM, i + 1, 5,
                                                       (char *)&hmi_tx_buffer[len],
                                                       "%s",
                                                       history_record.device_name);

                    /* 漏液距离: t(i+1)_6 (如果是漏液报警才显示) */
                    if (history_record.alarm_type == APP_LEAKAGE_SUB_DEVICE_STATE_LEAKAGE)
                    {
                        len += gui_tjc_hmi_tx_text_display(GUI_HISTORY_ALARM, i + 1, 6,
                                                           (char *)&hmi_tx_buffer[len],
                                                           "%.2f",
                                                           history_record.leak_distance / LEAKAGE_MULTIPLE);
                    }
                    else
                    {
                        len += gui_tjc_hmi_tx_text_display(GUI_HISTORY_ALARM, i + 1, 6,
                                                           (char *)&hmi_tx_buffer[len],
                                                           "-");
                    }

                    /* 开始时间: t(i+1)_7 */
                    uint16_t year = (history_record.start_time[0] << 8) | history_record.start_time[1];
                    sprintf(time_str, "%04d-%02d-%02d %02d:%02d:%02d",
                            year,
                            history_record.start_time[2],
                            history_record.start_time[3],
                            history_record.start_time[4],
                            history_record.start_time[5],
                            history_record.start_time[6]);
                    len += gui_tjc_hmi_tx_text_display(GUI_HISTORY_ALARM, i + 1, 7,
                                                       (char *)&hmi_tx_buffer[len],
                                                       "%s",
                                                       time_str);
                }
                else
                {
                    /* 读取失败，显示空 */
                    len += gui_tjc_hmi_tx_text_display(GUI_HISTORY_ALARM, i + 1, 1, (char *)&hmi_tx_buffer[len], "");
                    len += gui_tjc_hmi_tx_text_display(GUI_HISTORY_ALARM, i + 1, 2, (char *)&hmi_tx_buffer[len], "");
                    len += gui_tjc_hmi_tx_text_display(GUI_HISTORY_ALARM, i + 1, 3, (char *)&hmi_tx_buffer[len], "");
                    len += gui_tjc_hmi_tx_text_display(GUI_HISTORY_ALARM, i + 1, 4, (char *)&hmi_tx_buffer[len], "");
                    len += gui_tjc_hmi_tx_text_display(GUI_HISTORY_ALARM, i + 1, 5, (char *)&hmi_tx_buffer[len], "");
                    len += gui_tjc_hmi_tx_text_display(GUI_HISTORY_ALARM, i + 1, 6, (char *)&hmi_tx_buffer[len], "");
                    len += gui_tjc_hmi_tx_text_display(GUI_HISTORY_ALARM, i + 1, 7, (char *)&hmi_tx_buffer[len], "");
                }
            }

            /* 如果本页不足15条记录，清空剩余行 */
            for (; i < HISTORY_ALARM_PER_PAGE; i++)
            {
                len += gui_tjc_hmi_tx_text_display(GUI_HISTORY_ALARM, i + 1, 1, (char *)&hmi_tx_buffer[len], "");
                len += gui_tjc_hmi_tx_text_display(GUI_HISTORY_ALARM, i + 1, 2, (char *)&hmi_tx_buffer[len], "");
                len += gui_tjc_hmi_tx_text_display(GUI_HISTORY_ALARM, i + 1, 3, (char *)&hmi_tx_buffer[len], "");
                len += gui_tjc_hmi_tx_text_display(GUI_HISTORY_ALARM, i + 1, 4, (char *)&hmi_tx_buffer[len], "");
                len += gui_tjc_hmi_tx_text_display(GUI_HISTORY_ALARM, i + 1, 5, (char *)&hmi_tx_buffer[len], "");
                len += gui_tjc_hmi_tx_text_display(GUI_HISTORY_ALARM, i + 1, 6, (char *)&hmi_tx_buffer[len], "");
                len += gui_tjc_hmi_tx_text_display(GUI_HISTORY_ALARM, i + 1, 7, (char *)&hmi_tx_buffer[len], "");
            }

            len = strlen((char *)hmi_tx_buffer);
            gui_tjc_hmi_data_send(hmi_tx_buffer, len);
        }
        break;

        case 0x03: /* 翻页 */
        {
            if (0x01 == p_data[0]) /* 下一页 */
            {
                if (p_tjc_hmi->page.history_alarm_index >= page_num - 1)
                {
                    p_tjc_hmi->page.history_alarm_index = 0;
                }
                else
                {
                    p_tjc_hmi->page.history_alarm_index++;
                }
            }
            else /* 上一页 */
            {
                if (p_tjc_hmi->page.history_alarm_index == 0)
                {
                    p_tjc_hmi->page.history_alarm_index = page_num - 1;
                }
                else
                {
                    p_tjc_hmi->page.history_alarm_index--;
                }
            }
        }
        break;
        default:
            return;
        }
        len = strlen((char *)hmi_tx_buffer);
        gui_tjc_hmi_data_send(hmi_tx_buffer, len);
    }
    else if (HMI_PROTO_CMD_SET == cmd) /*设置*/
    {
        switch (opa)
        {
        case 0x01: /*清空*/
        {
            history.clean_history();
            p_tjc_hmi->page.history_alarm_index = 0; // 重置页码

            memset(hmi_tx_buffer, 0, sizeof(hmi_tx_buffer));
            len = 0;

            //                // 清空所有15行的7列数据
            //                for(i = 0; i < HISTORY_ALARM_PER_PAGE; i++)
            //                {
            //                    len += gui_tjc_hmi_tx_text_display(i+1, 1, (char *)&hmi_tx_buffer[len], ""); // 区域名
            //                    len += gui_tjc_hmi_tx_text_display(i+1, 2, (char *)&hmi_tx_buffer[len], ""); // 设备ID
            //                    len += gui_tjc_hmi_tx_text_display(i+1, 3, (char *)&hmi_tx_buffer[len], ""); // 通道
            //                    len += gui_tjc_hmi_tx_text_display(i+1, 4, (char *)&hmi_tx_buffer[len], ""); // 报警类型
            //                    len += gui_tjc_hmi_tx_text_display(i+1, 5, (char *)&hmi_tx_buffer[len], ""); // 设备名称
            //                    len += gui_tjc_hmi_tx_text_display(i+1, 6, (char *)&hmi_tx_buffer[len], ""); // 漏液距离
            //                    len += gui_tjc_hmi_tx_text_display(i+1, 7, (char *)&hmi_tx_buffer[len], ""); // 时间
            //                }

            gui_tjc_hmi_data_send(hmi_tx_buffer, len);
        }
        break;
        case 0x02: /*无*/
        {
        }
        break;
        default:
            return;
        }
        len = strlen((char *)hmi_tx_buffer);
        gui_tjc_hmi_data_send(hmi_tx_buffer, len);
    }
}

/*网络配置界面*/
static void gui_tjc_hmi_tcp_config_send(u8 cmd, u8 opa, u8 *p_data)
{
    u16 len = 0, i, j;
    u16 port_temp;
    u8 ip_str[16], mask_str[16], gw_str[16], port_str[BSP_W5500_PORT_NUM][16];
    u8 field_count = 0;
    u8 *current_pos = p_data;
    u8 ip_len, mask_len, gw_len, port_len;
    u16 port_val;

    memset(hmi_tx_buffer, 0, sizeof(hmi_tx_buffer));

    if (HMI_PROTO_CMD_GET == cmd) /*获取数据*/
    {
        switch (opa)
        {
        case 0x01: /*读取网络配置信息，p_data[0]=0x01为读取设置的网络配置，00为读取默认的,网络IP,子网掩码,网关,DNS服务器*/
        {
            if (p_data[0] == 0x01)
            {
                len += gui_tjc_hmi_tx_text_display(GUI_TCP_CONFIG, 1, 1, (char *)&hmi_tx_buffer[len],
                                                   "%d.%d.%d.%d",
                                                   W5500.IP_Addr[0],
                                                   W5500.IP_Addr[1],
                                                   W5500.IP_Addr[2],
                                                   W5500.IP_Addr[3]);

                len += gui_tjc_hmi_tx_text_display(GUI_TCP_CONFIG, 1, 2, (char *)&hmi_tx_buffer[len],
                                                   "%d.%d.%d.%d",
                                                   W5500.Sub_Mask[0],
                                                   W5500.Sub_Mask[1],
                                                   W5500.Sub_Mask[2],
                                                   W5500.Sub_Mask[3]);

                len += gui_tjc_hmi_tx_text_display(GUI_TCP_CONFIG, 1, 3, (char *)&hmi_tx_buffer[len],
                                                   "%d.%d.%d.%d",
                                                   W5500.Gateway_IP[0],
                                                   W5500.Gateway_IP[1],
                                                   W5500.Gateway_IP[2],
                                                   W5500.Gateway_IP[3]);
                /*port端口*/
                for (i = 0; i < BSP_W5500_PORT_NUM; i++)
                {
                    len += gui_tjc_hmi_tx_text_display(GUI_TCP_CONFIG, 1, 4 + i, (char *)&hmi_tx_buffer[len], "%d", (W5500.W5500_Class[i].ConfigData.Port[0] << 8) | W5500.W5500_Class[i].ConfigData.Port[1]);
                }
            }
            else if (p_data[0] == 0x00)
            {
                len += gui_tjc_hmi_tx_text_display(GUI_TCP_CONFIG, 1, 1, (char *)&hmi_tx_buffer[len], "%s", "192.168.100.100");
                len += gui_tjc_hmi_tx_text_display(GUI_TCP_CONFIG, 1, 2, (char *)&hmi_tx_buffer[len], "%s", "255.255.255.0");
                len += gui_tjc_hmi_tx_text_display(GUI_TCP_CONFIG, 1, 3, (char *)&hmi_tx_buffer[len], "%s", "192.168.50.1");
                len += gui_tjc_hmi_tx_text_display(GUI_TCP_CONFIG, 1, 4, (char *)&hmi_tx_buffer[len], "%s", "502");
                len += gui_tjc_hmi_tx_text_display(GUI_TCP_CONFIG, 1, 5, (char *)&hmi_tx_buffer[len], "%s", "503");
                len += gui_tjc_hmi_tx_text_display(GUI_TCP_CONFIG, 1, 6, (char *)&hmi_tx_buffer[len], "%s", "504");
                len += gui_tjc_hmi_tx_text_display(GUI_TCP_CONFIG, 1, 7, (char *)&hmi_tx_buffer[len], "%s", "505");

                sscanf("192.168.100.100", "%hhu.%hhu.%hhu.%hhu", &W5500.IP_Addr[0], &W5500.IP_Addr[1], &W5500.IP_Addr[2], &W5500.IP_Addr[3]);
                sscanf("255.255.255.0", "%hhu.%hhu.%hhu.%hhu", &W5500.Sub_Mask[0], &W5500.Sub_Mask[1], &W5500.Sub_Mask[2], &W5500.Sub_Mask[3]);
                sscanf("192.168.50.1", "%hhu.%hhu.%hhu.%hhu", &W5500.Gateway_IP[0], &W5500.Gateway_IP[1], &W5500.Gateway_IP[2], &W5500.Gateway_IP[3]);

                port_temp = 502;
                for (i = 0; i < BSP_W5500_PORT_NUM; i++)
                {
                    W5500.W5500_Class[i].ConfigData.Port[0] = (port_temp >> 8) & 0xFF;
                    W5500.W5500_Class[i].ConfigData.Port[1] = port_temp & 0xFF;
                    port_temp++;
                }
                W5500.Init();
            }
        }
        break;
        case 0x02: /*无*/
        {
        }
        break;
        default:
            return;
        }
        len = strlen((char *)hmi_tx_buffer);
        gui_tjc_hmi_data_send(hmi_tx_buffer, len);
    }
    else if (HMI_PROTO_CMD_SET == cmd) /*设置*/
    {
        switch (opa)
        {
        case 0x01: /*添加网络配置，并将网络配置信息存入flash*/
        {

            /* 解析IP地址 */
            for (i = 0; i < 16; i++)
            {
                if (current_pos[i] == HMI_PROTO_ASCII_RX_DELINITER)
                {
                    ip_len = i;
                    memcpy(ip_str, current_pos, ip_len);
                    ip_str[ip_len] = '\0';
                    current_pos += (i + 1);
                    field_count++;
                    break;
                }
            }

            /* 解析子网掩码 */
            for (i = 0; i < 16; i++)
            {
                if (current_pos[i] == HMI_PROTO_ASCII_RX_DELINITER)
                {
                    mask_len = i;
                    memcpy(mask_str, current_pos, mask_len);
                    mask_str[mask_len] = '\0';
                    current_pos += (i + 1);
                    field_count++;
                    break;
                }
            }

            /* 解析网关 */
            for (i = 0; i < 16; i++)
            {
                if (current_pos[i] == HMI_PROTO_ASCII_RX_DELINITER)
                {
                    gw_len = i;
                    memcpy(gw_str, current_pos, gw_len);
                    gw_str[gw_len] = '\0';
                    current_pos += (i + 1);
                    field_count++;
                    break;
                }
            }

            /* 解析端口号 */
            for (j = 0; j < BSP_W5500_PORT_NUM; j++)
            {
                for (i = 0; i < 16; i++)
                {
                    if (current_pos[i] == HMI_PROTO_ASCII_RX_DELINITER)
                    {
                        port_len = i;
                        memcpy(port_str[j], current_pos, port_len);
                        port_str[j][port_len] = '\0';
                        current_pos += (i + 1);
                        field_count++;
                        break;
                    }
                }
            }

            if (field_count == 7)
            {
                parse_ip_string(ip_str, ip_len, W5500.IP_Addr);
                parse_ip_string(mask_str, mask_len, W5500.Sub_Mask);
                parse_ip_string(gw_str, gw_len, W5500.Gateway_IP);
                /* 端口号转换为整数 */
                for (i = 0; i < BSP_W5500_PORT_NUM; i++)
                {
                    port_val = atoi((char *)(port_str[i]));
                    W5500.W5500_Class[i].ConfigData.Port[0] = (port_val >> 8) & 0xFF;
                    W5500.W5500_Class[i].ConfigData.Port[1] = port_val & 0xFF;
                }
                /* 保存到Flash */
                gui_tjc_hmi_save_network_config_to_w25q();
                /* 重启W5500使新配置生效 */
                W5500.Init();
            }
        }
        break;
        case 0x02: /*无*/
        {
        }
        break;
        default:
            return;
        }
        len = strlen((char *)hmi_tx_buffer);
        gui_tjc_hmi_data_send(hmi_tx_buffer, len);
    }
}

/*设备配置界面    */
static void gui_tjc_hmi_device_config_send(u8 cmd, u8 opa, u8 *p_data)
{
#define DEVICES_PER_PAGE (8)

    u16 len = 0, i, j;
    u8 found_empty_slot = 0, enabled_device_count, field_count, page_num, remain_region_num;
    u8 empty_slot_index = 0;
    u8 *current_pos = NULL;
    app_leakage_sub_device_flash_data_t new_device;

    memset(hmi_tx_buffer, 0, sizeof(hmi_tx_buffer));

    //        enabled_device_count = 0;
    //    for (i = 0; i < APP_LEAKAGE_SUB_DEVICE_NUM; i++)
    //    {
    //        if (leakage.sub_device_data[i].flash_data.state == ENABLE)
    //        {
    //            enabled_device_count++;
    //        }
    //    }

    enabled_device_count = leakage.sub_device_num;
    page_num = enabled_device_count / DEVICES_PER_PAGE;
    remain_region_num = enabled_device_count % DEVICES_PER_PAGE;
    if (remain_region_num > 0)
    {
        page_num++;
    }
    if (page_num == 0)
        page_num = 1;

    /*页数*/
    len += gui_tjc_hmi_tx_text_display(GUI_DEVICE_CONFIG, 0, 0,
                                       (char *)&hmi_tx_buffer[len],
                                       "%d/%d",
                                       p_tjc_hmi->page.device_config_index + 1, page_num);

    if (HMI_PROTO_CMD_GET == cmd) /*获取数据*/
    {
        switch (opa)
        {
        case 0x01: /*读取已存在的设备，显示区域，端口，设备ID,设备名,*/
        {
            u8 page_device_indices[DEVICES_PER_PAGE] = {0}; /*存储当前页8个设备在app_leakage中的索引*/
            u8 page_device_count = 0;                       /*当前页实际启用的设备数量*/
            u8 current_enabled_index = 0;                   /*当前是第几个启用的设备*/
            u8 device_index;

            /*计算启用的设备数量*/
            //                enabled_device_count = 0;
            //                for(i = 0; i < APP_LEAKAGE_SUB_DEVICE_NUM; i++)
            //                {
            //                    if(leakage.sub_device_data[i].flash_data.state == ENABLE)
            //                    {
            //                        enabled_device_count++;
            //                    }
            //                }
            //
            //                 /*计算总页数*/
            //                page_num = enabled_device_count / DEVICES_PER_PAGE;
            //                remain_region_num = enabled_device_count % DEVICES_PER_PAGE;
            //                if(remain_region_num > 0)
            //                {
            //                    page_num++;
            //                }
            //
            /*确保页码在有效范围内*/
            if (p_tjc_hmi->page.device_config_index >= page_num)
            {
                p_tjc_hmi->page.device_config_index = 0;
            }

            if (enabled_device_count == 0)
            {
                for (i = 0; i < DEVICES_PER_PAGE; i++)
                {
                    len += gui_tjc_hmi_tx_text_display(GUI_DEVICE_CONFIG, i + 1, 1, (char *)&hmi_tx_buffer[len], "");
                    len += gui_tjc_hmi_tx_text_display(GUI_DEVICE_CONFIG, i + 1, 2, (char *)&hmi_tx_buffer[len], "");
                    len += gui_tjc_hmi_tx_text_display(GUI_DEVICE_CONFIG, i + 1, 3, (char *)&hmi_tx_buffer[len], "");
                    len += gui_tjc_hmi_tx_text_display(GUI_DEVICE_CONFIG, i + 1, 4, (char *)&hmi_tx_buffer[len], "");
                }
                len = strlen((char *)hmi_tx_buffer);
                gui_tjc_hmi_data_send(hmi_tx_buffer, len);
                return;
            }

            /*获取当前页的设备索引*/
            for (i = 0; i < APP_LEAKAGE_SUB_DEVICE_NUM && page_device_count < DEVICES_PER_PAGE; i++)
            {
                if (leakage.sub_device_data[i].flash_data.state == ENABLE)
                {
                    current_enabled_index++;

                    /*判断这个设备是否在当前页*/
                    u8 device_page = (current_enabled_index - 1) / DEVICES_PER_PAGE;
                    if (device_page == p_tjc_hmi->page.device_config_index)
                    {
                        page_device_indices[page_device_count] = i;
                        page_device_count++;
                    }
                }
            }

            if (page_device_count == 0)
            {
                /*当前页没有设备，发送空数据*/
                len = strlen((char *)hmi_tx_buffer);
                gui_tjc_hmi_data_send(hmi_tx_buffer, len);
                return;
            }

            /*显示当前页的设备信息*/
            for (i = 0; i < page_device_count; i++)
            {
                device_index = page_device_indices[i];

                /*区域名: t(i+1)_1 */
                len += gui_tjc_hmi_tx_text_display(GUI_DEVICE_CONFIG, i + 1, 1,
                                                   (char *)&hmi_tx_buffer[len],
                                                   "%s",
                                                   leakage.sub_device_data[device_index].flash_data.region_name);

                /*端口号: t(i+1)_2 */
                u8 com_port = leakage.sub_device_data[device_index].flash_data.com;
                if (com_port < 4) /*确保端口号在有效范围内*/
                {
                    len += gui_tjc_hmi_tx_text_display(GUI_DEVICE_CONFIG, i + 1, 2,
                                                       (char *)&hmi_tx_buffer[len],
                                                       "%s",
                                                       hmi_proto_string_com[com_port]);
                }
                else
                {
                    len += gui_tjc_hmi_tx_text_display(GUI_DEVICE_CONFIG, i + 1, 2,
                                                       (char *)&hmi_tx_buffer[len],
                                                       "未知");
                }

                /*设备ID: t(i+1)_3 */
                len += gui_tjc_hmi_tx_text_display(GUI_DEVICE_CONFIG, i + 1, 3,
                                                   (char *)&hmi_tx_buffer[len],
                                                   "%d",
                                                   leakage.sub_device_data[device_index].flash_data.modbus_id);

                /*设备名称: t(i+1)_4 */
                len += gui_tjc_hmi_tx_text_display(GUI_DEVICE_CONFIG, i + 1, 4,
                                                   (char *)&hmi_tx_buffer[len],
                                                   "%s",
                                                   leakage.sub_device_data[device_index].flash_data.device_name);
            }

            /*如果当前页不足8个设备，清空剩余的设备显示位置*/
            if (page_device_count < DEVICES_PER_PAGE)
            {
                for (i = page_device_count; i < DEVICES_PER_PAGE; i++)
                {
                    /*清空区域名*/
                    len += gui_tjc_hmi_tx_text_display(GUI_DEVICE_CONFIG, i + 1, 1,
                                                       (char *)&hmi_tx_buffer[len],
                                                       "");

                    /*清空端口号*/
                    len += gui_tjc_hmi_tx_text_display(GUI_DEVICE_CONFIG, i + 1, 2,
                                                       (char *)&hmi_tx_buffer[len],
                                                       "");

                    /*清空设备ID*/
                    len += gui_tjc_hmi_tx_text_display(GUI_DEVICE_CONFIG, i + 1, 3,
                                                       (char *)&hmi_tx_buffer[len],
                                                       "");

                    /*清空设备名称*/
                    len += gui_tjc_hmi_tx_text_display(GUI_DEVICE_CONFIG, i + 1, 4,
                                                       (char *)&hmi_tx_buffer[len],
                                                       "");
                }
            }
        }
        break;

        case 0x02: /*读取四个COM口的波特率*/
        {
            u8 baud_vals[4];
            for (i = 0; i < 4; i++)
            {
                baud_vals[i] = app_com.com[i].flash_data.baudrate;
            }

            len = 0;
            len += sprintf((char *)&hmi_tx_buffer[len], "cb0.val=%d", baud_vals[0]);
            for (i = 0; i < 3; i++)
                hmi_tx_buffer[len + i] = 0xFF;
            len += 3;

            len += sprintf((char *)&hmi_tx_buffer[len], "cb1.val=%d", baud_vals[1]);
            for (i = 0; i < 3; i++)
                hmi_tx_buffer[len + i] = 0xFF;
            len += 3;

            len += sprintf((char *)&hmi_tx_buffer[len], "cb2.val=%d", baud_vals[2]);
            for (i = 0; i < 3; i++)
                hmi_tx_buffer[len + i] = 0xFF;
            len += 3;

            len += sprintf((char *)&hmi_tx_buffer[len], "cb3.val=%d", baud_vals[3]);
            for (i = 0; i < 3; i++)
                hmi_tx_buffer[len + i] = 0xFF;
            len += 3;

            gui_tjc_hmi_data_send(hmi_tx_buffer, len);
            return;
        }
        break;

        case 0x03: /*翻页功能，每页显示8个设备*/
        {

            if (0x01 == p_data[0]) /*下一页*/
            {
                if (page_num - 1 <= p_tjc_hmi->page.device_config_index)
                {
                    p_tjc_hmi->page.device_config_index = 0;
                }
                else
                {
                    p_tjc_hmi->page.device_config_index++;
                }
            }
            else /*上一页*/
            {
                if (0 == p_tjc_hmi->page.device_config_index)
                {
                    p_tjc_hmi->page.device_config_index = page_num - 1;
                }
                else
                {
                    p_tjc_hmi->page.device_config_index--;
                }
            }
            /*翻页后需要重新获取数据并显示，这里不直接发送数据*/
            return;
        }
        break;
        default:
            return;
        }
        len = strlen((char *)hmi_tx_buffer);
        gui_tjc_hmi_data_send(hmi_tx_buffer, len);
    }
    else if (HMI_PROTO_CMD_SET == cmd) /*设置*/
    {
        switch (opa)
        {
        case 0x01:
        {
            found_empty_slot = 0;
            for (i = 0; i < APP_LEAKAGE_SUB_DEVICE_NUM; i++)
            {
                if (leakage.sub_device_data[i].flash_data.state == DISABLE)
                {
                    found_empty_slot = 1;
                    empty_slot_index = i;
                    break;
                }
            }

            if (!found_empty_slot)
            {
                /*设备数量已满*/
                return;
            }

            field_count = 0;
            current_pos = p_data;
            memset(&new_device, 0, sizeof(new_device));

            /*解析端口号*/
            for (i = 0; i < 10; i++)
            {
                if (current_pos[i] == HMI_PROTO_ASCII_RX_DELINITER)
                {
                    if (i == 0)
                    {
                        /*端口号不能为空*/
                        return;
                    }

                    char port_str[10] = {0};
                    memcpy(port_str, current_pos, i);
                    port_str[i] = '\0';

                    /*将字符串端口号转换为数值*/
                    if (strcmp(port_str, "COM1") == 0)
                    {
                        new_device.com = 0;
                    }
                    else if (strcmp(port_str, "COM2") == 0)
                    {
                        new_device.com = 1;
                    }
                    else if (strcmp(port_str, "COM3") == 0)
                    {
                        new_device.com = 2;
                    }
                    else if (strcmp(port_str, "COM4") == 0)
                    {
                        new_device.com = 3;
                    }

                    current_pos += (i + 1);
                    field_count++;
                    break;
                }
            }

            //                /*解析波特率*/
            //                for(i = 0; i < 10; i++) // 波特率最大为115200
            //                {
            //                    if(current_pos[i] == HMI_PROTO_ASCII_RX_DELINITER)
            //                    {
            //                        if(i == 0)
            //                        {
            //                            /*波特率不能为空*/
            //                            return;
            //                        }

            //                        char baud_str[10] = {0};
            //                        memcpy(baud_str, current_pos, i);
            //                        baud_str[i] = '\0';

            //                        /*将字符串波特率转换为数值*/
            //                        if(strcmp(baud_str, "2400") == 0)
            //                        {
            //                            new_device.baudrate = 0;
            //                        }
            //                        else if(strcmp(baud_str, "4800") == 0)
            //                        {
            //                            new_device.baudrate = 1;
            //                        }
            //                        else if(strcmp(baud_str, "9600") == 0)
            //                        {
            //                            new_device.baudrate = 2;
            //                        }
            //                        else if(strcmp(baud_str, "115200") == 0)
            //                        {
            //                            new_device.baudrate = 3;
            //                        }

            //                        current_pos += (i + 1);
            //                        field_count++;
            //                        break;
            //                    }
            //                }

            /*解析区域名*/
            for (i = 0; i < APP_LEAKAGE_STRING_NANE_LEN; i++)
            {
                if (current_pos[i] == HMI_PROTO_ASCII_RX_DELINITER)
                {
                    memcpy(new_device.region_name, current_pos, i);
                    new_device.region_name[i] = '\0';
                    current_pos += (i + 1);
                    field_count++;
                    break;
                }
            }

            /*解析设备ID */
            for (i = 0; i < 10; i++)
            {
                if (current_pos[i] == HMI_PROTO_ASCII_RX_DELINITER)
                {
                    if (i == 0)
                    {
                        /*设备ID不能为空*/
                        return;
                    }

                    /*设备ID是数字字符串，转换为数值*/
                    char id_str[10] = {0};
                    memcpy(id_str, current_pos, i);
                    id_str[i] = '\0';
                    new_device.modbus_id = atoi(id_str);

                    if (new_device.modbus_id < 1 || new_device.modbus_id > 255)
                    {
                        return;
                    }

                    current_pos += (i + 1);
                    field_count++;
                    break;
                }
            }

            /*解析设备名称*/
            for (i = 0; i < APP_LEAKAGE_STRING_NANE_LEN; i++)
            {
                if (current_pos[i] == HMI_PROTO_ASCII_RX_DELINITER)
                {
                    memcpy(new_device.device_name, current_pos, i);
                    new_device.device_name[i] = '\0';
                    field_count++;
                    break;
                }
            }

            /*相同id时覆盖之前的*/
            if (field_count == 4)
            {
                for (u8 x = 0; x < APP_LEAKAGE_SUB_DEVICE_NUM; x++)
                {
                    if (leakage.sub_device_data[x].flash_data.modbus_id == new_device.modbus_id)
                    {
                        new_device.state = ENABLE;
                        new_device.baudrate = app_com.com[new_device.com].flash_data.baudrate;
                        leakage.sub_device_data[x].shield = UNBLOCKED;
                        leakage.sub_device_data[x].flash_data = new_device;
                        gui_tjc_hmi_save_device_info_to_w25q();
                        gui_tjc_hmi_class_update();
                        field_count++;
                    }
                }
            }

            /*添加到设备列表*/
            if (field_count == 4)
            {
                /*设置默认状态为启用*/
                new_device.state = ENABLE;

                /*波特率设置*/
                new_device.baudrate = app_com.com[new_device.com].flash_data.baudrate;

                leakage.sub_device_data[empty_slot_index].shield = UNBLOCKED;

                /*添加到app_leakage的设备列表中*/
                leakage.sub_device_data[empty_slot_index].flash_data = new_device;

                /*清空通道数据*/
                memset(leakage.sub_device_data[empty_slot_index].ch_data, 0,
                       sizeof(leakage.sub_device_data[empty_slot_index].ch_data));

                /*保存到W25Q32*/
                gui_tjc_hmi_save_device_info_to_w25q();

                /*重新分类区域*/
                gui_tjc_hmi_class_update();

                page_num = leakage.sub_device_num / DEVICES_PER_PAGE;
                remain_region_num = leakage.sub_device_num % DEVICES_PER_PAGE;
                if (remain_region_num > 0)
                {
                    page_num++;
                }
                if (page_num == 0)
                    page_num = 1;
                p_tjc_hmi->page.device_config_index = page_num - 1; // xian

                //                    if (new_device.com < APP_COM_NUM && new_device.baudrate < 4) {
                //                        app_com.com[new_device.com].set.baud_rate(
                //                            &app_com.com[new_device.com],
                //                            new_device.baudrate
                //                        );
                //                    }
            }
            else
            {
                /*发送错误响应*/
                return;
            }
        }
        break;
        case 0x02: /*删除设备，将设备信息从w25q中删除*/
        {
            u8 page_device_indices[8] = {0}; /*存储当前页8个设备在app_leakage中的索引*/
            u8 page_device_count = 0;        /*当前页实际启用的设备数量*/
            u8 current_enabled_index = 0;    /*当前是第几个启用的设备*/

            for (i = 0; i < APP_LEAKAGE_SUB_DEVICE_NUM && page_device_count < DEVICES_PER_PAGE; i++)
            {
                if (leakage.sub_device_data[i].flash_data.state == ENABLE)
                {
                    current_enabled_index++;

                    /*判断这个设备是否在当前页*/
                    u8 device_page = (current_enabled_index - 1) / DEVICES_PER_PAGE;
                    if (device_page == p_tjc_hmi->page.device_config_index)
                    {
                        page_device_indices[page_device_count] = i;
                        page_device_count++;
                    }
                }
            }

            if (page_device_count == 0)
            {
                /*当前页没有设备*/
                return;
            }

            /*遍历8个选中框字节，删除被选中的设备（从后往前删除）*/
            u8 deleted_count = 0;
            for (i = page_device_count; i > 0; i--)
            {
                u8 idx = i - 1;
                if (p_data[idx] == 0x01)
                {
                    u8 actual_index = page_device_indices[idx]; // 直接使用原始索引
                    /*将后面的设备向前移动*/
                    for (j = actual_index; j < APP_LEAKAGE_SUB_DEVICE_NUM - 1; j++)
                    {
                        leakage.sub_device_data[j].flash_data = leakage.sub_device_data[j + 1].flash_data;
                    }
                    /*最后一个设备清空*/
                    memset(&leakage.sub_device_data[APP_LEAKAGE_SUB_DEVICE_NUM - 1].flash_data, 0,
                           sizeof(app_leakage_sub_device_flash_data_t));
                    leakage.sub_device_data[APP_LEAKAGE_SUB_DEVICE_NUM - 1].flash_data.state = DISABLE;

                    /*清空通道数据*/
                    memset(leakage.sub_device_data[APP_LEAKAGE_SUB_DEVICE_NUM - 1].ch_data, 0,
                           sizeof(leakage.sub_device_data[APP_LEAKAGE_SUB_DEVICE_NUM - 1].ch_data));

                    deleted_count++;
                }
            }

            if (deleted_count > 0)
            {
                /*保存到W25Q32*/
                gui_tjc_hmi_save_device_info_to_w25q();
                /*重新分类区域*/
                gui_tjc_hmi_class_update();
                /*可选：发送确认响应*/
            }
            else
            {
                /*没有选中任何设备*/
                return;
            }
        }
        break;

        case 0x03: /*设置波特率，波特率1对应COM1的*/
        {
            u8 *ptr = p_data;
            u8 baud_vals[APP_COM_NUM];
            char temp_buf[10]; /*临时存储ASCII字符串*/

            for (i = 0; i < APP_COM_NUM; i++)
            {
                u8 temp_len = 0;
                // 提取直到下一个0xAA分隔符
                while (*ptr != HMI_PROTO_ASCII_RX_DELINITER && temp_len < sizeof(temp_buf) - 1)
                {
                    temp_buf[temp_len++] = *ptr++;
                }
                if (*ptr != HMI_PROTO_ASCII_RX_DELINITER)
                {
                    return;
                }
                temp_buf[temp_len] = '\0';
                ptr++; // 跳过分隔符

                // 将ASCII字符串转换为整数波特率
                u32 baud_int = atoi(temp_buf);

                // 映射到枚举值
                u8 enum_val;
                if (baud_int == 4800)
                    enum_val = 0;
                else if (baud_int == 9600)
                    enum_val = 1;
                else if (baud_int == 19200)
                    enum_val = 2;
                else if (baud_int == 57600)
                    enum_val = 3;
                else if (baud_int == 115200)
                    enum_val = 4;
                else
                    enum_val = 4;

                baud_vals[i] = enum_val;
            }

            /*设置每个COM的波特率*/
            for (i = 0; i < APP_COM_NUM; i++)
            {
                if (app_com.com[i].flash_data.baudrate != baud_vals[i])
                {
                    app_com.com[i].flash_data.baudrate = baud_vals[i];
                    if (app_com.com[i].set.baud_rate)
                    {
                        app_com.com[i].set.baud_rate(&app_com.com[i], baud_vals[i]);
                    }
                }
            }
            app_com.save_flah();
            return;
        }
        break;

        default:
            return;
        }
        len = strlen((char *)hmi_tx_buffer);
        gui_tjc_hmi_data_send(hmi_tx_buffer, len);
    }
}

/*设置时间界面*/
static void gui_tjc_hmi_time_set_send(u8 cmd, u8 opa, u8 *p_data)
{
    u16 i, len = 0;
    char temp_buf[5];
    bsp_DS1302_Time_t new_time;

    if (HMI_PROTO_CMD_SET == cmd) /* 设置命令 */
    {
        switch (opa)
        {
        case 0x01: /* 设置时间 */
        {
            int idx = 0;   /*数据索引*/
            int field = 0; /*当前字段编号（0:年,1:月,2:日,3:时,4:分）*/
            char temp_buf[5];
            int value;

            while (field < 5)
            {
                int len = 0;
                /*收集当前字段的ASCII字符直到遇到分隔符0xAA*/
                while (p_data[idx] != 0xAA)
                {
                    if (len >= 4)
                    {
                        return;
                    }
                    temp_buf[len++] = p_data[idx++];
                }

                if (len == 0)
                {
                    return;
                }

                temp_buf[len] = '\0';
                value = atoi(temp_buf);

                /* 根据字段序号赋值*/
                switch (field)
                {
                case 0:
                    new_time.Year = value % 2000;
                    break; // 年份取后两位
                case 1:
                    new_time.Month = value;
                    break;
                case 2:
                    new_time.Day = value;
                    break;
                case 3:
                    new_time.Hour = value;
                    break;
                case 4:
                    new_time.Minute = value;
                    break;
                }

                /*跳过当前分隔符0xAA，准备下一个字段*/
                idx++;
                field++;
            }

            DS1302.Set(&new_time);
        }
        break;

        default:
            break;
        }
    }
}

/*屏幕指令解析*/
static void gui_tjc_hmi_communication_data_analysis(u8 *p_data, u16 len, void *rx_uart)
{
    u8 cmd, data, gui_id, opa, *p_offset_data;
    u16 i, modbus_crc16, check_crc16;
    /*长度不足*/
    if (len < 5)
    {
        return;
    }
    /*检测帧头*/
    if (p_data[0] != HMI_PROTO_FRAME_HEADER1 || p_data[1] != HMI_PROTO_FRAME_HEADER2)
    {
        return;
    }
    /*校验位*/
    check_crc16 = p_data[len - 2] << 8 | p_data[len - 1];
    modbus_crc16 = modbus_lib_crc16(p_data, len - 2);
    modbus_crc16 = (modbus_crc16 >> 8) | (modbus_crc16 << 8);
    if (modbus_crc16 != check_crc16)
    {
        return;
    }

    /*CMD*/
    cmd = p_data[2];
    if (cmd != HMI_PROTO_CMD_GET && cmd != HMI_PROTO_CMD_SET)
    {
        return;
    }
    gui_id = p_data[3];                /*gui_id*/
    opa = p_data[4];                   /*操作码*/
    p_offset_data = &p_data[5];        /*附带数据*/
    p_rx_uart = (bsp_uart_t *)rx_uart; /*串口指针*/
    switch (gui_id)
    {
    case HMI_PROTO_GUI_MAIN:
    {
        gui_tjc_hmi_main_send(cmd, opa, p_offset_data);
    }
    break;
    case HMI_PROTO_GUI_CURR_ALARM:
    {
        gui_tjc_hmi_curr_alarm_send(cmd, opa, p_offset_data);
    }
    break;
    case HMI_PROTO_GUI_DETAIL_MAIN:
    {
        gui_tjc_hmi_detail_main_send(cmd, opa, p_offset_data);
    }
    break;
    case HMI_PROTO_GUI_LOGIN:
    {
        gui_tjc_hmi_login_send(cmd, opa, p_offset_data);
    }
    break;
    case HMI_PROTO_GUI_HISTORY_ALARM:
    {
        gui_tjc_hmi_history_alarm_send(cmd, opa, p_offset_data);
    }
    break;
    case HMI_PROTO_GUI_TCP_CONFIG:
    {
        gui_tjc_hmi_tcp_config_send(cmd, opa, p_offset_data);
    }
    break;
    case HMI_PROTO_GUI_DEVICE_CONFIG:
    {
        gui_tjc_hmi_device_config_send(cmd, opa, p_offset_data);
    }
    break;
    case HMI_PROTO_GUI_HELP:
    {
        // gui_tjc_hmi_help_send(cmd,opa,p_offset_data);
    }
    break;
    case HMI_PROTO_GUI_TIME:
    {
        gui_tjc_hmi_time_set_send(cmd, opa, p_offset_data);
    }
    }
}
