作者 朱兆平

update:

1. 登录页面取消动态视频背景
@@ -41,9 +41,8 @@ module.exports = { @@ -41,9 +41,8 @@ module.exports = {
41 include: [ 41 include: [
42 resolve('src'), 42 resolve('src'),
43 resolve('test'), 43 resolve('test'),
44 - resolve('node_modules/@kangc/v-md-editor/lib'),  
45 resolve('node_modules/vue-beautiful-chat/dist'), 44 resolve('node_modules/vue-beautiful-chat/dist'),
46 - 45 + resolve('node_modules/@kangc/v-md-editor')
47 ] 46 ]
48 }, 47 },
49 { 48 {
@@ -26,6 +26,8 @@ import vuepressTheme from '@kangc/v-md-editor/lib/theme/vuepress.js'; @@ -26,6 +26,8 @@ import vuepressTheme from '@kangc/v-md-editor/lib/theme/vuepress.js';
26 import '@kangc/v-md-editor/lib/theme/style/vuepress.css'; 26 import '@kangc/v-md-editor/lib/theme/style/vuepress.css';
27 import createTodoListPlugin from '@kangc/v-md-editor/lib/plugins/todo-list/index'; 27 import createTodoListPlugin from '@kangc/v-md-editor/lib/plugins/todo-list/index';
28 import '@kangc/v-md-editor/lib/plugins/todo-list/todo-list.css'; 28 import '@kangc/v-md-editor/lib/plugins/todo-list/todo-list.css';
  29 +import createEmojiPlugin from '@kangc/v-md-editor/lib/plugins/emoji/index';
  30 +import '@kangc/v-md-editor/lib/plugins/emoji/emoji.css'
29 import Prism from 'prismjs'; 31 import Prism from 'prismjs';
30 32
31 33
@@ -33,6 +35,7 @@ VueMarkdownEditor.use(vuepressTheme, { @@ -33,6 +35,7 @@ VueMarkdownEditor.use(vuepressTheme, {
33 Prism, 35 Prism,
34 }); 36 });
35 VueMarkdownEditor.use(createTodoListPlugin()); 37 VueMarkdownEditor.use(createTodoListPlugin());
  38 +VueMarkdownEditor.use(createEmojiPlugin());
36 Vue.use(VueMarkdownEditor); 39 Vue.use(VueMarkdownEditor);
37 40
38 Vue.component('barcode', VueBarcode); 41 Vue.component('barcode', VueBarcode);
1 -import Login from './views/Login.vue' 1 +import Login from './views/Login1.vue'
2 import NotFound from './views/404.vue' 2 import NotFound from './views/404.vue'
3 import Home from './views/Home.vue' 3 import Home from './views/Home.vue'
4 import HomeNew from './views/HomeNew.vue' 4 import HomeNew from './views/HomeNew.vue'
  1 +<template>
  2 + <div class="backgroud">
  3 + <el-row>
  4 + <el-col :xs="{span: 22, offset: 1}" :sm="{span: 12, offset: 6}" :md="{span: 8, offset: 8}" :lg="{span: 6, offset: 9}" :xl="{span: 6, offset: 9}" :style="fixStyle" id="loginCol">
  5 + <el-form :model="ruleForm2" :rules="rules2" ref="ruleForm2" label-position="left" label-width="0px" class="demo-ruleForm login-container" id="loginForm">
  6 + <h3 class="title">系统登录</h3>
  7 + <el-form-item prop="account">
  8 + <el-input type="text" v-model="ruleForm2.account" autofocus placeholder="账号"></el-input>
  9 + </el-form-item>
  10 + <el-form-item prop="checkPass">
  11 + <el-input type="password" v-model="ruleForm2.checkPass" placeholder="密码" @keydown.enter.native="keyDown" show-password></el-input>
  12 + </el-form-item>
  13 + <el-form-item prop="verify">
  14 + <el-input type="text" v-model="ruleForm2.verify" placeholder="请在2分钟内输入下方图片中的答案" @keyup.enter.native="handleSubmit2"></el-input>
  15 + </el-form-item>
  16 + <el-form-item>
  17 + <img
  18 + style="width: 98%; height: 60px"
  19 + :src="verifyImg"
  20 + @click="getVerifyCode"
  21 + >
  22 + </el-form-item>
  23 + <el-checkbox v-model="checked" checked class="remeberme">记住密码</el-checkbox>
  24 + <el-form-item style="width:100%;">
  25 + <el-button type="primary" style="width:100%;" @click.native.prevent="handleSubmit2" :loading="logining" :plain="true">登录</el-button>
  26 + <!--<el-button @click.native.prevent="handleReset2">重置</el-button>-->
  27 + </el-form-item>
  28 + </el-form>
  29 + </el-col>
  30 + </el-row>
  31 + </div>
  32 +</template>
  33 +
  34 +<script>
  35 +import {getRandCode} from "@/api/user";
  36 +import {mapActions} from 'vuex'
  37 +import http from "@/api/http";
  38 +import axios from 'axios'
  39 +
  40 +export default {
  41 + name: 'App',
  42 + data() {
  43 + return {
  44 + verifyImg: "",
  45 + vedioCanPlay: false,
  46 + fixStyle: '',
  47 + logining: false,
  48 + ruleForm2: {
  49 + account: '',
  50 + // checkPass: 'zzairport@kako2020'
  51 + checkPass: '',
  52 + verify: '',
  53 + verifyToken: ''
  54 + },
  55 + rules2: {
  56 + account: [
  57 + { required: true, message: '请输入账号', trigger: 'blur' },
  58 + //{ validator: validaePass }
  59 + ],
  60 + checkPass: [
  61 + { required: true, message: '请输入密码', trigger: 'blur' },
  62 + //{ validator: validaePass2 }
  63 + ],
  64 + checkVerify: [
  65 + { required: false, message: '请输入验证码', trigger: 'blur' }
  66 + ]
  67 + },
  68 + checked: false,
  69 + userMenus: []
  70 + }
  71 + },
  72 + methods: {
  73 + ...mapActions( // 语法糖
  74 + ['setUserInfoStore'] // 相当于this.$store.dispatch('modifyName'),提交这个方法
  75 + ),
  76 + getVerifyCode: function(){
  77 + getRandCode().then((res) =>{
  78 + let status = res.status;
  79 + this.ruleForm2.verifyToken = res.data.jwtToken;
  80 + this.verifyImg = res.data.data.verifyImg;
  81 + }).catch(error => {
  82 + this.$message({
  83 + message: "验证码获取失败:"+error.toString(),
  84 + type: "error"
  85 + });
  86 + });
  87 + },
  88 + fixLoginHeight:function (){
  89 + const windowHeight = document.body.clientHeight
  90 + const colElement = document.getElementById("loginCol")
  91 + if (colElement) {
  92 + const col_height = colElement.offsetHeight; // 获取元素的高度
  93 + this.fixStyle = {
  94 + 'margin-top': (windowHeight - col_height) / 2 + 'px',
  95 + }
  96 + }
  97 + },
  98 + handleMenuList : function (router,menu) {
  99 + var _this = this;
  100 + var routerName = "";
  101 + var routerTemp = router.concat();
  102 +
  103 + routerTemp.forEach(function (v_router,v_index,v_arr) {
  104 + routerName = v_router.name;
  105 +
  106 + //查找返回的目录列表是否包含路由名称,有就返回匹配到的元素,没有就移除
  107 + let result = menu.find(item => {
  108 + return item.name === routerName;
  109 + });
  110 +
  111 + //匹配到继续判断是否子元素,有子元素继续递归
  112 + if (result) {
  113 + if (v_router.children && v_router.children.length>0) {
  114 + _this.handleMenuList(v_router.children, result.children);
  115 + }
  116 + }else {
  117 + //没有则可以移除
  118 + let deletRouter = router.findIndex(itm => itm.name === routerName );
  119 + router.splice(deletRouter,1);
  120 + }
  121 + });
  122 + // console.log("longined router:");
  123 + // console.log(routerName);
  124 + // console.log(_this.$router.options.routes);
  125 +// 本地存储用户目录 ,防刷新目录丢失用
  126 + sessionStorage.setItem('menu', JSON.stringify(_this.$router.options.routes));
  127 + },
  128 + handleSubmit2: function (ev) {
  129 + var _this = this;
  130 + this.$refs.ruleForm2.validate((valid) => {
  131 + if (valid) {
  132 + //_this.$router.replace('/table');
  133 + this.logining = true;
  134 + //NProgress.start();
  135 + var loginParams = {
  136 + username: this.ruleForm2.account,
  137 + password: this.ruleForm2.checkPass,
  138 + verify: this.ruleForm2.verify,
  139 + verifyToken:this.ruleForm2.verifyToken
  140 + };
  141 + http.login(loginParams).then(res => {
  142 + this.logining = false;
  143 + //NProgress.done();
  144 + let status = res.status;
  145 + let authentication = res.data.authentication;
  146 + let token = authentication.token;
  147 + let loginUserMenus = res.data.loginUserMenus;
  148 + if (status !== 200) {
  149 + this.getVerifyCode();
  150 + let msg = "登录错误";
  151 + this.$message({
  152 + message: msg,
  153 + type: "error"
  154 + });
  155 + } else if (token) {
  156 + sessionStorage.setItem('user', JSON.stringify(authentication));
  157 + sessionStorage.setItem('token','Bearer '+ token);
  158 + this.setUserInfoStore(authentication);
  159 + //设置token,设置axios 基本配置,但是刷新后 这个登录保存的就没了
  160 + axios.defaults.headers.common['Authorization'] = 'Bearer '+token;
  161 + //处理用户menu
  162 + _this.userMenus = loginUserMenus.list;
  163 + let sysMenus = _this.$router.options.routes;
  164 + _this.handleMenuList(_this.$router.options.routes,_this.userMenus);
  165 + _this.$router.push({path: '/main'});
  166 + }
  167 + }).catch(error => {
  168 + this.$message({
  169 + message: error.toString()+"-登录验证失败;",
  170 + type: "error"
  171 + });
  172 + this.getVerifyCode();
  173 + }).finally(()=>{
  174 + this.logining = false;
  175 + });
  176 + } else {
  177 + return false;
  178 + }
  179 + });
  180 + }
  181 + },
  182 + mounted:function (){
  183 + this.$store.commit('set_user_menu', []);
  184 + this.$store.commit('set_user_info', {
  185 + userId: 0,
  186 + username: '',
  187 + companyId: 0,
  188 + companyName: '',
  189 + realname: '',
  190 + userface: '',
  191 + companyInfo:{}
  192 + });
  193 + this.$nextTick(() => {
  194 + window.onresize = () => {
  195 + this.fixLoginHeight()
  196 + }
  197 + window.onresize();
  198 + })
  199 +
  200 + document.onkeydown = function (e) {
  201 + let key = window.event.keyCode;
  202 + if (key == 13) {
  203 + _this.handleSubmit2();
  204 + }
  205 + };
  206 +
  207 + },
  208 + created(){
  209 + this.getVerifyCode()
  210 + },
  211 +}
  212 +</script>
  213 +
  214 +<style lang="scss" scoped>
  215 + #loginForm{
  216 + filter:alpha(Opacity=80);
  217 + -moz-opacity:0.8;
  218 + opacity: 0.8;
  219 + }
  220 + .backgroud {
  221 + width: 100%;
  222 + height: 100vh; /* 设置为视口高度 */
  223 + z-index: 1;
  224 + position: absolute;
  225 + background:url("/static/login/login_backgroud.jpg") rgba(0, 0, 0, 0.4);
  226 + }
  227 + .login-container {
  228 + /*box-shadow: 0 0px 8px 0 rgba(0, 0, 0, 0.06), 0 1px 0px 0 rgba(0, 0, 0, 0.02);*/
  229 + -webkit-border-radius: 5px;
  230 + border-radius: 5px;
  231 + -moz-border-radius: 5px;
  232 + background-clip: padding-box;
  233 + padding: 35px 35px 15px 35px;
  234 + background: #fff;
  235 + border: 1px solid #eaeaea;
  236 + box-shadow: 0 0 25px #cac6c6;
  237 + .title {
  238 + margin: 0px auto 40px auto;
  239 + text-align: center;
  240 + color: #505458;
  241 + }
  242 + .remember {
  243 + margin: 0px 0px 35px 0px;
  244 + }
  245 + }
  246 +</style>
@@ -68,6 +68,7 @@ @@ -68,6 +68,7 @@
68 end-placeholder="结束日期" 68 end-placeholder="结束日期"
69 size="small" 69 size="small"
70 value-format="yyyy-MM-dd HH:mm:ss" 70 value-format="yyyy-MM-dd HH:mm:ss"
  71 + :picker-options="pickerOptions"
71 clearable> 72 clearable>
72 </el-date-picker> 73 </el-date-picker>
73 </el-col> 74 </el-col>
@@ -148,7 +149,7 @@ @@ -148,7 +149,7 @@
148 </el-input> 149 </el-input>
149 </el-drawer> 150 </el-drawer>
150 151
151 - <v-md-editor v-model="reskResult" height="400px" :default-show-toc="true" :include-level="[1,2,3,4,5]"></v-md-editor> 152 + <v-md-editor v-model="reskResult" height="400px" :default-show-toc="true" :include-level="[1,2,3,4,5]" left-toolbar="undo redo" ></v-md-editor>
152 153
153 <!-- Dialog --> 154 <!-- Dialog -->
154 <el-dialog :title="dialogStateMap[dialogType]" :visible.sync="showDialog" width="80%"> 155 <el-dialog :title="dialogStateMap[dialogType]" :visible.sync="showDialog" width="80%">
@@ -200,6 +201,33 @@ export default { @@ -200,6 +201,33 @@ export default {
200 dialogType: 'view', 201 dialogType: 'view',
201 showDialog: false, 202 showDialog: false,
202 formData: {}, 203 formData: {},
  204 + pickerOptions: {
  205 + shortcuts: [{
  206 + text: '最近一周',
  207 + onClick(picker) {
  208 + const end = new Date();
  209 + const start = new Date();
  210 + start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
  211 + picker.$emit('pick', [start, end]);
  212 + }
  213 + }, {
  214 + text: '最近一个月',
  215 + onClick(picker) {
  216 + const end = new Date();
  217 + const start = new Date();
  218 + start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
  219 + picker.$emit('pick', [start, end]);
  220 + }
  221 + }, {
  222 + text: '最近三个月',
  223 + onClick(picker) {
  224 + const end = new Date();
  225 + const start = new Date();
  226 + start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
  227 + picker.$emit('pick', [start, end]);
  228 + }
  229 + }]
  230 + },
203 rules: { 231 rules: {
204 // Form validation rules go here, for example: 232 // Form validation rules go here, for example:
205 mailId: [ 233 mailId: [