240717班级,工业化控制系统,煤矿相关行业,昆仑系统
Administrator
2024-11-06 731aab44a67db573ab7a9e6af8bfecf6efebbd23
Merge branch 'master' of ssh://115.28.86.8:29418/~admin/昆仑_1025
1 文件已重命名
24个文件已修改
19个文件已添加
3065 ■■■■ 已修改文件
Client/冀浩昶/log/日志_冀浩昶_1105.doc 补丁 | 查看 | 原始文档 | blame | 历史
Client/冀浩昶/log/日志_冀浩昶_1106.doc 补丁 | 查看 | 原始文档 | blame | 历史
Client/刘子航/log/日志_刘子航_1106.doc 补丁 | 查看 | 原始文档 | blame | 历史
Client/姜可庚/code/2024kunlun_project_permisson/2024kunlun_project_permisson.pro.user 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Client/姜可庚/code/2024kunlun_project_permisson/PmsClientSocket.cpp 100 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Client/姜可庚/code/2024kunlun_project_permisson/PmsClientSocket.h 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Client/姜可庚/code/2024kunlun_project_permisson/permissondialog.cpp 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Client/姜可庚/code/2024kunlun_project_permisson/permissondialog.ui 241 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Client/姜可庚/code/2024kunlun_project_permisson/permissonwindow.cpp 99 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Client/姜可庚/code/2024kunlun_project_permisson/permissonwindow.h 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Client/姜可庚/code/2024kunlun_project_permisson/pmsparam.h 19 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Client/姜可庚/code/2024kunlun_project_permisson/pmsplusparam.h 62 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Client/姜可庚/code/2024kunlun_project_permisson/pmsqueryresult.h 83 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Client/姜可庚/code/2024kunlun_project_permisson/qcomboxdelegate.cpp 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Client/姜可庚/code/2024kunlun_project_permisson/qcomboxdelegate.h 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Client/姜可庚/code/2024kunlun_project_permisson/syncdatatodb.cpp 52 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Client/姜可庚/code/服务端业务代码/PermissonManage.cpp 152 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Client/姜可庚/code/服务端业务代码/PermissonManage.h 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Client/姜可庚/code/服务端业务代码/ServerSocket.cpp 166 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Client/姜可庚/code/服务端业务代码/common.h 1064 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Client/姜可庚/document/权限管理需求分析.docx 补丁 | 查看 | 原始文档 | blame | 历史
Client/姜可庚/log/姜可庚_1106.doc 补丁 | 查看 | 原始文档 | blame | 历史
Client/朱航/log/朱航1104.doc 补丁 | 查看 | 原始文档 | blame | 历史
Client/李宵增/log/历史查询_李宵增_1102.doc 补丁 | 查看 | 原始文档 | blame | 历史
Client/申烜/log/日志_申烜_1105.doc 补丁 | 查看 | 原始文档 | blame | 历史
Client/黎弘霖/log/设备管理_黎弘霖_1105.doc 补丁 | 查看 | 原始文档 | blame | 历史
Client/黎弘霖/log/设备管理_黎弘霖_1106.doc 补丁 | 查看 | 原始文档 | blame | 历史
Client/龚启祥/log/日志模板_龚启祥_1105.doc 补丁 | 查看 | 原始文档 | blame | 历史
Server/李转转/log/配置管理_李转转_1106.doc 补丁 | 查看 | 原始文档 | blame | 历史
Server/王琨元/code/ConnectionPool.cpp 204 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Server/王琨元/code/ConnectionPool.h 82 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Server/王琨元/code/MysqlConn.cpp 310 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Server/王琨元/code/MysqlConn.h 88 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Server/王琨元/log/日志模板_王琨元_1101.doc 补丁 | 查看 | 原始文档 | blame | 历史
Server/王琨元/log/日志模板_王琨元_1103 .doc 补丁 | 查看 | 原始文档 | blame | 历史
Server/王琨元/log/日志模板_王琨元_1104.doc 补丁 | 查看 | 原始文档 | blame | 历史
Server/王琨元/log/日志模板_王琨元_1105.doc 补丁 | 查看 | 原始文档 | blame | 历史
Server/陈楚丹/log/日志_陈楚丹_1105.doc 补丁 | 查看 | 原始文档 | blame | 历史
Server/马渝杭/log/20241105昆仑日报.doc 补丁 | 查看 | 原始文档 | blame | 历史
Server/马渝杭/log/日志_马渝杭_20241104.doc 补丁 | 查看 | 原始文档 | blame | 历史
Server/马渝杭/log/日志_马渝杭_20241105.doc 补丁 | 查看 | 原始文档 | blame | 历史
common.h 142 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
kunlun.sql 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
表.docx 补丁 | 查看 | 原始文档 | blame | 历史
Client/¼½ºÆêÆ/log/ÈÕÖ¾_¼½ºÆêÆ_1105.doc
Binary files differ
Client/¼½ºÆêÆ/log/ÈÕÖ¾_¼½ºÆêÆ_1106.doc
Binary files differ
Client/Áõ×Óº½/log/ÈÕÖ¾_Áõ×Óº½_1106.doc
Binary files differ
Client/½ª¿É¸ý/code/2024kunlun_project_permisson/2024kunlun_project_permisson.pro.user
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 4.5.0, 2024-10-31T16:02:45. -->
<!-- Written by QtCreator 4.5.0, 2024-11-04T20:34:52. -->
<qtcreator>
 <data>
  <variable>EnvironmentId</variable>
