//在这里编写相关的JS代码
变量 全局_秘钥 = "1219723580123456"; //用于aes加解密
//在每次请求页面时都必须检测 cookie的user和pwd是否正确, 第一次登录会混淆加密到数据库,后面每次去查数据库的通讯秘钥是否正确就可以
异步 定义函数 首页页面(访问信息, 整体信息) {
    局部变量 局部_解析Cookie = 同步 解析Cookie(访问信息);
    局部变量 局部_Bool = 局部_解析Cookie[0]; //如果Cookie解析出 CookieUserID、CookieSessionKey 则返回true 否则false
    如果 (局部_Bool) {
        局部变量 局部_UserID = 局部_解析Cookie[1];
        局部变量 局部_SessionKey = 局部_解析Cookie[2];
        局部变量 局部_SQL语句 = "SELECT u_UserID a1 FROM demo.f_ERP_Account where u_UserID = ? and u_SessionKey = ?";
        局部变量 局部_SQL返回 = 同步 mysql客户端.查询SQL语句_同步(局部_SQL语句, [局部_UserID, 局部_SessionKey]);
        如果 (局部_SQL返回["状态"] == "成功" && 局部_SQL返回["数据"].长度 == 1) {
            //SQL执行成功,而且返回数据1行,符合要求
            访问信息["主动发送"]({ "发送数据": 访问信息["文件数据"]["文件数据"], "数据协议": HTTP服务类.获取数据协议(访问信息["请求类型"]) });
            返回;
        }
    }
    //是在需要从这个页面跳转到另一个页面的时候使用!
    // 访问信息["主动301跳转"]({ "发送数据": "/@名称_登陆页面.lhtml", "数据协议": HTTP服务类.获取数据协议(访问信息["请求类型"]) }); //上面验证Cookie失败,返回登陆页面
    访问信息["主动301跳转"]({ "发送数据": "/login.html", "数据协议": HTTP服务类.获取数据协议(访问信息["请求类型"]) });
}
异步 定义函数 登陆页面(访问信息, 整体信息) {
    访问信息["主动发送"]({ "发送数据": 文件操作类.读入文件(文件操作类.取资源目录() + "/@名称_登陆页面.lhtml"), "数据协议": HTTP服务类.获取数据协议(访问信息["请求类型"]) });
}

//看起来函数好像很乱,实际是为了以后使用时没那么臃肿且轻便才这样封装,您也可以将所有函数合并在一起,看起来就只有极少函数.
//也可以根据快码老大教程 多建立几个筛选器,就可以知道自己的代码放哪里了,也不会乱,适合自己的才是最优的.

