4f2c3637 by yangwei

自定义登录

1 parent 9ec6679c
<!--
* @Description: 引入配置文件
* @Autor: renchao
* @LastEditTime: 2023-06-02 10:57:01
* @LastEditTime: 2023-06-20 11:24:04
-->
<!DOCTYPE html>
<html>
......@@ -23,7 +23,7 @@
cloudEnable: false,
baseUrl: location.origin || location.protocol + '//' + location.host,
// 是否启用单点登录
casEnable: true,
casEnable: false,
// cas 基地址
casBaseURL: 'http://192.168.2.38/cas',
services: {
......
......@@ -17,55 +17,48 @@
</div>
</template>
<script>
import axios from 'axios'
import Cookies from 'js-cookie'
import { mapGetters } from 'vuex'
import Breadcrumb from './Breadcrumb'
export default {
import axios from "axios";
import { mapGetters } from "vuex";
import Breadcrumb from "./Breadcrumb";
import { setToken } from "@/utils/util";
export default {
components: {
Breadcrumb
Breadcrumb,
},
computed: {
...mapGetters(["userInfo"]),
userName () {
return this.userInfo ? this.userInfo.name : ""
}
userName() {
return this.userInfo ? this.userInfo.name : "";
},
},
methods: {
handleDataView () {
const { href } = this.$router.resolve('/dataView');
window.open(href, '_blank');
handleDataView() {
const { href } = this.$router.resolve("/dataView");
window.open(href, "_blank");
},
themeChange (val) {
this.$store.dispatch('app/updateTheme', val)
themeChange(val) {
this.$store.dispatch("app/updateTheme", val);
},
onCancel () {
axios.post(this.BASE_API.ip + "/management/logout").then(() => {
if (process.env.NODE_ENV === 'development') {
localStorage.removeItem('token')
} else {
Cookies.remove('token')
}
if (window._config.casEnable) {
window.location.href = window._config.casBaseURL + '/logout?service=' + encodeURIComponent(window.location.href);
} else {
this.$router.push({
path: '/login',
replace: true,
query: {
redirect: router.currentRoute.value.fullPath
}
})
}
})
}
}
}
onCancel() {
axios
.post(window._config.services.management + "/management/logout")
.then(() => {
setToken(undefined);
sessionStorage.removeItem("token");
localStorage.setItem("dj-location", window.location.href);
window.location.href =
window._config.casBaseURL +
"/logout?service=" +
encodeURIComponent(window.location.href);
});
},
},
};
</script>
<style lang="scss" scoped>
@import "~@/styles/_handle.scss";
@import "~@/styles/_handle.scss";
.navbar-con {
.navbar-con {
position: relative;
.logo {
......@@ -86,9 +79,9 @@
line-height: 50px;
}
}
}
}
.navbar {
.navbar {
height: $headerHeight;
overflow: hidden;
position: relative;
......@@ -111,5 +104,5 @@
align-items: center;
}
}
}
}
</style>
......
/*
* @Description:
* @Autor: renchao
* @LastEditTime: 2023-06-09 09:43:07
* @LastEditTime: 2023-06-20 11:28:11
*/
import Vue from 'vue'
import axios from 'axios'
import store from "./store";
import router from "./router";
import { getMenuInfo } from "@/api/user";
import { getUrlParam } from '@/utils/operation';
import NProgress from "nprogress"; // progress bar
import "nprogress/nprogress.css"; // progress bar style
import getPageTitle from "@/utils/get-page-title";
import getTheme from "@/utils/theme";
import Cookies from "js-cookie";
import {getToken, getUrlParam, setToken} from "@/utils/util";
NProgress.configure({ showSpinner: false });
router.beforeEach(async (to, from, next) => {
getTheme()
NProgress.start();
......@@ -23,42 +25,24 @@ router.beforeEach(async (to, from, next) => {
let hasUser = store.state.user.hasUser;
let hasAddRoute = store.state.permission.addRoutes;
// cas操作
const token = localStorage.getItem("token") || Cookies.get('token');
if (to.path === '/login') {
if (token) {
next('/')
} else {
next()
}
return
}
if (window._config.casEnable === true) {
let locationUrl = window.location.protocol + '//' + window.location.host + window.location.pathname;
if (!token) {
let ticket = getUrlParam('ticket');
if (ticket) {
axios.get(Vue.prototype.BASE_API.ip + "/management/cas/validate", {
const token = getToken()
let locationUrl = window.location.origin + window.location.pathname;
function casValidate (ticket){
axios.get(window._config.services.management + "/management/cas/validate", {
params: {
'ticket': ticket,
'service': locationUrl
}
ticket: ticket,
service: locationUrl,
},
}).then(async (res) => {
if (process.env.NODE_ENV === 'development') {
localStorage.setItem('token', res.data.content.accessToken)
if (res.data.status === 1) {
setToken(res.data.content.accessToken)
window.location.href = localStorage.getItem('sjsb-location') + '#' + localStorage.getItem('hash')
} else {
Cookies.set('token', res.data.content.accessToken)
alert(res.data.message)
}
window.location.href = localStorage.getItem('location')
}).catch(e => {
console.log(e)
})
} else {
localStorage.setItem("location", window.location.href)
window.location.href = window._config.casBaseURL + '/login?service=' + encodeURIComponent(locationUrl);
}
} else {
permission()
}).catch((e) => {
console.log(e);
});
}
async function permission () {
if (!hasUser) {
......@@ -89,22 +73,55 @@ router.beforeEach(async (to, from, next) => {
}
}
}
if (window._config.casEnable === true) {
if (!token) {
let ticket = getUrlParam("ticket");
if (ticket) {
casValidate(ticket)
} else {
localStorage.setItem("location", window.location.href)
window.location.href = window._config.casBaseURL + '/login?service=' + encodeURIComponent(locationUrl);
}
} else {
permission()
}
} else {
// 使用自定义页面实现单点登录
if (!token) {
const redirectData = {
path: '/login',
replace: true,
let ticket = getUrlParam('ticket');
if (ticket) {
casValidate(ticket)
} else {
if (to.path === '/login') {
if (getUrlParam('_flag') === '1') {
next();
return
} else {
//todo: loginUrl 需要业务系统根据登录页面路由地址获取,这里只是简写
localStorage.setItem('sjsb-location',locationUrl)
localStorage.setItem('hash',to.fullPath)
window.location.href = window._config.services.management + `/management/cas/status?loginUrl=${window._config.baseUrl}/sjsb/&hash=/login&`
return
}
}
if (to.path) {
redirectData.query = {
...redirectData.query,
redirect: to.path,
};
localStorage.setItem('sjsb-location',locationUrl)
localStorage.setItem('hash',to.fullPath)
//todo: loginUrl 需要业务系统根据登录页面路由地址获取,这里只是简写
window.location.href = window._config.services.management + `/management/cas/status?loginUrl=${window._config.baseUrl}/sjsb/&hash=/login`
}
next(redirectData)
}else{
if (to.path === '/login') {
const redirectUrl = getUrlParam('redirectUrl');
if (redirectUrl && redirectUrl !== '') {
window.location.href = redirectUrl
return
} else {
next('/');
return
}
}
permission()
}
next()
}
NProgress.done()
});
......
/*
* @Description :路由配置
* @Autor : miaofang
* @LastEditTime: 2023-06-09 09:21:27
* @LastEditTime: 2023-06-20 11:09:57
*/
import Vue from 'vue'
import Router from 'vue-router'
......@@ -22,7 +22,15 @@ export const constantRoutes = [
meta: { title: '404' }
}
]
}
},
// 登录页
{
path: '/login',
component: () => import('@/views/login/index'),
name: 'login',
hidden: true,
meta: { title: '登录' }
},
]
/**
* asyncRoutes
......
......@@ -142,25 +142,4 @@ export function getFirstDayOfSeason (d) {
return timeFormat(date);
}
export function getUrlParam (paraName) {
let url = document.location.toString();
let arrObj = url.split('?');
if (arrObj.length > 1) {
let arrPara = arrObj[1].split('&');
let arr;
for (let i = 0; i < arrPara.length; i++) {
arr = arrPara[i].split('=');
if (arr != null && arr[0] === paraName) {
const index = arr[1].indexOf("#");
return arr[1].substring(0, index);
}
}
return '';
} else {
return '';
}
}
......
import Cookies from 'js-cookie'
const cookies = {}
/**
* @description 存储 cookie 值
* @param {String} name cookie name
* @param {String} value cookie value
* @param {Object} setting cookie setting
*/
cookies.set = function (name = 'default', value = '', cookieSetting = {}) {
let currentCookieSetting = {
expires: 1
}
Object.assign(currentCookieSetting, cookieSetting)
Cookies.set(`${name}`, value, currentCookieSetting)
}
/**
* @description 拿到 cookie 值
* @param {String} name cookie name
*/
cookies.get = function (name = 'default') {
return Cookies.get(`${name}`)
}
/**
* @description 拿到 cookie 全部的值
*/
cookies.getAll = function () {
return Cookies.get()
}
/**
* @description 删除 cookie
* @param {String} name cookie name
*/
cookies.remove = function (name = 'default') {
return Cookies.remove(`${name}`)
}
export default cookies
import cookies from './util.cookies'
export function getUrlParam(paraName) {
let url = document.location.toString();
let arrObj = url.split('?');
if (arrObj.length > 1) {
let arrPara = arrObj[1].split('&');
let arr;
for (let i = 0; i < arrPara.length; i++) {
arr = arrPara[i].split('=');
if (arr != null && arr[0] === paraName) {
// 截取#之前的内容
let result = arr[1].endsWith('#/') ? arr[1].substr(0, arr[1].indexOf('#')) : arr[1];
return result;
}
}
return '';
} else {
return '';
}
}
export function setToken(token) {
if (token === undefined) {
if (process.env.NODE_ENV === 'development') {
sessionStorage.removeItem('token')
} else {
cookies.remove('ACCESS_TOKEN')
}
} else {
if (process.env.NODE_ENV === 'development') {
sessionStorage.setItem('token', token);
} else {
cookies.set('ACCESS_TOKEN', token)
}
}
}
export function getToken() {
if (process.env.NODE_ENV === 'development') {
return sessionStorage.getItem('token')
}
return cookies.get('ACCESS_TOKEN')
}
<template>
<div class="bg">
<div class="title">
<img src="../../image/bdclogo.png" alt="" />
<h2>{{ BASE_API.TITLE }}</h2>
</div>
<div class="login-inner-bg login">
<div class="user_style">
<h3>用户登录</h3>
<el-form
:model="userInfo"
:rules="rules"
ref="user"
id="loginform"
class="demo-ruleForm"
>
<el-form-item prop="username">
<el-input
class="username"
v-model="userInfo.username"
placeholder="请输入用户名"
></el-input>
</el-form-item>
<el-form-item prop="password">
<el-input
type="password"
class="password"
@keyup.enter.native="login('user')"
v-model="userInfo.password"
placeholder="请输入密码"
show-password
></el-input>
</el-form-item>
<!-- <el-form-item prop="yz">
<div class="flex-container">
<div class="flex-input">
<el-input class="yz" @keyup.native="login('user')" v-model="userInfo.yz" placeholder="请输入验证码"></el-input>
</div>
<div class="flex-line"></div>
<div class="flex-img"><canvas id="s-canvas" ref="s-canvas"></canvas></div>
<div class="flex-renovate">
<font id="renovate" @click="verification">换一批</font>
</div>
</div>
</el-form-item> -->
<el-form-item class="login-btn">
<el-button type="primary" style="width: 100%" @click="login('user')"
>登录</el-button
>
</el-form-item>
</el-form>
</div>
</div>
</div>
</template>
<script>
import axios from "axios";
export default {
name: "sbLogin",
data() {
return {
userInfo: {
username: "admin",
password: "123",
redirectUrl: "",
yz: "",
checkStatus: false,
},
productName: "",
rules: {
username: [{ required: true, message: "请填写帐号", trigger: "blur" }],
password: [{ required: true, message: "请填写密码", trigger: "blur" }],
},
};
},
mounted() {
this.userInfo.redirectUrl = localStorage.getItem("sjsb-location");
},
methods: {
verification() {
let str = "1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ",
code = "",
i = 0;
for (; i++ < 4; )
code += str[Math.floor(Math.random() * (str.length - 0) + 0)];
setTimeout(() => {
let canvas = document.getElementById("s-canvas"),
ctx = canvas.getContext("2d");
canvas.width = 80;
canvas.height = 28;
ctx.fillStyle = "#ffffff";
ctx.fillRect(0, 0, 80, 28);
for (i = 0; i < code.length; i++) {
this.drawText(ctx, code[i], i);
}
}, 0);
},
drawText(ctx, txt, i) {
ctx.fillStyle = this.randomColor(50, 160);
ctx.font = "18px SimHei";
let x = (i + 1) * (80 / (4 + 1)),
y = this.randomNum(18, 28 - 5);
ctx.translate(x, y);
ctx.fillText(txt, 0, 0);
ctx.rotate((-0 * Math.PI) / 180);
ctx.translate(-x, -y);
},
randomColor(min, max) {
let r = this.randomNum(min, max);
let g = this.randomNum(min, max);
let b = this.randomNum(min, max);
return "rgb(" + r + "," + g + "," + b + ")";
},
randomNum(min, max) {
return Math.floor(Math.random() * (max - min) + min);
},
//记住用户名
checkUserName: function (flag) {
this.userInfo.checkStatus = flag;
if (this.userInfo.checkStatus) {
localStorage.setItem("usernameId", this.userInfo.username);
let name = localStorage.getItem("usernameId");
if (name === "") {
return;
} else {
this.userInfo.username = name;
}
} else {
this.userInfo.username = localStorage.getItem("usernameId");
}
},
login() {
axios.post(window._config.services.management + "/management/cas/login", this.userInfo).then(response => {
if (response.data.status === 1) {
if (response.data.content.location) {
window.location.href = response.data.content.location
}
} else {
this.$message.error(response.data.message)
}
}).catch(error => {
console.log(error)
this.$message.error(error.message)
})
},
},
};
</script>
<style scoped lang="scss">
.username,
.password,
.yz {
position: relative;
&:before {
content: "";
display: block;
width: 16px;
height: 16px;
position: absolute;
left: 10px;
top: 7px;
background-size: 100% 100%;
}
/deep/ .el-input__inner {
color: #000 !important;
text-indent: 24px;
}
}
.flex-container {
position: relative;
display: -webkit-flex;
display: flex;
}
.flex-input {
width: 100%;
}
.flex-line {
position: absolute;
width: 1px;
height: 64%;
margin: 5px;
right: 36%;
background-color: #cccccc;
}
.flex-img {
position: absolute;
margin: 2px;
right: 16%;
}
.flex-renovate {
position: absolute;
margin: 1px;
right: 3%;
}
#renovate {
color: #3f8fea;
font-size: 16px;
font-weight: 700;
cursor: pointer;
}
.username::before {
background-image: url(../../image/userlogo.png);
}
.password::before {
background-image: url(../../image/passlogo.png);
}
.yz::before {
background-image: url(../../image/yzlogo.png);
}
.bg {
width: 100%;
height: 100%;
min-width: 1440px;
min-height: 560px;
background: url(../../image/loginBoxsb.png) no-repeat;
background-size: 100% 100%;
overflow: hidden;
position: relative;
}
.title {
width: 24%;
height: 6%;
top: 20%;
right: 38%;
position: absolute;
img {
width: 60px;
height: 60px;
top: 0%;
left: 2%;
position: absolute;
}
h2 {
top: 25%;
left: 22%;
position: absolute;
width: 383px;
height: 42px;
font-size: 28px;
font-weight: 600;
color: #ffffff;
text-shadow: 0px 4px 4px #002c95;
}
}
.login-inner-bg {
background: white;
width: 24.6%;
min-width: 360px;
top: 30%;
right: 38%;
position: absolute;
background-size: 100% 100%;
box-sizing: border-box;
padding: 56px;
}
.login {
.user_style {
h3 {
font-weight: normal;
text-align: center;
margin: -10px auto 28px;
font-weight: 400;
width: 125px;
height: 29px;
font-size: 20px;
font-family: Source Han Sans CN;
font-weight: 400;
color: #333333;
}
}
.btn {
width: 100%;
height: 6vh;
background-color: #00c2de;
border-radius: 5px;
font-size: 1.4vw;
color: #000;
}
.btn:hover {
cursor: pointer;
background-color: #2d8cf0;
}
}
.login #loginform {
.el-form-item {
margin-bottom: 24px !important;
}
.login-btn {
margin-top: 30px !important;
}
.el-button {
font-size: 18px;
border-radius: 0;
background: #4162d8 !important;
color: #ffffff !important;
cursor: pointer !important;
}
.el-input__inner {
width: 100% !important;
}
.el-checkbox__label {
color: #fff;
}
}
.inputUser .ivu-input {
padding: 6px 24px !important;
border: 1px solid #9f9f9f !important;
}
</style>
......@@ -15,7 +15,7 @@ module.exports = {
* Detail: https://cli.vuejs.org/config/#publicpath
*/
// 加载资源的路径
publicPath: './',
publicPath: '/sjsb/',
// 设置项目打包生成的文件的存储目录,可以是静态路径也可以是相对路径
outputDir: 'dist',
// 设置放置打包生成的静态资源 (js、css、img、fonts) 的目录
......