物联网实战--平台篇之(八)分组后台管理

目录

一、分组数据库

二、请求分组列表

三、添加分组

四、重命名分组

五、删除分组

六、分组排序


本项目的交流QQ群:701889554

物联网实战--入门篇https://blog.csdn.net/ypp240124016/category_12609773.html

物联网实战--驱动篇https://blog.csdn.net/ypp240124016/category_12631333.html

本项目资源文件 https://download.csdn.net/download/ypp240124016/89317308

一、分组数据库

如上图所示,后台系统会为每一个应用创建一个文件夹,用于存放该应用的数据库,目前这里的appInfo.db主要是分组库表和设备列表,数据库内容如下,目前还没有设备信息。

cpp 复制代码
bool GroupSqlite::createGroupTable(void)
{
    QString str_query = QString::asprintf("CREATE TABLE If Not Exists group_tb ("
                                          "groupName varchar(1000)  NOT NULL,"
                                          "groupOrder INTEGER  DEFAULT 1000,"
                                          "devList varchar(10000) DEFAULT 0,"
                                          "createTime timestamp DEFAULT (datetime(\'now\',\'localtime\')),"
                                          "PRIMARY KEY (groupName)"
                                          ")"
                                          );
//    qDebug()<<"str_query= "<<str_query;
    if(runSqlQuery(str_query)==false)
    {
        qDebug()<<"createGroupTable error";
        return false;
    }
    else
    {
        qDebug()<<"createGroupTable ok:  ";

    }
    return true;
}

以上是分组数据库创建库表的代码,里面有一个groupOrder字段,默认值是1000,在分组排序的时候会用到,当有排序指令时,后台会按照上传的分组列表从0开始,按顺序更新这个groupOrder值,读取的时候按groupOrder的升序读取就可以达到排序的目的了。以下是读取分组列表的代码,SQL语句中的ASC就是升序读取的意思。

cpp 复制代码
bool GroupSqlite::selectGroupList(QList<GroupNodeStruct> &groupList)
{
    QString str_query = QString::asprintf("SELECT groupName, groupOrder, devList, createTime  FROM  group_tb  ORDER BY groupOrder ASC");                                            
    //    qDebug()<<str_query;
        if(runSqlQuery(str_query)==false)
        {
            qDebug("selectGroupList error_01!");
             return false;
        }
        while(m_sqlQuery.next())
        {
            int ptr=0;
            GroupNodeStruct tag_group_node;
            tag_group_node.groupName=m_sqlQuery.value(ptr++).toString();
            tag_group_node.groupOrder=m_sqlQuery.value(ptr++).toUInt();
            tag_group_node.devList.clear();
            QString json_str=m_sqlQuery.value(ptr++).toString();
            QByteArray json_ba=QByteArray::fromBase64(json_str.toUtf8());
            QJsonParseError json_error;
            QJsonDocument json_doc;
            json_doc = QJsonDocument(QJsonDocument::fromJson(json_ba, &json_error));//转为JSON格式
            if(json_error.error != QJsonParseError::NoError)
            {
                qDebug()<<"json error= "<<json_error.error;
            }
            else
            {
                QJsonObject root_obj = json_doc.object();
                if(root_obj.contains("dev_list"))//设备列表
                {
                    QJsonValue value=root_obj.value("dev_list");
                    if(value.isArray())
                    {
                        QJsonArray dev_array=value.toArray();
                        int nSize=dev_array.size();
                        for(int i=0; i<nSize; i++)
                        {
                            QJsonValue value=dev_array.at(i);
                            if(value.isDouble())
                            {
                                u32 dev_sn=value.toDouble();
                                if(dev_sn>0)
                                {
                                    tag_group_node.devList.append(dev_sn);//添加dev_sn
                                }
                            }
                        }
                    }
                }
            }
            tag_group_node.createTime=m_sqlQuery.value(ptr++).toString();
            groupList.append(tag_group_node);
        }
        m_sqlQuery.finish();    
        return true;
}

数据库的其它操作都算比较常规的,自行阅读代码。

二、请求分组列表

用户后端请求代码如下:

cpp 复制代码
void CenterMan::requestGroupList(void)
{
    QJsonObject root_obj;
    QJsonDocument json_doc;

    root_obj.insert("account", m_loginAccount);
    root_obj.insert("rand_num", m_randNum);
    root_obj.insert("mac", m_macStr); 
    root_obj.insert("app_id", (qint64)m_currAppWork.appID); 
    root_obj.insert("cmd_type", "group_list");
    json_doc.setObject(root_obj);
    QByteArray msg_ba = json_doc.toJson(QJsonDocument::Indented);
    QString topic=makePubTopic("group");
    emit sigMqttPushMessage(topic, msg_ba);
}

服务器收到请求指令后读取数据并返回:

cpp 复制代码
    if(cmd_type=="group_list")
    {
        QList<GroupSqlite::GroupNodeStruct>group_list;
        tag_groupSqlite.selectGroupList(group_list);
        for(auto iter : group_list)
        {
            QJsonObject group_obj;
            QJsonArray dev_list;
            for(auto iter2 : iter.devList)
            {
                u32 dev_sn=iter2;
                dev_list.append((qint64)dev_sn);
            }
            group_obj.insert("group_name", iter.groupName);
            group_obj.insert("dev_list", dev_list);
            group_array.append(group_obj);
        }
        ackTakeGroupList(account, mac_str, rand_num, app_id, group_array, result, ack_str);
    }



void CenterThread::ackTakeGroupList(QString account, QString mac_str, int rand_num, u32 app_id, QJsonArray group_array, int result, QString ack_str)
{
    QJsonObject root_obj;
    QJsonDocument json_doc;

    root_obj.insert("cmd_type", "group_list");
    root_obj.insert("account", account);
    root_obj.insert("app_id", (qint64)app_id);
    root_obj.insert("group_list", group_array);
    root_obj.insert("result", result);
    root_obj.insert("ack_str", ack_str);
    json_doc.setObject(root_obj);
    QByteArray msg_ba = json_doc.toJson(QJsonDocument::Indented);
    QString topic=makePubTopic(account, mac_str, rand_num, "group");
    emit sigMqttPushMessage(topic, msg_ba);
}

最后,用户端收到解析并发送到前端显示分组名称:

cpp 复制代码
       if(cmd_type=="group_list")
        {
            QJsonArray group_array;
            QJsonValue value=root_obj.value("group_list");
            m_groupList.clear();
            if(value.isArray())
            {
                group_array=value.toArray();
                int nSize=group_array.size();
                for(int i=0; i<nSize; i++)
                {
                    QJsonValue value=group_array.at(i);
                    if(value.isObject())
                    {
                        GroupNodeStruct group_node;
                        QJsonObject group_obj=value.toObject();
                        if(group_obj.contains("group_name"))
                        {
                            QJsonValue value=group_obj.value("group_name");
                            if(value.isString())
                            {
                                group_node.groupName=value.toString();
                            }
                        }
                        if(group_obj.contains("dev_list"))//分组内的设备
                        {
                            QJsonValue value=group_obj.value("dev_list");
                            if(value.isArray())
                            {
                                QJsonArray dev_array=value.toArray();
                                int nSize=dev_array.size();
                                for(int i=0; i<nSize; i++)
                                {
                                    QJsonValue value=dev_array.at(i);
                                    if(value.isDouble())
                                    {
                                        u32 dev_sn=value.toDouble();
                                        if(dev_sn>0)
                                        {
                                            group_node.devList.append(dev_sn);
                                        }
                                    }
                                }
                            }
                        }
                        if(!group_node.groupName.isEmpty())
                        {
                            int total_num=group_node.devList.size();
                            emit siqAddGroup(i, group_node.groupName, total_num);
                            m_groupList.append(group_node);
                        }
                    }
                }
            }
        }
三、添加分组

用户后端请求添加分组代码:

cpp 复制代码
void CenterMan::requestAddGroup(QString group_name)
{
    QJsonObject root_obj;
    QJsonDocument json_doc;

    root_obj.insert("account", m_loginAccount);
    root_obj.insert("rand_num", m_randNum);
    root_obj.insert("mac", m_macStr); 
    root_obj.insert("app_id", (qint64)m_currAppWork.appID); 
    root_obj.insert("cmd_type", "add_group");
    root_obj.insert("group_name", group_name); 
    json_doc.setObject(root_obj);
    QByteArray msg_ba = json_doc.toJson(QJsonDocument::Indented);
    QString topic=makePubTopic("group");
    emit sigMqttPushMessage(topic, msg_ba);
}