//获取Cookie的CookieUserID、CookieSessionKey,封装是为了方便以后拓展参数后不需要在意顺序也可以准确获取该值
异步 定义函数 解析Cookie(访问信息) {
    如果 (访问信息["cookie"].长度 >= 2) {
        局部变量 局部_UserID = "";
        局部变量 局部_SessionKey = "";
        //循环 获取 CookieUserID、CookieSessionKey
        循环 (局部变量 i = 0; i < 访问信息["cookie"].长度; i++) {
            如果 (访问信息["cookie"][i]["名称"] == "SessionKey") {
                局部_SessionKey = 访问信息["cookie"][i]["数据"];
            }
            如果 (访问信息["cookie"][i]["名称"] == "UserID") {
                局部_UserID = 访问信息["cookie"][i]["数据"];
            }
        }
        返回 [真, 局部_UserID, 局部_SessionKey]; //返回3个所需参数
    } 否则 {
        返回 假;
    }
}
//登陆页面
异步 定义函数 登陆函数(访问信息, 整体信息) {
    调试输出(1, "SetLogin", 访问信息);
    局部变量 局部_Return = "";
    调试输出(2, "SetLogin-携带表单访问", 访问信息);
    //此处获取用户提交的登陆表单数据
    局部变量 局部_User = 访问信息["表单对象"]["user"];
    局部变量 局部_Pass = 访问信息["表单对象"]["password"];
    局部变量 局部_ReturnTips = "";
    局部变量 局部_UserID = "";

    如果 (局部_User.长度 <= 0 || 局部_User.长度 > 11 || 局部_Pass.长度 <= 0 || 局部_Pass.长度 > 16) {
        局部_ReturnTips = { "User": 局部_User, "code": "404", "desc": "用户名或密码错误!" };
        访问信息["主动发送"]({ "发送数据": JSON类.到可读JSON文本(局部_ReturnTips), "数据协议": HTTP服务类.获取数据协议("json") });
        返回;
    }
    //获取USERID,如果账号和密码正确的前提下
    局部变量 局部_SQL语句 = "SELECT u_UserID a1 FROM demo.f_ERP_Account where u_Account = ? and u_PassWord = ?";
    局部变量 局部_ReturnSQL = 同步 mysql客户端.查询SQL语句_同步(局部_SQL语句, [局部_User, 局部_Pass]); /*参数化sql语句*/
    如果 (局部_ReturnSQL["状态"] == "成功" && 局部_ReturnSQL["数据"].长度 == 1) {
        //成功获取UserID
        局部_UserID = 局部_ReturnSQL["数据"][0]["a1"];
        局部变量 局部_SessionKey = 加解密本地类.AES加密(局部_User + 局部_Pass + 日期类.取时间戳2()+局部_UserID, 全局_秘钥);

        //更新登陆凭证
        局部_SQL语句 = `UPDATE demo.f_ERP_Account set u_SessionKey = ?,u_UpdateTime = now() where u_UserID = '${局部_UserID}'`;
        局部_ReturnSQL = 同步 mysql客户端.查询SQL语句_同步(局部_SQL语句, [局部_SessionKey]); 
        如果 (局部_ReturnSQL["状态"] != "成功") {
            调试输出("SetLogin-更新用户登陆凭证到mysql数据库失败!");
        }
      
        局部_ReturnTips = { "User": 局部_User, "code": "200", "desc": "登陆成功!" };
        访问信息["主动发送"]({
            "发送数据": JSON类.到可读JSON文本(局部_ReturnTips),
            "数据协议": HTTP服务类.获取数据协议("json"),
            "cookie": [
                { "名称": "SessionKey", "cookie": 局部_SessionKey },
                { "名称": "UserID", "cookie": 局部_UserID }
            ],
            "过期时间": 60 * 60 * 24 * 30
        });
    } 否则 {
        局部_ReturnTips = { "User": 局部_User, "code": "404", "desc": "用户名或密码错误!" }; //如果账号不存在也会导致查询sql失败.所以这里只管返回账号和密码错误即可
        访问信息["主动发送"]({ "发送数据": JSON类.到可读JSON文本(局部_ReturnTips), "数据协议": HTTP服务类.获取数据协议("json") });
        返回;
    }
    调试输出("SetLogin", 200, "OK");
}
//检测该SessionKey,如果可用返回true,不可用返回false
异步 定义函数 检测凭证(p_SessionKey, p_UserID) {
    调试输出(0, "检测凭证", p_SessionKey, p_UserID);
    局部变量 p_Return = "";
    如果 (p_SessionKey == 未定义内容 || p_UserID == 未定义内容) {
        p_Return = { "UserID": p_UserID, "state": "false", "code": "404", "desc": "缺少SessionKey、UserID参数!" };
        调试输出(1, "检测凭证", p_Return);
        返回 假;
    }
    局部变量 局部_SQL语句 = "SELECT u_UserID a1 FROM demo.f_ERP_Account where u_UserID = ? and u_SessionKey = ?";
    局部变量 局部_ReturnSQL = 同步 mysql客户端.查询SQL语句_同步(局部_SQL语句, [p_UserID,  p_SessionKey]);
    如果 (局部_ReturnSQL["状态"] == "成功" && 局部_ReturnSQL["数据"].长度 == 1) {
        p_Return = { "UserID": p_UserID, "state": "true", "code": "200", "desc": 局部_ReturnSQL["数据"][0]["a1"] + " 登陆成功!" };
        调试输出(2, "检测凭证", p_Return);
        返回 真;
    } 否则 {
        p_Return = { "UserID": p_UserID, "state": "false", "code": "404", "desc": "会话超时,请您重新登录!" };
        调试输出(3, "检测凭证", p_Return);
        返回 假;
    }
}
//检测菜单路径权限,如果没有权限则不允许访问该路径
异步 定义函数 检测路径权限(p_SessionKey, p_UserID, p_UrlPath) {
    调试输出(0, "检测路径权限", p_SessionKey, p_UserID, p_UrlPath);
    如果 (p_SessionKey == 未定义内容 || p_UserID == 未定义内容 || p_UrlPath == 未定义内容) {
        调试输出(1, "检测路径权限", { "UserID": p_UserID, "state": "false", "code": "404", "desc": "缺少参数,请您重新登录!" });
        返回 假;
    }
    局部变量 局部_是否可用 = 同步 检测凭证(p_SessionKey, p_UserID);
    如果 (局部_是否可用) {
        局部变量 局部_SQL语句 = "SELECT id a1 FROM demo.f_ERP_MenuControl where c_UserID = ? and c_Menu2ID = (SELECT m2_MenuID a1 FROM demo.f_ERP_MenuLv2 where m2_MenuUrl = ?) ";
        局部变量 局部_ReturnSQL = 同步 mysql客户端.查询SQL语句_同步(局部_SQL语句, [p_UserID, p_UrlPath]);
        如果 (局部_ReturnSQL["状态"] == "成功" && 局部_ReturnSQL["数据"].长度 == 1) {
            调试输出(2, "检测路径权限", { "UserID": p_UserID, "state": "true", "code": "200", "desc": p_UrlPath + " 允许访问!" });
            返回 真;
        } 否则 {
            调试输出(3, "检测路径权限", { "UserID": p_UserID, "state": "false", "code": "404", "desc": p_UrlPath + " 权限不够,无法访问" });
            返回 假;
        }
    } 否则 {
        返回 假;
    }
    //1.检测Cookie是否过期
    //2.检测路径,获取二级菜单ID
    //3.检测UserID和二级菜单ID是否在存在菜单控制表
}
//获取数据库的返回JSON列表
异步 定义函数 获取JsonList(访问信息, 整体信息) {
    局部变量 局部_解析Cookie = 同步 解析Cookie(访问信息);
    局部变量 局部_Bool = 局部_解析Cookie[0]; //如果Cookie解析出 CookieUserID、CookieSessionKey 则返回true 否则false
    如果 (局部_Bool) {
        //循环 获取 CookieUserID、CookieSessionKey
        局部变量 局部_UserID = 局部_解析Cookie[1];
        局部变量 局部_SessionKey = 局部_解析Cookie[2];
        局部变量 局部_是否允许访问 = 同步 检测路径权限(局部_SessionKey, 局部_UserID, 访问信息["路径"]); //检测权限是否可以访问该路径
        如果 (局部_是否允许访问 != 真) {
            访问信息["主动发送"]({ "发送数据": JSON类.到可读JSON文本({ "状态": "404", "提示文本": "权限不够,无法访问!" }), "数据协议": HTTP服务类.获取数据协议("json") });
            返回;
        }
        局部变量 局部_SQL语句 = "SELECT u_UserID a1 FROM demo.f_ERP_Account where u_UserID = ? and u_SessionKey = ?";
        局部变量 局部_SQL返回 = 同步 mysql客户端.查询SQL语句_同步(局部_SQL语句, [局部_UserID, 局部_SessionKey]);
        如果 (局部_SQL返回["状态"] == "成功" && 局部_SQL返回["数据"].长度 == 1) {
            // 调试输出(3,"获取测试列表-访问信息");
            //SQL执行成功,而且返回数据1行,符合要求
            局部变量 局部_Path = 访问信息["路径"];
            局部变量 局部_Table = "";
            局部变量 局部_字段别名 = "";
            如果 (局部_Path == "/getxxx1List") {
                局部_Table = "demo.xxx1";
            }
            如果 (局部_Path == "/getxxx2List") {
                局部_Table = "demo.xxx2";
            }
            局部变量 基础行数 = 文本到整数(访问信息["参数信息"]["每页数量"]); /*每一页显示的行数*/
            局部变量 总行数 = 同步 mysql客户端.查询SQL语句_同步("SELECT COUNT(*) FROM " + 局部_Table); /*获取总行数*/
            总行数 = 总行数["数据"][0]["COUNT(*)"];
            局部变量 总页数 = 0;
            如果 (总行数 % 基础行数 == 0) {
                总页数 = 总行数 / 基础行数;
            } 否则 {
                总页数 = 文本到整数(总行数 / 基础行数) + 1;
            }
            查询页数 = 文本到整数(访问信息["参数信息"]["当前页"]);
            查询页数 = 查询页数 - 1;
            查询页数 = 查询页数 * 基础行数;
            局部变量 局部_SQL语句 = `select * from ${局部_Table} limit ${查询页数},${基础行数}`; /*js支持的格式化语句*/
            变量 查询结果 = 同步 mysql客户端.查询SQL语句_同步(局部_SQL语句);
            查询结果["总页数"] = 总页数;
            查询结果["数据总数"] = 总行数;
            如果 ((查询结果["状态"] = "成功")) {
                查询结果["状态"] = 0;
                //如果这里不改为0,那么layui读取到表格数据的时候就会提示错误描述 //返回的数据不符合规范,正确的成功状态码应为:"状态": 0
            }
            访问信息["主动发送"]({ "发送数据": JSON类.到可读JSON文本(查询结果), "数据协议": HTTP服务类.获取数据协议("json") });
            调试输出("获取JsonList-查询结果", 查询结果, 局部_SQL语句);
        } 否则 {
            访问信息["主动发送"]({ "发送数据": JSON类.到可读JSON文本({ "状态": "404", "提示文本": "登陆过期,无法获取信息!" }), "数据协议": HTTP服务类.获取数据协议("json") });
        }
    } 否则 {
        //这里是Cookie少于2个的时候(不需要检测都知道是未登录).
        访问信息["主动发送"]({ "发送数据": JSON类.到可读JSON文本({ "状态": "404", "提示文本": "未登录,无法获取信息!" }), "数据协议": HTTP服务类.获取数据协议("json") });
    }
    调试输出("获取JsonList-END");
}

