Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
622070db51 | ||
|
|
0c20eefdc2 | ||
|
|
68b1ca15f2 | ||
|
|
4ca5553815 | ||
|
|
be042c4a60 | ||
|
|
9dcb1f5e50 |
@@ -4,13 +4,13 @@
|
||||
"HTTPS_PRIVATE_PEM": "./certs/private.pem",
|
||||
"HTTPS_CRT_FILE": "./certs/file.crt",
|
||||
"MAX_PROJECT_NUM_PER_USER": 20,
|
||||
"MAX_MESSAGE_PER_USER": 1000,
|
||||
"MAX_MESSAGE_PER_SECOND": 5,
|
||||
"ALLOW_REGISTER": true,
|
||||
"ALLOW_HOOK": true,
|
||||
"OFFLINE_MODE": true,
|
||||
"BAIDU_MAP_AK": "",
|
||||
"BAIDU_MAP_SERVER_AK": "",
|
||||
"ADMIN_USERNAME":"admin",
|
||||
"ADMIN_PASSWORD":"public",
|
||||
"MAX_MESSAGE_COUNT":1000,
|
||||
"MIN_PUBLISH_INTERVAL": 200
|
||||
"ADMIN_PASSWORD":"public"
|
||||
}
|
||||
@@ -229,6 +229,8 @@ input[type="search"]{
|
||||
.prj_blk:hover{
|
||||
box-shadow: 1px 1px 40px lightgray;
|
||||
transform: scale(1.05);
|
||||
transition: all 0.2s;
|
||||
box-shadow: #4e73df 0px 0px 60px;
|
||||
}
|
||||
|
||||
.laydiv{
|
||||
@@ -272,7 +274,7 @@ input[type="search"]{
|
||||
margin:6px 5px;
|
||||
user-select: none;
|
||||
background-color:white;
|
||||
width:250px;height:50px;border-radius:25px;border:solid #4e73df 2px;display:flex;align-items:center;justify-content:space-between
|
||||
width:250px;height:50px;border:solid #4e73df 2px;border-radius:10px;display:flex;align-items:center;justify-content:space-between
|
||||
}
|
||||
.widget_div div{
|
||||
display:flex;align-items:center;justify-content:center;margin:10px
|
||||
@@ -464,10 +466,7 @@ input{
|
||||
opacity: .6;
|
||||
}
|
||||
}
|
||||
|
||||
.ui-dialog-content{
|
||||
padding: 0px !important;
|
||||
overflow: visible !important;
|
||||
}
|
||||
|
||||
|
||||
padding:0 !important;
|
||||
overflow: visible !important;
|
||||
}
|
||||
2
src/css/sb-admin-2.min.css
vendored
@@ -40,7 +40,6 @@
|
||||
<script src="js/flatpkr.js"></script>
|
||||
<script src="js/dataTables.bootstrap4.min.js"></script>
|
||||
<script src="js/tools.js"></script>
|
||||
<script>var MAX_MESSAGE_COUNT = '<%=configs['MAX_MESSAGE_COUNT']%>'</script>
|
||||
<script src="js/data.js?v=6"></script>
|
||||
</head>
|
||||
<body id="page-top" class="sidebar-toggled">
|
||||
|
||||
147
src/ejs/index.ejs
Normal file
@@ -0,0 +1,147 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta name="description" content="">
|
||||
<meta name="author" content="">
|
||||
|
||||
<title>爱上米思齐(MixIO)</title>
|
||||
<link rel="shortcut icon" href="img/shortcut.png"/>
|
||||
<link href="css/font-awesome.min.css" rel="stylesheet">
|
||||
<link href="css/nunito.css" rel="stylesheet">
|
||||
<link href="css/sb-admin-2.min.css?v=2" rel="stylesheet">
|
||||
<link rel="stylesheet" href="css/muuri.css?v=2">
|
||||
<link rel="preload" href="fonts/fontawesome-webfont.ttf" as="font" type="font/woff" crossorigin="anonymous">
|
||||
<script src="js/jquery.min.js"></script>
|
||||
<script src="js/lang.js?v=5"></script>
|
||||
<script src="js/lang2.js?v=5"></script>
|
||||
<script src="js/tools.js?v=10"></script>
|
||||
<script src="js/login.js?v=22"></script>
|
||||
</head>
|
||||
|
||||
<body id="body" class="bg-gradient-light" style="height:100vh">
|
||||
<style>
|
||||
.translate{
|
||||
width:50px;
|
||||
padding: 0;
|
||||
margin-left:5px;
|
||||
}
|
||||
</style>
|
||||
<div style="position:fixed;right:10px;top:10px;display:flex;align-items:center;justify-content:center">
|
||||
<i class="fa fa-globe" style="color:#4e73df;margin-right:5px;font-size:2rem"></i>
|
||||
<button class="translate btn btn-secondary" id="zh">简</button>
|
||||
<button class="translate btn btn-secondary" id="tw">繁</button>
|
||||
<button class="translate btn btn-secondary" id="en">EN</button>
|
||||
</div>
|
||||
<div style="height:calc(100vh - 40px);display:flex;align-items:center;justify-content:center">
|
||||
<div class="container" style="opacity: 0.9;margin-top:20px">
|
||||
<!-- Outer Row -->
|
||||
<div class="row justify-content-center">
|
||||
|
||||
<div class="col-xl-10 col-lg-12 col-md-9">
|
||||
|
||||
<div id="cd" class="card o-hidden border-0 shadow-lg my-5" style="margin-top:0!important">
|
||||
<div class="card-body p-0">
|
||||
<!-- Nested Row within Card Body -->
|
||||
<div class="row">
|
||||
<div class="d-md-none" style="display: flex;width:100%;align-items: center;justify-content: center;margin-top:25px;margin-bottom:-0.5rem">
|
||||
<img src="img/shortcut.png" style="width:40px" alt="">
|
||||
<span style="font-size:30px;font-weight:bold;color:#4e73df;margin-left:10px">MixIO</span>
|
||||
</div>
|
||||
<div id="lg_img" class="col-lg-6 d-none d-lg-block bg-login-image" style="margin-right:-0.375rem"></div>
|
||||
<div class="col-lg-6">
|
||||
<div class="p-5">
|
||||
<div style="margin-left:-1rem;margin-right:-1rem;margin-top:-1.5rem;display:flex;margin-bottom:1.5rem;justify-content:center">
|
||||
<a class="btn btn-lg btn-primary btn-circle" style="border:solid #d1d3e2 1px;margin-right:.5rem" id="switch1" onclick="mixioLogin()">
|
||||
<i class="fa fa-user-o"></i>
|
||||
</a>
|
||||
<a class="btn btn-lg btn-light btn-circle" style="border:solid #d1d3e2 1px;margin-left:.5rem;margin-right:.5rem" id="switch2" onclick="mixlyLogin()">
|
||||
<i class="fa fa-key"></i>
|
||||
</a>
|
||||
<a class="btn btn-lg btn-light btn-circle" style="border:solid #d1d3e2 1px;margin-left:.5rem" id="switch3" onclick="projLogin()">
|
||||
<i class="fa fa-cube"></i>
|
||||
</a>
|
||||
</div>
|
||||
<form class="user" id="form_login" method="post">
|
||||
<div class="form-group">
|
||||
<input type="email" class="form-control form-control-user lang" key="EMAIL"
|
||||
aria-describedby="emailHelp" name="userName" style="min-width:0;text-align:center;"
|
||||
placeholder="请输入电子邮箱地址">
|
||||
</div>
|
||||
<div class="form-group" id="ref1">
|
||||
<input type="password" name="password" class="form-control form-control-user lang" key="PASSWORD" style="min-width:0;text-align:center;"
|
||||
placeholder="请输入密码">
|
||||
</div>
|
||||
<div style="display:flex;align-items: center;justify-content: center;">
|
||||
<button type="submit" class="btn btn-primary btn-icon-split"><span class="icon"><i class="fa fa-arrow-right" style="margin-top:5px;width:1rem;height:1rem"></i></span><span class="text lang" key="LOGIN" style="margin-top:1px">登录MixIO</span></button>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
<form class="user" id="form_login_2" method="post" hidden>
|
||||
<div class="form-group">
|
||||
<input class="form-control form-control-user lang" key="MIXLYKEY"
|
||||
aria-describedby="emailHelp" name="userName" style="min-width:0;text-align:center;"
|
||||
placeholder="请输入Mixly Key">
|
||||
</div>
|
||||
<div style="display:flex;align-items: center;justify-content: center;">
|
||||
<button type="submit" class="btn btn-primary btn-icon-split"><span class="icon"><i class="fa fa-arrow-right" style="margin-top:5px;width:1rem;height:1rem"></i></span><span class="text lang" style="margin-top:1px" key="LOGIN2">登录MixIO</span></button>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
<div class="user" id="form_login_3" hidden>
|
||||
<div class="form-group">
|
||||
<input class="form-control form-control-user lang" key="VFCODE"
|
||||
aria-describedby="emailHelp" id="vfCode" name="vfCode" style="min-width:0;text-align:center;font-size: .8rem;border-radius: 10rem;padding: 1.5rem 1rem;"
|
||||
placeholder="请输入项目授权码">
|
||||
</div>
|
||||
<div style="display:flex;align-items: center;justify-content: center;">
|
||||
<button id="submit3" onclick="guestLogin()" class="btn btn-primary btn-icon-split"><span class="icon"><i class="fa fa-arrow-right" style="margin-top:5px;width:1rem;height:1rem"></i></span><span class="text lang" style="margin-top:1px" key="BROWSE">访问MixIO项目</span></button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<hr>
|
||||
<div style="display:flex;flex-wrap:wrap;align-items:center;justify-content:center;margin-bottom:-1.5rem">
|
||||
<div class="text-center" style="margin-bottom:10px;padding-left: 5px;padding-right: 5px;" id="reset_text">
|
||||
<a class="btn btn-light btn-icon-split" href="forgot"><span class="icon"><i class="fa fa-refresh" style="margin-top:5px;width:1rem;height:1rem"></i></span><span class="text lang" style="margin-top:1px" key="RESET">重置密码</span></a>
|
||||
</div>
|
||||
<div class="text-center" style="margin-bottom:10px;padding-left: 5px;padding-right: 5px;" id="register_text">
|
||||
<a class="btn btn-light btn-icon-split" href="register" ><span class="icon"><i class="fa fa-flag" style="margin-top:5px;width:1rem;height:1rem"></i></span><span class="text lang" style="margin-top:1px" key="SIGNUP">注册账号</span></a>
|
||||
</div>
|
||||
<div class="text-center" style="margin-bottom:10px;padding-left: 5px;padding-right: 5px;" id="documentation_text">
|
||||
<a class="btn btn-light btn-icon-split" href="documentation/"><span class="icon"><i class="fa fa-compass" style="margin-top:5px;width:1rem;height:1rem"></i></span><span class="text lang" style="margin-top:1px" key="GUIDE">入门指南</span></a>
|
||||
</div>
|
||||
<div class="text-center" style="margin-bottom:10px;padding-left: 5px;padding-right: 5px;" id="android_text">
|
||||
<a class="btn btn-light btn-icon-split" href="android"><span class="icon"><i class="fa fa-android" style="margin-top:5px;width:1rem;height:1rem"></i></span><span class="text lang" style="margin-top:1px" key="ANDROID">安卓微端</span></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<footer id="footer" style="height:40px;font-size:0.8rem;text-align:center">
|
||||
<% if (main) { %>
|
||||
<a href="https://beian.miit.gov.cn/">京ICP备13037033号-1</a>
|
||||
<% } %>
|
||||
<% if (mixly) { %>
|
||||
<a href="/mixly">Mixly Lite</a>
|
||||
<% } %>
|
||||
<a href="https://gitee.com/mixly2/mixio" class="lang" key="OPENSRC"></a>
|
||||
<a id="admin" class="lang" key="ADMINDASH"></a>
|
||||
MixIO © Mixly Team
|
||||
</footer>
|
||||
<!-- Bootstrap core JavaScript-->
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -128,6 +128,21 @@
|
||||
<div class="card shadow" style="margin-top:1.5rem;border-radius:10px">
|
||||
<div class="card-body" style="display: flex;align-items: center;justify-content: center;flex-direction: column;">
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<span>管理员账号:</span>
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" id="ADMIN_USERNAME">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<span>管理员密码:</span>
|
||||
</td>
|
||||
<td>
|
||||
<input type="password" id="ADMIN_PASSWORD">
|
||||
</td>
|
||||
<tr>
|
||||
<td>
|
||||
<span>离线模式:</span>
|
||||
@@ -197,7 +212,15 @@
|
||||
<span>单用户最大消息数:</span>
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" id="MAX_MESSAGE_COUNT">
|
||||
<input type="text" id="MAX_MESSAGE_PER_USER">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<span>消息频率限制(次/秒):</span>
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" id="MAX_MESSAGE_PER_SECOND">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -251,7 +274,7 @@
|
||||
<td style="min-width:100px">
|
||||
消息量
|
||||
</td>
|
||||
<td style="min-width:100px">
|
||||
<td style="min-width:300px">
|
||||
执行操作
|
||||
</td>
|
||||
</thead>
|
||||
@@ -293,6 +316,73 @@
|
||||
}
|
||||
})
|
||||
}
|
||||
var clearProject = function(userName){
|
||||
$.get('clearMessage',{
|
||||
"userName":userName
|
||||
},function(res){
|
||||
if(res == 1)
|
||||
{
|
||||
$.get('clearProject',{
|
||||
"userName":userName
|
||||
},function(res){
|
||||
if(res == 1)
|
||||
{
|
||||
showtext("操作成功!")
|
||||
setTimeout(function(){
|
||||
window.location.href = window.location.href
|
||||
},1000)
|
||||
}
|
||||
else
|
||||
{
|
||||
showtext("操作失败")
|
||||
}
|
||||
})
|
||||
}
|
||||
else
|
||||
{
|
||||
showtext("操作失败")
|
||||
}
|
||||
})
|
||||
}
|
||||
var clearUser = function(userName){
|
||||
$.get('clearMessage',{
|
||||
"userName":userName
|
||||
},function(res){
|
||||
if(res == 1)
|
||||
{
|
||||
$.get('clearProject',{
|
||||
"userName":userName
|
||||
},function(res){
|
||||
if(res == 1)
|
||||
{
|
||||
$.get('clearUser',{
|
||||
"userName":userName
|
||||
},function(res){
|
||||
if(res == 1)
|
||||
{
|
||||
showtext("操作成功!")
|
||||
setTimeout(function(){
|
||||
window.location.href = window.location.href
|
||||
},1000)
|
||||
}
|
||||
else
|
||||
{
|
||||
showtext("操作失败")
|
||||
}
|
||||
})
|
||||
}
|
||||
else
|
||||
{
|
||||
showtext("操作失败")
|
||||
}
|
||||
})
|
||||
}
|
||||
else
|
||||
{
|
||||
showtext("操作失败")
|
||||
}
|
||||
})
|
||||
}
|
||||
$("#time").html(new Date().toLocaleTimeString())
|
||||
setInterval(() => {
|
||||
$("#time").html(new Date().toLocaleTimeString())
|
||||
@@ -302,12 +392,15 @@
|
||||
var HTTPS_PRIVATE_PEM = "<%=configs["HTTPS_PRIVATE_PEM"]%>"
|
||||
var HTTPS_CRT_FILE = "<%=configs["HTTPS_CRT_FILE"]%>"
|
||||
var MAX_PROJECT_NUM_PER_USER = "<%=configs["MAX_PROJECT_NUM_PER_USER"]%>"
|
||||
var MAX_MESSAGE_COUNT = "<%=configs["MAX_MESSAGE_COUNT"]%>"
|
||||
var MAX_MESSAGE_PER_USER = "<%=configs["MAX_MESSAGE_PER_USER"]%>"
|
||||
var MAX_MESSAGE_PER_SECOND= "<%=configs["MAX_MESSAGE_PER_SECOND"]%>"
|
||||
var ALLOW_REGISTER = <%=configs["ALLOW_REGISTER"]%>
|
||||
var ALLOW_HOOK = <%=configs["ALLOW_HOOK"]%>
|
||||
var OFFLINE_MODE = <%=configs["OFFLINE_MODE"]%>
|
||||
var BAIDU_MAP_AK = "<%=configs["BAIDU_MAP_AK"]%>"
|
||||
var BAIDU_MAP_SERVER_AK = "<%=configs["BAIDU_MAP_SERVER_AK"]%>"
|
||||
var ADMIN_USERNAME = "<%=configs["ADMIN_USERNAME"]%>"
|
||||
var ADMIN_PASSWORD = "<%=configs["ADMIN_PASSWORD"]%>"
|
||||
$("#OFFLINE_MODE").bind('change',function(){
|
||||
if($("#OFFLINE_MODE").prop("checked"))
|
||||
{
|
||||
@@ -331,7 +424,10 @@
|
||||
$("#BAIDU_MAP_AK").val(BAIDU_MAP_AK)
|
||||
$("#BAIDU_MAP_SERVER_AK").val(BAIDU_MAP_SERVER_AK)
|
||||
$("#MAX_PROJECT_NUM_PER_USER").val(MAX_PROJECT_NUM_PER_USER)
|
||||
$("#MAX_MESSAGE_COUNT").val(MAX_MESSAGE_COUNT)
|
||||
$("#MAX_MESSAGE_PER_USER").val(MAX_MESSAGE_PER_USER)
|
||||
$("#MAX_MESSAGE_PER_SECOND").val(MAX_MESSAGE_PER_SECOND)
|
||||
$("#ADMIN_USERNAME").val(ADMIN_USERNAME)
|
||||
$("#ADMIN_PASSWORD").val(ADMIN_PASSWORD)
|
||||
if($("#OFFLINE_MODE").prop("checked"))
|
||||
{
|
||||
$("#BAIDU_MAP_AK").attr("disabled","true")
|
||||
@@ -354,12 +450,15 @@
|
||||
configs["HTTPS_PRIVATE_PEM"] = $("#HTTPS_PRIVATE_PEM").val()
|
||||
configs["HTTPS_CRT_FILE"] = $("#HTTPS_CRT_FILE").val()
|
||||
configs["MAX_PROJECT_NUM_PER_USER"] = parseInt($("#MAX_PROJECT_NUM_PER_USER").val())
|
||||
configs["MAX_MESSAGE_PER_USER"] = parseInt($("#MAX_MESSAGE_PER_USER").val())
|
||||
configs["MAX_MESSAGE_PER_SECOND"] = parseInt($("#MAX_MESSAGE_PER_SECOND").val())
|
||||
configs["ALLOW_REGISTER"] = $("#ALLOW_REGISTER").prop("checked")
|
||||
configs["ALLOW_HOOK"] = $("#ALLOW_HOOK").prop("checked")
|
||||
configs["OFFLINE_MODE"] = $("#OFFLINE_MODE").prop("checked")
|
||||
configs["BAIDU_MAP_AK"] = $("#BAIDU_MAP_AK").val()
|
||||
configs["BAIDU_MAP_SERVER_AK"] = $("#BAIDU_MAP_SERVER_AK").val()
|
||||
configs["MAX_MESSAGE_COUNT"] = parseInt($("#MAX_MESSAGE_COUNT").val())
|
||||
configs["ADMIN_USERNAME"] = $("#ADMIN_USERNAME").val()
|
||||
configs["ADMIN_PASSWORD"] = $("#ADMIN_PASSWORD").val()
|
||||
$.get('/saveAndRestart',{'configs':JSON.stringify(configs,null,2)},function(res){
|
||||
if(res=="1")
|
||||
{
|
||||
|
||||
@@ -8,9 +8,11 @@ function get_data() {
|
||||
$.getJSON('getData', {
|
||||
|
||||
}, function(res) {
|
||||
$("#prj_num").html(res['count'] + " / " + MAX_MESSAGE_COUNT)
|
||||
var max = res["max"]
|
||||
$("#prj_num").html(res['count'] + " / " + max)
|
||||
$("#prj_num_bar").attr("aria-valuenow", res['count'])
|
||||
$("#prj_num_bar").css("width", (res['count'] * 100 / MAX_MESSAGE_COUNT) + "%")
|
||||
$("#prj_num_bar").attr("aria-valuemax", max)
|
||||
$("#prj_num_bar").css("width", (res['count'] * 100 / max) + "%")
|
||||
globalRows = res["rows"]
|
||||
init_table(res["rows"])
|
||||
sync_chart()
|
||||
|
||||
@@ -97,7 +97,7 @@ var JSLang = {
|
||||
"dataMap": "数据地图",
|
||||
"dashboard": "仪表盘",
|
||||
"weather": "实时气象仪",
|
||||
"text": "- 文本 -",
|
||||
"text": "- 媒体 -",
|
||||
"keyboard": "文本输入",
|
||||
"screen": "文本显示屏",
|
||||
"decorate": "- 装饰 -",
|
||||
@@ -289,7 +289,7 @@ var JSLang = {
|
||||
"dataMap": "數據地圖",
|
||||
"dashboard": "儀表盤",
|
||||
"weather": "實時氣象儀",
|
||||
"text": "- 文本 -",
|
||||
"text": "- 媒體 -",
|
||||
"keyboard": "文本輸入",
|
||||
"screen": "文本顯示屏",
|
||||
"decorate": "- 裝飾 -",
|
||||
@@ -477,7 +477,7 @@ var JSLang = {
|
||||
"dataMap": "Map",
|
||||
"dashboard": "Dashboard",
|
||||
"weather": "Weather",
|
||||
"text": "- Text -",
|
||||
"text": "- Media -",
|
||||
"keyboard": "Input",
|
||||
"screen": "Text Screen",
|
||||
"decorate": "- Decoration -",
|
||||
@@ -639,7 +639,7 @@ var arrLang = {
|
||||
"TOPIC": "主题",
|
||||
"MESSAGE": "消息",
|
||||
"TIME": "时间",
|
||||
"DATAMANAGE": "数据",
|
||||
"DATAMANAGE": "数据管理",
|
||||
"ADMIN": "管理",
|
||||
"BASICADMIN": "基础设置",
|
||||
"USERADMIN": "批量注册",
|
||||
@@ -657,13 +657,13 @@ var arrLang = {
|
||||
"GUIDE": "入门指南",
|
||||
"ANDROID": "安卓微端",
|
||||
"MANAGE": "管理",
|
||||
"PROJECTSMANAGE": "项目",
|
||||
"STORAGEMANAGE": "存储",
|
||||
"SHAREMANAGE": "共享",
|
||||
"PROJECTSMANAGE": "项目管理",
|
||||
"STORAGEMANAGE": "数据管理",
|
||||
"SHAREMANAGE": "共享管理",
|
||||
"SETTINGS": "设置",
|
||||
"LOGOUT": "退出登录",
|
||||
"IMPORT": "导入用户项目",
|
||||
"EXPORT": "导出用户项目",
|
||||
"IMPORT": "导入项目",
|
||||
"EXPORT": "导出项目",
|
||||
"CONNECTINGSERVER": "正在连接服务器",
|
||||
"MANAGECOUNT": "管理项目数",
|
||||
"OFFLINECOUNT": "离线消息数",
|
||||
|
||||
@@ -2,7 +2,7 @@ $(function(){
|
||||
$.getJSON("queryData",function(res){
|
||||
for(var i = 0;i<=res.length-1;i = i+1)
|
||||
{
|
||||
$("#tbody").append("<tr><td>"+res[i]["username"]+"</td><td>"+res[i]["projects"]+"</td><td>"+res[i]["messages"]+"</td><td>"+ "<a class='btn btn-primary' style='cursor:pointer;' onclick=\"clearMessage('"+res[i]["username"]+"')\" >清空消息</a>"+"</td></tr>")
|
||||
$("#tbody").append("<tr><td>"+res[i]["username"]+"</td><td>"+res[i]["projects"]+"</td><td>"+res[i]["messages"]+"</td><td>"+ "<a class='btn btn-primary' style='cursor:pointer;margin-right:5px' onclick=\"clearMessage('"+res[i]["username"]+"')\" >清空消息</a>"+"<a class='btn btn-primary' style='cursor:pointer;margin-right:5px' onclick=\"clearProject('"+res[i]["username"]+"')\" >清空项目</a>"+"<a class='btn btn-primary' style='cursor:pointer;' onclick=\"clearUser('"+res[i]["username"]+"')\" >删除用户</a>"+"</td></tr>")
|
||||
}
|
||||
datatable = $("#table").DataTable({
|
||||
"order": [[ 2, "desc" ]],
|
||||
|
||||
@@ -23,15 +23,17 @@ $(function() {
|
||||
save_layout();
|
||||
}
|
||||
};
|
||||
if (Math.random() > 0.75) {
|
||||
/*
|
||||
if (Math.random() > 0.6) {
|
||||
var d = dialog({
|
||||
title: '限时推广',
|
||||
content: '<div style="width:250px">MixIO正处于不断迭代的阶段,有稳定应用、持续改进、私有部署MixIO平台的一线教师或个人开发者,欢迎加QQ群742608657,以向我们提供建议并得到技术支持,谢谢!</div>',
|
||||
cancelValue: '确定',
|
||||
content: '<div style="width:250px">尊敬的MixIO用户,您好!<br>现邀请您参与《MixIO平台技术接受度调查》,共计10题,预计用时5-8分钟。您的作答数据将被用于科学研究和平台改进设计,感谢您的参与! <a href="https://wj.qq.com/s2/11118283/89a9/">点击此处进入调查</a></div>',
|
||||
cancelValue: '我知道了',
|
||||
cancel: function() {}
|
||||
});
|
||||
d.showModal();
|
||||
}
|
||||
*/
|
||||
})
|
||||
|
||||
const DATA_MODE = 0;
|
||||
@@ -893,6 +895,25 @@ function view_project(projectName, projectType) {
|
||||
} else if (topic1.split('/').length == 3 && !isMixly) {
|
||||
var tp = stringendecoder.encodeHtml(topic1.split('/')[2])
|
||||
var ms = message1.toString()
|
||||
if(isJSON(ms))
|
||||
{
|
||||
var msJSON = JSON.parse(ms)
|
||||
if(("clientid" in msJSON)&&("long" in msJSON)&&("lat" in msJSON)&&("message" in msJSON))
|
||||
{
|
||||
var newJSON = {}
|
||||
var clientid = msJSON["clientid"]
|
||||
newJSON[clientid+"-"+"long"] = msJSON["long"]
|
||||
newJSON[clientid+"-"+"lat"] = msJSON["lat"]
|
||||
var msg = msJSON["message"]
|
||||
if(typeof msg == "string")
|
||||
msg = JSON.parse(msg)
|
||||
for(item of msg)
|
||||
{
|
||||
newJSON[clientid+"-"+item["label"]] = item["value"]
|
||||
}
|
||||
ms = JSON.stringify(newJSON)
|
||||
}
|
||||
}
|
||||
if (globalTableProjectInfo.received[tp]) {
|
||||
globalTableProjectInfo.received[tp].unshift({
|
||||
'时间': timeStamp2String(),
|
||||
@@ -917,6 +938,25 @@ function view_project(projectName, projectType) {
|
||||
} else if (topic1.split('/').length == 4 && isMixly) {
|
||||
var tp = stringendecoder.encodeHtml(topic1.split('/')[3])
|
||||
var ms = message1.toString()
|
||||
if(isJSON(ms))
|
||||
{
|
||||
var msJSON = JSON.parse(ms)
|
||||
if(("clientid" in msJSON)&&("long" in msJSON)&&("lat" in msJSON)&&("message" in msJSON))
|
||||
{
|
||||
var newJSON = {}
|
||||
var clientid = msJSON["clientid"]
|
||||
newJSON[clientid+"-"+"long"] = msJSON["long"]
|
||||
newJSON[clientid+"-"+"lat"] = msJSON["lat"]
|
||||
var msg = msJSON["message"]
|
||||
if(typeof msg == "string")
|
||||
msg = JSON.parse(msg)
|
||||
for(item of msg)
|
||||
{
|
||||
newJSON[clientid+"-"+item["label"]] = item["value"]
|
||||
}
|
||||
ms = JSON.stringify(newJSON)
|
||||
}
|
||||
}
|
||||
if (globalTableProjectInfo.received[tp]) {
|
||||
globalTableProjectInfo.received[tp].unshift({
|
||||
'时间': timeStamp2String(),
|
||||
@@ -1074,6 +1114,19 @@ function view_project(projectName, projectType) {
|
||||
grid2.append(topicOuterDiv2)
|
||||
var dataset = []
|
||||
chart = echarts.init(rightCardBodyDiv[0])
|
||||
chart.setOption({
|
||||
tooltip:{
|
||||
trigger: "axis",
|
||||
formatter: function(params){
|
||||
let str = '';
|
||||
params.forEach((item, idx) => {
|
||||
str += "<div style='margin:0;display:flex;justify-content:space-between;align-items:center'><div>" + `${item.marker}${item.seriesName}: </div><b>${chart.getOption().series[item.seriesIndex].oriData[item.dataIndex]}</b>` + "</div>"
|
||||
|
||||
})
|
||||
return str
|
||||
}
|
||||
}
|
||||
})
|
||||
init_table = function() {
|
||||
var fields = ["时间"]
|
||||
for (dataitem in dataset) {
|
||||
@@ -1168,7 +1221,8 @@ function view_project(projectName, projectType) {
|
||||
type: 'line',
|
||||
name: tableFields[tableField].name,
|
||||
data: [],
|
||||
connectNulls: true,
|
||||
oriData:[],
|
||||
connectNulls: true
|
||||
})
|
||||
}
|
||||
for (dataitem in dataset) {
|
||||
@@ -1179,18 +1233,27 @@ function view_project(projectName, projectType) {
|
||||
var seryName = series[sery].name
|
||||
if (seryName != JSLang[lang].time)
|
||||
if (json_parsed[seryName] || json_parsed[seryName] === 0) {
|
||||
series[sery].data.unshift(json_parsed[seryName])
|
||||
series[sery].data.unshift(parseFloat(json_parsed[seryName]))
|
||||
series[sery].oriData.unshift(json_parsed[seryName])
|
||||
} else
|
||||
{
|
||||
series[sery].data.unshift(NaN)
|
||||
series[sery].oriData.unshift("-")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (sery in series) {
|
||||
var seryName = series[sery].name
|
||||
if (seryName != JSLang[lang].time)
|
||||
if (seryName == JSLang[lang].value)
|
||||
series[sery].data.unshift(dataset[dataitem][JSLang[lang].value])
|
||||
if (seryName == JSLang[lang].value){
|
||||
series[sery].data.unshift(parseFloat(dataset[dataitem][JSLang[lang].value]))
|
||||
series[sery].oriData.unshift(dataset[dataitem][JSLang[lang].value])
|
||||
}
|
||||
else
|
||||
{
|
||||
series[sery].data.unshift(NaN)
|
||||
series[sery].oriData.unshift("-")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1203,9 +1266,19 @@ function view_project(projectName, projectType) {
|
||||
xAxis: xAxis,
|
||||
yAxis: yAxis,
|
||||
series: series,
|
||||
tooltip: {
|
||||
trigger: 'axis'
|
||||
}
|
||||
|
||||
tooltip:{
|
||||
trigger: "axis",
|
||||
formatter: function(params){
|
||||
let str = '';
|
||||
params.forEach((item, idx) => {
|
||||
str += "<div style='margin:0;display:flex;justify-content:space-between;align-items:center'><div>" + `${item.marker}${item.seriesName}: </div><b>${chart.getOption().series[item.seriesIndex].oriData[item.dataIndex]}</b>` + "</div>"
|
||||
|
||||
})
|
||||
return str
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
sync_export()
|
||||
}
|
||||
@@ -1218,6 +1291,7 @@ function view_project(projectName, projectType) {
|
||||
var bottomCardTitle = $('<div class="card-header py-3" style="display:flex">')
|
||||
bottomCard.append(bottomCardTitle)
|
||||
bottomCardTitle.append($('<h6 class="m-0 font-weight-bold text-primary">' + JSLang[lang].sendString + '</h6>'))
|
||||
bottomCardTitle.append($('<input type="checkbox" id="sendClear" style="min-width:0px!important;margin-left:20px;margin-right:3px"/><label style="margin:0;padding:0;font-size:small">发送后清空</label>'))
|
||||
var bottomCardBody = $('<div class="card-body">')
|
||||
bottomCard.append(bottomCardBody)
|
||||
var bottomCardBodyDiv = $('<div style="display:flex;align-items:center"></div>')
|
||||
@@ -1226,7 +1300,9 @@ function view_project(projectName, projectType) {
|
||||
messageInput.bind('input', function() {
|
||||
globalTableProjectInfo['toBeSent'] = stringendecoder.encodeHtml(messageInput.val())
|
||||
})
|
||||
var messageSendButton = $('<a class="btn btn-primary btn-circle btn-lg" style="margin-left:10px"><i class="fa fa-paper-plane" style="margin-right:3px"></i></a>')
|
||||
var messageSendButton = $('<a class="btn btn-primary btn-circle btn-lg" style="margin-left:10px"></a>')
|
||||
var messageSendIcon = $('<i class="fa fa-paper-plane" style="margin-right:3px"></i>')
|
||||
messageSendButton.append(messageSendIcon)
|
||||
bottomCardBodyDiv.append(messageInput)
|
||||
bottomCardBodyDiv.append(messageSendButton)
|
||||
messageSendButton.click(function() {
|
||||
@@ -1234,6 +1310,14 @@ function view_project(projectName, projectType) {
|
||||
publish(stringendecoder.decodeHtml(globalTableProjectInfo.currentTp2), messageInput.val(), true)
|
||||
else
|
||||
showtext(JSLang[lang].topicUnset)
|
||||
messageSendButton.removeClass("btn-primary")
|
||||
messageSendButton.addClass("btn-success")
|
||||
setTimeout(function(){
|
||||
messageSendButton.addClass("btn-primary")
|
||||
messageSendButton.removeClass("btn-success")
|
||||
},200)
|
||||
if($("#sendClear").prop("checked"))
|
||||
messageInput.val("")
|
||||
})
|
||||
|
||||
var bottomDiv2 = $("<div class='col-xl-6'></div>")
|
||||
@@ -1449,7 +1533,6 @@ function add_widget() {
|
||||
widget_list.append(input_keyboard_add)
|
||||
var output_text_add = $("<div class='widget_div'><div><img src='icons/output_text.svg'><span>" + JSLang[lang].screen + "</span></div><a class='btn btn-success btn-block'><i class='fa fa-plus'></i></a></div>")
|
||||
widget_list.append(output_text_add)
|
||||
widget_list.append($("<h5 style='width:100%;text-align:center;margin-bottom:5px;margin-top:10px;color:#4e73df;font-size:1.3rem;font-weight:bold'>" + JSLang[lang].decorate + "</h5>"))
|
||||
var decorate_text_add = $("<div class='widget_div'><div><img src='icons/decorate_text.svg'><span>" + JSLang[lang].label + "</span></div><a class='btn btn-success btn-block'><i class='fa fa-plus'></i></a></div>")
|
||||
widget_list.append(decorate_text_add)
|
||||
var decorate_pic_add = $("<div class='widget_div'><div><img src='icons/decorate_pic.svg'><span>" + JSLang[lang].picture + "</span></div><a class='btn btn-success btn-block'><i class='fa fa-plus'></i></a></div>")
|
||||
|
||||
@@ -1198,6 +1198,7 @@ function add_trigger(user_title, user_topic, user_content, user_style) {
|
||||
var dstMessage = user_content.split("$$$")[6]
|
||||
var itemdiv = add_block(1, 1, contents, attrs)
|
||||
var relationLogic = function(message, condition_1, condition_2) {
|
||||
var condition_2 = parseFloat(condition_2)
|
||||
if (condition_1 == ">")
|
||||
return message > condition_2
|
||||
else if (condition_1 == "≥")
|
||||
@@ -1215,10 +1216,10 @@ function add_trigger(user_title, user_topic, user_content, user_style) {
|
||||
}
|
||||
MixIO.triggers[title.text()] = function() {
|
||||
MixIO.onMessage(function(topic1, message) {
|
||||
var message = String(message)
|
||||
if (topic1 == topic.text()) {
|
||||
if (conditionRelation == "AND") {
|
||||
if (relationLogic(message, condition1_1, condition1_2) && relationLogic(message, condition2_1, condition2_2)) {
|
||||
|
||||
itemdiv.addClass("triggered")
|
||||
setTimeout(function() {
|
||||
itemdiv.removeClass("triggered")
|
||||
@@ -2265,8 +2266,9 @@ function add_map(user_title, user_topic, user_content, user_style) {
|
||||
if (topic1.split("/")[(isMixly ? 3 : 2)] == topic.text()) {
|
||||
|
||||
var label = (new Date().getHours() + ":" + (new Date().getMinutes() < 10 ? "0" : "") + new Date().getMinutes() + ":" + (new Date().getSeconds() < 10 ? "0" : "") + new Date().getSeconds())
|
||||
if (isJSON(String(message1)) && JSON.parse(String(message1)).long && JSON.parse(String(message1)).lat && JSON.parse(String(message1)).clientid) {
|
||||
if (isJSON(String(message1)) && ("long" in JSON.parse(String(message1))) && ("lat" in JSON.parse(String(message1))) && JSON.parse(String(message1)).clientid) {
|
||||
var jsonMessage = JSON.parse(String(message1))
|
||||
console.log(jsonMessage)
|
||||
itemdiv.trigger(MixIO.eventTags.DATA_MAP_CHANGED, [jsonMessage.clientid, jsonMessage.long, jsonMessage.lat, jsonMessage.message])
|
||||
var newOrNot = true
|
||||
var markerIndex = -1
|
||||
@@ -2279,6 +2281,8 @@ function add_map(user_title, user_topic, user_content, user_style) {
|
||||
}
|
||||
if (newOrNot) {
|
||||
var msgstr = ""
|
||||
if (typeof jsonMessage.message == "string")
|
||||
jsonMessage.message = JSON.parse(jsonMessage.message)
|
||||
for (msg in jsonMessage.message) {
|
||||
msgstr = msgstr + jsonMessage.message[msg].label + ":" + jsonMessage.message[msg].value + "<br>"
|
||||
}
|
||||
@@ -2287,6 +2291,7 @@ function add_map(user_title, user_topic, user_content, user_style) {
|
||||
markerIndex = markers.length
|
||||
var bubble = create_a_map_bubble(msgstr, label, point)
|
||||
newMarker.bubble = bubble
|
||||
console.log(msgstr)
|
||||
markers.push({
|
||||
"clientid": jsonMessage.clientid,
|
||||
"long": jsonMessage.long,
|
||||
@@ -2310,6 +2315,8 @@ function add_map(user_title, user_topic, user_content, user_style) {
|
||||
} else {
|
||||
markers[markerIndex].time = label
|
||||
var msgstr = ""
|
||||
if (typeof jsonMessage.message == "string")
|
||||
jsonMessage.message = JSON.parse(jsonMessage.message)
|
||||
for (msg in jsonMessage.message) {
|
||||
msgstr = msgstr + jsonMessage.message[msg].label + ":" + jsonMessage.message[msg].value + "<br>"
|
||||
}
|
||||
|
||||
243
src/loader.js
@@ -17,11 +17,21 @@ const { execPath } = require('process');
|
||||
var { JSLang, arrLang, lang } = require("./js/lang.js")
|
||||
const path = require('path');
|
||||
|
||||
var VERSION = JSON.parse(fs.readFileSync("../version.json", "utf-8"))["version"]
|
||||
var configs = fs.readFileSync('./config.json');
|
||||
var versionPath = "../version.json"
|
||||
if(!fs.existsSync(versionPath)){
|
||||
versionPath = path.join(__dirname,"../version.json")
|
||||
}
|
||||
var VERSION = JSON.parse(fs.readFileSync(versionPath), "utf-8")["version"]
|
||||
var configPath = "./config.json"
|
||||
if(!fs.existsSync(configPath)){
|
||||
configPath = path.join(__dirname,"./config.json")
|
||||
}
|
||||
var configs = fs.readFileSync(configPath);
|
||||
configs = JSON.parse(configs.toString());
|
||||
var MAX_MESSAGE_PER_USER = configs["MAX_MESSAGE_COUNT"] ? configs["MAX_MESSAGE_COUNT"] : 1000
|
||||
var minInterval = configs["MIN_PUBLISH_INTERVAL"] ? configs["MIN_PUBLISH_INTERVAL"] : 100
|
||||
|
||||
|
||||
var MAX_MESSAGE_PER_USER = configs["MAX_MESSAGE_PER_USER"]
|
||||
var MAX_MESSAGE_PER_SECOND = configs["MAX_MESSAGE_PER_SECOND"]
|
||||
|
||||
var serverStatus = true
|
||||
|
||||
@@ -210,6 +220,40 @@ async function daemon_start() {
|
||||
res.send('-1')
|
||||
})
|
||||
|
||||
app.get('/clearProject', function(req, res){
|
||||
if(req.session.admin){
|
||||
var userName = req.query.userName
|
||||
if(userName){
|
||||
db.run("delete from `project` where userName=?", [userName, ], function(err){
|
||||
if(err){
|
||||
console.log(err.message)
|
||||
res.send('-1')
|
||||
}else{
|
||||
res.send('1')
|
||||
}
|
||||
})
|
||||
}else
|
||||
res.send('-1')
|
||||
}
|
||||
})
|
||||
|
||||
app.get('/clearUser', function(req, res){
|
||||
if(req.session.admin){
|
||||
var userName = req.query.userName
|
||||
if(userName){
|
||||
db.run("delete from `user` where username=?", [userName, ], function(err){
|
||||
if(err){
|
||||
console.log(err.message)
|
||||
res.send('-1')
|
||||
}else{
|
||||
res.send('1')
|
||||
}
|
||||
})
|
||||
}else
|
||||
res.send('-1')
|
||||
}
|
||||
})
|
||||
|
||||
app.post('/adminLogin', function(req, res) {
|
||||
if (req.body.userName == (configs["ADMIN_USERNAME"] ? configs["ADMIN_USERNAME"] : "admin") && req.body.password == (configs["ADMIN_PASSWORD"] ? configs["ADMIN_PASSWORD"] : "public")) {
|
||||
req.session.admin = true
|
||||
@@ -222,9 +266,8 @@ async function daemon_start() {
|
||||
app.get('/saveAndRestart', async function(req, res) {
|
||||
newConfig = req.query.configs
|
||||
if (newConfig) {
|
||||
fs.writeFileSync('./config.json', newConfig)
|
||||
fs.writeFileSync(configPath, newConfig)
|
||||
configs = JSON.parse(newConfig)
|
||||
MAX_MESSAGE_PER_USER = configs["MAX_MESSAGE_COUNT"] ? configs["MAX_MESSAGE_COUNT"] : 1000
|
||||
console.log("[INFO] Shutting down MixIO Server...")
|
||||
await mixio.stop();
|
||||
serverStatus = false;
|
||||
@@ -300,12 +343,26 @@ async function daemon_start() {
|
||||
}
|
||||
|
||||
var mixioServer = function() {
|
||||
var privateKey = fs.readFileSync(configs['HTTPS_PRIVATE_PEM'], 'utf8');
|
||||
var certificate = fs.readFileSync(configs['HTTPS_CRT_FILE'], 'utf8');
|
||||
var keyPath = "./certs/private.pem"
|
||||
if(!fs.existsSync(keyPath))
|
||||
keyPath = path.join(__dirname,"./certs/private.pem")
|
||||
var crtPath = "./certs/file.crt"
|
||||
if(!fs.existsSync(crtPath))
|
||||
crtPath = path.join(__dirname,"./certs/file.crt")
|
||||
var privateKey = fs.readFileSync(keyPath, 'utf8');
|
||||
var certificate = fs.readFileSync(crtPath, 'utf8');
|
||||
|
||||
var credentials = {
|
||||
key: privateKey,
|
||||
cert: certificate
|
||||
};
|
||||
|
||||
var chainPath = "./certs/chain.crt"
|
||||
if(!fs.existsSync(chainPath))
|
||||
chainPath = path.join(__dirname,"./certs/chain.crt")
|
||||
if(fs.existsSync(chainPath))
|
||||
credentials['ca'] = fs.readFileSync(chainPath, 'utf8')
|
||||
|
||||
aedes = aedesmodule()
|
||||
const httpServer = http.createServer()
|
||||
var tasks = {};
|
||||
@@ -416,6 +473,7 @@ var mixioServer = function() {
|
||||
server: httpsServer
|
||||
}, aedes.handle)
|
||||
|
||||
|
||||
aedes.authenticate = function(client, username, password, callback) {
|
||||
if (username == "MixIO_public" && password == "MixIO_public") {
|
||||
client.user = "MixIO"
|
||||
@@ -440,15 +498,19 @@ var mixioServer = function() {
|
||||
return callback(new Error('wrong topic'))
|
||||
else
|
||||
{
|
||||
/*
|
||||
if(globalConnectionControl[client.id])
|
||||
{
|
||||
if(Date.now() - globalConnectionControl[client.id] < minInterval)
|
||||
if(Date.now() - globalConnectionControl[client.id][0] > 1000)
|
||||
{
|
||||
globalConnectionControl[client.id][0] = Date.now()
|
||||
globalConnectionControl[client.id][1] = 0
|
||||
}
|
||||
else if(globalConnectionControl[client.id][1] > MAX_MESSAGE_PER_SECOND)
|
||||
{
|
||||
delete globalConnectionControl[client.id]
|
||||
return callback(new Error('too fast'))
|
||||
}
|
||||
}
|
||||
*/
|
||||
callback(null)
|
||||
}
|
||||
}
|
||||
@@ -472,8 +534,15 @@ var mixioServer = function() {
|
||||
},10000)
|
||||
|
||||
aedes.on('publish', function(packet, client) {
|
||||
|
||||
if(client)
|
||||
globalConnectionControl[client.id] = Date.now()
|
||||
{
|
||||
if(globalConnectionControl[client.id])
|
||||
globalConnectionControl[client.id][1] = globalConnectionControl[client.id][1] + 1
|
||||
else
|
||||
globalConnectionControl[client.id] = [Date.now(),1]
|
||||
}
|
||||
|
||||
var topic = packet.topic.split('/')
|
||||
var payload = String(packet.payload)
|
||||
if (topic.length == 3) {
|
||||
@@ -485,7 +554,7 @@ var mixioServer = function() {
|
||||
} else if (configs["ALLOW_HOOK"] && reserveJSON[topic[0]] && topic[0] != "$SYS") {
|
||||
var userName = topic[0]
|
||||
var reserveTopic = topic[1] + "/" + topic[2]
|
||||
var hash = 0, i, chr;
|
||||
var hash = 0,i, chr;
|
||||
for (i = 0; i < userName.length; i++) {
|
||||
chr = userName.charCodeAt(i);
|
||||
hash = ((hash << 5) - hash) + chr;
|
||||
@@ -496,33 +565,33 @@ var mixioServer = function() {
|
||||
if (err) {
|
||||
console.log(err.message)
|
||||
} else {
|
||||
if (row && row["count(*)"] < MAX_MESSAGE_PER_USER - 1) {
|
||||
if (row && row["count(*)"] < MAX_MESSAGE_PER_USER) {
|
||||
targetDB.run("insert into 'reserve' (userName, topic, message) values (?,?,?)", [userName, reserveTopic, payload], function(err) {
|
||||
if (err) {
|
||||
console.log(err.message)
|
||||
}
|
||||
})
|
||||
} else if (row["count(*)"] >= MAX_MESSAGE_PER_USER - 1) {
|
||||
targetDB.get("select id from 'reserve' where userName = ? order by id asc limit 1", [userName, ], function(err, row) {
|
||||
if (err) {
|
||||
console.log(err.message)
|
||||
} else {
|
||||
console.log(row)
|
||||
if (row && row["id"]) {
|
||||
targetDB.run("delete from 'reserve' where id = ?", [row["id"], ], function(err) {
|
||||
if (err) {
|
||||
console.log(err.message)
|
||||
} else {
|
||||
targetDB.run("insert into 'reserve' (userName, topic, message) values (?,?,?)", [userName, reserveTopic, payload], function(err) {
|
||||
if (err) {
|
||||
console.log(err.message)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
} else if (row["count(*)"] >= MAX_MESSAGE_PER_USER) {
|
||||
targetDB.get("select id from 'reserve' where userName = ? order by id asc limit 1", [userName, ], function(err, row) {
|
||||
if (err) {
|
||||
console.log(err.message)
|
||||
} else {
|
||||
if (row && row["id"]) {
|
||||
targetDB.run("delete from 'reserve' where id = ?", [row["id"], ], function(err) {
|
||||
if (err) {
|
||||
console.log(err.message)
|
||||
}
|
||||
else{
|
||||
targetDB.run("insert into 'reserve' (userName, topic, message) values (?,?,?)", [userName, reserveTopic, payload], function(err) {
|
||||
if (err) {
|
||||
console.log(err.message)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -554,11 +623,21 @@ var mixioServer = function() {
|
||||
app.set('trust proxy', 1)
|
||||
|
||||
app.get('/', function(req, res) {
|
||||
res.sendFile(__dirname + "/" + "ejs/index.html");
|
||||
ejs.renderFile(__dirname + '/ejs/index.ejs', {
|
||||
'main':fs.existsSync(__dirname + "/certs/chain.crt"),
|
||||
'mixly':fs.existsSync(__dirname + "/mixly")
|
||||
}, function(err, data) {
|
||||
res.send(data)
|
||||
})
|
||||
})
|
||||
|
||||
app.get('/index', function(req, res) {
|
||||
res.sendFile(__dirname + "/" + "ejs/index.html");
|
||||
ejs.renderFile(__dirname + '/ejs/index.ejs', {
|
||||
'main':fs.existsSync(__dirname + "/certs/chain.crt"),
|
||||
'mixly':fs.existsSync(__dirname + "/mixly")
|
||||
}, function(err, data) {
|
||||
res.send(data)
|
||||
})
|
||||
})
|
||||
|
||||
app.get('/observe', function(req, res) {
|
||||
@@ -830,7 +909,7 @@ var mixioServer = function() {
|
||||
app.get('/getData', function(req, res) {
|
||||
if (req.session.userName) {
|
||||
var userName = req.session.userName
|
||||
var hash = 0, i, chr;
|
||||
var hash = 0,i, chr;
|
||||
for (i = 0; i < userName.length; i++) {
|
||||
chr = userName.charCodeAt(i);
|
||||
hash = ((hash << 5) - hash) + chr;
|
||||
@@ -843,7 +922,8 @@ var mixioServer = function() {
|
||||
if (rows) {
|
||||
res.send({
|
||||
"count": rows.length,
|
||||
"rows": rows
|
||||
"rows": rows,
|
||||
"max": configs['MAX_MESSAGE_PER_USER']
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1341,7 +1421,10 @@ var mixioServer = function() {
|
||||
|
||||
app.get('/time.php', function(req, res) {
|
||||
var date = new Date()
|
||||
res.send([date.getFullYear(), date.getMonth() + 1, date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds(), date.getDay()].join(','))
|
||||
var day = date.getDay() - 1
|
||||
if (day < 0)
|
||||
day = 6
|
||||
res.send([date.getFullYear(), date.getMonth() + 1, date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds(), day].join(','))
|
||||
})
|
||||
|
||||
app.get('/mixio-php/sharekey.php', function(req, res) {
|
||||
@@ -1387,10 +1470,13 @@ var mixioServer = function() {
|
||||
}
|
||||
})
|
||||
|
||||
var filterPath = "./reserve/filter.json"
|
||||
if(!fs.existsSync(filterPath))
|
||||
filterPath = path.join(__dirname,'./reserve/filter.json')
|
||||
app.get('/startHook', function(req, res) {
|
||||
if (req.session.userName) {
|
||||
reserveJSON[req.session.userName] = true
|
||||
fs.writeFileSync('./reserve/filter.json', JSON.stringify(reserveJSON, false, 4))
|
||||
fs.writeFileSync(filterPath, JSON.stringify(reserveJSON, false, 4))
|
||||
res.send('1')
|
||||
} else {
|
||||
res.send('0')
|
||||
@@ -1400,7 +1486,7 @@ var mixioServer = function() {
|
||||
app.get('/stopHook', function(req, res) {
|
||||
if (req.session.userName) {
|
||||
reserveJSON[req.session.userName] = false
|
||||
fs.writeFileSync('./reserve/filter.json', JSON.stringify(reserveJSON, false, 4))
|
||||
fs.writeFileSync(filterPath, JSON.stringify(reserveJSON, false, 4))
|
||||
res.send('1')
|
||||
} else {
|
||||
res.send('0')
|
||||
@@ -1454,10 +1540,20 @@ var mixioServer = function() {
|
||||
|
||||
app.use('/documentation', express.static(path.join(__dirname, 'documentation')));
|
||||
|
||||
app.use('/mixly', express.static(path.join(__dirname, 'mixly')));
|
||||
var mixlyPath = "./mixly"
|
||||
if(!fs.existsSync(mixlyPath)) {
|
||||
mixlyPath = path.join(__dirname,'./mixly')
|
||||
}
|
||||
if(fs.existsSync(mixlyPath)){
|
||||
app.use('/mixly', express.static(mixlyPath));
|
||||
}
|
||||
|
||||
var dbPath = "./mixio.db"
|
||||
if(!fs.existsSync(dbPath)) {
|
||||
dbPath = path.join(__dirname,'./mixio.db')
|
||||
}
|
||||
db = new sqlite3.Database(
|
||||
'./mixio.db',
|
||||
dbPath,
|
||||
sqlite3.OPEN_READWRITE,
|
||||
function(err) {
|
||||
if (err) {
|
||||
@@ -1470,9 +1566,13 @@ var mixioServer = function() {
|
||||
|
||||
reserveDBs = []
|
||||
for (var i = 1; i <= 8; i = i + 1) {
|
||||
var dbPath = "./reserve/" + i + ".db"
|
||||
if(!fs.existsSync(dbPath)) {
|
||||
dbPath = path.join(__dirname,'./reserve/' + i + ".db")
|
||||
}
|
||||
reserveDBs.push(
|
||||
new sqlite3.Database(
|
||||
'./reserve/' + i + ".db",
|
||||
dbPath,
|
||||
sqlite3.OPEN_READWRITE,
|
||||
function(err) {
|
||||
if (err)
|
||||
@@ -1481,8 +1581,7 @@ var mixioServer = function() {
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
var reserveJSON = JSON.parse(fs.readFileSync('./reserve/filter.json'), "utf8")
|
||||
var reserveJSON = JSON.parse(fs.readFileSync(filterPath), "utf8")
|
||||
|
||||
|
||||
return new Promise(resolve => {
|
||||
@@ -1502,14 +1601,19 @@ var mixioServer = function() {
|
||||
return new Promise(resolve => {
|
||||
//MQTT
|
||||
plainServer.close(function() {
|
||||
console.log("[INFO] Plain MQTT server closed")
|
||||
//MQTT Websocket
|
||||
httpServer.close(function() {
|
||||
console.log("[INFO] WebSocket MQTT server closed")
|
||||
//MixIO HTTP
|
||||
httpServer2.close(function() {
|
||||
console.log("[INFO] MixIO server closed")
|
||||
//MQTT WebsocketS
|
||||
httpsServer.close(function() {
|
||||
console.log("[INFO] WebSocketS MQTT server closed")
|
||||
//MixIO HTTPS
|
||||
httpsServer2.close(function() {
|
||||
console.log("[INFO] MixIO server (HTTPS) closed")
|
||||
resolve("1")
|
||||
})
|
||||
})
|
||||
@@ -2371,9 +2475,51 @@ var MixIOclosure = function(userName, projectName, projectPass, dataStorage, dom
|
||||
['user-content', user_content]
|
||||
]
|
||||
var itemdiv = add_block(2, 2, contents, attrs)
|
||||
var sync_weather = function(){
|
||||
var dsc_code = title.parent().parent().attr('user-content').split(',')[0].split('w')[0]
|
||||
if(globalWeather[dsc_code] && globalWeather[dsc_code].time && (new Date().getTime() - globalWeather[dsc_code].time) < 600000) {
|
||||
var result = globalWeather[dsc_code].data
|
||||
var resJSON = JSON.parse(result)
|
||||
weather_type = resJSON.result.now.text
|
||||
temperature = resJSON.result.now.temp
|
||||
humidity = resJSON.result.now.rh
|
||||
wind_dir = resJSON.result.now.wind_dir
|
||||
wind_class = resJSON.result.now.wind_class
|
||||
district = resJSON.result.location.name
|
||||
title.parent().parent().attr('user-content', [title.parent().parent().attr('user-content').split(',')[0], district, weather_type, temperature, humidity, wind_dir, wind_class].join(','))
|
||||
itemdiv.trigger(MixIO.eventTags.WEATHER_SYNCED, [district, weather_type, temperature, humidity, wind_dir, wind_class])
|
||||
} else {
|
||||
http.get('http://api.map.baidu.com/weather/v1/?district_id=' + dsc_code + '&data_type=now&ak=' + configs["BAIDU_MAP_SERVER_AK"], function(req2, res2) {
|
||||
var html = ''
|
||||
req2.on('data', function(data) {
|
||||
html += data;
|
||||
});
|
||||
req2.on('end', function() {
|
||||
globalWeather[dsc_code] = {
|
||||
time: new Date().getTime(),
|
||||
data: html
|
||||
}
|
||||
var result = html
|
||||
var resJSON = JSON.parse(result)
|
||||
if(resJSON.result && resJSON.result.now)
|
||||
{
|
||||
weather_type = resJSON.result.now.text
|
||||
temperature = resJSON.result.now.temp
|
||||
humidity = resJSON.result.now.rh
|
||||
wind_dir = resJSON.result.now.wind_dir
|
||||
wind_class = resJSON.result.now.wind_class
|
||||
district = resJSON.result.location.name
|
||||
title.parent().parent().attr('user-content', [title.parent().parent().attr('user-content').split(',')[0], district, weather_type, temperature, humidity, wind_dir, wind_class].join(','))
|
||||
itemdiv.trigger(MixIO.eventTags.WEATHER_SYNCED, [district, weather_type, temperature, humidity, wind_dir, wind_class])
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
itemdiv.bind(MixIO.actionTags.WEATHER_SYNC, function() {
|
||||
|
||||
sync_weather()
|
||||
})
|
||||
sync_weather()
|
||||
itemdiv.bind(MixIO.actionTags.WEATHER_SEND, function() {
|
||||
var weather = {
|
||||
'district': district,
|
||||
@@ -2383,7 +2529,8 @@ var MixIOclosure = function(userName, projectName, projectPass, dataStorage, dom
|
||||
'wind_dir': wind_dir,
|
||||
'wind_class': wind_class
|
||||
}
|
||||
publish(topic.text(), JSON.stringify(weather))
|
||||
MixIO.publish(topic.text(), JSON.stringify(weather))
|
||||
itemdiv.trigger(MixIO.eventTags.WEATHER_SENT, [district, weather_type, temperature, humidity, wind_dir, wind_class])
|
||||
})
|
||||
},
|
||||
'trigger': function() {
|
||||
|
||||
BIN
src/mixly/board/ThirdParty/common/media/1x1.gif
vendored
|
Before Width: | Height: | Size: 43 B |
@@ -1,9 +0,0 @@
|
||||
.blocklyTable {
|
||||
vertical-align: top;
|
||||
}
|
||||
.blocklyTree .blocklyActiveDescendant > label,
|
||||
.blocklyTree .blocklyActiveDescendant > div > label,
|
||||
.blocklyActiveDescendant > button,
|
||||
.blocklyActiveDescendant > input {
|
||||
outline: 2px dotted #00f;
|
||||
}
|
||||
BIN
src/mixly/board/ThirdParty/common/media/ban.png
vendored
|
Before Width: | Height: | Size: 6.1 KiB |
BIN
src/mixly/board/ThirdParty/common/media/blocks.png
vendored
|
Before Width: | Height: | Size: 207 KiB |
|
Before Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 4.6 KiB |
|
Before Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 3.5 KiB |
|
Before Width: | Height: | Size: 4.0 KiB |
|
Before Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 3.8 KiB |
|
Before Width: | Height: | Size: 3.5 KiB |
|
Before Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 4.1 KiB |
|
Before Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 4.0 KiB |
|
Before Width: | Height: | Size: 3.1 KiB |
|
Before Width: | Height: | Size: 5.7 KiB |
|
Before Width: | Height: | Size: 106 KiB |
|
Before Width: | Height: | Size: 330 KiB |
|
Before Width: | Height: | Size: 561 KiB |
|
Before Width: | Height: | Size: 298 KiB |
|
Before Width: | Height: | Size: 444 KiB |
|
Before Width: | Height: | Size: 45 KiB |
|
Before Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 528 KiB |
|
Before Width: | Height: | Size: 606 KiB |
|
Before Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 37 KiB |
|
Before Width: | Height: | Size: 94 KiB |
|
Before Width: | Height: | Size: 487 KiB |
|
Before Width: | Height: | Size: 142 KiB |
|
Before Width: | Height: | Size: 676 KiB |
|
Before Width: | Height: | Size: 138 KiB |
|
Before Width: | Height: | Size: 173 KiB |
|
Before Width: | Height: | Size: 97 KiB |
|
Before Width: | Height: | Size: 138 KiB |
|
Before Width: | Height: | Size: 561 KiB |
|
Before Width: | Height: | Size: 811 KiB |
|
Before Width: | Height: | Size: 350 KiB |
|
Before Width: | Height: | Size: 236 KiB |
|
Before Width: | Height: | Size: 599 KiB |
|
Before Width: | Height: | Size: 1.2 KiB |
BIN
src/mixly/board/ThirdParty/common/media/click.mp3
vendored
BIN
src/mixly/board/ThirdParty/common/media/click.ogg
vendored
BIN
src/mixly/board/ThirdParty/common/media/click.wav
vendored
BIN
src/mixly/board/ThirdParty/common/media/config.png
vendored
|
Before Width: | Height: | Size: 27 KiB |
BIN
src/mixly/board/ThirdParty/common/media/delete.mp3
vendored
BIN
src/mixly/board/ThirdParty/common/media/delete.ogg
vendored
BIN
src/mixly/board/ThirdParty/common/media/delete.wav
vendored
|
Before Width: | Height: | Size: 326 B |
|
Before Width: | Height: | Size: 766 B |
BIN
src/mixly/board/ThirdParty/common/media/handopen.cur
vendored
|
Before Width: | Height: | Size: 198 B |
BIN
src/mixly/board/ThirdParty/common/media/help.png
vendored
|
Before Width: | Height: | Size: 16 KiB |
BIN
src/mixly/board/ThirdParty/common/media/help1.png
vendored
|
Before Width: | Height: | Size: 16 KiB |
BIN
src/mixly/board/ThirdParty/common/media/help2.png
vendored
|
Before Width: | Height: | Size: 16 KiB |
BIN
src/mixly/board/ThirdParty/common/media/loading.gif
vendored
|
Before Width: | Height: | Size: 5.4 KiB |
@@ -1,11 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 14 32 18" width="32" height="4" fill="#f20" preserveAspectRatio="none">
|
||||
<path opacity="0.8" transform="translate(0 0)" d="M2 14 V18 H6 V14z">
|
||||
<animateTransform attributeName="transform" type="translate" values="0 0; 24 0; 0 0" dur="2s" begin="0" repeatCount="indefinite" keySplines="0.2 0.2 0.4 0.8;0.2 0.2 0.4 0.8" calcMode="spline" />
|
||||
</path>
|
||||
<path opacity="0.5" transform="translate(0 0)" d="M0 14 V18 H8 V14z">
|
||||
<animateTransform attributeName="transform" type="translate" values="0 0; 24 0; 0 0" dur="2s" begin="0.1s" repeatCount="indefinite" keySplines="0.2 0.2 0.4 0.8;0.2 0.2 0.4 0.8" calcMode="spline" />
|
||||
</path>
|
||||
<path opacity="0.25" transform="translate(0 0)" d="M0 14 V18 H8 V14z">
|
||||
<animateTransform attributeName="transform" type="translate" values="0 0; 24 0; 0 0" dur="2s" begin="0.2s" repeatCount="indefinite" keySplines="0.2 0.2 0.4 0.8;0.2 0.2 0.4 0.8" calcMode="spline" />
|
||||
</path>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 980 B |
BIN
src/mixly/board/ThirdParty/common/media/logo.png
vendored
|
Before Width: | Height: | Size: 874 B |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 15 KiB |
BIN
src/mixly/board/ThirdParty/common/media/mark/act.png
vendored
|
Before Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 954 B |
|
Before Width: | Height: | Size: 1.2 KiB |
BIN
src/mixly/board/ThirdParty/common/media/mark/ai.png
vendored
|
Before Width: | Height: | Size: 16 KiB |
BIN
src/mixly/board/ThirdParty/common/media/mark/ai2.png
vendored
|
Before Width: | Height: | Size: 15 KiB |
BIN
src/mixly/board/ThirdParty/common/media/mark/av.png
vendored
|
Before Width: | Height: | Size: 576 B |
BIN
src/mixly/board/ThirdParty/common/media/mark/av2.png
vendored
|
Before Width: | Height: | Size: 513 B |
|
Before Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 946 B |
|
Before Width: | Height: | Size: 729 B |
|
Before Width: | Height: | Size: 465 B |
|
Before Width: | Height: | Size: 389 B |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 15 KiB |