| @@ -0,0 +1,3 @@ | |||
| > 1% | |||
| last 2 versions | |||
| not ie <= 8 | |||
| @@ -0,0 +1,14 @@ | |||
| module.exports = { | |||
| root: true, | |||
| env: { | |||
| node: true | |||
| }, | |||
| extends: ["plugin:vue/essential"], | |||
| rules: { | |||
| "no-console": process.env.NODE_ENV === "production" ? "error" : "off", | |||
| "no-debugger": process.env.NODE_ENV === "production" ? "error" : "off" | |||
| }, | |||
| parserOptions: { | |||
| parser: "babel-eslint" | |||
| } | |||
| }; | |||
| @@ -0,0 +1,21 @@ | |||
| .DS_Store | |||
| node_modules | |||
| /dist | |||
| # local env files | |||
| .env.local | |||
| .env.*.local | |||
| # Log files | |||
| npm-debug.log* | |||
| yarn-debug.log* | |||
| yarn-error.log* | |||
| # Editor directories and files | |||
| .idea | |||
| .vscode | |||
| *.suo | |||
| *.ntvs* | |||
| *.njsproj | |||
| *.sln | |||
| *.sw* | |||
| @@ -0,0 +1,27 @@ | |||
| # mobile-admin | |||
| ## Project setup | |||
| ``` | |||
| npm install | |||
| ``` | |||
| ### Compiles and hot-reloads for development | |||
| ``` | |||
| npm run serve | |||
| ``` | |||
| ### Compiles and minifies for production | |||
| ``` | |||
| npm run build | |||
| ``` | |||
| ### Run your tests | |||
| ``` | |||
| npm run test | |||
| ``` | |||
| ### Lints and fixes files | |||
| ``` | |||
| npm run lint | |||
| ``` | |||
| @@ -0,0 +1 @@ | |||
| <!DOCTYPE html><html lang=en><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge"><meta name=viewport content="maximum-scale=1,minimum-scale=1,user-scalable=1,width=device-width,initial-scale=1"><link rel=icon href=/favicon.ico><title>mobile-admin</title><link href=/static/css/chunk-4ca71562.c4fd982f.css rel=prefetch><link href=/static/js/chunk-2d0df214.55b65f36.js rel=prefetch><link href=/static/js/chunk-4ca71562.02fcf80f.js rel=prefetch><link href=/static/css/app.640e1136.css rel=preload as=style><link href=/static/css/chunk-vendors.3bd1146c.css rel=preload as=style><link href=/static/js/app.58b1b7dc.js rel=preload as=script><link href=/static/js/chunk-vendors.6e82d040.js rel=preload as=script><link href=/static/css/chunk-vendors.3bd1146c.css rel=stylesheet><link href=/static/css/app.640e1136.css rel=stylesheet></head><body style="background-color: #f7f8fa;"><noscript><strong>We're sorry but mobile-admin doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id=app></div><script src=/static/js/chunk-vendors.6e82d040.js></script><script src=/static/js/app.58b1b7dc.js></script></body></html> | |||
| @@ -0,0 +1 @@ | |||
| #app{font-family:Avenir,Helvetica,Arial,sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;color:#2c3e50;overflow:hidden}a:-webkit-any-link{text-decoration:none}input:-webkit-autofill{-webkit-box-shadow:0 0 0 26.66667rem #fff inset}input{-webkit-filter:none!important;filter:none!important}.panel-container{margin-bottom:.13333rem}.panel-container .panel-content{padding:.26667rem .4rem}.van-hairline--top-bottom:after{border:none!important}.van-cell{padding-bottom:0!important}.van-cell .van-cell__title{-webkit-box-flex:3;-ms-flex:3;flex:3}@font-face{font-family:iconfont;src:url(//at.alicdn.com/t/font_927880_2ihl8qth6yg.eot);src:url(//at.alicdn.com/t/font_927880_2ihl8qth6yg.eot#iefix) format("embedded-opentype"),url(//at.alicdn.com/t/font_927880_2ihl8qth6yg.woff) format("woff"),url(//at.alicdn.com/t/font_927880_2ihl8qth6yg.ttf) format("truetype"),url(//at.alicdn.com/t/font_927880_2ihl8qth6yg.svg#iconfont) format("svg")}@font-face{font-family:iconfont;src:url(//at.alicdn.com/t/font_2723835_y1jsf7gbkz.woff2?t=1628136189738) format("woff2"),url(//at.alicdn.com/t/font_2723835_y1jsf7gbkz.woff?t=1628136189738) format("woff"),url(//at.alicdn.com/t/font_2723835_y1jsf7gbkz.ttf?t=1628136189738) format("truetype")}.iconfont{font-family:iconfont!important;font-size:.74667rem;font-style:normal;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.icon-home:before{content:"\E620"}.icon-shu:before{content:"\E634"}.icon-ziyuan:before{content:"\E621"}.icon-username:before{content:"\EAC3";position:absolute;left:-.13333rem;bottom:.05333rem;font-size:.58667rem}.icon-password:before{content:"\EAC2";position:absolute;left:-.13333rem;bottom:.02667rem;font-size:.64rem}.icon-yanzhengma:before{content:"\E63F";position:absolute;left:-.05333rem;bottom:.08rem;font-size:.48rem;font-weight:700} | |||
| @@ -0,0 +1 @@ | |||
| .login-container[data-v-3d4a5790]{height:100vh;background:#fff!important;text-align:center}.login-container .input-box[data-v-3d4a5790]{display:inline-block;position:relative}.login-container .input-box input[data-v-3d4a5790]{outline:none;border-bottom:.02667rem solid #c8b185;border-left-width:0;border-top-width:0;border-right-width:0;text-align:left;padding:0 .8rem;width:6.66667rem;-webkit-box-sizing:border-box;box-sizing:border-box;font-size:.42667rem;border-radius:0}.login-container .van-button[data-v-3d4a5790]{margin-top:1.33333rem;width:6.66667rem} | |||
| @@ -0,0 +1 @@ | |||
| (window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-2d0df214"],{8930:function(t,e,n){"use strict";n.r(e);var s=function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{staticStyle:{height:"calc(100vh - 2.5rem)",overflow:"auto","margin-top":"1.3rem"}},[t.sysConfig?n("van-cell",{attrs:{center:"",title:"报警提醒"}},[[n("van-switch",{attrs:{value:t.checked,size:"24"},on:{input:t.onInput}})]],2):n("div",{staticClass:"van-list__finished-text"},[t._v("服务器异常,请稍后重试~~")]),n("van-row",{attrs:{type:"flex",justify:"space-around"}},[n("van-col",[n("van-button",{attrs:{type:"info",size:"small"},on:{click:t.handleLogout}},[t._v("退出登录")])],1)],1)],1)},i=[],o=n("b970"),a=n("2f62"),c={data(){return{checked:!0}},computed:{...Object(a["c"])(["sysConfig"])},mounted(){this.getSysConfig("limit=10&page=1&sidx=&order=asc&key=IS_NOTIFY_SERVICE").then(t=>{0===t.code&&(this.checked="1"===this.sysConfig["value"])})},methods:{...Object(a["b"])({getSysConfig:"setting/fetchSysConfig",handleSysConfigs:"setting/handleSysConfigs"}),onInput(t){let e=t?"开启":"关闭";o["a"].confirm({title:"提醒",message:`是否${e}报警通知?`}).then(()=>{this.sysConfig["value"]=t?"1":"0",this.handleSysConfigs(this.sysConfig).then(e=>{0===e.code?this.checked=t:o["b"].error("设置失败,请稍后重试~~")})}).catch(()=>{})},handleLogout(){o["a"].confirm({title:"退出登录",message:"是否立即退出登录?"}).then(()=>{this.$store.dispatch("LogOut",(new Date).getTime()).then(t=>{window.location.href="/login"})}).catch(()=>{})}}},l=c,h=n("2877"),r=Object(h["a"])(l,s,i,!1,null,null,null);r.options.__file="index.vue";e["default"]=r.exports}}]); | |||
| @@ -0,0 +1 @@ | |||
| (window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-4ca71562"],{d9c9:function(t,i,e){"use strict";e.r(i);var n=function(){var t=this,i=t.$createElement,e=t._self._c||i;return e("div",{staticClass:"login-container"},[e("header",{staticStyle:{"padding-top":"50px","font-size":"0.7rem"}},[t._v("综合管理平台")]),e("div",[e("div",{staticClass:"input-box",staticStyle:{"margin-top":"100px"}},[e("i",{staticClass:"iconfont icon-username"}),e("input",{directives:[{name:"model",rawName:"v-model",value:t.loginInfo.username,expression:"loginInfo.username"}],attrs:{type:"text"},domProps:{value:t.loginInfo.username},on:{input:function(i){i.target.composing||t.$set(t.loginInfo,"username",i.target.value)}}})]),e("div",{staticClass:"input-box",staticStyle:{"margin-top":"10px"}},[e("i",{staticClass:"iconfont icon-password"}),e("input",{directives:[{name:"model",rawName:"v-model",value:t.loginInfo.password,expression:"loginInfo.password"}],attrs:{type:"password"},domProps:{value:t.loginInfo.password},on:{input:function(i){i.target.composing||t.$set(t.loginInfo,"password",i.target.value)}}})]),e("div",{staticClass:"input-box",staticStyle:{"margin-top":"10px"}},[e("i",{staticClass:"iconfont icon-yanzhengma"}),e("input",{directives:[{name:"model",rawName:"v-model",value:t.loginInfo.captcha,expression:"loginInfo.captcha"}],domProps:{value:t.loginInfo.captcha},on:{input:function(i){i.target.composing||t.$set(t.loginInfo,"captcha",i.target.value)}}}),e("div",{staticStyle:{color:"darkgray",position:"absolute",right:"-2px",bottom:"1px"}},[e("img",{staticStyle:{width:"3.3rem","vertical-align":"middle","line-height":"16px","font-size":"11px","border-radius":"4px 4px 0 0"},attrs:{src:"/platform-framework/captcha.jpg?t="+t.loginInfo.time,alt:"验证码获取失败~~"},on:{click:t.handleClickFreshCaptcha}})])])]),e("van-button",{attrs:{loading:t.isLogin,type:"info"},nativeOn:{click:function(i){return t.login(i)}}},[t._v("登录")])],1)},o=[],a=e("b970"),s=e("ed08"),r={data(){return{loginInfo:{username:"",password:"",captcha:"",time:""},isLogin:!1,redirect:void 0}},created(){this.loginInfo.username=this.$route.query.username||"",this.loginInfo.password=this.$route.query.password||""},mounted(){},watch:{$route:{handler:function(t){this.redirect=t.query&&t.query.redirect},immediate:!0}},methods:{async login(){if(Object(s["a"])(this.loginInfo.username)&&""!==this.loginInfo.password){const{username:i,password:e,captcha:n}=this.loginInfo;if(i&&e&&n){this.isLogin=!0;try{const o=await this.$store.dispatch("Login",`username=${i.trim()}&password=${e}&captcha=${n}`);if(this.isLogin=!1,this.handleClickFreshCaptcha(),0!==o.code)return Object(a["b"])(o.msg);this.$router.push({path:this.redirect||"/"})}catch(t){this.isLogin=!1,Object(a["b"])(t.toString())}}else Object(a["b"])("请检查账号、密码以及验证码是否填写完毕 ~~")}},handleClickFreshCaptcha(){this.loginInfo.time=(new Date).getTime()}}},c=r,l=(e("fc32"),e("2877")),p=Object(l["a"])(c,n,o,!1,null,"3d4a5790",null);p.options.__file="index.vue";i["default"]=p.exports},f565:function(t,i,e){},fc32:function(t,i,e){"use strict";var n=e("f565"),o=e.n(n);o.a}}]); | |||
| @@ -0,0 +1,48 @@ | |||
| { | |||
| "name": "mobile-admin", | |||
| "version": "0.1.0", | |||
| "private": true, | |||
| "scripts": { | |||
| "dev": "vue-cli-service serve", | |||
| "build": "vue-cli-service build", | |||
| "lint": "vue-cli-service lint", | |||
| "start": "concurrently -k \"npm run server\" \"npm run dev\"" | |||
| }, | |||
| "dependencies": { | |||
| "amfe-flexible": "^2.2.1", | |||
| "axios": "^0.18.0", | |||
| "bcryptjs": "^2.4.3", | |||
| "clipboard": "^2.0.4", | |||
| "js-cookie": "^2.2.0", | |||
| "koa": "^2.6.2", | |||
| "koa-bodyparser": "^4.2.1", | |||
| "koa-jwt": "^3.5.1", | |||
| "koa-router": "^7.4.0", | |||
| "mysql2": "^1.6.4", | |||
| "vant": "^1.6.28", | |||
| "vue": "^2.5.17", | |||
| "vue-router": "^3.0.1", | |||
| "vuex": "^3.0.1", | |||
| "weixin-js-sdk": "^1.4.0-test" | |||
| }, | |||
| "devDependencies": { | |||
| "@vue/cli-plugin-eslint": "^3.0.5", | |||
| "@vue/cli-service": "^3.0.5", | |||
| "@vue/eslint-config-prettier": "^4.0.0", | |||
| "babel-core": "^6.26.3", | |||
| "babel-eslint": "^10.0.1", | |||
| "babel-preset-env": "^1.7.0", | |||
| "concurrently": "^4.1.0", | |||
| "eslint": "^5.8.0", | |||
| "eslint-plugin-vue": "^5.0.0-0", | |||
| "ioredis": "^4.2.0", | |||
| "less": "^3.0.4", | |||
| "less-loader": "^4.1.0", | |||
| "node-uuid": "^1.4.8", | |||
| "nodemon": "^1.18.7", | |||
| "postcss-pxtorem": "^4.0.1", | |||
| "request-promise": "^4.2.2", | |||
| "sha1": "^1.1.1", | |||
| "vue-template-compiler": "^2.5.17" | |||
| } | |||
| } | |||
| @@ -0,0 +1,5 @@ | |||
| module.exports = { | |||
| plugins: { | |||
| autoprefixer: {} | |||
| } | |||
| }; | |||
| @@ -0,0 +1,17 @@ | |||
| <!DOCTYPE html> | |||
| <html lang="en"> | |||
| <head> | |||
| <meta charset="utf-8"> | |||
| <meta http-equiv="X-UA-Compatible" content="IE=edge"> | |||
| <meta name="viewport" content="maximum-scale=1.0,minimum-scale=1.0,user-scalable=1,width=device-width,initial-scale=1.0"/> | |||
| <link rel="icon" href="<%= BASE_URL %>favicon.ico"> | |||
| <title>mobile-admin</title> | |||
| </head> | |||
| <body style=" background-color: #f7f8fa;"> | |||
| <noscript> | |||
| <strong>We're sorry but mobile-admin 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> | |||
| @@ -0,0 +1,65 @@ | |||
| <template> | |||
| <div id="app"> | |||
| <van-nav-bar v-if="path !== '/login'" :title="navTitle" fixed /> | |||
| <router-view /> | |||
| <van-tabbar v-model="active" v-if="path !== '/login'" @change="handleChangeTabbar"> | |||
| <van-tabbar-item icon="wap-home" :to="{ path: '/' }">首页</van-tabbar-item> | |||
| <van-tabbar-item icon="setting" :to="{ path: '/setting' }">设置</van-tabbar-item> | |||
| </van-tabbar> | |||
| </div> | |||
| </template> | |||
| <script> | |||
| export default { | |||
| data() { | |||
| return { | |||
| navTitle: '警报列表' | |||
| } | |||
| }, | |||
| computed: { | |||
| path() { | |||
| return this.$route.path | |||
| }, | |||
| active: { | |||
| get: function() { | |||
| return this.$route.path === '/' ? 0 : 1 | |||
| }, | |||
| set: function() {} | |||
| } | |||
| }, | |||
| mounted() { | |||
| const navTitle = localStorage.getItem('navTitle') | |||
| if (navTitle) { | |||
| this.navTitle = navTitle | |||
| } else { | |||
| localStorage.setItem('navTitle', this.navTitle) | |||
| } | |||
| }, | |||
| methods: { | |||
| handleChangeTabbar(active) { | |||
| this.navTitle = active === 0 ? '警报列表': '设置中心' | |||
| localStorage.setItem('navTitle', this.navTitle) | |||
| } | |||
| } | |||
| } | |||
| </script> | |||
| <style lang="less"> | |||
| #app { | |||
| font-family: "Avenir", Helvetica, Arial, sans-serif; | |||
| -webkit-font-smoothing: antialiased; | |||
| -moz-osx-font-smoothing: grayscale; | |||
| //text-align: center; | |||
| color: #2c3e50; | |||
| overflow: hidden; | |||
| } | |||
| a:-webkit-any-link { | |||
| text-decoration: none; | |||
| } | |||
| input:-webkit-autofill { | |||
| -webkit-box-shadow: 0 0 0px 1000px white inset; | |||
| } | |||
| input { | |||
| filter: none !important; | |||
| } | |||
| </style> | |||
| @@ -0,0 +1,18 @@ | |||
| import request from '@/utils/request' | |||
| /* 获取紧急报警列表 */ | |||
| export function getAlarmList(data) { | |||
| return request({ | |||
| url: `/alarm/list?${data}`, | |||
| method: 'get' | |||
| }) | |||
| } | |||
| /* 处理紧急报警 */ | |||
| export function handleAlarm(data) { | |||
| return request({ | |||
| url: '/alarm/handle', | |||
| method: 'post', | |||
| data | |||
| }) | |||
| } | |||
| @@ -0,0 +1,65 @@ | |||
| import request from '@/utils/request'; | |||
| // export function login(data) { | |||
| // return request({ | |||
| // url: '/user/login', | |||
| // method: 'post', | |||
| // data | |||
| // }) | |||
| // } | |||
| // export function getUserInfo(id) { | |||
| // return request({ | |||
| // url: '/user/getUserInfo', | |||
| // method: 'get', | |||
| // params: { id } | |||
| // }) | |||
| // } | |||
| export function getWxUserInfo(data) { | |||
| return request({ | |||
| url: '/user/getWxUserInfo', | |||
| method: 'post', | |||
| data | |||
| }) | |||
| } | |||
| export function registerUser(data) { | |||
| return request({ | |||
| url: '/user/register', | |||
| method: 'post', | |||
| data | |||
| }) | |||
| } | |||
| export function getJsapiSignature(url) { | |||
| return request({ | |||
| url: '/user/getJsapiSignature', | |||
| method: 'get', | |||
| params: { url } | |||
| }) | |||
| } | |||
| export function checkAuthorizeCode(data) { | |||
| return request({ | |||
| url: '/user/checkAuthorizeCode', | |||
| method: 'post', | |||
| data | |||
| }) | |||
| } | |||
| export function saveUrlToken(data) { | |||
| return request({ | |||
| url: '/user/saveUrlToken', | |||
| method: 'post', | |||
| data | |||
| }) | |||
| } | |||
| export function getProxyList(data) { | |||
| return request({ | |||
| url: '/user/getProxyList', | |||
| method: 'post', | |||
| data | |||
| }) | |||
| } | |||
| @@ -0,0 +1,18 @@ | |||
| import request from '@/utils/request' | |||
| /* 获取系统参数配置 */ | |||
| export function getSysConfig(data) { | |||
| return request({ | |||
| url: `/sys/config/list?${data}`, | |||
| method: 'get' | |||
| }) | |||
| } | |||
| /* 修改系统参数配置 */ | |||
| export function handleSysConfig(data) { | |||
| return request({ | |||
| url: `/sys/config/update`, | |||
| method: 'post', | |||
| data | |||
| }) | |||
| } | |||
| @@ -0,0 +1,26 @@ | |||
| import request from '@/utils/request' | |||
| /* 登录 */ | |||
| export function login(data) { | |||
| return request({ | |||
| url: '/sys/login', | |||
| method: 'post', | |||
| data | |||
| }) | |||
| } | |||
| /* 获取用户信息 */ | |||
| export function getInfo(time) { | |||
| return request({ | |||
| url: `/sys/user/info?${time}`, | |||
| method: 'get' | |||
| }) | |||
| } | |||
| /* 退出登录 */ | |||
| export function logout(time) { | |||
| return request({ | |||
| url: `/logout?${time}`, | |||
| method: 'get' | |||
| }) | |||
| } | |||
| @@ -0,0 +1,18 @@ | |||
| import Vue from "vue" | |||
| import App from "./App.vue" | |||
| import router from "@/router" | |||
| import store from "@/store" | |||
| import '@/styles/index.less' // global css | |||
| import '@/permission' // permission control | |||
| import Vant from 'vant' | |||
| import 'vant/lib/index.css' | |||
| import 'amfe-flexible' | |||
| Vue.use(Vant) | |||
| Vue.config.productionTip = false | |||
| new Vue({ | |||
| router, | |||
| store, | |||
| render: h => h(App) | |||
| }).$mount("#app") | |||
| @@ -0,0 +1,38 @@ | |||
| import router from '@/router'; | |||
| import store from '@/store'; | |||
| import { getToken } from '@/utils/auth'; // 验权 | |||
| const whiteList = ['/login']; // 不重定向白名单 | |||
| router.beforeEach(async (to, from, next) => { | |||
| if (getToken()) { | |||
| if (to.path === '/login') { | |||
| next({ path: '/' }) | |||
| } else { | |||
| if (!store.getters.userInfo.userId) { | |||
| // store.dispatch('GetUserInfo').then(res => { | |||
| // // 如果拉取用户信息成功则跳转页面,否则重新登录 | |||
| // if (res) next() | |||
| // else store.dispatch('FedLogOut').then(() => { next({ path: '/' }) }) | |||
| // }).catch(err => { | |||
| // store.dispatch('FedLogOut').then(() => { | |||
| // next({ path: '/' }) | |||
| // }); | |||
| // }) | |||
| const res = await store.dispatch('GetUserInfo') | |||
| if (res === 0) next() | |||
| else store.dispatch('FedLogOut').then(() => { | |||
| //next({ path: '/' }) | |||
| next(`/login?redirect=${to.path}`) | |||
| }) | |||
| } else { | |||
| next() | |||
| } | |||
| } | |||
| } else { | |||
| if (whiteList.indexOf(to.path) !== -1 || whiteList.indexOf(to.path.split('to/')[0] + 'to') !== -1) { | |||
| next() | |||
| } else { | |||
| next(`/login?redirect=${to.path}`) | |||
| } | |||
| } | |||
| }) | |||
| @@ -0,0 +1,76 @@ | |||
| import Vue from 'vue'; | |||
| import Router from 'vue-router'; | |||
| import Home from '@/views/Home.vue'; | |||
| Vue.use(Router); | |||
| export default new Router({ | |||
| mode: 'history', | |||
| // base: process.env.BASE_URL, | |||
| routes: [ | |||
| { | |||
| path: '/login', | |||
| component: () => import('@/views/Login/index'), | |||
| hidden: true | |||
| }, | |||
| { | |||
| path: '/', | |||
| name: 'home', | |||
| component: Home, | |||
| meta: { | |||
| // 页面标题title | |||
| title: '警报列表' | |||
| } | |||
| }, | |||
| { | |||
| path: '/setting', | |||
| name: 'setting', | |||
| component: () => import('@/views/Setting/index'), | |||
| meta: { | |||
| // 页面标题title | |||
| title: '设置中心' | |||
| } | |||
| } | |||
| // { | |||
| // path: '/answer', | |||
| // name: 'answer', | |||
| // // route level code-splitting | |||
| // // this generates a separate chunk (about.[hash].js) for this route | |||
| // // which is lazy-loaded when the route is visited. | |||
| // component: () => import(/* webpackChunkName: 'about' */ '@/views/Answer') | |||
| // }, | |||
| // { | |||
| // path: '/personal', | |||
| // name: 'personal', | |||
| // component: () => import('@/views/Personal') | |||
| // }, | |||
| // { | |||
| // path: '/personal/order', | |||
| // component: () => import('@/views/Personal/Order') | |||
| // }, | |||
| // { | |||
| // path: '/personal/address', | |||
| // component: () => import('@/views/Personal/Address') | |||
| // }, | |||
| // { | |||
| // path: '/personal/develop', | |||
| // component: () => import('@/views/Personal/Develop') | |||
| // }, | |||
| // { | |||
| // path: '/personal/develop/share', | |||
| // component: () => import('@/views/Personal/Develop/Share') | |||
| // }, | |||
| // { | |||
| // path: '/personal/develop/to/:state', | |||
| // component: () => import('@/views/Personal/Develop/To') | |||
| // }, | |||
| // { | |||
| // path: '/login', | |||
| // component: () => import('@/views/Login') | |||
| // }, | |||
| // { | |||
| // path: '/product/list', | |||
| // component: () => import('@/views/Product') | |||
| // } | |||
| ] | |||
| }); | |||
| @@ -0,0 +1,8 @@ | |||
| const getters = { | |||
| token: state => state.user.token, | |||
| userInfo: state => state.user.userInfo, | |||
| alarmList: state => state.alarm.alarmList, | |||
| alarmMsg: state => state.alarm.alarmMsg, | |||
| sysConfig: state => state.setting.sysConfig, | |||
| } | |||
| export default getters | |||
| @@ -0,0 +1,19 @@ | |||
| import Vue from 'vue'; | |||
| import Vuex from 'vuex'; | |||
| import user from './modules/user'; | |||
| import alarm from './modules/alarm'; | |||
| import setting from './modules/setting'; | |||
| import getters from './getters'; | |||
| Vue.use(Vuex) | |||
| const store = new Vuex.Store({ | |||
| modules: { | |||
| user, | |||
| alarm, | |||
| setting | |||
| }, | |||
| getters | |||
| }) | |||
| export default store | |||
| @@ -0,0 +1,63 @@ | |||
| import { getAlarmList, handleAlarm } from '@/api/alarm' | |||
| const state = { | |||
| alarmList: '', | |||
| alarmMsg: '' | |||
| } | |||
| const mutations = { | |||
| SET_ALARM_LIST: (state, payload) => { | |||
| state.alarmList = payload | |||
| }, | |||
| SET_ALARM_MSG: (state, payload) => { | |||
| state.alarmMsg = payload | |||
| } | |||
| } | |||
| const actions = { | |||
| fetchAlarmList({ commit }, option) { | |||
| return new Promise((resolve, reject) => { | |||
| getAlarmList(option).then((res) => { | |||
| if (res.code === 0) { | |||
| const { page } = res | |||
| commit('SET_ALARM_LIST', page.list) | |||
| } | |||
| if (res.msg == '没有权限,请联系管理员授权') { | |||
| commit('SET_ALARM_LIST', []) | |||
| } | |||
| resolve(res) | |||
| }).catch((err) => { | |||
| reject(err) | |||
| }) | |||
| }) | |||
| }, | |||
| handleAlarms({ commit }, ids) { | |||
| return new Promise((resolve, reject) => { | |||
| handleAlarm(ids).then(res => { | |||
| resolve(res) | |||
| }).catch(err => { | |||
| reject(err) | |||
| }) | |||
| }) | |||
| } | |||
| // fetchVideoMsg({ commit }, videoId) { | |||
| // return new Promise((resolve, reject) => { | |||
| // getVideoMsg(videoId).then((res) => { | |||
| // const { video } = res | |||
| // video['label'] = video['label'] ? video['label'].split(',') : [] | |||
| // commit('SET_VIDEO_MSG', video) | |||
| // resolve() | |||
| // }).catch((err) => { | |||
| // reject(err) | |||
| // }) | |||
| // }) | |||
| // }, | |||
| } | |||
| export default { | |||
| namespaced: true, | |||
| state, | |||
| mutations, | |||
| actions | |||
| } | |||
| @@ -0,0 +1,47 @@ | |||
| import { getSysConfig, handleSysConfig } from '@/api/setting' | |||
| const state = { | |||
| sysConfig: '' | |||
| } | |||
| const mutations = { | |||
| SET_SYS_CONFIG: (state, payload) => { | |||
| state.sysConfig = payload | |||
| } | |||
| } | |||
| const actions = { | |||
| fetchSysConfig({ commit }, option) { | |||
| return new Promise((resolve, reject) => { | |||
| getSysConfig(option).then((res) => { | |||
| if (res.code === 0) { | |||
| const { page } = res | |||
| commit('SET_SYS_CONFIG', ...page.list) | |||
| } | |||
| if (res.msg == '没有权限,请联系管理员授权') { | |||
| commit('SET_SYS_CONFIG', '') | |||
| } | |||
| resolve(res) | |||
| }).catch((err) => { | |||
| reject(err) | |||
| }) | |||
| }) | |||
| }, | |||
| handleSysConfigs({ commit }, option) { | |||
| return new Promise((resolve, reject) => { | |||
| handleSysConfig(option).then(res => { | |||
| resolve(res) | |||
| }).catch(err => { | |||
| reject(err) | |||
| }) | |||
| }) | |||
| } | |||
| } | |||
| export default { | |||
| namespaced: true, | |||
| state, | |||
| mutations, | |||
| actions | |||
| } | |||
| @@ -0,0 +1,82 @@ | |||
| import { login, getInfo, logout } from '@/api/user' | |||
| import { getToken, setToken, removeToken } from '@/utils/auth' | |||
| import { uuid } from '@/utils' | |||
| const user = { | |||
| state: { | |||
| token: getToken(), | |||
| userInfo: {} | |||
| }, | |||
| mutations: { | |||
| SET_TOKEN: (state, token) => { | |||
| state.token = token | |||
| }, | |||
| SET_USERINFO: (state, userInfo) => { | |||
| state.userInfo = userInfo | |||
| } | |||
| }, | |||
| actions: { | |||
| // 登录 | |||
| Login({ commit }, loginInfo) { | |||
| return new Promise((resolve, reject) => { | |||
| login(loginInfo).then(data => { | |||
| // const { success, msg, authData } = data | |||
| //console.log(data, 'login success') | |||
| // resolve({ success, msg }) | |||
| const { code } = data | |||
| resolve(data) | |||
| if (code !== 0) return | |||
| const token = uuid() | |||
| setToken(token) | |||
| commit('SET_TOKEN', token) | |||
| //setToken(authData.token) | |||
| //commit('SET_TOKEN', authData.token) | |||
| }).catch(error => { | |||
| reject(error) | |||
| }) | |||
| }) | |||
| }, | |||
| // 获取用户信息 | |||
| GetUserInfo({ commit, state }) { | |||
| return new Promise((resolve, reject) => { | |||
| getInfo(new Date().getTime()).then(data => { | |||
| const { code, user } = data | |||
| if (code === 0) commit('SET_USERINFO', user) | |||
| resolve(code) | |||
| }).catch(error => { | |||
| reject(error) | |||
| }) | |||
| }) | |||
| }, | |||
| // 登出 | |||
| LogOut({ commit, time }) { | |||
| return new Promise((resolve, reject) => { | |||
| logout(time) | |||
| .then(() => { | |||
| commit('SET_TOKEN', '') | |||
| //commit('SET_ROLES', []) | |||
| removeToken() | |||
| resolve() | |||
| }) | |||
| .catch(error => { | |||
| reject(error) | |||
| }) | |||
| }) | |||
| }, | |||
| // 前端 登出 | |||
| FedLogOut({ commit }) { | |||
| return new Promise(resolve => { | |||
| commit('SET_TOKEN', '') | |||
| removeToken() | |||
| resolve() | |||
| }) | |||
| } | |||
| } | |||
| } | |||
| export default user | |||
| @@ -0,0 +1,35 @@ | |||
| @font-face { | |||
| font-family: 'iconfont'; /* project id 927880 */ | |||
| src: url('//at.alicdn.com/t/font_927880_2ihl8qth6yg.eot'); | |||
| src: url('//at.alicdn.com/t/font_927880_2ihl8qth6yg.eot?#iefix') format('embedded-opentype'), | |||
| url('//at.alicdn.com/t/font_927880_2ihl8qth6yg.woff') format('woff'), | |||
| url('//at.alicdn.com/t/font_927880_2ihl8qth6yg.ttf') format('truetype'), | |||
| url('//at.alicdn.com/t/font_927880_2ihl8qth6yg.svg#iconfont') format('svg'); | |||
| } | |||
| @font-face { | |||
| font-family: 'iconfont'; /* Project id 2723835 */ | |||
| src: url('//at.alicdn.com/t/font_2723835_y1jsf7gbkz.woff2?t=1628136189738') format('woff2'), | |||
| url('//at.alicdn.com/t/font_2723835_y1jsf7gbkz.woff?t=1628136189738') format('woff'), | |||
| url('//at.alicdn.com/t/font_2723835_y1jsf7gbkz.ttf?t=1628136189738') format('truetype'); | |||
| } | |||
| .iconfont { | |||
| font-family:"iconfont" !important; | |||
| font-size: 28px; | |||
| font-style:normal; | |||
| -webkit-font-smoothing: antialiased; | |||
| -moz-osx-font-smoothing: grayscale; | |||
| } | |||
| .icon-home:before { content: "\e620"; } | |||
| .icon-shu:before { content: "\e634"; } | |||
| .icon-ziyuan:before { content: "\e621"; } | |||
| .icon-username:before { content: "\eac3"; position: absolute; left: -5px; bottom: 2px; font-size: 22px;} | |||
| .icon-password:before { content: "\eac2"; position: absolute; left: -5px; bottom: 1px; font-size: 24px;} | |||
| .icon-yanzhengma:before { content: "\e63f"; position: absolute; left: -2px; bottom: 3px; font-size: 18px; font-weight: bold;} | |||
| @@ -0,0 +1,14 @@ | |||
| @import './icon.less'; | |||
| // .van-tabs__nav--card { | |||
| // border: 1px solid #c8b185 !important; | |||
| // .van-tab { | |||
| // color: #c8b185 !important; | |||
| // border-right: 1px solid #c8b185 !important; | |||
| // } | |||
| // .van-tab--active { | |||
| // color: #fff!important; | |||
| // background-color: #c8b185 !important; | |||
| // } | |||
| // } | |||
| @@ -0,0 +1,15 @@ | |||
| import Cookies from 'js-cookie'; | |||
| const TokenKey = 'User-Token'; | |||
| export function getToken() { | |||
| return Cookies.get(TokenKey) | |||
| } | |||
| export function setToken(token) { | |||
| return Cookies.set(TokenKey, token) | |||
| } | |||
| export function removeToken() { | |||
| return Cookies.remove(TokenKey) | |||
| } | |||
| @@ -0,0 +1,74 @@ | |||
| /* 合法手机号*/ | |||
| export function checkPhone(value) { | |||
| const reg = /^1[34578]\d{9}$/; | |||
| return reg.test(value) | |||
| } | |||
| export function param2Obj(url) { | |||
| const search = url.split('?')[1] | |||
| if (!search) { | |||
| return {} | |||
| } | |||
| return JSON.parse( | |||
| '{"' + | |||
| decodeURIComponent(search) | |||
| .replace(/"/g, '\\"') | |||
| .replace(/&/g, '","') | |||
| .replace(/=/g, '":"') + | |||
| '"}' | |||
| ) | |||
| } | |||
| export function trim(str) { | |||
| return str.replace(/(^\s*)|(\s*$)/g, "") | |||
| } | |||
| export function check_user_name(str) { | |||
| var str2 = "该用户名合法"; | |||
| if ("" == str) { | |||
| str2 = "用户名为空"; | |||
| return str2; | |||
| } else if ((str.length < 5) || (str.length > 20)) { | |||
| str2 = "用户名必须为5 ~ 20位"; | |||
| return str2; | |||
| } else if (check_other_char(str)) { | |||
| str2 = "不能含有特殊字符"; | |||
| return str2; | |||
| } | |||
| return str2; | |||
| } | |||
| // 验证用户名是否含有特殊字符 | |||
| function check_other_char(str) { | |||
| var arr = ["&", "\\", "/", "*", ">", "<", "@", "!"]; | |||
| for (var i = 0; i < arr.length; i++) { | |||
| for (var j = 0; j < str.length; j++) { | |||
| if (arr[i] == str.charAt(j)) { | |||
| return true; | |||
| } | |||
| } | |||
| } | |||
| return false; | |||
| } | |||
| export function getUrlToken() { | |||
| let urlToken = '' | |||
| for (let i = 0; i < 6; i++) { | |||
| urlToken += Math.floor(Math.random() * 10) | |||
| } | |||
| const date = new Date() | |||
| return urlToken = date.getFullYear() + '' + (date.getMonth() + 1) + '' + date.getDate() + '' + urlToken | |||
| } | |||
| export function uuid() { | |||
| const s = [] | |||
| const hexDigits = '0123456789abcdef' | |||
| for (let i = 0; i < 36; i++) { | |||
| s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1) | |||
| } | |||
| s[14] = '4' // bits 12-15 of the time_hi_and_version field to 0010 | |||
| s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1) // bits 6-7 of the clock_seq_hi_and_reserved to 01 | |||
| s[8] = s[13] = s[18] = s[23] = '-' | |||
| const uuid = s.join('') | |||
| return uuid | |||
| }; | |||
| @@ -0,0 +1,98 @@ | |||
| import axios from 'axios'; | |||
| import store from '@/store'; | |||
| import { getToken } from '@/utils/auth'; | |||
| // 创建axios实例 | |||
| const service = axios.create({ | |||
| baseURL: '/platform-framework', // api 的 base_url | |||
| timeout: 5000 // 请求超时时间 | |||
| }) | |||
| // request拦截器 | |||
| service.interceptors.request.use( | |||
| config => { | |||
| // if (store.getters.token) { | |||
| // config.headers.authorization = getToken() // jwt token | |||
| // } | |||
| return config | |||
| }, | |||
| error => { | |||
| // Do something with request error | |||
| // console.log(error) // for debug | |||
| Promise.reject(error) | |||
| } | |||
| ) | |||
| // response 拦截器 | |||
| service.interceptors.response.use( | |||
| // response => response, | |||
| /** | |||
| * 下面的注释为通过在response里,自定义code来标示请求状态 | |||
| * 当code返回如下情况则说明权限有问题,登出并返回到登录页 | |||
| * 如想通过 xmlhttprequest 来状态码标识 逻辑可写在下面error中 | |||
| * 以下代码均为样例,请结合自生需求加以修改,若不需要,则可删除 | |||
| */ | |||
| res => { | |||
| // const res = response.data | |||
| // if (res.code !== 20000 && res.code !== 0) { | |||
| // Message({ | |||
| // message: res.message, | |||
| // type: 'error', | |||
| // duration: 5 * 1000 | |||
| // }) | |||
| // // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了; | |||
| // if (res.code === 50008 || res.code === 50012 || res.code === 50014) { | |||
| // // 请自行在引入 MessageBox | |||
| // // import { Message, MessageBox } from 'element-ui' | |||
| // MessageBox.confirm('你已被登出,可以取消继续留在该页面,或者重新登录', '确定登出', { | |||
| // confirmButtonText: '重新登录', | |||
| // cancelButtonText: '取消', | |||
| // type: 'warning' | |||
| // }).then(() => { | |||
| // store.dispatch('FedLogOut').then(() => { | |||
| // location.reload() // 为了重新实例化vue-router对象 避免bug | |||
| // }) | |||
| // }) | |||
| // } | |||
| // return Promise.reject('error') | |||
| // } else { | |||
| // return response.data | |||
| // } | |||
| if (res.code && res.code !== 0) { | |||
| Message({ | |||
| message: res.msg || 'Error', | |||
| type: 'error', | |||
| duration: 5 * 1000 | |||
| }) | |||
| // 50008: Illegal token; 50012: Other clients logged in; 50014: Token expired; | |||
| if (res.code && res.code === 401 || res.msg == "没有权限,请联系管理员授权") { | |||
| // to re-login | |||
| MessageBox.confirm('您已经退出登录,请重新重新登录', '退出登录', { | |||
| confirmButtonText: '重新登录', | |||
| // cancelButtonText: '返回', | |||
| showCancelButton: false, | |||
| type: 'warning' | |||
| }).then(() => { | |||
| store.dispatch('FedLogOut').then(() => { | |||
| location.reload() | |||
| }) | |||
| }) | |||
| } | |||
| return Promise.reject(new Error(res.msg || 'Error')) | |||
| } else { | |||
| return res.data || res | |||
| } | |||
| }, | |||
| error => { | |||
| console.log('err' + error) // for debug | |||
| // Message({ | |||
| // message: error.message, | |||
| // type: 'error', | |||
| // duration: 5 * 1000 | |||
| // }) | |||
| return Promise.reject(error) | |||
| } | |||
| ) | |||
| export default service | |||
| @@ -0,0 +1,122 @@ | |||
| <template> | |||
| <div style="height: calc(100vh - 2.5rem); overflow: auto; margin-top: 1.3rem;"> | |||
| <van-pull-refresh v-model="refreshing" @refresh="onRefresh"> | |||
| <van-list | |||
| v-model="loading" | |||
| :finished="finished" | |||
| :finished-text="finishedText" | |||
| @load="onLoad" | |||
| > | |||
| <van-cell v-for="item in list" :key="item.id" class="panel-container"> | |||
| <van-panel :title="`${item.userName ? item.userName : ''} ${item.userMobile ? item.userMobile : ''}`" :desc="`${item.createTime}`" status="紧急报警"> | |||
| <div class="panel-content"> | |||
| <div style="font-size: 0.27rem;" v-if="item.address && item.longitude !== 0 && item.latitude !== 0">设备{{item.imei}},在{{item.address}}附近发起紧急报警。</div> | |||
| <div style="font-size: 0.27rem;" v-else>设备{{item.imei}}, {{item.address}}</div> | |||
| <div style="text-align: right"> | |||
| <van-button size="small" type="primary" @click.native="handleDetailAlarm(item)">处理</van-button> | |||
| </div> | |||
| </div> | |||
| </van-panel> | |||
| </van-cell> | |||
| </van-list> | |||
| </van-pull-refresh> | |||
| </div> | |||
| </template> | |||
| <script> | |||
| import { Toast, Dialog } from "vant"; | |||
| import { mapGetters, mapActions } from "vuex"; | |||
| export default { | |||
| data() { | |||
| return { | |||
| list: [], | |||
| dialogLoading: false, | |||
| loading: false, | |||
| finished: false, | |||
| refreshing: false, | |||
| page: 1, | |||
| finishedText: '已经到底啦~~' | |||
| }; | |||
| }, | |||
| computed: { | |||
| ...mapGetters(["alarmList"]), | |||
| }, | |||
| methods: { | |||
| ...mapActions({ | |||
| getAlarmList: "alarm/fetchAlarmList", | |||
| handleAlarms: "alarm/handleAlarms" | |||
| }), | |||
| onLoad() { | |||
| setTimeout(() => { | |||
| if (this.refreshing) { | |||
| this.list = []; | |||
| this.refreshing = false; | |||
| } | |||
| this.getAlarmList(`startTime=&endTime=&state=0&limit=10&page=${this.page}&type=0&sidx=&order=asc&serviceTime=1`).then((res) => { | |||
| this.loading = false; | |||
| if (res.code === 0) { | |||
| this.list.push(...this.alarmList); | |||
| if (this.page == res.totalPage) { | |||
| this.finishedText = '已经到底啦~~' | |||
| this.finished = true; | |||
| } | |||
| this.page++; | |||
| } else { | |||
| this.finished = true; | |||
| this.finishedText = '服务器异常,请稍后重试~~' | |||
| } | |||
| }); | |||
| }, 500); | |||
| }, | |||
| onRefresh() { | |||
| // 清空列表数据 | |||
| this.finished = false; | |||
| // 重新加载数据 | |||
| // 将 loading 设置为 true,表示处于加载状态 | |||
| this.loading = true; | |||
| this.page = 1; | |||
| this.onLoad(); | |||
| }, | |||
| handleDetailAlarm(alarm) { | |||
| Dialog.confirm({ | |||
| title: '报警处理', | |||
| message: '是否处理该紧急报警?', | |||
| beforeClose: (action, done) => { | |||
| if (action === 'confirm') { | |||
| this.handleAlarms([alarm.id]).then(res => { | |||
| if (res.code === 0) { | |||
| Toast.success('处理成功!'); | |||
| this.list = [] | |||
| this.onRefresh() | |||
| } | |||
| done() | |||
| }) | |||
| } else done() | |||
| } | |||
| }).catch(() => { | |||
| console.log('返回') | |||
| }) | |||
| } | |||
| }, | |||
| }; | |||
| </script> | |||
| <style lang="less"> | |||
| .panel-container { | |||
| margin-bottom: 5px; | |||
| .panel-content { | |||
| padding: 0.26667rem 0.4rem; | |||
| } | |||
| } | |||
| .van-hairline--top-bottom::after { | |||
| border: none !important; | |||
| } | |||
| .van-cell { | |||
| padding-bottom: 0 !important; | |||
| .van-cell__title { | |||
| flex: 3; | |||
| } | |||
| } | |||
| </style> | |||
| @@ -0,0 +1,127 @@ | |||
| <template> | |||
| <div class="login-container"> | |||
| <header style="padding-top: 50px;font-size: 0.7rem;">综合管理平台</header> | |||
| <div> | |||
| <div class="input-box" style="margin-top: 100px;"> | |||
| <i class="iconfont icon-username" /> | |||
| <input v-model="loginInfo.username" type="text"> | |||
| </div> | |||
| <div class="input-box" style="margin-top: 10px;"> | |||
| <i class="iconfont icon-password" /> | |||
| <input v-model="loginInfo.password" type="password"> | |||
| </div> | |||
| <div class="input-box" style="margin-top: 10px;"> | |||
| <i class="iconfont icon-yanzhengma" /> | |||
| <input v-model="loginInfo.captcha"> | |||
| <div style="color: darkgray;position: absolute;right: -2px; bottom: 1px;"> | |||
| <img | |||
| :src="`/platform-framework/captcha.jpg?t=${loginInfo.time}`" | |||
| alt="验证码获取失败~~" | |||
| style="width: 3.3rem;vertical-align: middle;line-height: 16px; font-size: 11px;border-radius: 4px 4px 0 0;" | |||
| @click="handleClickFreshCaptcha" | |||
| > | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <van-button :loading="isLogin" type="info" @click.native="login">登录</van-button> | |||
| </div> | |||
| </template> | |||
| <script> | |||
| import { Toast } from "vant"; | |||
| import { check_user_name } from "@/utils"; | |||
| export default { | |||
| data() { | |||
| return { | |||
| loginInfo: { | |||
| username: "", | |||
| password: "", | |||
| captcha: "", | |||
| time: "", | |||
| }, | |||
| isLogin: false, | |||
| redirect: undefined, | |||
| }; | |||
| }, | |||
| created() { | |||
| this.loginInfo.username = this.$route.query.username || ""; | |||
| this.loginInfo.password = this.$route.query.password || ""; | |||
| }, | |||
| mounted() { | |||
| }, | |||
| watch: { | |||
| $route: { | |||
| handler: function(route) { | |||
| this.redirect = route.query && route.query.redirect; | |||
| }, | |||
| immediate: true, | |||
| }, | |||
| }, | |||
| methods: { | |||
| async login() { | |||
| if ( | |||
| check_user_name(this.loginInfo.username) && | |||
| this.loginInfo.password !== "" | |||
| ) { | |||
| // 调用登录接口 | |||
| // 登录成功后继续跳转到被拦截的页面 this.$router.push({ path: this.redirect }) | |||
| const { username, password, captcha } = this.loginInfo | |||
| if (username && password && captcha) { | |||
| this.isLogin = true; | |||
| try { | |||
| const res = await this.$store.dispatch("Login", `username=${username.trim()}&password=${password}&captcha=${captcha}`); | |||
| this.isLogin = false; | |||
| this.handleClickFreshCaptcha(); | |||
| if (res.code !== 0) return Toast(res.msg); | |||
| this.$router.push({ path: this.redirect || "/" }); | |||
| } catch (e) { | |||
| this.isLogin = false; | |||
| Toast(e.toString()); | |||
| } | |||
| } else { | |||
| Toast('请检查账号、密码以及验证码是否填写完毕 ~~'); | |||
| } | |||
| } | |||
| }, | |||
| handleClickFreshCaptcha() { | |||
| this.loginInfo.time = new Date().getTime() | |||
| } | |||
| }, | |||
| }; | |||
| </script> | |||
| <style lang="less" scoped> | |||
| .login-container { | |||
| height: 100vh; | |||
| // display: flex; | |||
| // align-items: center; | |||
| // flex-direction: column; | |||
| // justify-content: center; | |||
| // padding: 0 10px; | |||
| background: #fff !important; | |||
| text-align: center; | |||
| .input-box { | |||
| display: inline-block; | |||
| position: relative; | |||
| input { | |||
| outline: none; | |||
| border-bottom: 1px solid #c8b185; | |||
| border-left-width: 0px; | |||
| border-top-width: 0px; | |||
| border-right-width: 0px; | |||
| text-align: left; | |||
| padding: 0 30px; | |||
| width: 250px; | |||
| box-sizing: border-box; | |||
| font-size: 16px; | |||
| border-radius: 0; | |||
| } | |||
| } | |||
| .van-button { | |||
| margin-top: 50px; | |||
| width: 250px; | |||
| // background: #c8b185; | |||
| // color: #fff; | |||
| } | |||
| } | |||
| </style> | |||
| @@ -0,0 +1,71 @@ | |||
| <template> | |||
| <div style="height: calc(100vh - 2.5rem); overflow: auto; margin-top: 1.3rem;"> | |||
| <van-cell center title="报警提醒" v-if="sysConfig"> | |||
| <template #right-icon> | |||
| <van-switch :value="checked" @input="onInput" size="24" /> | |||
| </template> | |||
| </van-cell> | |||
| <div class="van-list__finished-text" v-else>服务器异常,请稍后重试~~</div> | |||
| <van-row type="flex" justify="space-around"> | |||
| <van-col> | |||
| <van-button type="info" size="small" @click="handleLogout">退出登录</van-button> | |||
| </van-col> | |||
| </van-row> | |||
| </div> | |||
| </template> | |||
| <script> | |||
| import { Toast, Dialog } from "vant"; | |||
| import { mapGetters, mapActions } from "vuex"; | |||
| export default { | |||
| data() { | |||
| return { | |||
| checked: true | |||
| }; | |||
| }, | |||
| computed: { | |||
| ...mapGetters(["sysConfig"]), | |||
| }, | |||
| mounted() { | |||
| this.getSysConfig('limit=10&page=1&sidx=&order=asc&key=IS_NOTIFY_SERVICE').then(res => { | |||
| if (res.code === 0) { | |||
| this.checked = this.sysConfig['value'] === '1' ? true : false | |||
| } | |||
| }) | |||
| }, | |||
| methods: { | |||
| ...mapActions({ | |||
| getSysConfig: "setting/fetchSysConfig", | |||
| handleSysConfigs: "setting/handleSysConfigs", | |||
| }), | |||
| onInput(checked) { | |||
| let msg = checked ? '开启' : '关闭' | |||
| Dialog.confirm({ | |||
| title: '提醒', | |||
| message: `是否${msg}报警通知?`, | |||
| }).then(() => { | |||
| this.sysConfig['value'] = checked ? '1' : '0' | |||
| this.handleSysConfigs(this.sysConfig).then(res => { | |||
| if (res.code === 0) { | |||
| this.checked = checked; | |||
| } else { | |||
| Toast.error('设置失败,请稍后重试~~'); | |||
| } | |||
| }) | |||
| }).catch(() => {}) | |||
| }, | |||
| handleLogout() { | |||
| Dialog.confirm({ | |||
| title: '退出登录', | |||
| message: `是否立即退出登录?`, | |||
| }).then(() => { | |||
| this.$store.dispatch('LogOut', new Date().getTime()).then(res => { | |||
| //this.$router.push(`/login?redirect=${this.$route.fullPath}`) | |||
| window.location.href = '/login' | |||
| }) | |||
| }).catch(() => {}) | |||
| } | |||
| }, | |||
| } | |||
| </script> | |||
| @@ -0,0 +1,40 @@ | |||
| const autoprefixer = require('autoprefixer') | |||
| const pxtorem = require('postcss-pxtorem') | |||
| module.exports = { | |||
| outputDir: 'docs', | |||
| baseUrl: '/', | |||
| assetsDir: 'static', | |||
| productionSourceMap: false, | |||
| css: { | |||
| loaderOptions: { | |||
| postcss: { | |||
| plugins: [ | |||
| autoprefixer(), | |||
| pxtorem({ | |||
| rootValue: 37.5, | |||
| propList: ['*'] | |||
| }) | |||
| ] | |||
| } | |||
| } | |||
| }, | |||
| devServer: { | |||
| port: 9090, // 端口号 | |||
| https: false, // https:{type:Boolean} | |||
| open: true, //配置自动启动浏览器 | |||
| disableHostCheck: true, | |||
| proxy: { | |||
| // '/api': { | |||
| // target: 'http://localhost:8889', | |||
| // changeOrigin: true | |||
| // }, | |||
| '/platform-framework': { | |||
| // target: `http://127.0.0.1:${port}/mock`, | |||
| target: `http://192.168.1.83:8080`, | |||
| // target: 'http://192.168.1.169:8086/', | |||
| changeOrigin: true | |||
| } | |||
| } | |||
| } | |||
| } | |||