HTTP服务类.启动服务(
    {
        "端口": 80,
        "域名": "127.0.0.1",
        "首页文件": "@名称_index2.lhtml",
        "链接视图": [
            { "url": "/", "回调方法": 首页页面 },
            { "url": "/index.html", "回调方法": 首页页面 },
            { "url": "/login.html", "回调方法": 登陆页面 },
            
            { "url": "/getxxx1List", "回调方法": 获取JsonList },
            { "url": "/getxxx2List", "回调方法": 获取JsonList },
            { "url": "/Login", "回调方法": 登陆函数 }
        ],
        "防火墙":{
            "开启状态":true,
            "访问时间":1000*30,
            "访问次数":30,
            "限制描述":"访问过快,请稍后再试!",
            "参与URL":["/getxxx1List","/getxxx2List","/Login"]
        }
    },
    (反馈信息) => {
        调试输出("反馈信息", 反馈信息);
    },
    (访问信息, 整体信息) => {
        //调试输出("访问信息", 访问信息);
        返回 { "发送数据": 访问信息["文件数据"]["文件数据"], "数据协议": HTTP服务类.获取数据协议(访问信息["请求类型"]) };
    },
    (访问信息, 整体信息) => {
        //调试输出("访问信息", 访问信息);
        返回 { "发送数据": 访问信息["文件数据"]["文件数据"], "数据协议": HTTP服务类.获取数据协议(访问信息["请求类型"]) };
    }
);
mysql客户端.连接Mysql(
    (连接状态) => {
        调试输出("连接状态", 连接状态);
    },
    "127.0.0.1",
    "root",
    "haosql",
    "demp",
    3306,
    20
);