服务器后台检查名称的合法性,如果重复了或者为空的都无法正常写入。

cpp 复制代码
    else if(cmd_type=="add_group")
    {
        QString group_name;
        if(root_obj.contains("group_name"))
        {
            group_name=root_obj.value("group_name").toString();
        }
        if(group_name.isEmpty())
            return;
        GroupSqlite::GroupNodeStruct tag_group;
        tag_groupSqlite.selectGroupNode(group_name, tag_group);
        if(group_name==tag_group.groupName)
        {
            result=3;//已存在相同名称
            ack_str="名称重复!";
        }
        else  
        {
            ok=tag_groupSqlite.insertGroup(group_name);
            if(ok)
            {
                result=0;//成功
                ack_str="添加成功!";
            }
            else   
            {
                result=4;//写入失败
                ack_str="写入失败!";
            }
        }
        ackAddGroup(account, mac_str, rand_num, app_id, group_name, result, ack_str);
    }



void CenterThread::ackAddGroup(QString account, QString mac_str, int rand_num, u32 app_id, QString group_name, int result, QString ack_str)
{
    QJsonObject root_obj;
    QJsonDocument json_doc;

    root_obj.insert("cmd_type", "add_group");
    root_obj.insert("account", account);
    root_obj.insert("app_id", (qint64)app_id);
    root_obj.insert("group_name", group_name);
    root_obj.insert("result", result);
    root_obj.insert("ack_str", ack_str);
    json_doc.setObject(root_obj);
    QByteArray msg_ba = json_doc.toJson(QJsonDocument::Indented);
    QString topic=makePubTopic(account, mac_str, rand_num, "group");
    emit sigMqttPushMessage(topic, msg_ba);
}

用户端将新添加的分组发送到前端显示:

cpp 复制代码
        else if(cmd_type=="add_group")
        {
            QString group_name="";
            if(root_obj.contains("group_name"))
            {
                QJsonValue value = root_obj.value("group_name");
                group_name=value.toString();
            }
            if(group_name.isEmpty())
                return;
            if(result==0)
            {
                emit siqAddGroup(m_groupList.size(), group_name, 0);           
                GroupNodeStruct group_node;
                group_node.groupName=group_name;
                m_groupList.append(group_node);
            }
        }
四、重命名分组

用户后端请求重命名代码,输入参数是旧名称和新名称:

cpp 复制代码
void CenterMan::requestRenameGroup(QString old_name, QString new_name)
{
    QJsonObject root_obj;
    QJsonDocument json_doc;

    root_obj.insert("account", m_loginAccount);
    root_obj.insert("rand_num", m_randNum);
    root_obj.insert("mac", m_macStr); 
    root_obj.insert("app_id", (qint64)m_currAppWork.appID); 
    root_obj.insert("cmd_type", "rename_group");
    root_obj.insert("old_name", old_name); 
    root_obj.insert("new_name", new_name); 
    json_doc.setObject(root_obj);
    QByteArray msg_ba = json_doc.toJson(QJsonDocument::Indented);
    QString topic=makePubTopic("group");
    emit sigMqttPushMessage(topic, msg_ba);
}

服务器后台需要检查名称是否重复:

cpp 复制代码
    else if(cmd_type=="rename_group")
    {
        QString old_name;
        if(root_obj.contains("old_name"))
        {
            old_name=root_obj.value("old_name").toString();
        }
        QString new_name;
        if(root_obj.contains("new_name"))
        {
            new_name=root_obj.value("new_name").toString();
        }
        
        GroupSqlite::GroupNodeStruct tag_group;
        tag_group.groupName="";
        tag_groupSqlite.selectGroupNode(old_name, tag_group);
        if(old_name==tag_group.groupName)
        {
            tag_group.groupName="";
            tag_groupSqlite.selectGroupNode(new_name, tag_group);
            if(new_name==tag_group.groupName)
            {
                result=4;//新名称已存在
                ack_str="新名称已存在!";
            }
            else  
            {
                tag_groupSqlite.updateGroupName(old_name, new_name);
                tag_group.groupName="";
                tag_groupSqlite.selectGroupNode(new_name, tag_group);
                if(new_name==tag_group.groupName)
                {
                    result=0;
                    ack_str="更新成功!";
                }
                else  
                {
                    result=5;//写入失败
                    ack_str="写入失败!";
                }
            }
        }
        else  
        {
            result=3;//旧名称不存在
            ack_str="旧名称不存在!";
        }
         ackUpdateGroupName(account, mac_str, rand_num, app_id, old_name, new_name, result,ack_str);
    }




