Quellcode durchsuchen

Signed-off-by: Changpeng Duan <838560574@qq.com>

Changpeng Duan vor 5 Jahren
Ursprung
Commit
e321186fcd
100 geänderte Dateien mit 11911 neuen und 3125 gelöschten Zeilen
  1. 9 4
      app/.gitignore
  2. 31 15
      app/README.md
  3. 5 0
      app/babel.config.js
  4. 0 44
      app/index.html
  5. 35 53
      app/package.json
  6. BIN
      app/public/favicon.ico
  7. 19 0
      app/public/index.html
  8. 45 10
      app/src/App.vue
  9. 99 548
      app/src/Global.js
  10. 141 0
      app/src/Mock/index.js
  11. 59 0
      app/src/api/getApiRes.js
  12. 110 0
      app/src/components/BaseCharts.js
  13. 63 0
      app/src/components/LineExample.js
  14. 3833 0
      app/src/components/address3.json
  15. 388 0
      app/src/components/appHeader.vue
  16. 47 0
      app/src/components/bottomTab.vue
  17. 139 0
      app/src/components/cityPicker.vue
  18. 396 0
      app/src/components/mapDrag.vue
  19. 581 0
      app/src/components/mapPage.vue
  20. 218 0
      app/src/components/statischart.vue
  21. 152 0
      app/src/components/statischart2.vue
  22. 134 0
      app/src/language/en-US.js
  23. 135 0
      app/src/language/ru-RU.js
  24. 135 0
      app/src/language/zh-CN.js
  25. 133 25
      app/src/main.js
  26. 44 0
      app/src/page/404.vue
  27. 257 0
      app/src/page/detector.vue
  28. 140 0
      app/src/page/detectorDetail.vue
  29. 176 0
      app/src/page/enterpriseDetail.vue
  30. 376 0
      app/src/page/enterprisemanage.vue
  31. 32 0
      app/src/page/index.vue
  32. 354 0
      app/src/page/listDetail.vue
  33. 434 0
      app/src/page/login.vue
  34. 317 0
      app/src/page/mainpage.vue
  35. 51 0
      app/src/page/map.vue
  36. 47 0
      app/src/page/modal.vue
  37. 61 0
      app/src/page/notFound.vue
  38. 332 0
      app/src/page/plane.vue
  39. 265 0
      app/src/page/profile.vue
  40. 706 0
      app/src/page/record.vue
  41. 318 0
      app/src/page/runtime.vue
  42. 148 0
      app/src/page/setting.vue
  43. 50 0
      app/src/page/statis.vue
  44. 157 0
      app/src/page/userDetail.vue
  45. 212 0
      app/src/page/usermanage.vue
  46. 360 0
      app/src/page/white.vue
  47. 0 152
      app/src/pages/basic.vue
  48. 0 67
      app/src/pages/category.vue
  49. 0 39
      app/src/pages/chart.vue
  50. 0 77
      app/src/pages/detail.vue
  51. 0 92
      app/src/pages/index.vue
  52. 0 132
      app/src/pages/main.vue
  53. 0 138
      app/src/pages/mine.vue
  54. 0 36
      app/src/pages/model.vue
  55. 0 366
      app/src/pages/news.vue
  56. 0 53
      app/src/pages/order.vue
  57. 0 304
      app/src/pages/phone.vue
  58. 0 154
      app/src/pages/pwd.vue
  59. 0 116
      app/src/pages/safe.vue
  60. 0 451
      app/src/pages/search.vue
  61. 0 164
      app/src/pages/setting.vue
  62. 167 85
      app/src/router/index.js
  63. 0 0
      app/src/static/images/comm/arrow-left.png
  64. BIN
      app/src/static/images/comm/b11.png
  65. BIN
      app/src/static/images/comm/b11_1.png
  66. BIN
      app/src/static/images/comm/b12.png
  67. BIN
      app/src/static/images/comm/b12_1.png
  68. BIN
      app/src/static/images/comm/b13.png
  69. BIN
      app/src/static/images/comm/b13_1.png
  70. BIN
      app/src/static/images/comm/b14.png
  71. BIN
      app/src/static/images/comm/b14_1.png
  72. BIN
      app/src/static/images/comm/cityPicker.png
  73. BIN
      app/src/static/images/comm/headerBg.png
  74. BIN
      app/src/static/images/comm/iconEquipmanage.png
  75. BIN
      app/src/static/images/comm/iconEquipmanage_a.png
  76. BIN
      app/src/static/images/comm/iconHome.png
  77. BIN
      app/src/static/images/comm/iconHome_a.png
  78. BIN
      app/src/static/images/comm/iconMap.png
  79. BIN
      app/src/static/images/comm/iconMap_a.png
  80. BIN
      app/src/static/images/comm/iconProfile.png
  81. BIN
      app/src/static/images/comm/iconProfile_a.png
  82. BIN
      app/src/static/images/comm/iconRecord.png
  83. BIN
      app/src/static/images/comm/iconRecord_a.png
  84. BIN
      app/src/static/images/comm/iconRuntime.png
  85. BIN
      app/src/static/images/comm/iconRuntime_a.png
  86. BIN
      app/src/static/images/comm/iconStatis.png
  87. BIN
      app/src/static/images/comm/iconStatis_a.png
  88. BIN
      app/src/static/images/comm/iconUser.png
  89. BIN
      app/src/static/images/comm/iconUser_a.png
  90. BIN
      app/src/static/images/comm/list.png
  91. BIN
      app/src/static/images/comm/right.png
  92. 0 0
      app/src/static/images/comm/tab01.png
  93. 0 0
      app/src/static/images/comm/tab01_b.png
  94. 0 0
      app/src/static/images/comm/tab02.png
  95. 0 0
      app/src/static/images/comm/tab02_b.png
  96. 0 0
      app/src/static/images/comm/tab03.png
  97. 0 0
      app/src/static/images/comm/tab03_b.png
  98. 0 0
      app/src/static/images/comm/tab04.png
  99. 0 0
      app/src/static/images/comm/tab04_b.png
  100. 0 0
      app/src/static/images/comm/tab05.png

+ 9 - 4
app/.gitignore

@@ -1,6 +1,12 @@
 .DS_Store
-node_modules/
-/dist/
+node_modules
+/dist
+
+# local env files
+.env.local
+.env.*.local
+
+# Log files
 npm-debug.log*
 yarn-debug.log*
 yarn-error.log*
@@ -12,5 +18,4 @@ yarn-error.log*
 *.ntvs*
 *.njsproj
 *.sln
-.idea
-*.xml
+*.sw?

+ 31 - 15
app/README.md

@@ -1,25 +1,41 @@
-# app_template
+# musevue
 
-> A Vue.js project
-
-## Build Setup
-
-``` bash
-# install dependencies
+## Project setup
+```
 npm install
+```
 
-# serve with hot reload at localhost:8080
-npm run dev
+### Compiles and hot-reloads for development
+```
+npm run serve
+```
 
-# build for production with minification
+### Compiles and minifies for production
+```
 npm run build
+```
 
-# build for production and view the bundle analyzer report
-npm run build --report
+### Lints and fixes files
+```
+npm run lint
 ```
 
-For a detailed explanation on how things work, check out the [guide](http://vuejs-templates.github.io/webpack/) and [docs for vue-loader](http://vuejs.github.io/vue-loader).
+### Customize configuration
+See [Configuration Reference](https://cli.vuejs.org/config/).
+
+##
+
+=====
+toast
+
+<mu-snackbar :position="normal.position" :open.sync="normal.open" :color="normal.color">
+{{normal.message}}
+<mu-button flat slot="action" color="secondary" @click="normal.open = false">关闭</mu-button>
+</mu-snackbar>
+    
+data
 
-20200824 小飞龙 APP
+normal:normal,
 
-for wechat and apps
+使用
+Toast(msg,color);

+ 5 - 0
app/babel.config.js

@@ -0,0 +1,5 @@
+module.exports = {
+  presets: [
+    '@vue/cli-plugin-babel/preset'
+  ]
+}

+ 0 - 44
app/index.html

@@ -1,44 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-    <meta charset="utf-8">
-    <meta name="viewport" content="width=device-width,initial-scale=1.0">
-    <title>app_template</title>
-    <meta name="keywords" content="xxx">
-    <meta name="description"
-          content="xxx">
-</head>
-<script src="static/mui/js/mui.min.js"></script>
-<script type="text/javascript" charset="utf-8">
-    if (typeof mui === "function") {
-        mui.init({
-            keyEventBind: {
-                backbutton: true  //关闭back按键监听
-            }
-        });
-        var mui_old_back = mui.back;
-        var mui_is_switch = 1;
-        mui.back = function(){
-            var arr = location.href.split('#');
-            if(arr[1] == '/main' || arr[1] == '/login' || arr[1] == '/'){
-                if(mui_is_switch == 1){
-                    mui.toast("再按一次退出应用");
-                    mui_is_switch = 2;
-                }else{
-                    plus.runtime.quit();
-                }
-            }else{
-                mui_old_back();
-                //history.go(-1)//回退到上一页面
-            }
-        }
-    }
-</script>
-<div style="display: none">
-   <!--友盟统计-->
-</div>
-<body>
-<div id="app"></div>
-</body>
-
-</html>

+ 35 - 53
app/package.json

@@ -1,66 +1,48 @@
 {
-  "name": "app_template",
-  "version": "1.0.0",
-  "description": "A Vue.js project",
-  "author": "Changpeng Duan <838560574@qq.com>",
+  "name": "xiaofeilong",
+  "version": "0.1.0",
   "private": true,
   "scripts": {
-    "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
-    "start": "npm run dev",
-    "build": "node build/build.js"
+    "serve": "vue-cli-service serve",
+    "build": "vue-cli-service build",
+    "lint": "vue-cli-service lint"
   },
   "dependencies": {
-    "axios": "^0.18.0",
-    "mint-ui": "^2.2.13",
-    "mockjs": "^1.0.1-beta3",
-    "vue": "^2.5.2",
-    "vue-router": "^3.0.1",
-    "vuex": "^3.1.0"
+    "axios": "^0.19.2",
+    "chart.js": "^2.9.3",
+    "core-js": "^3.6.4",
+    "muse-ui": "^3.0.2",
+    "muse-ui-loading": "^0.2.0",
+    "muse-ui-toast": "^0.3.0",
+    "vue": "^2.6.11",
+    "vue-router": "^3.1.5"
   },
   "devDependencies": {
-    "autoprefixer": "^7.1.2",
-    "babel-core": "^6.22.1",
-    "babel-helper-vue-jsx-merge-props": "^2.0.3",
-    "babel-loader": "^7.1.1",
-    "babel-plugin-syntax-jsx": "^6.18.0",
-    "babel-plugin-transform-runtime": "^6.22.0",
-    "babel-plugin-transform-vue-jsx": "^3.5.0",
-    "babel-preset-env": "^1.3.2",
-    "babel-preset-stage-2": "^6.22.0",
-    "chalk": "^2.0.1",
-    "copy-webpack-plugin": "^4.0.1",
-    "css-loader": "^0.28.0",
-    "extract-text-webpack-plugin": "^3.0.0",
-    "file-loader": "^1.1.4",
-    "friendly-errors-webpack-plugin": "^1.6.1",
-    "html-webpack-plugin": "^2.30.1",
-    "node-notifier": "^5.1.2",
-    "optimize-css-assets-webpack-plugin": "^3.2.0",
-    "ora": "^1.2.0",
-    "portfinder": "^1.0.13",
-    "postcss-import": "^11.0.0",
-    "postcss-loader": "^2.0.8",
-    "postcss-url": "^7.2.1",
-    "rimraf": "^2.6.0",
-    "semver": "^5.3.0",
-    "shelljs": "^0.7.6",
-    "uglifyjs-webpack-plugin": "^1.1.1",
-    "url-loader": "^0.5.8",
-    "vue-loader": "^13.3.0",
-    "vue-style-loader": "^3.0.1",
-    "vue-template-compiler": "^2.5.2",
-    "webpack": "^3.6.0",
-    "webpack-bundle-analyzer": "^2.9.0",
-    "webpack-dev-server": "^2.9.1",
-    "webpack-merge": "^4.1.0"
+    "@vue/cli-plugin-babel": "~4.2.0",
+    "@vue/cli-plugin-eslint": "~4.2.0",
+    "@vue/cli-plugin-router": "^4.2.2",
+    "@vue/cli-service": "~4.2.0",
+    "babel-eslint": "^10.0.3",
+    "eslint": "^6.7.2",
+    "eslint-plugin-vue": "^6.1.2",
+    "vue-cli-plugin-axios": "0.0.4",
+    "vue-template-compiler": "^2.6.11"
   },
-  "engines": {
-    "node": ">= 6.0.0",
-    "npm": ">= 3.0.0"
+  "eslintConfig": {
+    "root": true,
+    "env": {
+      "node": true
+    },
+    "extends": [
+      "plugin:vue/essential",
+      "eslint:recommended"
+    ],
+    "parserOptions": {
+      "parser": "babel-eslint"
+    }
   },
   "browserslist": [
     "> 1%",
-    "last 2 versions",
-    "not ie <= 8"
+    "last 2 versions"
   ]
 }

BIN
app/public/favicon.ico


+ 19 - 0
app/public/index.html

@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="utf-8">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+    <meta name="viewport" content="width=device-width,initial-scale=1.0">
+    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
+    <title><%= htmlWebpackPlugin.options.title %></title>
+    <link rel="stylesheet" href="https://cdn.bootcss.com/material-design-icons/3.0.1/iconfont/material-icons.css">
+</head>
+<body>
+<noscript>
+    <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled.
+        Please enable it to continue.</strong>
+</noscript>
+<div id="app"></div>
+<!-- built files will be auto injected -->
+</body>
+</html>

+ 45 - 10
app/src/App.vue

@@ -1,25 +1,60 @@
 <template>
-  <div id="app">
-    <router-view/>
-  </div>
+    <div id="app">
+        <transition name="fade">
+            <router-view/>
+        </transition>
+    </div>
 </template>
 
-<script>
-export default {
-  name: 'App'
-}
-</script>
-
 <style>
     #app {
         position: absolute;
         top: 0;
-        bottom: 0;
         left: 0;
         right: 0;
+        bottom: 0;
         width: 100%;
+        height: 100%;
+        overflow-y: hidden;
+    }
+
+    #nav {
+        padding: 30px;
+    }
+
+    #nav a {
+        font-weight: bold;
+        color: #2c3e50;
+    }
+
+    #nav a.router-link-exact-active {
+        color: #42b983;
+    }
+
+    ul, li {
+        list-style: none;
+        padding: 0;
+    }
+
+    s, i, em {
+        text-decoration: none;
+        font-style: normal;
+    }
+
+    .mu-loading-wrap {
+        width: 50px;
         overflow: hidden;
         display: block;
         margin: 0 auto;
+        margin-top: 10px;
+        background-color: transparent !important;
+    }
+
+    .mu-warning-color {
+        background: rgb(255, 162, 0) !important;
+    }
+
+    .mu-appbar-title {
+        font-size: 18px !important;
     }
 </style>

+ 99 - 548
app/src/Global.js

@@ -1,87 +1,54 @@
-globalVersion = function () {
-    return '1.0.1';
-};
-companyInfo = {
-    url: 'http://bobox360.com/',
-    main: 'BOBO',
-    year: new Date().getFullYear(),
-};
-
-thisglobal = function () {
-    return 123
-};
-
 headapi = process.env.NODE_ENV === 'development' ? '/api/' : '../';
 
-// login
-globalCompany = function () {
-    let globalCompany = {
-        name: 'xxx',
-        tel: '400-000-0000',
-        app: '设备管理总后台',
-        url: 'xxx.xxx.com'
-    };
-    return globalCompany
+//Toast
+Toast = function (message, color) {
+    // normal.open = true;
+    // normal.message = message;
+    // normal.color = !color ? 'warning' : color;
+    // normal.timer = setTimeout(() => {
+    //     normal.open = false;
+    // }, normal.timeout);
+    this.$toast.message(message);
 };
 
-// 获取周数据
-globalWeeks = function () {
-    let arr = [];
-    let t = 0;
-    for (var i = 0; i < 53; i++) {
-        t = i+1 < 10 ? '0' + (i + 1) : i + 1;
-        arr.push(t );
-    }
-    return arr;
+// Toast default setting
+normal = {
+    color: 'warning', // ['success', 'info', 'error', 'warning'],
+    position: 'top',
+    message: 'Hello World, Snackbar !',
+    open: false,
+    timeout: 3000
 };
 
-globaroundYear = function () {
-    let currentyear = new Date().getFullYear();
-    let arr = [currentyear - 1, currentyear, currentyear + 1]
-    return arr;
+globaltime2StringNoMin = function (time) {
+    let datetime = new Date();
+    datetime.setTime(time);
+    let year = datetime.getFullYear();
+    let month = datetime.getMonth() + 1 < 10 ? "0" + (datetime.getMonth() + 1) : datetime.getMonth() + 1;
+    let date = datetime.getDate() < 10 ? "0" + datetime.getDate() : datetime.getDate();
+    let hour = datetime.getHours() < 10 ? "0" + datetime.getHours() : datetime.getHours();
+    let minus = datetime.getMinutes() < 10 ? "0" + datetime.getMinutes() : datetime.getMinutes();
+    return year + "-" + month + "-" + date;
 };
 
-// 星期转换成中文数字
-weekdayTurnC = function (getDay) {
-    switch (parseInt(getDay)) {
-        case 1:
-            return '一';
-            break;
-        case 2:
-            return '二';
-            break;
-        case 3:
-            return '三';
-            break;
-        case 4:
-            return '四';
-            break;
-        case 5:
-            return '五';
-            break;
-        case 6:
-            return '六';
-            break;
-        case 0:
-            return '天';
-            break;
-    }
+globalBt2 = function () {
+    const et = new Date();
+    const bt = new Date();
+    bt.setTime(bt.getTime() - 3600 * 1000 * 24 * 7);
+    return [bt, et];
 };
 
-// 获取当前第几周
-globalGetCurrentWeeks = function (a, b, c) {
-    //date1是当前日期
-    //date2是当年第一天
-    //d是当前日期是今年第多少天
-    //用d + 当前年的第一天的周差距的和在除以7就是本年第几周
-    let date1 = new Date(a, parseInt(b) - 1, c), date2 = new Date(a, 0, 1),
-        d = Math.round((date1.valueOf() - date2.valueOf()) / 86400000);
-    let res = Math.ceil((d + ((date2.getDay() + 1) - 1)) / 7);
-    res = res < 10 ? '0' + res : res;
-    return res
-};
+globalTimeToYY = function () {
+    let datetime = new Date();
+    let year = datetime.getFullYear();
+    let month = datetime.getMonth() + 1 < 10 ? "0" + (datetime.getMonth() + 1) : datetime.getMonth() + 1;
+    let date = datetime.getDate() < 10 ? "0" + datetime.getDate() : datetime.getDate();
+    console.log(year + "-" + month + "-" + date);
+    return year + "-" + month + "-" + date;
 
-globalgetcurrent = function () {
+};
+// 获取当前时间
+globalcurrent = function () {
     let date = new Date();
     let seperator1 = "-";
     let year = date.getFullYear();
@@ -93,384 +60,8 @@ globalgetcurrent = function () {
     if (strDate >= 0 && strDate <= 9) {
         strDate = "0" + strDate;
     }
-    var currentdate = year + '年' + month + '月' + strDate + '日';
-    return currentdate;
-};
-
-// 第一周转换为日期
-globalWeeksTurnDate = function (year, weeks) {
-    var date = new Date(year, "0", "1");
-    var time = date.getTime(); // 获取当前星期几,0:星期一
-    var _week = date.getDay();    //当这一年的1月1日为周日时则本年有54周,否则没有54周,没有则去除第54周的提示
-    if (_week != 0) {//一年53周情况
-        if (weeks == 54) {
-            return '今年没有54周';
-        }
-        var cnt = 0;// 获取距离周末的天数
-        if (_week == 0) {
-            cnt = 7;
-        } else if (_week == 1) {
-            cnt = 6;
-        } else if (_week == 2) {
-            cnt = 5;
-        } else if (_week == 3) {
-            cnt = 4;
-        } else if (_week == 4) {
-            cnt = 3;
-        } else if (_week == 5) {
-            cnt = 2;
-        } else if (_week == 6) {
-            cnt = 1;
-        }
-        cnt += 1;//加1表示以星期一为一周的第一天    // 将这个长整形时间加上第N周的时间偏移
-        time += cnt * 24 * 3600000; //第2周开始时间
-        var nextYear = new Date(parseInt(year, 10) + 1, "0", "1");
-        var nextWeek = nextYear.getDay();
-        var lastcnt = 0;//获取最后一周开始时间到周末的天数
-        if (nextWeek == 0) {
-            lastcnt = 6;
-        } else if (nextWeek == 1) {
-            lastcnt = 0;
-        } else if (nextWeek == 2) {
-            lastcnt = 1;
-        } else if (nextWeek == 3) {
-            lastcnt = 2;
-        } else if (nextWeek == 4) {
-            lastcnt = 3;
-        } else if (nextWeek == 5) {
-            lastcnt = 4;
-        } else if (nextWeek == 6) {
-            lastcnt = 5;
-        }
-        if (weeks == 1) {//第1周特殊处理    // 为日期对象 date 重新设置成时间 time
-            var start = date.Format("MM/dd");
-            date.setTime(time - 24 * 3600000);
-            var _end = date.Format("MM/dd");
-            return start + "-" + _end;
-        } else if (weeks == 53) {//第53周特殊处理
-            var start = time + (weeks - 2) * 7 * 24 * 3600000; //第53周开始时间
-            var end = time + (weeks - 2) * 7 * 24 * 3600000 + lastcnt * 24 * 3600000 - 24 * 3600000; //第53周结束时间
-            date.setTime(start);
-            var _start = date.Format("MM/dd");
-            date.setTime(end);
-            var _end = date.Format("MM/dd");
-            return _start + "-" + _end;
-        } else {
-            var start = time + (weeks - 2) * 7 * 24 * 3600000; //第n周开始时间
-            var end = time + (weeks - 1) * 7 * 24 * 3600000 - 24 * 3600000; //第n周结束时间
-            date.setTime(start);
-            var _start = date.Format("MM/dd");
-            date.setTime(end);
-            var _end = date.Format("MM/dd");
-            return _start + "-" + _end;
-        }
-    } else {//一年54周情况
-        var cnt = 0;// 获取距离周末的天数
-        if (_week == 0 && weeks == 1) {//第一周
-            cnt = 0;
-        } else if (_week == 0) {
-            cnt = 7;
-        } else if (_week == 1) {
-            cnt = 6;
-        } else if (_week == 2) {
-            cnt = 5;
-        } else if (_week == 3) {
-            cnt = 4;
-        } else if (_week == 4) {
-            cnt = 3;
-        } else if (_week == 5) {
-            cnt = 2;
-        } else if (_week == 6) {
-            cnt = 1;
-        }
-        cnt += 1;//加1表示以星期一为一周的第一天
-        // 将这个长整形时间加上第N周的时间偏移
-        time += 24 * 3600000; //第2周开始时间
-        var nextYear = new Date(parseInt(year, 10) + 1, "0", "1");
-        var nextWeek = nextYear.getDay();
-        var lastcnt = 0;//获取最后一周开始时间到周末的天数
-        if (nextWeek == 0) {
-            lastcnt = 6;
-        } else if (nextWeek == 1) {
-            lastcnt = 0;
-        } else if (nextWeek == 2) {
-            lastcnt = 1;
-        } else if (nextWeek == 3) {
-            lastcnt = 2;
-        } else if (nextWeek == 4) {
-            lastcnt = 3;
-        } else if (nextWeek == 5) {
-            lastcnt = 4;
-        } else if (nextWeek == 6) {
-            lastcnt = 5;
-        }
-        if (weeks == 1) {//第1周特殊处理
-            var start = date.Format("yyyy-MM-dd");
-            date.setTime(time - 24 * 3600000);
-            alert(start + '--' + date);
-            return _start + "--" + date;
-        } else if (weeks == 54) {//第54周特殊处理
-            var start = time + (weeks - 2) * 7 * 24 * 3600000; //第54周开始时间
-            var end = time + (weeks - 2) * 7 * 24 * 3600000 + lastcnt * 24 * 3600000 - 24 * 3600000; //第53周结束时间
-            date.setTime(start);
-            var _start = date.Format("yyyy-MM-dd");
-            date.setTime(end);
-            var _end = date.Format("yyyy-MM-dd");
-            return _start + "--" + _end;
-        } else {
-            var start = time + (weeks - 2) * 7 * 24 * 3600000; //第n周开始时间
-            var end = time + (weeks - 1) * 7 * 24 * 3600000 - 24 * 3600000; //第n周结束时间
-            date.setTime(start);
-            var _start = date.Format("yyyy-MM-dd");
-            date.setTime(end);
-            var _end = date.Format("yyyy-MM-dd");
-            return _start + "--" + _end;
-        }
-    }
-};
-
-Date.prototype.Format = function (fmt) { //author: meizz
-    var o = {
-        "M+": this.getMonth() + 1,                 //月份
-        "d+": this.getDate(),                    //日
-        "h+": this.getHours(),                   //小时
-        "m+": this.getMinutes(),                 //分
-        "s+": this.getSeconds(),                 //秒
-        "q+": Math.floor((this.getMonth() + 3) / 3), //季度
-        "S": this.getMilliseconds()             //毫秒
-    };
-    if (/(y+)/.test(fmt))
-        fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
-    for (var k in o)
-        if (new RegExp("(" + k + ")").test(fmt))
-            fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
-    return fmt;
-};
-
-// 获取周最后一天
-globalWeekEndDay = function (year, weeks) {
-    var date = new Date(year, "0", "1");
-    var time = date.getTime(); // 获取当前星期几,0:星期一
-    var _week = date.getDay();    //当这一年的1月1日为周日时则本年有54周,否则没有54周,没有则去除第54周的提示
-    if (_week != 0) {//一年53周情况
-        if (weeks == 54) {
-            return '今年没有54周';
-        }
-        var cnt = 0;// 获取距离周末的天数
-        if (_week == 0) {
-            cnt = 7;
-        } else if (_week == 1) {
-            cnt = 6;
-        } else if (_week == 2) {
-            cnt = 5;
-        } else if (_week == 3) {
-            cnt = 4;
-        } else if (_week == 4) {
-            cnt = 3;
-        } else if (_week == 5) {
-            cnt = 2;
-        } else if (_week == 6) {
-            cnt = 1;
-        }
-        cnt += 1;//加1表示以星期一为一周的第一天    // 将这个长整形时间加上第N周的时间偏移
-        time += cnt * 24 * 3600000; //第2周开始时间
-        var nextYear = new Date(parseInt(year, 10) + 1, "0", "1");
-        var nextWeek = nextYear.getDay();
-        var lastcnt = 0;//获取最后一周开始时间到周末的天数
-        if (nextWeek == 0) {
-            lastcnt = 6;
-        } else if (nextWeek == 1) {
-            lastcnt = 0;
-        } else if (nextWeek == 2) {
-            lastcnt = 1;
-        } else if (nextWeek == 3) {
-            lastcnt = 2;
-        } else if (nextWeek == 4) {
-            lastcnt = 3;
-        } else if (nextWeek == 5) {
-            lastcnt = 4;
-        } else if (nextWeek == 6) {
-            lastcnt = 5;
-        }
-        if (weeks == 1) {//第1周特殊处理    // 为日期对象 date 重新设置成时间 time
-            var start = date.Format("MM/dd");
-            date.setTime(time - 24 * 3600000);
-            var _end = date.Format("-MM-dd");
-            return year + _end;
-        } else if (weeks == 53) {//第53周特殊处理
-            var start = time + (weeks - 2) * 7 * 24 * 3600000; //第53周开始时间
-            var end = time + (weeks - 2) * 7 * 24 * 3600000 + lastcnt * 24 * 3600000 - 24 * 3600000; //第53周结束时间
-            date.setTime(start);
-            var _start = date.Format("MM/dd");
-            date.setTime(end);
-            var _end = date.Format("-MM-dd");
-            return year + _end;
-        } else {
-            var start = time + (weeks - 2) * 7 * 24 * 3600000; //第n周开始时间
-            var end = time + (weeks - 1) * 7 * 24 * 3600000 - 24 * 3600000; //第n周结束时间
-            date.setTime(start);
-            var _start = date.Format("MM/dd");
-            date.setTime(end);
-            var _end = date.Format("-MM-dd");
-            return year + _end;
-        }
-    } else {//一年54周情况
-        var cnt = 0;// 获取距离周末的天数
-        if (_week == 0 && weeks == 1) {//第一周
-            cnt = 0;
-        } else if (_week == 0) {
-            cnt = 7;
-        } else if (_week == 1) {
-            cnt = 6;
-        } else if (_week == 2) {
-            cnt = 5;
-        } else if (_week == 3) {
-            cnt = 4;
-        } else if (_week == 4) {
-            cnt = 3;
-        } else if (_week == 5) {
-            cnt = 2;
-        } else if (_week == 6) {
-            cnt = 1;
-        }
-        cnt += 1;//加1表示以星期一为一周的第一天
-        // 将这个长整形时间加上第N周的时间偏移
-        time += 24 * 3600000; //第2周开始时间
-        var nextYear = new Date(parseInt(year, 10) + 1, "0", "1");
-        var nextWeek = nextYear.getDay();
-        var lastcnt = 0;//获取最后一周开始时间到周末的天数
-        if (nextWeek == 0) {
-            lastcnt = 6;
-        } else if (nextWeek == 1) {
-            lastcnt = 0;
-        } else if (nextWeek == 2) {
-            lastcnt = 1;
-        } else if (nextWeek == 3) {
-            lastcnt = 2;
-        } else if (nextWeek == 4) {
-            lastcnt = 3;
-        } else if (nextWeek == 5) {
-            lastcnt = 4;
-        } else if (nextWeek == 6) {
-            lastcnt = 5;
-        }
-        if (weeks == 1) {//第1周特殊处理
-            var start = date.Format("yyyy-MM-dd");
-            date.setTime(time - 24 * 3600000);
-            alert(start + '--' + date);
-            return _start + "--" + date;
-        } else if (weeks == 54) {//第54周特殊处理
-            var start = time + (weeks - 2) * 7 * 24 * 3600000; //第54周开始时间
-            var end = time + (weeks - 2) * 7 * 24 * 3600000 + lastcnt * 24 * 3600000 - 24 * 3600000; //第53周结束时间
-            date.setTime(start);
-            var _start = date.Format("yyyy-MM-dd");
-            date.setTime(end);
-            var _end = date.Format("yyyy-MM-dd");
-            return _start + "--" + _end;
-        } else {
-            var start = time + (weeks - 2) * 7 * 24 * 3600000; //第n周开始时间
-            var end = time + (weeks - 1) * 7 * 24 * 3600000 - 24 * 3600000; //第n周结束时间
-            date.setTime(start);
-            var _start = date.Format("yyyy-MM-dd");
-            date.setTime(end);
-            var _end = date.Format("yyyy-MM-dd");
-            return _start + "--" + _end;
-        }
-    }
-};
-
-// 获取周最后一天
-globalMonEndDay = function (year, mons) {
-    let date = year + '-' + mons
-    let endDate = new Date(date); //date 是需要传递的时间如:2018-08
-    let month = endDate.getMonth();
-    let nextMonth = ++month;
-    let nextMonthFirstDay = new Date(endDate.getFullYear(), nextMonth, 1);
-    let oneDay = 1000 * 60 * 60 * 24;
-    let dateString = new Date(nextMonthFirstDay - oneDay);
-    let dateYar = dateString.toLocaleDateString(); //toLocaleDateString() 返回 如:2018/8/31
-    var end = dateYar.replace(new RegExp('/', 'g'), "-");
-    return end
-};
-
-// 设备状态
-globalQuipState = function () {
-    let option = [
-        {
-            value: '',
-            label: '全部'
-        }, {
-            value: '0',
-            label: '新入库'
-        }, {
-            value: '1',
-            label: '未售'
-        }, {
-            value: '2',
-            label: '未售'
-        }, {
-            value: '3',
-            label: '已售'
-        }, {
-            value: '4',
-            label: '维修'
-        }, {
-            value: '5',
-            label: '报废'
-        }, {
-            value: '6',
-            label: '已售未入'
-        }
-    ];
-    return option
-};
-
-// 操作员
-globalOperatorList = function () {
-    let option = [
-        {
-            value: '',
-            label: '全部'
-        }, {
-            value: '0',
-            label: '高瑟'
-        }, {
-            value: '1',
-            label: '林克'
-        }, {
-            value: '2',
-            label: '小智'
-        },
-    ];
-    return option
-};
-
-// 产品线状态
-globalLinestatusOpt = function () {
-    let option = [
-        {
-            value: '',
-            label: '全部'
-        }, {
-            value: '0',
-            label: '禁用'
-        }, {
-            value: '1',
-            label: '启用'
-        }, {
-            value: '44',
-            label: '删除'
-        },
-    ];
-    return option
-};
-
-// 开始时间
-globalBt = function () {
-    const et = new Date();
-    const bt = new Date();
-    bt.setTime(bt.getTime() - 3600 * 1000 * 24 * 7);
-    return [bt, et];
+    let thisdata = year + seperator1 + month + seperator1 + strDate;
+    return thisdata;
 };
 
 // 格式化时间
@@ -482,7 +73,6 @@ globalfmtDate = function (datetime, length) {
     length = !length ? 10 : length;//缺省参数
     return (datetime != null) ? datetime.substr(0, length) : '';
 };
-
 //格式化日期  年月日
 globaltime2String = function (time) {
     let datetime = new Date();
@@ -490,99 +80,60 @@ globaltime2String = function (time) {
     let year = datetime.getFullYear();
     let month = datetime.getMonth() + 1 < 10 ? "0" + (datetime.getMonth() + 1) : datetime.getMonth() + 1;
     let date = datetime.getDate() < 10 ? "0" + datetime.getDate() : datetime.getDate();
-    return year + "-" + month + "-" + date;
-};
-
-// 获取当前时间
-globalcurrent = function () {
-    let date = new Date();
-    let seperator1 = "-";
-    let year = date.getFullYear();
-    let month = date.getMonth() + 1;
-    let strDate = date.getDate();
-    if (month >= 1 && month <= 9) {
-        month = "0" + month;
-    }
-    if (strDate >= 0 && strDate <= 9) {
-        strDate = "0" + strDate;
-    }
-    let thisdata = year + seperator1 + month + seperator1 + strDate;
-    return thisdata;
-};
-
-// 校验内容长度
-globalValid = function (data, mins, maxs, text, that) {
-    let thisVal = data;
-    let thisLeng = thisVal.length;
-    let min = parseInt(mins);
-    let max = parseInt(maxs);
-    let dispalyMin = min + 1;
-    let title = '警告';
-    if (thisVal == '') {
-        Toast(text + '不能为空!');
-        return false
-    } else if (thisLeng <= min) {
-        Toast(text + '最少' + dispalyMin + '字符!');
-        return false
-    } else if (thisLeng > max) {
-        Toast(text + '超出限制数量!');
-        return false
-    } else {
-        return true
-    }
-};
-
-// 每页选项
-pageOptions = function () {
-    let option = [
-        {
-            value: 10,
-            label: '10'
-        }, {
-            value: 25,
-            label: '25'
-        }, {
-            value: 50,
-            label: '50'
-        }, {
-            value: 100,
-            label: '100'
-        },
-    ];
-    return option
-};
-
-// 手机号码格式
-globalCheckPhone = function (val) {
-    let re = /^1[3|4|5|7|8|9][0-9]\d{8}$/;
-    if (val.search(re) == -1) {
-        return false;
-    } else {
-        return true;
-    }
-};
-
-// session 检测
-globalCheckSession = function (val, that) {
-    if (val == '<script>top.window.location="http://det/?act=login"</script>') {
-        that.$router.push({path: '/login'});
-    }
-};
-
-// 每页选项
-HdOptions = function () {
-    let option = [
-        {
-            value: '',
-            label: '全部'
-        },
-        {
-            value: '1',
-            label: '硬件驱动'
-        }, {
-            value: '2',
-            label: '配置文件'
-        },
-    ];
-    return option
-};
+    let hour = datetime.getHours() < 10 ? "0" + datetime.getHours() : datetime.getHours();
+    let minus = datetime.getMinutes() < 10 ? "0" + datetime.getMinutes() : datetime.getMinutes();
+    return year + "-" + month + "-" + date + " " + hour + ":" + minus + ":00";
+};
+
+address = {
+    '北京': ['北京'],
+    '广东': ['广州', '深圳', '珠海', '汕头', '韶关', '佛山', '江门', '湛江', '茂名', '肇庆', '惠州', '梅州', '汕尾', '河源', '阳江', '清远', '东莞', '中山', '潮州', '揭阳', '云浮'],
+    '上海': ['上海'],
+    '天津': ['天津'],
+    '重庆': ['重庆'],
+    '辽宁': ['沈阳', '大连', '鞍山', '抚顺', '本溪', '丹东', '锦州', '营口', '阜新', '辽阳', '盘锦', '铁岭', '朝阳', '葫芦岛'],
+    '江苏': ['南京', '苏州', '无锡', '常州', '镇江', '南通', '泰州', '扬州', '盐城', '连云港', '徐州', '淮安', '宿迁'],
+    '湖北': ['武汉', '黄石', '十堰', '荆州', '宜昌', '襄樊', '鄂州', '荆门', '孝感', '黄冈', '咸宁', '随州', '恩施土家族苗族自治州', '仙桃', '天门', '潜江', '神农架林区'],
+    '四川': ['成都', '自贡', '攀枝花', '泸州', '德阳', '绵阳', '广元', '遂宁', '内江', '乐山', '南充', '眉山', '宜宾', '广安', '达州', '雅安', '巴中', '资阳', '阿坝藏族羌族自治州', '甘孜藏族自治州', '凉山彝族自治州'],
+    '陕西': ['西安', '铜川', '宝鸡', '咸阳', '渭南', '延安', '汉中', '榆林', '安康', '商洛'],
+    '河北': ['石家庄', '唐山', '秦皇岛', '邯郸', '邢台', '保定', '张家口', '承德', '沧州', '廊坊', '衡水'],
+    '山西': ['太原', '大同', '阳泉', '长治', '晋城', '朔州', '晋中', '运城', '忻州', '临汾', '吕梁'],
+    '河南': ['郑州', '开封', '洛阳', '平顶山', '安阳', '鹤壁', '新乡', '焦作', '濮阳', '许昌', '漯河', '三门峡', '南阳', '商丘', '信阳', '周口', '驻马店'],
+    '吉林': ['长春', '吉林', '四平', '辽源', '通化', '白山', '松原', '白城', '延边朝鲜族自治州'],
+    '黑龙江': ['哈尔滨', '齐齐哈尔', '鹤岗', '双鸭山', '鸡西', '大庆', '伊春', '牡丹江', '佳木斯', '七台河', '黑河', '绥化', '大兴安岭地区'],
+    '内蒙古': ['呼和浩特', '包头', '乌海', '赤峰', '通辽', '鄂尔多斯', '呼伦贝尔', '巴彦淖尔', '乌兰察布', '锡林郭勒盟', '兴安盟', '阿拉善盟'],
+    '山东': ['济南', '青岛', '淄博', '枣庄', '东营', '烟台', '潍坊', '济宁', '泰安', '威海', '日照', '莱芜', '临沂', '德州', '聊城', '滨州', '菏泽'],
+    '安徽': ['合肥', '芜湖', '蚌埠', '淮南', '马鞍山', '淮北', '铜陵', '安庆', '黄山', '滁州', '阜阳', '宿州', '巢湖', '六安', '亳州', '池州', '宣城'],
+    '浙江': ['杭州', '宁波', '温州', '嘉兴', '湖州', '绍兴', '金华', '衢州', '舟山', '台州', '丽水'],
+    '福建': ['福州', '厦门', '莆田', '三明', '泉州', '漳州', '南平', '龙岩', '宁德'],
+    '湖南': ['长沙', '株洲', '湘潭', '衡阳', '邵阳', '岳阳', '常德', '张家界', '益阳', '郴州', '永州', '怀化', '娄底', '湘西土家族苗族自治州'],
+    '广西': ['南宁', '柳州', '桂林', '梧州', '北海', '防城港', '钦州', '贵港', '玉林', '百色', '贺州', '河池', '来宾', '崇左'],
+    '江西': ['南昌', '景德镇', '萍乡', '九江', '新余', '鹰潭', '赣州', '吉安', '宜春', '抚州', '上饶'],
+    '贵州': ['贵阳', '六盘水', '遵义', '安顺', '铜仁地区', '毕节地区', '黔西南布依族苗族自治州', '黔东南苗族侗族自治州', '黔南布依族苗族自治州'],
+    '云南': ['昆明', '曲靖', '玉溪', '保山', '昭通', '丽江', '普洱', '临沧', '德宏傣族景颇族自治州', '怒江傈僳族自治州', '迪庆藏族自治州', '大理白族自治州', '楚雄彝族自治州', '红河哈尼族彝族自治州', '文山壮族苗族自治州', '西双版纳傣族自治州'],
+    '西藏': ['拉萨', '那曲地区', '昌都地区', '林芝地区', '山南地区', '日喀则地区', '阿里地区'],
+    '海南': ['海口', '三亚', '五指山', '琼海', '儋州', '文昌', '万宁', '东方', '澄迈县', '定安县', '屯昌县', '临高县', '白沙黎族自治县', '昌江黎族自治县', '乐东黎族自治县', '陵水黎族自治县', '保亭黎族苗族自治县', '琼中黎族苗族自治县'],
+    '甘肃': ['兰州', '嘉峪关', '金昌', '白银', '天水', '武威', '酒泉', '张掖', '庆阳', '平凉', '定西', '陇南', '临夏回族自治州', '甘南藏族自治州'],
+    '宁夏': ['银川', '石嘴山', '吴忠', '固原', '中卫'],
+    '青海': ['西宁', '海东地区', '海北藏族自治州', '海南藏族自治州', '黄南藏族自治州', '果洛藏族自治州', '玉树藏族自治州', '海西蒙古族藏族自治州'],
+    '新疆': ['乌鲁木齐', '克拉玛依', '吐鲁番地区', '哈密地区', '和田地区', '阿克苏地区', '喀什地区', '克孜勒苏柯尔克孜自治州', '巴音郭楞蒙古自治州', '昌吉回族自治州', '博尔塔拉蒙古自治州', '石河子', '阿拉尔', '图木舒克', '五家渠', '伊犁哈萨克自治州'],
+    '香港': ['香港'],
+    '澳门': ['澳门'],
+    '台湾': ['台北市', '高雄市', '台北县', '桃园县', '新竹县', '苗栗县', '台中县', '彰化县', '南投县', '云林县', '嘉义县', '台南县', '高雄县', '屏东县', '宜兰县', '花莲县', '台东县', '澎湖县', '基隆市', '新竹市', '台中市', '嘉义市', '台南市']
+};
+if (localStorage.language == 'zh') {
+    dayAbbreviation = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
+    dayList = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
+    monthList = ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月',
+        '十月', '十一月', '十二月'];
+    monthLongList = ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月',
+        '十月', '十一月', '十二月'];
+} else {
+    dayAbbreviation = ['S', 'M', 'T', 'W', 'T', 'F', 'S'];
+    dayList = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
+    monthList = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',
+        'Oct', 'Nov', 'Dec'];
+    monthLongList = ['January', 'February', 'March', 'April', 'May', 'June',
+        'July', 'August', 'September', 'October', 'November', 'December'];
+
+}

+ 141 - 0
app/src/Mock/index.js

@@ -0,0 +1,141 @@
+import Mock from 'mockjs'
+
+let Random = Mock.Random;
+
+// worldDetail
+let worldDetail = function () {
+    let item = [];
+    for (var i = 0; i < 30; i++) {
+        item.push({
+            "id": "@guid",
+            "name": "@region",
+            "Confirmed": "@integer(36844, 368449)",
+            "Deaths": "@integer(1099, 10993)",
+            "Recovered": "@integer(1986, 19865)",
+        })
+    }
+
+    let res = {
+        Rs: item,
+        Code: 0,
+        Memo: ''
+    };
+    return res;
+};
+
+let testPic = function () {
+    let res = {
+        pic:  Random.image('200x100', '#894FC4', '#FFF', '@natural(1111, 9999)'),
+        id: "@guid",
+        Code: 0,
+        Memo: ''
+    };
+    return res;
+};
+
+let testTable = function () {
+    let item = [];
+
+    let members = [
+        {id: 1, name: '霍元甲', userCode: '15253135600', vipType: 1},
+        {id: 2, name: '陈真', userCode: '15253135602', vipType: 2},
+        {id: 3, name: '成龙', userCode: '15253135604', vipType: 1},
+    ]
+
+    for (var i = 0; i < 6; i++) {
+        item.push({
+            "id": "@guid",
+            "userCode": "@integer(15253135600, 15253135699)",
+            "name": "@region",
+            "tel": "@integer(15253135600, 15253135699)",
+            "shop": "@region",
+            "create": "@datetime",
+            "expTime": "@datetime",
+            "valid": "@datetime",
+            "Confirmed": "@integer(36844, 368449)",
+            "Deaths": "@integer(1099, 10993)",
+            "Recovered": "@integer(1986, 9999)",
+            "Status": "@integer(1, 2)",
+            "color": "@hex",
+            "memo": "@paragraph(1, 1)",
+            "dialogValue": "@range(1, 3)",
+            "vipType": "@integer(1, 2)",
+            "members": members,
+            "wxVisible": "@integer(0, 1)",
+            "timeScope":  [new Date(2016, 9, 10, 8, 40), new Date(2016, 9, 10, 9, 40)],
+        })
+    }
+
+    let res = {
+        Rs: item,
+        Code: 0,
+        Memo: ''
+    };
+    return res;
+};
+
+let testSelect = function () {
+    let item = [];
+    for (var i = 0; i < 30; i++) {
+        item.push({
+            "key": i + 1,
+            "value": i + 1,
+            "label": "@region",
+        })
+    }
+
+    let res = {
+        Rs: item,
+        Code: 0,
+        Memo: ''
+    };
+    return res;
+};
+
+let SignIn = function () {
+
+    let Rs = {
+        token: "@guid"
+    };
+    let res = {
+        Rs: Rs,
+        Code: 0,
+        Memo: '登陆成功'
+    };
+    return res;
+};
+
+let editbasicinfo = function () {
+
+    let res = {
+        Code: 0,
+        Memo: '修改成功'
+    };
+    return res;
+};
+
+let modPwd = function () {
+    let res = {
+        Code: 0,
+        Memo: '修改成功'
+    };
+    return res;
+};
+let logout = function () {
+    let res = {
+        Code: 0,
+        Memo: '退出成功'
+    };
+    return res;
+};
+
+Mock.mock('/api/testPic', 'post', testPic());
+Mock.mock('/api/testSelect', 'post', testSelect());
+Mock.mock('/api/testTable', 'post', testTable());
+Mock.mock('/api/worldDetail', 'post', worldDetail());
+Mock.mock('/api/SignIn', 'post', SignIn());//用户登录
+Mock.mock('/api/editbasicinfo', 'post', editbasicinfo());//用户设置修改
+Mock.mock('/api/modPwd', 'post', modPwd());//密码修改
+Mock.mock('/api/logout', 'post', logout());//退出登陆
+
+export default Mock;

+ 59 - 0
app/src/api/getApiRes.js

@@ -0,0 +1,59 @@
+import axios from 'axios';
+import global from '../Global.js'
+// 基础方法进行封装
+function getApiBasic(url, postdata) {
+    return  axios.post(url, postdata).then(function(data){
+        let json = data.data;
+        return json
+    },function(response){
+        console.info(response);
+    })
+}
+
+// 调用的api改写成方法
+export function worldDetail(postdata) {
+        let url = headapi + 'worldDetail';
+        return getApiBasic(url,postdata);
+}
+
+export function SignIn(postdata) {
+        let url = headapi + 'SignIn';
+        return getApiBasic(url,postdata);
+}
+export function GenVerifyPic(postdata) {
+        let url = headapi + '/Auth/GenVerifyPic';
+        return getApiBasic(url,postdata);
+}
+
+export function editbasicinfo(postdata) {
+    let url = headapi + 'editbasicinfo';
+    return getApiBasic(url,postdata);
+}
+export function modPwd(postdata) {
+    let url = headapi + 'modPwd';
+    return getApiBasic(url,postdata);
+}
+export function logout(postdata) {
+    let url = headapi + 'logout';
+    return getApiBasic(url,postdata);
+}
+
+// 调用的api改写成方法
+export function testTable(postdata) {
+    let url = headapi + 'testTable';
+    return getApiBasic(url,postdata);
+}
+export function testSelect(postdata) {
+    let url = headapi + 'testSelect';
+    return getApiBasic(url,postdata);
+}
+
+export function testPic(postdata) {
+    let url = headapi + 'testPic';
+    return getApiBasic(url,postdata);
+}
+
+
+
+
+

+ 110 - 0
app/src/components/BaseCharts.js

@@ -0,0 +1,110 @@
+import Chart from 'chart.js'
+
+export function generateChart (chartId, chartType) {
+    return {
+        render: function (createElement) {
+            return createElement(
+                'div', {
+                    style: this.styles,
+                    class: this.cssClasses
+                },
+                [
+                    createElement(
+                        'canvas', {
+                            attrs: {
+                                id: this.chartId,
+                                width: this.width,
+                                height: this.height
+                            },
+                            ref: 'canvas'
+                        }
+                    )
+                ]
+            )
+        },
+
+        props: {
+            chartId: {
+                default: chartId,
+                type: String
+            },
+            width: {
+                default: 400,
+                type: Number
+            },
+            height: {
+                default: 400,
+                type: Number
+            },
+            cssClasses: {
+                type: String,
+                default: ''
+            },
+            styles: {
+                type: Object
+            },
+            plugins: {
+                type: Array,
+                default () {
+                    return []
+                }
+            }
+        },
+
+        data () {
+            return {
+                _chart: null,
+                _plugins: this.plugins
+            }
+        },
+
+        methods: {
+            addPlugin (plugin) {
+                this.$data._plugins.push(plugin)
+            },
+            generateLegend () {
+                if (this.$data._chart) {
+                    return this.$data._chart.generateLegend()
+                }
+            },
+            renderChart (data, options) {
+                if (this.$data._chart) this.$data._chart.destroy()
+                this.$data._chart = new Chart(
+                    this.$refs.canvas.getContext('2d'), {
+                        type: chartType,
+                        data: data,
+                        options: options,
+                        plugins: this.$data._plugins
+                    }
+                )
+            }
+        },
+        beforeDestroy () {
+            if (this.$data._chart) {
+                this.$data._chart.destroy()
+            }
+        }
+    }
+}
+
+export const Bar = generateChart('bar-chart', 'bar')
+export const HorizontalBar = generateChart('horizontalbar-chart', 'horizontalBar')
+export const Doughnut = generateChart('doughnut-chart', 'doughnut')
+export const Line = generateChart('line-chart', 'line')
+export const Pie = generateChart('pie-chart', 'pie')
+export const PolarArea = generateChart('polar-chart', 'polarArea')
+export const Radar = generateChart('radar-chart', 'radar')
+export const Bubble = generateChart('bubble-chart', 'bubble')
+export const Scatter = generateChart('scatter-chart', 'scatter')
+
+export default {
+    Bar,
+    HorizontalBar,
+    Doughnut,
+    Line,
+    Pie,
+    PolarArea,
+    Radar,
+    Bubble,
+    Scatter
+}

+ 63 - 0
app/src/components/LineExample.js

@@ -0,0 +1,63 @@
+import {Line} from './BaseCharts'
+import axios from 'axios';
+
+let qs = require('qs');
+export default {
+    extends: Line,
+    data() {
+        return {
+            labels: [],
+            datasets: [],
+        }
+    },
+    props: ['dataLabels','datadatasets'],
+    watch:{
+        dataLabels(e){
+            this.drawCanvas();
+        },
+        datadatasets(e){
+            this.drawCanvas();
+        }
+    },
+    mounted() {
+      this.drawCanvas();
+    },
+    methods:{
+        drawCanvas(){
+            this.renderChart({
+                labels: this.dataLabels,
+                datasets: [
+                    {
+                        title: {
+                            display: false,
+                            text: 'Custom Chart Title'
+                        },
+                        Legend: {
+                            display: false,
+                        },
+                        label: '',
+                        color: '#FFA200',
+                        borderColor: '#FFA200',
+                        backgroundColor: 'rgba(255,255,255,0)',
+                        data: this.datadatasets
+                    }
+                ]
+            }, {
+                responsive: false,
+                maintainAspectRatio: false,
+                scales: {
+                    yAxes: [{
+                        ticks: {
+                            beginAtZero: true,
+                            callback: function (value) {
+                                if (value % 1 === 0) {
+                                    return value;
+                                }
+                            }
+                        }
+                    }]
+                }
+            })
+        }
+    }
+}

+ 3833 - 0
app/src/components/address3.json

@@ -0,0 +1,3833 @@
+{
+  "北京市": {
+    "市辖区": [
+      "东城区",
+      "西城区",
+      "朝阳区",
+      "丰台区",
+      "石景山区",
+      "海淀区",
+      "门头沟区",
+      "房山区",
+      "通州区",
+      "顺义区",
+      "昌平区",
+      "大兴区",
+      "怀柔区",
+      "平谷区",
+      "密云区",
+      "延庆区"
+    ]
+  },
+  "天津市": {
+    "市辖区": [
+      "和平区",
+      "河东区",
+      "河西区",
+      "南开区",
+      "河北区",
+      "红桥区",
+      "东丽区",
+      "西青区",
+      "津南区",
+      "北辰区",
+      "武清区",
+      "宝坻区",
+      "滨海新区",
+      "宁河区",
+      "静海区",
+      "蓟州区"
+    ]
+  },
+  "河北省": {
+    "石家庄市": [
+      "长安区",
+      "桥西区",
+      "新华区",
+      "井陉矿区",
+      "裕华区",
+      "藁城区",
+      "鹿泉区",
+      "栾城区",
+      "井陉县",
+      "正定县",
+      "行唐县",
+      "灵寿县",
+      "高邑县",
+      "深泽县",
+      "赞皇县",
+      "无极县",
+      "平山县",
+      "元氏县",
+      "赵县",
+      "石家庄高新技术产业开发区",
+      "石家庄循环化工园区",
+      "辛集市",
+      "晋州市",
+      "新乐市"
+    ],
+    "唐山市": [
+      "路南区",
+      "路北区",
+      "古冶区",
+      "开平区",
+      "丰南区",
+      "丰润区",
+      "曹妃甸区",
+      "滦南县",
+      "乐亭县",
+      "迁西县",
+      "玉田县",
+      "唐山市芦台经济技术开发区",
+      "唐山市汉沽管理区",
+      "唐山高新技术产业开发区",
+      "河北唐山海港经济开发区",
+      "遵化市",
+      "迁安市",
+      "滦州市"
+    ],
+    "秦皇岛市": [
+      "海港区",
+      "山海关区",
+      "北戴河区",
+      "抚宁区",
+      "青龙满族自治县",
+      "昌黎县",
+      "卢龙县",
+      "秦皇岛市经济技术开发区",
+      "北戴河新区"
+    ],
+    "邯郸市": [
+      "邯山区",
+      "丛台区",
+      "复兴区",
+      "峰峰矿区",
+      "肥乡区",
+      "永年区",
+      "临漳县",
+      "成安县",
+      "大名县",
+      "涉县",
+      "磁县",
+      "邱县",
+      "鸡泽县",
+      "广平县",
+      "馆陶县",
+      "魏县",
+      "曲周县",
+      "邯郸经济技术开发区",
+      "邯郸冀南新区",
+      "武安市"
+    ],
+    "邢台市": [
+      "桥东区",
+      "桥西区",
+      "邢台县",
+      "临城县",
+      "内丘县",
+      "柏乡县",
+      "隆尧县",
+      "任县",
+      "南和县",
+      "宁晋县",
+      "巨鹿县",
+      "新河县",
+      "广宗县",
+      "平乡县",
+      "威县",
+      "清河县",
+      "临西县",
+      "河北邢台经济开发区",
+      "南宫市",
+      "沙河市"
+    ],
+    "保定市": [
+      "竞秀区",
+      "莲池区",
+      "满城区",
+      "清苑区",
+      "徐水区",
+      "涞水县",
+      "阜平县",
+      "定兴县",
+      "唐县",
+      "高阳县",
+      "容城县",
+      "涞源县",
+      "望都县",
+      "安新县",
+      "易县",
+      "曲阳县",
+      "蠡县",
+      "顺平县",
+      "博野县",
+      "雄县",
+      "保定高新技术产业开发区",
+      "保定白沟新城",
+      "涿州市",
+      "定州市",
+      "安国市",
+      "高碑店市"
+    ],
+    "张家口市": [
+      "桥东区",
+      "桥西区",
+      "宣化区",
+      "下花园区",
+      "万全区",
+      "崇礼区",
+      "张北县",
+      "康保县",
+      "沽源县",
+      "尚义县",
+      "蔚县",
+      "阳原县",
+      "怀安县",
+      "怀来县",
+      "涿鹿县",
+      "赤城县",
+      "张家口市高新技术产业开发区",
+      "张家口市察北管理区",
+      "张家口市塞北管理区"
+    ],
+    "承德市": [
+      "双桥区",
+      "双滦区",
+      "鹰手营子矿区",
+      "承德县",
+      "兴隆县",
+      "滦平县",
+      "隆化县",
+      "丰宁满族自治县",
+      "宽城满族自治县",
+      "围场满族蒙古族自治县",
+      "承德高新技术产业开发区",
+      "平泉市"
+    ],
+    "沧州市": [
+      "新华区",
+      "运河区",
+      "沧县",
+      "青县",
+      "东光县",
+      "海兴县",
+      "盐山县",
+      "肃宁县",
+      "南皮县",
+      "吴桥县",
+      "献县",
+      "孟村回族自治县",
+      "河北沧州经济开发区",
+      "沧州高新技术产业开发区",
+      "沧州渤海新区",
+      "泊头市",
+      "任丘市",
+      "黄骅市",
+      "河间市"
+    ],
+    "廊坊市": [
+      "安次区",
+      "广阳区",
+      "固安县",
+      "永清县",
+      "香河县",
+      "大城县",
+      "文安县",
+      "大厂回族自治县",
+      "廊坊经济技术开发区",
+      "霸州市",
+      "三河市"
+    ],
+    "衡水市": [
+      "桃城区",
+      "冀州区",
+      "枣强县",
+      "武邑县",
+      "武强县",
+      "饶阳县",
+      "安平县",
+      "故城县",
+      "景县",
+      "阜城县",
+      "河北衡水高新技术产业开发区",
+      "衡水滨湖新区",
+      "深州市"
+    ]
+  },
+  "山西省": {
+    "太原市": [
+      "小店区",
+      "迎泽区",
+      "杏花岭区",
+      "尖草坪区",
+      "万柏林区",
+      "晋源区",
+      "清徐县",
+      "阳曲县",
+      "娄烦县",
+      "山西转型综合改革示范区",
+      "古交市"
+    ],
+    "大同市": [
+      "新荣区",
+      "平城区",
+      "云冈区",
+      "云州区",
+      "阳高县",
+      "天镇县",
+      "广灵县",
+      "灵丘县",
+      "浑源县",
+      "左云县",
+      "山西大同经济开发区"
+    ],
+    "阳泉市": [
+      "城区",
+      "矿区",
+      "郊区",
+      "平定县",
+      "盂县"
+    ],
+    "长治市": [
+      "潞州区",
+      "上党区",
+      "屯留区",
+      "潞城区",
+      "襄垣县",
+      "平顺县",
+      "黎城县",
+      "壶关县",
+      "长子县",
+      "武乡县",
+      "沁县",
+      "沁源县",
+      "山西长治高新技术产业园区"
+    ],
+    "晋城市": [
+      "城区",
+      "沁水县",
+      "阳城县",
+      "陵川县",
+      "泽州县",
+      "高平市"
+    ],
+    "朔州市": [
+      "朔城区",
+      "平鲁区",
+      "山阴县",
+      "应县",
+      "右玉县",
+      "山西朔州经济开发区",
+      "怀仁市"
+    ],
+    "晋中市": [
+      "榆次区",
+      "榆社县",
+      "左权县",
+      "和顺县",
+      "昔阳县",
+      "寿阳县",
+      "太谷县",
+      "祁县",
+      "平遥县",
+      "灵石县",
+      "介休市"
+    ],
+    "运城市": [
+      "盐湖区",
+      "临猗县",
+      "万荣县",
+      "闻喜县",
+      "稷山县",
+      "新绛县",
+      "绛县",
+      "垣曲县",
+      "夏县",
+      "平陆县",
+      "芮城县",
+      "永济市",
+      "河津市"
+    ],
+    "忻州市": [
+      "忻府区",
+      "定襄县",
+      "五台县",
+      "代县",
+      "繁峙县",
+      "宁武县",
+      "静乐县",
+      "神池县",
+      "五寨县",
+      "岢岚县",
+      "河曲县",
+      "保德县",
+      "偏关县",
+      "五台山风景名胜区",
+      "原平市"
+    ],
+    "临汾市": [
+      "尧都区",
+      "曲沃县",
+      "翼城县",
+      "襄汾县",
+      "洪洞县",
+      "古县",
+      "安泽县",
+      "浮山县",
+      "吉县",
+      "乡宁县",
+      "大宁县",
+      "隰县",
+      "永和县",
+      "蒲县",
+      "汾西县",
+      "侯马市",
+      "霍州市"
+    ],
+    "吕梁市": [
+      "离石区",
+      "文水县",
+      "交城县",
+      "兴县",
+      "临县",
+      "柳林县",
+      "石楼县",
+      "岚县",
+      "方山县",
+      "中阳县",
+      "交口县",
+      "孝义市",
+      "汾阳市"
+    ]
+  },
+  "内蒙古自治区": {
+    "呼和浩特市": [
+      "新城区",
+      "回民区",
+      "玉泉区",
+      "赛罕区",
+      "土默特左旗",
+      "托克托县",
+      "和林格尔县",
+      "清水河县",
+      "武川县",
+      "呼和浩特金海工业园区",
+      "呼和浩特经济技术开发区"
+    ],
+    "包头市": [
+      "东河区",
+      "昆都仑区",
+      "青山区",
+      "石拐区",
+      "白云鄂博矿区",
+      "九原区",
+      "土默特右旗",
+      "固阳县",
+      "达尔罕茂明安联合旗",
+      "包头稀土高新技术产业开发区"
+    ],
+    "乌海市": [
+      "海勃湾区",
+      "海南区",
+      "乌达区"
+    ],
+    "赤峰市": [
+      "红山区",
+      "元宝山区",
+      "松山区",
+      "阿鲁科尔沁旗",
+      "巴林左旗",
+      "巴林右旗",
+      "林西县",
+      "克什克腾旗",
+      "翁牛特旗",
+      "喀喇沁旗",
+      "宁城县",
+      "敖汉旗"
+    ],
+    "通辽市": [
+      "科尔沁区",
+      "科尔沁左翼中旗",
+      "科尔沁左翼后旗",
+      "开鲁县",
+      "库伦旗",
+      "奈曼旗",
+      "扎鲁特旗",
+      "通辽经济技术开发区",
+      "霍林郭勒市"
+    ],
+    "鄂尔多斯市": [
+      "东胜区",
+      "康巴什区",
+      "达拉特旗",
+      "准格尔旗",
+      "鄂托克前旗",
+      "鄂托克旗",
+      "杭锦旗",
+      "乌审旗",
+      "伊金霍洛旗"
+    ],
+    "呼伦贝尔市": [
+      "海拉尔区",
+      "扎赉诺尔区",
+      "阿荣旗",
+      "莫力达瓦达斡尔族自治旗",
+      "鄂伦春自治旗",
+      "鄂温克族自治旗",
+      "陈巴尔虎旗",
+      "新巴尔虎左旗",
+      "新巴尔虎右旗",
+      "满洲里市",
+      "牙克石市",
+      "扎兰屯市",
+      "额尔古纳市",
+      "根河市"
+    ],
+    "巴彦淖尔市": [
+      "临河区",
+      "五原县",
+      "磴口县",
+      "乌拉特前旗",
+      "乌拉特中旗",
+      "乌拉特后旗",
+      "杭锦后旗"
+    ],
+    "乌兰察布市": [
+      "集宁区",
+      "卓资县",
+      "化德县",
+      "商都县",
+      "兴和县",
+      "凉城县",
+      "察哈尔右翼前旗",
+      "察哈尔右翼中旗",
+      "察哈尔右翼后旗",
+      "四子王旗",
+      "丰镇市"
+    ],
+    "兴安盟": [
+      "乌兰浩特市",
+      "阿尔山市",
+      "科尔沁右翼前旗",
+      "科尔沁右翼中旗",
+      "扎赉特旗",
+      "突泉县"
+    ],
+    "锡林郭勒盟": [
+      "二连浩特市",
+      "锡林浩特市",
+      "阿巴嘎旗",
+      "苏尼特左旗",
+      "苏尼特右旗",
+      "东乌珠穆沁旗",
+      "西乌珠穆沁旗",
+      "太仆寺旗",
+      "镶黄旗",
+      "正镶白旗",
+      "正蓝旗",
+      "多伦县",
+      "乌拉盖管委会"
+    ],
+    "阿拉善盟": [
+      "阿拉善左旗",
+      "阿拉善右旗",
+      "额济纳旗",
+      "内蒙古阿拉善经济开发区"
+    ]
+  },
+  "辽宁省": {
+    "沈阳市": [
+      "和平区",
+      "沈河区",
+      "大东区",
+      "皇姑区",
+      "铁西区",
+      "苏家屯区",
+      "浑南区",
+      "沈北新区",
+      "于洪区",
+      "辽中区",
+      "康平县",
+      "法库县",
+      "新民市"
+    ],
+    "大连市": [
+      "中山区",
+      "西岗区",
+      "沙河口区",
+      "甘井子区",
+      "旅顺口区",
+      "金州区",
+      "普兰店区",
+      "长海县",
+      "瓦房店市",
+      "庄河市"
+    ],
+    "鞍山市": [
+      "铁东区",
+      "铁西区",
+      "立山区",
+      "千山区",
+      "台安县",
+      "岫岩满族自治县",
+      "海城市"
+    ],
+    "抚顺市": [
+      "新抚区",
+      "东洲区",
+      "望花区",
+      "顺城区",
+      "抚顺县",
+      "新宾满族自治县",
+      "清原满族自治县"
+    ],
+    "本溪市": [
+      "平山区",
+      "溪湖区",
+      "明山区",
+      "南芬区",
+      "本溪满族自治县",
+      "桓仁满族自治县"
+    ],
+    "丹东市": [
+      "元宝区",
+      "振兴区",
+      "振安区",
+      "宽甸满族自治县",
+      "东港市",
+      "凤城市"
+    ],
+    "锦州市": [
+      "古塔区",
+      "凌河区",
+      "太和区",
+      "黑山县",
+      "义县",
+      "凌海市",
+      "北镇市"
+    ],
+    "营口市": [
+      "站前区",
+      "西市区",
+      "鲅鱼圈区",
+      "老边区",
+      "盖州市",
+      "大石桥市"
+    ],
+    "阜新市": [
+      "海州区",
+      "新邱区",
+      "太平区",
+      "清河门区",
+      "细河区",
+      "阜新蒙古族自治县",
+      "彰武县"
+    ],
+    "辽阳市": [
+      "白塔区",
+      "文圣区",
+      "宏伟区",
+      "弓长岭区",
+      "太子河区",
+      "辽阳县",
+      "灯塔市"
+    ],
+    "盘锦市": [
+      "双台子区",
+      "兴隆台区",
+      "大洼区",
+      "盘山县"
+    ],
+    "铁岭市": [
+      "银州区",
+      "清河区",
+      "铁岭县",
+      "西丰县",
+      "昌图县",
+      "调兵山市",
+      "开原市"
+    ],
+    "朝阳市": [
+      "双塔区",
+      "龙城区",
+      "朝阳县",
+      "建平县",
+      "喀喇沁左翼蒙古族自治县",
+      "北票市",
+      "凌源市"
+    ],
+    "葫芦岛市": [
+      "连山区",
+      "龙港区",
+      "南票区",
+      "绥中县",
+      "建昌县",
+      "兴城市"
+    ]
+  },
+  "吉林省": {
+    "长春市": [
+      "南关区",
+      "宽城区",
+      "朝阳区",
+      "二道区",
+      "绿园区",
+      "双阳区",
+      "九台区",
+      "农安县",
+      "长春经济技术开发区",
+      "长春净月高新技术产业开发区",
+      "长春高新技术产业开发区",
+      "长春汽车经济技术开发区",
+      "榆树市",
+      "德惠市"
+    ],
+    "吉林市": [
+      "昌邑区",
+      "龙潭区",
+      "船营区",
+      "丰满区",
+      "永吉县",
+      "吉林经济开发区",
+      "吉林高新技术产业开发区",
+      "吉林中国新加坡食品区",
+      "蛟河市",
+      "桦甸市",
+      "舒兰市",
+      "磐石市"
+    ],
+    "四平市": [
+      "铁西区",
+      "铁东区",
+      "梨树县",
+      "伊通满族自治县",
+      "公主岭市",
+      "双辽市"
+    ],
+    "辽源市": [
+      "龙山区",
+      "西安区",
+      "东丰县",
+      "东辽县"
+    ],
+    "通化市": [
+      "东昌区",
+      "二道江区",
+      "通化县",
+      "辉南县",
+      "柳河县",
+      "梅河口市",
+      "集安市"
+    ],
+    "白山市": [
+      "浑江区",
+      "江源区",
+      "抚松县",
+      "靖宇县",
+      "长白朝鲜族自治县",
+      "临江市"
+    ],
+    "松原市": [
+      "宁江区",
+      "前郭尔罗斯蒙古族自治县",
+      "长岭县",
+      "乾安县",
+      "吉林松原经济开发区",
+      "扶余市"
+    ],
+    "白城市": [
+      "洮北区",
+      "镇赉县",
+      "通榆县",
+      "吉林白城经济开发区",
+      "洮南市",
+      "大安市"
+    ],
+    "延边朝鲜族自治州": [
+      "延吉市",
+      "图们市",
+      "敦化市",
+      "珲春市",
+      "龙井市",
+      "和龙市",
+      "汪清县",
+      "安图县"
+    ]
+  },
+  "黑龙江省": {
+    "哈尔滨市": [
+      "道里区",
+      "南岗区",
+      "道外区",
+      "平房区",
+      "松北区",
+      "香坊区",
+      "呼兰区",
+      "阿城区",
+      "双城区",
+      "依兰县",
+      "方正县",
+      "宾县",
+      "巴彦县",
+      "木兰县",
+      "通河县",
+      "延寿县",
+      "尚志市",
+      "五常市"
+    ],
+    "齐齐哈尔市": [
+      "龙沙区",
+      "建华区",
+      "铁锋区",
+      "昂昂溪区",
+      "富拉尔基区",
+      "碾子山区",
+      "梅里斯达斡尔族区",
+      "龙江县",
+      "依安县",
+      "泰来县",
+      "甘南县",
+      "富裕县",
+      "克山县",
+      "克东县",
+      "拜泉县",
+      "讷河市"
+    ],
+    "鸡西市": [
+      "鸡冠区",
+      "恒山区",
+      "滴道区",
+      "梨树区",
+      "城子河区",
+      "麻山区",
+      "鸡东县",
+      "虎林市",
+      "密山市"
+    ],
+    "鹤岗市": [
+      "向阳区",
+      "工农区",
+      "南山区",
+      "兴安区",
+      "东山区",
+      "兴山区",
+      "萝北县",
+      "绥滨县"
+    ],
+    "双鸭山市": [
+      "尖山区",
+      "岭东区",
+      "四方台区",
+      "宝山区",
+      "集贤县",
+      "友谊县",
+      "宝清县",
+      "饶河县"
+    ],
+    "大庆市": [
+      "萨尔图区",
+      "龙凤区",
+      "让胡路区",
+      "红岗区",
+      "大同区",
+      "肇州县",
+      "肇源县",
+      "林甸县",
+      "杜尔伯特蒙古族自治县",
+      "大庆高新技术产业开发区"
+    ],
+    "伊春市": [
+      "伊春区",
+      "南岔区",
+      "友好区",
+      "西林区",
+      "翠峦区",
+      "新青区",
+      "美溪区",
+      "金山屯区",
+      "五营区",
+      "乌马河区",
+      "汤旺河区",
+      "带岭区",
+      "乌伊岭区",
+      "红星区",
+      "上甘岭区",
+      "嘉荫县",
+      "铁力市"
+    ],
+    "佳木斯市": [
+      "向阳区",
+      "前进区",
+      "东风区",
+      "郊区",
+      "桦南县",
+      "桦川县",
+      "汤原县",
+      "同江市",
+      "富锦市",
+      "抚远市"
+    ],
+    "七台河市": [
+      "新兴区",
+      "桃山区",
+      "茄子河区",
+      "勃利县"
+    ],
+    "牡丹江市": [
+      "东安区",
+      "阳明区",
+      "爱民区",
+      "西安区",
+      "林口县",
+      "牡丹江经济技术开发区",
+      "绥芬河市",
+      "海林市",
+      "宁安市",
+      "穆棱市",
+      "东宁市"
+    ],
+    "黑河市": [
+      "爱辉区",
+      "嫩江县",
+      "逊克县",
+      "孙吴县",
+      "北安市",
+      "五大连池市"
+    ],
+    "绥化市": [
+      "北林区",
+      "望奎县",
+      "兰西县",
+      "青冈县",
+      "庆安县",
+      "明水县",
+      "绥棱县",
+      "安达市",
+      "肇东市",
+      "海伦市"
+    ],
+    "大兴安岭地区": [
+      "漠河市",
+      "呼玛县",
+      "塔河县",
+      "加格达奇区",
+      "松岭区",
+      "新林区",
+      "呼中区"
+    ]
+  },
+  "上海市": {
+    "市辖区": [
+      "黄浦区",
+      "徐汇区",
+      "长宁区",
+      "静安区",
+      "普陀区",
+      "虹口区",
+      "杨浦区",
+      "闵行区",
+      "宝山区",
+      "嘉定区",
+      "浦东新区",
+      "金山区",
+      "松江区",
+      "青浦区",
+      "奉贤区",
+      "崇明区"
+    ]
+  },
+  "江苏省": {
+    "南京市": [
+      "玄武区",
+      "秦淮区",
+      "建邺区",
+      "鼓楼区",
+      "浦口区",
+      "栖霞区",
+      "雨花台区",
+      "江宁区",
+      "六合区",
+      "溧水区",
+      "高淳区"
+    ],
+    "无锡市": [
+      "锡山区",
+      "惠山区",
+      "滨湖区",
+      "梁溪区",
+      "新吴区",
+      "江阴市",
+      "宜兴市"
+    ],
+    "徐州市": [
+      "鼓楼区",
+      "云龙区",
+      "贾汪区",
+      "泉山区",
+      "铜山区",
+      "丰县",
+      "沛县",
+      "睢宁县",
+      "徐州经济技术开发区",
+      "新沂市",
+      "邳州市"
+    ],
+    "常州市": [
+      "天宁区",
+      "钟楼区",
+      "新北区",
+      "武进区",
+      "金坛区",
+      "溧阳市"
+    ],
+    "苏州市": [
+      "虎丘区",
+      "吴中区",
+      "相城区",
+      "姑苏区",
+      "吴江区",
+      "苏州工业园区",
+      "常熟市",
+      "张家港市",
+      "昆山市",
+      "太仓市"
+    ],
+    "南通市": [
+      "崇川区",
+      "港闸区",
+      "通州区",
+      "如东县",
+      "南通经济技术开发区",
+      "启东市",
+      "如皋市",
+      "海门市",
+      "海安市"
+    ],
+    "连云港市": [
+      "连云区",
+      "海州区",
+      "赣榆区",
+      "东海县",
+      "灌云县",
+      "灌南县",
+      "连云港经济技术开发区",
+      "连云港高新技术产业开发区"
+    ],
+    "淮安市": [
+      "淮安区",
+      "淮阴区",
+      "清江浦区",
+      "洪泽区",
+      "涟水县",
+      "盱眙县",
+      "金湖县",
+      "淮安经济技术开发区"
+    ],
+    "盐城市": [
+      "亭湖区",
+      "盐都区",
+      "大丰区",
+      "响水县",
+      "滨海县",
+      "阜宁县",
+      "射阳县",
+      "建湖县",
+      "盐城经济技术开发区",
+      "东台市"
+    ],
+    "扬州市": [
+      "广陵区",
+      "邗江区",
+      "江都区",
+      "宝应县",
+      "扬州经济技术开发区",
+      "仪征市",
+      "高邮市"
+    ],
+    "镇江市": [
+      "京口区",
+      "润州区",
+      "丹徒区",
+      "镇江新区",
+      "丹阳市",
+      "扬中市",
+      "句容市"
+    ],
+    "泰州市": [
+      "海陵区",
+      "高港区",
+      "姜堰区",
+      "泰州医药高新技术产业开发区",
+      "兴化市",
+      "靖江市",
+      "泰兴市"
+    ],
+    "宿迁市": [
+      "宿城区",
+      "宿豫区",
+      "沭阳县",
+      "泗阳县",
+      "泗洪县",
+      "宿迁经济技术开发区"
+    ]
+  },
+  "浙江省": {
+    "杭州市": [
+      "上城区",
+      "下城区",
+      "江干区",
+      "拱墅区",
+      "西湖区",
+      "滨江区",
+      "萧山区",
+      "余杭区",
+      "富阳区",
+      "临安区",
+      "桐庐县",
+      "淳安县",
+      "建德市"
+    ],
+    "宁波市": [
+      "海曙区",
+      "江北区",
+      "北仑区",
+      "镇海区",
+      "鄞州区",
+      "奉化区",
+      "象山县",
+      "宁海县",
+      "余姚市",
+      "慈溪市"
+    ],
+    "温州市": [
+      "鹿城区",
+      "龙湾区",
+      "瓯海区",
+      "洞头区",
+      "永嘉县",
+      "平阳县",
+      "苍南县",
+      "文成县",
+      "泰顺县",
+      "温州经济技术开发区",
+      "瑞安市",
+      "乐清市"
+    ],
+    "嘉兴市": [
+      "南湖区",
+      "秀洲区",
+      "嘉善县",
+      "海盐县",
+      "海宁市",
+      "平湖市",
+      "桐乡市"
+    ],
+    "湖州市": [
+      "吴兴区",
+      "南浔区",
+      "德清县",
+      "长兴县",
+      "安吉县"
+    ],
+    "绍兴市": [
+      "越城区",
+      "柯桥区",
+      "上虞区",
+      "新昌县",
+      "诸暨市",
+      "嵊州市"
+    ],
+    "金华市": [
+      "婺城区",
+      "金东区",
+      "武义县",
+      "浦江县",
+      "磐安县",
+      "兰溪市",
+      "义乌市",
+      "东阳市",
+      "永康市"
+    ],
+    "衢州市": [
+      "柯城区",
+      "衢江区",
+      "常山县",
+      "开化县",
+      "龙游县",
+      "江山市"
+    ],
+    "舟山市": [
+      "定海区",
+      "普陀区",
+      "岱山县",
+      "嵊泗县"
+    ],
+    "台州市": [
+      "椒江区",
+      "黄岩区",
+      "路桥区",
+      "三门县",
+      "天台县",
+      "仙居县",
+      "温岭市",
+      "临海市",
+      "玉环市"
+    ],
+    "丽水市": [
+      "莲都区",
+      "青田县",
+      "缙云县",
+      "遂昌县",
+      "松阳县",
+      "云和县",
+      "庆元县",
+      "景宁畲族自治县",
+      "龙泉市"
+    ]
+  },
+  "安徽省": {
+    "合肥市": [
+      "瑶海区",
+      "庐阳区",
+      "蜀山区",
+      "包河区",
+      "长丰县",
+      "肥东县",
+      "肥西县",
+      "庐江县",
+      "合肥高新技术产业开发区",
+      "合肥经济技术开发区",
+      "合肥新站高新技术产业开发区",
+      "巢湖市"
+    ],
+    "芜湖市": [
+      "镜湖区",
+      "弋江区",
+      "鸠江区",
+      "三山区",
+      "芜湖县",
+      "繁昌县",
+      "南陵县",
+      "无为县",
+      "芜湖经济技术开发区",
+      "安徽芜湖长江大桥经济开发区"
+    ],
+    "蚌埠市": [
+      "龙子湖区",
+      "蚌山区",
+      "禹会区",
+      "淮上区",
+      "怀远县",
+      "五河县",
+      "固镇县",
+      "蚌埠市高新技术开发区",
+      "蚌埠市经济开发区"
+    ],
+    "淮南市": [
+      "大通区",
+      "田家庵区",
+      "谢家集区",
+      "八公山区",
+      "潘集区",
+      "凤台县",
+      "寿县"
+    ],
+    "马鞍山市": [
+      "花山区",
+      "雨山区",
+      "博望区",
+      "当涂县",
+      "含山县",
+      "和县"
+    ],
+    "淮北市": [
+      "杜集区",
+      "相山区",
+      "烈山区",
+      "濉溪县"
+    ],
+    "铜陵市": [
+      "铜官区",
+      "义安区",
+      "郊区",
+      "枞阳县"
+    ],
+    "安庆市": [
+      "迎江区",
+      "大观区",
+      "宜秀区",
+      "怀宁县",
+      "太湖县",
+      "宿松县",
+      "望江县",
+      "岳西县",
+      "安徽安庆经济开发区",
+      "桐城市",
+      "潜山市"
+    ],
+    "黄山市": [
+      "屯溪区",
+      "黄山区",
+      "徽州区",
+      "歙县",
+      "休宁县",
+      "黟县",
+      "祁门县"
+    ],
+    "滁州市": [
+      "琅琊区",
+      "南谯区",
+      "来安县",
+      "全椒县",
+      "定远县",
+      "凤阳县",
+      "苏滁现代产业园",
+      "滁州经济技术开发区",
+      "天长市",
+      "明光市"
+    ],
+    "阜阳市": [
+      "颍州区",
+      "颍东区",
+      "颍泉区",
+      "临泉县",
+      "太和县",
+      "阜南县",
+      "颍上县",
+      "阜阳合肥现代产业园区",
+      "阜阳经济技术开发区",
+      "界首市"
+    ],
+    "宿州市": [
+      "埇桥区",
+      "砀山县",
+      "萧县",
+      "灵璧县",
+      "泗县",
+      "宿州马鞍山现代产业园区",
+      "宿州经济技术开发区"
+    ],
+    "六安市": [
+      "金安区",
+      "裕安区",
+      "叶集区",
+      "霍邱县",
+      "舒城县",
+      "金寨县",
+      "霍山县"
+    ],
+    "亳州市": [
+      "谯城区",
+      "涡阳县",
+      "蒙城县",
+      "利辛县"
+    ],
+    "池州市": [
+      "贵池区",
+      "东至县",
+      "石台县",
+      "青阳县"
+    ],
+    "宣城市": [
+      "宣州区",
+      "郎溪县",
+      "广德县",
+      "泾县",
+      "绩溪县",
+      "旌德县",
+      "宣城市经济开发区",
+      "宁国市"
+    ]
+  },
+  "福建省": {
+    "福州市": [
+      "鼓楼区",
+      "台江区",
+      "仓山区",
+      "马尾区",
+      "晋安区",
+      "长乐区",
+      "闽侯县",
+      "连江县",
+      "罗源县",
+      "闽清县",
+      "永泰县",
+      "平潭县",
+      "福清市"
+    ],
+    "厦门市": [
+      "思明区",
+      "海沧区",
+      "湖里区",
+      "集美区",
+      "同安区",
+      "翔安区"
+    ],
+    "莆田市": [
+      "城厢区",
+      "涵江区",
+      "荔城区",
+      "秀屿区",
+      "仙游县"
+    ],
+    "三明市": [
+      "梅列区",
+      "三元区",
+      "明溪县",
+      "清流县",
+      "宁化县",
+      "大田县",
+      "尤溪县",
+      "沙县",
+      "将乐县",
+      "泰宁县",
+      "建宁县",
+      "永安市"
+    ],
+    "泉州市": [
+      "鲤城区",
+      "丰泽区",
+      "洛江区",
+      "泉港区",
+      "惠安县",
+      "安溪县",
+      "永春县",
+      "德化县",
+      "金门县",
+      "石狮市",
+      "晋江市",
+      "南安市"
+    ],
+    "漳州市": [
+      "芗城区",
+      "龙文区",
+      "云霄县",
+      "漳浦县",
+      "诏安县",
+      "长泰县",
+      "东山县",
+      "南靖县",
+      "平和县",
+      "华安县",
+      "龙海市"
+    ],
+    "南平市": [
+      "延平区",
+      "建阳区",
+      "顺昌县",
+      "浦城县",
+      "光泽县",
+      "松溪县",
+      "政和县",
+      "邵武市",
+      "武夷山市",
+      "建瓯市"
+    ],
+    "龙岩市": [
+      "新罗区",
+      "永定区",
+      "长汀县",
+      "上杭县",
+      "武平县",
+      "连城县",
+      "漳平市"
+    ],
+    "宁德市": [
+      "蕉城区",
+      "霞浦县",
+      "古田县",
+      "屏南县",
+      "寿宁县",
+      "周宁县",
+      "柘荣县",
+      "福安市",
+      "福鼎市"
+    ]
+  },
+  "江西省": {
+    "南昌市": [
+      "东湖区",
+      "西湖区",
+      "青云谱区",
+      "湾里区",
+      "青山湖区",
+      "新建区",
+      "南昌县",
+      "安义县",
+      "进贤县"
+    ],
+    "景德镇市": [
+      "昌江区",
+      "珠山区",
+      "浮梁县",
+      "乐平市"
+    ],
+    "萍乡市": [
+      "安源区",
+      "湘东区",
+      "莲花县",
+      "上栗县",
+      "芦溪县"
+    ],
+    "九江市": [
+      "濂溪区",
+      "浔阳区",
+      "柴桑区",
+      "武宁县",
+      "修水县",
+      "永修县",
+      "德安县",
+      "都昌县",
+      "湖口县",
+      "彭泽县",
+      "瑞昌市",
+      "共青城市",
+      "庐山市"
+    ],
+    "新余市": [
+      "渝水区",
+      "分宜县"
+    ],
+    "鹰潭市": [
+      "月湖区",
+      "余江区",
+      "贵溪市"
+    ],
+    "赣州市": [
+      "章贡区",
+      "南康区",
+      "赣县区",
+      "信丰县",
+      "大余县",
+      "上犹县",
+      "崇义县",
+      "安远县",
+      "龙南县",
+      "定南县",
+      "全南县",
+      "宁都县",
+      "于都县",
+      "兴国县",
+      "会昌县",
+      "寻乌县",
+      "石城县",
+      "瑞金市"
+    ],
+    "吉安市": [
+      "吉州区",
+      "青原区",
+      "吉安县",
+      "吉水县",
+      "峡江县",
+      "新干县",
+      "永丰县",
+      "泰和县",
+      "遂川县",
+      "万安县",
+      "安福县",
+      "永新县",
+      "井冈山市"
+    ],
+    "宜春市": [
+      "袁州区",
+      "奉新县",
+      "万载县",
+      "上高县",
+      "宜丰县",
+      "靖安县",
+      "铜鼓县",
+      "丰城市",
+      "樟树市",
+      "高安市"
+    ],
+    "抚州市": [
+      "临川区",
+      "东乡区",
+      "南城县",
+      "黎川县",
+      "南丰县",
+      "崇仁县",
+      "乐安县",
+      "宜黄县",
+      "金溪县",
+      "资溪县",
+      "广昌县"
+    ],
+    "上饶市": [
+      "信州区",
+      "广丰区",
+      "上饶县",
+      "玉山县",
+      "铅山县",
+      "横峰县",
+      "弋阳县",
+      "余干县",
+      "鄱阳县",
+      "万年县",
+      "婺源县",
+      "德兴市"
+    ]
+  },
+  "山东省": {
+    "济南市": [
+      "历下区",
+      "市中区",
+      "槐荫区",
+      "天桥区",
+      "历城区",
+      "长清区",
+      "章丘区",
+      "济阳区",
+      "平阴县",
+      "商河县",
+      "济南高新技术产业开发区"
+    ],
+    "青岛市": [
+      "市南区",
+      "市北区",
+      "黄岛区",
+      "崂山区",
+      "李沧区",
+      "城阳区",
+      "即墨区",
+      "青岛高新技术产业开发区",
+      "胶州市",
+      "平度市",
+      "莱西市"
+    ],
+    "淄博市": [
+      "淄川区",
+      "张店区",
+      "博山区",
+      "临淄区",
+      "周村区",
+      "桓台县",
+      "高青县",
+      "沂源县"
+    ],
+    "枣庄市": [
+      "市中区",
+      "薛城区",
+      "峄城区",
+      "台儿庄区",
+      "山亭区",
+      "滕州市"
+    ],
+    "东营市": [
+      "东营区",
+      "河口区",
+      "垦利区",
+      "利津县",
+      "广饶县",
+      "东营经济技术开发区",
+      "东营港经济开发区"
+    ],
+    "烟台市": [
+      "芝罘区",
+      "福山区",
+      "牟平区",
+      "莱山区",
+      "长岛县",
+      "烟台高新技术产业开发区",
+      "烟台经济技术开发区",
+      "龙口市",
+      "莱阳市",
+      "莱州市",
+      "蓬莱市",
+      "招远市",
+      "栖霞市",
+      "海阳市"
+    ],
+    "潍坊市": [
+      "潍城区",
+      "寒亭区",
+      "坊子区",
+      "奎文区",
+      "临朐县",
+      "昌乐县",
+      "潍坊滨海经济技术开发区",
+      "青州市",
+      "诸城市",
+      "寿光市",
+      "安丘市",
+      "高密市",
+      "昌邑市"
+    ],
+    "济宁市": [
+      "任城区",
+      "兖州区",
+      "微山县",
+      "鱼台县",
+      "金乡县",
+      "嘉祥县",
+      "汶上县",
+      "泗水县",
+      "梁山县",
+      "济宁高新技术产业开发区",
+      "曲阜市",
+      "邹城市"
+    ],
+    "泰安市": [
+      "泰山区",
+      "岱岳区",
+      "宁阳县",
+      "东平县",
+      "新泰市",
+      "肥城市"
+    ],
+    "威海市": [
+      "环翠区",
+      "文登区",
+      "威海火炬高技术产业开发区",
+      "威海经济技术开发区",
+      "威海临港经济技术开发区",
+      "荣成市",
+      "乳山市"
+    ],
+    "日照市": [
+      "东港区",
+      "岚山区",
+      "五莲县",
+      "莒县",
+      "日照经济技术开发区"
+    ],
+    "莱芜市": [
+      "莱城区",
+      "钢城区"
+    ],
+    "临沂市": [
+      "兰山区",
+      "罗庄区",
+      "河东区",
+      "沂南县",
+      "郯城县",
+      "沂水县",
+      "兰陵县",
+      "费县",
+      "平邑县",
+      "莒南县",
+      "蒙阴县",
+      "临沭县",
+      "临沂高新技术产业开发区",
+      "临沂经济技术开发区",
+      "临沂临港经济开发区"
+    ],
+    "德州市": [
+      "德城区",
+      "陵城区",
+      "宁津县",
+      "庆云县",
+      "临邑县",
+      "齐河县",
+      "平原县",
+      "夏津县",
+      "武城县",
+      "德州经济技术开发区",
+      "德州运河经济开发区",
+      "乐陵市",
+      "禹城市"
+    ],
+    "聊城市": [
+      "东昌府区",
+      "阳谷县",
+      "莘县",
+      "茌平县",
+      "东阿县",
+      "冠县",
+      "高唐县",
+      "临清市"
+    ],
+    "滨州市": [
+      "滨城区",
+      "沾化区",
+      "惠民县",
+      "阳信县",
+      "无棣县",
+      "博兴县",
+      "邹平市"
+    ],
+    "菏泽市": [
+      "牡丹区",
+      "定陶区",
+      "曹县",
+      "单县",
+      "成武县",
+      "巨野县",
+      "郓城县",
+      "鄄城县",
+      "东明县",
+      "菏泽经济技术开发区",
+      "菏泽高新技术开发区"
+    ]
+  },
+  "河南省": {
+    "郑州市": [
+      "中原区",
+      "二七区",
+      "管城回族区",
+      "金水区",
+      "上街区",
+      "惠济区",
+      "中牟县",
+      "郑州经济技术开发区",
+      "郑州高新技术产业开发区",
+      "郑州航空港经济综合实验区",
+      "巩义市",
+      "荥阳市",
+      "新密市",
+      "新郑市",
+      "登封市"
+    ],
+    "开封市": [
+      "龙亭区",
+      "顺河回族区",
+      "鼓楼区",
+      "禹王台区",
+      "祥符区",
+      "杞县",
+      "通许县",
+      "尉氏县",
+      "兰考县"
+    ],
+    "洛阳市": [
+      "老城区",
+      "西工区",
+      "瀍河回族区",
+      "涧西区",
+      "吉利区",
+      "洛龙区",
+      "孟津县",
+      "新安县",
+      "栾川县",
+      "嵩县",
+      "汝阳县",
+      "宜阳县",
+      "洛宁县",
+      "伊川县",
+      "洛阳高新技术产业开发区",
+      "偃师市"
+    ],
+    "平顶山市": [
+      "新华区",
+      "卫东区",
+      "石龙区",
+      "湛河区",
+      "宝丰县",
+      "叶县",
+      "鲁山县",
+      "郏县",
+      "平顶山高新技术产业开发区",
+      "平顶山市新城区",
+      "舞钢市",
+      "汝州市"
+    ],
+    "安阳市": [
+      "文峰区",
+      "北关区",
+      "殷都区",
+      "龙安区",
+      "安阳县",
+      "汤阴县",
+      "滑县",
+      "内黄县",
+      "安阳高新技术产业开发区",
+      "林州市"
+    ],
+    "鹤壁市": [
+      "鹤山区",
+      "山城区",
+      "淇滨区",
+      "浚县",
+      "淇县",
+      "鹤壁经济技术开发区"
+    ],
+    "新乡市": [
+      "红旗区",
+      "卫滨区",
+      "凤泉区",
+      "牧野区",
+      "新乡县",
+      "获嘉县",
+      "原阳县",
+      "延津县",
+      "封丘县",
+      "长垣县",
+      "新乡高新技术产业开发区",
+      "新乡经济技术开发区",
+      "新乡市平原城乡一体化示范区",
+      "卫辉市",
+      "辉县市"
+    ],
+    "焦作市": [
+      "解放区",
+      "中站区",
+      "马村区",
+      "山阳区",
+      "修武县",
+      "博爱县",
+      "武陟县",
+      "温县",
+      "焦作城乡一体化示范区",
+      "沁阳市",
+      "孟州市"
+    ],
+    "濮阳市": [
+      "华龙区",
+      "清丰县",
+      "南乐县",
+      "范县",
+      "台前县",
+      "濮阳县",
+      "河南濮阳工业园区",
+      "濮阳经济技术开发区"
+    ],
+    "许昌市": [
+      "魏都区",
+      "建安区",
+      "鄢陵县",
+      "襄城县",
+      "许昌经济技术开发区",
+      "禹州市",
+      "长葛市"
+    ],
+    "漯河市": [
+      "源汇区",
+      "郾城区",
+      "召陵区",
+      "舞阳县",
+      "临颍县",
+      "漯河经济技术开发区"
+    ],
+    "三门峡市": [
+      "湖滨区",
+      "陕州区",
+      "渑池县",
+      "卢氏县",
+      "河南三门峡经济开发区",
+      "义马市",
+      "灵宝市"
+    ],
+    "南阳市": [
+      "宛城区",
+      "卧龙区",
+      "南召县",
+      "方城县",
+      "西峡县",
+      "镇平县",
+      "内乡县",
+      "淅川县",
+      "社旗县",
+      "唐河县",
+      "新野县",
+      "桐柏县",
+      "南阳高新技术产业开发区",
+      "南阳市城乡一体化示范区",
+      "邓州市"
+    ],
+    "商丘市": [
+      "梁园区",
+      "睢阳区",
+      "民权县",
+      "睢县",
+      "宁陵县",
+      "柘城县",
+      "虞城县",
+      "夏邑县",
+      "豫东综合物流产业聚集区",
+      "河南商丘经济开发区",
+      "永城市"
+    ],
+    "信阳市": [
+      "浉河区",
+      "平桥区",
+      "罗山县",
+      "光山县",
+      "新县",
+      "商城县",
+      "固始县",
+      "潢川县",
+      "淮滨县",
+      "息县",
+      "信阳高新技术产业开发区"
+    ],
+    "周口市": [
+      "川汇区",
+      "扶沟县",
+      "西华县",
+      "商水县",
+      "沈丘县",
+      "郸城县",
+      "淮阳县",
+      "太康县",
+      "鹿邑县",
+      "河南周口经济开发区",
+      "项城市"
+    ],
+    "驻马店市": [
+      "驿城区",
+      "西平县",
+      "上蔡县",
+      "平舆县",
+      "正阳县",
+      "确山县",
+      "泌阳县",
+      "汝南县",
+      "遂平县",
+      "新蔡县",
+      "河南驻马店经济开发区"
+    ],
+    "省直辖县级行政区划": [
+      "济源市"
+    ]
+  },
+  "湖北省": {
+    "武汉市": [
+      "江岸区",
+      "江汉区",
+      "硚口区",
+      "汉阳区",
+      "武昌区",
+      "青山区",
+      "洪山区",
+      "东西湖区",
+      "汉南区",
+      "蔡甸区",
+      "江夏区",
+      "黄陂区",
+      "新洲区"
+    ],
+    "黄石市": [
+      "黄石港区",
+      "西塞山区",
+      "下陆区",
+      "铁山区",
+      "阳新县",
+      "大冶市"
+    ],
+    "十堰市": [
+      "茅箭区",
+      "张湾区",
+      "郧阳区",
+      "郧西县",
+      "竹山县",
+      "竹溪县",
+      "房县",
+      "丹江口市"
+    ],
+    "宜昌市": [
+      "西陵区",
+      "伍家岗区",
+      "点军区",
+      "猇亭区",
+      "夷陵区",
+      "远安县",
+      "兴山县",
+      "秭归县",
+      "长阳土家族自治县",
+      "五峰土家族自治县",
+      "宜都市",
+      "当阳市",
+      "枝江市"
+    ],
+    "襄阳市": [
+      "襄城区",
+      "樊城区",
+      "襄州区",
+      "南漳县",
+      "谷城县",
+      "保康县",
+      "老河口市",
+      "枣阳市",
+      "宜城市"
+    ],
+    "鄂州市": [
+      "梁子湖区",
+      "华容区",
+      "鄂城区"
+    ],
+    "荆门市": [
+      "东宝区",
+      "掇刀区",
+      "沙洋县",
+      "钟祥市",
+      "京山市"
+    ],
+    "孝感市": [
+      "孝南区",
+      "孝昌县",
+      "大悟县",
+      "云梦县",
+      "应城市",
+      "安陆市",
+      "汉川市"
+    ],
+    "荆州市": [
+      "沙市区",
+      "荆州区",
+      "公安县",
+      "监利县",
+      "江陵县",
+      "荆州经济技术开发区",
+      "石首市",
+      "洪湖市",
+      "松滋市"
+    ],
+    "黄冈市": [
+      "黄州区",
+      "团风县",
+      "红安县",
+      "罗田县",
+      "英山县",
+      "浠水县",
+      "蕲春县",
+      "黄梅县",
+      "龙感湖管理区",
+      "麻城市",
+      "武穴市"
+    ],
+    "咸宁市": [
+      "咸安区",
+      "嘉鱼县",
+      "通城县",
+      "崇阳县",
+      "通山县",
+      "赤壁市"
+    ],
+    "随州市": [
+      "曾都区",
+      "随县",
+      "广水市"
+    ],
+    "恩施土家族苗族自治州": [
+      "恩施市",
+      "利川市",
+      "建始县",
+      "巴东县",
+      "宣恩县",
+      "咸丰县",
+      "来凤县",
+      "鹤峰县"
+    ],
+    "省直辖县级行政区划": [
+      "仙桃市",
+      "潜江市",
+      "天门市",
+      "神农架林区"
+    ]
+  },
+  "湖南省": {
+    "长沙市": [
+      "芙蓉区",
+      "天心区",
+      "岳麓区",
+      "开福区",
+      "雨花区",
+      "望城区",
+      "长沙县",
+      "浏阳市",
+      "宁乡市"
+    ],
+    "株洲市": [
+      "荷塘区",
+      "芦淞区",
+      "石峰区",
+      "天元区",
+      "渌口区",
+      "攸县",
+      "茶陵县",
+      "炎陵县",
+      "云龙示范区",
+      "醴陵市"
+    ],
+    "湘潭市": [
+      "雨湖区",
+      "岳塘区",
+      "湘潭县",
+      "湖南湘潭高新技术产业园区",
+      "湘潭昭山示范区",
+      "湘潭九华示范区",
+      "湘乡市",
+      "韶山市"
+    ],
+    "衡阳市": [
+      "珠晖区",
+      "雁峰区",
+      "石鼓区",
+      "蒸湘区",
+      "南岳区",
+      "衡阳县",
+      "衡南县",
+      "衡山县",
+      "衡东县",
+      "祁东县",
+      "衡阳综合保税区",
+      "湖南衡阳高新技术产业园区",
+      "湖南衡阳松木经济开发区",
+      "耒阳市",
+      "常宁市"
+    ],
+    "邵阳市": [
+      "双清区",
+      "大祥区",
+      "北塔区",
+      "邵东县",
+      "新邵县",
+      "邵阳县",
+      "隆回县",
+      "洞口县",
+      "绥宁县",
+      "新宁县",
+      "城步苗族自治县",
+      "武冈市"
+    ],
+    "岳阳市": [
+      "岳阳楼区",
+      "云溪区",
+      "君山区",
+      "岳阳县",
+      "华容县",
+      "湘阴县",
+      "平江县",
+      "岳阳市屈原管理区",
+      "汨罗市",
+      "临湘市"
+    ],
+    "常德市": [
+      "武陵区",
+      "鼎城区",
+      "安乡县",
+      "汉寿县",
+      "澧县",
+      "临澧县",
+      "桃源县",
+      "石门县",
+      "常德市西洞庭管理区",
+      "津市市"
+    ],
+    "张家界市": [
+      "永定区",
+      "武陵源区",
+      "慈利县",
+      "桑植县"
+    ],
+    "益阳市": [
+      "资阳区",
+      "赫山区",
+      "南县",
+      "桃江县",
+      "安化县",
+      "益阳市大通湖管理区",
+      "湖南益阳高新技术产业园区",
+      "沅江市"
+    ],
+    "郴州市": [
+      "北湖区",
+      "苏仙区",
+      "桂阳县",
+      "宜章县",
+      "永兴县",
+      "嘉禾县",
+      "临武县",
+      "汝城县",
+      "桂东县",
+      "安仁县",
+      "资兴市"
+    ],
+    "永州市": [
+      "零陵区",
+      "冷水滩区",
+      "祁阳县",
+      "东安县",
+      "双牌县",
+      "道县",
+      "江永县",
+      "宁远县",
+      "蓝山县",
+      "新田县",
+      "江华瑶族自治县",
+      "永州经济技术开发区",
+      "永州市金洞管理区",
+      "永州市回龙圩管理区"
+    ],
+    "怀化市": [
+      "鹤城区",
+      "中方县",
+      "沅陵县",
+      "辰溪县",
+      "溆浦县",
+      "会同县",
+      "麻阳苗族自治县",
+      "新晃侗族自治县",
+      "芷江侗族自治县",
+      "靖州苗族侗族自治县",
+      "通道侗族自治县",
+      "怀化市洪江管理区",
+      "洪江市"
+    ],
+    "娄底市": [
+      "娄星区",
+      "双峰县",
+      "新化县",
+      "冷水江市",
+      "涟源市"
+    ],
+    "湘西土家族苗族自治州": [
+      "吉首市",
+      "泸溪县",
+      "凤凰县",
+      "花垣县",
+      "保靖县",
+      "古丈县",
+      "永顺县",
+      "龙山县",
+      "湖南吉首经济开发区",
+      "湖南永顺经济开发区"
+    ]
+  },
+  "广东省": {
+    "广州市": [
+      "荔湾区",
+      "越秀区",
+      "海珠区",
+      "天河区",
+      "白云区",
+      "黄埔区",
+      "番禺区",
+      "花都区",
+      "南沙区",
+      "从化区",
+      "增城区"
+    ],
+    "韶关市": [
+      "武江区",
+      "浈江区",
+      "曲江区",
+      "始兴县",
+      "仁化县",
+      "翁源县",
+      "乳源瑶族自治县",
+      "新丰县",
+      "乐昌市",
+      "南雄市"
+    ],
+    "深圳市": [
+      "罗湖区",
+      "福田区",
+      "南山区",
+      "宝安区",
+      "龙岗区",
+      "盐田区",
+      "龙华区",
+      "坪山区",
+      "光明区"
+    ],
+    "珠海市": [
+      "香洲区",
+      "斗门区",
+      "金湾区"
+    ],
+    "汕头市": [
+      "龙湖区",
+      "金平区",
+      "濠江区",
+      "潮阳区",
+      "潮南区",
+      "澄海区",
+      "南澳县"
+    ],
+    "佛山市": [
+      "禅城区",
+      "南海区",
+      "顺德区",
+      "三水区",
+      "高明区"
+    ],
+    "江门市": [
+      "蓬江区",
+      "江海区",
+      "新会区",
+      "台山市",
+      "开平市",
+      "鹤山市",
+      "恩平市"
+    ],
+    "湛江市": [
+      "赤坎区",
+      "霞山区",
+      "坡头区",
+      "麻章区",
+      "遂溪县",
+      "徐闻县",
+      "廉江市",
+      "雷州市",
+      "吴川市"
+    ],
+    "茂名市": [
+      "茂南区",
+      "电白区",
+      "高州市",
+      "化州市",
+      "信宜市"
+    ],
+    "肇庆市": [
+      "端州区",
+      "鼎湖区",
+      "高要区",
+      "广宁县",
+      "怀集县",
+      "封开县",
+      "德庆县",
+      "四会市"
+    ],
+    "惠州市": [
+      "惠城区",
+      "惠阳区",
+      "博罗县",
+      "惠东县",
+      "龙门县"
+    ],
+    "梅州市": [
+      "梅江区",
+      "梅县区",
+      "大埔县",
+      "丰顺县",
+      "五华县",
+      "平远县",
+      "蕉岭县",
+      "兴宁市"
+    ],
+    "汕尾市": [
+      "城区",
+      "海丰县",
+      "陆河县",
+      "陆丰市"
+    ],
+    "河源市": [
+      "源城区",
+      "紫金县",
+      "龙川县",
+      "连平县",
+      "和平县",
+      "东源县"
+    ],
+    "阳江市": [
+      "江城区",
+      "阳东区",
+      "阳西县",
+      "阳春市"
+    ],
+    "清远市": [
+      "清城区",
+      "清新区",
+      "佛冈县",
+      "阳山县",
+      "连山壮族瑶族自治县",
+      "连南瑶族自治县",
+      "英德市",
+      "连州市"
+    ],
+    "东莞市": [
+      "东城街道",
+      "南城街道",
+      "万江街道",
+      "莞城街道",
+      "石碣镇",
+      "石龙镇",
+      "茶山镇",
+      "石排镇",
+      "企石镇",
+      "横沥镇",
+      "桥头镇",
+      "谢岗镇",
+      "东坑镇",
+      "常平镇",
+      "寮步镇",
+      "樟木头镇",
+      "大朗镇",
+      "黄江镇",
+      "清溪镇",
+      "塘厦镇",
+      "凤岗镇",
+      "大岭山镇",
+      "长安镇",
+      "虎门镇",
+      "厚街镇",
+      "沙田镇",
+      "道滘镇",
+      "洪梅镇",
+      "麻涌镇",
+      "望牛墩镇",
+      "中堂镇",
+      "高埗镇",
+      "松山湖管委会",
+      "东莞港",
+      "东莞生态园"
+    ],
+    "中山市": [
+      "石岐区街道",
+      "东区街道",
+      "火炬开发区街道",
+      "西区街道",
+      "南区街道",
+      "五桂山街道",
+      "小榄镇",
+      "黄圃镇",
+      "民众镇",
+      "东凤镇",
+      "东升镇",
+      "古镇镇",
+      "沙溪镇",
+      "坦洲镇",
+      "港口镇",
+      "三角镇",
+      "横栏镇",
+      "南头镇",
+      "阜沙镇",
+      "南朗镇",
+      "三乡镇",
+      "板芙镇",
+      "大涌镇",
+      "神湾镇"
+    ],
+    "潮州市": [
+      "湘桥区",
+      "潮安区",
+      "饶平县"
+    ],
+    "揭阳市": [
+      "榕城区",
+      "揭东区",
+      "揭西县",
+      "惠来县",
+      "普宁市"
+    ],
+    "云浮市": [
+      "云城区",
+      "云安区",
+      "新兴县",
+      "郁南县",
+      "罗定市"
+    ]
+  },
+  "广西壮族自治区": {
+    "南宁市": [
+      "兴宁区",
+      "青秀区",
+      "江南区",
+      "西乡塘区",
+      "良庆区",
+      "邕宁区",
+      "武鸣区",
+      "隆安县",
+      "马山县",
+      "上林县",
+      "宾阳县",
+      "横县"
+    ],
+    "柳州市": [
+      "城中区",
+      "鱼峰区",
+      "柳南区",
+      "柳北区",
+      "柳江区",
+      "柳城县",
+      "鹿寨县",
+      "融安县",
+      "融水苗族自治县",
+      "三江侗族自治县"
+    ],
+    "桂林市": [
+      "秀峰区",
+      "叠彩区",
+      "象山区",
+      "七星区",
+      "雁山区",
+      "临桂区",
+      "阳朔县",
+      "灵川县",
+      "全州县",
+      "兴安县",
+      "永福县",
+      "灌阳县",
+      "龙胜各族自治县",
+      "资源县",
+      "平乐县",
+      "恭城瑶族自治县",
+      "荔浦市"
+    ],
+    "梧州市": [
+      "万秀区",
+      "长洲区",
+      "龙圩区",
+      "苍梧县",
+      "藤县",
+      "蒙山县",
+      "岑溪市"
+    ],
+    "北海市": [
+      "海城区",
+      "银海区",
+      "铁山港区",
+      "合浦县"
+    ],
+    "防城港市": [
+      "港口区",
+      "防城区",
+      "上思县",
+      "东兴市"
+    ],
+    "钦州市": [
+      "钦南区",
+      "钦北区",
+      "灵山县",
+      "浦北县"
+    ],
+    "贵港市": [
+      "港北区",
+      "港南区",
+      "覃塘区",
+      "平南县",
+      "桂平市"
+    ],
+    "玉林市": [
+      "玉州区",
+      "福绵区",
+      "容县",
+      "陆川县",
+      "博白县",
+      "兴业县",
+      "北流市"
+    ],
+    "百色市": [
+      "右江区",
+      "田阳县",
+      "田东县",
+      "平果县",
+      "德保县",
+      "那坡县",
+      "凌云县",
+      "乐业县",
+      "田林县",
+      "西林县",
+      "隆林各族自治县",
+      "靖西市"
+    ],
+    "贺州市": [
+      "八步区",
+      "平桂区",
+      "昭平县",
+      "钟山县",
+      "富川瑶族自治县"
+    ],
+    "河池市": [
+      "金城江区",
+      "宜州区",
+      "南丹县",
+      "天峨县",
+      "凤山县",
+      "东兰县",
+      "罗城仫佬族自治县",
+      "环江毛南族自治县",
+      "巴马瑶族自治县",
+      "都安瑶族自治县",
+      "大化瑶族自治县"
+    ],
+    "来宾市": [
+      "兴宾区",
+      "忻城县",
+      "象州县",
+      "武宣县",
+      "金秀瑶族自治县",
+      "合山市"
+    ],
+    "崇左市": [
+      "江州区",
+      "扶绥县",
+      "宁明县",
+      "龙州县",
+      "大新县",
+      "天等县",
+      "凭祥市"
+    ]
+  },
+  "海南省": {
+    "海口市": [
+      "秀英区",
+      "龙华区",
+      "琼山区",
+      "美兰区"
+    ],
+    "三亚市": [
+      "海棠区",
+      "吉阳区",
+      "天涯区",
+      "崖州区"
+    ],
+    "三沙市": [
+      "西沙群岛",
+      "南沙群岛",
+      "中沙群岛的岛礁及其海域"
+    ],
+    "儋州市": [
+      "那大镇",
+      "和庆镇",
+      "南丰镇",
+      "大成镇",
+      "雅星镇",
+      "兰洋镇",
+      "光村镇",
+      "木棠镇",
+      "海头镇",
+      "峨蔓镇",
+      "王五镇",
+      "白马井镇",
+      "中和镇",
+      "排浦镇",
+      "东成镇",
+      "新州镇",
+      "洋浦经济开发区",
+      "华南热作学院"
+    ],
+    "省直辖县级行政区划": [
+      "五指山市",
+      "琼海市",
+      "文昌市",
+      "万宁市",
+      "东方市",
+      "定安县",
+      "屯昌县",
+      "澄迈县",
+      "临高县",
+      "白沙黎族自治县",
+      "昌江黎族自治县",
+      "乐东黎族自治县",
+      "陵水黎族自治县",
+      "保亭黎族苗族自治县",
+      "琼中黎族苗族自治县"
+    ]
+  },
+  "重庆市": {
+    "市辖区": [
+      "万州区",
+      "涪陵区",
+      "渝中区",
+      "大渡口区",
+      "江北区",
+      "沙坪坝区",
+      "九龙坡区",
+      "南岸区",
+      "北碚区",
+      "綦江区",
+      "大足区",
+      "渝北区",
+      "巴南区",
+      "黔江区",
+      "长寿区",
+      "江津区",
+      "合川区",
+      "永川区",
+      "南川区",
+      "璧山区",
+      "铜梁区",
+      "潼南区",
+      "荣昌区",
+      "开州区",
+      "梁平区",
+      "武隆区"
+    ],
+    "县": [
+      "城口县",
+      "丰都县",
+      "垫江县",
+      "忠县",
+      "云阳县",
+      "奉节县",
+      "巫山县",
+      "巫溪县",
+      "石柱土家族自治县",
+      "秀山土家族苗族自治县",
+      "酉阳土家族苗族自治县",
+      "彭水苗族土家族自治县"
+    ]
+  },
+  "四川省": {
+    "成都市": [
+      "锦江区",
+      "青羊区",
+      "金牛区",
+      "武侯区",
+      "成华区",
+      "龙泉驿区",
+      "青白江区",
+      "新都区",
+      "温江区",
+      "双流区",
+      "郫都区",
+      "金堂县",
+      "大邑县",
+      "蒲江县",
+      "新津县",
+      "都江堰市",
+      "彭州市",
+      "邛崃市",
+      "崇州市",
+      "简阳市"
+    ],
+    "自贡市": [
+      "自流井区",
+      "贡井区",
+      "大安区",
+      "沿滩区",
+      "荣县",
+      "富顺县"
+    ],
+    "攀枝花市": [
+      "东区",
+      "西区",
+      "仁和区",
+      "米易县",
+      "盐边县"
+    ],
+    "泸州市": [
+      "江阳区",
+      "纳溪区",
+      "龙马潭区",
+      "泸县",
+      "合江县",
+      "叙永县",
+      "古蔺县"
+    ],
+    "德阳市": [
+      "旌阳区",
+      "罗江区",
+      "中江县",
+      "广汉市",
+      "什邡市",
+      "绵竹市"
+    ],
+    "绵阳市": [
+      "涪城区",
+      "游仙区",
+      "安州区",
+      "三台县",
+      "盐亭县",
+      "梓潼县",
+      "北川羌族自治县",
+      "平武县",
+      "江油市"
+    ],
+    "广元市": [
+      "利州区",
+      "昭化区",
+      "朝天区",
+      "旺苍县",
+      "青川县",
+      "剑阁县",
+      "苍溪县"
+    ],
+    "遂宁市": [
+      "船山区",
+      "安居区",
+      "蓬溪县",
+      "射洪县",
+      "大英县"
+    ],
+    "内江市": [
+      "市中区",
+      "东兴区",
+      "威远县",
+      "资中县",
+      "内江经济开发区",
+      "隆昌市"
+    ],
+    "乐山市": [
+      "市中区",
+      "沙湾区",
+      "五通桥区",
+      "金口河区",
+      "犍为县",
+      "井研县",
+      "夹江县",
+      "沐川县",
+      "峨边彝族自治县",
+      "马边彝族自治县",
+      "峨眉山市"
+    ],
+    "南充市": [
+      "顺庆区",
+      "高坪区",
+      "嘉陵区",
+      "南部县",
+      "营山县",
+      "蓬安县",
+      "仪陇县",
+      "西充县",
+      "阆中市"
+    ],
+    "眉山市": [
+      "东坡区",
+      "彭山区",
+      "仁寿县",
+      "洪雅县",
+      "丹棱县",
+      "青神县"
+    ],
+    "宜宾市": [
+      "翠屏区",
+      "南溪区",
+      "叙州区",
+      "江安县",
+      "长宁县",
+      "高县",
+      "珙县",
+      "筠连县",
+      "兴文县",
+      "屏山县"
+    ],
+    "广安市": [
+      "广安区",
+      "前锋区",
+      "岳池县",
+      "武胜县",
+      "邻水县",
+      "华蓥市"
+    ],
+    "达州市": [
+      "通川区",
+      "达川区",
+      "宣汉县",
+      "开江县",
+      "大竹县",
+      "渠县",
+      "达州经济开发区",
+      "万源市"
+    ],
+    "雅安市": [
+      "雨城区",
+      "名山区",
+      "荥经县",
+      "汉源县",
+      "石棉县",
+      "天全县",
+      "芦山县",
+      "宝兴县"
+    ],
+    "巴中市": [
+      "巴州区",
+      "恩阳区",
+      "通江县",
+      "南江县",
+      "平昌县",
+      "巴中经济开发区"
+    ],
+    "资阳市": [
+      "雁江区",
+      "安岳县",
+      "乐至县"
+    ],
+    "阿坝藏族羌族自治州": [
+      "马尔康市",
+      "汶川县",
+      "理县",
+      "茂县",
+      "松潘县",
+      "九寨沟县",
+      "金川县",
+      "小金县",
+      "黑水县",
+      "壤塘县",
+      "阿坝县",
+      "若尔盖县",
+      "红原县"
+    ],
+    "甘孜藏族自治州": [
+      "康定市",
+      "泸定县",
+      "丹巴县",
+      "九龙县",
+      "雅江县",
+      "道孚县",
+      "炉霍县",
+      "甘孜县",
+      "新龙县",
+      "德格县",
+      "白玉县",
+      "石渠县",
+      "色达县",
+      "理塘县",
+      "巴塘县",
+      "乡城县",
+      "稻城县",
+      "得荣县"
+    ],
+    "凉山彝族自治州": [
+      "西昌市",
+      "木里藏族自治县",
+      "盐源县",
+      "德昌县",
+      "会理县",
+      "会东县",
+      "宁南县",
+      "普格县",
+      "布拖县",
+      "金阳县",
+      "昭觉县",
+      "喜德县",
+      "冕宁县",
+      "越西县",
+      "甘洛县",
+      "美姑县",
+      "雷波县"
+    ]
+  },
+  "贵州省": {
+    "贵阳市": [
+      "南明区",
+      "云岩区",
+      "花溪区",
+      "乌当区",
+      "白云区",
+      "观山湖区",
+      "开阳县",
+      "息烽县",
+      "修文县",
+      "清镇市"
+    ],
+    "六盘水市": [
+      "钟山区",
+      "六枝特区",
+      "水城县",
+      "盘州市"
+    ],
+    "遵义市": [
+      "红花岗区",
+      "汇川区",
+      "播州区",
+      "桐梓县",
+      "绥阳县",
+      "正安县",
+      "道真仡佬族苗族自治县",
+      "务川仡佬族苗族自治县",
+      "凤冈县",
+      "湄潭县",
+      "余庆县",
+      "习水县",
+      "赤水市",
+      "仁怀市"
+    ],
+    "安顺市": [
+      "西秀区",
+      "平坝区",
+      "普定县",
+      "镇宁布依族苗族自治县",
+      "关岭布依族苗族自治县",
+      "紫云苗族布依族自治县"
+    ],
+    "毕节市": [
+      "七星关区",
+      "大方县",
+      "黔西县",
+      "金沙县",
+      "织金县",
+      "纳雍县",
+      "威宁彝族回族苗族自治县",
+      "赫章县"
+    ],
+    "铜仁市": [
+      "碧江区",
+      "万山区",
+      "江口县",
+      "玉屏侗族自治县",
+      "石阡县",
+      "思南县",
+      "印江土家族苗族自治县",
+      "德江县",
+      "沿河土家族自治县",
+      "松桃苗族自治县"
+    ],
+    "黔西南布依族苗族自治州": [
+      "兴义市",
+      "兴仁市",
+      "普安县",
+      "晴隆县",
+      "贞丰县",
+      "望谟县",
+      "册亨县",
+      "安龙县"
+    ],
+    "黔东南苗族侗族自治州": [
+      "凯里市",
+      "黄平县",
+      "施秉县",
+      "三穗县",
+      "镇远县",
+      "岑巩县",
+      "天柱县",
+      "锦屏县",
+      "剑河县",
+      "台江县",
+      "黎平县",
+      "榕江县",
+      "从江县",
+      "雷山县",
+      "麻江县",
+      "丹寨县"
+    ],
+    "黔南布依族苗族自治州": [
+      "都匀市",
+      "福泉市",
+      "荔波县",
+      "贵定县",
+      "瓮安县",
+      "独山县",
+      "平塘县",
+      "罗甸县",
+      "长顺县",
+      "龙里县",
+      "惠水县",
+      "三都水族自治县"
+    ]
+  },
+  "云南省": {
+    "昆明市": [
+      "五华区",
+      "盘龙区",
+      "官渡区",
+      "西山区",
+      "东川区",
+      "呈贡区",
+      "晋宁区",
+      "富民县",
+      "宜良县",
+      "石林彝族自治县",
+      "嵩明县",
+      "禄劝彝族苗族自治县",
+      "寻甸回族彝族自治县",
+      "安宁市"
+    ],
+    "曲靖市": [
+      "麒麟区",
+      "沾益区",
+      "马龙区",
+      "陆良县",
+      "师宗县",
+      "罗平县",
+      "富源县",
+      "会泽县",
+      "宣威市"
+    ],
+    "玉溪市": [
+      "红塔区",
+      "江川区",
+      "澄江县",
+      "通海县",
+      "华宁县",
+      "易门县",
+      "峨山彝族自治县",
+      "新平彝族傣族自治县",
+      "元江哈尼族彝族傣族自治县"
+    ],
+    "保山市": [
+      "隆阳区",
+      "施甸县",
+      "龙陵县",
+      "昌宁县",
+      "腾冲市"
+    ],
+    "昭通市": [
+      "昭阳区",
+      "鲁甸县",
+      "巧家县",
+      "盐津县",
+      "大关县",
+      "永善县",
+      "绥江县",
+      "镇雄县",
+      "彝良县",
+      "威信县",
+      "水富市"
+    ],
+    "丽江市": [
+      "古城区",
+      "玉龙纳西族自治县",
+      "永胜县",
+      "华坪县",
+      "宁蒗彝族自治县"
+    ],
+    "普洱市": [
+      "思茅区",
+      "宁洱哈尼族彝族自治县",
+      "墨江哈尼族自治县",
+      "景东彝族自治县",
+      "景谷傣族彝族自治县",
+      "镇沅彝族哈尼族拉祜族自治县",
+      "江城哈尼族彝族自治县",
+      "孟连傣族拉祜族佤族自治县",
+      "澜沧拉祜族自治县",
+      "西盟佤族自治县"
+    ],
+    "临沧市": [
+      "临翔区",
+      "凤庆县",
+      "云县",
+      "永德县",
+      "镇康县",
+      "双江拉祜族佤族布朗族傣族自治县",
+      "耿马傣族佤族自治县",
+      "沧源佤族自治县"
+    ],
+    "楚雄彝族自治州": [
+      "楚雄市",
+      "双柏县",
+      "牟定县",
+      "南华县",
+      "姚安县",
+      "大姚县",
+      "永仁县",
+      "元谋县",
+      "武定县",
+      "禄丰县"
+    ],
+    "红河哈尼族彝族自治州": [
+      "个旧市",
+      "开远市",
+      "蒙自市",
+      "弥勒市",
+      "屏边苗族自治县",
+      "建水县",
+      "石屏县",
+      "泸西县",
+      "元阳县",
+      "红河县",
+      "金平苗族瑶族傣族自治县",
+      "绿春县",
+      "河口瑶族自治县"
+    ],
+    "文山壮族苗族自治州": [
+      "文山市",
+      "砚山县",
+      "西畴县",
+      "麻栗坡县",
+      "马关县",
+      "丘北县",
+      "广南县",
+      "富宁县"
+    ],
+    "西双版纳傣族自治州": [
+      "景洪市",
+      "勐海县",
+      "勐腊县"
+    ],
+    "大理白族自治州": [
+      "大理市",
+      "漾濞彝族自治县",
+      "祥云县",
+      "宾川县",
+      "弥渡县",
+      "南涧彝族自治县",
+      "巍山彝族回族自治县",
+      "永平县",
+      "云龙县",
+      "洱源县",
+      "剑川县",
+      "鹤庆县"
+    ],
+    "德宏傣族景颇族自治州": [
+      "瑞丽市",
+      "芒市",
+      "梁河县",
+      "盈江县",
+      "陇川县"
+    ],
+    "怒江傈僳族自治州": [
+      "泸水市",
+      "福贡县",
+      "贡山独龙族怒族自治县",
+      "兰坪白族普米族自治县"
+    ],
+    "迪庆藏族自治州": [
+      "香格里拉市",
+      "德钦县",
+      "维西傈僳族自治县"
+    ]
+  },
+  "西藏自治区": {
+    "拉萨市": [
+      "城关区",
+      "堆龙德庆区",
+      "达孜区",
+      "林周县",
+      "当雄县",
+      "尼木县",
+      "曲水县",
+      "墨竹工卡县",
+      "格尔木藏青工业园区",
+      "拉萨经济技术开发区",
+      "西藏文化旅游创意园区",
+      "达孜工业园区"
+    ],
+    "日喀则市": [
+      "桑珠孜区",
+      "南木林县",
+      "江孜县",
+      "定日县",
+      "萨迦县",
+      "拉孜县",
+      "昂仁县",
+      "谢通门县",
+      "白朗县",
+      "仁布县",
+      "康马县",
+      "定结县",
+      "仲巴县",
+      "亚东县",
+      "吉隆县",
+      "聂拉木县",
+      "萨嘎县",
+      "岗巴县"
+    ],
+    "昌都市": [
+      "卡若区",
+      "江达县",
+      "贡觉县",
+      "类乌齐县",
+      "丁青县",
+      "察雅县",
+      "八宿县",
+      "左贡县",
+      "芒康县",
+      "洛隆县",
+      "边坝县"
+    ],
+    "林芝市": [
+      "巴宜区",
+      "工布江达县",
+      "米林县",
+      "墨脱县",
+      "波密县",
+      "察隅县",
+      "朗县"
+    ],
+    "山南市": [
+      "乃东区",
+      "扎囊县",
+      "贡嘎县",
+      "桑日县",
+      "琼结县",
+      "曲松县",
+      "措美县",
+      "洛扎县",
+      "加查县",
+      "隆子县",
+      "错那县",
+      "浪卡子县"
+    ],
+    "那曲市": [
+      "色尼区",
+      "嘉黎县",
+      "比如县",
+      "聂荣县",
+      "安多县",
+      "申扎县",
+      "索县",
+      "班戈县",
+      "巴青县",
+      "尼玛县",
+      "双湖县"
+    ],
+    "阿里地区": [
+      "普兰县",
+      "札达县",
+      "噶尔县",
+      "日土县",
+      "革吉县",
+      "改则县",
+      "措勤县"
+    ]
+  },
+  "陕西省": {
+    "西安市": [
+      "新城区",
+      "碑林区",
+      "莲湖区",
+      "灞桥区",
+      "未央区",
+      "雁塔区",
+      "阎良区",
+      "临潼区",
+      "长安区",
+      "高陵区",
+      "鄠邑区",
+      "蓝田县",
+      "周至县"
+    ],
+    "铜川市": [
+      "王益区",
+      "印台区",
+      "耀州区",
+      "宜君县"
+    ],
+    "宝鸡市": [
+      "渭滨区",
+      "金台区",
+      "陈仓区",
+      "凤翔县",
+      "岐山县",
+      "扶风县",
+      "眉县",
+      "陇县",
+      "千阳县",
+      "麟游县",
+      "凤县",
+      "太白县"
+    ],
+    "咸阳市": [
+      "秦都区",
+      "杨陵区",
+      "渭城区",
+      "三原县",
+      "泾阳县",
+      "乾县",
+      "礼泉县",
+      "永寿县",
+      "长武县",
+      "旬邑县",
+      "淳化县",
+      "武功县",
+      "兴平市",
+      "彬州市"
+    ],
+    "渭南市": [
+      "临渭区",
+      "华州区",
+      "潼关县",
+      "大荔县",
+      "合阳县",
+      "澄城县",
+      "蒲城县",
+      "白水县",
+      "富平县",
+      "韩城市",
+      "华阴市"
+    ],
+    "延安市": [
+      "宝塔区",
+      "安塞区",
+      "延长县",
+      "延川县",
+      "子长县",
+      "志丹县",
+      "吴起县",
+      "甘泉县",
+      "富县",
+      "洛川县",
+      "宜川县",
+      "黄龙县",
+      "黄陵县"
+    ],
+    "汉中市": [
+      "汉台区",
+      "南郑区",
+      "城固县",
+      "洋县",
+      "西乡县",
+      "勉县",
+      "宁强县",
+      "略阳县",
+      "镇巴县",
+      "留坝县",
+      "佛坪县"
+    ],
+    "榆林市": [
+      "榆阳区",
+      "横山区",
+      "府谷县",
+      "靖边县",
+      "定边县",
+      "绥德县",
+      "米脂县",
+      "佳县",
+      "吴堡县",
+      "清涧县",
+      "子洲县",
+      "神木市"
+    ],
+    "安康市": [
+      "汉滨区",
+      "汉阴县",
+      "石泉县",
+      "宁陕县",
+      "紫阳县",
+      "岚皋县",
+      "平利县",
+      "镇坪县",
+      "旬阳县",
+      "白河县"
+    ],
+    "商洛市": [
+      "商州区",
+      "洛南县",
+      "丹凤县",
+      "商南县",
+      "山阳县",
+      "镇安县",
+      "柞水县"
+    ]
+  },
+  "甘肃省": {
+    "兰州市": [
+      "城关区",
+      "七里河区",
+      "西固区",
+      "安宁区",
+      "红古区",
+      "永登县",
+      "皋兰县",
+      "榆中县",
+      "兰州新区"
+    ],
+    "嘉峪关市": [
+      "新城镇",
+      "峪泉镇",
+      "文殊镇",
+      "雄关区",
+      "镜铁区",
+      "长城区"
+    ],
+    "金昌市": [
+      "金川区",
+      "永昌县"
+    ],
+    "白银市": [
+      "白银区",
+      "平川区",
+      "靖远县",
+      "会宁县",
+      "景泰县"
+    ],
+    "天水市": [
+      "秦州区",
+      "麦积区",
+      "清水县",
+      "秦安县",
+      "甘谷县",
+      "武山县",
+      "张家川回族自治县"
+    ],
+    "武威市": [
+      "凉州区",
+      "民勤县",
+      "古浪县",
+      "天祝藏族自治县"
+    ],
+    "张掖市": [
+      "甘州区",
+      "肃南裕固族自治县",
+      "民乐县",
+      "临泽县",
+      "高台县",
+      "山丹县"
+    ],
+    "平凉市": [
+      "崆峒区",
+      "泾川县",
+      "灵台县",
+      "崇信县",
+      "庄浪县",
+      "静宁县",
+      "华亭市"
+    ],
+    "酒泉市": [
+      "肃州区",
+      "金塔县",
+      "瓜州县",
+      "肃北蒙古族自治县",
+      "阿克塞哈萨克族自治县",
+      "玉门市",
+      "敦煌市"
+    ],
+    "庆阳市": [
+      "西峰区",
+      "庆城县",
+      "环县",
+      "华池县",
+      "合水县",
+      "正宁县",
+      "宁县",
+      "镇原县"
+    ],
+    "定西市": [
+      "安定区",
+      "通渭县",
+      "陇西县",
+      "渭源县",
+      "临洮县",
+      "漳县",
+      "岷县"
+    ],
+    "陇南市": [
+      "武都区",
+      "成县",
+      "文县",
+      "宕昌县",
+      "康县",
+      "西和县",
+      "礼县",
+      "徽县",
+      "两当县"
+    ],
+    "临夏回族自治州": [
+      "临夏市",
+      "临夏县",
+      "康乐县",
+      "永靖县",
+      "广河县",
+      "和政县",
+      "东乡族自治县",
+      "积石山保安族东乡族撒拉族自治县"
+    ],
+    "甘南藏族自治州": [
+      "合作市",
+      "临潭县",
+      "卓尼县",
+      "舟曲县",
+      "迭部县",
+      "玛曲县",
+      "碌曲县",
+      "夏河县"
+    ]
+  },
+  "青海省": {
+    "西宁市": [
+      "城东区",
+      "城中区",
+      "城西区",
+      "城北区",
+      "大通回族土族自治县",
+      "湟中县",
+      "湟源县"
+    ],
+    "海东市": [
+      "乐都区",
+      "平安区",
+      "民和回族土族自治县",
+      "互助土族自治县",
+      "化隆回族自治县",
+      "循化撒拉族自治县"
+    ],
+    "海北藏族自治州": [
+      "门源回族自治县",
+      "祁连县",
+      "海晏县",
+      "刚察县"
+    ],
+    "黄南藏族自治州": [
+      "同仁县",
+      "尖扎县",
+      "泽库县",
+      "河南蒙古族自治县"
+    ],
+    "海南藏族自治州": [
+      "共和县",
+      "同德县",
+      "贵德县",
+      "兴海县",
+      "贵南县"
+    ],
+    "果洛藏族自治州": [
+      "玛沁县",
+      "班玛县",
+      "甘德县",
+      "达日县",
+      "久治县",
+      "玛多县"
+    ],
+    "玉树藏族自治州": [
+      "玉树市",
+      "杂多县",
+      "称多县",
+      "治多县",
+      "囊谦县",
+      "曲麻莱县"
+    ],
+    "海西蒙古族藏族自治州": [
+      "格尔木市",
+      "德令哈市",
+      "茫崖市",
+      "乌兰县",
+      "都兰县",
+      "天峻县",
+      "大柴旦行政委员会"
+    ]
+  },
+  "宁夏回族自治区": {
+    "银川市": [
+      "兴庆区",
+      "西夏区",
+      "金凤区",
+      "永宁县",
+      "贺兰县",
+      "灵武市"
+    ],
+    "石嘴山市": [
+      "大武口区",
+      "惠农区",
+      "平罗县"
+    ],
+    "吴忠市": [
+      "利通区",
+      "红寺堡区",
+      "盐池县",
+      "同心县",
+      "青铜峡市"
+    ],
+    "固原市": [
+      "原州区",
+      "西吉县",
+      "隆德县",
+      "泾源县",
+      "彭阳县"
+    ],
+    "中卫市": [
+      "沙坡头区",
+      "中宁县",
+      "海原县"
+    ]
+  },
+  "新疆维吾尔自治区": {
+    "乌鲁木齐市": [
+      "天山区",
+      "沙依巴克区",
+      "新市区",
+      "水磨沟区",
+      "头屯河区",
+      "达坂城区",
+      "米东区",
+      "乌鲁木齐县",
+      "乌鲁木齐经济技术开发区",
+      "乌鲁木齐高新技术产业开发区"
+    ],
+    "克拉玛依市": [
+      "独山子区",
+      "克拉玛依区",
+      "白碱滩区",
+      "乌尔禾区"
+    ],
+    "吐鲁番市": [
+      "高昌区",
+      "鄯善县",
+      "托克逊县"
+    ],
+    "哈密市": [
+      "伊州区",
+      "巴里坤哈萨克自治县",
+      "伊吾县"
+    ],
+    "昌吉回族自治州": [
+      "昌吉市",
+      "阜康市",
+      "呼图壁县",
+      "玛纳斯县",
+      "奇台县",
+      "吉木萨尔县",
+      "木垒哈萨克自治县"
+    ],
+    "博尔塔拉蒙古自治州": [
+      "博乐市",
+      "阿拉山口市",
+      "精河县",
+      "温泉县"
+    ],
+    "巴音郭楞蒙古自治州": [
+      "库尔勒市",
+      "轮台县",
+      "尉犁县",
+      "若羌县",
+      "且末县",
+      "焉耆回族自治县",
+      "和静县",
+      "和硕县",
+      "博湖县",
+      "库尔勒经济技术开发区"
+    ],
+    "阿克苏地区": [
+      "阿克苏市",
+      "温宿县",
+      "库车县",
+      "沙雅县",
+      "新和县",
+      "拜城县",
+      "乌什县",
+      "阿瓦提县",
+      "柯坪县"
+    ],
+    "克孜勒苏柯尔克孜自治州": [
+      "阿图什市",
+      "阿克陶县",
+      "阿合奇县",
+      "乌恰县"
+    ],
+    "喀什地区": [
+      "喀什市",
+      "疏附县",
+      "疏勒县",
+      "英吉沙县",
+      "泽普县",
+      "莎车县",
+      "叶城县",
+      "麦盖提县",
+      "岳普湖县",
+      "伽师县",
+      "巴楚县",
+      "塔什库尔干塔吉克自治县"
+    ],
+    "和田地区": [
+      "和田市",
+      "和田县",
+      "墨玉县",
+      "皮山县",
+      "洛浦县",
+      "策勒县",
+      "于田县",
+      "民丰县"
+    ],
+    "伊犁哈萨克自治州": [
+      "伊宁市",
+      "奎屯市",
+      "霍尔果斯市",
+      "伊宁县",
+      "察布查尔锡伯自治县",
+      "霍城县",
+      "巩留县",
+      "新源县",
+      "昭苏县",
+      "特克斯县",
+      "尼勒克县"
+    ],
+    "塔城地区": [
+      "塔城市",
+      "乌苏市",
+      "额敏县",
+      "沙湾县",
+      "托里县",
+      "裕民县",
+      "和布克赛尔蒙古自治县"
+    ],
+    "阿勒泰地区": [
+      "阿勒泰市",
+      "布尔津县",
+      "富蕴县",
+      "福海县",
+      "哈巴河县",
+      "青河县",
+      "吉木乃县"
+    ],
+    "自治区直辖县级行政区划": [
+      "石河子市",
+      "阿拉尔市",
+      "图木舒克市",
+      "五家渠市",
+      "铁门关市"
+    ]
+  }
+}

+ 388 - 0
app/src/components/appHeader.vue

@@ -0,0 +1,388 @@
+<template>
+    <div id="appHeader">
+        <div id="headerContent">
+            <mu-appbar style="width: 100%;" color="primary">
+                <mu-button icon slot="left">
+                    <mu-button ref="button" @click="open = !open">
+                        <img src="../static/images/comm/list.png" alt="" class="listBtn">
+                    </mu-button>
+                    <mu-popover cover :open.sync="open" :trigger="trigger">
+                        <mu-list>
+                            <mu-list-item button :class="[{'active':t == curLi},'modalLi' ]"
+                                          v-for="(panel,t) in panelData" :key="panel.tabs" @click="goPage(panel)">
+                                <mu-list-item-title>
+                                    <!--<span :class="panel.img"></span>-->
+                                    <mu-icon :value="panel.img"></mu-icon>
+                                    <s>{{panel.name}}</s>
+                                </mu-list-item-title>
+                            </mu-list-item>
+                        </mu-list>
+                    </mu-popover>
+                </mu-button>
+                {{curTitle}}
+                <mu-menu slot="right">
+                    <img src="../static/images/comm/user.png" alt="" class="userBtn">
+                </mu-menu>
+            </mu-appbar>
+            <div class="alertRed" v-show="alertState && title == '系统首页'">
+                <em>
+                    <i class="curIcon yellowTri"></i>
+                    发现危险设备{{dangerNum}} {{$t("item")}}
+                </em>
+                <span @click="goRuntime">{{$t("Suspicious device")}}MAC:{{mac}} 品牌:{{MacCom}} <i
+                        @click="closeAlert">×</i></span>
+            </div>
+        </div>
+    </div>
+</template>
+
+<script>
+    import axios from 'axios';
+
+    let qs = require('qs');
+    export default {
+        data() {
+            return {
+                open: false,
+                trigger: null,
+                curLi: 0,
+                curTitle: this.title,
+                alertState: false,
+                dangerNum: 0,
+                mac: '',
+                MacCom: '',
+                panelData: [
+                    {name: this.$t('System home page'), path: '', img: 'home', tabs: 1},
+                    {name: this.$t('User list'), path: 'usermanage', img: 'account_box', tabs: 2},
+                    {name: this.$t('Enterprise list'), path: 'enterprisemanage', img: 'assignment', tabs: 3},
+                    {name: this.$t('Detection equipment'), path: 'detector', img: 'laptop', tabs: 4},
+                    {name: this.$t('Detection record'), path: 'record', img: 'reorder', tabs: 5},
+                    {name: this.$t('Statistical report forms'), path: 'statis', img: 'receipt', tabs: 6},
+                    {name: this.$t('System setup'), path: 'setting', img: 'settings', tabs: 7},
+                    {name: this.$t('whiteList'), path: 'white', img: 'view_list', tabs: 8},
+                    {name: this.$t('Real-time monitoring'), path: 'runtime', img: 'poll', tabs: 9},
+                ]
+            }
+        },
+        props: ['title'],
+        mounted() {
+            this.trigger = this.$refs.button.$el;
+            this.timer = setInterval(() => {
+                this.readAlert();
+            }, 5000);
+        },
+        beforeDestroy() {
+            clearInterval(this.timer);
+        },
+        methods: {
+            goPage(panel) {
+                console.log(panel);
+                this.$emit('goNewpage', panel.path);
+                this.open = false;
+            },
+            goRuntime() {
+                this.alertState = false;
+                this.$emit('goNewpage', 'runtime');
+                this.open = false;
+            },
+            // 读取警告信息
+            readAlert() {
+                const that = this;
+                let url = headapi + 'v1/Detector/DetectedMacs';
+                // let url = headapi + 'v1/Detector/DetectedMacsTest';//test
+                let param = {
+                    token: localStorage.token,
+                };
+                let postdata = qs.stringify(param);
+                axios.post(url, postdata).then(function (data) {
+                    let json = data.data;
+                    if (json.Code == 0) {
+                        if (json.Rs) {
+                            if (localStorage.alertState == true) {
+                                that.alertState = true;
+                            } else {
+                                that.alertState = false;
+                            }
+                            that.dangerNum = json.Rs.length;
+                            that.mac = json.Rs[0].Mac;
+                            if (json.Rs[0].MacCom) {
+                                that.MacCom = json.Rs[0].MacCom.substr(0, 9) + '...';
+                            }
+
+                        }
+                    }
+                    if (json.Code == 1010) {
+                        that.$router.push({path: '/login'});
+                    }
+                }, function (response) {
+                    that.$router.push({path: '/login'});
+                    console.info(response);
+                })
+            },
+            closeAlert() {
+                this.alertState = false
+            }
+        },
+    }
+</script>
+
+<style scoped>
+    #appHeader {
+        width: 100%;
+        height: 55px;
+        z-index: 99999;
+    }
+    #headerContent {
+        width: 100%;
+        position: absolute;
+        z-index: 99999;
+        top: 0;
+    }
+    /deep/ .mu-appbar-title {
+        text-align: center;
+    }
+
+    .mu-raised-button {
+        background: none;
+        box-shadow: none;
+    }
+
+    .listBtn {
+        width: 20px;
+        height: 14px;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        margin-top: 0px;
+    }
+
+    .userBtn {
+        width: 28px;
+        height: 28px;
+        margin-top: 15px;
+        margin-right: 15px;
+    }
+
+    .mu-appbar {
+        background: url("../static/images/comm/headerBg.png") top center no-repeat;
+        background-size: 100%;
+    }
+
+    /*icon iconHome*/
+    .iconHome {
+        width: 20px;
+        height: 20px;
+        float: left;
+        margin-right: 10px;
+        background: url("../static/images/comm/iconHome.png") top center no-repeat;
+        background-size: 100%;
+    }
+
+    .active .iconHome {
+        width: 20px;
+        height: 20px;
+        float: left;
+        margin-right: 10px;
+        background: url("../static/images/comm/iconHome_a.png") top center no-repeat;
+        background-size: 100%;
+    }
+
+    .iconUser {
+        width: 20px;
+        height: 20px;
+        float: left;
+        margin-right: 10px;
+        background: url("../static/images/comm/iconUser.png") top center no-repeat;
+        background-size: 100%;
+    }
+
+    .active .iconUser {
+        width: 20px;
+        height: 20px;
+        float: left;
+        margin-right: 10px;
+        background: url("../static/images/comm/iconUser_a.png") top center no-repeat;
+        background-size: 100%;
+    }
+
+    .iconProfile {
+        width: 20px;
+        height: 20px;
+        float: left;
+        margin-right: 10px;
+        background: url("../static/images/comm/iconProfile.png") top center no-repeat;
+        background-size: 100%;
+    }
+
+    .active .iconProfile {
+        width: 20px;
+        height: 20px;
+        float: left;
+        margin-right: 10px;
+        background: url("../static/images/comm/iconProfile_a.png") top center no-repeat;
+        background-size: 100%;
+    }
+
+    .iconEquipmanage {
+        width: 20px;
+        height: 20px;
+        float: left;
+        margin-right: 10px;
+        background: url("../static/images/comm/iconEquipmanage.png") top center no-repeat;
+        background-size: 100%;
+    }
+
+    .active .iconEquipmanage {
+        width: 20px;
+        height: 20px;
+        float: left;
+        margin-right: 10px;
+        background: url("../static/images/comm/iconEquipmanage_a.png") top center no-repeat;
+        background-size: 100%;
+    }
+
+    .iconRecord {
+        width: 20px;
+        height: 20px;
+        float: left;
+        margin-right: 10px;
+        background: url("../static/images/comm/iconRecord.png") top center no-repeat;
+        background-size: 100%;
+    }
+
+    .active .iconRecord {
+        width: 20px;
+        height: 20px;
+        float: left;
+        margin-right: 10px;
+        background: url("../static/images/comm/iconRecord_a.png") top center no-repeat;
+        background-size: 100%;
+    }
+
+    .iconStatis {
+        width: 20px;
+        height: 20px;
+        float: left;
+        margin-right: 10px;
+        background: url("../static/images/comm/iconStatis.png") top center no-repeat;
+        background-size: 100%;
+    }
+
+    .active .iconStatis {
+        width: 20px;
+        height: 20px;
+        float: left;
+        margin-right: 10px;
+        background: url("../static/images/comm/iconStatis_a.png") top center no-repeat;
+        background-size: 100%;
+    }
+
+    .iconMap {
+        width: 20px;
+        height: 20px;
+        float: left;
+        margin-right: 10px;
+        background: url("../static/images/comm/iconMap.png") top center no-repeat;
+        background-size: 100%;
+    }
+
+    .active .iconMap {
+        width: 20px;
+        height: 20px;
+        float: left;
+        margin-right: 10px;
+        background: url("../static/images/comm/iconMap_a.png") top center no-repeat;
+        background-size: 100%;
+    }
+
+    .iconRuntime {
+        width: 20px;
+        height: 20px;
+        float: left;
+        margin-right: 10px;
+        background: url("../static/images/comm/iconRuntime.png") top center no-repeat;
+        background-size: 100%;
+    }
+
+    .active .iconRuntime {
+        width: 20px;
+        height: 20px;
+        float: left;
+        margin-right: 10px;
+        background: url("../static/images/comm/iconRuntime_a.png") top center no-repeat;
+        background-size: 100%;
+    }
+
+    .modalLi span {
+        width: 20px;
+        height: 20px;
+        margin-right: 0px !important;
+    }
+
+    .modalLi s {
+        text-decoration: none;
+        font-size: 14px;
+        line-height: 30px;
+        padding-left: 10px;
+        float: right;
+    }
+
+    .alertRed {
+        position: absolute;
+        width: 100%;
+        overflow: visible;
+        display: block;
+        margin: 0 auto;
+        background: #FFF8DB;
+        padding-left: 2%;
+        padding-right: 2%;
+    }
+
+    .alertRed em {
+        position: relative;
+        top: -10px;
+        width: 139px;
+        height: 18px;
+        line-height: 18px;
+        background: red;
+        color: #fff;
+        margin: 0 auto;
+        display: block;
+        border-radius: 9px;
+        text-align: center;
+        font-size: 12px;
+    }
+
+    .yellowTri {
+        width: 9px;
+        height: 8px;
+        float: left;
+        margin-left: 15px;
+        margin-top: 4px;
+        background: url("../static/images/icon/triIcon.png") top center no-repeat;
+        background-size: 100%;
+    }
+
+    .alertRed span {
+        width: 100%;
+        height: 30px;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        text-align: center;
+        color: red;
+        font-size: 12px;
+    }
+
+    .alertRed span i {
+        float: right;
+        color: #ccc;
+        font-size: 18px;
+        line-height: 20px;
+    }
+    /deep/ .mu-item-title s {
+        width: 65px;
+        text-align: justify;
+        text-align-last: justify;
+    }
+</style>

+ 47 - 0
app/src/components/bottomTab.vue

@@ -0,0 +1,47 @@
+<template>
+    <div id="bottomTab">
+        <mu-container style="width: 100%;" color="primary">
+            <mu-bottom-nav :value="nowTab" color="#FFA200">
+                <mu-bottom-nav-item v-for="tab in tabs" :title="tab.name" :icon="tab.src" :to="tab.class"  :key="tab.tabindex" :value="tab.name"></mu-bottom-nav-item>
+            </mu-bottom-nav>
+        </mu-container>
+    </div>
+</template>
+
+<script>
+    export default {
+        data() {
+            return {
+                nowTab:this.curTab,
+                tabs: [
+                    {name:this.$t('home'), class: '/', src: 'home',tabindex:1},
+                    {name:this.$t('Map'), class: 'map', src: 'map',tabindex:2},
+                    {name:this.$t('Detection'), class: 'detector', src: 'laptop',tabindex:3},
+                    {name:this.$t('Real-time'), class: 'runtime', src: 'poll',tabindex:4},
+                ]
+            }
+        },
+        props: ['curTab'],
+        methods: {
+        },
+        watch: {
+            '$route': function (e) {
+                this.nowTab = e.meta.title;
+            }
+        },
+    }
+</script>
+
+<style scoped>
+    #bottomTab {
+        position: absolute;
+        bottom: 0;
+        width: 100%;
+        background: #fff;
+        border-top: 1px solid #eee;
+        z-index: 9999;
+    }
+    .container {
+        padding: 0;
+    }
+</style>

+ 139 - 0
app/src/components/cityPicker.vue

@@ -0,0 +1,139 @@
+<template>
+    <div>
+        <div class="demo-picker-container citypickerContainer">
+            <p @click="pickerState = true">
+                <span> {{addressProvince}} <img src="../static/images/comm/cityPicker.png" alt=""></span>
+                <span> {{addressCity}} <img src="../static/images/comm/cityPicker.png" alt=""></span>
+                <span> {{addressCounty}} <img src="../static/images/comm/cityPicker.png" alt=""></span>
+            </p>
+            <mu-slide-picker
+                    v-show="pickerState"
+                    :slots="addressSlots"
+                             :visible-item-count="7"
+                             @change="addressChange"
+                             :values="address"></mu-slide-picker>
+            <mu-button id="closeBtn" color="warning" @click="pickerState = false" v-show="pickerState">收起</mu-button>
+
+        </div>
+    </div>
+</template>
+
+<script>
+    import myaddress from '../components/address3.json'
+
+    export default {
+        data() {
+            return {
+                addressSlots: [
+                    {
+                        width: '100%',
+                        textAlign: 'right',
+                        values: Object.keys(myaddress)
+                    }, {
+                        width: '100%',
+                        textAlign: 'left',
+                        values: Object.keys(myaddress['山东省']),
+                    }, {
+                        width: '100%',
+                        textAlign: 'left',
+                        values: myaddress['山东省']['济南市'],
+                    }
+                ],
+                address: ['山东省', '济南市', '历下区'],
+                addressProvince: '山东省',
+                addressCity: '济南市',
+                addressCounty: '历下区',
+                pickerState: false,
+            }
+        },
+        created() {
+        },
+        methods: {
+            addressChange(value, index) {
+                switch (index) {
+                    case 0:
+                        this.addressProvince = value;
+                        let ProvinceName = value.substring(0, value.length - 1);
+                        this.addressSlots[1].values = address[ProvinceName];
+                        this.addressCity = address[ProvinceName][0] + '市';
+                        break;
+                    case 1:
+                        this.addressCity = value;
+                        let arrCity = myaddress[this.addressProvince][value];
+                        this.addressSlots[2].values = arrCity;
+                        this.addressCounty = arrCity[0];
+                        break;
+                    case 2:
+                        this.addressCounty = value;
+                        break
+                }
+                this.address = [this.addressProvince, this.addressCity, this.addressCounty];
+                localStorage.defaultProv =this.addressProvince.substring(0, this.addressProvince.length - 1);
+                localStorage.defaultCity =this.addressCity.substring(0, this.addressCity.length - 1);
+                localStorage.defaultArea =this.addressCounty;
+            }
+        }
+    }
+</script>
+
+<style scoped>
+    .demo-picker-container {
+        width: 100%;
+    }
+    .citypickerContainer {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+    }
+
+    .citypickerContainer p {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+    }
+
+    .citypickerContainer p span {
+        width: 94px;
+        float: left;
+        border: 1px solid #D5D5D5;
+        height: 30px;
+        line-height: 30px;
+        font-size: 12px;
+        padding-left: 10px;
+        padding-right: 10px;
+        margin-right: 3%;
+    }
+
+    .citypickerContainer p span:nth-child(3) {
+        margin-right: 0;
+        float: left;
+    }
+
+    .citypickerContainer p span img {
+        float: right;
+        width: 8px;
+        margin-top: 10px;
+    }
+    .pickerPart {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+    }
+
+    .center {
+        width: 100px;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        font-size: 12px;
+    }
+    #closeBtn {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+    }
+</style>

+ 396 - 0
app/src/components/mapDrag.vue

@@ -0,0 +1,396 @@
+<!--
+  描述:拖放地图组件,默认尺寸是 500 * 300
+  接收属性参数:
+    lat: 纬度
+    lng: 经度
+  自定义事件:
+    drag: 拖放完成事件
+  示例:
+    <mapDrag @drag="dragMap" lat="22.574405" lng="114.095388"></mapDrag>
+-->
+<template>
+    <div class="m-map" :style="{ height: curheight + 'px' }">
+        <div id="js-container" class="map">
+            <h5 style="text-align: center">{{$t("Loading data")}} ...</h5>
+        </div>
+    </div>
+</template>
+
+<script>
+    import remoteLoad from '../utils/remoteLoad.js'
+    import {MapKey, MapCityName} from '../tools/map'
+
+    let qs = require('qs');
+    import axios from 'axios';
+    import Global from '../../src/Global.js'
+
+    export default {
+        data() {
+            return {
+                searchKey: '',
+                placeSearch: null,
+                dragStatus: false,
+                AMapUI: null,
+                AMap: null,
+            }
+        },
+        props: {
+            curheight: {
+                default: 310,
+                type: Number
+            }
+        },
+        watch: {
+            searchKey() {
+                if (this.searchKey === '') {
+                    this.placeSearch.clear()
+                }
+            },
+        },
+        beforeDestroy() {
+            clearInterval(this.getPoint);
+        },
+        methods: {
+            // 实例化地图
+            initMap() {
+                let AMapUI = this.AMapUI = window.AMapUI;
+                let AMap = this.AMap = window.AMap;
+                let timeInterval = 5000;
+                let lang = localStorage.language == 'zh' ? 'zh' : 'en';
+                AMapUI.loadUI(['misc/PositionPicker'], PositionPicker => {
+                    let mapConfig = {
+                        resizeEnable: true, //是否监控地图容器尺寸变化
+                        // mapStyle: mapStyle,//地图颜色风格
+                        zoom: 16,
+                        cityName: MapCityName,
+                        lang: lang
+                    };
+                    let map = new AMap.Map('js-container', mapConfig);
+                    // 获取点位置
+                    this.getPoint(map);
+                    setInterval(this.getPoint(map), 5000);
+                    // 获取围栏信息
+                    this.getFenceInfo(map);
+
+                    // 启用工具条
+                    AMap.plugin(['AMap.ToolBar'], function () {
+                        map.addControl(new AMap.ToolBar({
+                            position: 'RB'
+                        }))
+                    });
+                })
+            },
+
+            // 实例化点标记
+            addMarker(map, lng, lat, content, imgState) {
+                let marker = new AMap.Marker({
+                    position: [lng, lat],
+                    offset: new AMap.Pixel(-13, -30),
+                    content: imgState,
+                });
+                marker.setMap(map);
+
+                // 弹窗偏移度
+                let infoWindow = new AMap.InfoWindow({offset: new AMap.Pixel(14, -20)});
+
+                marker.on('click', function (e) {
+                    infoWindow.setContent(content);
+                    infoWindow.open(map, e.target.getPosition());
+                });
+            },
+            // 获取所有的点位置
+            getPoint(map) {
+                const that = this;
+                let lnglats = [];
+                let url = '';
+                if (localStorage.userLevel == this.$t('单位管理员')) {
+                    url = headapi + 'v1/Company/GetRegionMapinfo';//获取 单个企业获取
+                } else {
+                    url = headapi + 'v1/Company/GetMapinfo';//获取
+                }
+                let param = {
+                    token: localStorage.token
+                };
+                let postdata = qs.stringify(param);
+                axios.post(url, postdata).then(function (data) {
+                    let json = data.data;
+                    if (json) {
+                        // 单个企业
+                        map.setCenter([json.Rs[0].Lng, json.Rs[0].Lat]);
+                        // todo 使用数学中心计算显示点中心
+                        localStorage.lnglats = JSON.stringify(json.Rs);
+                        if (localStorage.lnglats != JSON.stringify(lnglats)) {
+                            that.wirtePoint(map, json);
+                        }
+                        map.setFitView();
+                    }
+                }, function (response) {
+                    console.info(response);
+                })
+            },
+            // 画点
+            wirtePoint(map, json) {
+                let that = this;
+                let markers = [];
+                let curPointName = '';
+                let lnglats = json.Rs;
+                map.remove(markers);
+                // 根据状态判断图标显示颜色
+                for (var i = 0; i < lnglats.length; i++) {
+                    let imgState = '';
+                    curPointName = !lnglats[i].RegionName ? lnglats[i].ComName : lnglats[i].RegionName;
+                    switch (parseInt(lnglats[i].Detstatus)) {
+                        // 0 safe 1 warning 2 danger
+                        case 0:
+                            imgState = '<i class="green_point"></i> <span class="point_name">' + curPointName + '</span>';
+                            break;
+                        case 1:
+                            imgState = '<i class="green_point"></i> <span class="point_name">' + curPointName + '</span>';
+                            break;
+                        case 2:
+                            imgState = '<i class="red_point"></i> <span class="point_name">' + curPointName + '</span>';
+                            break;
+                    }
+
+                    var position;
+                    position = [json.Rs[i].Lng, json.Rs[i].Lat];
+
+                    let content = '';
+                        var state = '';
+                        switch (parseInt(lnglats[i].Detstatus)) {
+                            // 0 safe 1 warning 2 danger
+                            case 0:
+                                state = this.$t('normal');
+                                break;
+                            case 1:
+                                state = '<span style="color:#ffe943">' + this.$t('abnormal') + '</span>';
+                                break;
+                            case 2:
+                                state = '<span style="color:#ff0000">' + this.$t('danger') + '</span>';
+                                break;
+                        }
+
+                        let DecList = !json.Rs[i].DecList ? that.$t('not found') : json.Rs[i].DecList;
+                        content =
+                            '<span class="map_a" href="profile.html?hotelid=' + localStorage.comId + '&Regionid=' + json.Rs[i].Regionid + '">' +
+                            this.$t('region') + json.Rs[i].RegionName
+                            + '<br>' + this.$t('state') + ':' + state
+                            + '<br>' + this.$t('Detection') + ':' + json.Rs[i].DectorNum
+                            + '<br>' + this.$t('phone signal') + ':' + DecList
+                            + '<br>' + json.Rs[i].Wifiname + ':' + json.Rs[i].CamNum
+                            + '<br>' + this.$t('Suspicious') + json.Rs[i].Wifiname + ':' + json.Rs[i].DancapNum
+                            + '</span><em class="jumper" Regionid=' + json.Rs[i].Regionid + '>' +
+                            '<i class="icon iconProfile"  href="profile.html?hotelid=' + localStorage.comId + '&Regionid=' + json.Rs[i].Regionid + '"></i>' +
+                            '<i class="icon iconPlane" href="plane.html?hotelid=' + localStorage.comId + '&Regionid=' + json.Rs[i].Regionid + '"></i></em>';
+
+                    that.addMarker(map, json.Rs[i].Lng, json.Rs[i].Lat, content, imgState);
+                }
+            },
+            // 获取围栏信息
+            getFenceInfo(map) {
+                const that = this;
+                let url = headapi + 'v1/Company/GetComfencelist';
+                let param = {
+                    token: localStorage.token,
+                    comid: localStorage.comId
+                };
+                let postdata = qs.stringify(param);
+                axios.post(url, postdata).then(function (data) {
+                    let json = data.data;
+                    if (json.Code == 0) {
+                        let fence = json.Rs.Fence;
+                        let fenceArr = fence.split(",");
+                        let path = [];
+                        for (var i = 0; i < fenceArr.length; i++) {
+                            if (i % 2 == 0) {
+                                path.push([fenceArr[i], fenceArr[i + 1]]);
+                            }
+                        }
+                        let polygon = new AMap.Polygon({
+                            path: path,
+                            strokeColor: "#6496FF",
+                            strokeWeight: 6,
+                            strokeOpacity: 0.15,
+                            fillOpacity: 0.4,
+                            fillColor: '#6496FF',
+                            zIndex: 50,
+                        });
+
+                        map.add(polygon);
+
+                        // 缩放地图到合适的视野级别
+                        map.setFitView([polygon]);
+                    }
+                }, function (response) {
+                    console.info(response);
+                })
+            },
+            // 计算点中心
+            calcCenterBySingle(data) {
+                var total = data.length;
+                var lat = 0, lon = 0;
+                for (var i = 0; i < total; i++) {
+                    lat += data[i].Lat * Math.PI / 180;
+                    lon += data[i].Lng * Math.PI / 180;
+                }
+                lat /= total;
+                lon /= total;
+                return [lon * 180 / Math.PI, lat * 180 / Math.PI];
+            },
+            // 计算多点的数学圆心
+            calcCenter(data) {
+                var total = data.length;
+                var lat = 0, lon = 0;
+                for (var i = 0; i < total; i++) {
+                    lat += data[i][0] * Math.PI / 180;
+                    lon += data[i][1] * Math.PI / 180;
+                }
+                lat /= total;
+                lon /= total;
+                return [lat * 180 / Math.PI, lon * 180 / Math.PI];
+            }
+        },
+        async created() {
+            // 已载入高德地图API,则直接初始化地图
+            if (window.AMap && window.AMapUI) {
+                this.initMap()
+                // 未载入高德地图API,则先载入API再初始化
+            } else {
+                await remoteLoad(`http://webapi.amap.com/maps?v=1.3&key=${MapKey}`);
+                await remoteLoad('http://webapi.amap.com/ui/1.0/main.js');
+                this.initMap()
+            }
+        }
+    }
+</script>
+
+<style scoped>
+    .m-map {
+        width: 100%;
+        /*max-height: 317px;*/
+        /*height: 317px;*/
+        position: relative;
+    }
+
+    .m-map .map {
+        width: 100%;
+        height: 100%;
+    }
+
+    .m-map .search {
+        position: absolute;
+        top: 10px;
+        left: 10px;
+        width: 285px;
+        z-index: 1;
+    }
+
+    .m-map .search input {
+        width: 180px;
+        border: 1px solid #ccc;
+        line-height: 20px;
+        padding: 5px;
+        outline: none;
+    }
+
+    .m-map .search button {
+        line-height: 26px;
+        background: #fff;
+        border: 1px solid #ccc;
+        width: 50px;
+        text-align: center;
+    }
+
+    .m-map .result {
+        max-height: 300px;
+        overflow: auto;
+        margin-top: 10px;
+    }
+
+    /deep/ .green_point {
+        margin: 16px;
+        height: 16px;
+        width: 16px;
+        border-radius: 50% !important;
+        display: inline-block;
+        background-color: #1eff30;
+    }
+
+    /deep/ .yellow_point {
+        margin: 16px;
+        height: 16px;
+        width: 16px;
+        border-radius: 50% !important;
+        display: inline-block;
+        background-color: #f2ff24;
+    }
+
+    /deep/ .red_point {
+        margin: 16px;
+        height: 16px;
+        width: 16px;
+        border-radius: 50% !important;
+        display: inline-block;
+        transform: scale(0.5);
+        animation: bulge 2s infinite ease-in-out;
+        background-color: #ff0000;
+        animation-delay: 0s;
+    }
+
+    /deep/ .red_point::after {
+        position: absolute;
+        display: inline-block;
+        content: '';
+        height: 100%;
+        width: 100%;
+        border-radius: 50%;
+        background-color: inherit;
+        top: 0;
+        left: 0;
+        z-index: -1;
+        transform: scale(1);
+        animation: blow 2s infinite ease-in-out;
+    }
+
+    /deep/ .point_name {
+        position: relative;
+        left: -30px;
+        top: -15px;
+        width: 100%;
+        min-width: 90px;
+        padding: 1px;
+        text-align: center;
+        background-color: rgb(26, 34, 41);
+        border: 1px solid #060D16;
+        border-radius: 10px !important;
+        color: #eeeeee;
+        display: block;
+        overflow: hidden;
+        opacity: 0.9;
+        font-size: 12px;
+    }
+
+
+    @keyframes bulge {
+        50% {
+            transform: scale(1);
+        }
+    }
+
+
+    @keyframes blow {
+        25% {
+            opacity: 0.4;
+        }
+        50% {
+            opacity: 0.1;
+        }
+        90% {
+            opacity: 0;
+        }
+        100% {
+            transform: scale(9);
+            opacity: 0;
+        }
+    }
+</style>

+ 581 - 0
app/src/components/mapPage.vue

@@ -0,0 +1,581 @@
+<!--
+  描述:拖放地图组件,默认尺寸是 500 * 300
+  接收属性参数:
+    lat: 纬度
+    lng: 经度
+  自定义事件:
+    drag: 拖放完成事件
+  示例:
+    <mapDrag @drag="dragMap" lat="22.574405" lng="114.095388"></mapDrag>
+-->
+<template>
+    <div class="m-map" :style="{ height: curheight + 'px' }">
+        <div id="js-containerPage" class="map">
+            <h5 style="text-align: center">{{$t("Loading data")}} ...</h5>
+        </div>
+        <mu-bottom-sheet :open.sync="detailState">
+            <div class="detailContianer">
+                <h5>
+                    <span class="name">{{row.RegionName}}</span>
+                </h5>
+                <ul>
+                    <li class="lt">{{$t("state")}}:<em
+                            :class="{'red':row.Detstatus != '正常','green':row.Detstatus == '正常'}">{{row.Detstatus}}</em>
+                    </li>
+                    <li class="lt">{{$t("Detection equipment")}}:{{row.DectorNum}} {{$t("pcs")}}</li>
+                    <li class="lt">{{$t("phone signal")}}:{{row.DecList}}</li>
+                    <li class="lt">{{$t("Camera")}}:{{row.CamNum}} {{$t("pcs")}}</li>
+                    <li class="lt">{{$t("Suspicious camera")}}:{{row.DancapNum}} {{$t("pcs")}}</li>
+                </ul>
+                <div class="btnContainer">
+                    <button class="goPlane" @click="goPlane">{{$t("Plane details")}}</button>
+                    <button class="goProfile" @click="goProfile">{{$t("Company details")}}</button>
+                </div>
+            </div>
+        </mu-bottom-sheet>
+    </div>
+</template>
+
+<script>
+    import remoteLoad from '../utils/remoteLoad.js'
+    import {MapKey, MapCityName} from '../tools/map'
+
+    let qs = require('qs');
+    import axios from 'axios';
+    import Global from '../../src/Global.js'
+
+    export default {
+        data() {
+            return {
+                searchKey: '',
+                placeSearch: null,
+                dragStatus: false,
+                AMapUI: null,
+                AMap: null,
+                ComId: 0,
+                detailState: false,
+                row: {
+                    RegionName: '',
+                    Detstatus: '',
+                    DectorNum: '',
+                    CamNum: '',
+                    DecList: '',
+                    DancapNum: '',
+                    Regionid: '',
+                },
+            }
+        },
+        props: {
+            curheight: {
+                default: 310,
+                type: Number
+            }
+        },
+        watch: {
+            searchKey() {
+                if (this.searchKey === '') {
+                    this.placeSearch.clear()
+                }
+            },
+        },
+        beforeDestroy() {
+            clearInterval(this.getPoint);
+        },
+        methods: {
+            goPlane() {
+                let that = this;
+                that.$router.push({path: '/plane', query: {Regionid: that.row.Regionid, ComId: that.ComId}});
+            },
+            goProfile() {
+                let that = this;
+                that.$router.push({path: '/profile', query: {Regionid: that.row.Regionid, ComId: that.ComId}});
+            },
+            // 实例化地图
+            initMap() {
+                let AMapUI = this.AMapUI = window.AMapUI;
+                let AMap = this.AMap = window.AMap;
+                let timeInterval = 5000;
+                let lang = localStorage.language == 'zh' ? 'zh' : 'en';
+                AMapUI.loadUI(['misc/PositionPicker'], PositionPicker => {
+                    let mapConfig = {
+                        resizeEnable: true, //是否监控地图容器尺寸变化
+                        // mapStyle: mapStyle,//地图颜色风格
+                        zoom: 16,
+                        cityName: MapCityName,
+                        lang: lang
+                    };
+                    let map = new AMap.Map('js-containerPage', mapConfig);
+                    // 获取点位置
+                    this.getPoint(map);
+
+                    setInterval(this.getPoint(map), 5000);
+                    // 获取围栏信息
+                    this.getFenceInfo(map);
+                    // 启用工具条
+                    AMap.plugin(['AMap.ToolBar'], function () {
+                        map.addControl(new AMap.ToolBar({
+                            position: 'RB'
+                        }))
+                    });
+                })
+            },
+
+            // 实例化点标记
+            addMarker(map, lng, lat, content, imgState, row) {
+                let that = this;
+                let marker = new AMap.Marker({
+                    position: [lng, lat],
+                    offset: new AMap.Pixel(-13, -30),
+                    content: imgState,
+                });
+                marker.setMap(map);
+
+                // 弹窗偏移度
+                let infoWindow = new AMap.InfoWindow({offset: new AMap.Pixel(14, -20)});
+                marker.on('click', function (e) {
+                    // 自定义的弹窗
+                        that.detailState = true;
+                        that.row.RegionName = row.RegionName;
+                        that.row.Detstatus = row.Detstatus == 1 ? that.$t('normal') : that.$t('abnormal');
+                        that.row.DecList = !row.DecList ? that.$t('Not found') : row.DecList;
+                        that.row.DectorNum = row.DectorNum;
+                        that.row.CamNum = row.CamNum;
+                        that.row.DancapNum = row.DancapNum;
+                        that.row.Regionid = row.Regionid;
+                        // 原生的弹窗
+                        // infoWindow.setContent(content);
+                        // infoWindow.open(map, e.target.getPosition());
+                });
+            },
+            // 获取所有的点位置
+            getPoint(map) {
+                const that = this;
+                let lnglats = [];
+                let url = '';
+                if (localStorage.userLevel == '单位管理员') {
+                    url = headapi + 'v1/Company/GetRegionMapinfo';//获取 单个企业获取
+                } else {
+                    url = headapi + 'v1/Company/GetMapinfo';//获取
+                }
+                let param = {
+                    token: localStorage.token
+                };
+                let postdata = qs.stringify(param);
+                axios.post(url, postdata).then(function (data) {
+                    let json = data.data;
+                    if (json.Rs) {
+                        map.setCenter([json.Rs[0].Lng, json.Rs[0].Lat]);
+                        // todo 使用数学中心计算显示点中心
+                        if (localStorage.lnglats != JSON.stringify(lnglats)) {
+                            that.wirtePoint(map, json);
+                        }
+                        localStorage.lnglats = JSON.stringify(json.Rs)
+                    }
+                    map.setFitView();
+                }, function (response) {
+                    console.info(response);
+                })
+            },
+            // 画点
+            wirtePoint(map, json) {
+                let that = this;
+                let markers = [];
+                let curPointName = '';
+                let lnglats = json.Rs;
+                map.remove(markers);
+                // 根据状态判断图标显示颜色
+                for (var i = 0; i < lnglats.length; i++) {
+                    let imgState = '';
+                    curPointName = !lnglats[i].RegionName ? lnglats[i].ComName : lnglats[i].RegionName;
+                    switch (parseInt(lnglats[i].Detstatus)) {
+                        // 0 safe 1 warning 2 danger
+                        case 0:
+                            imgState = '<i class="green_point"></i> <span class="point_name">' + curPointName + '</span>';
+                            break;
+                        case 1:
+                            imgState = '<i class="green_point"></i> <span class="point_name">' + curPointName + '</span>';
+                            break;
+                        case 2:
+                            imgState = '<i class="red_point"></i> <span class="point_name">' + curPointName + '</span>';
+                            break;
+                    }
+                    var position;
+                    position = [json.Rs[i].Lng, json.Rs[i].Lat];
+
+                    let content = '';
+                    if (localStorage.userLevel == '单位管理员') {
+                        let state = json.Rs[i].Detstatus == 1 ? this.$t("normal") : '<span style="color:#ff0000">this.$t("abnormal")</span>';
+                        let DecList = !json.Rs[i].DecList ? this.$t("Not found") : json.Rs[i].DecList;
+                        content =
+                            '<span class="map_a" href="profile.html?hotelid=' + localStorage.comId + '&Regionid=' + json.Rs[i].Regionid + '">' +
+                            +this.$t("region") + ':' + json.Rs[i].RegionName
+                            + '<br>' + this.$t("state") + ':' + state
+                            + '<br>' + this.$t("Detection equipment") + ':' + json.Rs[i].DectorNum
+                            + '<br>' + this.$t("phone signal") + ':' + DecList
+                            + '<br>' + json.Rs[i].Wifiname + ':' + json.Rs[i].CamNum
+                            + '<br>可疑' + json.Rs[i].Wifiname + ':' + json.Rs[i].DancapNum
+                            + '</span><em class="jumper" Regionid=' + json.Rs[i].Regionid + '>' +
+                            '<i class="icon iconProfile"  href="profile.html?hotelid=' + localStorage.comId + '&Regionid=' + json.Rs[i].Regionid + '"></i>' +
+                            '<i class="icon iconPlane" href="plane.html?hotelid=' + localStorage.comId + '&Regionid=' + json.Rs[i].Regionid + '"></i></em>';
+                    } else {
+                        let state = json.Rs[i][3] == 1 ? '正常' : '<span style="color:#ff0000">异常</span>';
+                        let macAddr = !json.Rs[i][7] ? '无' : json.Rs[i][7];
+                        content =
+                            '<span class="map_a" href="profile.html?hotelid=' + json.Rs[i][8] + '">' +
+                            '企业:' + json.Rs[i][5]
+                            + '<br>' + this.$t("state") + ':' + state
+                            + '<br>' + this.$t("Detection equipment") + ':' + json.Rs[i][4]
+                            + '<br>' + this.$t("phone signal") + ':' + json.Rs[i][2]
+                            + '<br>可疑' + json.Rs[i][9] + ':' + json.Rs[i][6]
+                            + '<br>可疑MAC地址:' + macAddr
+                            + '</span><em class="jumper" Regionid=' + json.Rs[i][9] + '>' +
+                            '<i class="icon iconProfile"  href="profile.html?hotelid=' + json.Rs[i][8] + '"></i>' +
+                            '<i class="icon iconPlane" href="plane.html?hotelid=' + json.Rs[i][8] + '"></i></em>';
+                    }
+                    that.addMarker(map, json.Rs[i].Lng, json.Rs[i].Lat, content, imgState, json.Rs[i]);
+                }
+            },
+            // 给总管理员的画点
+            wirtePointForAdmin(map, json) {
+                let that = this;
+                let markers = [];
+                map.remove(markers);
+                // 根据状态判断图标显示颜色
+                for (var i = 0; i < json.length; i++) {
+                    let imgState = '';
+                    switch (parseInt(json[i][3])) {
+                        case 1:
+                            imgState = '<i class="green_point"></i> <span class="point_name">' + json[i][5] + '</span>';
+                            break;
+                        case 2:
+                            imgState = '<i class="yellow_point"></i> <span class="point_name">' + json[i][5] + '</span>';
+                            break;
+                        case 0:
+                            imgState = '<i class="red_point"></i> <span class="point_name">' + json[i][5] + '</span>';
+                            break
+                    }
+                    var position = json[i];
+                    let content = '';
+                    let state = json[i][3] == 1 ? this.$t('normal') : '<span style="color:#ff0000">' + this.$t('abnormal') + '</span>';
+                    let macAddr = !json[i][7] ? this.$t('nothing') : json[i][7];
+                    content = '<span class="map_a" href="profile.html?hotelid=' + json[i][8] + '">' +
+                        '企业:' + json[i][5]
+                        + '<br>状态:' + state
+                        + '<br>探测设备:' + json[i][4]
+                        + '<br>' + json[i][9] + ':' + json[i][2]
+                        + '<br>可疑' + json[i][9] + ':' + json[i][6]
+                        + '<br>可疑MAC地址:' + macAddr
+                        + '</span><em class="jumper" Regionid=' + json[i][9] + '>' +
+                        '<i class="icon iconProfile"  href="profile.html?hotelid=' + json[i][8] + '"></i>' +
+                        '<i class="icon iconPlane" href="plane.html?hotelid=' + json[i][8] + '"></i></em>';
+                    that.addMarker(map, json[i][0], json[i][1], content, imgState,json[i]);
+                }
+            },
+            // 获取围栏信息
+            getFenceInfo(map) {
+                const that = this;
+                let url = headapi + 'v1/Company/GetComfencelist';
+                let param = {
+                    token: localStorage.token,
+                    comid: localStorage.comId
+                };
+                let postdata = qs.stringify(param);
+                axios.post(url, postdata).then(function (data) {
+                    let json = data.data;
+                    if (json.Code == 0) {
+                        that.ComId = json.Rs.ComId;
+                        let fence = json.Rs.Fence;
+                        let fenceArr = fence.split(",");
+                        let path = [];
+                        for (var i = 0; i < fenceArr.length; i++) {
+                            if (i % 2 == 0) {
+                                path.push([fenceArr[i], fenceArr[i + 1]]);
+                            }
+                        }
+                        let polygon = new AMap.Polygon({
+                            path: path,
+                            strokeColor: "#6496FF",
+                            strokeWeight: 6,
+                            strokeOpacity: 0.15,
+                            fillOpacity: 0.4,
+                            fillColor: '#6496FF',
+                            zIndex: 50,
+                        });
+
+                        map.add(polygon);
+
+                        // 缩放地图到合适的视野级别
+                        map.setFitView([polygon]);
+                    }
+                }, function (response) {
+                    console.info(response);
+                })
+            },
+            // 计算点中心
+            calcCenterBySingle(data) {
+                var total = data.length;
+                var lat = 0, lon = 0;
+                for (var i = 0; i < total; i++) {
+                    lat += data[i].Lat * Math.PI / 180;
+                    lon += data[i].Lng * Math.PI / 180;
+                }
+                lat /= total;
+                lon /= total;
+                return [lon * 180 / Math.PI, lat * 180 / Math.PI];
+            },
+            // 计算多点的数学圆心
+            calcCenter(data) {
+                var total = data.length;
+                var lat = 0, lon = 0;
+                for (var i = 0; i < total; i++) {
+                    lat += data[i][0] * Math.PI / 180;
+                    lon += data[i][1] * Math.PI / 180;
+                }
+                lat /= total;
+                lon /= total;
+                return [lat * 180 / Math.PI, lon * 180 / Math.PI];
+            }
+        },
+        async created() {
+            // 已载入高德地图API,则直接初始化地图
+            if (window.AMap && window.AMapUI) {
+                this.initMap()
+                // 未载入高德地图API,则先载入API再初始化
+            } else {
+                await remoteLoad(`http://webapi.amap.com/maps?v=1.3&key=${MapKey}`);
+                await remoteLoad('http://webapi.amap.com/ui/1.0/main.js');
+                this.initMap()
+            }
+        }
+    }
+</script>
+
+<style scoped>
+    .m-map {
+        width: 100%;
+        /*max-height: 317px;*/
+        /*height: 317px;*/
+        position: relative;
+    }
+
+    .m-map .map {
+        width: 100%;
+        height: 100%;
+    }
+
+    .m-map .search {
+        position: absolute;
+        top: 10px;
+        left: 10px;
+        width: 285px;
+        z-index: 1;
+    }
+
+    .m-map .search input {
+        width: 180px;
+        border: 1px solid #ccc;
+        line-height: 20px;
+        padding: 5px;
+        outline: none;
+    }
+
+    .m-map .search button {
+        line-height: 26px;
+        background: #fff;
+        border: 1px solid #ccc;
+        width: 50px;
+        text-align: center;
+    }
+
+    .m-map .result {
+        max-height: 300px;
+        overflow: auto;
+        margin-top: 10px;
+    }
+
+    /deep/ .green_point {
+        margin: 16px;
+        height: 16px;
+        width: 16px;
+        border-radius: 50% !important;
+        display: inline-block;
+        background-color: #1eff30;
+    }
+
+    /deep/ .yellow_point {
+        margin: 16px;
+        height: 16px;
+        width: 16px;
+        border-radius: 50% !important;
+        display: inline-block;
+        background-color: #f2ff24;
+    }
+
+    /deep/ .red_point {
+        margin: 16px;
+        height: 16px;
+        width: 16px;
+        border-radius: 50% !important;
+        display: inline-block;
+        transform: scale(0.5);
+        animation: bulge 2s infinite ease-in-out;
+        background-color: #ff0000;
+        animation-delay: 0s;
+    }
+
+    /deep/ .red_point::after {
+        position: absolute;
+        display: inline-block;
+        content: '';
+        height: 100%;
+        width: 100%;
+        border-radius: 50%;
+        background-color: inherit;
+        top: 0;
+        left: 0;
+        z-index: -1;
+        transform: scale(1);
+        animation: blow 2s infinite ease-in-out;
+    }
+
+    /deep/ .point_name {
+        position: relative;
+        left: -30px;
+        top: -15px;
+        width: 100%;
+        min-width: 90px;
+        padding: 1px;
+        text-align: center;
+        background-color: rgb(26, 34, 41);
+        border: 1px solid #060D16;
+        border-radius: 10px !important;
+        color: #eeeeee;
+        display: block;
+        overflow: hidden;
+        opacity: 0.9;
+        font-size: 12px;
+    }
+
+    .red {
+        color: red;
+    }
+
+    .green {
+        color: greenyellow;
+    }
+
+    @keyframes bulge {
+        50% {
+            transform: scale(1);
+        }
+    }
+
+
+    @keyframes blow {
+        25% {
+            opacity: 0.4;
+        }
+        50% {
+            opacity: 0.1;
+        }
+        90% {
+            opacity: 0;
+        }
+        100% {
+            transform: scale(9);
+            opacity: 0;
+        }
+    }
+
+    .detailContianer {
+        position: absolute;
+        bottom: 85px;
+        left: 0;
+        right: 0;
+        width: 96%;
+        height: 257px;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        background: #fff;
+        box-shadow: #333333 0 0 7px;
+        z-index: 9999;
+        border-radius: 8px;
+        padding: 18px 10px;
+    }
+
+    .detailContianer h5 {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        font-size: 16px;
+    }
+
+    .detailContianer h5 .name {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        text-align: center;
+    }
+
+    .detailContianer h5 .state {
+        float: right;
+    }
+
+    .detailContianer ul {
+        width: 88%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        margin-top: 15px;
+        margin-bottom: 10px;
+        border-top: 1px solid #EBEBEB;
+        border-bottom: 1px solid #EBEBEB;
+        padding-top: 10px;
+        padding-bottom: 10px;
+    }
+
+    .detailContianer li {
+        width: 100%;
+        float: left;
+        margin-bottom: 3px;
+    }
+
+    .detailContianer .rt {
+        text-align: right;
+    }
+
+    .detailContianer .btnContainer {
+        width: 88%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+    }
+
+    .btnContainer button {
+        width: 120px;
+        height: 32px;
+        line-height: 32px;
+        text-align: center;
+        border-radius: 250px;
+        outline: none;
+        border: none;
+    }
+
+    .btnContainer .goPlane {
+        border: 1px solid #FFCC00;
+        background: #fff;
+    }
+
+    .btnContainer .goProfile {
+        border: 1px solid #FFCC00;
+        background: #FFCC00;
+        float: right;
+    }
+
+    /deep/ .amap-zoomcontrol {
+        bottom: 10px !important;
+    }
+</style>

+ 218 - 0
app/src/components/statischart.vue

@@ -0,0 +1,218 @@
+<template>
+    <div id="statischart">
+        <div class="time">
+    <span @click="changeTime(1)">
+    {{bt}}
+    </span>
+            <span @click="changeTime(2)">
+    {{et}}
+    </span>
+            <mu-select label="" v-model="selectVal">
+                <mu-option v-for="option in options" :key="option.optionsVal" :label="option.name"
+                           :value="option.optionsVal"></mu-option>
+            </mu-select>
+            <mu-button color="warning" @click="getNewChart" small>{{$t('search')}}</mu-button>
+        </div>
+
+        <Line-example
+                :width="390"
+                :height="200"
+                :dataLabels="dataLabels"
+                :datadatasets="datadatasets"
+        />
+
+        <mu-bottom-sheet :open.sync="open">
+            <mu-flex justify-content="between" align-items="end" wrap="wrap">
+                <mu-paper :z-depth="1" class="demo-date-picker">
+                    <mu-date-picker :date.sync="date" color="#FFA200" :date-time-format="enDateFormat"
+                                    @change="confirmDay"></mu-date-picker>
+                </mu-paper>
+            </mu-flex>
+        </mu-bottom-sheet>
+    </div>
+</template>
+<script>
+    import Global from '../Global'
+    import Vue from 'vue'
+    import LineExample from './LineExample'
+
+    let qs = require('qs');
+    import axios from 'axios';
+
+    const enDateFormat = {
+        formatDisplay(date) {
+            return `${dayList[date.getDay()]}, ${monthList[date.getMonth()]} ${date.getDate()}`;
+        },
+        formatMonth(date) {
+            return `${monthLongList[date.getMonth()]} ${date.getFullYear()}`;
+        },
+        getWeekDayArray(firstDayOfWeek) {
+            let beforeArray = [];
+            let afterArray = [];
+            for (let i = 0; i < dayAbbreviation.length; i++) {
+                if (i < firstDayOfWeek) {
+                    afterArray.push(dayAbbreviation[i]);
+                } else {
+                    beforeArray.push(dayAbbreviation[i]);
+                }
+            }
+            return beforeArray.concat(afterArray);
+        },
+        getMonthList() {
+            return monthList;
+        }
+    };
+    export default {
+        data() {
+            return {
+                enDateFormat,
+                bt: globaltime2StringNoMin(new Date() - 3 * 24 * 3600 * 1000),//test
+                et: globaltime2StringNoMin(new Date()),
+                date: new Date(),
+                pickerValue: '',
+                open: false,
+                selectTime: 0,
+                selectVal: 1,
+                pickerItem: 0,
+                dataLabels: [],
+                datadatasets: [],
+                options: [
+                    {name: this.$t('Total detection record'), optionsVal: 1},
+                ]
+            }
+        },
+        mounted() {
+            this.getNewChart()
+        },
+        methods: {
+            changeTime(val) {
+                this.open = true;
+                let curVal = val == 1 ? new Date(this.bt) : new Date(this.et);
+                this.selectTime = val;
+                this.date = curVal;
+            },
+            confirmDay(date) {
+                if (this.selectTime == 1) {
+                    this.bt = globaltime2StringNoMin(date);
+                } else {
+                    this.et = globaltime2StringNoMin(date);
+                }
+                this.open = false;
+            },
+            getNewChart() {
+                const that = this;
+                let url = headapi + 'v1/Detector/GetCtNumStatisticByday';
+                let param = {
+                    token: localStorage.token,
+                    bt: that.bt + ' 00:00:00',
+                    et: that.et + ' 23:59:59',
+                    dailytype: that.selectVal,
+                };
+                let postdata = qs.stringify(param);
+                axios.post(url, postdata).then(function (data) {
+                    let json = data.data;
+                    if (json.Code == 0) {
+                        let detectorArr = json.Rs;
+                        that.dataLabels = detectorArr.RsX;
+                        that.datadatasets = detectorArr.RsY;
+                    } else {
+                        if (!localStorage.token) { //未登录状态
+                            console.log(json.Memo);
+                        } else { //已登录状态
+                            that.Toast(that.TransMemo(json.Memo));
+                        }
+                    }
+                }, function (response) {
+                    console.info(response);
+                });
+            },
+        },
+        components: {
+            LineExample
+        },
+    }
+</script>
+
+<style scoped>
+    .container {
+        width: 100%;
+        height: 230px;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+    }
+
+    #statischart {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        margin-bottom: 10px;
+    }
+
+    .time {
+        width: 100%;
+        height: 48px;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        padding-left: 2%;
+        padding-right: 2%;
+        padding-top: 15px;
+        margin-bottom: 15px;
+        border-bottom: 1px solid #f2f2f2;
+    }
+
+    .time span {
+        width: 80px;
+        height: 27px;
+        float: left;
+        border: 1px solid #DEDEDE;
+        text-align: center;
+        line-height: 27px;
+        font-size: 12px;
+        margin-right: 10px;
+    }
+
+    .time select {
+        width: 96px;
+        height: 27px;
+        float: left;
+        border: 1px solid #DEDEDE;
+        text-align: center;
+        line-height: 27px;
+        font-size: 12px;
+        margin-right: 10px;
+    }
+
+    .time .mint-button {
+        height: 27px;
+        border-radius: 0;
+    }
+
+    .mu-input {
+        width: 100px;
+        float: left;
+        padding: 0;
+        margin: 0;
+    }
+
+    /deep/ .mu-select-input {
+        font-size: 12px !important;
+    }
+
+    .mu-button {
+        float: left;
+        min-width: 66px;
+    }
+
+    .demo-date-picker {
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+    }
+
+    /deep/ .mu-button-wrapper {
+        color: #000 !important;
+    }
+</style>

+ 152 - 0
app/src/components/statischart2.vue

@@ -0,0 +1,152 @@
+<template>
+    <div class="container">
+        <div class="Chart">
+            <div class="time">
+                <span @click="changeTime(1)">
+                    {{bt}}
+                </span>
+                <span @click="changeTime(2)">
+                    {{et}}
+                </span>
+                <select name="" id="" v-model="selectVal">
+                    <option value="1">总探测记录</option>
+                </select>
+                <mt-button size="small" type="primary" @click="getNewChart">查询</mt-button>
+            </div>
+            <Line-example
+                    :width="414"
+                    :height="200"
+                    :dataLabels="dataLabels"
+                    :datadatasets="datadatasets"
+            />
+        </div>
+        <mt-datetime-picker
+                ref="picker"
+                type="date"
+                v-model="pickerValue"
+                @confirm="handleConfirm"
+        >
+        </mt-datetime-picker>
+    </div>
+</template>
+
+<script>
+    import {DatetimePicker} from 'mint-ui';
+    import {Toast} from 'mint-ui';
+    import LineExample from './LineExample'
+    import Global from '../Global'
+    import Vue from 'vue'
+
+    let qs = require('qs');
+    import axios from 'axios';
+
+    Vue.component(DatetimePicker.name, DatetimePicker);
+    export default {
+        data() {
+            return {
+                bt: globaltime2StringNoMin(new Date() - 3 * 24 * 3600 * 1000),
+                et: globaltime2StringNoMin(new Date()),
+                pickerValue: '',
+                selectVal: 1,
+                pickerItem: 0,
+                dataLabels: [],
+                datadatasets: [],
+            }
+        },
+        mounted() {
+            this.getNewChart();
+        },
+        methods: {
+            changeTime(val) {
+                this.$refs.picker.open();
+                this.pickerValue = val == 1 ? this.bt : this.et;
+                this.pickerItem = val;
+            },
+            handleConfirm(e) {
+                let that = this;
+                console.log(this.pickerItem);
+                if (this.pickerItem == 1) {
+                    that.bt = globaltime2String(e)
+                } else {
+                    that.et = globaltime2String(e)
+                }
+                this.$refs.picker.close();
+            },
+            // 查询
+            getNewChart() {
+                const that = this;
+                let url = headapi + 'v1/Detector/GetCtNumStatisticByday';
+                let param = {
+                    token: localStorage.token,
+                    bt: that.bt + ' 00:00:00',
+                    et: that.et + ' 23:59:59',
+                    dailytype: that.selectVal,
+                };
+                let postdata = qs.stringify(param);
+                axios.post(url, postdata).then(function (data) {
+                    let json = data.data;
+                    if (json.Code == 0) {
+                        let detectorArr = json.Rs;
+                        that.dataLabels = detectorArr.RsX;
+                        that.datadatasets = detectorArr.RsY;
+                    } else {
+                        // Toast(json.memo);
+                        console.log(json.Memo);
+                    }
+                }, function (response) {
+                    console.info(response);
+                });
+            }
+        },
+        components: {
+            LineExample
+        },
+    }
+</script>
+
+<style>
+    .container {
+        width: 100%;
+        height: 230px;
+        margin: 0 auto;
+    }
+
+    .time {
+        width: 96%;
+        height: 48px;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        padding-left: 2%;
+        padding-right: 2%;
+        padding-top: 15px;
+        border-bottom: 1px solid #f2f2f2;
+    }
+
+    .time span {
+        width: 96px;
+        height: 27px;
+        float: left;
+        border: 1px solid #DEDEDE;
+        text-align: center;
+        line-height: 27px;
+        font-size: 12px;
+        margin-right: 10px;
+    }
+
+    .time select {
+        width: 96px;
+        height: 27px;
+        float: left;
+        border: 1px solid #DEDEDE;
+        text-align: center;
+        line-height: 27px;
+        font-size: 12px;
+        margin-right: 10px;
+    }
+
+    .time .mint-button {
+        height: 27px;
+        border-radius: 0;
+    }
+</style>

+ 134 - 0
app/src/language/en-US.js

@@ -0,0 +1,134 @@
+export default {
+    "whiteList": "whiteList",
+    "search": "search",
+    "index": "index",
+    "keyword": "keyword",
+    "order": "order",
+    "detect tag": "detect tag",
+    "detect local": "detect local",
+    "be detect MAC": "be detect MAC",
+    "sign time": "sign time",
+    "operator": "operator",
+    "memo": "memo",
+    "control": "control",
+    "close": "close",
+    "remove white": "remove white",
+    "no use data": "no use data",
+    "Wireless device detection system management": "Wireless device detection system management",
+    "Management system for wireless camera detection and equipment detection": "Management system for wireless camera detection and equipment detection",
+    "login": "login",
+    "User name or email address": "User name or email address",
+    "Password": "Password",
+    "Verification Code": "Verification Code",
+    "Invisibility? Give it a try!": "Invisibility? Give it a try!",
+    "cancel": "cancel",
+    "usercode": "usercode",
+    "can not be empty": "can not be empty",
+    "least": "least",
+    "character": "character!",
+    "Limit exceeded": "Limit exceeded",
+    "The verification code has timed out. Please re-enter": "The verification code has timed out. Please re-enter",
+    "System home page": "System home page",
+    "home": "home",
+    "Real-time monitoring": "Real-time monitoring",
+    "Real-time": "Real-time",
+    "Detection record": "Detection record",
+    "Detection": "Detection",
+    "Record": "Record",
+    "item": "item",
+    "Suspicious device": "Suspicious device",
+    "Detection equipment": "Detection equipment",
+    "Supervision quantity": "Supervision quantity",
+    "Statistical report forms": "Statistical report forms",
+    "Dangerous equipment found": "Dangerous equipment found",
+    "brand": "brand",
+    "User list": "User list",
+    "Enterprise list": "Enterprise list",
+    "System setup": "System setup",
+    "Map display": "Map display",
+    "Map": "Map",
+    "Loading data": "Loading data",
+    "region": "region",
+    "state": "state",
+    "pcs": "pcs",
+    "phone signal": "phone signal",
+    "Camera": "Camera",
+    "Suspicious camera": "Suspicious camera",
+    "Plane details": "Plane details",
+    "Company details": "Company details",
+    "normal": "normal",
+    "abnormal": "abnormal",
+    "Not found": "Not found",
+    "enterprise": "enterprise",
+    "Suspicious": "Suspicious",
+    "Prohibit": "Prohibit",
+    "fault": "fault",
+    "Off-line": "Off-line",
+    "Depot repair": "Depot repair",
+    "delete": "delete",
+    "other": "other",
+    "total": "total",
+    "Back to previous page": "Back to previous page",
+    "detail": "detail",
+    "Affiliated Enterprises": "Affiliated Enterprises",
+    "Tag name": "Tag name",
+    "local": "local",
+    "wireless device": "wireless device",
+    "No mobile signal detected": "No mobile signal detected",
+    "disabled": "disabled",
+    "Enabled": "Enabled",
+    "nothing": "nothing",
+    "user management": "user management",
+    "User details": "User details",
+    "User roles": "User roles",
+    "Business management": "Business management",
+    "query criteria": "query criteria",
+    "Keyword query": "Keyword query",
+    "Reset": "Reset",
+    "query": "query",
+    "hotel": "hotel",
+    "tavern": "tavern",
+    "Prison": "Prison",
+    "Enterprise name": "Enterprise name",
+    "Enterprise types": "Enterprise types",
+    "Enterprise address": "Enterprise address",
+    "Subordinate supervision": "Subordinate supervision",
+    "Contacts": "Contacts",
+    "Total detection record": "Total detection record",
+    "to": "to",
+    "Please go to the webpage for more records": "Please go to the webpage for more records",
+    "Query already": "Query already",
+    "Please select a device first": "Please select a device first",
+    "No records found": "No records found",
+    "Alarm sound": "Alarm sound",
+    "Alarm flicker": "Alarm flicker",
+    "Quit landing": "Quit landing",
+    "Confirm to exit the current account": "Confirm to exit the current account",
+    "confirm": "confirm",
+    // error code
+    "Record does not exist": "Record does not exist",
+    "Successful implementation": "Successful implementation",
+    "The server is busy. Please try again later": "The server is busy. Please try again later",
+    "Service is temporarily unavailable": "Service is temporarily unavailable",
+    "Key does not exist": "Key does not exist",
+    "Wrong user name or password": "Wrong user name or password",
+    "Graphic verification code error": "Graphic verification code error",
+    "Password format error": "Password format error",
+    "Password error": "Password error",
+    "User already exists": "User already exists",
+    "Transmission frequency too high": "Transmission frequency too high",
+    "User is disabled": "User is disabled",
+    "Abnormal user status": "Abnormal user status",
+    "user does not exist": "user does not exist",
+    "Verification code error": "Verification code error",
+    "Logon failure": "Logon failure",
+    "MAC already exists": "MAC already exists",
+    "Is not a complete comma separated list format": "Is not a complete comma separated list format",
+    "HBase error": "HBase error",
+    "Please upload the picture again": "Please upload the picture again",
+    "not found": "not found",
+    "danger": "danger",
+    "warning": "warning",
+    "deal": "deal",
+    "white": "deal",
+};

+ 135 - 0
app/src/language/ru-RU.js

@@ -0,0 +1,135 @@
+export default {
+    "whiteList": "белый список",
+    "search": "запрос",
+    "index": "Первая страница",
+    "keyword": "ключевые слова",
+    "order": "порядковый номер",
+    "detect tag": "метка детектора",
+    "detect local": "место обнаружения",
+    "be detect MAC": "измерительное устройство MAC",
+    "sign time": "время отметки",
+    "operator": "оператор",
+    "memo": "Примечание",
+    "control": "операция",
+    "close": "Выключить",
+    "remove white": "Выключить белый список",
+    "no use data": "неиспользуемые данные",
+    "Wireless device detection system management": "управление системой обнаружения",
+    "Management system for wireless camera detection and equipment detection": "система управления обнаружением радиокамер, обнаружением фотоаппарата и т.д.",
+    "login": "входить",
+    "User name or email address": "Имя пользователя или почтовый адрес",
+    "Password": "пароль",
+    "Verification Code": "код проверки",
+    "Invisibility? Give it a try!": "не видишь?примерить кистью!",
+    "cancel": "отмена",
+    "usercode": "Имя пользователя",
+    "can not be empty": "не может быть пустым!",
+    "least": "минимум",
+    "character": "знак!",
+    "Limit exceeded": "превышать лимит",
+    "The verification code has timed out. Please re-enter": "код проверки истек, повторите ввод",
+    "System home page": "системная страница",
+    "home": "страница",
+    "Real-time monitoring": "контроль реального времени",
+    "Real-time": "истинное",
+    "Detection record": "запись обнаружения",
+    "Detection": "энергопитающая",
+    "Record": "запись",
+    "item": "полоса",
+    "Suspicious device": "подозрительное оборудование",
+    "Detection equipment": "энергопитающая",
+    "Supervision quantity": "контрольный количество",
+    "Statistical report forms": "статистический отчет",
+    "Dangerous equipment found": "обнаружение опасного оборудования",
+    "brand": "бренд",
+    "User list": "Список пользователей",
+    "Enterprise list": "Список предприятий",
+    "System setup": "Настройки системы",
+    "Map display": "карта",
+    "Map": "карта",
+    "Loading data": "Загрузка данных",
+    "region": "область",
+    "state": "состояние",
+    "pcs": "стол",
+    "phone signal": "сотовый сигнал",
+    "phone": "мобильный",
+    "Camera": "камера",
+    "Suspicious camera": "подозрительная камера",
+    "Plane details": "плоская деталь",
+    "Company details": "сведения о предприятии",
+    "normal": "нормальный",
+    "abnormal": "аномалия",
+    "Not found": "Не найдено",
+    "enterprise": "предприятие",
+    "Suspicious": "сомнительный",
+    "Prohibit": "Отключить",
+    "fault": "неисправность",
+    "Off-line": "оффлайн",
+    "Depot repair": "ремонт на заводе",
+    "delete": "Удалить",
+    "other": "Прочее",
+    "total": "весь",
+    "Back to previous page": "вернуться на предыдущую страницу",
+    "detail": "подробности",
+    "Affiliated Enterprises": "подведомственное предприятие",
+    "Tag name": "название метки",
+    "local": "место",
+    "wireless device": "радиооборудование",
+    "No mobile signal detected": "сигнал телефона не обнаружен",
+    "disabled": "Отключено",
+    "Enabled": "Включено",
+    "nothing": "Нет",
+    "user management": "Управление пользователями",
+    "User details": "сведения о пользователе",
+    "User roles": "роль пользователя",
+    "Business management": "управление предприятием",
+    "query criteria": "условия запроса",
+    "Keyword query": "запрос ключевого слова",
+    "Reset": "сбросить",
+    "query": "запрос",
+    "hotel": "гостиница",
+    "tavern": "кабак",
+    "Prison": "тюрьма",
+    "Enterprise name": "название компании",
+    "Enterprise types": "тип предприятия",
+    "Enterprise address": "адрес предприятия",
+    "Subordinate supervision": "подведомственный контроль",
+    "Contacts": "контакт",
+    "Total detection record": "запись общего обнаружения",
+    "to": "to",
+    "Please go to the webpage for more records": "Пожалуйста, Просматривайте страницу",
+    "Query already": "опрос",
+    "Please select a device first": "Выберите устройство",
+    "No records found": "Нет запроса на запись",
+    "Alarm sound": "сигнал тревоги",
+    "Alarm flicker": "мигание тревоги",
+    "Quit landing": "выход из десанта",
+    "Confirm to exit the current account": "установить выход из текущего счета",
+    "confirm": "определение",
+    // error code
+    "Record does not exist": "запись не существует",
+    "Successful implementation": "успешная реализация",
+    "The server is busy. Please try again later": "Сервер загружен, попробуйте позже",
+    "Service is temporarily unavailable": "обслуживание временно недоступно",
+    "Key does not exist.": "Key не существует",
+    "Wrong user name or password": "ошибка по имени или паролю",
+    "Graphic verification code error": "ошибка графического кода",
+    "Password format error": "ошибка формата пароля",
+    "Password error": "ошибка пароля",
+    "User already exists": "пользователь уже существует",
+    "Transmission frequency too high": "частота пересылки",
+    "User is disabled": "пользователь отключен",
+    "Abnormal user status": "аномалия состояния пользователя",
+    "user does not exist": "пользователь не существует",
+    "Verification code error": "Ошибка проверки кода",
+    "Logon failure": "Ошибка регистрации",
+    "MAC already exists": "MAC уже существует",
+    "Is not a complete comma separated list format": "не весь формат разделённых запятыми списков",
+    "HBase error": "ошибка HBase",
+    "Please upload the picture again": "Перезагрузите изображение",
+    "not found": "не найдено",
+    "danger": "Опасности",
+    "warning": "Предупреждение",
+    "deal": "Сделки",
+    "white": "Белый",
+};

+ 135 - 0
app/src/language/zh-CN.js

@@ -0,0 +1,135 @@
+export default {
+    "whiteList": "白名单",
+    "search": "搜索",
+    "index": "首页",
+    "keyword": "关键词",
+    "order": "序号",
+    "detect tag": "探测器标签",
+    "detect local": "探测位置",
+    "be detect MAC": "被测设备MAC",
+    "sign time": "标注时间",
+    "operator": "操作员",
+    "memo": "备注",
+    "control": "操作",
+    "close": "关闭",
+    "remove white": "移出白名单",
+    "no use data": "暂没有符合条件的数据",
+    "Wireless device detection system management": "无线设备探测系统管理",
+    "Management system for wireless camera detection and equipment detection": "无线摄像头探测、偷拍设备探测等管理系统",
+    "login": "登录",
+    "User name or email address": "用户名或邮件地址",
+    "Password": "密码",
+    "Verification Code": "验证码",
+    "Invisibility? Give it a try!": "看不清?刷一下试试!",
+    "cancel": "取消",
+    "usercode": "用户名",
+    "can not be empty": "不能为空!",
+    "least": "最少",
+    "character": "字符!",
+    "Limit exceeded": "超出限制数量",
+    "The verification code has timed out. Please re-enter": "验证码已超时,请重新输入",
+    "System home page": "系统首页",
+    "home": "系统首页",
+    "Real-time monitoring": "实时监控",
+    "Real-time": "实时监控",
+    "Detection record": "探测记录",
+    "Detection": "探测设备",
+    "Record": "记录",
+    "item": "条",
+    "Suspicious device": "可疑设备",
+    "Detection equipment": "探测设备",
+    "Supervision quantity": "监管数量",
+    "Statistical report forms": "统计报表",
+    "Dangerous equipment found": "发现危险设备",
+    "brand": "品牌",
+    "User list": "用户列表",
+    "Enterprise list": "企业列表",
+    "System setup": "系统设置",
+    "Map display": "地图展示",
+    "Map": "地图展示",
+    "Loading data": "正在加载数据",
+    "region": "区域",
+    "state": "状态",
+    "pcs": "台",
+    "phone signal": "手机信号",
+    "phone": "手机",
+    "Camera": "摄像头",
+    "Suspicious camera": "可疑摄像头",
+    "Plane details": "平面详情",
+    "Company details": "企业详情",
+    "normal": "正常",
+    "abnormal": "异常",
+    "Not found": "没有发现",
+    "enterprise": "企业",
+    "Suspicious": "可疑",
+    "Prohibit": "禁用",
+    "fault": "故障",
+    "Off-line": "离线",
+    "Depot repair": "返厂维修",
+    "delete": "删除",
+    "other": "其他",
+    "total": "共",
+    "Back to previous page": "返回上一页",
+    "detail": "详情",
+    "Affiliated Enterprises": "所属企业",
+    "Tag name": "标签名",
+    "local": "位置",
+    "wireless device": "无线设备",
+    "No mobile signal detected": "未检测到手机信号",
+    "disabled": "已禁用",
+    "Enabled": "已启用",
+    "nothing": "无",
+    "user management": "用户管理",
+    "User details": "用户详情",
+    "User roles": "用户角色",
+    "Business management": "企业管理",
+    "query criteria": "查询条件",
+    "Keyword query": "关键字查询",
+    "Reset": "重 置",
+    "query": "查 询",
+    "hotel": "宾馆",
+    "tavern": "酒店",
+    "Prison": "监狱",
+    "Enterprise name": "企业名称",
+    "Enterprise types": "企业类型",
+    "Enterprise address": "企业地址",
+    "Subordinate supervision": "所属监管",
+    "Contacts": "联 系 人",
+    "Total detection record": "总探测记录",
+    "to": "至",
+    "Please go to the webpage for more records": "更多记录请前往网页端查看",
+    "Query already": "已查询",
+    "Please select a device first": "请先选择一个设备",
+    "No records found": "没有查询到记录",
+    "Alarm sound": "报警声音",
+    "Alarm flicker": "报警闪烁",
+    "Quit landing": "退出登陆",
+    "Confirm to exit the current account": "确定退出当前账户",
+    "confirm": "确定",
+    // error code
+    "Record does not exist": "记录不存在",
+    "Successful implementation": "执行成功",
+    "The server is busy. Please try again later": "服务器繁忙,请稍后再试",
+    "Service is temporarily unavailable": "服务暂不可用",
+    "Key does not exist.": "key不存在",
+    "Wrong user name or password": "用户名或密码错误",
+    "Graphic verification code error": "图形验证码错误",
+    "Password format error": "密码格式错误",
+    "Password error": "密码错误",
+    "User already exists": "用户已存在",
+    "Transmission frequency too high": "发送频率过高",
+    "User is disabled": "用户被禁用",
+    "Abnormal user status": "用户状态异常",
+    "user does not exist": "用户不存在",
+    "Verification code error": "验证码错误",
+    "Logon failure": "登录失效",
+    "MAC already exists": "MAC已存在",
+    "Is not a complete comma separated list format": "不是完整的逗号分隔列表格式",
+    "HBase error": "HBase错误",
+    "Please upload the picture again": "请重新上传图片",
+    "not found": "没有发现",
+    "danger": "高危",
+    "warning": "低危",
+    "deal": "已处理",
+    "white": "白名单",
+};

+ 133 - 25
app/src/main.js

@@ -1,37 +1,145 @@
-// The Vue build version to load with the `import` command
-// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
 import Vue from 'vue'
-import App from './App'
+import App from './App.vue'
 import router from './router'
 import axios from 'axios'
-import Mint from 'mint-ui';
-import 'mint-ui/lib/style.css'
-import { Toast } from 'mint-ui';
-// import VConsole from 'vconsole/dist/vconsole.min.js' //import vconsole
-// let vConsole = new VConsole();//初始化;
-// export  default vConsole
-// import Mui from 'vue-awesome-mui';
+import MuseUI from 'muse-ui';
+import 'muse-ui/dist/muse-ui.css';
+// 全局插件
+import Toast from 'muse-ui-toast';
+import Loading from 'muse-ui-loading';
 
-// Vue.use(Mui);
-Vue.use(Mint);
+
+
+
+Vue.use(MuseUI);
+Vue.locale = () => {
+};
+
+let ToastConfig = {
+    position: 'bottom',               // 弹出的位置
+    time: 2000,                       // 显示的时长
+    closeIcon: 'close',               // 关闭的图标
+    close: true,                      // 是否显示关闭按钮
+    successIcon: 'check_circle',      // 成功信息图标
+    infoIcon: 'info',                 // 信息信息图标
+    warningIcon: 'priority_high',     // 提醒信息图标
+    errorIcon: 'warning'
+};
+
+Vue.use(Toast, ToastConfig);
+
+Vue.use(Loading);
+
+// 演示版本数据
+require('./Mock/index.js');
 
 Vue.config.productionTip = false;
 
-/* eslint-disable no-new */
 new Vue({
-  el: '#app',
-  router,
-  components: { App },
-  template: '<App/>'
-});
+    render: h => h(App),
+    router,
+}).$mount('#app');
 
-Vue.prototype.thisUrl = process.env.NODE_ENV === 'development' ? '/api' : '';
+Vue.prototype.axios = axios;
 
-if(process.env.NODE_ENV === 'development'){
-    // 引入mockjs
-    require('./mock.js');
-}else{
 
-}
+//Toast
+Vue.prototype.Toast = function (e, color) {
+    let ToastColor = !color ? 'warning' : color;
+    let that = this;
+    switch (ToastColor) {
+        case 'message':
+            that.$toast.message(e);
+            break;
+        case 'success':
+            that.$toast.success(e);
+            break;
+        case 'info':
+            that.$toast.info(e);
+            break;
+        case 'warning':
+            that.$toast.warning(e);
+            break;
+        case 'error':
+            that.$toast.error(e);
+            break;
+    }
+};
 
-Vue.prototype.axios = axios;
+// loading
+Vue.prototype.Loading = function (target) {
+    let loading = this.$loading({
+        overlayColor: 'hsla(0,0%,100%,.9)',        // 背景色
+        size: 48,
+        color: 'warning',                           // color
+    });
+    setTimeout(() => {
+        loading.close();
+    }, 3000)
+};
+
+Vue.prototype.TransMemo = function (text) {
+    let that = this;
+    switch (text) {
+        case '记录不存在':
+            that.$toast.error(that.$t('Record does not exist'));
+            break;
+        case '服务器繁忙,请稍后再试':
+            that.$toast.error(that.$t('The server is busy. Please try again later'));
+            break;
+        case '服务暂不可用':
+            that.$toast.error(that.$t('Service is temporarily unavailable'));
+            break;
+        case 'key不存在':
+            that.$toast.error(that.$t('Key does not exist'));
+            break;
+        case '用户名或密码错误':
+            that.$toast.error(that.$t('Wrong user name or password'));
+            break;
+        case '图形验证码错误':
+            that.$toast.error(that.$t('Graphic verification code error'));
+            break;
+        case '密码格式错误':
+            that.$toast.error(that.$t('Password format error'));
+            break;
+        case '密码错误':
+            that.$toast.error(that.$t('Password error'));
+            break;
+        case '用户已存在':
+            that.$toast.error(that.$t('User already exists'));
+            break;
+        case '发送频率过高':
+            that.$toast.error(that.$t('Transmission frequency too high'));
+            break;
+        case '用户被禁用':
+            that.$toast.error(that.$t('User is disabled'));
+            break;
+        case '用户状态异常':
+            that.$toast.error(that.$t('Abnormal user status'));
+            break;
+        case '用户不存在':
+            that.$toast.error(that.$t('user does not exist'));
+            break;
+        case '验证码错误':
+            that.$toast.error(that.$t('Verification code error'));
+            break;
+        case '登录失效':
+            that.$toast.error(that.$t('Logon failure'));
+            break;
+        case 'MAC已存在':
+            that.$toast.error(that.$t('MAC already exists'));
+            break;
+        case '不是完整的逗号分隔列表格式':
+            that.$toast.error(that.$t('Is not a complete comma separated list format'));
+            break;
+        case 'HBase错误':
+            that.$toast.error(that.$t('HBase error'));
+            break;
+        case '请重新上传图片':
+            that.$toast.error(that.$t('Please upload the picture again'));
+            break;
+        default:
+            that.$toast.error(text);
+            break
+    }
+};

+ 44 - 0
app/src/page/404.vue

@@ -0,0 +1,44 @@
+<template>
+    <div class="container">
+        <h5 class="title">404</h5>
+        <p class="content">网络状况不佳,请改善网络状况后重启本应用</p>
+    </div>
+</template>
+
+<script>
+    import axios from 'axios';
+    let qs = require('qs');
+    import Global from '../Global.js'
+    export default {
+        data() {
+            return {
+                lists: []
+            }
+        },
+        mounted() {
+        },
+        methods: {},
+    }
+</script>
+
+<style scoped>
+    /*mu-header*/
+    .mu-primary-color {
+        line-height: 60px;
+        height: 60px;
+        background: url("../static/images/comm/headerBg.png") top center no-repeat;
+        background-size: 100%;
+    }
+
+    /deep/ .mu-appbar-left {
+        padding-top: 15px;
+    }
+
+    /deep/ .material-icons {
+        color: #fff;
+    }
+
+   /deep/ .mu-appbar-title {
+        text-align: center;
+    }
+</style>

+ 257 - 0
app/src/page/detector.vue

@@ -0,0 +1,257 @@
+<template>
+    <div class="">
+        <appHeader @goNewpage="onGoNewPage" :title="this.pagetitle"></appHeader>
+        <bottomTab :curTab="thisTab"></bottomTab>
+        <div class="listContainer">
+            <ul class="deteUl">
+                <li v-if="!lists.length">
+                    <h4>{{$t("no use data")}}</h4>
+                </li>
+                <transition-group name="fade">
+                    <li v-for="list in stus" v-if="lists" @click="goPage(list)" v-bind:key="list.Id">
+                        <div class="lt">
+                            <div class="rowTop">
+                                <h5>{{list.TagName}}</h5>
+                                <!--<span>{{list.Status | typeFileter}}</span>-->
+                                <span>{{list.stusType}}</span>
+                            </div>
+                            <div class="rowDetail">
+                                <span>{{list.Mac}}</span>
+                                <span class="pull-right">{{list.Memo}}</span>
+                            </div>
+                            <div class="rowDetail">
+                                <span>{{list.RegisterTime  | timeFileter}}</span>
+                                <span class="pull-right">{{list.ComName}}{{list.Name}}</span>
+                            </div>
+                        </div>
+                        <div class="rt">
+                            <mu-icon value="keyboard_arrow_right"></mu-icon>
+                        </div>
+                    </li>
+                </transition-group>
+                <div class="tips" v-if="lists">
+                    {{$t("total")}}{{lists.length}}{{$t("pcs")}} {{$t("Detection equipment")}}
+                </div>
+            </ul>
+        </div>
+    </div>
+</template>
+
+<script>
+    import appHeader from '../components/appHeader'
+    import bottomTab from '../components/bottomTab'
+    import axios from 'axios';
+
+    let qs = require('qs');
+    import Global from '../Global.js'
+
+    export default {
+        data() {
+            return {
+                pagetitle: this.$t('Detection'),
+                thisTab: this.$t('Detection'),
+                lists: [],
+                show: true
+            }
+        },
+        mounted() {
+            this.writeData();
+        },
+        methods: {
+            onGoNewPage(path) {
+                this.$router.push({path: '/' + path});
+            },
+            goPage(list) {
+                this.$router.push({path: '/detectorDetail', query: {detector: JSON.stringify(list)}});
+            },
+            writeData() {
+                const that = this;
+                let url = headapi + 'v1/Detector/DetectorQuery';
+                let pageIndex = 1;
+                let tableMax = 100;
+                let prov = localStorage.defaultProv;
+                let city = localStorage.defaultCity;
+                let area = localStorage.defaultArea;
+                let comid = localStorage.Comid;
+                let searchs = '';
+                let param = {
+                    token: localStorage.token,
+                    prov: prov,
+                    city: city,
+                    area: area,
+                    supregionid: 0,
+                    regionid: 0,
+                    comid: 48,
+                    keyword: '',
+                    pageIndex: pageIndex,
+                    tableMax: tableMax
+                };
+                let postdata = qs.stringify(param);
+                axios.post(url, postdata).then(function (data) {
+                    let json = data.data;
+                    if (json.Code == 0) {
+                        that.lists = json.Rs;
+                    } else {
+                        this.Toast(that.TransMemo(json.Memo));
+                    }
+                }, function (response) {
+                    console.info(response);
+                })
+            }
+        },
+        computed: {
+            stus() {
+                let that = this;
+                let text = '';
+                /*es6写法 防止用不了this.type*/
+                return this.lists.filter((v) => {
+                    switch (parseInt(v.Status)) {
+                        case 0:
+                            text = that.$t('Prohibit');
+                            break;
+                        case 1:
+                            text = that.$t('normal');
+                            break;
+                        case 2:
+                            text = that.$t('Off-line');
+                            break;
+                        case 3:
+                            text = that.$t('fault');
+                            break;
+                        case 9:
+                            text = that.$t('delete');
+                            break;
+                        default:
+                            text = that.$t('other');
+                            break;
+                    }
+                    return v.stusType = text;
+                })
+            }
+        },
+        filters: {
+            timeFileter: function (time) {
+                return globalfmtDate(time, 10)
+            },
+        },
+        components: {
+            appHeader, bottomTab
+        }
+    }
+</script>
+
+<style scoped>
+    #pages {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin-top: 0px;
+        padding-bottom: 10px;
+        background: #f2f2f2;
+    }
+
+    /*!*index mu-header*!*/
+    /deep/ .mint-header {
+        line-height: 60px;
+        height: 60px;
+        background: url("../static/images/comm/headerBg.png") top center no-repeat;
+        background-size: 100%;
+    }
+
+    /deep/ .mint-button--default {
+        background: none;
+        color: #fff;
+        font-size: 14px;
+    }
+
+    /deep/ .mint-header-title {
+        padding-top: 0 !important;
+    }
+
+    .listContainer ul {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+    }
+
+    .listContainer li {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        padding: 10px 20px;
+        border-bottom: 2px solid #f2f2f2;
+        background: #fff;
+    }
+
+    .listContainer .rowTop {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+    }
+
+    .rowTop .red {
+        color: #FFA200;
+    }
+
+    .listContainer h5 {
+        margin: 0;
+        float: left;
+        font-size: 16px;
+    }
+
+    .listContainer .rowTop {
+        margin-bottom: 10px;
+    }
+
+    .listContainer .rowTop span {
+        float: right;
+        font-size: 14px;
+    }
+
+    .listContainer .rowDetail {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        color: #999999;
+        font-size: 14px;
+    }
+
+    .deteUl .lt {
+        width: 95%;
+        float: left;
+    }
+
+    .deteUl .rt {
+        float: right;
+    }
+
+    .rt i {
+        width: 8px;
+        height: 14px;
+        margin-top: 20px;
+        margin-right: 5px;
+        color: #ccc;
+    }
+
+    .pull-right {
+        float: right;
+        text-align: right;
+    }
+
+    .tips {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        text-align: center;
+        font-size: 12px;
+        color: #999999;
+        margin-top: 20px;
+    }
+
+
+</style>

+ 140 - 0
app/src/page/detectorDetail.vue

@@ -0,0 +1,140 @@
+<template>
+    <div id="pages">
+        <mu-appbar style="width: 100%;" color="primary" :title="titletext">
+            <router-link to="/detector" slot="left">
+                <mu-icon value="arrow_back"></mu-icon>
+            </router-link>
+        </mu-appbar>
+        <div class="row">
+            <h5>{{detail.ComName}}</h5>
+            <ul>
+                <li><em>Mac:</em><span>{{detail.Mac}}</span></li>
+                <li><em>{{$t("Affiliated Enterprises")}}:</em><span>{{detail.ComName  | filterContent}}</span></li>
+                <li><em>{{$t("Tag name")}}:</em><span>{{detail.TagName  | filterContent}}</span></li>
+                <li><em>{{$t("local")}}:</em><span>{{detail.Prov}}{{detail.City}}{{detail.Area}}{{detail.Name}}</span></li>
+                <li><em>{{$t("memo")}}:</em><span>{{detail.Memo  | filterContent}}</span></li>
+            </ul>
+        </div>
+    </div>
+</template>
+
+<script>
+    import axios from 'axios';
+
+    let qs = require('qs');
+    import Global from '../Global.js'
+
+    export default {
+        data() {
+            return {
+                detail: {},
+                titletext:this.$t('Detection') + this.$t('detail'),
+            }
+        },
+        mounted() {
+            this.writeData();
+        },
+        methods: {
+            writeData() {
+                let content = this.$route.query.detector;
+                this.detail = JSON.parse(content);
+                console.log(this.detail);
+            }
+        },
+        filters: {
+            filterContent: function (value) {
+                if (value == '' || value == undefined) {
+                    return '-'
+                } else {
+                    return value
+                }
+            },
+        },
+        components: {}
+    }
+</script>
+
+<!-- Add "scoped" attribute to limit CSS to this component only -->
+<style scoped>
+    /*mu-header*/
+    /deep/ .mu-primary-color {
+        line-height: 60px;
+        height: 60px;
+        background: url("../static/images/comm/headerBg.png") top center no-repeat;
+        background-size: 100%;
+    }
+
+    /deep/ .mu-appbar-left {
+        padding-top: 15px;
+    }
+
+    /deep/ .material-icons {
+        color: #fff;
+    }
+
+    /deep/ .mu-appbar-title {
+        text-align: center;
+    }
+
+
+    #pages {
+        position: absolute;
+        top: 0;
+        left: 0;
+        right: 0;
+        bottom: 0;
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        padding-bottom: 200px;
+        background: #f2f2f2;
+    }
+
+    .row {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        background: #fff;
+    }
+
+    .row h5 {
+        width: 80%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        text-align: center;
+        font-size: 20px;
+        color: #FFA200;
+        padding: 20px;
+        border-bottom: 1px solid rgba(112, 112, 112, 0.14);
+        margin-bottom: 20px;
+    }
+
+    .row ul {
+        width: 80%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        margin-top: 10px;
+    }
+
+    .row li {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        margin-bottom: 10px;
+        font-size: 16px;
+    }
+
+
+    .row li em {
+        float: left;
+        min-width: 80px;
+    }
+
+    .row li span {
+        color: #6E6E6E;
+    }
+</style>

+ 176 - 0
app/src/page/enterpriseDetail.vue

@@ -0,0 +1,176 @@
+<template>
+    <div id="pages">
+        <mu-appbar style="width: 100%;" color="primary" :title="$t('Company details')">
+            <router-link to="/enterprisemanage" slot="left">
+                <mu-icon value="arrow_back"></mu-icon>
+            </router-link>
+        </mu-appbar>
+        <div class="container">
+            <div class="row">
+                <h5>{{detail.ComName}}</h5>
+                <ul>
+                    <li><em>{{$t("Enterprise name")}}:</em><span>{{detail.ComName}}</span></li>
+                    <li><em>{{$t("Enterprise types")}}:</em><span>{{ComType}}</span></li>
+                    <li>
+                        <em>{{$t("Enterprise address")}}:</em><span>{{detail.ProvCode}}{{detail.CityCode}}{{detail.AreaCode}}{{detail.Addr}}</span>
+                    </li>
+                    <li><em>{{$t("Subordinate supervision")}}:</em><span>
+                        <em v-for="(org,index) in detail.Orgs">{{org.Orgname}} <i
+                                v-if="detail.Orgs.length-1 != index">、</i></em>
+                    </span></li>
+                    <li><em>{{$t("Contacts")}}:</em><span>{{Legal}}</span></li>
+                    <li><em>{{$t("phone")}}:</em><span>{{Phone}}</span></li>
+                </ul>
+            </div>
+        </div>
+    </div>
+
+</template>
+
+<script>
+    import axios from 'axios';
+
+    let qs = require('qs');
+    import Global from '../Global.js'
+
+    export default {
+        data() {
+            return {
+                detail: {},
+                // Legal:'',
+                // Phone:'',
+                // ComType:'',
+            }
+        },
+        mounted() {
+            this.writeData();
+        },
+        computed: {
+            Legal() {
+                if (this.detail.Legal == '' || this.detail.Legal == undefined) {
+                    return this.$t('nothing')
+                } else {
+                    return this.detail.Legal
+                }
+            },
+            Phone() {
+                if (this.detail.Phone == '' || this.detail.Phone == undefined) {
+                    return this.$t('nothing')
+                } else {
+                    return this.detail.Legal
+                }
+            },
+            ComType() {
+                if (this.detail.ComType == '' || this.detail.ComType == undefined) {
+                    return this.$t('nothing')
+                } else {
+                    return this.detail.Legal
+                }
+            },
+        },
+        methods: {
+            writeData() {
+                const that = this;
+                let url = headapi + 'v1/Company/ComInfoDetail';
+                let param = {
+                    token: localStorage.token,
+                    comId: that.$route.query.ComId
+                };
+                let postdata = qs.stringify(param);
+                axios.post(url, postdata).then(function (data) {
+                    let json = data.data;
+                    if (json.Code == 0) {
+                        that.detail = json.Rs;
+                    } else {
+                        this.Toast(that.TransMemo(json.Memo));
+                    }
+                }, function (response) {
+                    console.info(response);
+                })
+            }
+        },
+    }
+</script>
+
+<style scoped>
+    /*mu-header*/
+    .mu-primary-color {
+        line-height: 60px;
+        height: 60px;
+        background: url("../static/images/comm/headerBg.png") top center no-repeat;
+        background-size: 100%;
+    }
+
+    /deep/ .mu-appbar-left {
+        padding-top: 15px;
+    }
+
+    /deep/ .material-icons {
+        color: #fff;
+    }
+
+    /deep/ .mu-appbar-title {
+        text-align: center;
+    }
+
+    #pages {
+        position: absolute;
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin-top: 0px;
+        top: 0;
+        bottom: 0;
+        padding-bottom: 200px;
+        background: #f2f2f2;
+    }
+
+    .row {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        margin-top: 10px;
+        background: #fff;
+    }
+
+    .row h5 {
+        width: 80%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        text-align: center;
+        font-size: 20px;
+        color: #FFA200;
+        padding: 20px;
+        border-bottom: 1px solid rgba(112, 112, 112, 0.14);
+        margin-bottom: 20px;
+    }
+
+    .row ul {
+        width: 80%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        margin-top: 10px;
+    }
+
+    .row li {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        margin-bottom: 10px;
+        font-size: 16px;
+    }
+
+
+    .row li em {
+        float: left;
+        min-width: 80px;
+    }
+
+    .row li span {
+        color: #6E6E6E;
+    }
+</style>

+ 376 - 0
app/src/page/enterprisemanage.vue

@@ -0,0 +1,376 @@
+<template>
+    <div id="pages">
+        <mu-appbar style="width: 100%;" color="primary" :title="$t('Business management')">
+            <router-link to="/" slot="left">
+                <mu-icon value="arrow_back"></mu-icon>
+            </router-link>
+            <mu-button flat color="primary" slot="right" @click="showPanel">{{btnText}}</mu-button>
+        </mu-appbar>
+        <mu-bottom-sheet :open.sync="popupVisible" @close="whenClose">
+            <div class="modal-content">
+                <div class="modal-body">
+                    <div class="location">
+                        <span>{{$t("query criteria")}}</span>
+                        <cityPicker></cityPicker>
+                        <span>{{$t("Keyword query")}}</span>
+                        <input type="text" placeholder="" v-model="keywords">
+                    </div>
+                </div>
+                <div class="modalBottom">
+                    <div class="reset" @click="resetModal">
+                        {{$t("Reset")}}
+                    </div>
+                    <div class="pullUp" @click="searchModal">
+                        {{$t("query")}}
+                    </div>
+                </div>
+            </div>
+        </mu-bottom-sheet>
+        <div class="listContainer">
+            <ul class="deteUl">
+                <li v-if="!lists.length">
+                    <h4>{{$t("no use data")}}</h4>
+                </li>
+                <li v-for="list in stus" v-if="lists" @click="goPage(list)">
+                    <div class="lt">
+                        <div class="rowTop">
+                            <h5>{{list.ComName}}</h5>
+                            <span>{{list.stusType}}</span>
+                            <!--<span>{{list.ComType | typeFileter}}</span>-->
+                        </div>
+                        <div class="rowDetail">
+                            <span>{{list.ProvCode}}{{list.CityCode}}{{list.AreaCode}}</span>
+                            <span class="pull-right" v-if="list.Orgs">{{list.Orgs[0].Orgname}}</span>
+                        </div>
+                    </div>
+                    <div class="rt">
+                        <mu-icon value="keyboard_arrow_right"></mu-icon>
+                    </div>
+                </li>
+                <div class="tips" v-if="lists">{{$t("total")}}{{lists.length}} {{$t("enterprise")}}</div>
+            </ul>
+        </div>
+    </div>
+</template>
+
+<script>
+    import axios from 'axios';
+
+    let qs = require('qs');
+    import Global from '../Global.js'
+    import cityPicker from '../components/cityPicker'
+
+    export default {
+        data() {
+            return {
+                popupVisible: false,//true false
+                keywords: '',
+                btnText: this.$t("search"),
+                lists: []
+            }
+        },
+        mounted() {
+            this.writeData();
+        },
+        computed: {
+            stus() {
+                let that = this;
+                let text = '';
+                /*es6写法 防止用不了this.type*/
+                return this.lists.filter((v) => {
+                    switch (parseInt(v.Status)) {
+                        case 1:
+                            text = that.$t('hotel');
+                            break;
+                        case 2:
+                            text = that.$t('tavern');
+                            break;
+                        case 3:
+                            text = 'KTV';
+                            break;
+                        case 4:
+                            text = that.$t('Prison');
+                            break;
+                        default:
+                            text = that.$t('other');
+                            break;
+                    }
+                    return v.stusType = text;
+                })
+            }
+        },
+        methods: {
+            // 重置
+            resetModal() {
+                this.keywords = '';
+                localStorage.defaultProv = '';
+                localStorage.defaultCity = '';
+                localStorage.defaultArea = '';
+            },
+            showPanel() {
+                this.popupVisible = true;
+                this.btnText = this.$t("close");
+            },
+            whenClose() {
+                this.popupVisible = false;
+                this.btnText = this.$t("search");
+            },
+            // 查询
+            searchModal() {
+                this.writeData();
+                this.popupVisible = false;
+                this.Toast('已查询', 'success');
+            },
+            goPage(list) {
+                this.$router.push({path: '/enterpriseDetail', query: {ComId: list.ComId}});
+            },
+            writeData() {
+                const that = this;
+                let url = headapi + 'v1/Company/GetComlist';
+                let pageIndex = 1;
+                let tableMax = 100;
+                let prov = localStorage.defaultProv;
+                let city = localStorage.defaultCity;
+                let area = localStorage.defaultArea;
+                let searchs = this.keywords;
+                let param = {
+                    token: localStorage.token,
+                    prov: prov,
+                    city: city,
+                    area: area,
+                    searchs: searchs,
+                    pageIndex: pageIndex,
+                    tableMax: tableMax
+                };
+                let postdata = qs.stringify(param);
+                axios.post(url, postdata).then(function (data) {
+                    let json = data.data;
+                    if (json.Code == 0) {
+                        that.lists = json.Rs;
+                    } else {
+                        this.Toast(that.TransMemo(json.Memo));
+                    }
+                }, function (response) {
+                    console.info(response);
+                })
+            }
+        },
+        components: {
+            cityPicker
+        }
+    }
+</script>
+
+<style scoped>
+    /*mu-header*/
+    .mu-primary-color {
+        line-height: 60px;
+        height: 60px;
+        background: url("../static/images/comm/headerBg.png") top center no-repeat;
+        background-size: 100%;
+    }
+
+    /deep/ .mu-appbar-left {
+        padding-top: 15px;
+    }
+
+    /deep/ .mu-appbar .material-icons {
+        color: #fff;
+    }
+
+    /deep/ .mu-appbar-title {
+        text-align: center;
+    }
+
+    #pages {
+        width: 100%;
+        height: 100%;
+        overflow: hidden;
+        overflow-y: scroll;
+        display: block;
+        margin-top: 0px;
+        padding-bottom: 20px;
+        background: #f2f2f2;
+    }
+
+    .modalSkip {
+        position: absolute;
+        top: 60px;
+        left: 0;
+        bottom: 0;
+        right: 0;
+        width: 100%;
+        height: 100%;
+        min-height: 736px;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        background: rgba(0, 0, 0, 0.35);
+    }
+
+    .listContainer {
+        width: 100%;
+        height: 100%;
+        display: block;
+        margin: 0 auto;
+        overflow-y: scroll;
+    }
+
+    .listContainer ul {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        padding-bottom: 100px;
+    }
+
+    .listContainer li {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        margin-bottom: 2px;
+        padding: 10px 20px;
+        background: #fff;
+    }
+
+    .listContainer .rowTop {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+    }
+
+    .rowTop .red {
+        color: #FFA200;
+    }
+
+    .listContainer h5 {
+        margin: 0;
+        float: left;
+        font-size: 16px;
+    }
+
+    .listContainer .rowTop span {
+        float: right;
+        font-size: 14px;
+    }
+
+    .listContainer .rowDetail {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        color: #999999;
+        font-size: 14px;
+        margin-top: 10px;
+        margin-bottom: 10px;
+    }
+
+    .deteUl .lt {
+        width: 88%;
+        float: left;
+    }
+
+    .deteUl .rt {
+        float: right;
+    }
+
+    .rt i {
+        margin-top: 20px;
+    }
+
+    .pull-right {
+        float: right;
+        text-align: right;
+    }
+
+    .tips {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        text-align: center;
+        font-size: 12px;
+        color: #999999;
+        margin-top: 20px;
+    }
+
+    /*mu-bottom-sheet*/
+    .mu-bottom-sheet {
+        top: 60px !important;
+        bottom: 405px;
+        background: none;
+    }
+
+    .location {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        /*padding-bottom: 40px;*/
+    }
+
+    .location span {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        margin-top: 10px;
+        margin-bottom: 10px;
+    }
+
+    .location input {
+        width: 95px;
+        height: 30px;
+        border: 1px solid #D5D5D5;
+        float: left;
+        text-indent: 10px;
+    }
+
+    .modal-content {
+        width: 100%;
+        display: block;
+        margin: 0 auto;
+        z-index: 99999;
+        overflow: hidden;
+    }
+
+    .modal-body {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        background: #fff;
+        padding-top: 20px;
+        padding-left: 5%;
+        padding-right: 5%;
+        padding-bottom: 40px;
+    }
+
+    .modalBottom {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        background: #fff;
+    }
+
+    .modalBottom .reset {
+        width: 50%;
+        float: left;
+        height: 40px;
+        line-height: 40px;
+        background: #FFF6CF;
+        text-align: center;
+    }
+
+    .modalBottom .pullUp {
+        width: 50%;
+        float: right;
+        height: 40px;
+        line-height: 40px;
+        background: #FFCC00;
+        text-align: center;
+    }
+</style>

+ 32 - 0
app/src/page/index.vue

@@ -0,0 +1,32 @@
+<template>
+<div id="index">
+    <keep-alive>
+        <transition name="fade">
+            <router-view></router-view>
+        </transition>
+    </keep-alive>
+</div>
+</template>
+
+<script>
+    export default {
+        data() {
+            return {}
+        },
+    }
+</script>
+<style>
+    #index {
+        height: 100%;
+        padding-bottom: 40px;
+        overflow-y: scroll;
+    }
+    .fade-enter-active, .fade-leave-active {
+        transition: opacity .5s;
+    }
+
+    .fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */
+    {
+        opacity: 0;
+    }
+</style>

+ 354 - 0
app/src/page/listDetail.vue

@@ -0,0 +1,354 @@
+<template>
+    <div id="pages">
+        <mu-appbar style="width: 100%;" color="primary" :title="$t('detail')">
+                <span @click="$router.back(-1)" slot="left">
+                       <mu-icon value="arrow_back"></mu-icon>
+                </span>
+        </mu-appbar>
+        <div class="container listContainer">
+            <div class="row ">
+                <ul class="deteUl" v-if="selected == 1">
+                    <li v-if="!lists.length">
+                        <h4>{{$t("no use data")}}</h4>
+                    </li>
+                    <li v-for="list in lists" v-if="lists">
+                        <div class="rowTop"><h5>{{list.Name}}</h5>
+                            <span v-if="list.DangerLevel == -1" class="green">{{$t("other")}}</span>
+                            <span v-if="list.DangerLevel == 0" class="green">{{$t("white")}}</span>
+                            <span v-if="list.DangerLevel == 2" class="yellow">{{$t("deal")}}</span>
+                            <span v-if="list.DangerLevel == 3" class="red">{{$t("warning")}}</span>
+                            <span v-if="list.DangerLevel == 4" class="red">{{$t("danger")}}</span>
+                        </div>
+                        <div class="rowDetail">
+                            <span>{{list.MacCom.length > 16 ? list.MacCom.slice(0, 16)+'...':list.MacCom}}</span>
+                            <s>{{list.Mac}}</s>
+                        </div>
+                        <div class="rowBottom">
+                            {{list.Memo}}
+                        </div>
+                    </li>
+                    <s class="tips" v-if="lists"> {{$t("total")}} {{lists.length}} {{$t("pcs")}} {{$t("wireless device")}}</s>
+                </ul>
+                <ul class="phoneUl" v-if="selected == 2">
+                    <li v-if="!phones">
+                        <h4>{{$t("no use data")}}</h4>
+                    </li>
+                    <li v-for="phone in phones" v-if="phones">
+                        <div class="peTop">
+                            {{phone.DetectorName}} <span>{{phone.RegionName}}</span>
+                        </div>
+                        <div class="peMemo">
+                            {{phone.Signalstr == ''?$t('No mobile signal detected'):phone.Signalstr}}
+                        </div>
+                    </li>
+                    <s class="tips" v-if="phones">  {{$t("total")}}{{phones.length}} {{$t("pcs")}} {{$t("Detection")}}</s>
+                </ul>
+            </div>
+        </div>
+    </div>
+</template>
+
+<script>
+    import axios from 'axios';
+
+    let qs = require('qs');
+    import Global from '../Global.js'
+
+    export default {
+        data() {
+            return {
+                selected: "1",
+                location: {
+                    ComName: this.$route.query.comName,
+                    Region: this.$route.query.Region,
+                },
+                RegionList: [],
+                unite: {
+                    ComName: '',
+                    Legal: '',
+                    Introduction: '',
+                },
+                lists: [],
+                phones: [],
+            }
+        },
+        mounted() {
+            this.readList();
+        },
+        methods: {
+            // 读取无线设备具体分布
+            readList() {
+                const that = this;
+                let url = headapi + 'v1/Company/RegionDetectDeviceDetailList';
+                let param = {
+                    token: localStorage.token,
+                    regionId: this.$route.query.RegionId
+                };
+                let postdata = qs.stringify(param);
+                axios.post(url, postdata).then(function (data) {
+                    let json = data.data;
+                    if (json.Code == 0) {
+                        that.lists = json.Rs;
+                    } else {
+                        this.Toast(that.TransMemo(json.Memo));
+                    }
+                }, function (response) {
+                    console.info(response);
+                })
+            },
+            goListDetail(list) {
+                this.$router.push({path: '/list', query: {RegionId: list.RegionId}});
+            },
+            readPhone() {
+                const that = this;
+                let url = headapi + 'v1/Detector/SignalDeviceByregion';
+                let param = {
+                    token: localStorage.token,
+                    regionid: this.$route.query.RegionId
+                };
+                let postdata = qs.stringify(param);
+                axios.post(url, postdata).then(function (data) {
+                    let json = data.data;
+                    if (json.Code == 0) {
+                        that.phones = json.Rs;
+                    } else {
+                        this.Toast(that.TransMemo(json.Memo));
+                    }
+                }, function (response) {
+                    console.info(response);
+                })
+            }
+        },
+    }
+</script>
+
+<style scoped>
+    /*mu-header*/
+    .mu-primary-color {
+        line-height: 60px;
+        height: 60px;
+        background: url("../static/images/comm/headerBg.png") top center no-repeat;
+        background-size: 100%;
+    }
+
+    /deep/ .mu-appbar-left {
+        padding-top: 15px;
+    }
+
+    /deep/ .material-icons {
+        color: #fff;
+    }
+
+    /deep/ .mu-appbar-title {
+        text-align: center;
+    }
+ #pages {
+     width: 100%;
+     overflow: hidden;
+     overflow-y: scroll;
+     display: block;
+     margin: 0 auto;
+     height: 100%;
+     position: absolute;
+     top: 0;
+     bottom: 0;
+     background: #f2f2f2;
+     padding-bottom: 20px;
+ }
+    .detail {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        padding-top: 0px;
+        padding-bottom: 20px;
+        padding-left: 2%;
+        padding-right: 2%;
+        margin-bottom: 10px;
+        background: #fff;
+    }
+    .detail ul {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        padding-left: 2%;
+        padding-right: 2%;
+    }
+
+    .detail h5 span {
+        font-size: 16px;
+    }
+
+    .detail h5 em {
+        float: right;
+        color: #666666;
+        font-size: 12px;
+        font-weight: normal;
+        text-align: right;
+    }
+
+    .detail p {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        font-size: 12px;
+        color: #666666;
+        line-height: 16px;
+    }
+
+    /deep/ .mint-navbar .mint-tab-item.is-selected {
+        border-bottom: 3px solid #FFA200;
+        color: #FFA200;
+    }
+
+    /deep/ .mint-navbar .mint-tab-item.is-selected .mint-tab-item-label {
+        color: #FFA200;
+    }
+
+    .listContainer ul {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+    }
+
+    .listContainer li {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        margin-bottom: 2px;
+        padding: 10px 20px;
+        background: #fff;
+    }
+
+    .listContainer .rowTop {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+    }
+
+    .rowTop .red {
+        color: #FFA200;
+    }
+
+    .listContainer h5 {
+        margin: 0;
+        float: left;
+        font-size: 16px;
+    }
+
+    .listContainer .rowTop span {
+        float: right;
+        font-size: 14px;
+    }
+
+    .listContainer .rowDetail {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        color: #999999;
+        font-size: 14px;
+        margin-top: 10px;
+        margin-bottom: 10px;
+    }
+
+    .rowDetail span {
+        float: left;
+    }
+
+    .rowDetail s {
+        float: right;
+    }
+
+    .rowBottom {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        font-size: 12px;
+        color: #999999;
+    }
+
+
+    .location {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        padding: 11px 4%;
+        font-size: 12px;
+        color: #999999;
+    }
+
+    .tips {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        text-align: center;
+        font-size: 12px;
+        color: #999999;
+        margin-top: 10px;
+    }
+
+    .phoneUl {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+    }
+
+    .phoneUl li {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        margin-bottom: 2px;
+        padding: 10px 20px;
+        background: #fff;
+    }
+
+    .phoneUl .peTop {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        font-size: 16px;
+        margin-bottom: 10px;
+    }
+
+    .peTop span {
+        float: right;
+        text-align: right;
+        font-size: 14px;
+    }
+
+    .peMemo {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        font-size: 14px;
+        color: #999999;
+    }
+    .deteUl {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+    }
+    .deteUl li h4 {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        text-align: center;
+        font-weight: normal;
+        line-height: 30px;
+    }
+</style>

+ 434 - 0
app/src/page/login.vue

@@ -0,0 +1,434 @@
+<template>
+    <div id="skin-blur-violate">
+        <section id="login">
+            <header>
+                <img src="../static/images/login/logo.png" height="109" width="109" id="logo"/>
+                <img src="../static/images/login/title.png" height="100%" width="274px"/>
+            </header>
+            <div class="clearfix"></div>
+            <!-- Login -->
+            <form class="box tile animated active" id="box-login">
+                <h2 class="m-t-0 m-b-15"></h2>
+                <div class="rowHeight">
+                    <input type="text" class="login-control login_account" placeholder="输入手机号"
+                           v-model="login.username">
+                </div>
+                <div class="rowHeight">
+                    <input type="number" class="login-control login_valid" placeholder="输入右侧图形码"
+                           v-model="login.uservalid">
+                    <img id="imgValidcode" :src="valImgSrc" :title="InvisibilityGiveitatry" @click="getValImgSrc">
+                </div>
+                <div class="rowHeight">
+                    <input type="password" class="login-control login_pwd" placeholder="输入验证码" v-model="login.userpwd"
+                           @keyup.enter="pwdLoginBtn">
+                    <span id="getValidSms" @click="getValidSmsBtn">获取验证码</span>
+                </div>
+                <div class="btn_center">
+                    <span class="btn btn-md login_btn" @click="pwdLoginBtn">登    录</span>
+                </div>
+            </form>
+        </section>
+        <mu-snackbar :position="normal.position" :open.sync="normal.open" :color="normal.color">
+            {{normal.message}}
+            <mu-button flat slot="action" color="secondary" @click="normal.open = false">{{"close"}}</mu-button>
+        </mu-snackbar>
+    </div>
+</template>
+
+<script>
+    import {
+        testSelect,
+        testPic,
+    } from '../api/getApiRes.js'
+
+    let qs = require('qs');
+
+    export default {
+        data() {
+            let samepass = (rule, value, callback) => {
+                if (value !== this.form.newpwd) {
+                    callback(new Error('两次输入密码不一致!'));
+                } else {
+                    callback();
+                }
+            };
+            let pwdPass = (rule, value, callback) => {
+                let re = /^[0-9a-zA-Z_]{1,}$/;
+                if (value.search(re) == -1) {
+                    callback(new Error('错了哦,密码只能由字母、数字及下划线组成'));
+                } else {
+                    callback()
+                }
+            };
+            let phonetest = (rule, value, callback) => {
+                let re = /^1[3|4|5|7|8|9][0-9]\d{8}$/;
+                if (value.search(re) == -1) {
+                    callback(new Error('错了哦,手机号码格式不正确'));
+                } else {
+                    callback()
+                }
+            };
+            return {
+                Password: "Password",
+                VerificationCode: "Verification Code",
+                InvisibilityGiveitatry: "无效?再点一下试试吧!",
+                valImgSrc: '',//
+                picId: '',//
+                overtime: '',
+                normal: normal,
+                login: {
+                    username: '',
+                    userpwd: '',
+                    uservalid: '',
+                },
+                rules: {
+                    username: [
+                        {required: true, message: '请输入用户名', trigger: 'blur'},
+                        {min: 6, max: 32, message: '长度在 6 到 32 个字符', trigger: 'blur'},
+                    ],
+                    phone: [
+                        {required: true, message: '请输入手机号', trigger: 'blur'},
+                        {min: 11, max: 12, message: '手机号长度是11位', trigger: 'blur'},
+                        {validator: phonetest, trigger: 'blur'}
+                    ],
+                    re_phonevalid: [
+                        {required: true, message: '请输入验证码', trigger: 'blur'},
+                        {min: 4, max: 4, message: '长度在 4 个字符', trigger: 'blur'},
+                    ],
+                    newpwd: [
+                        {required: true, message: '请输入新密码', trigger: 'blur'},
+                        {min: 6, max: 32, message: '长度在 6 到 32 个字符', trigger: 'blur'},
+                        {validator: pwdPass, trigger: 'blur'}
+                    ],
+                    again: [
+                        {required: true, message: '请输入确认密码', trigger: 'blur'},
+                        {min: 6, max: 32, message: '长度在 6 到 32 个字符', trigger: 'blur'},
+                        {validator: pwdPass, trigger: 'blur'},
+                        {validator: samepass, trigger: 'blur'},
+                    ],
+                }
+            }
+        },
+        mounted() {
+            // 获取图形验证码
+            this.getValImgSrc();
+            this.overtime = new Date();
+        },
+        methods: {
+            // 获取验证码
+            getValidSmsBtn() {
+                
+            },
+            clearLogin() {
+                this.login.username = '';
+                this.login.userpwd = '';
+                this.login.uservalid = '';
+                this.getValImgSrc();
+            },
+            // 点击验证码切换
+            getValImgSrc() {
+                let that = this;
+                let param = {
+                    token: localStorage.token,
+                };
+                let postdata = qs.stringify(param);
+                testPic(postdata).then(res => {
+                    let json = res;
+                    if (json.Code == 0) {
+                        that.valImgSrc = json.pic;
+                        that.valImgId = json.id;
+                    } else {
+                        that.$message.error(json.Memo);
+                    }
+                })
+            },
+            // pwd登录
+            pwdLoginBtn() {
+                let that = this;
+                let username = this.login.username;
+                let userpwd = this.login.userpwd;
+                let uservalid = this.login.uservalid;
+                // 重置验证码超时
+                that.overtime = new Date();
+                if (!that.globalValid(username, 2, 17, 'usercode', that)) return;
+                if (!that.globalValid(userpwd, 5, 17, 'Password', that)) return;
+                if (!that.globalValid(uservalid, 3, 5, 'Verification Code', that)) return;
+                this.loginInfo();
+            },
+            // 校验内容长度
+            globalValid(data, mins, maxs, text, that) {
+                let thisVal = data;
+                let thisLeng = thisVal.length;
+                let min = parseInt(mins);
+                let max = parseInt(maxs);
+                let dispalyMin = min + 1;
+                if (thisVal == '') {
+                    this.Toast(text + 'usercode' + ' ' + 'can not be empty');
+                    return false
+                } else if (thisLeng <= min) {
+                    this.Toast(text + 'least' + dispalyMin + 'character');
+                    return false
+                } else if (thisLeng > max) {
+                    this.Toast(text + 'Limit exceeded');
+                    return false
+                } else {
+                    return true
+                }
+            },
+            //            pwd登陆
+            loginInfo: function () {
+                const that = this;
+                let url = headapi + 'v1/Auth/SignIn';
+                let username = this.login.username;
+                let userpwd = this.login.userpwd;
+                let uservalid = this.login.uservalid;
+                let picId = this.picId;
+                let current = new Date();
+                let betweenTime = current - that.overtime;
+                let s = 120;
+                if (betweenTime > s * 1000) {
+                    that.changeValImg();
+                    that.$message.error('The verification code has timed out. Please re-enter');
+                    return false
+                }
+                let param = {
+                    'verifyName': username,
+                    'verifyCode': userpwd,
+                    'picId': picId,
+                    'picCode': uservalid,
+                    'src': 'pc'
+                };
+                let postdata = qs.stringify(param);
+                axios.post(url, postdata).then(function (data) {
+                    let json = data.data;
+                    if (json.Code == 0) {
+                        localStorage.token = json.Rs.token;
+                        that.getUserInfo(json.Rs.token);
+                    } else {
+                        that.Toast(that.TransMemo(json.Memo));
+                        that.getValImgSrc();//重置验证码
+                        that.clearLogin();
+                    }
+                }, function (response) {
+                    console.info(response);
+                })
+            },
+            getUserInfo(token) {
+                const that = this;
+                let url = headapi + 'v1/User/GetUserBytoken';
+                let param = {
+                    token: token
+                };
+                let postdata = qs.stringify(param);
+                axios.post(url, postdata).then(function (data) {
+                    let json = data.data;
+                    var userLevel = json.Rs.Rolesname;
+                    localStorage.userLevel = userLevel;
+                    localStorage.comId = json.Rs.Comid;
+                    localStorage.Insname = json.Rs.Insname;
+                    that.$router.push({path: '/'});
+                }, function (response) {
+                    console.info(response);
+                })
+            }
+        },
+        components: {}
+    }
+</script>
+
+<style scoped>
+    #skin-blur-violate {
+        position: relative;
+        top: 0;
+        left: 0;
+        right: 0;
+        bottom: 0;
+        width: 100%;
+        height: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        background: #3B3B3B;
+        background: url("../static/images/login/bg.png") top center no-repeat;
+        background-size: 100% 100%;
+    }
+
+    #login {
+        width: 90%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+    }
+
+    #login .box {
+        margin: 0 auto;
+        position: inherit;
+        margin-top: 20px;
+        border-radius: 9px;
+        padding: 20px 20px;
+    }
+
+    h1 {
+        color: #FFA200;
+        font-size: 30px;
+    }
+
+    header p {
+        font-size: 14px;
+        color: #7B7B7B;
+    }
+
+    #login header {
+        text-align: center;
+        margin-top: 15%;
+    }
+
+    #box-login h2 {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        margin-bottom: 20px;
+        text-align: center;
+        font-size: 24px;
+        color: #fff;
+    }
+
+    #tableBordered {
+        margin: 0;
+        padding: 0;
+    }
+
+    #tableBordered h5 {
+        margin: 0;
+        text-align: center;
+        padding: 0;
+    }
+
+    #login .box {
+        margin: 0 auto;
+        position: inherit;
+        margin-top: 20px;
+        border-radius: 9px !important;
+    }
+
+    #login header {
+        text-align: center;
+        margin-top: 15%;
+    }
+
+    #tableBordered {
+        margin: 0;
+        padding: 0;
+    }
+
+    #tableBordered h5 {
+        margin: 0;
+        text-align: center;
+        padding: 0;
+    }
+
+    #imgValidcode {
+        position: relative;
+        float: right;
+        /*bottom: 54px;*/
+        width: 121px;
+        height: 50px;
+        background: #eee;
+    }
+
+    .login_btn {
+        width: 100%;
+        height: 50px;
+        line-height: 50px;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        margin-top: 42px;
+        background: #E75296;
+        color: #fff;
+        font-size: 14px;
+        text-align: center;
+        border: none;
+        padding: 0;
+        font-size: 24px;
+        margin-bottom: 3%;
+    }
+
+    .clear_btn {
+        width: 100%;
+        height: 40px;
+        line-height: 40px;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        background: rgba(255, 255, 255, 0.32);
+        color: #FFCC00;
+        font-size: 14px;
+        text-align: center;
+        border: none;
+        padding: 0;
+    }
+
+    header p {
+        margin-top: 10px;
+    }
+
+    #login .login-control {
+        width: 100%;
+        height: 50px;
+        line-height: 50px;
+        background: rgba(255, 255, 255, 0.4);
+        margin-bottom: 3px;
+        text-indent: 10px;
+        border: none;
+
+    }
+
+    #login .login-control::placeholder {
+        color: #000000;
+        font-size: 16px;
+    }
+
+    #logo {
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        margin-top: 10%;
+        margin-bottom: 10px;
+    }
+
+    .rowHeight {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        height: 50px;
+        margin-bottom: 3px;
+    }
+
+    #getValidSms {
+        width: 121px;
+        height: 50px;
+        background: #fff;
+        border: 1px solid #fff;
+        opacity: 0.6;
+        position: relative;
+        /*bottom: 55px;*/
+        float: right;
+        text-align: center;
+        color: #E75296;
+        line-height: 50px;
+        font-size: 16px;
+    }
+
+    #login .login_valid {
+        width: 173px;
+        float: left;
+    }
+
+    #login .login_pwd {
+        width: 173px;
+        float: left;
+    }
+</style>

+ 317 - 0
app/src/page/mainpage.vue

@@ -0,0 +1,317 @@
+<template>
+    <div id="mainPage">
+        <appHeader @goNewpage="onGoNewPage" :title="this.pagetitle"></appHeader>
+        <bottomTab :curTab="thisTab"></bottomTab>
+        <div class="goPage goTitle" @click="goPage('runtime')">
+            <span>{{"Real-time monitoring"}}</span>
+            <mu-icon value="keyboard_arrow_right"></mu-icon>
+        </div>
+        <div class="mapContainer">
+            <mapDrag :curheight="310" :divcontainer="'js-container1'"></mapDrag>
+        </div>
+        <div class="goPage goTitle" @click="goPage('record')">
+            <span>{{"Detection record")}</span>
+            <mu-icon value="keyboard_arrow_right"></mu-icon>
+        </div>
+        <div class="runDate">
+            <div class="box4">
+                <div class="border4">
+                </div>
+                <span class="sum"><em>{{"Record"}}</em><s>{{recordNum}} {{"item"}}</s></span>
+            </div>
+            <div class="basic">
+                <ul>
+                    <mu-row gutter>
+                        <mu-col span="4">
+                            <li @click="goPage('runtime')">
+                                <em :class="{'red':Dannum > 0}">{{Dannum}}</em>
+                                <s>{{"Suspicious device"}}</s>
+                            </li>
+                        </mu-col>
+                        <mu-col span="4">
+                            <li @click="goPage('detector')">
+                                <em>{{GetDetectorNum}}</em>
+                                <s>{{"Detection equipment"}}</s>
+                            </li>
+                        </mu-col>
+                        <mu-col span="4">
+                            <li @click="goPage('enterprisemanage')">
+                                <em>{{GetHotelCounts}}</em>
+                                <s>{{"Supervision quantity"}}</s>
+                            </li>
+                        </mu-col>
+                    </mu-row>
+                </ul>
+            </div>
+        </div>
+        <div class="goPage" @click="goPage('statis')">
+            <span>{{"Statistical report forms"}}</span>
+            <mu-icon value="keyboard_arrow_right"></mu-icon>
+        </div>
+        <div class="chartContaienr">
+            <statischart></statischart>
+        </div>
+    </div>
+</template>
+
+<script>
+    import appHeader from '../components/appHeader'
+    import bottomTab from '../components/bottomTab'
+    import mapDrag from '../components/mapDrag'
+    import statischart from '../components/statischart'
+    import axios from 'axios';
+
+    let qs = require('qs');
+    import Global from '../Global.js'
+
+    export default {
+        data() {
+            return {
+                pagetitle: 'Wireless device detection system management',
+                thisTab: 'System home page',
+                recordNum: 0,
+                Dannum: 0,
+                GetHotelCounts: 0,
+                GetDetectorNum: 0,
+            }
+        },
+        mounted() {
+            this.GetStaticinfo();
+            this.GetUserProv();
+            this.timer = setInterval(() => {
+                this.GetStaticinfo();
+            }, 5000);
+        },
+        destroyed() {
+            clearInterval(this.timer);
+        },
+        methods: {
+            onGoNewPage(path) {
+                this.$router.push({path: '/' + path});
+            },
+            goPage(pages) {
+                this.$router.push({path: pages});
+            },
+            // 获得数据
+            GetStaticinfo() {
+                const that = this;
+                let url = headapi + 'v1/Company/GetStaticinfo';
+                let param = {
+                    token: localStorage.token,
+                };
+                let postdata = qs.stringify(param);
+                axios.post(url, postdata).then(function (data) {
+                    let json = data.data;
+                    if (json.Code == 0) {
+                        that.recordNum = json.Rs.Decrsnum;
+                        that.Dannum = json.Rs.Danwifinum;
+                        that.GetHotelCounts = json.Rs.Comnum;
+                        that.GetDetectorNum = json.Rs.Detectornum;
+                    } else {
+                        if (json.Code == 1010) {
+                            that.$router.push({path: '/login'});
+                            return false
+                        }
+                    }
+                }, function (response) {
+                    console.info(response);
+                })
+            },
+            GetUserProv() {
+                let url = headapi + 'v1/User/GetUserBytoken';
+                let param = {
+                    token: localStorage.token
+                };
+                let postdata = qs.stringify(param);
+                axios.post(url, postdata).then(function (data) {
+                    let json = data.data;
+                    if (json.Code == 0) {
+                        // todo 改写用vuex
+                        localStorage.defaultProv = json.Rs.Insprov;
+                        localStorage.defaultCity = json.Rs.Inscity;
+                        localStorage.defaultArea = json.Rs.Insarea;
+                        localStorage.Comid = json.Rs.Comid;
+                    }
+                }, function (response) {
+                    console.info(response);
+                })
+            }
+
+        },
+        components: {
+            appHeader, bottomTab, mapDrag, statischart
+        }
+    }
+</script>
+
+<style scoped>
+    #mainPage {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        background: #f2f2f2;
+    }
+
+    .goPage {
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        background: #fff;
+        height: 50px;
+        line-height: 50px;
+        padding: 0 20px;
+        color: #333;
+        font-size: 18px;
+        border-bottom: 1px solid #f2f2f2;
+    }
+
+    .goPage span {
+        float: left;
+    }
+
+    .goPage i {
+        float: right;
+        margin-top: 12px;
+    }
+
+    .goPage img {
+        overflow: hidden;
+        display: block;
+        width: 8px;
+        height: 14px;
+        float: right;
+        margin-top: 16px;
+        margin-right: 10px;
+    }
+
+    .goTitle i {
+        margin-top: 10px;
+        float: right;
+    }
+
+    .mapContainer {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        max-height: 317px;
+    }
+
+    .runDate {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+    }
+
+    .runDate span.sum {
+        position: relative;
+        /*bottom: 80px;*/
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        text-align: center;
+        line-height: 80px;
+    }
+
+    .runDate span.sum em {
+        font-size: 18px;
+        color: #333;
+        padding-right: 10px;
+    }
+
+    .runDate .sum s {
+        font-size: 28px;
+        color: #FFA200;
+    }
+
+    .box4 {
+        position: relative;
+        width: 100%;
+        height: 75px;
+        display: block;
+        margin: 0 auto;
+        overflow: hidden;
+    }
+
+    .border4 {
+        position: absolute;
+        top: 0px;
+        left: 0px;
+        /*width: 1400px;*/
+        /*-webkit-animation: scrollText2 3s infinite cubic-bezier(1, 0, 0.5, 0);*/
+        /*animation: scrollText2 3s infinite cubic-bezier(1, 0, 0.5, 0);*/
+        width: 100%;
+        height: 100px;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        background: url("../static/images/main/11.gif") top center no-repeat;
+        background-size: 100%;
+    }
+
+    .basic {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        padding: 5px 0;
+    }
+
+    .basic ul {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        padding: 0;
+    }
+
+    .basic li {
+        width: 100%;
+        min-height: 110px;
+        /*width: 120px;*/
+        overflow: hidden;
+        padding-bottom: 5px;
+        float: left;
+        background: #fff;
+        text-align: center;
+    }
+
+    .col {
+        padding-left: 3px;
+        padding-right: 3px;
+    }
+
+    .basic li em {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        margin-top: 9px;
+        font-size: 36px;
+        color: #000;
+    }
+
+    .basic li s {
+        font-size: 14px;
+        color: #888888;
+        text-decoration: none;
+    }
+
+    .chartContaienr {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        background: #fff;
+        margin-top: 2px;
+        padding-top: 15px;
+        padding-bottom: 40px;
+    }
+
+    .basic li em.red {
+        color: red;
+    }
+</style>

+ 51 - 0
app/src/page/map.vue

@@ -0,0 +1,51 @@
+<template>
+    <div id="map">
+        <appHeader @goNewpage="onGoNewPage" :title="this.pagetitle"></appHeader>
+        <bottomTab :curTab="thisTab"></bottomTab>
+        <mapPage @drag="dragMap" :curheight="curheight" :divcontainer="'js-container2'"></mapPage>
+    </div>
+</template>
+
+<script>
+    import appHeader from '../components/appHeader'
+    import bottomTab from '../components/bottomTab'
+    import mapPage from '../components/mapPage'
+    export default {
+        data() {
+            return {
+                pagetitle: this.$t('Map'),
+                thisTab:  this.$t('Map'),
+                curheight:  window.screen.height,
+            }
+        },
+        mounted(){
+            console.log(window.screen.height);
+        },
+        methods: {
+            onGoNewPage(path) {
+                this.$router.push({path: '/' + path});
+            },
+            dragMap() {
+            },
+        },
+      components: {
+          mapPage,appHeader,bottomTab
+      }
+    }
+</script>
+
+<style scoped>
+    #map {
+        position: absolute;
+        top: 0;
+        left: 0;
+        right: 0;
+        bottom: 0;
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin-top: 0px;
+        padding-bottom: 0px;
+        background: #f2f2f2;
+    }
+</style>

+ 47 - 0
app/src/page/modal.vue

@@ -0,0 +1,47 @@
+<template>
+    <div>
+        <mu-appbar style="width: 100%;" color="primary" title="详情信息">
+            <router-link to="/" slot="left">
+                <mu-icon value="arrow_back"></mu-icon>
+            </router-link>
+        </mu-appbar>
+    </div>
+</template>
+
+<script>
+    import axios from 'axios';
+    let qs = require('qs');
+    import Global from '../Global.js'
+    export default {
+        data() {
+            return {
+                lists: []
+            }
+        },
+        mounted() {
+        },
+        methods: {},
+    }
+</script>
+
+<style scoped>
+    /*mu-header*/
+    .mu-primary-color {
+        line-height: 60px;
+        height: 60px;
+        background: url("../static/images/comm/headerBg.png") top center no-repeat;
+        background-size: 100%;
+    }
+
+    /deep/ .mu-appbar-left {
+        padding-top: 15px;
+    }
+
+    /deep/ .material-icons {
+        color: #fff;
+    }
+
+   /deep/ .mu-appbar-title {
+        text-align: center;
+    }
+</style>

+ 61 - 0
app/src/page/notFound.vue

@@ -0,0 +1,61 @@
+<template>
+    <div id="pages">
+            <h5>404</h5>
+            <span @click="$router.back(-1)">{{$t("Back to previous page")}}</span>
+    </div>
+</template>
+
+<script>
+export default {
+    data () {
+    return {
+      msg: 'Welcome to Your Vue.js App'
+    }
+    },
+}
+</script>
+
+<!-- Add "scoped" attribute to limit CSS to this component only -->
+<style scoped>
+    #pages {
+        position: absolute;
+        top:0;
+        bottom: 0;
+        left: 0;
+        right: 0;
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        background:#2c2e2f
+    }
+    h5 {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        font-size: 160px;
+        text-align: center;
+        margin-top: 10%;
+        color: #fff;
+        font-weight: normal;
+    }
+    span {
+        width: 200px;
+        height: 45px;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        margin-top: 10%;
+        background:#FFA200 ;
+        color: #fff;
+        font-size: 18px;
+        text-align: center;
+        border-radius: 250px;
+        line-height: 45px;
+        cursor: pointer;
+    }
+    span:hover {
+        background: #FFA200;
+    }
+</style>

+ 332 - 0
app/src/page/plane.vue

@@ -0,0 +1,332 @@
+<template>
+    <div id="pages">
+        <mu-appbar style="width: 100%;" color="primary" :title="$t('Plane details')">
+            <router-link to="/map" slot="left">
+                <mu-icon value="arrow_back"></mu-icon>
+            </router-link>
+        </mu-appbar>
+        <mu-tabs :value.sync="active" inverse color="warning" full-width>
+            <mu-tab :id="Region.RegionId" v-for="(Region,index) in RegionList" :key="Region.RegionId">
+                {{Region.Region}}
+            </mu-tab>
+        </mu-tabs>
+        <div class="planeContainer">
+            <ul>
+                <li v-if="!lists.length">
+                    <h4>{{$t("no use data")}}</h4>
+                </li>
+                <li v-for="(list,index) in lists" v-if="lists">
+                    <div class="basic">
+                        <h5>{{list.Region}}</h5>
+                        <span>
+                                 {{$t("Detection")}} :{{list.DetectorCount}}台|
+                                {{$t("Dangerous equipment found")}} :{{list.DangerCamCount}}台|
+                                {{$t("phone")}}:{{list.Signalstr == ' '? $t("No mobile signal detected"):list.Signalstr}}
+                            </span>
+                        <div v-if="imgSrc[index]" class="imgSrcContainer">
+                            <img :src="imgSrc[index]" alt="">
+                            <span class="imgContainer">
+                                <em :class="[{'green':pointStates[index].DetectorType == 0},{'red':pointStates[index].DetectorType != 0}]"
+                                    v-for="(point,index) in points[index]"
+                                    :style="{left:point.Width*0.30+'px',top:point.Height * -0.4+'px'}"
+                                ></em>
+                            </span>
+                        </div>
+                        <div v-else>
+                            <p class="tips">{{$t("No records found")}}</p>
+                        </div>
+                    </div>
+                </li>
+            </ul>
+        </div>
+    </div>
+</template>
+
+<script>
+    import axios from 'axios';
+
+    let qs = require('qs');
+    import Global from '../Global.js'
+
+    export default {
+        data() {
+            return {
+                active: 0,
+                selected: 0,
+                RegionList: [],
+                lists: [],
+                imgSrc: [],
+                points: [],
+                pointStates: [],
+            }
+        },
+        mounted() {
+            this.RegionDetectList();
+        },
+        watch: {
+            active(val) {
+                this.readList(this.RegionList[val]['RegionId']);
+            }
+        },
+        methods: {
+            // 读取楼栋信息
+            RegionDetectList() {
+                const that = this;
+                let url = headapi + 'v1/Company/ComRegionDetectList';
+                let comId = this.$route.query.ComId;
+                let param = {
+                    token: localStorage.token,
+                    comId: comId
+                };
+                that.RegionList = [];
+                let postdata = qs.stringify(param);
+                axios.post(url, postdata).then(function (data) {
+                    let json = data.data;
+                    if (json.Code == 0) {
+                        that.RegionList = json.Rs;
+                        if (json.Rs) {
+                            // that.selected = json.Rs[0].RegionId;
+                            that.selected = parseInt(that.$route.query.Regionid);
+                            that.readList( that.selected);
+                        }
+                    } else {
+                        that.Toast(that.TransMemo(json.Memo));
+                    }
+                }, function (response) {
+                    console.info(response);
+                })
+            },
+            readList(regionId) {
+                const that = this;
+                let url = headapi + 'v1/Company/RegionDetectList';
+                let param = {
+                    token: localStorage.token,
+                    regionId: regionId // regionId
+                };
+                that.lists = [];
+                let postdata = qs.stringify(param);
+                axios.post(url, postdata).then(function (data) {
+                    let json = data.data;
+                    if (json.Code == 0) {
+                        that.lists = json.Rs;
+                        that.imgFileter(json.Rs);
+                        that.DetectListByRegionID(json.Rs)
+                    } else {
+                        that.Toast(that.TransMemo(json.Memo));
+                    }
+                }, function (response) {
+                    console.info(response);
+                })
+            },
+            imgFileter(Rs) {
+                const that = this;
+                let url = headapi + 'v1/Company/RegionPictureGetByRegionId';
+                that.imgSrc = [];
+                for (var i = 0; i < Rs.length; i++) {
+                    let param = {
+                        token: localStorage.token,
+                        regionID: Rs[i].RegionId// regionId
+                    };
+                    let postdata = qs.stringify(param);
+                    axios.post(url, postdata).then(function (data) {
+                        let json = data.data;
+                        if (json.Code == 0) {
+                            that.imgSrc.push(json.EncodeString);
+                        }
+                    }, function (response) {
+                        console.info(response);
+                    })
+                }
+            },
+            DetectListByRegionID(Rs) {
+                const that = this;
+                let url = headapi + 'v1/Company/DetectListByRegionID';
+                let comId = this.$route.query.ComId;
+                for (var i = 0; i < Rs.length; i++) {
+                    let param = {
+                        token: localStorage.token,
+                        comId: comId, // regionId
+                        regionId: Rs[i].RegionId// regionId
+                    };
+                    let postdata = qs.stringify(param);
+                    axios.post(url, postdata).then(function (data) {
+                        let json = data.data;
+                        if (json.Code == 0) {
+                            if (json.Rs) {
+                                that.points.push(json.Rs);
+                                console.log(that.points);
+                            } else {
+                                that.points = [];
+                            }
+                            if (json.DetectorType != undefined && json.DetectorType != null) {
+                                that.pointStates = json.DetectorType;
+                            } else {
+                                that.pointStates = [];
+                                return false
+                            }
+                        }
+                    }, function (response) {
+                        console.info(response);
+                    })
+                }
+            },
+        },
+    }
+</script>
+
+<style scoped>
+    /*mu-header*/
+    .mu-primary-color {
+        line-height: 60px;
+        height: 60px;
+        background: url("../static/images/comm/headerBg.png") top center no-repeat;
+        background-size: 100%;
+    }
+
+    /deep/ .mu-appbar-left {
+        padding-top: 15px;
+    }
+
+    /deep/ .material-icons {
+        color: #fff;
+    }
+
+    /deep/ .mu-appbar-title {
+        text-align: center;
+    }
+
+    .mu-warning-text-color {
+        color: #FFA200;
+    }
+
+    /deep/ .mu-tab-link-highlight {
+        background-color: #FFA200 !important;
+    }
+
+    #pages {
+        position: absolute;
+        width: 100%;
+        height: 100%;
+        overflow-y: scroll;
+        display: block;
+        margin: 0 auto;
+        background-color: #f2f2f2;
+        top: 0;
+        bottom: 0;
+    }
+
+    .info {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        background: #fff;
+        margin-bottom: 10px;
+        padding-left: 20px;
+    }
+
+    .planeContainer li {
+        width: 100%;
+        height: 360px;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+    }
+
+    .basic {
+        width: 100%;
+        height: 360px;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        border-bottom: 1px solid #f2f2f2;
+        background: #fff;
+        padding: 5px 0px;
+    }
+
+    .basic h5 {
+        border: 2px solid #f2f2f2;
+        border-left: 0;
+        border-right: 0;
+        padding: 10px 0;
+        padding-left: 20px;
+        font-size: 14px;
+    }
+
+    .basic > span {
+        width: 88%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        font-size: 12px;
+    }
+
+    .basic img {
+        width: 96%;
+        height: 200px;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        margin-top: 15px;
+        margin-bottom: 5px;
+    }
+
+    .red {
+        width: 20px;
+        height: 20px;
+        border-radius: 250px !important;
+        float: left;
+        margin: 0;
+        padding: 0;
+        background-color: red;
+        color: red;
+    }
+
+    .green {
+        width: 20px;
+        height: 20px;
+        border-radius: 250px !important;
+        float: left;
+        margin: 0;
+        padding: 0;
+        background-color: yellowgreen;
+        color: yellowgreen;
+    }
+    .imgSrcContainer {
+        width: 100%;
+        height: 220px;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+    }
+
+    .imgContainer {
+        position: relative;
+        bottom: 200px;
+        width: 96%;
+        height: 200px;
+        display: block;
+        margin: 0 auto;
+    }
+    .imgContainer em {
+        position: relative;
+    }
+
+    .tips {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        text-align: center;
+        margin-top: 10px;
+        margin-bottom: 10px;
+    }
+
+    ul li h4 {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        text-align: center;
+    }
+</style>

+ 265 - 0
app/src/page/profile.vue

@@ -0,0 +1,265 @@
+<template>
+    <div>
+        <mu-appbar style="width: 100%;" color="primary" :title="$t('detail')">
+            <router-link to="/map" slot="left">
+                <mu-icon value="arrow_back"></mu-icon>
+            </router-link>
+        </mu-appbar>
+        <div class="container">
+            <div class="row">
+                <div class="detail">
+                    <h5>
+                        <span>{{unite.ComName}}</span>
+                        <em>{{unite.Legal}}</em>
+                    </h5>
+                    <p>
+                        {{unite.Introduction}}
+                    </p>
+                </div>
+                <div class="listContainer">
+                    <ul>
+                        <li v-if="!lists.length">
+                            <h4>{{$t("no use data")}}</h4>
+                        </li>
+                        <li v-for="list in lists" v-if="lists" @click="goListDetail(list)">
+                            <h5>{{list.Region}}</h5>
+                            <div>
+                                <mu-icon value="keyboard_arrow_right"></mu-icon>
+                                <span>
+                                    {{$t("Camera")}}:{{list.CamCount}}  {{$t("pcs")}} |
+                                     {{$t("Detection")}} :{{list.DetectorCount}} {{$t("pcs")}} |
+                                     {{$t("Suspicious camera")}}:{{list.DangerCamCount}} {{$t("pcs")}}
+                                </span>
+                                <span>
+                                      {{$t("phone")}}:{{list.Signalstr == ' '?  $t("No mobile signal detected"):list.Signalstr}}
+                                </span>
+                            </div>
+                        </li>
+                    </ul>
+                </div>
+            </div>
+        </div>
+    </div>
+</template>
+
+<script>
+    import axios from 'axios';
+
+    let qs = require('qs');
+    import Global from '../Global.js'
+
+    export default {
+        data() {
+            return {
+                selected: "1",
+                RegionList: [],
+                unite: {
+                    ComName: '',
+                    Legal: '',
+                    Introduction: '',
+                },
+                lists: [],
+            }
+        },
+        mounted() {
+            this.readInfo();
+            this.RegionDetectList();
+        },
+        methods: {
+            // 基本信息
+            readInfo() {
+                const that = this;
+                let url = headapi + 'v1/Company/ComInfoDetail';
+                let comId = this.$route.query.ComId;
+                let param = {
+                    token: localStorage.token,
+                    comId: comId
+                };
+                let postdata = qs.stringify(param);
+                axios.post(url, postdata).then(function (data) {
+                    let json = data.data;
+                    if (json.Code == 0) {
+                        that.unite.ComName = json.Rs.ComName;
+                        that.unite.Legal = json.Rs.Legal;
+                        that.unite.Introduction = json.Rs.Introduction;
+                    } else {
+                        this.Toast(that.TransMemo(json.Memo));
+                    }
+                }, function (response) {
+                    console.info(response);
+                })
+            },
+            // 读取楼栋信息
+            RegionDetectList() {
+                const that = this;
+                let url = headapi + 'v1/Company/ComRegionDetectList';
+                let comId = this.$route.query.ComId;
+                let param = {
+                    token: localStorage.token,
+                    comId: comId
+                };
+                let postdata = qs.stringify(param);
+                axios.post(url, postdata).then(function (data) {
+                    let json = data.data;
+                    if (json.Code == 0) {
+                        that.RegionList = json.Rs;
+                        if (json.Rs) {
+                            that.selected = json.Rs[0].RegionId;
+                            that.readList();
+                        }
+                    } else {
+                        this.Toast(that.TransMemo(json.Memo));
+                    }
+                }, function (response) {
+                    console.info(response);
+                })
+            },
+            // 读取无线设备具体分布
+            readList() {
+                const that = this;
+                let url = headapi + 'v1/Company/RegionDetectList';
+                let param = {
+                    token: localStorage.token,
+                    regionId: this.selected
+                };
+                let postdata = qs.stringify(param);
+                axios.post(url, postdata).then(function (data) {
+                    let json = data.data;
+                    if (json.Code == 0) {
+                        that.lists = json.Rs;
+                    } else {
+                        this.Toast(that.TransMemo(json.Memo));
+                    }
+                }, function (response) {
+                    console.info(response);
+                })
+            },
+            goListDetail(list) {
+                let that = this;
+                that.$router.push(
+                    {
+                        path: '/listDetail',
+                        query: {
+                            RegionId: list.RegionId,
+                            Region: list.Region,
+                            comName: that.unite.ComName
+                        }
+                    });
+            }
+        },
+    }
+</script>
+
+<style scoped>
+    /*mu-header*/
+    .mu-primary-color {
+        line-height: 60px;
+        height: 60px;
+        background: url("../static/images/comm/headerBg.png") top center no-repeat;
+        background-size: 100%;
+    }
+
+    /deep/ .mu-appbar-left {
+        padding-top: 15px;
+    }
+
+    /deep/ .material-icons {
+        color: #fff;
+    }
+
+    /deep/ .mu-appbar-title {
+        text-align: center;
+    }
+
+    #pages {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin-top: 0px;
+        padding-bottom: 200px;
+        background: #f2f2f2;
+        overflow-y: scroll;
+    }
+
+    .detail {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        background: #fff;
+        padding-top: 0px;
+        padding-bottom: 20px;
+        padding-left: 2%;
+        padding-right: 2%;
+        margin-bottom: 10px;
+    }
+
+    .detail h5 span {
+        font-size: 16px;
+    }
+
+    .detail h5 em {
+        float: right;
+        color: #666666;
+        font-size: 12px;
+        font-weight: normal;
+        text-align: right;
+    }
+
+    .detail p {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        font-size: 12px;
+        color: #666666;
+        line-height: 16px;
+    }
+
+    /deep/ .mint-navbar .mint-tab-item.is-selected {
+        border-bottom: 3px solid #FFA200;
+        color: #FFA200;
+    }
+
+    /deep/ .mint-navbar .mint-tab-item.is-selected .mint-tab-item-label {
+        color: #FFA200;
+    }
+
+    .listContainer ul {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        margin-top: 10px;
+
+    }
+
+    .listContainer li {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        margin-bottom: 2px;
+        padding: 10px 20px;
+        background: #fff;
+    }
+
+    .listContainer li h5 {
+        font-size: 14px;
+        margin: 10px 0;
+    }
+
+    .listContainer li span {
+        width: 80%;
+        float: left;
+        font-size: 12px;
+        color: #606060;
+        line-height: 20px;
+    }
+
+    .listContainer li img {
+        width: 8px;
+        height: 14px;
+        float: right;
+    }
+</style>

+ 706 - 0
app/src/page/record.vue

@@ -0,0 +1,706 @@
+<template>
+    <div id="pages">
+        <mu-appbar style="width: 100%;" color="primary" :title="$t('Detection record')">
+            <router-link to="/" slot="left">
+                <mu-icon value="arrow_back"></mu-icon>
+            </router-link>
+            <mu-button flat color="primary" slot="right" @click="showPanel">{{btnText}}</mu-button>
+        </mu-appbar>
+        <mu-bottom-sheet :open.sync="popupVisible">
+            <div class="modal-content">
+                <div class="modal-body">
+                    <div class="location">
+                        <span>{{$t("query criteria")}}</span>
+                        <cityPicker></cityPicker>
+                        <select name="" id="unite" v-model="unite" @change="ChangeGetRegionlistByUnitId()">
+                            <option :value="uniteOption.Id" v-for="uniteOption in uniteOptions" :key="uniteOption.Id">
+                                {{uniteOption.Name}}
+                            </option>
+                        </select>
+                        <select name="" id="area" v-model="area" @change="ChangegetDetectorByRegionId()">
+                            <option :value="areaOption.Id" v-for="areaOption in areaOptions" :key="areaOption.Id">
+                                {{areaOption.Name}}
+                            </option>
+                        </select>
+                        <select name="" id="detector" v-model="detector">
+                            <option :value="detectorOption.Id" v-for="detectorOption in detectorOptions"
+                                    :key="detectorOption.Id">{{detectorOption.Name}}
+                            </option>
+                        </select>
+                        <input type="text" placeholder="MAC" v-model="MAC" id="macInput">
+                        <div class="timePickerPart">
+                            <span @click="changeTime(1)">{{bt}}</span> <em>{{$t("to")}}</em>
+                            <span @click="changeTime(2)">{{et}}</span>
+                        </div>
+                        <div v-show="open">
+                            <mu-flex justify-content="between" align-items="end" wrap="wrap">
+                                <mu-paper :z-depth="1" class="demo-date-picker">
+                                    <mu-date-picker :date.sync="date" color="#FFA200" :date-time-format="enDateFormat"
+                                                    @change="confirmDay"></mu-date-picker>
+                                </mu-paper>
+                            </mu-flex>
+                        </div>
+                    </div>
+                </div>
+                <div class="modalBottom">
+                    <div class="reset" @click="resetModal">
+                        {{$t("Reset")}}
+                    </div>
+                    <div class="pullUp" @click="searchModal">
+                        {{$t("query")}}
+                    </div>
+                </div>
+            </div>
+        </mu-bottom-sheet>
+        <div class="container">
+            <div class="row">
+                <mu-tabs :value.sync="active" inverse color="warning" full-width>
+                    <mu-tab>{{$t("wireless device")}}</mu-tab>
+                    <mu-tab>{{$t("phone signal")}}</mu-tab>
+                </mu-tabs>
+                <ul class="deteUl" v-if="active == 0"
+
+                >
+                    <li v-if="!lists.length.length">
+                        <h4>{{$t("no use data")}}</h4>
+                    </li>
+                    <li v-for="list in lists"
+                        v-if="lists"
+                    >
+                        <div class="rowTop"><h5>{{list.Name}}</h5>
+                            <span v-if="list.DangerLevel == -1" class="green">{{$t("other")}}</span>
+                            <span v-if="list.DangerLevel == 0" class="green">{{$t("white")}}</span>
+                            <span v-if="list.DangerLevel == 2" class="yellow">{{$t("deal")}}</span>
+                            <span v-if="list.DangerLevel == 3" class="red">{{$t("warning")}}</span>
+                            <span v-if="list.DangerLevel == 4" class="red">{{$t("danger")}}</span>
+                        </div>
+                        <div class="rowDetail">
+                            <span>{{list.CreateTime | timeFileter}}</span>
+                            <s>{{list.Mac}}</s>
+                        </div>
+                        <div class="rowBottom">
+                            {{list.Memo}}
+                        </div>
+                    </li>
+                    <s class="tips" v-if="lists"> {{$t("total")}} {{lists.length}} {{$t("item")}} {{$t("Record")}}</s>
+                    <s class="tips" v-if="lists.length > 100">  {{$t("Please go to the webpage for more records")}}</s>
+                </ul>
+                <ul class="phoneUl" v-if="active == 1">
+                    <li v-if="!phones.length">
+                        <h4>{{$t("no use data")}}</h4>
+                    </li>
+                    <li v-for="phone in phones" v-if="phones">
+                        <div class="peTop">
+                            {{phone.DetectorName}} <span>{{phone.RegionName}}</span>
+                        </div>
+                        <div class="peMemo">
+                            {{phone.Signalstr == ''?$t('No mobile signal detected'):phone.Signalstr}}
+                        </div>
+                    </li>
+                    <s class="tips" v-if="phones"> {{$t("total")}}{{phones.length}}{{$t("item")}} {{$t("Record")}}</s>
+                    <s class="tips" v-if="phones.length > 100">  {{$t("Please go to the webpage for more records")}}</s>
+                </ul>
+            </div>
+        </div>
+    </div>
+</template>
+
+<script>
+    import axios from 'axios';
+
+    let qs = require('qs');
+    import Global from '../Global.js'
+    import cityPicker from '../components/cityPicker'
+
+    const enDateFormat = {
+        formatDisplay (date) {
+            return `${dayList[date.getDay()]}, ${monthList[date.getMonth()]} ${date.getDate()}`;
+        },
+        formatMonth (date) {
+            return `${monthLongList[date.getMonth()]} ${date.getFullYear()}`;
+        },
+        getWeekDayArray (firstDayOfWeek) {
+            let beforeArray = [];
+            let afterArray = [];
+            for (let i = 0; i < dayAbbreviation.length; i++) {
+                if (i < firstDayOfWeek) {
+                    afterArray.push(dayAbbreviation[i]);
+                } else {
+                    beforeArray.push(dayAbbreviation[i]);
+                }
+            }
+            return beforeArray.concat(afterArray);
+        },
+        getMonthList () {
+            return monthList;
+        }
+    };
+
+    export default {
+        data() {
+            return {
+                enDateFormat,
+                selected: "1",
+                popupVisible: false,//false true
+                unite: '',
+                open: false,
+                area: '',
+                detector: '',
+                MAC: '',
+                selectTime: 0,
+                active: 0,
+                curIndex: 1,
+                curIndex2: 1,
+                loading: false,
+                pickerBtString: globaltime2String(globalBt2()[0]),
+                pickerBt: globalBt2()[0],
+                pickerEtString: globaltime2String(globalBt2()[1]),
+                pickerEt: globalBt2()[1],
+                uniteOptions: [],
+                areaOptions: [],
+                detectorOptions: [],
+                lists: [],
+                phones: [],
+                bt: globaltime2StringNoMin(new Date() - 3 * 24 * 3600 * 1000),
+                et: globaltime2StringNoMin(new Date()),
+                date: new Date(),
+                btnText: this.$t("search"),
+            }
+        },
+        mounted() {
+            // 省市区修改后查企业
+            this.citySearchUnite();
+            this.readList();
+        },
+        filters: {
+            timeFileter: function (time) {
+                return globalfmtDate(time, 10)
+            },
+        },
+        methods: {
+            changeTime(val) {
+                this.open = true;
+                let curVal = val == 1 ? new Date(this.bt) : new Date(this.et);
+                this.selectTime = val;
+                this.date = curVal;
+            },
+            confirmDay(date) {
+                if (this.selectTime == 1) {
+                    this.bt = globaltime2StringNoMin(date);
+                } else {
+                    this.et = globaltime2StringNoMin(date);
+                }
+                this.open = false;
+            },
+            // 重置
+            resetModal() {
+                this.MAC = '';
+                this.ChangeGetRegionlistByUnitId();
+                this.ChangegetDetectorByRegionId();
+                this.bt = globaltime2StringNoMin(new Date() - 3 * 24 * 3600 * 1000);
+                this.et = globaltime2StringNoMin(new Date());
+            },
+            showPanel() {
+                this.popupVisible = true;
+                this.btnText = this.$t("close");
+            },
+            whenClose(){
+                this.popupVisible = false;
+                this.btnText = this.$t("search");
+            },
+            // 查询
+            searchModal() {
+                let that = this;
+                this.popupVisible = false;
+                if (this.selected == 1) {
+                    that.readList();
+                } else {
+                    that.readPhone();
+                }
+                this.Toast(that.$t("Query already"), 'success');
+            },
+            citySearchUnite() {
+                const that = this;
+                let url = headapi + 'v1/Auth/GetComSelect';
+                let param = {
+                    token: localStorage.token,
+                    prov: localStorage.defaultProv,
+                    city: localStorage.defaultCity,
+                    area: localStorage.defaultArea,
+                };
+                let postdata = qs.stringify(param);
+                axios.post(url, postdata).then(function (data) {
+                    let json = data.data;
+                    if (json.Code == 0) {
+                        that.uniteOptions = json.Rs;
+                        if (json.Rs) {
+                            that.unite = that.uniteOptions[0].Id;
+                            that.GetRegionlistByUnitId(that.unite);
+                        }
+                    } else {
+                        that.$message.error(json.memo);
+                    }
+                }, function (response) {
+                    console.info(response);
+                })
+            },
+            GetRegionlistByUnitId(comid) {
+                const that = this;
+                let url = headapi + 'v1/Auth/GetRegionSelect';
+                let param = {
+                    token: localStorage.token,
+                    comid: comid,
+                    regionid: 0,
+                };
+                let postdata = qs.stringify(param);
+                axios.post(url, postdata).then(function (data) {
+
+                    let json = data.data;
+                    if (json.Code == 0) {
+                        that.areaOptions = json.Rs;
+                        if (json.Rs)
+                            that.area = that.areaOptions[0].Id;
+                        that.getDetectorByRegionId(that.area);
+                    } else {
+                        that.$message.error(json.memo);
+                    }
+                }, function (response) {
+                    console.info(response);
+                })
+            },
+            getDetectorByRegionId(regionid) {
+                const that = this;
+                let url = headapi + 'v1/Auth/GetDetectorSelect';
+                let param = {
+                    token: localStorage.token,
+                    regionid: regionid,
+                };
+                let postdata = qs.stringify(param);
+                axios.post(url, postdata).then(function (data) {
+                    let json = data.data;
+                    if (json.Code == 0) {
+                        that.detectorOptions = json.Rs;
+                        if (json.Rs != null) {
+                            that.detector = that.detectorOptions[0].Id;
+                        }
+                    } else {
+                        that.$message.error(json.memo);
+                    }
+                }, function (response) {
+                    console.info(response);
+                })
+            },
+            ChangeGetRegionlistByUnitId() {
+                this.GetRegionlistByUnitId(this.unite);
+            },
+            ChangegetDetectorByRegionId() {
+                this.getDetectorByRegionId(this.area);
+            },
+            // 实时监测无线设备
+            readList() {
+                const that = this;
+                let url = headapi + 'v1/Detector/DetectQueryByDetector';
+                let detectorid = that.detector;
+                // let detectorid = 40;
+                let bt = that.pickerBtString;
+                let et = that.pickerEtString;
+                // let bt = '2019-01-01 00:00:00';
+                // let et = '2020-01-01 00:00:00';
+                if (!detectorid) {
+                    that.Toast(that.$t('Please select a device first'));
+                    return false
+                }
+                let detectedmac = that.MAC;
+                let pageIndex = that.curIndex;
+                let tableMax = 100;
+                let param = {
+                    token: localStorage.token,
+                    detectorid: detectorid,
+                    bt: bt,
+                    et: et,
+                    detectedmac: detectedmac,
+                    start: pageIndex,
+                    tableMax: tableMax
+                };
+                let postdata = qs.stringify(param);
+                axios.post(url, postdata).then(function (data) {
+                    let json = data.data;
+                    that.lists = [];
+                    if (json.Code == 0) {
+                        if (!json.Rs || json.Rs == []) {
+                            that.Toast(that.$t('No records found'));
+                        }
+                        that.lists = json.Rs;
+                        that.curIndex = json.PageCount;
+                    } else {
+                        that.Toast(that.TransMemo(json.Memo));
+                    }
+                }, function (response) {
+                    console.info(response);
+                })
+            },
+            // 手机信号探测记录
+            readPhone() {
+                const that = this;
+                let url = headapi + 'v1/Detector/SignalDetectQueryByDetector';
+                let detectorid = that.detector;
+                if (!detectorid) {
+                    that.Toast(that.$t('Please select a device first'));
+                    return false
+                }
+                // let detectorid = 40;
+                let bt = that.pickerBtString;
+                let et = that.pickerEtString;
+
+                let detectedmac = that.MAC;
+                let pageIndex = that.curIndex2;
+                let tableMax = 100;
+                let param = {
+                    token: localStorage.token,
+                    detectorid: detectorid,
+                    bt: bt,
+                    et: et,
+                    detectedmac: detectedmac,
+                    start: pageIndex,
+                    tableMax: tableMax
+                };
+                let postdata = qs.stringify(param);
+                axios.post(url, postdata).then(function (data) {
+                    let json = data.data;
+                    that.lists = [];
+                    if (json.Code == 0) {
+                        that.phones = json.Rs;
+                        that.curIndex2 = json.PageCount;
+                    } else {
+                        this.Toast(that.TransMemo(json.Memo));
+                    }
+                }, function (response) {
+                    console.info(response);
+                })
+            },
+        },
+        components: {
+            cityPicker
+        }
+    }
+</script>
+
+<style scoped>
+    /*mu-header*/
+    /deep/ .mu-primary-color {
+        line-height: 60px;
+        height: 60px;
+        background: url("../static/images/comm/headerBg.png") top center no-repeat;
+        background-size: 100%;
+    }
+
+    /deep/ .mu-appbar-left {
+        padding-top: 15px;
+    }
+
+    /deep/ .material-icons {
+        color: #fff;
+    }
+
+    /deep/ .mu-appbar-title {
+        text-align: center;
+    }
+
+    #pages {
+        position: absolute;
+        width: 100%;
+        height: 100%;
+        overflow-y: scroll;
+        display: block;
+        margin: 0 auto;
+    }
+
+    /*mu-bottom-sheet*/
+    .mu-bottom-sheet {
+        top: 60px !important;
+        bottom: 410px;
+    }
+
+    .location {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        /*padding-bottom: 40px;*/
+    }
+
+    .location span {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        margin-top: 10px;
+        margin-bottom: 10px;
+    }
+
+    .location input {
+        width: 95px;
+        height: 30px;
+        border: 1px solid #D5D5D5;
+        float: left;
+        text-indent: 10px;
+    }
+
+    .modal-content {
+        width: 100%;
+        display: block;
+        margin: 0 auto;
+        z-index: 99999;
+        overflow: hidden;
+    }
+
+    .modal-body {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        background: #fff;
+        padding-top: 20px;
+        padding-left: 5%;
+        padding-right: 5%;
+        padding-bottom: 40px;
+    }
+
+    .modalBottom {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        background: #fff;
+    }
+
+    .modalBottom .reset {
+        width: 50%;
+        float: left;
+        height: 40px;
+        line-height: 40px;
+        background: #FFF6CF;
+        text-align: center;
+    }
+
+    .modalBottom .pullUp {
+        width: 50%;
+        float: right;
+        height: 40px;
+        line-height: 40px;
+        background: #FFCC00;
+        text-align: center;
+    }
+
+    .location select {
+        width: 95px;
+        height: 30px;
+        border: 1px solid #D5D5D5;
+        float: left;
+        margin-right: 10px;
+        margin-top: 10px;
+        margin-bottom: 10px;
+    }
+
+    .location select#detector {
+        margin-right: 0;
+        float: left;
+    }
+
+    #macInput {
+        width: 200px;
+    }
+
+    .timePickerPart {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+    }
+
+    .timePickerPart em {
+        width: 25px;
+        height: 30px;
+        line-height: 50px;
+        float: left;
+    }
+
+    .timePickerPart span {
+        width: 135px;
+        height: 30px;
+        line-height: 30px;
+        border: 1px solid #D5D5D5;
+        float: left;
+        margin-right: 8px;
+        margin-top: 10px;
+        margin-bottom: 10px;
+        text-align: center;
+    }
+
+    .listContainer ul {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+    }
+
+    .listContainer li {
+        width: 96%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        margin-bottom: 2px;
+        padding: 10px 20px;
+        background: #fff;
+    }
+
+    .listContainer .rowTop {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+    }
+
+    .rowTop .red {
+        color: #FFA200;
+    }
+
+    /*.pages {*/
+    /*width: 100%;*/
+    /*max-height: 600px;*/
+    /*overflow: hidden;*/
+    /*display: block;*/
+    /*margin: 0 auto;*/
+    /*overflow-y: scroll;*/
+    /*}*/
+    .deteUl h5 {
+        margin: 0;
+        float: left;
+        font-size: 16px;
+    }
+
+    .deteUl .rowTop span {
+        float: right;
+        font-size: 14px;
+    }
+
+    .deteUl .rowDetail {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        color: #999999;
+        font-size: 14px;
+        margin-top: 10px;
+        margin-bottom: 10px;
+    }
+
+    .rowDetail span {
+        float: left;
+    }
+
+    .rowDetail s {
+        float: right;
+    }
+
+    .rowBottom {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        font-size: 12px;
+        color: #999999;
+    }
+
+    .tips {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        text-align: center;
+        font-size: 12px;
+        color: #999999;
+        margin-top: 10px;
+    }
+
+    .phoneUl {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+    }
+
+    .phoneUl li {
+        width: 96%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        margin-bottom: 2px;
+        padding: 10px 20px;
+        background: #fff;
+    }
+
+    .phoneUl .peTop {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        font-size: 16px;
+        margin-bottom: 10px;
+    }
+
+    .peTop span {
+        float: right;
+        text-align: right;
+        font-size: 14px;
+    }
+
+    .peMemo {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        font-size: 14px;
+        color: #999999;
+    }
+
+    .deteUl {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+    }
+
+    .deteUl li {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        padding-top: 10px;
+        padding-left: 2%;
+        padding-right: 2%;
+        border-bottom: 1px solid #ccc;
+    }
+
+    .tips {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        font-size: 12px;
+        color: #999999;
+        margin-top: 10px;
+        text-align: center;
+    }
+
+    .mu-warning-text-color {
+        color: #FFA200;
+    }
+
+    /deep/ .mu-tab-link-highlight {
+        background-color: #FFA200 !important;
+    }
+    /deep/ .mu-tab-wrapper {
+        font-size: 16px;
+    }
+</style>

+ 318 - 0
app/src/page/runtime.vue

@@ -0,0 +1,318 @@
+<template>
+    <div id="pages">
+        <appHeader @goNewpage="onGoNewPage" :title="this.pagetitle"></appHeader>
+        <bottomTab :curTab="thisTab"></bottomTab>
+        <div class="container">
+            <div class="row">
+                <mu-tabs :value.sync="active" inverse color="warning" full-width>
+                    <mu-tab>{{$t("wireless device")}}</mu-tab>
+                    <mu-tab> {{$t("phone signal")}}</mu-tab>
+                </mu-tabs>
+                <div class="demo-text" v-if="active === 0">
+                    <ul class="deteUl">
+                        <li v-if="!lists">
+                            <h4>{{$t("no use data")}}</h4>
+                        </li>
+                        <transition-group name="fade">
+                            <li v-for="(list,i) in lists" v-if="lists"  v-bind:key="i">
+                                <div class="lt">
+                                    <div class="rowTop">
+                                        <h5>{{list.DetectorLocation}}</h5>
+                                        <span v-if="list.DangerLevel == -1" class="green">{{$t("other")}}</span>
+                                        <span v-if="list.DangerLevel == 0" class="green">{{$t("white")}}</span>
+                                        <span v-if="list.DangerLevel == 2" class="yellow">{{$t("deal")}}</span>
+                                        <span v-if="list.DangerLevel == 3" class="red">{{$t("warning")}}</span>
+                                        <span v-if="list.DangerLevel == 4" class="red">{{$t("danger")}}</span>
+                                    </div>
+                                    <div class="rowDetail">
+                                        <span>{{list.MacCom.length > 16 ? list.MacCom.slice(0, 16)+'...':list.MacCom}}</span>
+                                        <span class="pull-right">{{list.Mac}}</span>
+                                    </div>
+                                </div>
+                            </li>
+                        </transition-group>
+                        <s class="tips" v-if="lists"> {{$t("total")}}{{lists.length}}{{$t("item")}} {{$t("Record")}}</s>
+                    </ul>
+                </div>
+                <div class="demo-text" v-if="active === 1">
+                    <ul class="deteUl">
+                        <li v-if="!phones">
+                            <h4>{{$t("no use data")}}</h4>
+                        </li>
+                        <li v-for="phone in phones" v-if="phones">
+                            <div class="lt">
+                                <div class="rowTop">
+                                    <h5>{{phone.DetectorName}}</h5>
+                                    <span>{{phone.RegionName | filterContent}}</span>
+                                </div>
+                                <div class="rowDetail">
+                                    <span>{{phone.ComName}}</span>
+                                    <s :class="{'red':phone.Signalstr != ''}">{{phone.Signalstr | filterSignalstr}}</s>
+                                </div>
+                            </div>
+                        </li>
+                        <s class="tips" v-if="phones"> {{$t("total")}}{{phones.length}}{{$t("item")}}
+                            {{$t("Record")}}</s>
+                    </ul>
+                </div>
+            </div>
+        </div>
+    </div>
+</template>
+
+<script>
+    import appHeader from '../components/appHeader'
+    import bottomTab from '../components/bottomTab'
+    import axios from 'axios';
+
+    let qs = require('qs');
+    import Global from '../Global.js'
+
+    export default {
+        data() {
+            return {
+                pagetitle: this.$t('Real-time'),
+                thisTab: this.$t('Real-time'),
+                active: 0,
+                loading: true,
+                lists: [],
+                phones: [],
+            }
+        },
+        mounted() {
+            this.readList();
+            this.readPhone();
+        },
+        filters: {
+            filterContent: function (value) {
+                if (value == '' || value == undefined) {
+                    return '-'
+                } else {
+                    return value
+                }
+            },
+            filterSignalstr: function (value) {
+                switch (value) {
+                    case "":
+                        return '未检测到';
+                        break;
+                    default:
+                        return value;
+                        break;
+                }
+            }
+        },
+        watch: {
+            active(val) {
+                let that = this;
+                console.log(val);
+                if (val == 1) {
+                    that.readList();
+                } else {
+                    that.readPhone();
+                }
+            }
+        },
+        methods: {
+            onGoNewPage(path) {
+                this.$router.push({path: '/' + path});
+            },
+            // 实时监测无线设备
+            readList() {
+                const that = this;
+                let url = headapi + 'v1/Detector/DetectedMacs';
+                // let url = headapi + 'v1/Detector/DetectedMacsTest';//test
+                let param = {
+                    token: localStorage.token,
+                };
+                this.lists = [];
+                let postdata = qs.stringify(param);
+                axios.post(url, postdata).then(function (data) {
+                    let json = data.data;
+                    if (json.Code == 0) {
+                        that.lists = json.Rs;
+                    } else {
+                        that.Toast(that.TransMemo(json.Memo));
+                    }
+                }, function (response) {
+                    console.info(response);
+                })
+            },
+            readPhone() {
+                const that = this;
+                let url = headapi + 'v1/Detector/SignalDeviceList';
+                let pageIndex = 1;
+                let tableMax = 100;
+                let param = {
+                    token: localStorage.token,
+                    pageIndex: pageIndex,
+                    tableMax: tableMax
+                };
+                let postdata = qs.stringify(param);
+                axios.post(url, postdata).then(function (data) {
+                    let json = data.data;
+                    if (json.Code == 0) {
+                        that.phones = json.Rs;
+                    } else {
+                        that.Toast(that.TransMemo(json.Memo));
+                    }
+                }, function (response) {
+                    console.info(response);
+                })
+            },
+        },
+        components: {
+            appHeader, bottomTab
+        }
+    }
+</script>
+
+<style scoped>
+    .mu-warning-text-color {
+        color: #FFA200;
+    }
+
+    /deep/ .mu-tab-link-highlight {
+        background-color: #FFA200 !important;
+    }
+
+    /deep/ .mu-tab {
+        width: 50%;
+    }
+
+    #pages {
+        width: 100%;
+        height: 100%;
+        overflow: hidden;
+        display: block;
+        margin-top: 0px;
+        padding-bottom: 20px;
+        background: #f2f2f2;
+        overflow-y: scroll;
+    }
+
+    .demo-text {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+    }
+
+    .demo-text ul {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        border-top: 2px solid #f2f2f2;
+    }
+
+    .demo-text li {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        padding: 10px 20px;
+        background: #fff;
+        border-bottom: 2px solid #f2f2f2;
+    }
+
+    .deteUl h5 {
+        margin: 0;
+        float: left;
+        font-size: 16px;
+    }
+
+    .deteUl .rowTop span {
+        float: right;
+        font-size: 14px;
+    }
+
+    .deteUl .rowDetail {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        color: #999999;
+        font-size: 14px;
+    }
+
+    .rowDetail span {
+        float: left;
+    }
+
+    .rowDetail s {
+        float: right;
+    }
+
+    .rowBottom {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        font-size: 12px;
+        color: #999999;
+    }
+
+    .tips {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        text-align: center;
+        font-size: 12px;
+        color: #999999;
+        margin-top: 10px;
+    }
+
+    .deteUl img {
+        width: 8px;
+        height: 14px;
+        margin-top: 20px;
+        float: right;
+    }
+
+    .deteUl .lt {
+        width: 100%;
+        float: left;
+    }
+
+    .deteUl .rt {
+        float: right;
+    }
+
+    .row .pull-right {
+        float: right;
+        text-align: right;
+    }
+
+    .deteUl h4 {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        text-align: center;
+        font-weight: normal;
+    }
+
+    .rowDetail s {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        text-align: left;
+    }
+
+    .red {
+        color: red;
+    }
+    .green {
+        color: yellowgreen;
+    }
+    .yellow {
+        color: rgb(255, 162, 0);
+    }
+
+    /deep/ .mu-tab-wrapper {
+        font-size: 16px;
+    }
+</style>

+ 148 - 0
app/src/page/setting.vue

@@ -0,0 +1,148 @@
+<template>
+    <div id="pages">
+        <mu-appbar style="width: 100%;" color="primary" :title="$t('System setup')">
+            <router-link to="/" slot="left">
+                <mu-icon value="arrow_back"></mu-icon>
+            </router-link>
+        </mu-appbar>
+        <div class="">
+            <div class="row">
+                <mu-list>
+                    <mu-list-item button :ripple="false">
+                        <mu-list-item-title>{{$t("Alarm sound")}}</mu-list-item-title>
+                        <mu-list-item-action>
+                            <mu-switch v-model="voiceState"></mu-switch>
+                        </mu-list-item-action>
+                    </mu-list-item>
+                    <mu-divider></mu-divider>
+                    <mu-list-item button :ripple="false">
+                        <mu-list-item-title>{{$t("Alarm flicker")}}</mu-list-item-title>
+                        <mu-list-item-action>
+                            <mu-switch v-model="alertState"></mu-switch>
+                        </mu-list-item-action>
+                    </mu-list-item>
+                    <div class="grip"></div>
+                    <mu-list-item button :ripple="false" @click="openAlertDialog">
+                        <mu-list-item-title>{{$t("Quit landing")}}</mu-list-item-title>
+                    </mu-list-item>
+                </mu-list>
+            </div>
+        </div>
+        <mu-dialog width="600" max-width="80%" :esc-press-close="false"
+                   :overlay-close="false" :open.sync="openAlert">
+            {{$t("Confirm to exit the current account")}}?
+            <mu-button slot="actions" flat color="info" @click="closeAlertDialog">{{$t("cancel")}}</mu-button>
+            <mu-button slot="actions" flat color="warning" @click="logout">{{$t("confirm")}}</mu-button>
+        </mu-dialog>
+    </div>
+</template>
+
+<script>
+    import axios from 'axios';
+
+    let qs = require('qs');
+    import Global from '../Global.js'
+
+    export default {
+        data() {
+            return {
+                lists: [],
+                voiceState: false,
+                alertState: false,
+                openAlert: false
+            }
+        },
+        mounted() {
+            localStorage.voiceState = localStorage.voiceState || false;
+            localStorage.alertState = localStorage.alertState || false;
+            this.voiceState = JSON.parse(localStorage.voiceState);
+            this.alertState = JSON.parse(localStorage.alertState);
+        },
+        watch: {
+            voiceState: function (val) {
+                localStorage.voiceState = val;
+            },
+            alertState: function (val) {
+                localStorage.alertState = val;
+            },
+        },
+        methods: {
+            openAlertDialog() {
+                this.openAlert = true;
+            },
+            closeAlertDialog() {
+                this.openAlert = false;
+            },
+            // 退出
+            logout() {
+                this.openAlert = false;
+                const that = this;
+                localStorage.token = '';
+                that.$router.push({path: '/login'});
+            },
+        },
+    }
+</script>
+
+<style scoped>
+    #pages {
+        width: 100%;
+        top: 0;
+        bottom: 0;
+        height: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        background: #f2f2f2;
+    }
+
+    /*mu-header*/
+    .mu-primary-color {
+        line-height: 60px;
+        height: 60px;
+        background: url("../static/images/comm/headerBg.png") top center no-repeat;
+        background-size: 100%;
+    }
+
+    /deep/ .mu-appbar-left {
+        padding-top: 15px;
+    }
+
+    /deep/ .material-icons {
+        color: #fff;
+    }
+
+    /deep/ .mu-appbar-title {
+        text-align: center;
+    }
+
+    .mu-button {
+        display: block;
+        margin: 0 auto;
+    }
+
+    .row {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+    }
+
+    .mu-switch-checked {
+        color: #FFCC00;
+    }
+
+    .grip {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        height: 10px;
+    }
+
+    /deep/ .mu-item-wrapper {
+        background: #fff;
+        font-size: 16px;
+        color: #000;
+    }
+</style>

+ 50 - 0
app/src/page/statis.vue

@@ -0,0 +1,50 @@
+<template>
+    <div>
+        <appHeader @goNewpage="onGoNewPage" :title="this.pagetitle"></appHeader>
+        <div class="container">
+            <div class="row">
+                <statischart></statischart>
+            </div>
+        </div>
+    </div>
+</template>
+
+<script>
+    import appHeader from '../components/appHeader'
+    import axios from 'axios';
+    let qs = require('qs');
+    import Global from '../Global.js'
+    import statischart from '../components/statischart'
+    export default {
+        data() {
+            return {
+                pagetitle:this.$t('Statistical report forms'),
+                lists: []
+            }
+        },
+        mounted() {
+        },
+        methods: {
+            onGoNewPage(path) {
+                this.$router.push({path: '/' + path});
+            },
+        },
+        components: {
+            statischart,appHeader
+        }
+    }
+</script>
+
+<style scoped>
+    .container {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+    }
+    /deep/ #statischart {
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+    }
+</style>

+ 157 - 0
app/src/page/userDetail.vue

@@ -0,0 +1,157 @@
+<template>
+    <div>
+        <mu-appbar style="width: 100%;" color="primary" :title="$t('User details')">
+            <router-link to="/usermanage" slot="left">
+                <mu-icon value="arrow_back"></mu-icon>
+            </router-link>
+        </mu-appbar>
+        <div class="container">
+            <div class="row">
+                <h5>{{detail.Name}}</h5>
+                <ul>
+                    <li><em>{{$t("usercode")}}:</em><span>{{detail.Usercode}}</span></li>
+                    <li><em>Email:</em><span>{{detail.Email | filterContent}}</span></li>
+                    <li><em>{{$t("phone")}}:</em><span>{{detail.Phone}}</span></li>
+                    <!--<li><em>{{$t("state")}}:</em><span>{{detail.Status | typeFileter}}</span></li>-->
+                    <li><em>{{$t("state")}}:</em><span>{{Status}}</span></li>
+                    <li><em>{{$t("User roles")}}:</em><span>{{detail.Rolesname | filterContent}}</span></li>
+                    <li><em>{{$t("memo")}}:</em><span>{{detail.Memo | filterContent}}</span></li>
+                </ul>
+            </div>
+        </div>
+    </div>
+</template>
+
+<script>
+    import axios from 'axios';
+
+    let qs = require('qs');
+    import Global from '../Global.js'
+
+    export default {
+        data() {
+            return {
+                detail: {}
+            }
+        },
+        mounted() {
+            this.writeData();
+        },
+        methods: {
+            writeData() {
+                let content = this.$route.query.detector;
+                this.detail = JSON.parse(content);
+                console.log(this.detail);
+            }
+        },
+        computed:{
+            Status() {
+                switch (this.detail.Status) {
+                    case 1:
+                        return this.$t('disabled');
+                        break;
+                    default:
+                        return this.$t('Enabled');
+                        break;
+                }
+            },
+        },
+        filters: {
+            typeFileter: function (value) {
+                switch (parseInt(value)) {
+                    case 1:
+                        return '已禁用';
+                        break;
+                    default:
+                        return '已启用';
+                        break;
+                }
+            },
+            filterContent: function (value) {
+                if (value == '' || value == undefined) {
+                    return '-'
+                } else {
+                    return value
+                }
+            },
+        }
+    }
+</script>
+
+<style scoped>
+    /*mu-header*/
+    /deep/ .mu-primary-color {
+        line-height: 60px;
+        height: 60px;
+        background: url("../static/images/comm/headerBg.png") top center no-repeat;
+        background-size: 100%;
+    }
+
+    /deep/ .mu-appbar-left {
+        padding-top: 15px;
+    }
+
+    /deep/ .material-icons {
+        color: #fff;
+    }
+
+    /deep/ .mu-appbar-title {
+        text-align: center;
+    }
+
+    #pages {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin-top: 0px;
+        padding-bottom: 200px;
+        background: #f2f2f2;
+    }
+
+    .row {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        background: #fff;
+    }
+
+    .row h5 {
+        width: 80%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        text-align: center;
+        font-size: 20px;
+        color: #FFA200;
+        padding: 20px;
+        border-bottom: 1px solid rgba(112, 112, 112, 0.14);
+        margin-bottom: 20px;
+    }
+
+    .row ul {
+        width: 80%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        margin-top: 10px;
+    }
+
+    .row li {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        margin-bottom: 10px;
+        font-size: 16px;
+    }
+
+    .row li em {
+        float: left;
+        min-width: 80px;
+    }
+
+    .row li span {
+        color: #6E6E6E;
+    }
+</style>

+ 212 - 0
app/src/page/usermanage.vue

@@ -0,0 +1,212 @@
+<template>
+    <div id="pages">
+        <appHeader @goNewpage="onGoNewPage" :title="this.pagetitle"></appHeader>
+        <div class="listContainer">
+            <ul class="deteUl">
+                <li v-if="!lists.length">
+                    <h4>{{$t("no use data")}}</h4>
+                </li>
+                <transition-group name="fade">
+                <li v-for="list in stus" v-if="lists" @click="goPage(list)" v-bind:key="list.Id">
+                    <div class="lt">
+                        <div class="rowTop">
+                            <h5>{{list.Name}}</h5>
+                            <!--<span>{{list.Status | typeFileter}}</span>-->
+                            <span>{{list.stusType}}</span>
+                        </div>
+                        <div class="rowDetail">
+                            <span>{{list.Rolesname}}</span>
+                            <span class="pull-right">{{list.Insname | filterContent}}</span>
+                        </div>
+                    </div>
+                    <div class="rt">
+                         <mu-icon value="keyboard_arrow_right"></mu-icon>
+                    </div>
+                </li>
+                </transition-group>
+                <div class="tips" v-if="lists">{{$t("total")}} {{lists.length}} {{$t("enterprise")}}</div>
+            </ul>
+        </div>
+    </div>
+</template>
+
+<script>
+    import appHeader from '../components/appHeader'
+    import axios from 'axios';
+    let qs = require('qs');
+    import Global from '../Global.js'
+    export default {
+        data() {
+            return {
+                pagetitle:this.$t('user management'),
+                lists: []
+            }
+        },
+        mounted() {
+            this.writeData();
+        },
+        computed:{
+            stus(){
+                let that = this;
+                let text = '';
+                /*es6写法 防止用不了this.type*/
+                return this.lists.filter((v)=>{
+                    console.log(v.Status);
+                    switch (parseInt(v.Status)) {
+                        case 1:
+                            text = that.$t('disabled');
+                            break;
+                        default:
+                            text = that.$t('Enabled');
+                            break;
+                    }
+                    return v.stusType = text;
+                })
+            }
+        },
+        methods: {
+            onGoNewPage(path) {
+                this.$router.push({path: '/' + path});
+            },
+            goPage(list) {
+                this.$router.push({path: '/userDetail', query: {detector: JSON.stringify(list)}});
+            },
+            writeData() {
+                const that = this;
+                let url = headapi + 'v1/User/UserListInfo';
+                let pageIndex = 1;
+                let tableMax = 100;
+                let param = {
+                    token: localStorage.token,
+                    usertype: '0',
+                    searchs: '',
+                    pageIndex: pageIndex,
+                    tableMax: tableMax
+                };
+                let postdata = qs.stringify(param);
+                axios.post(url, postdata).then(function (data) {
+                    let json = data.data;
+                    if (json.Code == 0) {
+                        that.lists = json.Rs;
+                    } else {
+                        that.Toast(that.TransMemo(json.Memo));
+                    }
+                }, function (response) {
+                    console.info(response);
+                })
+            }
+        },
+        filters: {
+            typeFileter: function (value) {
+                switch (parseInt(value)) {
+                    case 1:
+                        return '已禁用';
+                        break;
+                    default:
+                        return '已启用';
+                        break;
+                }
+            },
+            filterContent: function (value) {
+                if (value == '' || value == undefined) {
+                    return '-'
+                } else {
+                    return value
+                }
+            },
+        },
+        components: {
+            appHeader
+        }
+    }
+</script>
+
+<style scoped>
+    #pages {
+        width: 100%;
+        height: 100%;
+        overflow: hidden;
+        display: block;
+        margin-top: 0px;
+        padding-bottom: 20px;
+        background: #f2f2f2;
+        overflow-y: scroll;
+    }
+
+    .listContainer ul {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+    }
+
+    .listContainer li {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        margin-bottom: 2px;
+        padding: 10px 20px;
+        background: #fff;
+    }
+
+    .listContainer .rowTop {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+    }
+
+    .rowTop .red {
+        color: #FFA200;
+    }
+
+    .listContainer h5 {
+        margin: 0;
+        float: left;
+        font-size: 16px;
+    }
+
+    .listContainer .rowTop span {
+        float: right;
+        font-size: 14px;
+    }
+
+    .listContainer .rowDetail {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        color: #999999;
+        font-size: 14px;
+        margin-top: 10px;
+        margin-bottom: 10px;
+    }
+
+    .deteUl .lt {
+        width: 88%;
+        float: left;
+    }
+
+    .deteUl .rt {
+        float: right;
+    }
+
+    .rt i {
+        margin-top: 20px;
+    }
+    .pull-right {
+        float: right;
+        text-align: right;
+    }
+    .tips {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        text-align: center;
+        font-size: 12px;
+        color: #999999;
+        margin-top: 20px;
+    }
+</style>

+ 360 - 0
app/src/page/white.vue

@@ -0,0 +1,360 @@
+<template>
+    <div id="pages">
+        <mu-appbar style="width: 100%;" color="primary" :title="curTitle">
+            <router-link to="/" slot="left">
+                <mu-icon value="arrow_back"></mu-icon>
+            </router-link>
+            <mu-button flat color="primary" slot="right" @click="showPanel">{{btnText}}</mu-button>
+        </mu-appbar>
+        <mu-bottom-sheet :open.sync="popupVisible">
+            <div class="modal-content">
+                <div class="modal-body">
+                    <div class="location">
+                        <span>{{$t("query criteria")}}</span>
+                        <div class="timePickerPart">
+                            <span @click="changeTime(1)">{{bt}}</span> <em>{{$t("to")}}</em>
+                            <span @click="changeTime(2)">{{et}}</span>
+                        </div>
+                        <div v-show="open">
+                            <mu-flex justify-content="between" align-items="end" wrap="wrap">
+                                <mu-paper :z-depth="1" class="demo-date-picker">
+                                    <mu-date-picker :date.sync="date" color="#FFA200" :date-time-format="enDateFormat"
+                                                    @change="confirmDay"></mu-date-picker>
+                                </mu-paper>
+                            </mu-flex>
+                        </div>
+                        <input type="text" placeholder="MAC" v-model="MAC" id="macInput">
+                        <input type="text" :placeholder="$t('keyword')" v-model="keyWord" id="keyWordInput">
+                    </div>
+                </div>
+                <div class="modalBottom">
+                    <div class="reset" @click="resetModal">
+                        {{$t("Reset")}}
+                    </div>
+                    <div class="pullUp" @click="searchModal">
+                        {{$t("query")}}
+                    </div>
+                </div>
+            </div>
+        </mu-bottom-sheet>
+        <div class="container">
+            <div class="row">
+                <p class="tips" v-if="!lists">{{$t("no use data")}}</p>
+                <mu-list textline="two-line" v-for="list in lists" :key="list.Id">
+                    <mu-list-item avatar :ripple="false" button>
+                        <mu-list-item-content>
+                            <mu-list-item-title>{{list.Name}}</mu-list-item-title>
+                            <mu-list-item-sub-title>{{list.Mac}}</mu-list-item-sub-title>
+                            <mu-list-item-sub-title>{{list.Memo}}</mu-list-item-sub-title>
+                        </mu-list-item-content>
+                        <mu-list-item-action>
+                            <mu-list-item-after-text>{{list.CreateTime | timeFileter}}</mu-list-item-after-text>
+                            <mu-list-item-after-text>{{list.Regionname}}</mu-list-item-after-text>
+                            <mu-list-item-after-text>{{$t("operator")}}: {{list.Usercode}}</mu-list-item-after-text>
+                        </mu-list-item-action>
+                    </mu-list-item>
+                    <mu-divider></mu-divider>
+                </mu-list>
+            </div>
+        </div>
+    </div>
+</template>
+
+<script>
+    import axios from 'axios';
+
+    let qs = require('qs');
+    import Global from '../Global.js'
+    const enDateFormat = {
+        formatDisplay (date) {
+            return `${dayList[date.getDay()]}, ${monthList[date.getMonth()]} ${date.getDate()}`;
+        },
+        formatMonth (date) {
+            return `${monthLongList[date.getMonth()]} ${date.getFullYear()}`;
+        },
+        getWeekDayArray (firstDayOfWeek) {
+            let beforeArray = [];
+            let afterArray = [];
+            for (let i = 0; i < dayAbbreviation.length; i++) {
+                if (i < firstDayOfWeek) {
+                    afterArray.push(dayAbbreviation[i]);
+                } else {
+                    beforeArray.push(dayAbbreviation[i]);
+                }
+            }
+            return beforeArray.concat(afterArray);
+        },
+        getMonthList () {
+            return monthList;
+        }
+    };
+    export default {
+        data() {
+            return {
+                enDateFormat,
+                curTitle:this.$t("whiteList"),
+                lists: [],
+                popupVisible:false,//true false
+                open:false,//true false
+                MAC:'',//
+                keyWord:'',//
+                bt: globaltime2StringNoMin(new Date() - 3 * 24 * 3600 * 1000),
+                et: globaltime2StringNoMin(new Date()),
+                date: new Date(),
+                btnText: this.$t("search"),
+            }
+        },
+        mounted() {
+            this.writeData();
+        },
+        filters: {
+            timeFileter: function (time) {
+                return globalfmtDate(time, 10)
+            },
+        },
+        methods: {
+            changeTime(val) {
+                this.open = true;
+                let curVal = val == 1 ? new Date(this.bt) : new Date(this.et);
+                this.selectTime = val;
+                this.date = curVal;
+            },
+            showPanel() {
+                this.popupVisible = true;
+                this.btnText = this.$t("close");
+            },
+            whenClose(){
+                this.popupVisible = false;
+                this.btnText = this.$t("search");
+            },
+            confirmDay(date) {
+                if (this.selectTime == 1) {
+                    this.bt = globaltime2StringNoMin(date);
+                } else {
+                    this.et = globaltime2StringNoMin(date);
+                }
+                this.open = false;
+            },
+            // 重置
+            resetModal() {
+                this.MAC = '';
+                this.keyWord = '';
+                this.bt = globaltime2StringNoMin(new Date() - 3 * 24 * 3600 * 1000);
+                this.et = globaltime2StringNoMin(new Date());
+                this.Toast('已重置','success');
+            },
+            // 查询
+            searchModal() {
+                let that = this;
+                this.popupVisible = false;
+                this.writeData();
+                this.Toast('已查询','success');
+            },
+            writeData() {
+                const that = this;
+                let url = headapi + 'v1/Detector/WhiteListQuery';
+                let param = {
+                    token: localStorage.token,
+                    detectedmac:that.MAC,
+                    keywords:that.keyWord,
+                    bt:that.bt + ' 00:00:00',
+                    et:that.et + ' 23:59:59',
+                };
+                let postdata = qs.stringify(param);
+                axios.post(url, postdata).then(function (data) {
+                    let json = data.data;
+                    if (json.Code == 0) {
+                        that.lists = json.Rs;
+                    } else {
+                        that.Toast(that.TransMemo(json.Memo));
+                    }
+                }, function (response) {
+                    console.info(response);
+                })
+            }
+        },
+    }
+</script>
+
+<style scoped>
+    /*mu-header*/
+    .mu-primary-color {
+        line-height: 60px;
+        height: 60px;
+        background: url("../static/images/comm/headerBg.png") top center no-repeat;
+        background-size: 100%;
+    }
+
+    /deep/ .mu-appbar-left {
+        padding-top: 15px;
+    }
+
+    /deep/ .material-icons {
+        color: #fff;
+    }
+
+    /deep/ .mu-appbar-title {
+        text-align: center;
+    }
+    #pages {
+        position: absolute;
+        top: 0;
+        bottom: 0;
+        width: 100%;
+        height: 100%;
+        overflow: hidden;
+        overflow-y: scroll;
+        display: block;
+        margin: 0 auto;
+    }
+    .modal-content {
+        width: 100%;
+        display: block;
+        margin: 0 auto;
+        z-index: 99999;
+        overflow: hidden;
+    }
+
+    /*mu-bottom-sheet*/
+    .mu-bottom-sheet {
+        top: 60px !important;
+        bottom: 410px;
+        background: none;
+    }
+
+    .location {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+    }
+
+    .location span {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        margin-top: 10px;
+        margin-bottom: 10px;
+    }
+
+    .location input {
+        width: 95px;
+        height: 30px;
+        border: 1px solid #D5D5D5;
+        float: left;
+        text-indent: 10px;
+    }
+
+    .modal-body {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        background: #fff;
+        padding-top: 20px;
+        padding-left: 5%;
+        padding-right: 5%;
+        padding-bottom: 20px;
+    }
+
+    .modalBottom {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        background: #fff;
+    }
+
+    .modalBottom .reset {
+        width: 50%;
+        float: left;
+        height: 40px;
+        line-height: 40px;
+        background: #FFF6CF;
+        text-align: center;
+    }
+
+    .modalBottom .pullUp {
+        width: 50%;
+        float: right;
+        height: 40px;
+        line-height: 40px;
+        background: #FFCC00;
+        text-align: center;
+    }
+
+    .location select {
+        width: 95px;
+        height: 30px;
+        border: 1px solid #D5D5D5;
+        float: left;
+        margin-right: 10px;
+        margin-top: 10px;
+        margin-bottom: 10px;
+    }
+
+    .location select#detector {
+        margin-right: 0;
+        float: left;
+    }
+
+    #macInput {
+        width: 200px;
+        margin-bottom: 10px;
+    }
+    #keyWordInput {
+        width: 200px;
+    }
+
+    .timePickerPart {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+    }
+
+    .timePickerPart em {
+        width: 25px;
+        height: 30px;
+        line-height: 50px;
+        float: left;
+    }
+
+    .timePickerPart span {
+        width: 135px;
+        height: 30px;
+        line-height: 30px;
+        border: 1px solid #D5D5D5;
+        float: left;
+        margin-right: 8px;
+        margin-top: 10px;
+        margin-bottom: 10px;
+        text-align: center;
+    }
+    .demo-date-picker {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        border: none;
+        box-shadow: none;
+    }
+    .mu-datepicker {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+    }
+    .mu-list {
+        background: #fff;
+    }
+    .tips {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        text-align: center;
+        margin-top: 20px;
+    }
+</style>

+ 0 - 152
app/src/pages/basic.vue

@@ -1,152 +0,0 @@
-<template>
-    <div id="pages">
-        <mt-header title="基本资料">
-            <router-link to="/setting" slot="left">
-               <
-            </router-link>
-        </mt-header>
-        <div class="container">
-            <mt-field label="姓名" placeholder="请输入姓名" v-model="username"></mt-field>
-            <mt-field label="企业" placeholder="请输入企业名称" v-model="company"></mt-field>
-            <mt-button type="default" @click.naive="confirm">确 认</mt-button>
-        </div>
-    </div>
-</template>
-
-<script>
-    import axios from 'axios';
-    import {Field} from 'mint-ui';
-    import {Button} from 'mint-ui';
-    import {Toast} from 'mint-ui';
-    import Vue from 'vue';
-
-    let qs = require('qs');
-    import Global from '../Global.js'
-
-    Vue.component(Field.name, Field);
-    Vue.component(Button.name, Button);
-
-    export default {
-        data() {
-            return {
-                username: '',
-                company: '',
-            }
-        },
-        created() {
-            this.userInfo();
-        },
-        mounted() {
-            this.userInfo();
-        },
-        methods: {
-            userInfo() {
-                const that = this;
-                let url = headapi + '?ctl=ajax&mod=xxx&act=xxx';
-                let param = {};
-                let postdata = qs.stringify(param);
-                axios.post(url, postdata).then(function (data) {
-                    let json = data.data;
-                    if (json.code == 0) {
-                        that.username = json.username;
-                        that.company = json.compname;
-                    } else {
-                        that.$message.error(json.memo);
-                    }
-                }, function (response) {
-                    console.info(response);
-                })
-            },
-            confirm() {
-                let username = this.username;
-                let company = this.company;
-                if (!username) {
-                    Toast('姓名不能为空');
-                    return false
-                }
-                if (username.length > 20) {
-                    Toast('姓名最长20个字符');
-                    return false
-                }
-                if (!company) {
-                    Toast('公司名不能为空');
-                    return false
-                }
-                if (company.length > 40) {
-                    Toast('公司名最长40个字符');
-                    return false
-                }
-                const that = this;
-                let url = headapi + '?ctl=ajax&mod=xxx&act=xxx';
-                let param = {
-                    NAME: username,
-                    COMPNAME: company,
-                };
-                let postdata = qs.stringify(param);
-                axios.post(url, postdata).then(function (data) {
-                    let json = data.data;
-                    if (json.code == 0) {
-                        Toast('基本资料修改/添加'+json.memo);
-                    } else {
-                        Toast(json.memo);
-                    }
-                }, function (response) {
-                    console.info(response);
-                })
-            }
-        },
-        components: {}
-    }
-</script>
-
-<!-- Add "scoped" attribute to limit CSS to this component only -->
-<style scoped>
-    @import "../assets/css/comm.css";
-
-    #pages {
-        background: #EBEBEB;
-    }
-
-    .container {
-        width: 100%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-        margin-top: 10px;
-    }
-
-    /deep/ .mint-cell {
-        margin-bottom: 1px;
-    }
-
-    .gary {
-        width: 100%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-        height: 10px;
-    }
-
-    /deep/ .mint-cell-title {
-        color: #454545;
-        font-size: 16px;
-    }
-
-    /deep/ .mint-cell-value span {
-        font-size: 14px;
-        color: #454545;
-    }
-
-    /deep/ .mint-button--default {
-        width: 92%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-        height: 46px;
-        text-align: center;
-        font-size: 16px;
-        color: #333333;
-        margin-top: 20px;
-        border-radius: 6px;
-    }
-</style>

+ 0 - 67
app/src/pages/category.vue

@@ -1,67 +0,0 @@
-<template>
-    <div id="pages">
-       <div class="lt">
-           <ul>
-               <li v-for="n in 17">
-                   text
-               </li>
-           </ul>
-       </div>
-       <div class="rt"></div>
-    </div>
-</template>
-
-<script>
-    import axios from 'axios';
-    let qs = require('qs');
-    import Global from '../Global.js'
-export default {
-    data () {
-    return {
-      msg: 'Welcome to Your Vue.js App'
-    }
-    },
-    mounted() {
-
-    },
-    methods: {
-
-    },
-    components: {
-
-    }
-}
-</script>
-
-<!-- Add "scoped" attribute to limit CSS to this component only -->
-<style scoped>
-    @import "../assets/css/comm.css";
-    .lt {
-        width: 87px;
-        height: 100%;
-        overflow: hidden;
-        float: left;
-    }
-    .lt ul {
-        position: absolute;
-        top: 0;
-        bottom: 0;
-        height: 100%;
-        width: 85px;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-        overflow-y: scroll;
-        padding-bottom: 20px;
-    }
-    .lt li {
-        width: 100%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-        height: 45px;
-        line-height: 45px;
-        text-align: center;
-    }
-
-</style>

+ 0 - 39
app/src/pages/chart.vue

@@ -1,39 +0,0 @@
-<template>
-    <div id="pages">
-        <mt-header title="标题过长会隐藏后面的内容啊哈哈哈哈">
-            <router-link to="/detail" slot="left">
-                <mt-button icon="back">返回</mt-button>
-            </router-link>
-            <mt-button icon="more" slot="right"></mt-button>
-        </mt-header>
-
-        {{msg}}
-    </div>
-</template>
-
-<script>
-    import axios from 'axios';
-    let qs = require('qs');
-    import Global from '../Global.js'
-export default {
-    data () {
-    return {
-      msg: 'Welcome to Your Vue.js App'
-    }
-    },
-    mounted() {
-
-    },
-    methods: {
-
-    },
-    components: {
-
-    }
-}
-</script>
-
-<!-- Add "scoped" attribute to limit CSS to this component only -->
-<style scoped>
-    @import "../assets/css/comm.css";
-</style>

+ 0 - 77
app/src/pages/detail.vue

@@ -1,77 +0,0 @@
-<template>
-    <div id="pages">
-        <mt-header title="标题过长会隐藏后面的内容啊哈哈哈哈">
-            <router-link to="/" slot="left">
-                <mt-button icon="back">返回</mt-button>
-            </router-link>
-            <mt-button icon="more" slot="right"></mt-button>
-        </mt-header>
-        <div class="content">
-            <mt-picker :slots="slots" @change="onValuesChange" v-model="dataVal"></mt-picker>
-        </div>
-        
-        <h5>
-            {{ dataVal }}
-        </h5>
-
-        <router-link to="/chart" >
-            <mt-button type="primary">click me </mt-button>
-        </router-link>
-    </div>
-</template>
-
-<script>
-    import axios from 'axios';
-    import Global from '../Global.js'
-    import { Header } from 'mint-ui';
-    let qs = require('qs');
-    import { Picker } from 'mint-ui';
-    import Vue from 'vue'
-    import { mapState, mapActions } from 'vuex'
-    Vue.component(Header.name, Header);
-    Vue.component(Picker.name, Picker);
-export default {
-    data () {
-    return {
-        dataVal:'01',
-        slots: [
-            {
-                flex: 1,
-                values: ['01', '02', '03', '04', '05', '06'],
-                className: 'slot1',
-                textAlign: 'center'
-            },
-        ]
-    }
-    },
-    mounted() {
-
-    },
-    methods: {
-        onValuesChange(picker, values) {
-           console.log(values);
-           this.dataVal = values[0];
-        },
-    },
-    computed: {
-        ...mapState(['car'])
-    },
-    components: {
-
-    }
-}
-</script>
-
-<!-- Add "scoped" attribute to limit CSS to this component only -->
-<style scoped>
-    @import "../assets/css/comm.css";
-    h5 {
-        width: 100%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-        text-align: center;
-        font-size: 24px;
-        margin-top: 20px;
-    }
-</style>

+ 0 - 92
app/src/pages/index.vue

@@ -1,92 +0,0 @@
-<template>
-    <div id="pages">
-        <transition :name="transitionName">
-            <keep-alive>
-                <router-view></router-view>
-            </keep-alive>
-        </transition>
-        <mt-tabbar v-model="selected" @click="mt_tab(selected)">
-            <mt-tab-item id="main">
-                <img slot="icon" src="../assets/images/100x100.png">
-                首页
-            </mt-tab-item>
-            <mt-tab-item id="order">
-                <img slot="icon" src="../assets/images/100x100.png">
-                订单
-            </mt-tab-item>
-            <mt-tab-item id="mine">
-                <img slot="icon" src="../assets/images/100x100.png">
-                我的
-            </mt-tab-item>
-        </mt-tabbar>
-    </div>
-</template>
-
-<script>
-    import axios from 'axios';
-
-    let qs = require('qs');
-    import Global from '../Global.js'
-
-    export default {
-        data() {
-            return {
-                selected: 'main',
-                transitionName:''
-            }
-        },
-        mounted() {
-
-        },
-        watch: {
-            selected: function (val, oldVal) {
-                // 这里就可以通过 val 的值变更来确定
-                this.$router.push({path: '/' + val});
-            },
-            $route(to, from) {
-                //如果to索引大于from索引,判断为前进状态,反之则为后退状态
-                if(to.meta.index > from.meta.index){
-                    //设置动画名称
-                    this.transitionName = 'slide-left';
-                }else{
-                    this.transitionName = 'slide-right';
-                }
-            }
-        },
-        components: {}
-    }
-</script>
-
-<!-- Add "scoped" attribute to limit CSS to this component only -->
-<style scoped>
-    @import "../assets/css/comm.css";
-
-    .mint-tabbar a {
-        width: 33%;
-        float: left;
-    }
-    .slide-right-enter-active,
-    .slide-right-leave-active,
-    .slide-left-enter-active,
-    .slide-left-leave-active {
-        will-change: transform;
-        transition: all 500ms;
-        position: absolute;
-    }
-    .slide-right-enter {
-        opacity: 0;
-        transform: translate3d(-100%, 0, 0);
-    }
-    .slide-right-leave-active {
-        opacity: 0;
-        transform: translate3d(100%, 0, 0);
-    }
-    .slide-left-enter {
-        opacity: 0;
-        transform: translate3d(100%, 0, 0);
-    }
-    .slide-left-leave-active {
-        opacity: 0;
-        transform: translate3d(-100%, 0, 0);
-    }
-</style>

+ 0 - 132
app/src/pages/main.vue

@@ -1,132 +0,0 @@
-<template>
-    <div id="pages">
-        <mt-swipe :auto="4000" :show-indicators="true">
-            <mt-swipe-item>
-                <div class="silder silder1"></div>
-            </mt-swipe-item>
-            <mt-swipe-item>
-                <div class="silder silder2"></div>
-            </mt-swipe-item>
-            <mt-swipe-item>
-                <div class="silder silder3"></div>
-            </mt-swipe-item>
-        </mt-swipe>
-        <div class="main_banner">
-            <div class="silder silder4"></div>
-        </div>
-        <div class="icon_list">
-            <ul>
-                <li v-for="icon in icons">
-                    <router-link :to="{path: '/detail', query: {icon: icon.href}}" >
-                        <img  :src="imgsrc + icon.img"  alt="">
-                        <em>{{icon.name}}</em>
-                    </router-link>
-                </li>
-            </ul>
-        </div>
-    </div>
-</template>
-
-<script>
-    import axios from 'axios';
-    let qs = require('qs');
-    import Global from '../Global.js'
-    import { Swipe, SwipeItem } from 'mint-ui';
-    import Vue from 'vue'
-    Vue.component(Swipe.name, Swipe);
-    Vue.component(SwipeItem.name, SwipeItem);
-export default {
-    data () {
-    return {
-        imgsrc:'../static/images/',
-        icons:[
-            {name:'划算1',href:'/detail',img:'icon.png'},
-            {name:'划算2',href:'/detail',img:'icon.png'},
-            {name:'划算3',href:'/detail',img:'icon.png'},
-            {name:'划算4',href:'/detail',img:'icon.png'},
-            {name:'划算5',href:'/detail',img:'icon.png'},
-            {name:'划算6',href:'/detail',img:'icon.png'},
-            {name:'划算7',href:'/detail',img:'icon.png'},
-            {name:'划算8',href:'/detail',img:'icon.png'},
-        ],
-    }
-    },
-    mounted() {
-
-    },
-    methods: {
-
-    },
-    components: {
-
-    }
-}
-</script>
-
-<!-- Add "scoped" attribute to limit CSS to this component only -->
-<style scoped>
-    @import "../assets/css/comm.css";
-    #pages {
-        padding-bottom: 20px;
-    }
-    .silder{
-        width: 100%;
-        height: 220px;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-    }
-    .silder1 {
-        background: red;
-    }
-    .silder2 {
-        background: green;
-    }
-    .silder3 {
-        background: deepskyblue;
-    }
-    .silder4 {
-        background: yellow;
-    }
-    /deep/ .mint-swipe {
-        height: 230px;
-        overflow: hidden;
-    }
-    .main_banner {
-        width: 100%;
-        height: 100px;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-    }
-    .icon_list {
-        width: 100%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-        margin-top: 10px;
-    }
-    .icon_list li {
-        width: 25%;
-        float: left;
-        padding: 0;
-        margin: 0;
-        margin-bottom: 10px;
-        list-style: none;
-    }
-    .icon_list li a {
-        width: 100%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-        text-align: center;
-        color: #000;
-    }
-    .icon_list a img {
-        width: 61px;
-        height: 48px;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;;
-    }
-</style>

+ 0 - 138
app/src/pages/mine.vue

@@ -1,138 +0,0 @@
-<template>
-    <div id="pages">
-        <div class="head">
-            <div class="user">
-                <img  :src="imgsrc + user.head" alt="head">
-                <h5>{{ user.name }}</h5>
-                <s class="subtitle">我的个人信息修改</s>
-            </div>
-            <div class="info">
-                <ul>
-                    <li>
-                        <span>123</span>
-                        <em>收藏夹</em>
-                    </li>
-                    <li>
-                        <span>123</span>
-                        <em>收藏夹</em>
-                    </li>
-                    <li>
-                        <span>123</span>
-                        <em>收藏夹</em>
-                    </li>
-                </ul>
-            </div>
-        </div>
-        <div class="list" v-for="n in 3">
-            <mt-cell
-                    title="标题文字"
-                    to="//github.com"
-                    is-link
-                    value="带链接">
-            </mt-cell>
-        </div>
-        <div class="test">
-            <router-link :to="{path: '/category'}" >分类列表</router-link>
-        </div>
-    </div>
-</template>
-
-<script>
-    import axios from 'axios';
-    let qs = require('qs');
-    import Global from '../Global.js'
-    import Vue from 'vue'
-    import { Cell } from 'mint-ui';
-
-    Vue.component(Cell.name, Cell);
-export default {
-    data () {
-    return {
-        imgsrc:'../static/images/',
-        user:{
-            head:'icon.png',
-            name:'mefisto',
-        },
-    }
-    },
-    mounted() {
-
-    },
-    methods: {
-
-    },
-    components: {
-
-    }
-}
-</script>
-
-<!-- Add "scoped" attribute to limit CSS to this component only -->
-<style scoped>
-    @import "../assets/css/comm.css";
-    .head {
-        width: 100%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-        min-height: 140px;
-        padding-top: 10px;
-        padding-bottom: 10px;
-        background: #FF5000;
-    }
-    .head .user {
-        width: 100%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-        padding-left: 2%;
-        padding-right: 2%;
-        padding-top: 20px;
-        margin-bottom: 10px;
-    }
-    .head .user img {
-        width: 49px;
-        float: left;
-    }
-    .head .user h5 {
-        float: left;
-        font-weight: normal;
-        font-size: 24px;
-        color: #fff;
-        margin: 0;
-    }
-    .head .user .subtitle {
-        width: 80%;
-        font-size: 12px;
-        color: #fff;
-        float: left;
-    }
-    .info {
-        width: 100%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-    }
-    .info ul {
-        width: 100%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-        padding-left: 2%;
-        padding-right: 2%;
-    }
-    .info li {
-        height: 60px;
-        width: 33%;
-        float: left;
-        color: #fff;
-        font-size: 12px;
-        text-align: center;
-    }
-    .info li span {
-        width: 100%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-    }
-</style>

+ 0 - 36
app/src/pages/model.vue

@@ -1,36 +0,0 @@
-<template>
-    <div id="pages">
-        <div class="container">
-            <div class="row">
-
-            </div>
-        </div>
-    </div>
-</template>
-
-<script>
-    import axios from 'axios';
-    let qs = require('qs');
-    import Global from '../Global.js'
-export default {
-    data () {
-    return {
-      msg: 'Welcome to Your Vue.js App'
-    }
-    },
-    mounted() {
-
-    },
-    methods: {
-
-    },
-    components: {
-
-    }
-}
-</script>
-
-<!-- Add "scoped" attribute to limit CSS to this component only -->
-<style scoped>
-    @import "../assets/css/comm.css";
-</style>

+ 0 - 366
app/src/pages/news.vue

@@ -1,366 +0,0 @@
-<template>
-    <div id="pages">
-        <div class="container" v-if="detail == false">
-            <mt-header title="系统消息">
-                    <div slot="left" @click="back">
-                       <
-                    </div>
-            </mt-header>
-            <ul class="results">
-                <li v-for="n in news" @click="seeDeatil(n)">
-                    <i v-if="n.msgstatus == 1"></i>
-                    <s v-else></s>
-                    <div class="lt">
-                        <h5>{{n.title}}</h5>
-                        <span>{{n.sndtime}}</span>
-                    </div>
-                   >
-                </li>
-            </ul>
-        </div>
-        <div class="detail" v-if="detail == true">
-            <mt-header title="系统消息">
-                <div class="mint-header-button is-left" slot="left" @click="goback">
-                   <
-                </div>
-            </mt-header>
-            <em class="times">{{detailInfo.times}}</em>
-            <div class="detail_card">
-                <span>{{detailInfo.times}}</span>
-                <em>{{detailInfo.title}}</em>
-                <p>{{detailInfo.content}}</p>
-                <!--监管邀请7-->
-                <div class="control" v-if="detailInfo.type == 7">
-                    <button id="ageree" @click="monitorResponse(2)">加入</button>
-                    <button id="refuse"  @click="monitorResponse(1)">拒绝</button>
-                </div>
-            </div>
-        </div>
-    </div>
-</template>
-
-<script>
-    import axios from 'axios';
-    import {Button} from 'mint-ui';
-    import Vue from 'vue';
-    import {Toast} from 'mint-ui';
-    import { Indicator } from 'mint-ui';
-    let qs = require('qs');
-    import Global from '../Global.js'
-
-    Vue.component(Button.name, Button);
-
-    export default {
-        data() {
-            return {
-                detail: false,
-                username: '',
-                company: '',
-                news: [],
-                detailInfo: {
-                    times: '',
-                    title: '',
-                    content: '',
-                    snduserid: '',
-                    type: ''
-                },
-            }
-        },
-        mounted() {
-            this.sysMsgListQuery();
-        },
-        methods: {
-            goback(){
-                this.sysMsgListQuery();
-                this.detail = false;
-            },
-            // 获取列表
-            sysMsgListQuery() {
-                const that = this;
-                let url = headapi + '?ctl=xxx&mod=xxxx&act=xxx';
-                let param = {};
-                let postdata = qs.stringify(param);
-                axios.post(url, postdata).then(function (data) {
-                    let json = data.data;
-                    if (json.code == 0) {
-                        that.news = json.rs;
-                    } else {
-                        Toast(json.memo);
-                    }
-                }, function (response) {
-                    console.info(response);
-                })
-            },
-            // 查看详情
-            seeDeatil(row) {
-                Indicator.open();
-                this.detailInfo.times = 'xxxxx';
-                this.detailInfo.tittle = 'xxxxx';
-                this.detailInfo.type = 'xxxxx';
-                this.detailInfo.snduserid = 'xxxxxx';
-                this.detailInfo.content = 'xxxxxx';
-                this.detail = true;
-                this.sysMsgDetail(row.msgid);
-            },
-            sysMsgDetail(msgid){
-                const that = this;
-                let url = headapi + '?ctl=xxx&mod=xxxx&act=xxx';
-                let param = {
-                    MSGID:msgid
-                };
-                let postdata = qs.stringify(param);
-                axios.post(url, postdata).then(function(data){
-                    let json = data.data;
-                    Indicator.close();
-                    if(json.code == 0){
-                        let row = json.rs[0];
-                        that.detailInfo.times = row.sndtime;
-                        that.detailInfo.tittle = row.tittle;
-                        that.detailInfo.type = row.msgtype;
-                        that.detailInfo.snduserid = row.snduserid;
-                        that.detailInfo.content = row.msg;
-                    }else{
-                        Toast(json.memo);
-                    }
-                },function(response){
-                    console.info(response);
-                })
-            },
-            // 监管接收邀请
-            monitorResponse(status){
-                const that = this;
-                let url = headapi + '?ctl=xxx&mod=xxxx&act=xxx';
-                let param = {
-                    LEADERID:this.detailInfo.snduserid,
-                    STATUS:status,
-                };
-                let postdata = qs.stringify(param);
-                axios.post(url, postdata).then(function(data){
-                    let json = data.data;
-                    if(json.code == 0){
-                        Toast(json.memo);
-                    }else{
-                        Toast(json.memo);
-                    }
-                },function(response){
-                    console.info(response);
-                })
-            },
-            back() {
-                this.$router.go(-1);
-            },
-        },
-        components: {}
-    }
-</script>
-
-<!-- Add "scoped" attribute to limit CSS to this component only -->
-<style scoped>
-    @import "../assets/css/comm.css";
-
-    #pages {
-        background: #EBEBEB;
-        overflow-y: scroll;
-    }
-
-    .container {
-        width: 100%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-        margin-top: 0px;
-        padding-bottom: 70px;
-    }
-
-    /deep/ .mint-cell {
-        margin-bottom: 1px;
-    }
-
-    .gary {
-        width: 100%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-        height: 10px;
-    }
-
-    /deep/ .mint-cell-title {
-        color: #454545;
-        font-size: 16px;
-    }
-
-    /deep/ .mint-cell-value span {
-        font-size: 14px;
-        color: #454545;
-    }
-
-    /deep/ .mint-button--default {
-        width: 92%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-        height: 46px;
-        text-align: center;
-        font-size: 16px;
-        color: #fff;
-        margin-top: 20px;
-        border-radius: 6px;
-        background: #FFD579;
-    }
-
-    .results {
-        width: 100%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-    }
-
-    .results ul {
-        width: 100%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-        padding-bottom: 20px;
-    }
-
-    .results li {
-        width: 92%;
-        padding-left: 4%;
-        padding-right: 4%;
-        background: #fff;
-        height: 60px;
-        line-height: 60px;
-        margin-top: 10px;
-    }
-
-    .results i {
-        width: 8px;
-        height: 8px;
-        float: left;
-        border-radius: 250px;
-        margin-top: 26px;
-        background: #03B1FF;
-        margin-right: 8px;
-    }
-
-    .results s {
-        width: 8px;
-        height: 8px;
-        float: left;
-        border-radius: 250px;
-        margin-top: 26px;
-        background: #ccc;
-        margin-right: 8px;
-    }
-
-    li .arr {
-        width: 6px;
-        float: right;
-        margin-top: 30px;
-        margin-right: 4%;
-        margin-left: 10px;
-    }
-
-    li .lt {
-        width: 80%;
-        height: 60px;
-        overflow: hidden;
-        float: left;
-    }
-
-    li .lt h5 {
-        margin: 0;
-        height: 40px;
-        font-weight: normal;
-        line-height: 40px;
-        color: #454545;
-        font-size: 14px;
-    }
-
-    li .lt span {
-        height: 20px;
-        float: left;
-        color: #777777;
-        font-size: 12px;
-        line-height: 10px;
-    }
-
-    .detail {
-        width: 100%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-    }
-
-    .times {
-        width: 100%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-        font-size: 12px;
-        text-align: center;
-        margin-bottom: 8px;
-        margin-top: 9px;
-        color: #777777;
-    }
-
-    .detail_card {
-        width: 92%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-        border-radius: 6px;
-        background: #fff;
-        padding: 10px;
-        box-shadow: 0 3px 6px rgba(0, 0, 0, 0.07);
-    }
-
-    .detail_card span {
-        width: 100%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-        color: #777777;
-        font-size: 14px;
-        margin-bottom: 9px;
-    }
-
-    .detail_card em {
-        color: #333333;
-        margin-bottom: 11px;
-        font-size: 14px;
-    }
-
-    .detail_card p {
-        font-size: 14px;
-        color: #777777;
-    }
-
-    .control {
-        width: 100%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-    }
-
-    .control button {
-        float: right;
-        width: 67px;
-        height: 30px;
-        font-size: 14px;
-        color: #fff;
-        border: none;
-        text-align: center;
-        line-height: 30px;
-        border-radius: 2px;
-        margin-left: 15px;
-    }
-
-    #refuse {
-        background: #FFBB3B;
-    }
-
-    #ageree {
-        background: #4CD964;
-    }
-</style>

+ 0 - 53
app/src/pages/order.vue

@@ -1,53 +0,0 @@
-<template>
-    <div id="pages">
-        <mt-navbar v-model="selected">
-            <mt-tab-item id="1">选项一</mt-tab-item>
-            <mt-tab-item id="2">选项二</mt-tab-item>
-            <mt-tab-item id="3">选项三</mt-tab-item>
-        </mt-navbar>
-        <!-- tab-container -->
-        <mt-tab-container v-model="selected">
-            <mt-tab-container-item id="1">
-                <mt-cell v-for="n in 10" :title="'内容 ' + n" />
-            </mt-tab-container-item>
-            <mt-tab-container-item id="2">
-                <mt-cell v-for="n in 4" :title="'测试 ' + n" />
-            </mt-tab-container-item>
-            <mt-tab-container-item id="3">
-                <mt-cell v-for="n in 6" :title="'选项 ' + n" />
-            </mt-tab-container-item>
-        </mt-tab-container>
-    </div>
-</template>
-
-<script>
-    import axios from 'axios';
-    let qs = require('qs');
-    import Global from '../Global.js'
-    import Vue from 'vue'
-    import { Navbar, TabItem } from 'mint-ui';
-
-    Vue.component(Navbar.name, Navbar);
-    Vue.component(TabItem.name, TabItem);
-export default {
-    data () {
-    return {
-        selected:'1',
-    }
-    },
-    mounted() {
-
-    },
-    methods: {
-
-    },
-    components: {
-
-    }
-}
-</script>
-
-<!-- Add "scoped" attribute to limit CSS to this component only -->
-<style scoped>
-    @import "../assets/css/comm.css";
-</style>

+ 0 - 304
app/src/pages/phone.vue

@@ -1,304 +0,0 @@
-<template>
-    <div id="pages">
-        <mt-header title="更换手机号">
-            <router-link to="/setting" slot="left">
-               <
-            </router-link>
-        </mt-header>
-        <div class="container" v-if="step == 1">
-            <!--<mt-field placeholder="图形验证" v-model="img_valid1">-->
-                <!--<img :src="valImgSrc" @click="changeValImg" height="23" width="55">-->
-            <!--</mt-field>-->
-            <mt-field placeholder="验证码" v-model="valid1">
-                <mt-button type="primary"
-                           class="valid_btn"
-                           :disabled ="button_state"
-                           @click.native="getChangeCode">{{ valid_btn }}</mt-button>
-            </mt-field>
-            <mt-button type="default" @click.native="step_confirm">下一步</mt-button>
-        </div>
-        <div  class="container" v-if="step == 2">
-            <mt-field label="新手机号" placeholder="请输入新手机号" v-model="news"></mt-field>
-            <mt-field placeholder="图形验证" v-model="img_valid2">
-                <img :src="valImgSrc" @click="changeValImg" height="23" width="55">
-            </mt-field>
-            <mt-field placeholder="验证码" v-model="valid2">
-                <mt-button type="primary"
-                           class="valid_btn"
-                           :disabled ="button_state"
-                           @click.native="get_phone_valid(news,img_valid2,4)">{{ valid_btn }}</mt-button>
-            </mt-field>
-            <mt-button type="default" @click.native="editContact">确认更换</mt-button>
-        </div>
-
-    </div>
-</template>
-
-<script>
-    import axios from 'axios';
-    import { Field } from 'mint-ui';
-    import { Button } from 'mint-ui';
-    import Vue from 'vue';
-    import { Toast } from 'mint-ui';
-    let qs = require('qs');
-    import Global from '../Global.js'
-    Vue.component(Field.name, Field);
-    Vue.component(Button.name, Button);
-
-    export default {
-        data() {
-            return {
-                step:1,
-                old: '',
-                news: '',
-                valid1: '',
-                valid2: '',
-                img_valid1: '',
-                img_valid2: '',
-                ckcode: '',
-                valImgSrc: headapi + 'mod/index/login_validcode.php',//测试用路径
-                button_state:false,
-                valid_btn:'获取验证码',
-            }
-        },
-        mounted() {
-
-        },
-        methods: {
-            // 点击验证码切换
-            changeValImg () {
-                let that = this;
-                that.valImgSrc = that.valImgSrc + '?' + Math.random();
-            },
-            // 获取更改联系方式验证码
-            getChangeCode(){
-                const that = this;
-                let url = headapi + '?ctl=ajax&mod=xxx&act=xxx';
-                let param = {
-                    TYPE:2
-                };
-                let postdata = qs.stringify(param);
-                that.button_state = true;
-                axios.post(url, postdata).then(function(data){
-                    let json = data.data;
-                    if(json.code == 0){
-                        let countdown = 60;
-                        that.valid_btn = countdown + "秒";
-                        let timer = setInterval(() => {
-                            if (countdown == 0) {
-                                clearInterval(timer);//停止计时器
-                                that.valid_btn = "重新发送";
-                                that.button_state = false;
-                            } else {
-                                countdown--;
-                                that.valid_btn = countdown + "秒";
-                                that.button_state = true
-                            }
-                        }, 1000);
-                        Toast('短信已发送,请注意查收');
-                    }else{
-                        Toast(json.memo);
-                    }
-                },function(response){
-                    console.info(response);
-                })
-            },
-            // 获取验证码
-            get_phone_valid (usercode,this_valid,type) {
-                let img_valid = this_valid;
-                let tel = usercode;
-                let that = this;
-                if (!tel) {
-                    Toast('手机号码不能为空');
-                    return false
-                }
-                if(tel.length != 11){
-                    Toast('手机号长度不正确');
-                    return false
-                }
-                if (!img_valid) {
-                    Toast('图形验证码不能为空');
-                    return false
-                }
-                if (img_valid.length != 4) {
-                    Toast('图形验证码位数不正确');
-                    return false
-                }
-                let url = headapi + '?ctl=ajax&mod=xxx&act=xxx';
-                let param = {
-                    NAME: tel,
-                    VALID: img_valid,
-                    TYPE: type,//(2)(1:注册,2:充值,3:登陆)
-                };
-                that.button_state = true;
-                let postdata = qs.stringify(param);
-                axios.post(url, postdata).then(function (data) {
-                    let json = data.data;
-                    let code = json.code;
-                    if (code == 0) {
-                        let countdown = 60;
-                        that.valid_btn = countdown + "秒";
-                        let timer = setInterval(() => {
-                            if (countdown == 0) {
-                                clearInterval(timer);//停止计时器
-                                that.valid_btn = "重新发送";
-                                that.button_state = false;
-                            } else {
-                                countdown--;
-                                that.valid_btn = countdown + "秒";
-                                that.button_state = true
-                            }
-                        }, 1000);
-                        Toast('短信已发送,请注意查收');
-                    } else {
-                        that.button_state = false;
-                        Toast(json.memo);
-                    }
-                }, function (response) {
-                    console.info(response);
-                })
-            },
-            // 校验原联系方式验证码
-            checkChangeCode(){
-                const that = this;
-                let url = headapi + '?ctl=ajax&mod=xxx&act=xxx';
-                if(!that.valid1){
-                    Toast('验证码不应为空');
-                    return false
-                }
-                if (that.valid1.length != 6) {
-                    Toast('验证码位数不正确');
-                    return false
-                }
-                let param = {
-                    TYPE:2, //1 mail 2 tel
-                    CODE: that.valid1
-                };
-                let postdata = qs.stringify(param);
-                axios.post(url, postdata).then(function(data){
-                    let json = data.data;
-                    if(json.code == 0){
-                        that.step = 2;//进入下一页
-                        that.changeValImg();//重置图形验证码
-                        that.ckcode = json.rs;
-                    }else{
-                         Toast(json.memo);
-                    }
-                },function(response){
-                    console.info(response);
-                })
-            },
-            // 下一步
-            step_confirm(){
-                this.valid_btn = "获取验证码";
-                this.button_state = false;
-                this.checkChangeCode();
-            },
-            // 用户修改联系方式
-            editContact(){
-                const that = this;
-                let url = headapi + '?ctl=ajax&mod=xxx&act=xxx';
-                let param = {
-                    CKCODE:that.ckcode,
-                    // CKCODE:999999,
-                    CODE:that.valid2
-                };
-                if(!that.valid2){
-                    Toast('验证码不应为空');
-                    return false
-                }
-                if (that.valid2.length != 6) {
-                    Toast('验证码位数不正确');
-                    return false
-                }
-                let postdata = qs.stringify(param);
-                axios.post(url, postdata).then(function(data){
-                    let json = data.data;
-                    if(json.code == 0){
-                        Toast('更换手机号'+json.memo);
-                    }else{
-                         Toast(json.memo);
-                    }
-                },function(response){
-                    console.info(response);
-                })
-            },
-        },
-        components: {}
-    }
-</script>
-
-<!-- Add "scoped" attribute to limit CSS to this component only -->
-<style scoped>
-    @import "../assets/css/comm.css";
-    #pages {
-        background: #EBEBEB;
-    }
-    .container {
-        width: 100%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-        margin-top: 10px;
-    }
-    /deep/ .mint-cell {
-        margin-bottom: 1px;
-    }
-    .gary {
-        width: 100%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-        height: 10px;
-    }
-    /deep/ .mint-cell-title {
-        color: #454545;
-        font-size: 16px;
-    }
-    /deep/ .mint-cell-value span {
-        font-size: 14px;
-        color: #454545;
-    }
-    /deep/ .mint-button--default {
-        width: 92%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-        height: 46px;
-        text-align: center;
-        font-size: 16px;
-        color: #333333;
-        margin-top: 20px;
-        border-radius: 6px;
-    }
-    #valid_btn1 {
-        width: 117px;
-        position: relative;
-        right: -10px;
-        height: 100%;
-        margin: 0;
-        text-align: center;
-        color: #fff;
-        background: #00C143;
-        border: 0;
-        height: 48px;
-    }
-    #valid_btn2 {
-        width: 117px;
-        position: relative;
-        right: -10px;
-        height: 100%;
-        margin: 0;
-        text-align: center;
-        color: #fff;
-        background: #00C143;
-        border: 0;
-        height: 48px;
-    }
-    /deep/ .mint-field-other button {
-        border-radius: 0;
-        color: #fff;
-        background: #00C143;
-        font-size: 14px;
-    }
-</style>

+ 0 - 154
app/src/pages/pwd.vue

@@ -1,154 +0,0 @@
-<template>
-    <div id="pages">
-        <mt-header title="修改密码">
-            <router-link to="/setting" slot="left">
-                <!--<img src="../../static/images/comm/arrow-left.png" alt="" class="arr_left">-->
-            </router-link>
-        </mt-header>
-        <div class="container">
-            <mt-field label="原密码" placeholder="请输入原密码" v-model="old" type="password"></mt-field>
-            <mt-field label="密码" placeholder="请输入密码" v-model="pwd" type="password"></mt-field>
-            <mt-field label="密码确认" placeholder="请再次输入密码" v-model="again" type="password"></mt-field>
-            <mt-button type="default" @click.naive="editPassword">确  认</mt-button>
-        </div>
-    </div>
-</template>
-
-<script>
-    import axios from 'axios';
-    import { Field } from 'mint-ui';
-    import { Button } from 'mint-ui';
-    import Vue from 'vue';
-    let qs = require('qs');
-    import { Toast } from 'mint-ui';
-    import Global from '../Global.js'
-    Vue.component(Field.name, Field);
-    Vue.component(Button.name, Button);
-
-    export default {
-        data() {
-            return {
-                valid: '',
-                old: '',
-                pwd: '',
-                again: '',
-            }
-        },
-        mounted() {
-
-        },
-        methods: {
-            editPassword(){
-                const that = this;
-                if(!this.old){
-                    Toast('密码不能为空');
-                    return false
-                }
-                if(this.old.length >= 20 || this.old.length < 6){
-                    Toast('密码长度不应小于6位切不大于20位');
-                    return false
-                }
-                if(!this.pwd){
-                    Toast('新密码不能为空');
-                    return false
-                }
-                if(this.pwd.length >= 20 || this.pwd.length < 6){
-                    Toast('新密码长度不应小于6位切不大于20位');
-                    return false
-                }
-                if(this.pwd != this.again){
-                    Toast('新密码与确认密码不一致');
-                    return false
-                }
-                let url = headapi + 'editPassword';
-                let param = {
-                    OLD:this.old,
-                    NEW:this.pwd,
-                };
-                let postdata = qs.stringify(param);
-                axios.post(url, postdata).then(function(data){
-                    let json = data.data;
-                    if(json.code == 0){
-                        that.old = '';
-                        that.pwd = '';
-                        that.again = '';
-                        Toast('修改密码'+json.memo);
-                        that.$router.push({
-                            name:'setting',
-                        });
-                    }else{
-                        Toast(json.memo);
-                    }
-                },function(response){
-                    console.info(response);
-                })
-            }
-        },
-        components: {}
-    }
-</script>
-
-<!-- Add "scoped" attribute to limit CSS to this component only -->
-<style scoped>
-    @import "../assets/css/comm.css";
-    #pages {
-        background: #EBEBEB;
-    }
-    .container {
-        width: 100%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-        margin-top: 10px;
-    }
-    /deep/ .mint-cell {
-        margin-bottom: 1px;
-    }
-    .gary {
-        width: 100%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-        height: 10px;
-    }
-    /deep/ .mint-cell-title {
-        color: #454545;
-        font-size: 16px;
-    }
-    /deep/ .mint-cell-value span {
-        font-size: 14px;
-        color: #454545;
-    }
-    /deep/ .mint-cell-text {
-        font-size: 14px;
-        color: #454545;
-    }
-    /deep/ .mint-field-core::placeholder {
-        color: #DDDDDD;
-        font-size: 14px;
-    }
-    #valid_btn {
-        width: 117px;
-        position: relative;
-        right: -10px;
-        height: 100%;
-        margin: 0;
-        text-align: center;
-        color: #fff;
-        background: #00C143;
-        border: 0;
-        height: 48px;
-    }
-    /deep/ .mint-button--default {
-        width: 92%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-        height: 46px;
-        text-align: center;
-        font-size: 16px;
-        color: #333333;
-        margin-top: 20px;
-        border-radius: 6px;
-    }
-</style>

+ 0 - 116
app/src/pages/safe.vue

@@ -1,116 +0,0 @@
-<template>
-    <div id="pages">
-        <mt-header title="安全设置">
-            <router-link to="/setting" slot="left">
-                <img src="../../static/images/comm/arrow-left.png" alt="" class="arr_left">
-            </router-link>
-        </mt-header>
-        <div class="container">
-            <mt-cell
-                    title="修改密码"
-                    to="/pwd"
-                    is-link>
-            </mt-cell>
-            <mt-cell
-                    title="更换手机号"
-                    to="/phone"
-                    is-link>
-            </mt-cell>
-            <mt-button type="default" @click.navie="logout">退  出</mt-button>
-        </div>
-    </div>
-</template>
-
-<script>
-    import axios from 'axios';
-    import { Button } from 'mint-ui';
-    import { Cell } from 'mint-ui';
-    import {Toast} from 'mint-ui';
-    import {MessageBox} from 'mint-ui';
-    import Vue from 'vue';
-    let qs = require('qs');
-    import Global from '../Global.js'
-    Vue.component(Button.name, Button);
-    Vue.component(Cell.name, Cell);
-
-    export default {
-        data() {
-            return {
-                username: '',
-                company: '',
-            }
-        },
-        mounted() {
-
-        },
-        methods: {
-            // 退出
-            logout() {
-                const that = this;
-                let url = headapi + 'logout';
-                let param = {};
-                let postdata = qs.stringify(param);
-                MessageBox.confirm('确定退出当前账户?').then(action => {
-                    axios.post(url, postdata).then(function (data) {
-                        let json = data.data;
-                        if (json.code == 0) {
-                            Toast('当前账户已退出');
-                            that.$router.push({path: '/login'});
-                        } else {
-                            Toast(json.memo);
-                        }
-                    }, function (response) {
-                        console.info(response);
-                    })
-                });
-            },
-        },
-        components: {}
-    }
-</script>
-
-<!-- Add "scoped" attribute to limit CSS to this component only -->
-<style scoped>
-    @import "../assets/css/comm.css";
-    #pages {
-        background: #EBEBEB;
-    }
-    .container {
-        width: 100%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-        margin-top: 10px;
-    }
-    /deep/ .mint-cell {
-        margin-bottom: 1px;
-    }
-    .gary {
-        width: 100%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-        height: 10px;
-    }
-    /deep/ .mint-cell-title {
-        color: #454545;
-        font-size: 16px;
-    }
-    /deep/ .mint-cell-value span {
-        font-size: 14px;
-        color: #454545;
-    }
-    /deep/ .mint-button--default {
-        width: 92%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-        height: 46px;
-        text-align: center;
-        font-size: 16px;
-        color: #fff;
-        margin-top: 20px;
-        border-radius: 6px;
-        background: #FFD579;
-    }
-</style>

+ 0 - 451
app/src/pages/search.vue

@@ -1,451 +0,0 @@
-<template>
-    <div id="pages">
-        <div class="step" v-if="step == 1">
-            <mt-header title="任务搜索">
-                <div slot="left" @click="back">
-                   <
-                </div>
-            </mt-header>
-            <div class="search" @click.naive="hide_icon">
-                <input type="text" placeholder="查询" @keyup.enter="search(keyword)" v-model="keyword">
-                <img src="../../static/images/search.png" alt="" class="search_icon" v-show="search_icon">
-            </div>
-            <div class="record">
-                <div class="title">
-                    <em>搜索查询记录</em>
-                    <s @click="clear">清空</s>
-                </div>
-                <ul>
-                    <li v-for="h in history" v-if="history.length > 0 " @click="cksearch(h.name)">
-                        {{h.name}}
-                    </li>
-                </ul>
-            </div>
-        </div>
-        <div class="step" v-if="step == 2">
-            <mt-header title="搜索结果">
-                <div class="back_search" slot="left" @click="step = 1">
-                   <
-                </div>
-            </mt-header>
-            <!-- tab-container -->
-            <span class="nope" v-if="!lists">
-                    暂没有符合条件的任务
-                </span>
-            <ul class="list" v-else>
-                <li v-for="list in lists" @click="gotoDetal(list,0)">
-                    <div class="part">
-                        <div class="up_p">
-                            <div class="lt">
-                                <h5>{{list.taskname}}</h5>
-                                <span><em>任务日期</em>{{ list.createtime|globalfmtDate }}</span>
-                            </div>
-                            <div class="rt">
-                                <em :class="[{'finished':list.state == 1},'state']">{{ list.state | stateText }}</em>
-                            </div>
-                        </div>
-                        <div class="down_p">
-                            <ul class="soliders">
-                                <li v-for="mem in list.members.slice(0, 5)">
-                                    {{mem.name}}
-                                </li>
-                            </ul>
-                            <ul class="results">
-                                <li class="res1">有意向 {{ list.answersnum }}</li>
-                                <li class="res2">准意向 {{ list.answermnum }}</li>
-                                <li class="res3">无意向 {{ list.answerfnum }}</li>
-                            </ul>
-                        </div>
-                    </div>
-                </li>
-            </ul>
-            <span id="total1">共{{lists.length}}个团队</span>
-        </div>
-    </div>
-
-</template>
-
-<script>
-    import axios from 'axios';
-    import {Toast} from 'mint-ui';
-
-    let qs = require('qs');
-    import Global from '../Global.js'
-
-    export default {
-        data() {
-            return {
-                search_icon: true,
-                step: 1,
-                keyword: '',
-                history: [],
-            }
-        },
-        mounted() {
-        },
-        methods: {
-            back() {
-                this.$router.go(-1);
-            },
-            clear() {
-                localStorage.history = '';
-                this.history = [];
-            },
-            search(keyword) {
-                const that = this;
-                if (!keyword) {
-                    Toast('搜索关键字不能为空');
-                    return false
-                }
-                if (!keyword.length > 20) {
-                    Toast('搜索关键字不能超过20字符');
-                    return false
-                }
-                let url = headapi + '?ctl=ajax&mod=xxx&act=xxx';
-                let param = {
-                    KEYWORD: keyword,
-                    FINISH: 99,//查全部
-                };
-                let postdata = qs.stringify(param);
-                axios.post(url, postdata).then(function (data) {
-                    let json = data.data;
-                    if (json.code == 0) {
-                        let arr = {name: keyword};
-                        that.history.push(arr);
-                        that.keyword = '';
-                        if (json.rs.length == 0) {
-                            Toast('抱歉,没有搜索到相应的任务内容');
-                        } else {
-                            that.lists = json.rs;
-                            that.step = 2;
-                        }
-                    } else {
-                        Toast(json.memo);
-                    }
-                }, function (response) {
-                    console.info(response);
-                })
-            },
-            hide_icon() {
-                this.search_icon = false;
-            },
-            cksearch(keyword) {
-                this.search(keyword)
-            },
-            gotoDetal(row, state) {
-                let taskid = row.taskid;
-                this.$router.push({
-                    path: '/task_detail',
-                    query: {
-                        'taskid': taskid,
-                        'state': state,
-                    }
-                })
-            },
-        },
-        filters: {
-            globalfmtDate(datetime) {
-                if ((datetime == '') || (datetime == undefined))
-                    return '';
-                if ((datetime == '1900-01-01') || (datetime == '1900-01-01 00:00:00.000'))
-                    return '';
-                length = 11;
-                return (datetime != null) ? datetime.substr(0, length) : '';
-            },
-            stateText(state) {
-                console.log(state);
-                let res = parseInt(state) == 0 ? "进行中" : "已完成";
-                return res;
-            }
-        },
-        components: {}
-    }
-</script>
-
-<!-- Add "scoped" attribute to limit CSS to this component only -->
-<style scoped>
-    @import "../assets/css/comm.css";
-
-    #pages {
-        background: #EBEBEB;
-    }
-
-    .search {
-        width: 92%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-        background: #fff;
-        border-radius: 250px;
-        height: 39px;
-        line-height: 39px;
-        margin-top: 8px;
-    }
-
-    .search img {
-        position: relative;
-        width: 16px;
-        height: 16px;
-        float: left;
-        bottom: 30px;
-        left: 38%;
-    }
-
-    .search input {
-        width: 100%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-        border: none;
-        outline: none;
-        text-align: center;
-        height: 39px;
-        line-height: 39px;
-        font-size: 16px;
-        color: #CCCCCC;
-    }
-
-    .record {
-        width: 92%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-        margin-top: 40px;
-    }
-
-    .record .title {
-        width: 100%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-    }
-
-    .title em {
-        float: left;
-        color: #777777;
-        font-size: 12px;
-    }
-
-    .title s {
-        float: right;
-        font-size: 12px;
-        color: #0079E2;
-    }
-
-    .record ul {
-        width: 100%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-        margin-top: 16px;
-    }
-
-    .record li {
-        float: left;
-        padding: 5px;
-        border-radius: 5px;
-        border: 1px solid #CCCCCC;
-        background: #fff;
-        font-size: 12px;
-        color: #777777;
-        margin-right: 10px;
-    }
-
-    #total2 {
-        width: 100%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-        text-align: center;
-        font-size: 12px;
-        background: #EBEBEB;
-        color: #CCCCCC;
-        margin-bottom: 30px;
-    }
-
-    #total1 {
-        width: 100%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-        text-align: center;
-        font-size: 12px;
-        background: #EBEBEB;
-        color: #CCCCCC;
-        margin-bottom: 30px;
-    }
-
-    /deep/ .mint-tab-container-item {
-        padding-bottom: 40px;
-    }
-
-    .list {
-        width: 100%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-        margin-top: 10px;
-    }
-
-    .list > li {
-        width: 92%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-        border-left: 5px solid #03B1FF;
-        background: #fff;
-        margin-bottom: 15px;
-        padding-left: 4%;
-        padding-right: 4%;
-    }
-
-    .list > li:nth-child(even) {
-        border-left: 5px solid #FFB103;
-    }
-
-    .list .part {
-        width: 100%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-    }
-
-    .list .part .up_p {
-        width: 100%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-        border-bottom: 1px solid #EBEBEB;
-        padding-top: 15px;
-        padding-bottom: 15px;
-    }
-
-    .up_p .lt {
-        width: 70%;
-        float: left;
-    }
-
-    .up_p .rt {
-        width: 30%;
-        float: right;
-    }
-
-    .up_p h5 {
-        color: #333333;
-        font-size: 18px;
-        font-weight: normal;
-        margin: 0;
-    }
-
-    .up_p .lt span {
-        font-size: 12px;
-        color: #CCCCCC;
-    }
-
-    .up_p .lt em {
-        background: #EBEBEB;
-        margin-right: 5px;
-        padding: 3px;
-        color: #777777;
-    }
-
-    .up_p .rt .static_btn {
-        width: 64px;
-        height: 30px;
-        line-height: 30px;
-        font-size: 14px;
-        color: #fff;
-        float: right;
-        background: #03B1FF;
-        border-radius: 4px;
-        margin-top: 3px;
-    }
-
-    .rt .static_btn img {
-        width: 11px;
-        height: 10px;
-        float: left;
-        margin-left: 11px;
-        margin-top: 10px;
-        margin-right: 5px;
-    }
-
-    .down_p {
-        width: 100%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-        margin-top: 15px;
-    }
-
-    .soliders {
-        width: 100%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-    }
-
-    .soliders li {
-        min-width: 55px;
-        float: left;
-        border-radius: 250px;
-        padding: 5px;
-        margin-right: 5px;
-        border: 1px solid #EBEBEB;
-        text-align: center;
-        font-size: 12px;
-    }
-
-    .results {
-        width: 100%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-        margin-top: 12px;
-        margin-bottom: 19px;
-    }
-
-    .results li {
-        width: 85px;
-        height: 17px;
-        float: left;
-        margin-right: 10px;
-        color: #fff;
-        border-radius: 250px;
-        text-align: center;
-        font-size: 12px;
-        padding: 3px;
-    }
-
-    .results .res1 {
-        background: #4CD964;
-    }
-
-    .results .res2 {
-        background: #FFA702;
-    }
-
-    .results .res3 {
-        background: #CCCCCC;
-    }
-
-    .finish_list .static_btn {
-        background: #0079E2 !important;
-    }
-
-    .state {
-        margin-left: 10px;
-        border-radius: 250px;
-        padding: 3px;
-        padding-left: 9px;
-        padding-right: 9px;
-        text-align: center;
-        color: #fff;
-        font-size: 12px;
-        background: #03B1FF;
-    }
-
-    .finished {
-        background: #0079E2 !important;
-    }
-</style>

+ 0 - 164
app/src/pages/setting.vue

@@ -1,164 +0,0 @@
-<template>
-    <div id="pages">
-        <mt-header title="设置">
-            <router-link to="/" slot="left">
-                <img src="../../static/images/comm/arrow-left.png" alt="" class="arr_left">
-            </router-link>
-        </mt-header>
-        <div class="container">
-            <div class="row">
-                <mt-cell
-                        title="基本资料"
-                        to="/basic"
-                        is-link>
-                </mt-cell>
-                <mt-cell
-                        title="安全设置"
-                        to="/safe"
-                        is-link>
-                </mt-cell>
-                <div class="gary"></div>
-                <mt-cell
-                        title="系统消息"
-                        to="/news"
-                        is-link>
-                </mt-cell>
-                <div class="gary"></div>
-                <mt-cell
-                        title="关于我们"
-                        to="/about"
-                        is-link>
-                </mt-cell>
-                <div  @click.naive="current" class="btns">
-                    <mt-cell
-                            title="版本更新"
-                            value="当前版本 1.0.3"
-                    >
-                    </mt-cell>
-                </div>
-
-            </div>
-
-            <!--<mt-button type="default" @click.navie="logout">退出登陆</mt-button>-->
-        </div>
-    </div>
-</template>
-
-<script>
-    import axios from 'axios';
-    import {Cell} from 'mint-ui';
-    import {Toast} from 'mint-ui';
-    import {MessageBox} from 'mint-ui';
-    import Vue from 'vue';
-
-    let qs = require('qs');
-    import Global from '../Global.js'
-
-    Vue.component(Cell.name, Cell);
-
-    export default {
-        data() {
-            return {
-                msg: 'Welcome to Your Vue.js App'
-            }
-        },
-        mounted() {
-
-        },
-        methods: {
-            current(){
-                Toast('当前已是最新版本');
-            },
-            // 退出
-            logout() {
-                const that = this;
-                let url = headapi + '?ctl=ajax&mod=index&act=logout';
-                let param = {};
-                let postdata = qs.stringify(param);
-                MessageBox.confirm('确定退出当前账户?').then(action => {
-                    axios.post(url, postdata).then(function (data) {
-                        let json = data.data;
-                        if (json.code == 0) {
-                            Toast('当前账户已退出');
-                            that.$router.push({path: '/login'});
-                        } else {
-                            Toast(json.memo);
-                        }
-                    }, function (response) {
-                        console.info(response);
-                    })
-                });
-            },
-        },
-        components: {}
-    }
-</script>
-
-<!-- Add "scoped" attribute to limit CSS to this component only -->
-<style scoped>
-    @import "../assets/css/comm.css";
-
-    #pages {
-        background: #EBEBEB;
-    }
-
-    .container {
-        width: 100%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-        margin-top: 10px;
-    }
-
-    /deep/ .mint-cell {
-        margin-bottom: 1px;
-    }
-
-    .gary {
-        width: 100%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-        height: 10px;
-    }
-
-    /deep/ .mint-cell-title {
-        color: #454545;
-        font-size: 16px;
-    }
-
-    /deep/ .mint-cell-value span {
-        font-size: 14px;
-        color: #454545;
-    }
-
-    /deep/ .mint-button--default {
-        width: 92%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-        height: 46px;
-        text-align: center;
-        font-size: 16px;
-        color: #fff;
-        background: #FFD579;
-        margin-top: 20px;
-        border-radius: 6px;
-    }
-    .btns {
-        width: 100%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-    }
-    /deep/ .mint-cell {
-        width: 100%;
-        overflow: hidden;
-        display: block;
-        margin: 0 auto;
-        border-bottom: 1px solid #EBEBEB;
-    }
-    /deep/ .mint-cell-wrapper {
-        background-image:none;
-    }
-</style>

+ 167 - 85
app/src/router/index.js

@@ -1,94 +1,176 @@
 import Vue from 'vue'
-import Router from 'vue-router'
-import index from '@/pages/index'
-import main from '@/pages/main'
-import order from '@/pages/order'
-import mine from '@/pages/mine'
-import category from '@/pages/category'
-import detail from '@/pages/detail'
-import chart from '@/pages/chart'
-import login from '@/pages/login'
+import VueRouter from 'vue-router'
 
-Vue.use(Router);
+Vue.use(VueRouter);
 
-export default new Router({
-    routes: [
-        {
-            path: '/',
-            name: 'index',
-            component: index,
-            meta:{index:0},//meta对象的index用来定义当前路由的层级,由小到大,由低到高
-            children: [
-                {
-                    path: '/',
-                    name: 'main',
-                    meta: {
-                        title: '首页',
-                        index:1
-                    },
-                    component: main,
+const routes = [
+    {
+        path: '/',
+        name: 'index',
+        component: () => import( '../page/index.vue'),
+        meta: {index: 0},//meta对象的index用来定义当前路由的层级,由小到大,由低到高
+        children: [
+            {
+                path: '/',
+                name: 'main',
+                meta: {
+                    title: '系统首页',
+                    index: 1
                 },
-                {
-                    path: '/main',
-                    name: 'main',
-                    meta: {
-                        title: '首页',
-                        index:1
-                    },
-                    component: main,
+                component: () => import( '../page/mainpage.vue')
+            },
+            {
+                path: '/map',
+                name: 'map',
+                meta: {
+                    title: '地图展示',
+                    index: 1
                 },
-                {
-                    path: '/order',
-                    name: 'order',
-                    meta: {
-                        title: 'order',
-                        index:2
-                    },
-                    component: order,
+                component: () => import( '../page/map.vue')
+            }, {
+                path: '/detector',
+                name: 'detector',
+                meta: {
+                    title: '探测设备',
+                    index: 1
                 },
-                {
-                    path: '/mine',
-                    name: 'mine',
-                    meta: {
-                        title: 'mine',
-                        index:2
-                    },
-                    component: mine,
-                }, {
-                    path: '/category',
-                    name: 'category',
-                    meta: {
-                        title: 'category',
-                        index:2
-                    },
-                    component: category,
-                },{
-                    path: '/detail',
-                    name: 'detail',
-                    meta: {
-                        title: 'detail',
-                        index:2
-                    },
-                    component: detail,
-                },{
-                    path: '/chart',
-                    name: 'chart',
-                    meta: {
-                        title: 'chart',
-                        index:2
-                    },
-                    component: chart,
+                component: () => import( '../page/detector.vue')
+            },{
+                path: '/runtime',
+                name: 'runtime',
+                meta: {
+                    title: '实时监控',
+                    index: 1
                 },
-            ]
-        },
-        {
-            path: '/login',
-            name: 'login',
-            meta: {
-                title: 'login',
-                index:1
+                component: () => import( '../page/runtime.vue')
             },
-            component: login,
+        ]
+    },
+    {
+        path: '/login',
+        name: 'login',
+        meta: {
+            title: '登陆',
+            index: 1
+        },
+        component: () => import( '../page/login.vue')
+    }, {
+        path: '/statischart',
+        name: 'statischart',
+        meta: {
+            title: 'statischart',
+            index: 1
+        },
+        component: () => import( '../components/statischart.vue')
+    },{
+        path: '/detectorDetail',
+        name: 'detectorDetail',
+        meta: {
+            title: '探测设备详情',
+            index: 3
+        },
+        component: () => import( '../page/detectorDetail.vue')
+    },{
+        path: '/usermanage',
+        name: 'usermanage',
+        meta: {
+            title: '用户管理',
+            index: 2
+        },
+        component: () => import( '../page/usermanage.vue')
+    },{
+        path: '/userDetail',
+        name: 'userDetail',
+        meta: {
+            title: '用户详情',
+            index: 3
+        },
+        component: () => import( '../page/userDetail.vue')
+    },{
+        path: '/enterprisemanage',
+        name: 'enterprisemanage',
+        meta: {
+            title: '企业管理',
+            index: 2
+        },
+        component: () => import( '../page/enterprisemanage.vue')
+    },{
+        path: '/enterpriseDetail',
+        name: 'enterpriseDetail',
+        meta: {
+            title: '企业详情',
+            index: 3
+        },
+        component: () => import( '../page/enterpriseDetail.vue')
+    },{
+        path: '/record',
+        name: 'record',
+        meta: {
+            title: '探测记录',
+            index: 2
         },
-    ]
-})
+        component: () => import( '../page/record.vue')
+    },{
+        path: '/statis',
+        name: 'statis',
+        meta: {
+            title: '统计报表',
+            index: 2
+        },
+        component: () => import( '../page/statis.vue')
+    },{
+        path: '/setting',
+        name: 'setting',
+        meta: {
+            title: '系统设置',
+            index: 2
+        },
+        component: () => import( '../page/setting.vue')
+    },{
+        path: '/plane',
+        name: 'plane',
+        meta: {
+            title: '平面详情',
+            index: 3
+        },
+        component: () => import( '../page/plane.vue')
+    },{
+        path: '/profile',
+        name: 'profile',
+        meta: {
+            title: '平面详情',
+            index: 3
+        },
+        component: () => import( '../page/profile.vue')
+    },{
+        path: '/listDetail',
+        name: 'listDetail',
+        meta: {
+            title: '平面详情',
+            index: 3
+        },
+        component: () => import( '../page/listDetail.vue')
+    },{
+        path: '/white',
+        name: 'white',
+        meta: {
+            title: '白名单',
+            index: 3
+        },
+        component: () => import( '../page/white.vue')
+    },{
+        path: '*',
+        name: 'notFound',
+        meta: {
+            title: '404',
+            index: 3
+        },
+        component: () => import( '../page/notFound.vue')
+    },
+];
+
+const router = new VueRouter({
+    routes
+});
+
+export default router

+ 0 - 0
app/static/images/comm/arrow-left.png → app/src/static/images/comm/arrow-left.png


BIN
app/src/static/images/comm/b11.png


BIN
app/src/static/images/comm/b11_1.png


BIN
app/src/static/images/comm/b12.png


BIN
app/src/static/images/comm/b12_1.png


BIN
app/src/static/images/comm/b13.png


BIN
app/src/static/images/comm/b13_1.png


BIN
app/src/static/images/comm/b14.png


BIN
app/src/static/images/comm/b14_1.png


BIN
app/src/static/images/comm/cityPicker.png


BIN
app/src/static/images/comm/headerBg.png


BIN
app/src/static/images/comm/iconEquipmanage.png


BIN
app/src/static/images/comm/iconEquipmanage_a.png


BIN
app/src/static/images/comm/iconHome.png


BIN
app/src/static/images/comm/iconHome_a.png


BIN
app/src/static/images/comm/iconMap.png


BIN
app/src/static/images/comm/iconMap_a.png


BIN
app/src/static/images/comm/iconProfile.png


BIN
app/src/static/images/comm/iconProfile_a.png


BIN
app/src/static/images/comm/iconRecord.png


BIN
app/src/static/images/comm/iconRecord_a.png


BIN
app/src/static/images/comm/iconRuntime.png


BIN
app/src/static/images/comm/iconRuntime_a.png


BIN
app/src/static/images/comm/iconStatis.png


BIN
app/src/static/images/comm/iconStatis_a.png


BIN
app/src/static/images/comm/iconUser.png


BIN
app/src/static/images/comm/iconUser_a.png


BIN
app/src/static/images/comm/list.png


BIN
app/src/static/images/comm/right.png


+ 0 - 0
app/static/images/comm/tab01.png → app/src/static/images/comm/tab01.png


+ 0 - 0
app/static/images/comm/tab01_b.png → app/src/static/images/comm/tab01_b.png


+ 0 - 0
app/static/images/comm/tab02.png → app/src/static/images/comm/tab02.png


+ 0 - 0
app/static/images/comm/tab02_b.png → app/src/static/images/comm/tab02_b.png


+ 0 - 0
app/static/images/comm/tab03.png → app/src/static/images/comm/tab03.png


+ 0 - 0
app/static/images/comm/tab03_b.png → app/src/static/images/comm/tab03_b.png


+ 0 - 0
app/static/images/comm/tab04.png → app/src/static/images/comm/tab04.png


+ 0 - 0
app/static/images/comm/tab04_b.png → app/src/static/images/comm/tab04_b.png


+ 0 - 0
app/static/images/comm/tab05.png → app/src/static/images/comm/tab05.png


Einige Dateien werden nicht angezeigt, da zu viele Dateien in diesem Diff geändert wurden.