4643c4c4 by renchao@pashanhoo.com

Merge branch 'dev'

2 parents 42045f44 50d4471c
<!--
* @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,99 +17,92 @@
</div>
</template>
<script>
import axios from 'axios'
import Cookies from 'js-cookie'
import { mapGetters } from 'vuex'
import Breadcrumb from './Breadcrumb'
export default {
components: {
Breadcrumb
import axios from "axios";
import { mapGetters } from "vuex";
import Breadcrumb from "./Breadcrumb";
import { setToken } from "@/utils/util";
export default {
components: {
Breadcrumb,
},
computed: {
...mapGetters(["userInfo"]),
userName() {
return this.userInfo ? this.userInfo.name : "";
},
computed: {
...mapGetters(["userInfo"]),
userName () {
return this.userInfo ? this.userInfo.name : ""
}
},
methods: {
handleDataView() {
const { href } = this.$router.resolve("/dataView");
window.open(href, "_blank");
},
methods: {
handleDataView () {
const { href } = this.$router.resolve('/dataView');
window.open(href, '_blank');
},
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
}
})
}
})
}
}
}
themeChange(val) {
this.$store.dispatch("app/updateTheme", val);
},
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 {
position: relative;
.navbar-con {
position: relative;
.logo {
color: #fff;
font-size: 26px;
font-weight: 700;
display: flex;
margin-left: 15px;
.logo {
color: #fff;
font-size: 26px;
font-weight: 700;
display: flex;
margin-left: 15px;
img {
width: 47px;
height: 47px;
}
img {
width: 47px;
height: 47px;
}
h4 {
margin-left: 20px;
height: 50px;
line-height: 50px;
}
h4 {
margin-left: 20px;
height: 50px;
line-height: 50px;
}
}
}
.navbar {
height: $headerHeight;
overflow: hidden;
position: relative;
@include background("navbg");
.navbar {
height: $headerHeight;
overflow: hidden;
position: relative;
@include background("navbg");
display: flex;
align-items: center;
padding-right: 20px;
justify-content: space-between;
display: flex;
align-items: center;
padding-right: 20px;
justify-content: space-between;
.header-logo {
width: 300px;
}
.header-logo {
width: 300px;
}
.right-menu-item {
&.hover-effect {
cursor: pointer;
transition: background 0.3s;
display: flex;
align-items: center;
}
.right-menu-item {
&.hover-effect {
cursor: pointer;
transition: background 0.3s;
display: flex;
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,36 +25,59 @@ 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('/')
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,
},
}).then(async (res) => {
if (res.data.status === 1) {
setToken(res.data.content.accessToken)
window.location.href = localStorage.getItem('sjsb-location') + '#' + localStorage.getItem('hash')
} else {
alert(res.data.message)
}
}).catch((e) => {
console.log(e);
});
}
async function permission () {
if (!hasUser) {
store.dispatch("user/getUserInfo");
if (!hasAddDict) {
await store.dispatch("dict/generateDic");
}
}
if (hasAddRoute) {
next();
} else {
next()
//请求菜单
const { result: getMenuData } = (await getMenuInfo(Vue.prototype.BASE_API.CODE)) || [];
const accessRoutes = await store.dispatch(
"permission/generateRoutes",
getMenuData
);
let path = JSON.parse(getMenuData[0].metadata)?.path + JSON.parse(getMenuData[0].children[0].metadata)?.path
router.addRoutes([
...accessRoutes,
{ path: "*", redirect: "/404", hidden: true }
]);
const routeTo = Cookies.get("routerTo");
if (routeTo && routeTo !== "/") {
next({ ...to, replace: true });
} else {
next(path)
}
}
return
}
if (window._config.casEnable === true) {
let locationUrl = window.location.protocol + '//' + window.location.host + window.location.pathname;
if (!token) {
let ticket = getUrlParam('ticket');
let ticket = getUrlParam("ticket");
if (ticket) {
axios.get(Vue.prototype.BASE_API.ip + "/management/cas/validate", {
params: {
'ticket': ticket,
'service': locationUrl
}
}).then(async (res) => {
if (process.env.NODE_ENV === 'development') {
localStorage.setItem('token', res.data.content.accessToken)
} else {
Cookies.set('token', res.data.content.accessToken)
}
window.location.href = localStorage.getItem('location')
}).catch(e => {
console.log(e)
})
casValidate(ticket)
} else {
localStorage.setItem("location", window.location.href)
window.location.href = window._config.casBaseURL + '/login?service=' + encodeURIComponent(locationUrl);
......@@ -60,51 +85,43 @@ router.beforeEach(async (to, from, next) => {
} else {
permission()
}
async function permission () {
if (!hasUser) {
store.dispatch("user/getUserInfo");
if (!hasAddDict) {
await store.dispatch("dict/generateDic");
}
}
if (hasAddRoute) {
next();
} else {
//请求菜单
const { result: getMenuData } = (await getMenuInfo(Vue.prototype.BASE_API.CODE)) || [];
const accessRoutes = await store.dispatch(
"permission/generateRoutes",
getMenuData
);
let path = JSON.parse(getMenuData[0].metadata)?.path + JSON.parse(getMenuData[0].children[0].metadata)?.path
router.addRoutes([
...accessRoutes,
{ path: "*", redirect: "/404", hidden: true }
]);
const routeTo = Cookies.get("routerTo");
if (routeTo && routeTo !== "/") {
next({ ...to, replace: true });
} else {
next(path)
}
}
}
} 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
}
}
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`
}
if (to.path) {
redirectData.query = {
...redirectData.query,
redirect: to.path,
};
}else{
if (to.path === '/login') {
const redirectUrl = getUrlParam('redirectUrl');
if (redirectUrl && redirectUrl !== '') {
window.location.href = redirectUrl
return
} else {
next('/');
return
}
}
next(redirectData)
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 '';
}
}
......
/*
* @Description: 此文件主要创建 axios 实例,然后添加请求拦截器和响应拦截器
* @Autor: renchao
* @LastEditTime: 2023-06-08 09:02:53
* @LastEditTime: 2023-06-26 09:24:00
*/
import Vue from 'vue'
import axios from 'axios'
import Router from '@/router'
import Cookies from 'js-cookie'
import { Message } from 'element-ui'
import { endLoadingSubCount } from './requestLoading'
import {getToken, setToken} from "@/utils/util";
// create an axios instance
const service = axios.create({
......@@ -27,15 +27,7 @@ const service = axios.create({
service.interceptors.request.use(
config => {
if (process.env.NODE_ENV === 'development') {
const token = localStorage.getItem('token')
// 添加请求头
if (token) {
config.headers['Authorization'] = 'Bearer ' + token
} else {
config.headers.delete('Authorization')
}
} else {
const token = Cookies.get('token')
const token = getToken()
// 添加请求头
if (token) {
config.headers['Authorization'] = 'Bearer ' + token
......@@ -75,12 +67,8 @@ service.interceptors.response.use(
window.__isNeedLogin = false
Message.error('token失效,请重新登录');
let locationUrl = window.location.protocol + '//' + window.location.host + window.location.pathname;
if (process.env.NODE_ENV === 'development') {
localStorage.removeItem('token')
} else {
Cookies.remove('token')
}
setToken(undefined)
sessionStorage.removeItem('token')
if (window._config.casEnable) {
window.location.href = window._config.casBaseURL + '/logout?service=' + encodeURIComponent(locationUrl);
} else {
......
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')
}
<?xml version="1.0" encoding="UTF-8"?>
<svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 56.3 (81716) - https://sketch.com -->
<title>隐藏</title>
<desc>Created with Sketch.</desc>
<g id="隐藏" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path d="M6.03072945,10.4919039 L5.73253111,12.7244564 C5.69597191,12.998168 5.44444773,13.190418 5.17073614,13.1538588 C4.89702455,13.1172996 4.70477455,12.8657754 4.74133375,12.5920638 L5.06197696,10.1914709 C4.16952851,9.84883526 3.3412638,9.33963486 2.57840414,8.66573829 L1.54490653,10.84056 C1.42638298,11.0899729 1.12811158,11.1960797 0.878698712,11.0775561 C0.629285844,10.9590326 0.52317909,10.6607612 0.641702643,10.4113483 L1.82431508,7.92273947 C1.1849111,7.22355926 0.59765863,6.39438608 0.0634190527,5.43653783 C-0.0710917064,5.19537095 0.0153701679,4.89082404 0.256537054,4.75631328 C0.49770394,4.62180252 0.802250844,4.7082644 0.936761603,4.94943128 C2.7218512,8.14995221 5.0622906,9.71807475 8.00009033,9.71807475 C10.9378901,9.71807475 13.2783295,8.14995221 15.0634191,4.94943128 C15.1979298,4.7082644 15.5024767,4.62180252 15.7436436,4.75631328 C15.9848105,4.89082404 16.0712724,5.19537095 15.9367616,5.43653783 C15.4384416,6.32998517 14.8939977,7.11147869 14.304129,7.77994884 L15.554597,10.4113483 C15.6731206,10.6607612 15.5670138,10.9590326 15.3176009,11.0775561 C15.0681881,11.1960797 14.7699167,11.0899729 14.6513931,10.84056 L13.5590961,8.54200484 C12.6449311,9.38205401 11.6347609,9.98078996 10.5307537,10.3348952 L10.8296734,12.5728484 C10.8662326,12.84656 10.6739826,13.0980842 10.400271,13.1346434 C10.1265594,13.1712026 9.87503523,12.9789526 9.83847602,12.705241 L9.5545725,10.5797109 C9.05379094,10.671864 8.53557174,10.7180748 8.00009033,10.7180748 C7.31528214,10.7180748 6.6587062,10.6424973 6.03072945,10.4919039 Z" id="形状结合" fill="#B4B4B4" fill-rule="nonzero"></path>
</g>
</svg>
\ No newline at end of file
This diff could not be displayed because it is too large.
<?xml version="1.0" encoding="UTF-8"?>
<svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 56.3 (81716) - https://sketch.com -->
<title>显示</title>
<desc>Created with Sketch.</desc>
<g id="显示" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path d="M8,13.5944821 C5.08783139,13.5944821 2.47901047,11.8330303 0.184843129,8.37324049 L3.55271368e-15,8.09448212 L0.184843129,7.81572374 C2.47901047,4.35593396 5.08783139,2.59448212 8,2.59448212 C10.9121686,2.59448212 13.5209895,4.35593396 15.8151569,7.81572374 L16,8.09448212 L15.8151569,8.37324049 C13.5209895,11.8330303 10.9121686,13.5944821 8,13.5944821 Z M8,3.59448212 C5.53379057,3.59448212 3.26813906,5.07524663 1.19270822,8.09448212 C3.26813906,11.1137176 5.53379057,12.5944821 8,12.5944821 C10.4662094,12.5944821 12.7318609,11.1137176 14.8072918,8.09448212 C12.7318609,5.07524663 10.4662094,3.59448212 8,3.59448212 Z M9.12299335,5.45693297 C8.68456104,5.73514629 8.39327462,6.2269821 8.39327462,6.78731592 C8.39327462,7.65519196 9.09205701,8.3587445 9.95404878,8.3587445 C10.2357938,8.3587445 10.5001026,8.28358173 10.7282737,8.15208542 C10.6331828,9.58403639 9.44941475,10.7158874 8.00308108,10.7158874 C6.49459548,10.7158874 5.27172629,9.48467042 5.27172629,7.96588735 C5.27172629,6.44710429 6.49459548,5.21588735 8.00308108,5.21588735 C8.40216026,5.21588735 8.78124917,5.30206019 9.12299335,5.45693297 Z" id="形状结合" fill="#0091FF" fill-rule="nonzero"></path>
</g>
</svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 56.3 (81716) - https://sketch.com -->
<title>password</title>
<desc>Created with Sketch.</desc>
<g id="password" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path d="M4.0011827,6.56400569 L4.0011827,4.87032377 C4.0011827,2.74881464 5.72100565,1.02899168 7.84251478,1.02899168 C9.96402392,1.02899168 11.6838469,2.74881464 11.6838469,4.87032377 L11.6838469,5.7928261 L10.7661998,5.7928261 L10.7661998,4.87032377 C10.7661998,3.25561712 9.45722144,1.94663874 7.84251478,1.94663874 C6.22780813,1.94663874 4.91882975,3.25561712 4.91882975,4.87032377 L4.91882975,6.56400569 L12.6850296,6.56400569 C13.4907156,6.56400569 14.1438531,7.21714323 14.1438531,8.02282922 L14.1438531,13.4028479 C14.1438531,14.2085339 13.4907156,14.8616714 12.6850296,14.8616714 L3,14.8616714 C2.19431401,14.8616714 1.54117647,14.2085339 1.54117647,13.4028479 L1.54117647,8.02282922 C1.54117647,7.21714323 2.19431401,6.56400569 3,6.56400569 L4.0011827,6.56400569 Z M3,7.48165275 C2.70111649,7.48165275 2.45882353,7.72394571 2.45882353,8.02282922 L2.45882353,13.4028479 C2.45882353,13.7017314 2.70111649,13.9440244 3,13.9440244 L12.6850296,13.9440244 C12.9839131,13.9440244 13.226206,13.7017314 13.226206,13.4028479 L13.226206,8.02282922 C13.226206,7.72394571 12.9839131,7.48165275 12.6850296,7.48165275 L3,7.48165275 Z" id="形状结合" fill="#6D7278" fill-rule="nonzero"></path>
</g>
</svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 56.3 (81716) - https://sketch.com -->
<title>user</title>
<desc>Created with Sketch.</desc>
<g id="user" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path d="M5.70040727,8.36338619 C4.96173204,8.70409103 4.31101884,9.24156453 3.78444015,9.95202823 C2.94870333,11.0788243 2.46666667,12.5978855 2.46666667,14.1120529 C2.46666667,14.2335891 2.59610246,14.3514362 2.77548069,14.3514362 L13.1661579,14.3514362 C13.3455361,14.3514362 13.4749719,14.2335891 13.4749719,14.1120529 C13.4749719,12.0278862 12.5626821,10.0351425 11.1096588,8.92092682 L11.6776024,8.18028444 C13.3693466,9.47755739 14.4083053,11.7469879 14.4083053,14.1120529 C14.4083053,14.7696063 13.8424825,15.2847695 13.1661579,15.2847695 L2.77548069,15.2847695 C2.09915609,15.2847695 1.53333333,14.7696063 1.53333333,14.1120529 C1.53333333,12.4013641 2.07738878,10.6868606 3.0347023,9.39614673 C3.53516209,8.7209228 4.13710805,8.17384176 4.81664416,7.7738283 C3.93912572,7.01707839 3.38576579,5.91929918 3.38576579,4.69637232 C3.38576579,2.40902821 5.3212908,0.556854908 7.69195361,0.556854908 C10.063179,0.556854908 11.9981414,2.40606943 11.9981414,4.69289423 C11.9981414,6.98023832 10.0626164,8.83241167 7.69195361,8.83241167 C6.97429417,8.83241167 6.29659602,8.66302531 5.70040727,8.36338619 Z M4.31909912,4.69637232 C4.31909912,6.45803072 5.82696798,7.89907833 7.69195361,7.89907833 C9.55611742,7.89907833 11.0648081,6.4553581 11.0648081,4.69289423 C11.0648081,2.93123585 9.55693923,1.49018824 7.69195361,1.49018824 C5.82778977,1.49018824 4.31909912,2.93390843 4.31909912,4.69637232 Z" id="形状结合" fill="#6D7278" fill-rule="nonzero"></path>
</g>
</svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1687311691503" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="10425" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M867.584 160.192c-149.632-16.928-262.208-57.408-334.592-120.352l-19.04-16.544-20.544 14.656C379.968 118.944 267.776 160 160 160H128v448c0 137.344 121.088 261.92 370.208 380.864l13.088 6.24 13.344-5.728C771.072 883.52 896 755.232 896 608V163.424l-28.416-3.232zM832 608c0 116.8-107.392 223.36-319.328 316.8C299.872 821.024 192 714.464 192 608V222.976c104.672-6.784 211.584-46.688 318.496-118.944C587.232 162.528 695.168 201.536 832 220.256V608z" p-id="10426" fill="#6D7278"></path><path d="M359.776 468.672a32 32 0 1 0-47.968 42.4l121.792 137.824c12.608 14.24 30.176 21.568 47.904 21.568a64.384 64.384 0 0 0 49.696-23.52l197.6-242.72a32 32 0 0 0-49.632-40.416l-197.6 242.688-121.792-137.824z" p-id="10427" fill="#6D7278"></path></svg>
\ No newline at end of file
<template>
<div id="login">
<div class="login-content-wrap">
<div class="login-logo"><img src="./images/logo-login.svg" /></div>
<div class="login-con">
<div class="login-wrap">
<p>用户登录</p>
<div class="login-user" :class="{ 'select-border': change.user }">
<img class="user-icon" src="./images/user.svg" />
<input
type="text"
class="user-input"
placeholder="请输入账号"
v-model="userInfo.username"
@focus="reduceBorder('user')"
@blur="addBorder('user')"
/>
<span class="warning" v-show="warning.user">账号不能为空</span>
</div>
<div class="login-user user-mt" :class="{ 'select-border': change.pass }">
<img class="user-icon" src="./images/password.svg" />
<input
type="password"
class="user-input"
placeholder="请输入密码"
v-model="userInfo.password"
v-show="!selectEye"
@focus="reduceBorder('pass')"
@blur="addBorder('pass')"
/>
<input
type="text"
class="user-input"
placeholder="请输入密码"
v-model="userInfo.password"
v-show="selectEye"
@focus="reduceBorder('pass')"
@blur="addBorder('pass')"
/>
<img
class="password-eye"
src="./images/open.svg"
@click="selectEyes"
v-show="selectEye"
/>
<img
class="password-eye"
src="./images/close.svg"
@click="selectEyes"
v-show="!selectEye"
/>
<span class="warning" v-show="warning.pass">密码不能为空</span>
</div>
<div class="login-user login-valid" :class="{ 'select-border': change.valid }">
<img class="user-icon" src="./images/valid.svg" />
<input
type="text"
class="user-input"
placeholder="请输入验证码"
v-model="userInfo.captchaCode"
@focus="reduceBorder('valid')"
@blur="addBorder('valid')"
/>
<img class="valid-img" :src="codeSrc" alt="暂无验证码" @click="reloadCaptcha">
<span class="warning" v-show="warning.valid">验证码不能为空</span>
</div>
<div id="loginBtn" class="login-btn" @click="goHome">登录</div>
</div>
</div>
</div>
</div>
</template>
<script>
import axios from "axios";
export default {
data() {
return {
// 用户名
selectIcon: true,
// 用户名
selectEye: false,
userInfo: {
// 用户名
username: "",
// 密码
password: "",
// 重定向地址
redirectUrl: "",
// 验证码key
captchaKey:'',
// 验证码值
captchaCode: ''
},
//边框
change: {
user: false,
pass: false,
valid:false
},
// 提示语
warning: {
user: false,
pass: false,
valid: false,
},
// 验证码图片地址
codeSrc:""
};
},
mounted() {
this.initPage();
this.userInfo.redirectUrl = localStorage.getItem("sjsb-location");
this.reloadCaptcha()
},
methods: {
// 更新验证码
reloadCaptcha(){
axios.get(window._config.services.management + "/management/captcha?format=json").then(res => {
if (res.data.status === 1) {
this.userInfo.captchaKey = res.data.content['dubhe.captcha']
this.codeSrc = res.data.content.image
}
})
},
// 初始化
initPage() {
let userInfo =
localStorage.getItem("userInfo") &&
JSON.parse(localStorage.getItem("userInfo"));
if (userInfo) {
this.userInfo.username = userInfo.username;
this.userInfo.password = userInfo.password;
}
},
// 登录
goHome() {
if (this.userInfo.username && this.userInfo.password) {
axios
.post(
window._config.services.management + "/management/cas/login",
this.userInfo
)
.then((response) => {
debugger
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);
});
} else {
return
}
},
selectEyes() {
this.selectEye = !this.selectEye;
},
//获取焦点
reduceBorder(type) {
this.change[type] = true
},
addBorder(type) {
//失去焦点
switch (type) {
case "user":
this.change.user = false;
if (!this.userInfo.username) {
this.warning.user = true;
} else {
this.warning.user = false;
}
break;
case "pass":
this.change.pass = false;
if (!this.userInfo.password) {
this.warning.pass = true;
} else {
this.warning.pass = false;
}
break;
case "valid":
this.change.valid = false;
if (!this.userInfo.captchaCode) {
this.warning.valid = true;
} else {
this.warning.valid = false;
}
break;
default:
break;
}
},
},
};
</script>
<style lang="scss" scoped>
input::placeholder{
color: #878787;
font-size: 14px;
font-family:Arial, Helvetica, sans-serif
}
#login {
width: 100vw;
height: 100vh;
background: url("./images/login-bg.png") no-repeat;
background-size: 100% 100%;
overflow: hidden;
position: relative;
.login-content-wrap{
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
.login-logo {
height: 70px;
width: 100%;
text-align: center;
position: absolute;
top: -70px;
}
.login-logo img {
height: 100%;
width: 486px;
}
.login-con {
margin: 14px auto;
width: 486px;
.login-wrap{
width: 100%;
height: 450px;
box-sizing: border-box;
padding: 48px 56px;
background: #FFFFFF;
box-shadow: 0px 7px 27px 0px rgba(133,169,231,0.51);
border-radius: 4px;
p{
width: 100%;
font-size: 20px;
font-weight: 500;
color: #333333;
line-height: 26px;
position: relative;
text-align: center;
}
}
}
.login-user {
width: 100%;
height: 40px;
border: 1px solid #E5E5E5;
box-sizing: border-box;
margin-top: 30px;
border-radius: 2px;
position: relative;
.user-icon {
float: left;
margin: 10px auto auto 10px;
width: 28px;
height: 18px;
}
.user-input {
width: 80%;
float: left;
font-size: 16px;
outline: 0;
border: none;
color: #4a4a4a;
height: 36px;
line-height: 40px;
}
.password-eye {
float: right;
width: 16px;
height: 16px;
margin-right: 12px;
margin-top: 13px;
cursor: pointer;
}
.warning {
font-size: 12px;
color: red;
position: absolute;
left: 0;
bottom: -18px;
}
}
.login-valid{
width: 60%;
.valid-img{
width: 50%;
position: absolute;
right: -66%;
top: 2px;
cursor: pointer;
}
}
.user-mt {
margin-top: 26px;
}
.select-border {
border: 1px solid rgba(0, 113, 255, 1);
}
.login-btn {
width: 100%;
height: 48px;
background: #4162D8;
border-radius: 2px;
margin: 0 auto;
margin-top: 40px;
font-size: 20px;
font-weight: 500;
line-height: 48px;
text-align: center;
color: #fff;
cursor: pointer;
}
}
</style>
......@@ -15,7 +15,7 @@ module.exports = {
* Detail: https://cli.vuejs.org/config/#publicpath
*/
// 加载资源的路径
publicPath: './',
publicPath: '/sjsb/',
// 设置项目打包生成的文件的存储目录,可以是静态路径也可以是相对路径
outputDir: 'dist',
// 设置放置打包生成的静态资源 (js、css、img、fonts) 的目录
......