void CenterThread::ackUpdateGroupName(QString account, QString mac_str, int rand_num, u32 app_id, QString old_name, QString new_name, int result, QString ack_str)
{
    QJsonObject root_obj;
    QJsonDocument json_doc;

    root_obj.insert("cmd_type", "rename_group");
    root_obj.insert("account", account);
    root_obj.insert("app_id", (qint64)app_id);
    root_obj.insert("old_name", old_name);
    root_obj.insert("new_name", new_name);
    root_obj.insert("result", result);
    root_obj.insert("ack_str", ack_str);
    json_doc.setObject(root_obj);
    QByteArray msg_ba = json_doc.toJson(QJsonDocument::Indented);
    QString topic=makePubTopic(account, mac_str, rand_num, "group");
    emit sigMqttPushMessage(topic, msg_ba);
}

用户后端收到返回后更新前端显示:

cpp 复制代码
       else if(cmd_type=="rename_group")
        {
            if(result==0)
            {
                QString old_name, new_name;
                if(root_obj.contains("old_name"))
                {
                    QJsonValue value = root_obj.value("old_name");
                    old_name=value.toString();
                }
                if(root_obj.contains("new_name"))
                {
                    QJsonValue value = root_obj.value("new_name");
                    new_name=value.toString();
                }
                emit siqRenameGroup(old_name, new_name);
            }
        }
五、删除分组

用户后端请求删除分组代码:

cpp 复制代码
void CenterMan::requestDelGroup(QString group_name)
{
    QJsonObject root_obj;
    QJsonDocument json_doc;

    root_obj.insert("account", m_loginAccount);
    root_obj.insert("rand_num", m_randNum);
    root_obj.insert("mac", m_macStr); 
    root_obj.insert("app_id", (qint64)m_currAppWork.appID); 
    root_obj.insert("cmd_type", "del_group");
    root_obj.insert("group_name", group_name); 
    json_doc.setObject(root_obj);
    QByteArray msg_ba = json_doc.toJson(QJsonDocument::Indented);
    QString topic=makePubTopic("group");
    emit sigMqttPushMessage(topic, msg_ba);
}

平台收到后操作数据库进行删除,

cpp 复制代码
    else if(cmd_type=="del_group")
    {
        QString group_name;
        if(root_obj.contains("group_name"))
        {
            group_name=root_obj.value("group_name").toString();
        }
        GroupSqlite::GroupNodeStruct tag_group;
        tag_group.groupName="";
        tag_groupSqlite.selectGroupNode(group_name, tag_group);
        if(group_name!=tag_group.groupName)
        {
            result=3;//分组不存在
            ack_str="分组不存在!";
        }
        else  
        {
            tag_groupSqlite.delGroupNode(group_name);
            tag_group.groupName="";
            tag_groupSqlite.selectGroupNode(group_name, tag_group);
            if(group_name!=tag_group.groupName)
            {
                result=0;//成功
                ack_str="删除成功!";
            }
            else   
            {
                result=4;//删除失败
                ack_str="删除失败!";
            }
        }
        ackDelGroup(account, mac_str, rand_num, app_id, group_name, result, ack_str);
    }


void CenterThread::ackDelGroup(QString account, QString mac_str, int rand_num, u32 app_id, QString group_name, int result, QString ack_str)
{
    QJsonObject root_obj;
    QJsonDocument json_doc;

    root_obj.insert("cmd_type", "del_group");
    root_obj.insert("account", account);
    root_obj.insert("app_id", (qint64)app_id);
    root_obj.insert("group_name", group_name);
    root_obj.insert("result", result);
    root_obj.insert("ack_str", ack_str);
    json_doc.setObject(root_obj);
    QByteArray msg_ba = json_doc.toJson(QJsonDocument::Indented);
    QString topic=makePubTopic(account, mac_str, rand_num, "group");
    emit sigMqttPushMessage(topic, msg_ba);
}