Client/½ª¿É¸ý/code/2024kunlun_project_permisson/PmsClientSocket.cpp
@@ -5,7 +5,7 @@
PmsClientSocket::PmsClientSocket(QWidget * parent):QWidget(parent)
{
    client = new QTcpSocket(this);
    connect(client,SIGNAL(connected()),this,SLOT(connected_Slot()));
    client->connectToHost(targetIp,port);
    if(!client->waitForConnected(3000)){
@@ -14,14 +14,12 @@
    }
    connectSuccess = true;
    qDebug()<< "QT网络通信成功已连接服务器!";
    connect(client,SIGNAL(connected()),this,SLOT(connected_Slot()));
}
void PmsClientSocket::queryAllUserAboutUser()
{
    if(connectSuccess){
        QueryPmsRequest req;
        QueryPmsReq req;
        client->write((char *)&req,req.head.len);
        qDebug() << "查询全部权限请求发送成功";
    }
@@ -30,10 +28,10 @@
void PmsClientSocket::queryPmsByParam(PmsParam param)
{
    if(connectSuccess){
        QueryPmsRequest req;
        strcpy(req.name,param.getName().c_str());
        strcpy(req.permissonType,param.getPermissonType().c_str());
        strcpy(req.userNo,param.getUserNo().c_str());
        QueryPmsReq req;
        strcpy(req.name,param.getName().toLocal8Bit().data());
        strcpy(req.permissonType,param.getPermissonType().toLocal8Bit().data());
        strcpy(req.userNo,param.getUserNo().toLocal8Bit().data());
        client->write((char *)&req,req.head.len);
        qDebug() << "条件查询权限请求发送成功";
    }
@@ -41,12 +39,23 @@
void PmsClientSocket::updatePmsByParam(PmsPlusParma param)
{
    UpdatePmsRequest upReq;
    upReq.devManage = param.getDevManage();
    upReq.loggerSearch = param.getLoggerSearch();
    upReq.mapMark = param.getMapMark();
    upReq.productPlan = param.getProductPlan();
    upReq.roleId = param.getRoleId();
    UpdatePmsReq upReq;
    upReq.id = param.getId();
    if(param.getPermissonType().isEmpty()){
        upReq.devManage = param.getDevManage();
        upReq.loggerSearch = param.getLoggerSearch();
        upReq.mapMark = param.getMapMark();
        upReq.productPlan = param.getProductPlan();
        upReq.warningManage = param.getWarninManage();
        upReq.versionManage = param.getVersionManage();
        upReq.admin = param.getAdmin();
        upReq.queryHistory = param.getQueryHistory();
        memset(upReq.permissonType,0,32);
    }else {
        strcpy(upReq.permissonType,param.getPermissonType().toLocal8Bit().data());
    }
    client->write((char *)&upReq,upReq.head.len);
    qDebug() << "更新权限请求发送成功";
}
@@ -59,40 +68,45 @@
void PmsClientSocket::readyRead_Slot()
{
    QByteArray buf = client->readAll();
    QString recvData = QString::fromLocal8Bit(buf);
    qDebug()<< "client收到的数据" << recvData;
    QueryPmsResponse * res;
    UpdatePmsResponse * upRes;
    int type = *(int *)buf.data();
    if(type == QUERY_PMS_REQ){
          res = (QueryPmsResponse *)buf.data();
    qDebug()<< "client收到了的数据";
    QueryPmsRes * res;
    UpdatePmsRes * upRes;
    Head head = *(Head *)buf.data();
    if(head.type == QUERY_PMS_RES){
        qDebug()<< "查询响应";
          res = (QueryPmsRes *)buf.data();
          if(res->success){
              vector<PmsQueryResult> vecs;
              int pmsLen = res->head.len-sizeof(QueryPmsResponse);
              for(int i =0;i<pmsLen;i+=sizeof(PmsRes)){
                  PmsRes structRes = *(PmsRes*)(res + sizeof(QueryPmsResponse) + i*sizeof(PmsRes));
                      PmsQueryResult res;
                      res.setName(string(structRes.name));
                      res.setUserNo(string(structRes.userNo));
                      res.setRoleId(structRes.roleId);
                      res.setStartDateTime(string(structRes.startDateTime));
                      res.setEndDateTime(string(structRes.endDateTime));
                      res.setLoggerSearch(structRes.loggerSearch);
                      res.setMapMark(structRes.mapMark);
                      res.setDevManage(structRes.devManage);
                      res.setProductPlan(structRes.productPlan);
                      res.setQueryHistory(structRes.queryHistory);
                      res.setPermissonType(string(structRes.permissonType));
                      vecs.push_back(res);
              int pmsLen = (res->head.len-sizeof(QueryPmsRes))/sizeof(PmsRes);
              for(int i =0;i<pmsLen;i++){
                  PmsRes structRes = res->pmsList[i];
                      PmsQueryResult qres;
                      qres.setName(QString::fromLocal8Bit(structRes.name));
                      qres.setUserNo(QString::fromLocal8Bit(structRes.userNo));
                      qres.setId(structRes.id);
                      qres.setLoginTime(string(structRes.loginTime));
                      qres.setRegisterTime(string(structRes.registerTime));
                      qres.setLoggerSearch(structRes.loggerSearch);
                      qres.setMapMark(structRes.mapMark);
                      qres.setDevManage(structRes.devManage);
                      qres.setProductPlan(structRes.productPlan);
                      qres.setQueryHistory(structRes.queryHistory);
                      qres.setPermissonType(QString::fromLocal8Bit(structRes.permissonType));
                      qres.setWarninManage(structRes.warningManage);
                      qres.setVersionManage(structRes.versionManage);
                      qres.setAdmin(structRes.admin);
                      vecs.push_back(qres);
              }
              if(!vecs.empty()){
                  emit notifyDateChange(vecs);
              }
              emit notifyDateChange(vecs);
          }else{
              // æŸ¥è¯¢å¤±è´¥æ•°æ®ä¸ºç©ºæ¸…除表格数据
              emit notifyDateChange(vector<PmsQueryResult>());
          }
    }
    if(type == UPDATE_PMS_REQ){
        res = (QueryPmsResponse *)buf.data();
        if(res->success){
    if(head.type == UPDATE_PMS_RES){
        upRes = (UpdatePmsRes *)buf.data();
        qDebug()<< "更新响应";
        if(upRes->success){
            QString dlgTitle = "更新结果";
            QString strInfo = "权限信息更新成功";
            QMessageBox::information(this,dlgTitle,strInfo,
Client/½ª¿É¸ý/code/2024kunlun_project_permisson/PmsClientSocket.h
@@ -16,7 +16,7 @@
};
enum option{
    QUERY_PMS_REQ,
    QUERY_PMS_REQ=6,
    UPDATE_PMS_REQ,
    QUERY_PMS_RES,
    UPDATE_PMS_RES,
@@ -24,73 +24,84 @@
// æŒ‰å‘˜å·¥ç¼–号、名字或职位查询人员权限信息请求
typedef struct QueryPmsRequest{
typedef struct QueryPmsReq{
    Head head;
    char userNo[32];
    char name[32];
    char permissonType[32];
    QueryPmsRequest(){
    QueryPmsReq(){
        head.type=QUERY_PMS_REQ;
        memset(userNo,0,32);
        memset(permissonType,0,32);
        memset(name,0,32);
        head.len = sizeof(QueryPmsRequest);
        head.len = sizeof(QueryPmsReq);
    }
} QueryPmsRequest;
} QueryPmsReq;
// æŒ‰è§’色id更新权限信息请求
typedef struct UpdatePmsRequest{
typedef struct UpdatePmsReq{
    Head head;
    int roleId;
    // äººå‘˜è¡¨ä¸»é”®id
    int id;
    int queryHistory;
    int loggerSearch;
    int mapMark;
    int devManage;
    int productPlan;
    UpdatePmsRequest(){
        head.type=QUERY_PMS_RES;
        head.len = sizeof(UpdatePmsRequest);
    }
} UpdatePmsRequest;
    int warningManage;
    int versionManage; //版本管理
    int admin; //系统管理员
// å•个人员权限结构体
typedef struct UserAboutPms{
    char permissonType[32];
    UpdatePmsReq(){
        head.type=UPDATE_PMS_REQ;
        head.len = sizeof(UpdatePmsReq);
    }
} UpdatePmsReq;
// å•个人员和权限联合查询结构体
typedef struct PmsRes{
    int queryHistory;
    int loggerSearch;
    int mapMark;
    int devManage;
    int productPlan;
    int roleId;
    int versionManage; //版本管理
    int warningManage;
    int admin; //系统管理员
    int id;
    char userNo[32];
    char name[32];
    char permissonType[32];
    char startDateTime[32];
    char endDateTime[32];
    char permissonType[32];  // è§’色类型
    char department[32];
    char loginTime[32];
    char registerTime[32];
} PmsRes;
// æŸ¥è¯¢äººå‘˜å’Œè§’色信息的响应结构体
typedef struct UserAboutPmsResponse{
typedef struct QueryPmsRes{
    Head head;
    int success; // 1为成功 ,0为失败
    //PmsRes pmsList[100];
    char pmsList[0];
    UserAboutPmsResponse(){
    PmsRes pmsList[0];
    QueryPmsRes(){
        head.type=QUERY_PMS_RES;
//        memset(pmsList,0,sizeof(PmsRes));
//        head.len = sizeof(UserAboutPmsResponse);
    }
} QueryPmsResponse;
} QueryPmsRes;
// æƒé™æ›´æ–°ç»“果响应体
typedef struct UpdatePmsResponse{
typedef struct UpdatePmsRes{
    Head head;
    int success; // 1为成功 ,0为失败
    UpdatePmsResponse(){
    UpdatePmsRes(){
        head.type = UPDATE_PMS_RES;
        head.len = sizeof(UpdatePmsResponse);
        head.len = sizeof(UpdatePmsRes);
    }
} UpdatePmsResponse ;
} UpdatePmsRes ;
class PmsClientSocket : public QWidget
@@ -99,7 +110,7 @@
    QTcpSocket *client;
    int port=88888;
    int port=16888;
    QString targetIp = "127.0.0.1";
    bool connectSuccess= false;
Client/½ª¿É¸ý/code/2024kunlun_project_permisson/permissondialog.cpp
@@ -34,11 +34,29 @@
    map5[2]=ui->radioButton_15;
    map<int,QRadioButton *> warningMap;
    warningMap[0]=ui->radioButton_16;
    warningMap[1]=ui->radioButton_17;
    warningMap[2]=ui->radioButton_18;
    map<int,QRadioButton *> versionMap;
    versionMap[0]=ui->radioButton_19;
    versionMap[1]=ui->radioButton_20;
    versionMap[2]=ui->radioButton_21;
    map<int,QRadioButton *> superManager;
    // 1为超级管理员
    superManager[0]=ui->radioButton_23;
    superManager[1]=ui->radioButton_22;
    btnList.push_back(map1);
    btnList.push_back(map2);
    btnList.push_back(map3);
    btnList.push_back(map4);
    btnList.push_back(map5);
    btnList.push_back(warningMap);
    btnList.push_back(versionMap);
    btnList.push_back(superManager);
}
@@ -50,7 +68,7 @@
int PermissonDialog::findBoxCheck(map<int, QRadioButton *> map)
{
    for(int i =0;i<map.size();i++){
        if(btnList[0][i]->isChecked()){
        if(map[i]->isChecked()){
            return i;
        }
    }
@@ -65,6 +83,12 @@
    btnList[2][res.getMapMark()]->setChecked(true);
    btnList[3][res.getDevManage()]->setChecked(true);
    btnList[4][res.getProductPlan()]->setChecked(true);
    btnList[5][res.getWarninManage()]->setChecked(true);
    btnList[6][res.getVersionManage()]->setChecked(true);
    btnList[7][res.getAdmin()]->setChecked(true);
    curRes = res;
@@ -81,8 +105,11 @@
    param.setMapMark(findBoxCheck(btnList[2]));
    param.setDevManage(findBoxCheck(btnList[3]));
    param.setProductPlan(findBoxCheck(btnList[4]));
    param.setWarninManage(findBoxCheck(btnList[5]));
    param.setVersionManage(findBoxCheck(btnList[6]));
    param.setAdmin(findBoxCheck(btnList[7]));
    param.setRoleId(curRes.getRoleId());
    param.setId(curRes.getId());
    client->updatePmsByParam(param);
}
Client/½ª¿É¸ý/code/2024kunlun_project_permisson/permissondialog.ui
@@ -6,8 +6,8 @@
   <rect>
    <x>0</x>
    <y>0</y>
    <width>421</width>
    <height>361</height>
    <width>560</width>
    <height>492</height>
   </rect>
  </property>
  <property name="windowTitle">
@@ -16,54 +16,18 @@
  <layout class="QGridLayout" name="gridLayout_3">
   <item row="0" column="0">
    <layout class="QGridLayout" name="gridLayout_2">
     <item row="3" column="0">
      <widget class="QDialogButtonBox" name="buttonBox">
       <property name="orientation">
        <enum>Qt::Horizontal</enum>
       </property>
       <property name="standardButtons">
        <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
       </property>
      </widget>
     </item>
     <item row="0" column="0">
      <layout class="QGridLayout" name="gridLayout">
       <item row="0" column="0">
        <widget class="QGroupBox" name="groupBox">
         <property name="title">
          <string>历时查询</string>
         </property>
         <widget class="QRadioButton" name="radioButton">
          <property name="geometry">
           <rect>
            <x>20</x>
            <y>20</y>
            <width>115</width>
            <height>19</height>
           </rect>
          </property>
          <property name="text">
           <string>无权限</string>
          </property>
         </widget>
         <widget class="QRadioButton" name="radioButton_2">
          <property name="geometry">
           <rect>
            <x>150</x>
            <y>20</y>
            <width>115</width>
            <height>19</height>
           </rect>
          </property>
          <property name="text">
           <string>可查看</string>
          </property>
         </widget>
         <widget class="QRadioButton" name="radioButton_3">
          <property name="geometry">
           <rect>
            <x>280</x>
            <y>20</y>
            <width>115</width>
            <height>19</height>
           </rect>
          </property>
          <property name="text">
           <string>可修改</string>
          </property>
         </widget>
        </widget>
       </item>
       <item row="1" column="0">
        <widget class="QGroupBox" name="groupBox_2">
         <property name="title">
@@ -96,6 +60,52 @@
          </property>
         </widget>
         <widget class="QRadioButton" name="radioButton_6">
          <property name="geometry">
           <rect>
            <x>280</x>
            <y>20</y>
            <width>115</width>
            <height>19</height>
           </rect>
          </property>
          <property name="text">
           <string>可修改</string>
          </property>
         </widget>
        </widget>
       </item>
       <item row="0" column="0">
        <widget class="QGroupBox" name="groupBox">
         <property name="title">
          <string>历时查询</string>
         </property>
         <widget class="QRadioButton" name="radioButton">
          <property name="geometry">
           <rect>
            <x>20</x>
            <y>20</y>
            <width>115</width>
            <height>19</height>
           </rect>
          </property>
          <property name="text">
           <string>无权限</string>
          </property>
         </widget>
         <widget class="QRadioButton" name="radioButton_2">
          <property name="geometry">
           <rect>
            <x>150</x>
            <y>20</y>
            <width>115</width>
            <height>19</height>
           </rect>
          </property>
          <property name="text">
           <string>可查看</string>
          </property>
         </widget>
         <widget class="QRadioButton" name="radioButton_3">
          <property name="geometry">
           <rect>
            <x>280</x>
@@ -248,17 +258,132 @@
         </widget>
        </widget>
       </item>
       <item row="5" column="0">
        <widget class="QGroupBox" name="groupBox_6">
         <property name="title">
          <string>警报管理</string>
         </property>
         <widget class="QRadioButton" name="radioButton_16">
          <property name="geometry">
           <rect>
            <x>20</x>
            <y>20</y>
            <width>115</width>
            <height>19</height>
           </rect>
          </property>
          <property name="text">
           <string>无权限</string>
          </property>
         </widget>
         <widget class="QRadioButton" name="radioButton_17">
          <property name="geometry">
           <rect>
            <x>150</x>
            <y>20</y>
            <width>115</width>
            <height>19</height>
           </rect>
          </property>
          <property name="text">
           <string>可查看</string>
          </property>
         </widget>
         <widget class="QRadioButton" name="radioButton_18">
          <property name="geometry">
           <rect>
            <x>280</x>
            <y>20</y>
            <width>115</width>
            <height>19</height>
           </rect>
          </property>
          <property name="text">
           <string>可修改</string>
          </property>
         </widget>
        </widget>
       </item>
       <item row="6" column="0">
        <widget class="QGroupBox" name="groupBox_7">
         <property name="title">
          <string>版本管理</string>
         </property>
         <widget class="QRadioButton" name="radioButton_19">
          <property name="geometry">
           <rect>
            <x>20</x>
            <y>20</y>
            <width>115</width>
            <height>19</height>
           </rect>
          </property>
          <property name="text">
           <string>无权限</string>
          </property>
         </widget>
         <widget class="QRadioButton" name="radioButton_20">
          <property name="geometry">
           <rect>
            <x>150</x>
            <y>20</y>
            <width>115</width>
            <height>19</height>
           </rect>
          </property>
          <property name="text">
           <string>可查看</string>
          </property>
         </widget>
         <widget class="QRadioButton" name="radioButton_21">
          <property name="geometry">
           <rect>
            <x>280</x>
            <y>20</y>
            <width>115</width>
            <height>19</height>
           </rect>
          </property>
          <property name="text">
           <string>可修改</string>
          </property>
         </widget>
        </widget>
       </item>
       <item row="7" column="0">
        <widget class="QGroupBox" name="groupBox_8">
         <property name="title">
          <string>超级管理员</string>
         </property>
         <widget class="QRadioButton" name="radioButton_22">
          <property name="geometry">
           <rect>
            <x>20</x>
            <y>20</y>
            <width>115</width>
            <height>19</height>
           </rect>
          </property>
          <property name="text">
           <string>是</string>
          </property>
         </widget>
         <widget class="QRadioButton" name="radioButton_23">
          <property name="geometry">
           <rect>
            <x>150</x>
            <y>20</y>
            <width>115</width>
            <height>19</height>
           </rect>
          </property>
          <property name="text">
           <string>否</string>
          </property>
         </widget>
        </widget>
       </item>
      </layout>
     </item>
     <item row="1" column="0">
      <widget class="QDialogButtonBox" name="buttonBox">
       <property name="orientation">
        <enum>Qt::Horizontal</enum>
       </property>
       <property name="standardButtons">
        <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
       </property>
      </widget>
     </item>
    </layout>
   </item>
Client/½ª¿É¸ý/code/2024kunlun_project_permisson/permissonwindow.cpp
@@ -11,46 +11,20 @@
    ui(new Ui::PermissonWindow)
{
    ui->setupUi(this);
    clientSocket = new PmsClientSocket(this);
    dia = new PermissonDialog(this,clientSocket);
    connect(this,SIGNAL(sendUserNo(PmsQueryResult)),dia,SLOT(recvUserNo(PmsQueryResult)));
    connect(clientSocket,SIGNAL(notifyDateChange(vector<PmsQueryResult>)),this,SLOT(renderItemData(vector<PmsQueryResult>)));
    roleMap["普通采矿员工"] = 1;
    roleMap["技术维护人员"] = 2;
    roleMap["系统管理员"] = 3;
    roleMap["安全管理人员"] = 4;
    this->setWindowTitle("权限管理");
    vector<QString> lableList;
    lableList.push_back("员工编号");
    lableList.push_back("姓名");
    lableList.push_back("当天工作时间");
    lableList.push_back("当天结束时间");
    lableList.push_back("部门");
    lableList.push_back("登录时间");
    lableList.push_back("注册时间");
    lableList.push_back("职位");
    clientSocket = new PmsClientSocket(this);
    dia = new PermissonDialog(this,clientSocket);
    m_model = new QStandardItemModel(globalPms.size(),lableList.size(),this);
    ui->tableView->setModel(m_model);
    for(int i=0;i<m_model->rowCount();i++){
        PmsQueryResult curRes = globalPms[i];
        m_model->setItem(i,0,new QStandardItem(QString::fromStdString(curRes.getUserNo())));
        m_model->setItem(i,1,new QStandardItem(QString::fromLocal8Bit(curRes.getName().c_str())));
        m_model->setItem(i,2,new QStandardItem(QString::fromStdString(curRes.getStartDateTime())));
        m_model->setItem(i,3,new QStandardItem(QString::fromStdString(curRes.getEndDateTime())));
        m_model->setItem(i,4,new QStandardItem(QString::fromLocal8Bit(curRes.getPermissonType().c_str())));
    }
    ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
    ui->tableView->verticalHeader()->hide();
    QStringList lable;
@@ -60,11 +34,22 @@
    m_model->setHorizontalHeaderLabels(lable);
    ui->tableView->setModel(m_model);
    ui->tableView->verticalHeader()->hide();
    connect(this,SIGNAL(sendUserNo(PmsQueryResult)),dia,SLOT(recvUserNo(PmsQueryResult)));
    connect(clientSocket,SIGNAL(notifyDateChange(vector<PmsQueryResult>)),this,SLOT(renderItemData(vector<PmsQueryResult>)));
    connect(m_model,SIGNAL(itemChanged(QStandardItem*)),this,SLOT(listenItemChange(QStandardItem*)));
    // å‘一次查询全部数据请求
    clientSocket->queryAllUserAboutUser();
    QComBoxDelegate * qc = new QComBoxDelegate(this);
    ui->tableView->setItemDelegateForColumn(4,qc);
    ui->tableView->setItemDelegateForColumn(5,qc);
    m = new QMenu(this);
@@ -82,17 +67,13 @@
    connect(ac1,&QAction::triggered,[=]{
         int row = ui->tableView->currentIndex().row();
         qDebug() << "更新当前员工信息"
                  <<  QString::fromStdString( globalPms[row].getUserNo());
                  << globalPms[row].getUserNo();
         // å‘送员工编号信息
         emit sendUserNo(globalPms[row]);
         dia->setModal(true);
         dia->show();
    });
    connect(m_model,SIGNAL(itemChanged(QStandardItem*)),this,SLOT(listenItemChange(QStandardItem*)));
}
@@ -123,44 +104,50 @@
void PermissonWindow::on_pushButton_clicked()
{
    qDebug() << "发送查询请求";
    PmsParam pm;
    pm.setName(ui->lineEdit->text().toStdString());
    pm.setPermissonType(ui->lineEdit_2->text().toStdString());
    pm.setUserNo(ui->lineEdit_3->text().toStdString());
    pm.setName(ui->lineEdit->text());
    pm.setPermissonType(ui->lineEdit_2->text());
    pm.setUserNo(ui->lineEdit_3->text());
    clientSocket->queryPmsByParam(pm);
    qDebug() << "查询中";
}
void PermissonWindow::listenItemChange(QStandardItem *item)
{
    QString localText = item->text();
    if(roleMap.count(localText.toStdString())){
        qDebug() << "发起职位更新请求";
    if(item->column()==m_model->columnCount()-1){
        QString localText = item->text();
        PmsPlusParma pm;
        pm.setPermissonType(localText.toStdString());
        pm.setRoleId(roleMap[localText.toStdString()]);
        pm.setPermissonType(localText);
        int id = globalPms[item->row()].getId();
        pm.setId(id);
        clientSocket->updatePmsByParam(pm);
    }
}
void PermissonWindow::renderItemData(vector<PmsQueryResult> res)
{
    globalPms = res;
    m_model->setRowCount(globalPms.size());
    for(int i=0;i<m_model->rowCount();i++){
        PmsQueryResult curRes = globalPms[i];
        m_model->setItem(i,0,new QStandardItem(QString::fromStdString(curRes.getUserNo())));
        m_model->setItem(i,1,new QStandardItem(QString::fromLocal8Bit(curRes.getName().c_str())));
        m_model->setItem(i,2,new QStandardItem(QString::fromStdString(curRes.getStartDateTime())));
        m_model->setItem(i,3,new QStandardItem(QString::fromStdString(curRes.getEndDateTime())));
        m_model->setItem(i,4,new QStandardItem(QString::fromLocal8Bit(curRes.getPermissonType().c_str())));
        m_model->setItem(i,0,new QStandardItem(curRes.getUserNo()));
        m_model->setItem(i,1,new QStandardItem(curRes.getName()));
        m_model->setItem(i,2,new QStandardItem(QString::fromStdString(curRes.getDepartment())));
        m_model->setItem(i,3,new QStandardItem(QString::fromStdString(curRes.getLoginTime())));
        m_model->setItem(i,4,new QStandardItem(QString::fromStdString(curRes.getRegisterTime())));
        m_model->blockSignals(true);
        m_model->setItem(i,5,new QStandardItem(curRes.getPermissonType()));
        m_model->blockSignals(false);
    }
    ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
    qDebug() << "查询到的数量 " << globalPms.size();
}
Client/½ª¿É¸ý/code/2024kunlun_project_permisson/permissonwindow.h
@@ -46,11 +46,13 @@
    QMenu * m;
    PermissonDialog *dia;
    SyncDataToDB * dbInfo;
    map<string,int> roleMap;
    vector<PmsQueryResult> globalPms;
    PmsClientSocket * clientSocket;
    bool isRenderData;
};
Client/½ª¿É¸ý/code/2024kunlun_project_permisson/pmsparam.h
@@ -1,32 +1,33 @@
#ifndef PMSPARAM_H
#define PMSPARAM_H
#include <QString>
#include <string>
using namespace std;
class PmsParam {
protected:
    string userNo;
    string name;
    string permissonType;
    QString userNo;
    QString name;
    QString permissonType;
public:
    void setUserNo(string id){
    void setUserNo(QString id){
        this->userNo = id;
    }
    void setName(string name){
    void setName(QString name){
        this->name = name;
    }
    void setPermissonType(string permissonType){
    void setPermissonType(QString permissonType){
        this->permissonType = permissonType;
    }
    string getUserNo(){
    QString getUserNo(){
        return userNo;
    }
    string getName(){
    QString getName(){
        return name;
    }
    string getPermissonType(){
    QString getPermissonType(){
        return permissonType;
    }
Client/½ª¿É¸ý/code/2024kunlun_project_permisson/pmsplusparam.h
@@ -1,15 +1,19 @@
#ifndef PMSPLUSPARAM_H
#ifndef PMSPLUSPARAM_H
#define PMSPLUSPARAM_H
#include "pmsparam.h"
class PmsPlusParma : public PmsParam{
    int roleId;
    int id;
    int queryHistory;
    int loggerSearch;
    int mapMark;
    int devManage;
    int productPlan;
    int warninManage;
    int versionManage; //版本管理
    int admin; //系统管理员
public:
    void setQueryHistory(int val){
        this->queryHistory = val;
@@ -27,8 +31,8 @@
        this->productPlan = val;
    }
    void setRoleId(int val){
        this->roleId = val;
    void setId(int val){
        this->id = val;
    }
    int getQueryHistory(){
@@ -47,19 +51,51 @@
        return productPlan;
    }
    int getRoleId(){
        return roleId;
    int getId(){
        return id;
    }
    PmsPlusParma(){
        id = 0;
        queryHistory = 0;
        loggerSearch = 0;
        mapMark = 0;
        devManage = 0;
        productPlan = 0;
    }
    PmsPlusParma(){
        roleId = -1;
        queryHistory = -1;
        loggerSearch = -1;
        mapMark = -1;
        devManage = -1;
        productPlan = -1;
    int getVersionManage() const
    {
        return versionManage;
    }
    void setVersionManage(int value)
    {
        versionManage = value;
    }
    int getAdmin() const
    {
    return admin;
    }
    void setAdmin(int value)
    {
    admin = value;
    }
    int getWarninManage() const
    {
        return warninManage;
    }
    void setWarninManage(int value)
    {
        warninManage = value;
    }
};
#endif // PMSPLUSPARAM_H
Client/½ª¿É¸ý/code/2024kunlun_project_permisson/pmsqueryresult.h
@@ -1,10 +1,8 @@
#ifndef PMSQUERYRESULT_H
#ifndef PMSQUERYRESULT_H
#define PMSQUERYRESULT_H
#include "pmsparam.h"
class PmsQueryResult : public PmsParam{
    string startDateTime;
    string endDateTime;
    int queryHistory;
    int loggerSearch;
@@ -12,13 +10,22 @@
    int devManage;
    int productPlan;
    int warninManage;
    int versionManage; //版本管理
    int admin; //系统管理员
    int id;
    int roleId;
    string department;
    string loginTime;
    string registerTime;
public:
    void setStartDateTime(string time){
        this->startDateTime = time;
    void setLoginTime(string time){
        this->loginTime = time;
    }
    void setEndDateTime(string time){
        this->endDateTime = time;
    void setRegisterTime(string time){
        this->registerTime = time;
    }
    void setQueryHistory(int val){
@@ -36,16 +43,16 @@
    void setProductPlan(int val){
        this->productPlan = val;
    }
    void setRoleId(int val){
        this->roleId = val;
    void setId(int val){
        this->id = val;
    }
    string getStartDateTime(){
        return startDateTime;
    string getLoginTime(){
        return loginTime;
    }
    string getEndDateTime(){
        return endDateTime;
    string getRegisterTime(){
        return registerTime;
    }
    int getQueryHistory(){
        return queryHistory;
@@ -62,12 +69,58 @@
    int getProductPlan(){
        return productPlan;
    }
    int getRoleId(){
        return roleId;
    int getId(){
        return id;
    }
    int getVersionManage() const
    {
        return versionManage;
    }
    void setVersionManage(int value)
    {
        versionManage = value;
    }
    int getAdmin() const
    {
    return admin;
    }
    void setAdmin(int value)
    {
    admin = value;
    }
    int getWarninManage() const
    {
        return warninManage;
    }
    void setWarninManage(int value)
    {
        warninManage = value;
    }
    string getDepartment() const
    {
        return department;
    }
    void setDepartment(const string &value)
    {
        department = value;
    }
};
#endif // PMSQUERYRESULT_H
Client/½ª¿É¸ý/code/2024kunlun_project_permisson/qcomboxdelegate.cpp
@@ -16,7 +16,21 @@
{
    QComboBox * box = new QComboBox(parent);
    QStringList text;
    text << "普通采矿员工" << "技术维护人员" << "系统管理员"<< "安全管理人员";
    QString curText = qvariant_cast<QString>(index.data());
    vector<QString> vecq;
    vecq.push_back("技术维护人员");
    vecq.push_back("系统管理员");
    vecq.push_back("安全管理人员");
    vecq.push_back("普通采矿员工");
    text << curText;
    for(QString role : vecq){
        if(curText!=role){
            text << role;
        }
    }
    box->addItems(text);
    return box;
Client/½ª¿É¸ý/code/2024kunlun_project_permisson/qcomboxdelegate.h
@@ -1,12 +1,14 @@
#ifndef QCOMBOXDELEGATE_H
#ifndef QCOMBOXDELEGATE_H
#define QCOMBOXDELEGATE_H
#include <QItemDelegate>
#include <QComboBox>
#pragma execution_character_set("utf-8")
#include <vector>
using namespace std;
class QComBoxDelegate : public QItemDelegate
{
public:
    QComBoxDelegate();
    QComBoxDelegate(QObject * p=0);
Client/½ª¿É¸ý/code/2024kunlun_project_permisson/syncdatatodb.cpp
@@ -23,17 +23,17 @@
{
    string sql = "SELECT * FROM user_info AS u, employee_permisson AS e WHERE u.role_id=e.id";
    if(!param.getUserNo().empty()){
        sql += " and u.user_no='" + param.getUserNo() + "'";
    }
//    if(!param.getUserNo().empty()){
//        sql += " and u.user_no='" + param.getUserNo() + "'";
//    }
    if(!param.getName().empty()){
        sql += " and u.name='" + param.getName()+ "'";
    }
//    if(!param.getName().empty()){
//        sql += " and u.name='" + param.getName()+ "'";
//    }
    if(!param.getPermissonType().empty()){
        sql += " and e.permission_type='" + param.getPermissonType()+ "'";
    }
//    if(!param.getPermissonType().empty()){
//        sql += " and e.permission_type='" + param.getPermissonType()+ "'";
//    }
    qDebug() << "sql语句" << QString::fromStdString(sql);
@@ -56,16 +56,16 @@
    string sql = "update employee_permisson";
    // åªæ›´æ”¹èŒä½
    if(!param.getPermissonType().empty()){
        sql.append(" set permission_type='" + param.getPermissonType())+ "'";
    }else{
        sql.append(" set query_history=") + to_string(param.getQueryHistory());
        sql.append(",logger_search=") + to_string(param.getLoggerSearch());
        sql.append(",map_mark=") + to_string(param.getMapMark());
        sql.append(",dev_manage=") + to_string(param.getDevManage());
        sql.append(",product_plan=") + to_string(param.getProductPlan());
    }
    sql.append(" where e.id=" + param.getRoleId());
//    if(!param.getPermissonType().empty()){
//        sql.append(" set permission_type='" + param.getPermissonType())+ "'";
//    }else{
//        sql.append(" set query_history=") + to_string(param.getQueryHistory());
//        sql.append(",logger_search=") + to_string(param.getLoggerSearch());
//        sql.append(",map_mark=") + to_string(param.getMapMark());
//        sql.append(",dev_manage=") + to_string(param.getDevManage());
//        sql.append(",product_plan=") + to_string(param.getProductPlan());
//    }
    //sql.append(" where e.id=" + param.getRoleId());
    mysql_real_query(&mysql, sql.c_str(), sql.size());
    mysql_store_result(&mysql);
@@ -76,13 +76,13 @@
void SyncDataToDB::setPmsResult(PmsQueryResult &res, char **row)
{
    res.setName(string(row[1]));
    res.setUserNo(string(row[5]));
    res.setStartDateTime(string(row[2]));
    res.setEndDateTime(string(row[3]));
    res.setRoleId(stoi(string(row[4])));
//    res.setName(string(row[1]));
//    res.setUserNo(string(row[5]));
//    res.setStartDateTime(string(row[2]));
//    res.setEndDateTime(string(row[3]));
//    res.setRoleId(stoi(string(row[4])));
    res.setPermissonType(string(row[8]));
   // res.setPermissonType(string(row[8]));
    res.setQueryHistory(stoi(string(row[9])));
    res.setLoggerSearch(stoi(string(row[10])));
    res.setMapMark(stoi(string(row[11])));
@@ -90,5 +90,5 @@
    res.setProductPlan(stoi(string(row[13])));
    qDebug() << QString::fromStdString(res.getUserNo());
    //qDebug() << QString::fromStdString(res.getUserNo());
}
Client/½ª¿É¸ý/code/·þÎñ¶ËÒµÎñ´úÂë/PermissonManage.cpp
New file
@@ -0,0 +1,152 @@
#include "stdafx.h"
#include "PermissonManage.h"
#include <iostream>
#include "MysqlConn.h"
#include <string.h>
#include <vector>
using namespace std;
PermissonManage::PermissonManage()
{
}
PermissonManage::~PermissonManage()
{
}
bool PermissonManage::queryPmsByParam(SOCKET client, QueryPmsReq * req)
{
    // ç»„装SQL语句
    string sql = "SELECT * FROM user_info AS u, role_info AS e WHERE u.role_id=e.id";
    if (*(req->userNo)) {
        sql += " and u.user_no='" + string(req->userNo) + "'";
    }
    if (*(req->name)) {
        sql += " and u.name='" + string(req->name) + "'";
    }
    if (*(req->permissonType)) {
        sql += " and e.permission_type='" + string(req->permissonType) + "'";
    }
    cout << "sql:" << sql << endl;
    // è°ƒç”¨MySQL API æ‰§è¡ŒSQL语句,根据返回值组装响应结构体
    MysqlConn conn;
    conn.connect("127.0.0.1", "root", "root", "mydb");
    bool ret = conn.query (sql);
    vector<PmsRes> pmsTempList;
    while (conn.getResult()){
        PmsRes pmsRes;
        pmsRes.admin = stoi(conn.getField(22));
        strcpy_s(pmsRes.department, conn.getField(1).c_str());
        pmsRes.devManage = stoi(conn.getField(18));
        pmsRes.id = stoi(conn.getField(0));
        pmsRes.loggerSearch = stoi(conn.getField(16));
        strcpy_s(pmsRes.loginTime, conn.getField(11).c_str());
        pmsRes.mapMark = stoi(conn.getField(17));
        strcpy_s(pmsRes.name, conn.getField(2).c_str());
        strcpy_s(pmsRes.permissonType, conn.getField(14).c_str());
        pmsRes.productPlan = stoi(conn.getField(19));
        pmsRes.queryHistory = stoi(conn.getField(15));
        strcpy_s(pmsRes.registerTime, conn.getField(12).c_str());
        strcpy_s(pmsRes.userNo, conn.getField(4).c_str());
        pmsRes.versionManage = stoi(conn.getField(21));
        pmsRes.warningManage = stoi(conn.getField(20));
        pmsTempList.push_back(pmsRes);
        cout << "获取结果集2" <<  conn.getField(0) << conn.getField(1) << conn.getField(2);
    }
    QueryPmsRes  *res;
    int len = sizeof(QueryPmsRes) + pmsTempList.size() * sizeof(PmsRes);
    res = (QueryPmsRes *)malloc(len);
    PmsRes * pmArr = new PmsRes[pmsTempList.size()];
    for (int i = 0; i < pmsTempList.size();i++) {
        pmArr[i] = pmsTempList[i];
    }
    memcpy(res->pmsList,pmArr, pmsTempList.size() * sizeof(PmsRes));
    res->head.type = QUERY_PMS_RES;
    res->head.len = len;
    if (ret > 0) {
        res->success = 1; // æˆåŠŸ
    }
    else {
        res->success = 0; // å¤±è´¥
    }
    cout <<  "id="<< res->pmsList[0].id << endl;
    // å‘送结构体给客户端
    cout << __FUNCTION__ << send(client, (char*)res, res->head.len, 0) << endl;
    delete[] pmArr;
    delete res;
    return true;
}
bool PermissonManage::updatePms(SOCKET client, UpdatePmsReq * req)
{
    // è°ƒç”¨MySQL API æ‰§è¡ŒSQL语句,根据返回值组装响应结构体
    MysqlConn conn;
    conn.connect("127.0.0.1", "root", "root", "mydb");
    char sql[512] = { 0 };
    UpdatePmsRes res;
    if (*(req->permissonType)) {
        // å…ˆç”¨è§’色类型查一遍角色表id
        sprintf(sql, "select id from role_info where permission_type='%s'", req->permissonType);
        bool ret = conn.query(sql);
        bool retRes = conn.getResult();
        if (!ret || !retRes) {
            res.success = 0;
        }
        else {
            int roleId = stoi(conn.getField(0));
            memset(sql, 0, 512);
            sprintf(sql, "update user_info set role_id=%d where id=%d", roleId, req->id);
            ret = conn.update(sql);
            res.success = ret;
        }
    }
    else {
        // å…ˆç”¨id查一遍角色id
        sprintf(sql,"select role_id from user_info where id=%d", req->id);
        bool ret = conn.query(sql);
        bool retRes = conn.getResult();
        if (!ret || !retRes) {
            res.success = 0;
        }else {
            int roleId = stoi(conn.getField(0));
            memset(sql, 0, 512);
            sprintf(sql, "update  role_info set query_history=%d,logger_search=%d,map_mark=%d,dev_manage=%d"
                            ",product_plan=%d,warning_manage=%d,version_manage=%d,role_info.admin=%d where id=%d",req->queryHistory,req->loggerSearch,
                                req->mapMark,req->devManage,req->productPlan,req->warningManage,req->versionManage,req->admin,roleId);
            cout << "更新权限sql:" << sql << endl;
            ret = conn.update(sql);
            res.success = ret;
        }
    }
    // å‘送结构体给客户端
    cout << __FUNCTION__ << send(client, (char*)&res, res.head.len, 0) << endl;
    return true;
}
Client/½ª¿É¸ý/code/·þÎñ¶ËÒµÎñ´úÂë/PermissonManage.h
New file
@@ -0,0 +1,16 @@
#pragma once
#include "common.h"
#include <WinSock2.h>
#include <string>
using namespace std;
class PermissonManage
{
public:
    PermissonManage();
    ~PermissonManage();
    bool queryPmsByParam(SOCKET client, QueryPmsReq * req);
    bool updatePms(SOCKET client, UpdatePmsReq * req);
};
Client/½ª¿É¸ý/code/·þÎñ¶ËÒµÎñ´úÂë/ServerSocket.cpp
New file
@@ -0,0 +1,166 @@
#include "stdafx.h"
#include "ServerSocket.h"
#include "common.h"
#include "DeviceManage.h"
#include "PermissonManage.h"
#define HEART_CHECK_TIMES 60  // å¿ƒè·³æ£€æµ‹çš„æ¬¡æ•°
struct TestData
{
    int type;
    int len;
    char data[32];
};
ServerSocket::ServerSocket(bool openHeartCheck):m_openHeartCheck(openHeartCheck)
{
    if (initSocket()) {
        cout << "init socket ok" << endl;
    }
    else {
        cout << "init socket fail" << endl;
    }
}
ServerSocket::~ServerSocket()
{
    closesocket(m_server); //  å…³é—­æœåŠ¡ç«¯å¥—æŽ¥å­—
    WSACleanup(); // å…³é—­ç½‘络环境
}
bool ServerSocket::initSocket()
{
    WSAData wsa = { 0 };
    WSAStartup(MAKEWORD(2, 2), &wsa); // å¯åŠ¨ç½‘ç»œçŽ¯å¢ƒ
    // SOCK_STREAM:TCP协议
    // SOCK_DGRAM:UDP协议
    m_server = socket(AF_INET, SOCK_STREAM, 0);
    SOCKADDR_IN addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(16888);
    addr.sin_addr.S_un.S_addr = 0;
    int ret_bind = ::bind(m_server, (sockaddr*)&addr, sizeof(addr));
    if (ret_bind) {
        cout << "bind fail:" << WSAGetLastError() << endl;
        return false;
    }
    int ret_listen = listen(m_server, 5);
    if (ret_listen) {
        cout << "listen fail:" << WSAGetLastError() << endl;
        return false;
    }
    // æ­£å¸¸ï¼ŒæˆåŠŸåˆå§‹åŒ–
    // å¯åЍaccept线程
    thread accept_thread(&ServerSocket::acceptThread, this);
    accept_thread.detach(); // å‰¥ç¦»çº¿ç¨‹ï¼Œé˜²æ­¢å¼‚常结束
    // å¯åŠ¨å¿ƒè·³æ£€æµ‹çº¿ç¨‹
    thread heart_check_thread(&ServerSocket::heartCheckThread, this);
    heart_check_thread.detach();
    return true;
}
void ServerSocket::acceptThread()
{
    while (true)
    {
        SOCKADDR_IN addr;
        SOCKET client; // å½“前连接上的客户端套接字
        int len = sizeof(addr);
        cout << "wait for conn..." << endl;
        client = accept(m_server, (sockaddr*)&addr, &len);
        cout << "conn client:" << client << endl;
        if (client == SOCKET_ERROR) {
            cout << "socket error:" << WSAGetLastError() << endl;
            break;
        }
        else if (client == 0) {
            cout << "socket close:" << WSAGetLastError() << endl;
            break;
        }
        // æ­£å¸¸
            // å»ºç«‹æ–°çš„键值对
        m_clientsMap[client] = HEART_CHECK_TIMES;
        // åˆ›å»ºé•¿è¿žæŽ¥çš„线程
        thread recv_send_thread(&ServerSocket::recvAndSendThread, this, client);
        recv_send_thread.detach();
    }
}
void ServerSocket::recvAndSendThread(SOCKET client)
{
    while (true) {
        char buffer[1024] = { 0 };
        int len_recv = recv(client, buffer, sizeof(buffer), 0);
        cout << "len_recv:" << len_recv << " client:" << client << endl;
        if (len_recv <= 0) {
            cout << "client socket å·²å…³é—­æˆ–异常结束:" << WSAGetLastError() << endl;
            break;
        }
        // æ­£å¸¸
            // é‡ç½®å¿ƒè·³é˜ˆå€¼
        m_clientsMap[client] = HEART_CHECK_TIMES;
        // è§£åŒ…处理
        cout << "buffer:" << buffer << endl;
        int type = *(int*)buffer;
        if (type == 100) {
            TestData* td = (TestData*)buffer;
            cout << "收到结构体:" << td->len << " " << td->data << endl;
        }
        else if (type == AD_REQ) {
            // æ·»åŠ è®¾å¤‡
            cout << "收到添加设备请求" << endl;
            ADReq *req = (ADReq*)buffer;
            cout << "设备名称" << req->devInfo[0].deviceName << endl;
            // è°ƒç”¨ æ·»åŠ è®¾å¤‡ ä¸šåŠ¡API
            DeviceManage devMan;
            devMan.addDeviceBusiness(client, req);
        }
        else if (type == QUERY_PMS_REQ) {
            cout << "查询权限请求" << endl;
            QueryPmsReq * req = (QueryPmsReq *)buffer;
            PermissonManage pmsManage;
            pmsManage.queryPmsByParam(client, req);
        }
        else if (type == UPDATE_PMS_REQ) {
            cout << "更新权限请求" << endl;
            UpdatePmsReq * req = (UpdatePmsReq *)buffer;
            PermissonManage pmsManage;
            pmsManage.updatePms(client, req);
        }
        // åŽŸå°ä¸åŠ¨çš„å›žæ”¶åˆ°çš„å†…å®¹ç»™å¯¹åº”å®¢æˆ·ç«¯
        //send(client, buffer, len_recv, 0);
    }
    closesocket(client);
}
void ServerSocket::heartCheckThread()
{
    while (m_openHeartCheck)
    {
        // è½®è¯¢map
        for (auto iter = m_clientsMap.begin();iter != m_clientsMap.end();) {
            iter->second--; // é˜ˆå€¼é€’减
            cout << "client:" << iter->first << " é˜ˆå€¼:" << iter->second << endl;
            if (iter->second == 0) {
                // è¿žæŽ¥æ— æ•ˆäº†ï¼Œå…³é—­è¿žæŽ¥ï¼Œå†åˆ é™¤
                cout << "发现无效客户端连接:" << iter->first << endl;
                closesocket(iter->first);
                iter = m_clientsMap.erase(iter); // æŽ¥æ”¶è¿”回值,防止迭代器失效
            }
            else {
                ++iter;
            }
        }
        // é—´éš”5秒
        Sleep(5 * 1000); // ç¡çœ 5000毫秒,就是5秒
    }
}
Client/½ª¿É¸ý/code/·þÎñ¶ËÒµÎñ´úÂë/common.h
New file
@@ -0,0 +1,1064 @@
#ifndef COMMON_H
#define COMMON_H
#include <string.h>
enum TypeInfo {
    //注册登录
    LOGIN_REQ, // ç™»å½•请求
    LOGIN_RES, // ç™»å½•响应
    REGISTER_REQ, //注册请求
    REGISTER_RES, //注册响应
    RESET_REQ, //重置密码请求
    RESET_RES, //重置密码响应
    //权限管理
    QUERY_PMS_REQ,      // æŒ‰å‘˜å·¥ç¼–号、名字或职位查询人员权限信息请求
    UPDATE_PMS_REQ,     // æŒ‰è§’色id更新权限信息请求
    QUERY_PMS_RES,      // æŸ¥è¯¢äººå‘˜å’Œè§’色信息的响应结构体
    UPDATE_PMS_RES,     // æƒé™æ›´æ–°ç»“果响应体
    //设备管理
    AD_REQ,//添加设备请求
    AD_RES,//添加设备响应
    MD_REQ,//修改设备请求
    MD_RES,//修改设备响应
    QD_REQ,//查询设备请求
    QD_RES,//查询设备响应
    //地图标注
    MML_REQ,//地图标注加载请求
    MML_RES,//地图标注加载响应
    MMI_REQ,//地图标注插入请求
    MMI_RES,//地图标注插入响应
    MMD_REQ,//地图标注删除请求
    MMD_RES,//地图标注删除响应
    //大屏显示
    ENVIRONMENT_REQ,//环境数据请求
    ENVIRONMENT_RES,//环境数据响应
    DEVICESTATUS_REQ,//设备状态请求
    DEVICESTATUS_RES,//设备状态响应
    MOVEMENTRECORD_REQ,//操作日志请求
    MOVEMENTRECORD_RES,//操作日志响应
    ALARMRECORD_REQ,//警报记录请求
    ALARMRECORD_RES,//警报记录响应
    YIELD_REQ,//煤矿产量请求
    YIELD_RES,//煤矿产量响应
    //警报管理
    WARNING_REQ, // è­¦æŠ¥è¯·æ±‚
    WARNING_RES, // è­¦æŠ¥å“åº”
    //生产计划管理
    ADD_PDPLAN_REQ,//添加一条生产计划的请求结构体
    ADD_PDPLAN_RES,//添加一条生产计划的响应结构体
    DEL_PDPLAN_REQ,//删除一条生产计划的请求结构体
    DEL_PDPLAN_RES,//删除一条生产计划的响应结构体
    UPDATE_PDPLAN_REQ,//更改一条生产计划的请求结构体
    UPDATE_PDPLAN_RES,//更改一条生产计划的响应结构体
    QUERY_PDPLAN_REQ,//查询一条生产计划的请求结构体
    QUERY_PDPLAN_RES,//查询一条生产计划的响应结构体
    ADD_MONOUTPUT_REQ,//添加月产量的请求结构体
    ADD_MONOUTPUT_RES,//添加月产量的响应结构体
    DEL_MONOUTPUT_REQ,//删除月产量的请求结构体
    DEL_MONOUTPUT_RES,//删除月产量的响应结构体
    UPDATE_MONOUTPUT_REQ,//更新月产量的请求结构体
    UPDATE_MONOUTPUT_RES,//更新月产量的响应结构体
    QUERY_MONOUTPUT_REQ,//查询月产量的请求结构体
    QUERY_MONOUTPUT_RES,//查询月产量的响应结构体
    //自动升级
    VERSION_NUM_REQ,  // ç‰ˆæœ¬å·è¯·æ±‚
    VERSION_NUM_RES,   // ç‰ˆæœ¬å·å“åº”
    UPLOAD_FILE_REQ, // ä¸Šä¼ æ–‡ä»¶çš„请求
    UPLOAD_FILE_RES, // ä¸Šä¼ æ–‡ä»¶çš„响应
    VERSION_INFOENTRY_REQ,       // ç‰ˆæœ¬ä¿¡æ¯å½•入请求
    VERSION_INFOENTRY_RES,       //版本信息录入响应
    VERSION_UPDATE_REQ, // ç‰ˆæœ¬æ›´æ–°è¯·æ±‚
    VERSION_UPDATE_RES, // ç‰ˆæœ¬æ›´æ–°å“åº”
    FILE_DOWNLOADS_REQ, // ç‰ˆæœ¬æ›´æ–°æ–‡ä»¶ä¸‹è½½è¯·æ±‚
    FILE_DOWNLOADS_RES, // ç‰ˆæœ¬æ›´æ–°æ–‡ä»¶ä¸‹è½½å“åº”
    DOWNLOAD_SUCCESSFULLY_RES,       // æ›´æ–°æ–‡ä»¶ä¸‹è½½æˆåŠŸçš„å“åº”
    //日志
    LOGSEARCH_REQ,//日志查询请求
    LOGSEARCH_RES,//日志查询响应
};
struct Head {
    int type;
    int len;
};
//注册登录
//登录请求
struct LoginReq
{
    Head head;
    char userName[32];
    char password[32];
    LoginReq() {
        head.type = LOGIN_REQ;
        head.len = sizeof(LoginReq);
    }
};
struct Permission
{
    int admin;//超级管理员
    int loggerSearch; //日志查询
    int queryHistory; //历史记录
    int mapMark;//地图
    int versionManage; // ç‰ˆæœ¬ç®¡ç†
    int warning; //警报
    int devManage; //设备管理
    int productPlan;//生产计划
    char roleName[32]; // è§’色名
};
//登录响应
struct LoginRes
{
    Head head;
    char userName[32];
    int status; // ç™»å½•状态
    // ç™»å½•成功时,该账号对应的权限组合
    Permission per;
    LoginRes()
    {
        head.type = LOGIN_RES;
        head.len = sizeof(LoginRes);
    }
};
//注册请求
struct RegisterReq
{
    Head head;
    char userName[32];
    char password[32];
    char email[50];
    char capcha[10];//验证码
    char telephone[32];
    RegisterReq() {
        head.type = REGISTER_REQ;
        head.len = sizeof(RegisterReq);
    }
};
//注册响应
struct RegisterRes
{
    Head head;
    char userName[32];
    int status; // æ³¨å†ŒçŠ¶æ€
    RegisterRes()
    {
        head.type = REGISTER_RES;
        head.len = sizeof(RegisterRes);
    }
};
//重置密码请求
struct ResetReq
{
    Head head;
    char email[50];
    char capcha[10];//验证码
    char password[32];//新密码
    char confirmPassword[32];//确认密码
    ResetReq() {
        head.type = RESET_REQ;
        head.len = sizeof(ResetReq);
    }
};
//重置密码响应
struct ResetRes
{
    Head head;
    char user_name[32];
    int status; // é‡ç½®å¯†ç çŠ¶æ€
    ResetRes()
    {
        head.type = RESET_RES;
        head.len = sizeof(ResetRes);
    }
};
//权限管理
// æŒ‰å‘˜å·¥ç¼–号、名字或职位查询人员权限信息请求
typedef struct QueryPmsReq {
    Head head;
    char userNo[32];
    char name[32];
    char permissonType[32];
    QueryPmsReq() {
        head.type = QUERY_PMS_REQ;
        memset(userNo, 0, 32);
        memset(permissonType, 0, 32);
        memset(name, 0, 32);
        head.len = sizeof(QueryPmsReq);
    }
} QueryPmsReq;
// æŒ‰è§’色id更新权限信息请求
typedef struct UpdatePmsReq {
    Head head;
    // äººå‘˜è¡¨ä¸»é”®id
    int id;
    int queryHistory;
    int loggerSearch;
    int mapMark;
    int devManage;
    int productPlan;
    int warningManage;
    int versionManage; //版本管理
    int admin; //系统管理员
    char permissonType[32];
    UpdatePmsReq() {
        head.type = QUERY_PMS_RES;
        head.len = sizeof(UpdatePmsReq);
    }
} UpdatePmsReq;
// å•个人员和权限联合查询结构体
typedef struct PmsRes {
    int queryHistory;
    int loggerSearch;
    int mapMark;
    int devManage;
    int productPlan;
    int versionManage; //版本管理
    int warningManage;
    int admin; //系统管理员
    int id;
    char userNo[32];
    char name[32];
    char permissonType[32];  // è§’色类型
    char department[32];
    char loginTime[32];
    char registerTime[32];
} PmsRes;
// æŸ¥è¯¢äººå‘˜å’Œè§’色信息的响应结构体
typedef struct QueryPmsRes {
    Head head;
    int success; // 1为成功 ,0为失败
    PmsRes pmsList[0];
    QueryPmsRes() {
        head.type = QUERY_PMS_REQ;
    }
} QueryPmsRes;
// æƒé™æ›´æ–°ç»“果响应体
struct UpdatePmsRes {
    Head head;
    int success; // 1为成功 ,0为失败
    UpdatePmsRes() {
        head.type = UPDATE_PMS_RES;
        head.len = sizeof(UpdatePmsRes);
    }
};
//设备管理
struct DevicesInfo
{
    char deviceName[32];//设备名称
    char deviceStatus[32];//设备状态
    char area[32]; // åœ°åŒº
    double longitude;//经度
    double latitude;//纬度
    char purchasingTime[15];//购买时间
    char installTime[15];//安装时间
    char manufacturer[100];//厂家
    char devicesSerialNumber[32];//设备编码
    char devicesType[32];//设备类型
};
//添加设备
struct ADReq//添加请求
{
    Head head;
    DevicesInfo devInfo[0];
    ADReq() {
        head.type = AD_REQ;
        head.len = sizeof(ADReq);
    }
};
struct ADRes//添加响应
{
    Head head;
    int status;
    ADRes() {
        head.type = AD_RES;
        head.len = sizeof(ADRes);
    }
};
//修改设备
struct MDRes//修改响应
{
    Head head;
    DevicesInfo info;
    MDRes() {
        head.type = MD_RES;
        head.len = sizeof(MDRes);
    }
};
struct MDReq//修改请求
{
    Head head;
    int type;
    MDReq() {
        head.type = MD_REQ;
        head.len = sizeof(MDReq);
    }
};
//查询设备
struct QDReq//查询请求
{
    Head head;
    DevicesInfo info;
    QDReq() {
        head.type = QD_REQ;
        head.len = sizeof(QDReq);
    }
};
struct QDRes//查询响应
{
    Head head;
    int type;
    QDRes() {
        head.type = QD_RES;
        head.len = sizeof(QDRes);
    }
};
//地图标注
struct MarkInfo
{
    int markId;//标注点id
    double latitude;//纬度
    double longitude;//经度
    int deviceId;//设备ID
    int deviceStatus;//设备状态
    char deviceName[32];//设备名称
};
//地图标注加载请求
struct MMLReq//地图
{
    Head head;
    MMLReq() {
        head.type = MML_REQ;
        head.len = sizeof(MMLReq);
    }
};
//地图标注加载响应:
struct MMLRes
{
    Head head;
    int status;//操作状态
    MarkInfo info[0];
    MMLRes() {
        head.type = MML_RES;
        head.len = sizeof(MMLRes);
    }
};
//地图标注插入请求
struct MMIReq//地图
{
    Head head;
    MarkInfo info[0];
    MMIReq() {
        head.type = MMI_REQ;
        head.len = sizeof(MMIReq);
    }
};
//地图标注插入响应:
struct MMIRes
{
    Head head;
    int status;//操作状态
    MarkInfo info[0];
    MMIRes() {
        head.type = MMI_RES;
        head.len = sizeof(MMIRes);
    }
};
//地图标注删除请求
struct MMDReq//地图
{
    Head head;
    MarkInfo info[0];
    MMDReq() {
        head.type = MMD_REQ;
        head.len = sizeof(MMDReq);
    }
};
//地图标注删除响应:
struct MMDRes
{
    Head head;
    int status;//操作状态
    MarkInfo info[0];
    MMDRes() {
        head.type = MMD_RES;
        head.len = sizeof(MMDRes);
    }
};
//大屏显示
//环境数据请求
struct EnvironmentReq
{
    Head head;
    EnvironmentReq() {
        head.type = ENVIRONMENT_REQ;
        head.len = sizeof(EnvironmentReq);
    }
};
//环境数据响应
struct Environment
{
    double longitude;//经度
    double latitude;//纬度
    float temp;//温度
    float humidity;//湿度
    float oxygen;//氧气浓度
    float carbon;//一氧化碳浓度
};
struct EnvironmentRes
{
    Head head;
    int status;
    Environment environment[0];
    EnvironmentRes() {
        head.type = ENVIRONMENT_RES;
        head.len = sizeof(EnvironmentRes);
    }
};
//设备状态请求
struct DeviceStatusReq
{
    Head head;
    DeviceStatusReq() {
        head.type = DEVICESTATUS_REQ;
        head.len = sizeof(DeviceStatusReq);
    }
};
//设备状态响应
struct DeviceStatus
{
    double longitude;//经度
    double latitude;//纬度
    int deviceID;//设备编号
    char deviceName[32];//设备名称
    char deviceStatus[32];//设备状态
};
struct DeviceStatusRes
{
    Head head;
    int status;
    DeviceStatus deviceStatus[0];
    DeviceStatusRes() {
        head.type = DEVICESTATUS_RES;
        head.len = sizeof(DeviceStatusRes);
    }
};
//操作日志请求
struct MovementRecordReq
{
    Head head;
    MovementRecordReq() {
        head.type = MOVEMENTRECORD_REQ;
        head.len = sizeof(MovementRecordReq);
    }
};
//操作日志响应
struct MovementRecord
{
    double longitude;//经度
    double latitude;//纬度
    char userName;//操作用户名
    char operateTime[32];//操作时间
    char deviceName[32];//操作设备
    char movement[256];//操作描述
};
struct MovementRecordRes
{
    Head head;
    int status;
    MovementRecord movementRecord[0];
    MovementRecordRes() {
        head.type = MOVEMENTRECORD_RES;
        head.len = sizeof(MovementRecordRes);
    }
};
//警报记录请求
struct AlarmRecordReq
{
    Head head;
    AlarmRecordReq() {
        head.type = ALARMRECORD_REQ;
        head.len = sizeof(AlarmRecordReq);
    }
};
//警报记录响应
struct AlarmRecord
{
    double longitude;//经度
    double latitude;//纬度
    char alarmTime[32];//警报时间
    char alarmtype[32];//处理时间
    char alarmContent[256];//警报内容
};
struct AlarmRecordRes
{
    Head head;
    int status;
    AlarmRecord alarmRecord[0];
    AlarmRecordRes() {
        head.type = ALARMRECORD_RES;
        head.len = sizeof(AlarmRecordRes);
    }
};
//煤矿产量请求
struct YieldReq
{
    Head head;
    YieldReq() {
        head.type = YIELD_REQ;
        head.len = sizeof(YieldReq);
    }
};
//煤矿产量响应
struct Yield
{
    int month;//月份
    int output;//产量
};
struct YieldRes
{
    Head head;
    int status;
    Yield yield[0];
    YieldRes() {
        head.type = YIELD_RES;
        head.len = sizeof(YieldRes);
    }
};
//警报管理
// è­¦æŠ¥è¯·æ±‚结构体
struct WarningReq {
    Head head;
    float oxygenWarning;
    float carbonWarning;
    float tempWarning;
    float humidityWarning;
    WarningReq() {
        head.type = WARNING_REQ;
        head.len = sizeof(WarningReq);
    }
};
struct DataThreshold {
    //阈值
    float oxygenThreshold;
    float carbonThreshold;
    float tempThreshold;
    float humidityThreshold;
};
struct Data {
    float oxygen;   // æ°§æ°”浓度
    float carbon;   // ä¸€æ°§åŒ–碳浓度
    float temp;     // æ¸©åº¦
    float humidity; // æ¹¿åº¦
};
// è­¦æŠ¥å“åº”结构体
struct WarningRes {
    Head head;
    int status;         // å“åº”状态(比如 0 è¡¨ç¤ºæˆåŠŸï¼Œ1 è¡¨ç¤ºå¤±è´¥ç­‰ï¼‰
    const char* message; // å“åº”消息描述
    WarningRes(int stat, const char* msg) {
        head.type = WARNING_RES;
        head.len = sizeof(WarningRes);
        status = stat;
        message = msg;
    }
};
//生产计划管理
struct PdplanInfo
{
    int planId;//订单编号
    char planName[32];//订单名字
    char startDate[32];//起始日期
    char closingDate[32];//交付日期
    char pdName[8];//产品名
    double plannedPd;//计划生产量
    double actualPd;//实际生产量
    double progress;//生产进度
    int finishOntime;//是否按期完成
};
struct MonoutputInfo
{
    int month;//月份
    double aOutput;//a产品月产量
    double bOutput;//b产品月产量
    double cOutput;//c产品月产量
};
//添加一条生产计划的请求结构体
struct AddPdplanReq
{
    Head head;
    PdplanInfo info[0];
    AddPdplanReq() {
        head.type = ADD_PDPLAN_REQ;
        head.len = sizeof(AddPdplanReq);
    }
};
//添加一条生产计划的响应结构体
struct AddPdplanRes
{
    Head head;
    int status;//表示是否添加成功,0否1是
    AddPdplanRes() {
        head.type = ADD_PDPLAN_RES;
        head.len = sizeof(AddPdplanRes);
    }
};
//删除一条生产计划的请求结构体
struct DelPdplanReq
{
    Head head;
    PdplanInfo info[0];
    DelPdplanReq() {
        head.type = DEL_PDPLAN_REQ;
        head.len = sizeof(DelPdplanReq);
    }
};
//删除一条生产计划的响应结构体
struct DelPdplanRes
{
    Head head;
    int status;//表示是否删除成功,0否1是
    DelPdplanRes() {
        head.type = DEL_PDPLAN_RES;
        head.len = sizeof(DelPdplanRes);
    }
};
//更改一条生产计划的请求结构体.
struct UpdatePdplanReq
{
    Head head;
    PdplanInfo info[0];
    UpdatePdplanReq() {
        head.type = UPDATE_PDPLAN_REQ;
        head.len = sizeof(UpdatePdplanReq);
    }
};
//更改一条生产计划的响应结构体
struct UpdatePdplanRes
{
    Head head;
    int status;//表示是否更新成功,0否1是
    PdplanInfo info[0];
    UpdatePdplanRes() {
        head.type = UPDATE_PDPLAN_RES;
        head.len = sizeof(UpdatePdplanRes);
    }
};
//查询一条生产计划的请求结构体
struct QueryPdplanReq
{
    Head head;
    int planId;//订单编号
    char planName[32];//订单划名字
    char startDate[32];//起始日期
    char closingDate[32];//交付日期
    char pdName[8];//产品名
    double plannedPd;//计划生产量
    double actualPd;//实际生产量
    double progress;//生产进度
    int finishOntime;//是否按期完成
    QueryPdplanReq() {
        head.type = QUERY_PDPLAN_REQ;
        head.len = sizeof(QueryPdplanReq);
    }
};
//查询一条生产计划的响应结构体
struct QueryPdplanRes
{
    Head head;
    int status;//表示是否添加成功,0否1是
    PdplanInfo info[0];
    QueryPdplanRes() {
        head.type = QUERY_PDPLAN_RES;
        head.len = sizeof(QueryPdplanRes);
    }
};
//添加月产量的请求结构体
struct AddMonoutputReq
{
    Head head;
    MonoutputInfo info[0];
    AddMonoutputReq() {
        head.type = ADD_MONOUTPUT_REQ;
        head.len = sizeof(AddMonoutputReq);
    }
};
//添加月产量的响应结构体
struct AddMonoutputRes
{
    Head head;
    int status;//表示是否添加成功,0否1是
    AddMonoutputRes() {
        head.type = ADD_MONOUTPUT_RES;
        head.len = sizeof(AddMonoutputRes);
    }
};
//删除月产量的请求结构体
struct DelMonoutputReq
{
    Head head;
    MonoutputInfo info[0];
    DelMonoutputReq() {
        head.type = DEL_MONOUTPUT_REQ;
        head.len = sizeof(DelMonoutputReq);
    }
};
//删除月产量的响应结构体
struct DelMonoutputRes
{
    Head head;
    int status;//表示是否删除成功,0否1是
    DelMonoutputRes() {
        head.type = DEL_MONOUTPUT_RES;
        head.len = sizeof(DelMonoutputRes);
    }
};
//更改月产量的请求结构体.
struct UpdateMonoutputReq
{
    Head head;
    MonoutputInfo info[0];
    UpdateMonoutputReq() {
        head.type = UPDATE_MONOUTPUT_REQ;
        head.len = sizeof(UpdateMonoutputReq);
    }
};
//更改月产量的响应结构体
struct UpdateMonoutputRes
{
    Head head;
    int status;//表示是否更新成功,0否1是
    MonoutputInfo info[0];
    UpdateMonoutputRes() {
        head.type = UPDATE_MONOUTPUT_RES;
        head.len = sizeof(UpdateMonoutputRes);
    }
};
//查询月产量的请求结构体
struct QueryMonoutputReq
{
    Head head;
    int month;//月份
    double aOutput;//a产品月产量
    double bOutput;//b产品月产量
    double cOutput;//c产品月产量
    QueryMonoutputReq() {
        head.type = QUERY_MONOUTPUT_REQ;
        head.len = sizeof(QueryMonoutputReq);
    }
};
//查询月产量的响应结构体
struct QueryMonoutputRes
{
    Head head;
    int status;//表示是否添加成功,0否1是
    MonoutputInfo info[0];
    QueryMonoutputRes() {
        head.type = QUERY_MONOUTPUT_RES;
        head.len = sizeof(QueryMonoutputRes);
    }
};
//历史查询分析
// åŽ†å²æŸ¥è¯¢è¯·æ±‚ç»“æž„ä½“
struct HistoryQueryReq {
    Head head;
    //根据时间范围查询
    char startTime[32];
    char endTime[32];
    //关键字查询
    char keyWord[32];
    HistoryQueryReq() {
        // åˆå§‹åŒ–数据头
        head.type = QUERY_MONOUTPUT_REQ;
        head.len = sizeof(HistoryQueryReq);
        // åˆå§‹åŒ–查询条件字段
        memset(startTime, 0, sizeof(startTime));
        memset(endTime, 0, sizeof(endTime));
    }
};
// åŽ†å²æŸ¥è¯¢å“åº”ç»“æž„ä½“
// ç³»ç»Ÿè¿è¡ŒçŠ¶æ€è¡¨ç›¸å…³ä¿¡æ¯
struct HistroyInfo {
    WarningRes warn;//警报查询
    QDRes dev;//设备查询
    QueryPdplanRes  pro;//生产计划查询
};
struct HistoryQueryRes {
    Head head;
    //HistroyInfo sys[0];
    HistoryQueryRes() {
        // åˆå§‹åŒ–数据头
        head.type = QUERY_MONOUTPUT_RES;
        head.len = sizeof(HistoryQueryRes);
    }
};
//自动升级
struct VersionNumReq        // ç‰ˆæœ¬å·è¯·æ±‚
{
    Head head;
    VersionNumReq() {
        head.type = VERSION_NUM_REQ;
        head.len = sizeof(VersionNumReq);
    }
};
struct VersionNumRes        // ç‰ˆæœ¬å·å“åº”
{
    Head head;
    char versionId[64]; // ç‰ˆæœ¬å·
    VersionNumRes() {
        head.type = VERSION_NUM_RES;
        head.len = sizeof(VersionNumRes);
    }
};
// æ–‡ä»¶ä¼ è¾“
struct FileInfo
{
    char fileName[256];
    long long fileSize;
    char s_filepath[128];
    char content[0];
};
struct UploadFileReq        // ä¸Šä¼ æ–‡ä»¶çš„请求
{
    Head head;
    FileInfo fileInfo;
    UploadFileReq() {
        head.type = UPLOAD_FILE_REQ;
        head.len = sizeof(UploadFileReq);
    }
};
struct UploadFileRes {      // ä¸Šä¼ æ–‡ä»¶çš„响应
    Head head;
    bool state = false;
    char fileName[256];
    long long file_size;
    UploadFileRes()
    {
        head.type = UPLOAD_FILE_RES;
        head.len = sizeof(UploadFileRes);
    }
};
// ç‰ˆæœ¬ä¿¡æ¯å½•å…¥
// è¯·æ±‚
struct VersionInfoEntryReq {
    Head head;
    char versionId[64]; // ç‰ˆæœ¬å·
    char versionIdOld[64]; // ä¸Šä¸€ä¸ªç‰ˆæœ¬å·
    int fileNum;
    char context[0];        //包含下载文件信息
    VersionInfoEntryReq()
    {
        head.type = VERSION_INFOENTRY_REQ;
        head.len = sizeof(VersionInfoEntryReq);
    }
};
// ç‰ˆæœ¬ä¿¡æ¯å½•入响应
struct VersionInfoEntryRes {
    Head head;
    bool state = false;
    VersionInfoEntryRes()
    {
        head.type = VERSION_INFOENTRY_RES;
        head.len = sizeof(VersionInfoEntryRes);
    }
};
// ç‰ˆæœ¬æ›´æ–°è¯·æ±‚
struct VersionUpdateReq {
    Head head;
    char curVersionId[64]; // ç‰ˆæœ¬å·
    VersionUpdateReq()
    {
        head.type = VERSION_UPDATE_REQ;
        head.len = sizeof(VersionUpdateReq);
    }
};
// ç‰ˆæœ¬æ›´æ–°å“åº”
struct VersionUpdateRes {
    Head head;
    bool state = false;
    char versionId[64]; // ç‰ˆæœ¬å·
    char updateDate[32]; // æ›´æ–°æ—¶é—´
    char versionDescription[1024]; //更新描述
    VersionUpdateRes()
    {
        head.type = VERSION_UPDATE_RES;
        head.len = sizeof(VersionUpdateRes);
    }
};
// ç‰ˆæœ¬æ›´æ–°æ–‡ä»¶ä¸‹è½½è¯·æ±‚
struct FileDownloadsReq {
    Head head;
    char versionId[64]; // ç‰ˆæœ¬å·
    FileDownloadsReq()
    {
        head.type = FILE_DOWNLOADS_REQ;
        head.len = sizeof(FileDownloadsReq);
    }
};
// ç‰ˆæœ¬æ›´æ–°æ–‡ä»¶ä¸‹è½½å“åº”
struct FileDownloadsRes {
    Head head;
    char versionId[64]; // ç‰ˆæœ¬å·
    char filename[128]; //文件名
    long long filesize; //文件大小
    char c_filepath[128];    //客户端放最新版本的本地路径
    int fileNum; // æ–‡ä»¶æ•°é‡
    long long allFileSize; // æ–‡ä»¶æ€»å¤§å°
    char content[0];
    FileDownloadsRes()
    {
        head.type = FILE_DOWNLOADS_RES;
        head.len = sizeof(FileDownloadsRes);
    }
};
// æ›´æ–°æ–‡ä»¶ä¸‹è½½æˆåŠŸçš„å“åº”
struct DownloadSuccessfullyRes {
    Head head;
    bool state = false;
    char fileName[256];
    long long fileSize;
    DownloadSuccessfullyRes()
    {
        head.type = DOWNLOAD_SUCCESSFULLY_RES;
        head.len = sizeof(DownloadSuccessfullyRes);
    }
};
//日志
struct ParsedLog {
    char timeStamp[64]; // æ—¶é—´æˆ³
    char deviceId[64]; // è®¾å¤‡ID
    char level[16];    // æ—¥å¿—级别
    char content[256];  // æ—¥å¿—内容
    char userId[64];    // ç”¨æˆ·ID
    char fileName[32];   //文件名
    char functionName[32];  //函数名
    int problemLine;    //产生错误行号
};
// æ—¥å¿—查询请求结构体
// æ—¥å¿—查询请求结构体
struct LogQueryReq {
    Head head;                      // æ•°æ®å¤´
    char timeStamp[64];             // æ—¶é—´æˆ³
    char content[256];           // æ—¥å¿—内容
    char level[16];                 //日志级别
    char deviceId[64];             // è®¾å¤‡ID
    // æ— å‚构造函数
    LogQueryReq() {
        head.type = LOGSEARCH_REQ;
        head.len = sizeof(LogQueryReq);
    }
};
// æ—¥å¿—查询响应结构体
struct LogQueryRes {
    Head head;
    int status;                    // å“åº”状态 (如 0 è¡¨ç¤ºæˆåŠŸï¼Œéž 0 è¡¨ç¤ºå¤±è´¥)
    char errorMessage[256];        // é”™è¯¯ä¿¡æ¯ï¼ˆå¦‚果有)
    // æ— å‚构造函数
    LogQueryRes() {
        head.type = LOGSEARCH_RES;
        head.len = sizeof(LogQueryRes);
    }
};
#endif // COMMON_H
Client/½ª¿É¸ý/document/ȨÏÞ¹ÜÀíÐèÇó·ÖÎö.docx
Binary files differ
Client/½ª¿É¸ý/log/½ª¿É¸ý_1106.doc
Binary files differ
Client/Ö캽/log/Ö캽1104.doc
Binary files differ
Client/ÀîÏüÔö/log/ÀúÊ·²éѯ_ÀîÏüÔö_1102.doc
Binary files differ
Client/ÉêŸ@/log/ÈÕÖ¾_ÉêŸ@_1105.doc
Binary files differ
Client/ÀèºëÁØ/log/É豸¹ÜÀí_ÀèºëÁØ_1105.doc
Binary files differ
Client/ÀèºëÁØ/log/É豸¹ÜÀí_ÀèºëÁØ_1106.doc
Binary files differ
Client/¹¨ÆôÏé/log/ÈÕ־ģ°å_¹¨ÆôÏé_1105.doc
Binary files differ
Server/Àîתת/log/ÅäÖùÜÀí_Àîתת_1106.doc
Binary files differ
Server/ÍõçûÔª/code/ConnectionPool.cpp
@@ -1,95 +1,102 @@
#include "stdafx.h"
#include "ConnectionPool.h"
ConnectionPool::ConnectionPool()
{
    if (!parseXmlFile())
#include <fstream>
#include <iostream>
#include <thread>
ConnectionPool* ConnectionPool::getInstance() {
    static ConnectionPool connPool;
    return &connPool;
}
ConnectionPool::ConnectionPool() {
    // åŠ è½½é…ç½®æ–‡ä»¶
    if (!parseJsonFile()) {
        std::cout << "parseJsonFile is failed!" << std::endl;
        return;
    for (m_num = 0; m_num < m_minSize;) {
        bool flag = addConnection();
        if (!flag) {
            return;
        }
    }
    // å¦‚果子线程的任务函数是类的非静态函数,我们需要指定任务函数的地址和任务函数的所有者
    thread producer(&ConnectionPool::productConnection, this); // åˆ›å»ºè¿žæŽ¥
    thread recycler(&ConnectionPool::recycleConnection, this); // æ£€æµ‹å¹¶é”€æ¯è¿žæŽ¥
                                                               // çº¿ç¨‹åˆ†ç¦»ï¼Œé˜²æ­¢é˜»å¡žä¸»çº¿ç¨‹
    for ( int i = 0 ; i < m_min_conn ; i++ ) {
        addConnection( );
    }
    // åˆ›å»ºä¸€ä¸ªçº¿ç¨‹ï¼Œå¯¹è¿žæŽ¥æ•°è¿›è¡Œç›‘控 ï¼Œè¿žæŽ¥æ•°ä¸è¶³å°±å†ç»§ç»­åˆ›å»º
    std::thread producer(&ConnectionPool::produce, this);
    // å¯¹è¿žæŽ¥æ•°è¿›è¡Œç›‘控 ï¼Œå¦‚果有太多空闲得线程 ï¼Œé‚£ä¹ˆå°±å¯¹å…¶è¿›è¡Œé”€æ¯
    std::thread recycler( &ConnectionPool::recycle,  this);
    // çº¿ç¨‹åˆ†ç¦»
    producer.detach();
    recycler.detach();
}
ConnectionPool::~ConnectionPool()
{
    while (!m_connections.empty()) {
        MysqlConn* conn = m_connections.front();
        m_connections.pop();
        delete conn;
    }
}
bool ConnectionPool::parseXmlFile()
{
    TiXmlDocument xml("mysql.xml");
    // åŠ è½½æ–‡ä»¶
    bool res = xml.LoadFile();
    if (!res) {
        return false; // æç¤º
    }
    // æ ¹
    TiXmlElement* rootElement = xml.RootElement();
    TiXmlElement* childElement = rootElement->FirstChildElement("mysql");
    // è¯»å–信息
    m_ip = childElement->FirstChildElement("ip")->GetText();
    m_port = static_cast<unsigned short>(stoi(string(childElement->FirstChildElement("port")->GetText())));
    m_user = childElement->FirstChildElement("username")->GetText();
    m_passwd = childElement->FirstChildElement("password")->GetText();
    m_dbName = childElement->FirstChildElement("dbName")->GetText();
    m_minSize = static_cast<int>(stoi(string(childElement->FirstChildElement("minSize")->GetText())));
    m_maxSize = static_cast<int>(stoi(string(childElement->FirstChildElement("maxSize")->GetText())));
    m_maxIdleTime = static_cast<int>(stoi(string(childElement->FirstChildElement("maxIdleTime")->GetText())));
    m_timeout = static_cast<int>(stoi(string(childElement->FirstChildElement("timeout")->GetText())));
    return true;
}
bool ConnectionPool::addConnection()
{
    MysqlConn* conn = new MysqlConn;
    bool res = conn->connect(m_user, m_passwd, m_dbName, m_ip, m_port);
    if (res) {
        // åˆ·æ–°ç©ºé—²æ—¶é—´
        conn->refreashAliveTime();
        m_connections.push(conn);
        ++m_num;
bool ConnectionPool::parseJsonFile() {
    /*std::ifstream ifs("dbconf.json");
    Reader rd;
    Value root;
    rd.parse(ifs, root);
    if ( root.isObject( ) ) {
        m_ip = root["ip"].asString();
        m_port = root["port"].asInt();
        m_userName = root["userName"].asString();
        m_passwd = root["password"].asString();
        m_db = root["dbName"].asString();
        m_min_conn = root["minSize"].asInt();
        m_max_conn = root["maxSize"].asInt();
        max_del_time = root["maxDleTime"].asInt();
        m_timeout = root["timeout"].asInt();
        return true;
    }*/
    return false;
}
void ConnectionPool::description() {
    std::cout << m_ip << ". " << m_userName << ". " << m_passwd << ". " << m_db << ". "
               << m_port << ". " << m_max_conn << ". " << m_min_conn << ". " << m_timeout << ". "
               << max_del_time << std::endl;
}
ConnectionPool::~ConnectionPool() {
    while (!m_connkQueue.empty()) {
        MysqlConn* conn = m_connkQueue.front();
        m_connkQueue.pop();
        delete  conn;
    }
    else {
}
void ConnectionPool::addConnection() {
    MysqlConn* conn = new MysqlConn();
    if ( !conn->connect( m_ip, m_userName, m_passwd, m_db, m_port  ) ) {
        std::cout << "ConnectionPool connect to mysql is failed!" << std::endl;
        delete conn;
        return false; // æç¤º
        return;
    }
    conn->refreshActiveTime( );
    m_connkQueue.push(conn);
    m_cond.notify_one();   // å”¤é†’一个线程
}
void ConnectionPool::productConnection()
{
void ConnectionPool::produce(){
    while (true) {
        unique_lock<mutex> lc(m_mutex);
        m_cond.wait(lc, [this]() {return m_connections.empty(); });
        if (m_num < m_maxSize) {
            bool flag = addConnection();
            if (!flag) {
                return;
            }
        std::unique_lock<std::mutex> lock(m_mutex);
        while (m_connkQueue.size() >= m_min_conn) { // è¿žæŽ¥é˜Ÿåˆ—的数量大于最小的连接数
            m_cond.wait(lock);
        }
        // å”¤é†’
        m_cond1.notify_all();
        addConnection();
    }
}
void ConnectionPool::recycleConnection()
{
    while (true) {
        // ä¼‘眠一段时间 0.5s
        this_thread::sleep_for(milliseconds(500));
        lock_guard<mutex> lc(m_mutex);
        while (!m_connections.empty() && m_num > m_minSize) {
            MysqlConn* conn = m_connections.front();
            if (conn->getAliveTime() >= m_maxIdleTime) {
                m_connections.pop();
// åˆ é™¤ç©ºé—²è¿žæŽ¥
void ConnectionPool::recycle() {
    while ( true ) {
        std::this_thread::sleep_for( std::chrono::milliseconds(500));   // ä¼‘眠500 ms
        std::unique_lock<std::mutex>lock(m_mutex);
        while ( m_connkQueue.size() > m_min_conn ) {
            MysqlConn* conn = m_connkQueue.front( );
            if (conn->getActiveTime() >= max_del_time) {
                m_connkQueue.pop();
                delete conn;
                --m_num;
            }
            else {
                break;
@@ -97,35 +104,22 @@
        }
    }
}
ConnectionPool* ConnectionPool::getConnectPool()
{
    // ä¸ä½¿ç”¨äº’斥锁的线程安全的懒汉模式
    static ConnectionPool pool; // åªåœ¨ç¬¬ä¸€æ¬¡è°ƒç”¨å‡½æ•°æ—¶åˆå§‹åŒ–
    return &pool;
}
shared_ptr<MysqlConn> ConnectionPool::getConnection()
{
    unique_lock<mutex> lc(m_mutex);
    while (m_connections.empty()) {
        if (cv_status::timeout == m_cond1.wait_for(lc, chrono::milliseconds(m_timeout))) {
            if (m_connections.empty()) {
                // cout << "out of time" << endl;
                return nullptr; // ç»“束  // æç¤º
                                // continue; // åˆ©ç”¨while配合continue ç»§ç»­é˜»å¡ž
            }
std::shared_ptr<MysqlConn>  ConnectionPool::getMysqlConn() {
    std::unique_lock<std::mutex>lock(m_mutex);
    while ( m_connkQueue.empty()) {
        // å¦‚果等待一段时间后,队列还是为空,返回一个 null
        if ( std::cv_status::timeout == m_cond.wait_for(lock, std::chrono::milliseconds(m_timeout)) ) {
            if( m_connkQueue.empty( ) )    return nullptr;
        }
    }
    // è¦æŒ‡å®šåˆ é™¤å™¨destructor,来保证连接的归还
    shared_ptr<MysqlConn> conn(m_connections.front(), [this](MysqlConn* conn) {
        // åŠ é”ä¿è¯é˜Ÿåˆ—çº¿ç¨‹å®‰å…¨
        // m_mutex.lock(); // 1
        unique_lock<mutex> lc(m_mutex); // 2
        // lock_guard<mutex> lc(m_mutex); // 3
        conn->refreashAliveTime();
        m_connections.push(conn);
        // m_mutex.unlock(); // 1
    std::shared_ptr<MysqlConn> connPtr(std::move(m_connkQueue.front()), [this](MysqlConn* conn) {
        std::unique_lock <std::mutex>lock(m_mutex) ;
        conn->refreshActiveTime();
        m_connkQueue.push(conn);
        });
    m_connections.pop();
    m_cond.notify_all();
    return conn;
}
    m_connkQueue.pop();
    m_cond.notify_one();   // å”¤é†’阻塞的生产者线程,开始生产
    return connPtr;
}
Server/ÍõçûÔª/code/ConnectionPool.h
@@ -1,54 +1,50 @@
#pragma once
#include "MysqlConn.h"
#include "./tinyxml/tinyxml.h"
#include <queue>
#include <mutex>
#include <thread>
#include <atomic>
#include <condition_variable>
//#include <json/json.h>
#include "MysqlConn.h"
#pragma comment(lib, "./tinyxml/x64/Debug/tinyxml.lib")
//using namespace Json;
// åº”用-单例模式:懒汉模式[需要考虑多线程安全问题]
class ConnectionPool
{
private:
    ConnectionPool();
    // ç§»åŠ¨æ‹·è´æœ€ç»ˆè¿˜æ˜¯æœ‰ä¸”ä»…æœ‰ä¸€ä¸ªå¯¹è±¡ï¼Œæ‰€ä»¥ä¾æ—§æ˜¯å±žäºŽå•ä¾‹æ¨¡å¼ã€‚
    // delete é˜»æ­¢æ‹·è´æž„造和拷贝赋值的类对象生成
    ConnectionPool(ConnectionPool&) = delete;
    ConnectionPool& operator=(ConnectionPool&) = delete;
    ~ConnectionPool();
    // è§£æžxml配置文件 è¯»å–数据库及连接池的相关信息
    bool parseXmlFile();
    // æ·»åŠ è¿žæŽ¥
    bool addConnection();
    // çº¿ç¨‹å‡½æ•°
    void productConnection();
    void recycleConnection();
    // å­˜æ”¾æ•°æ®åº“连接池建立的连接
    queue<MysqlConn*>    m_connections;
    // ä¸€äº›åŸºæœ¬ä¿¡æ¯
    string                m_ip;            // IP
    unsigned short        m_port;            // ç«¯å£
    string                m_user;            // ç”¨æˆ·å
    string                m_passwd;        // å¯†ç 
    string                m_dbName;        // æ•°æ®åº“名称
    int                    m_minSize;        // åˆå§‹è¿žæŽ¥é‡(最小连接量)
    int                    m_maxSize;        // æœ€å¤§è¿žæŽ¥é‡
    int                    m_timeout;        // è¶…æ—¶æ—¶é•¿
    int                    m_maxIdleTime;    // æœ€å¤§ç©ºé—²æ—¶é•¿
                                        // çº¿ç¨‹å®‰å…¨ç›¸å…³
    mutex                m_mutex;
    condition_variable    m_cond;            // ä»…用一个条件变量来唤醒线程,但并不影响线程运行
    condition_variable  m_cond1;
    // è¿žæŽ¥æ•°é‡
    atomic_int            m_num;            // è¿žæŽ¥çš„æ€»æ•°é‡
public:
    // èŽ·å–å•ä¾‹å¯¹è±¡çš„æŽ¥å£
    static ConnectionPool* getConnectPool();
    // ç”¨æˆ·èŽ·å–è¿žæŽ¥çš„æŽ¥å£, å¦‚果获取失败,会返回nullptr
    shared_ptr<MysqlConn> getConnection();
    static ConnectionPool* getInstance( );
    std::shared_ptr<MysqlConn>  getMysqlConn();    // ä»Žæ•°æ®åº“连接池获取连接
    ConnectionPool(const ConnectionPool& other) = delete;
    ConnectionPool& operator = (const ConnectionPool & other ) = delete;
    ~ConnectionPool();
    void description();
protected:
    ConnectionPool( );   // æž„造函数
private:
    bool parseJsonFile();   // è§£æžé…ç½®
    void produce();
    void recycle();
    void addConnection();  // å¢žåŠ è¿žæŽ¥æ•°
    std::string  m_ip;
    std::string  m_userName;
    std::string  m_passwd;
    std::string  m_db;
    unsigned short m_port;
    int m_max_conn;
    int m_min_conn;
    int m_timeout;      // è¿žæŽ¥è¶…æ—¶æ—¶é—´
    int max_del_time;   // æœ€å¤§åˆ é™¤æ—¶é—´( è¿žæŽ¥ç©ºé—²æ—¶é—´è¶…过这个,就给当前连接关闭 )
    std::queue<MysqlConn*>m_connkQueue ;   // è¿žæŽ¥é˜Ÿåˆ—
    std::mutex m_mutex;  // äº’斥锁
    std::condition_variable m_cond;   // æ¡ä»¶å˜é‡
};
Server/ÍõçûÔª/code/MysqlConn.cpp
@@ -1,174 +1,144 @@
#include "stdafx.h"
#include "MysqlConn.h"
#include <regex>
MysqlConn::MysqlConn()//初始化数据库
{
    m_result = nullptr;
    m_mysqlRow = nullptr;
    // ä¼ å…¥nullptr空指针时,会自动分配一个MYSQL对象
    m_conn = mysql_init(nullptr);
}
MysqlConn::~MysqlConn()//释放数据库连接
{
    freeRes(); // é‡Šæ”¾ç»“果集
    if (m_conn != nullptr) {
        mysql_close(m_conn);
        m_conn = nullptr;
    }
}
void MysqlConn::freeRes()//结果集释放
{
    if (m_result) {
        mysql_free_result(m_result);
        m_result = nullptr;
    }
}
bool MysqlConn::connect(const string user, const string passwd, \
    const string dbName, string ip, \
    const unsigned short port)//连接数据库
{
    MYSQL* res = mysql_real_connect(m_conn, ip.c_str(), user.c_str(), \
        passwd.c_str(), dbName.c_str(), port, nullptr, 0);
    // ä¿®æ”¹ç¼–码
    mysql_set_character_set(m_conn, "gb2312");
    return res != nullptr;
}
bool MysqlConn::update(const string sql) const
{
    // æ‰§è¡ŒæˆåŠŸè¿”å›ž0;
    int res = mysql_real_query(m_conn, sql.c_str(), static_cast<unsigned int>(sql.size()));
    if (res != 0) {
        return false; // æç¤º
    }
    return true;
}
bool MysqlConn::query(const string sql)
{
    freeRes();
    int res = mysql_real_query(m_conn, sql.c_str(), static_cast<unsigned int>(sql.size()));
    if (res != 0) {
        return false; // æç¤º
    }
    m_result = mysql_store_result(m_conn);
    return true;
}
bool MysqlConn::getRes()
{
    if (m_result != nullptr) {
        // char** èŽ·å–å•è¡Œè®°å½•
        m_mysqlRow = mysql_fetch_row(m_result);
        if (m_mysqlRow != nullptr) {
            return true;
        }
        freeRes();
    }
    return false;
}
string MysqlConn::getValue(const int fieldIndex) const
{
    int fieldCount = mysql_num_fields(m_result);
    if (fieldIndex >= fieldCount || fieldIndex < 0) {
        return string(); // æç¤º
    }
    char* value = m_mysqlRow[fieldIndex];
    // å¾—到一个保存各字段值长度的数组
    unsigned long* len = mysql_fetch_lengths(m_result);
    unsigned long length = len[fieldIndex];
    // é˜²æ­¢ç»“果中存在\0导致数据丢失
    return string(value, length);
}
bool MysqlConn::selectDB(const string dbName) const
{
    int res = mysql_select_db(m_conn, dbName.c_str());
    if (res != 0) {
        return false;  // æç¤º
    }
    return true;
}
void MysqlConn::backupCurrentDB(const string path)
{
    string sql = "show tables";
    int r = mysql_real_query(m_conn, sql.c_str(), static_cast<unsigned long>(sql.size()));
    if (r != 0) {
        return; // æç¤º
    }
    MYSQL_RES* tableRes = mysql_store_result(m_conn);
    for (int i = 0; i < mysql_num_rows(tableRes); ++i) {
        MYSQL_ROW tableName = mysql_fetch_row(tableRes);
        backupCurrentTable(path, tableName[0]);
    }
}
void MysqlConn::backupCurrentTable(const string path, const string tableName)
{
    string file = path + tableName + ".sql";
    ofstream ofs(file);
    if (!ofs.is_open()) {
        return; // æç¤º
    }
    // è¡¨ç»“构写入
    string showCreate = "show create table " + tableName + ";";
    bool res = query(showCreate);
    if (!res) {
        return; // æç¤º
    }
    if (getRes()) {
        string writeSQL = getValue(1) + ";\n";
        ofs.write(writeSQL.c_str(), writeSQL.size());
        // cout << writeSQL << endl;
    }
    // è¡¨æ•°æ®å†™å…¥
    string sql = "select * from " + tableName + ";";
    res = query(sql);
    if (!res) {
        return; // æç¤º
    }
    while (getRes()) {
        string writeSQL = "insert into `" + tableName + "` values(";
        for (int i = 0; !getValue(i).empty(); ++i) {
            if (i != 0) {
                writeSQL += ",";
            }
            MYSQL_FIELD* valueType = mysql_fetch_field_direct(m_result, i);
            if (valueType->type == MYSQL_TYPE_DECIMAL
                || valueType->type == MYSQL_TYPE_TINY
                || valueType->type == MYSQL_TYPE_SHORT
                || valueType->type == MYSQL_TYPE_LONG
                || valueType->type == MYSQL_TYPE_FLOAT
                || valueType->type == MYSQL_TYPE_DOUBLE
                || valueType->type == MYSQL_TYPE_TIMESTAMP
                || valueType->type == MYSQL_TYPE_LONGLONG
                || valueType->type == MYSQL_TYPE_INT24) {
                writeSQL += getValue(i);
            }
            else {
                writeSQL += "'" + getValue(i) + "'";
            }
        }
        writeSQL += ");\n";
        ofs.write(writeSQL.c_str(), writeSQL.size());
    }
    ofs.close();
}
bool MysqlConn::transaction() const
{
    // å°†äº‹åŠ¡æäº¤è®¾ç½®ä¸ºæ‰‹åŠ¨æäº¤
    return mysql_autocommit(m_conn, false);
}
bool MysqlConn::commit() const
{
    return mysql_commit(m_conn);
}
bool MysqlConn::rollback() const
{
    return mysql_rollback(m_conn);
}
void MysqlConn::refreashAliveTime()
{
    m_alivetime = steady_clock::now();
}
ll MysqlConn::getAliveTime()
{
    // æ¯«ç§’ <<= çº³ç§’:精度降低
    milliseconds res = duration_cast<milliseconds>(steady_clock::now() - m_alivetime);
    return res.count();
// åˆå§‹åŒ–连接
MysqlConn::MysqlConn() {
    mysql_ = mysql_init(mysql_);
    // è®¾ç½®å­—符集
    if (mysql_) mysql_set_character_set(mysql_, "gbk");
}
// è¿žæŽ¥æ•°æ®åº“
bool MysqlConn::connect(std::string ip, std::string userName, std::string passwd, std::string db, int port) {
    mysql_ = mysql_real_connect(mysql_, ip.c_str(), userName.c_str(), passwd.c_str(), db.c_str(), port, nullptr, 0);
    if (!mysql_) {
        return false;
    }
    return true;
}
// é‡Šæ”¾èµ„源
MysqlConn::~MysqlConn() {
    if (mysql_) {
        mysql_close(mysql_);
        mysql_ = nullptr;
    }
    freeRes();
}
// æ›´æ–°æ•°æ®
bool MysqlConn::update(std::string sql) {
    // å‚数化查询优化后的安全检查
    MYSQL_STMT* stmt = mysql_stmt_init(mysql_);
    if (!stmt) {
        return false;
    }
    if (mysql_stmt_prepare(stmt, sql.c_str(), sql.length())) {
        mysql_stmt_close(stmt);
        return false;
    }
    int paramCount = mysql_stmt_param_count(stmt);
    if (paramCount > 0) {
        // å¦‚果有参数,需要进行参数绑定等操作,这里暂不实现
        mysql_stmt_close(stmt);
        return false;
    }
    if (mysql_stmt_execute(stmt)) {
        mysql_stmt_close(stmt);
        return false;
    }
    mysql_stmt_close(stmt);
    return true;
}
// æŸ¥è¯¢æ•°æ®åº“
bool MysqlConn::query(std::string sql) {
    freeRes();
    // å‚数化查询优化后的安全检查
    MYSQL_STMT* stmt = mysql_stmt_init(mysql_);
    if (!stmt) {
        return false;
    }
    if (mysql_stmt_prepare(stmt, sql.c_str(), sql.length())) {
        mysql_stmt_close(stmt);
        return false;
    }
    int paramCount = mysql_stmt_param_count(stmt);
    if (paramCount > 0) {
        // å¦‚果有参数,需要进行参数绑定等操作,这里暂不实现
        mysql_stmt_close(stmt);
        return false;
    }
    if (mysql_stmt_execute(stmt)) {
        mysql_stmt_close(stmt);
        return false;
    }
    res_ = mysql_stmt_result_metadata(stmt);
    if (!res_) {
        mysql_stmt_close(stmt);
        return false;
    }
    mysql_stmt_close(stmt);
    return true;
}
// å¾—到结果集
bool MysqlConn::getResult() {
    if (res_) {
        row_ = mysql_fetch_row(res_);
        if (row_) return true;
    }
    return false;
}
// èŽ·å–ç»“æžœé›†çš„å­—æ®µ
std::string MysqlConn::getField(int index) {
    int cols = mysql_num_fields(res_);
    if (index >= cols || index < 0) return std::string("");
    char* value = row_[index];
    unsigned long len = mysql_fetch_lengths(res_)[index];
    return std::string(value, len);
}
// äº‹åŠ¡æ“ä½œ
bool MysqlConn::transaction() {
    return mysql_autocommit(mysql_, false);
}
// æäº¤äº‹åŠ¡
bool MysqlConn::commit() {
    return mysql_commit(mysql_);
}
// äº‹åŠ¡å›žæ»š
bool MysqlConn::rollback() {
    return mysql_rollback(mysql_);
}
void MysqlConn::refreshActiveTime() {
    activeTime_ = std::chrono::steady_clock::now();
}
long long MysqlConn::getActiveTime() {
    // çº³ç±³
    std::chrono::nanoseconds nased = std::chrono::steady_clock::now() - activeTime_;
    // è½¬æ¢æˆæ¯«ç±³
    std::chrono::microseconds millsed = std::chrono::duration_cast<std::chrono::microseconds>(nased);
    return millsed.count();   // å¤šå°‘毫秒
}
// å®‰å…¨æ ¡éªŒå®žçŽ°ï¼Œè¿™é‡Œç®€å•ä½¿ç”¨æ­£åˆ™è¡¨è¾¾å¼åˆ¤æ–­æ˜¯å¦åŒ…å«å±é™©å­—ç¬¦
bool MysqlConn::isSqlSafe(const std::string& sql) {
    std::regex dangerousPattern(".*(['\";\\-+=]).*");
    return!std::regex_search(sql, dangerousPattern);
}
void MysqlConn::freeRes() {
    if (res_) {
        mysql_free_result(res_);
        res_ = nullptr;
    }
}
Server/ÍõçûÔª/code/MysqlConn.h
@@ -1,63 +1,49 @@
#pragma once
#include<iostream>
#include <memory>
#include <string>
#include <mysql.h>
#include <chrono> // æ—¶é’Ÿ
#include <fstream>
#pragma comment(lib, "./lib/libmysql.lib") // åŠ è½½æ•°æ®åº“åº“æ–‡ä»¶
using namespace std;
using namespace chrono;
typedef long long ll;
#include <string>
#include <WinSock2.h>
//#include <mysql.h>
#include "MySQL/include/mysql.h"
#include <string.h>
#include <chrono>
#pragma comment(lib,"./MySQL/lib/libmysql.lib")
class MysqlConn
{
private:
    // ç»å¯¹æ—¶é’Ÿ
    steady_clock::time_point    m_alivetime;
    // è¿žæŽ¥
    MYSQL* m_conn;
    // æŸ¥è¯¢çš„结果集
    MYSQL_RES* m_result;
    // å•记录结果集
    MYSQL_ROW                    m_mysqlRow;
    // ç»“果集释放
    void freeRes();
    // å¯¼å‡ºæŸä¸€å¼ è¡¨ä¸­çš„æ•°æ®
    void backupCurrentTable(const string path, const string tableName);
public:
    // åˆå§‹åŒ–数据库
    // åˆå§‹åŒ–连接
    MysqlConn();
    // æ•°æ®åº“连接释放
    ~MysqlConn();
    // è¿žæŽ¥æ•°æ®åº“, éœ€æä¾›ç”¨æˆ· å¯†ç  æ•°æ®åº“名称 ip ç«¯å£
    bool connect(const string user, const string passwd, \
        const string dbName, string ip, \
        const unsigned short port = 3306U);
    // æ›´æ–°æ•°æ®åº“:增删改操作
    bool update(const string sql) const;
    // è¿žæŽ¥æ•°æ®åº“
    bool connect(std::string ip, std::string userName, std::string passwd, std::string db , int port = 3306);
    // é‡Šæ”¾èµ„源
    ~MysqlConn( );
    // æ›´æ–°æ•°æ®åº“  ( insert  update delete )
    bool update(std::string sql);
    // æŸ¥è¯¢æ•°æ®åº“
    bool query(const string sql);
    // éåŽ†æŸ¥è¯¢ç»“æžœé›†
    bool getRes();
    // èŽ·å–ç»“æžœé›†ä¸­çš„å­—æ®µå€¼
    string getValue(const int fieldIndex) const;
    // åˆ‡æ¢æ•°æ®åº“
    bool selectDB(const string dbName) const;
    // å»ºåº“
    //bool createDB(const string dbName) const;
    // å¤‡ä»½æŸä¸ªåº“
    void backupCurrentDB(const string path);
    bool query(std::string sql);
    // å¾—到结果集
    bool getResult();
    // èŽ·å–ç»“æžœé›†çš„å­—æ®µ
    std::string getField(int index);
    // äº‹åŠ¡æ“ä½œ
    bool transaction() const;
    bool transaction();
    // æäº¤äº‹åŠ¡
    bool commit() const;
    bool commit( );
    // äº‹åŠ¡å›žæ»š
    bool rollback() const;
    // åˆ·æ–°èµ·å§‹çš„空闲时间点
    void refreashAliveTime();
    // è®¡ç®—存活总时长
    ll getAliveTime();
    bool rollback();
    void refreshActiveTime( );   // åˆ·æ–°æ´»è·ƒæ—¶é—´
    long long getActiveTime();   // èŽ·å–å½“å‰æ´»è·ƒçš„æ—¶é—´é—´éš”
    // å®‰å…¨æ ¡éªŒæŽ¥å£
    bool isSqlSafe(const std::string& sql);
private:
    void freeRes();
    MYSQL* mysql_ = NULL ;
    MYSQL_RES* res_ = NULL;
    MYSQL_ROW row_ = nullptr;
    std::chrono::steady_clock::time_point  activeTime_;
};
Server/ÍõçûÔª/log/ÈÕ־ģ°å_ÍõçûÔª_1101.doc
Binary files differ
Server/ÍõçûÔª/log/ÈÕ־ģ°å_ÍõçûÔª_1103 .doc
Binary files differ
Server/ÍõçûÔª/log/ÈÕ־ģ°å_ÍõçûÔª_1104.doc
Binary files differ
Server/ÍõçûÔª/log/ÈÕ־ģ°å_ÍõçûÔª_1105.doc
Binary files differ
Server/³Â³þµ¤/log/ÈÕÖ¾_³Â³þµ¤_1105.doc
Binary files differ
Server/ÂíÓ庼/log/20241105À¥ÂØÈÕ±¨.doc
Binary files differ
Server/ÂíÓ庼/log/ÈÕÖ¾_ÂíÓ庼_20241104.doc
Binary files differ
Server/ÂíÓ庼/log/ÈÕÖ¾_ÂíÓ庼_20241105.doc
Binary files differ
common.h
@@ -90,6 +90,14 @@
    //日志
    LOGSEARCH_REQ,//日志查询请求
    LOGSEARCH_RES,//日志查询响应
    //历史查询分析
    HISTORY_DEV_REQ,        //历史查询硬件请求
    HISTORY_DEV_RES,        //历史查询硬件响应
    HISTORY_PRODUCE_REQ,    //历史查询生产请求
    HISTORY_PRODUCE_RES,    //历史查询生产响应
    HISTORY_ENV_REQ,    //历史查询环境请求
    HISTORY_ENV_RES,    //历史查询环境响应
};
@@ -276,22 +284,22 @@
//设备管理
struct DevicesInfo
{
    int deviceID;
    char deviceName[32];//设备名称
    char deviceStatus[32];//设备状态
    char area[32]; // åœ°åŒº
    double longitude;//经度
    double latitude;//纬度
    char purchasingTime[15];//购买时间
    char installTime[15];//安装时间
    char manufacturer[100];//厂家
    char devicesSerialNumber[32];//设备编码
    char devicesType[32];//设备类型
    double longitude;//经度
    double latitude;//纬度
    char purchasingTime[15];//购买时间
    char installTime[15];//安装时间
    char devicesSerialNumber[32];//设备编码
};
//添加设备
struct ADReq//添加请求
{
    Head head;
    char deviceName[32];
    DevicesInfo devInfo[0];
    ADReq() {
        head.type = AD_REQ;
        head.len = sizeof(ADReq);
@@ -302,7 +310,7 @@
struct ADRes//添加响应
{
    Head head;
    int type;
    int status;
    ADRes() {
        head.type = AD_RES;
        head.len = sizeof(ADRes);
@@ -310,22 +318,23 @@
};
//修改设备
struct MDRes//修改请求
struct MDReq//修改请求
{
    Head head;
    DevicesInfo info;
    MDRes() {
        head.type = MD_RES;
        head.len = sizeof(MDRes);
    }
};
struct MDReq//修改响应
{
    Head head;
    int type;
    MDReq() {
        head.type = MD_REQ;
        head.len = sizeof(MDReq);
    }
};
struct MDRes//修改响应
{
    Head head;
    DevicesInfo info;
    int status;
    MDRes() {
        head.type = MD_RES;
        head.len = sizeof(MDRes);
    }
};
//查询设备
@@ -341,7 +350,7 @@
struct QDRes//查询响应
{
    Head head;
    int type;
    int status;
    QDRes() {
        head.type = QD_RES;
        head.len = sizeof(QDRes);
@@ -827,40 +836,91 @@
//历史查询分析
// åŽ†å²æŸ¥è¯¢è¯·æ±‚ç»“æž„ä½“
struct HistoryQueryReq {
//历史查询分析
struct warningInfo {
    int device_id;
    char des[32];
    char time[32];
    float data;
    char type[16];
    char status[16];
};
// åŽ†å²æŸ¥è¯¢è®¾å¤‡ä¿¡æ¯è¯·æ±‚ç»“æž„ä½“
struct HistoryDevReq {
    Head head;
    //根据时间范围查询
    char startTime[32];
    char endTime[32];
    //关键字查询
    char keyWord[32];
    HistoryQueryReq() {
    HistoryDevReq() {
        // åˆå§‹åŒ–数据头
        head.type = QUERY_MONOUTPUT_REQ;
        head.len = sizeof(HistoryQueryReq);
        head.type = HISTORY_DEV_REQ;
        head.len = sizeof(HISTORY_DEV_REQ);
        // åˆå§‹åŒ–查询条件字段
        std::memset(startTime, 0, sizeof(startTime));
        std::memset(endTime, 0, sizeof(endTime));
    }
};
// åŽ†å²æŸ¥è¯¢ç”Ÿäº§è®¡åˆ’è¯·æ±‚ç»“æž„ä½“
struct HistoryProReq {
    Head head;
    //根据时间范围查询
    char startTime[32];
    char endTime[32];
    //关键字查询
    char keyWord[32];
    HistoryProReq() {
        // åˆå§‹åŒ–数据头
        head.type = HISTORY_PRODUCE_REQ;
        head.len = sizeof(HistoryProReq);
        // åˆå§‹åŒ–查询条件字段
    }
};
// åŽ†å²æŸ¥è¯¢çŽ¯å¢ƒä¿¡æ¯è¯·æ±‚ç»“æž„ä½“
struct HistoryEnvReq {
    Head head;
    //根据时间范围查询
    char startTime[32];
    char endTime[32];
    //关键字查询
    char keyWord[32];
    HistoryEnvReq() {
        // åˆå§‹åŒ–数据头
        head.type = HISTORY_ENV_REQ;
        head.len = sizeof(HistoryEnvReq);
        // åˆå§‹åŒ–查询条件字段
    }
};
// åŽ†å²æŸ¥è¯¢å“åº”ç»“æž„ä½“
// ç³»ç»Ÿè¿è¡ŒçŠ¶æ€è¡¨ç›¸å…³ä¿¡æ¯
struct HistroyInfo {
    WarningRes warn;//警报查询
    QDRes dev;//设备查询
    QueryPdplanRes  pro;//生产计划查询
};
struct HistoryQueryRes {
//查询设备信息响应结构体
struct HistoryDevRes {
    Head head;
    HistroyInfo sys[0];
    HistoryQueryRes() {
    DevicesInfo dev[0];
    HistoryDevRes() {
        // åˆå§‹åŒ–数据头
        head.type = QUERY_MONOUTPUT_RES;
        head.len = sizeof(HistoryQueryRes);
        head.type = HISTORY_DEV_RES;
        head.len = sizeof(HistoryDevRes);
    }
};
//查询生产计划响应结构体
struct HistoryProRes {
    Head head;
    PdplanInfo pro[0];
    HistoryProRes() {
        // åˆå§‹åŒ–数据头
        head.type = HISTORY_PRODUCE_RES;
        head.len = sizeof(HistoryProRes);
    }
};
//查询环境信息响应结构体
struct HistoryEnvRes {
    Head head;
    warningInfo env[0];
    HistoryEnvRes() {
        // åˆå§‹åŒ–数据头
        head.type = HISTORY_ENV_RES;
        head.len = sizeof(HistoryEnvRes);
    }
};
kunlun.sql
File was renamed from kunlun110401.sql
@@ -31,24 +31,29 @@
-- æ­£åœ¨å¯¼å‡ºè¡¨  mayi_kunlun.data_info çš„æ•°æ®ï¼š~0 rows (大约)
-- å¯¼å‡º  è¡¨ mayi_kunlun.devices_management ç»“æž„
CREATE TABLE IF NOT EXISTS `devices_management` (
  `id` int NOT NULL,
-- å¯¼å‡º  è¡¨ mayi_kunlun.devices_management_info ç»“æž„
CREATE TABLE IF NOT EXISTS `devices_management_info` (
  `id` int NOT NULL AUTO_INCREMENT,
  `devices_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL,
  `devices_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL,
  `devices_serial_number` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL,
  `devices_status` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL,
  `area` varchar(50) DEFAULT NULL,
  `longitude` double DEFAULT NULL,
  `latitude` double DEFAULT NULL,
  `purchasing_time` datetime DEFAULT NULL,
  `install_time` datetime DEFAULT NULL,
  `purchasing_time` varchar(50) DEFAULT NULL,
  `install_time` varchar(50) DEFAULT NULL,
  `manufacturer` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL,
  `mark_name` varchar(50) DEFAULT NULL,
  `mark_time` datetime DEFAULT NULL,
  `mark_time` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
-- æ­£åœ¨å¯¼å‡ºè¡¨  mayi_kunlun.devices_management çš„æ•°æ®ï¼š~0 rows (大约)
-- æ­£åœ¨å¯¼å‡ºè¡¨  mayi_kunlun.devices_management_info çš„æ•°æ®ï¼š~3 rows (大约)
INSERT INTO `devices_management_info` (`id`, `devices_name`, `devices_type`, `devices_serial_number`, `devices_status`, `area`, `longitude`, `latitude`, `purchasing_time`, `install_time`, `manufacturer`, `mark_name`, `mark_time`) VALUES
    (2, '12', '3', '2', '2', '3', 4, 6, '6', '3', '3', NULL, NULL),
    (3, '3', '1', '3', '3', '1', 2, 5, '6', '3', '6', NULL, NULL),
    (4, '10', '1', '3', '3', '1', 2, 5, '9', '3', '6', NULL, NULL);
-- å¯¼å‡º  è¡¨ mayi_kunlun.month_info ç»“æž„
CREATE TABLE IF NOT EXISTS `month_info` (
@@ -112,6 +117,16 @@
-- æ­£åœ¨å¯¼å‡ºè¡¨  mayi_kunlun.role_info çš„æ•°æ®ï¼š~0 rows (大约)
-- å¯¼å‡º  è¡¨ mayi_kunlun.student ç»“æž„
CREATE TABLE IF NOT EXISTS `student` (
  `id` int NOT NULL AUTO_INCREMENT,
  `name` varchar(50) DEFAULT NULL,
  `age` int DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
-- æ­£åœ¨å¯¼å‡ºè¡¨  mayi_kunlun.student çš„æ•°æ®ï¼š~0 rows (大约)
-- å¯¼å‡º  è¡¨ mayi_kunlun.threshold_info ç»“æž„
CREATE TABLE IF NOT EXISTS `threshold_info` (
  `id` int NOT NULL AUTO_INCREMENT,
@@ -128,19 +143,21 @@
-- å¯¼å‡º  è¡¨ mayi_kunlun.user_info ç»“æž„
CREATE TABLE IF NOT EXISTS `user_info` (
  `id` int NOT NULL AUTO_INCREMENT,
  `department` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL,
  `user_name` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL,
  `department` varchar(50) DEFAULT NULL,
  `user_name` varchar(32) DEFAULT NULL,
  `password` varchar(32) DEFAULT NULL,
  `user_no` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL,
  `user_no` varchar(10) DEFAULT NULL,
  `age` int DEFAULT NULL,
  `sex` varchar(10) DEFAULT NULL,
  `role_id` int DEFAULT NULL,
  `email` varchar(32) DEFAULT NULL,
  `telephone` varchar(32) DEFAULT NULL,
  `status` int DEFAULT NULL,
  `role_id` int DEFAULT NULL,
  `login_time` datetime DEFAULT NULL,
  `register_time` datetime DEFAULT NULL,
  PRIMARY KEY (`id`)
  PRIMARY KEY (`id`),
  KEY `role_id` (`role_id`),
  CONSTRAINT `user_info_ibfk_1` FOREIGN KEY (`role_id`) REFERENCES `role_info` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
-- æ­£åœ¨å¯¼å‡ºè¡¨  mayi_kunlun.user_info çš„æ•°æ®ï¼š~0 rows (大约)
@@ -155,13 +172,9 @@
  `c_filepath` varchar(256) NOT NULL,
  `uploader` char(64) NOT NULL DEFAULT '',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
-- æ­£åœ¨å¯¼å‡ºè¡¨  mayi_kunlun.version_file çš„æ•°æ®ï¼š~3 rows (大约)
INSERT INTO `version_file` (`id`, `version_id`, `filename`, `fliesize`, `s_filepath`, `c_filepath`, `uploader`) VALUES
    (1, '1.3', '1.jpd', 12555, './versoin', './2', ''),
    (2, '1.4', '2.jpd', 1255, './', './2', ''),
    (3, '1.5', '3.jpd', 122, './', './2', '');
-- æ­£åœ¨å¯¼å‡ºè¡¨  mayi_kunlun.version_file çš„æ•°æ®ï¼š~0 rows (大约)
-- å¯¼å‡º  è¡¨ mayi_kunlun.version_info ç»“æž„
CREATE TABLE IF NOT EXISTS `version_info` (
@@ -171,9 +184,9 @@
  `version_description` char(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '',
  `version_creatime` datetime NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
-- æ­£åœ¨å¯¼å‡ºè¡¨  mayi_kunlun.version_info çš„æ•°æ®ï¼š~3 rows (大约)
-- æ­£åœ¨å¯¼å‡ºè¡¨  mayi_kunlun.version_info çš„æ•°æ®ï¼š~2 rows (大约)
INSERT INTO `version_info` (`id`, `version_id`, `version_id_old`, `version_description`, `version_creatime`) VALUES
    (1, '1.3', '1.3', '225', '2024-10-29 15:47:00'),
    (2, '1.4', '1.4', '226', '2024-10-30 02:47:30'),
±í.docx
Binary files differ