用户端收到反馈后同步删除前端分组,

cpp 复制代码
        else if(cmd_type=="del_group")
        {
            QString group_name="";
            if(root_obj.contains("group_name"))
            {
                QJsonValue value = root_obj.value("group_name");
                group_name=value.toString();
            }

            if(result==0)
            {
                emit siqDelGroup(group_name);
                int nSize=m_groupList.size();
                for(int i=0; i<nSize; i++)
                {
                    if(m_groupList.at(i).groupName==group_name)
                    {
                        m_groupList.removeAt(i);
                        break;
                    }
                }
            }
        }
六、分组排序

排序的逻辑在文章开头时候说过了,用户端这边只需要按期望的顺序上传分组名称就行了,

cpp 复制代码
void CenterMan::requestOrderGroup(QStringList group_list)
{
    QJsonObject root_obj;
    QJsonDocument json_doc;    

    root_obj.insert("account", m_loginAccount);
    root_obj.insert("rand_num", m_randNum);
    root_obj.insert("mac", m_macStr); 
    root_obj.insert("app_id", (qint64)m_currAppWork.appID); 
    root_obj.insert("cmd_type", "order_group");
    QJsonArray group_array;
    qDebug()<<"group_list="<<group_list;
    for(auto iter : group_list)
    {
        group_array.append(iter);
    }
    root_obj.insert("group_list", group_array); 
    json_doc.setObject(root_obj);
    QByteArray msg_ba = json_doc.toJson(QJsonDocument::Indented);
    QString topic=makePubTopic("group");
    emit sigMqttPushMessage(topic, msg_ba);
}

服务器后台按分组名称顺序一个个更新groupOrder值,这里的返回取巧了,直接返回了group_list的指令内容了,也就是分组列表。

cpp 复制代码
  else if(cmd_type=="order_group")
    {
        QJsonArray group_array;
        if(root_obj.contains("group_list"))
        {
            group_array=root_obj.value("group_list").toArray();
        }
        int nSize=group_array.size();
        for(int i=0; i<nSize; i++)
        {
            QString group_name=group_array.at(i).toString();
            tag_groupSqlite.updateGroupOrder(group_name, i);
        }
        result=0;//成功
        ack_str="排序成功!";
//        ackOrderGroup(account, mac_str, rand_num, app_id, group_array, result, ack_str);
        if(1)
        {
            QList<GroupSqlite::GroupNodeStruct>group_list;
            QJsonArray group_array;
            tag_groupSqlite.selectGroupList(group_list);
            for(auto iter : group_list)
            {
                QJsonObject group_obj;
                QJsonArray dev_list;
                for(auto iter2 : iter.devList)
                {
                    u32 dev_sn=iter2;
                    dev_list.append((qint64)dev_sn);
                }
                group_obj.insert("group_name", iter.groupName);
                group_obj.insert("dev_list", dev_list);
                group_array.append(group_obj);
            }
            ackTakeGroupList(account, mac_str, rand_num, app_id, group_array, result, ack_str);
        }
    }

用户端收到后整体上重新更新前端的分组页面。

相关推荐
wqq_9922502773 分钟前
springboot基于微信小程序的食堂预约点餐系统
数据库·微信小程序·小程序
爱上口袋的天空5 分钟前
09 - Clickhouse的SQL操作
数据库·sql·clickhouse
2401_882727571 小时前
BY组态-低代码web可视化组件
前端·后端·物联网·低代码·数学建模·前端框架
聂 可 以2 小时前
Windows环境安装MongoDB
数据库·mongodb
web前端神器2 小时前
mongodb多表查询,五个表查询
数据库·mongodb
门牙咬脆骨2 小时前
【Redis】redis缓存击穿,缓存雪崩,缓存穿透
数据库·redis·缓存
门牙咬脆骨2 小时前
【Redis】GEO数据结构
数据库·redis·缓存
wusong9992 小时前
mongoDB回顾笔记(一)
数据库·笔记·mongodb
代码小鑫2 小时前
A043-基于Spring Boot的秒杀系统设计与实现
java·开发语言·数据库·spring boot·后端·spring·毕业设计
changuncle2 小时前
MongoDB数据备份与恢复(内含工具下载、数据处理以及常见问题解决方法)
数据库·mongodb