0412dfcd by yangwei

自定义登录

1 parent 69c583cc
<!--
* @Description:
* @Autor: renchao
* @LastEditTime: 2023-06-02 09:47:57
* @LastEditTime: 2023-06-20 09:56:19
-->
<!DOCTYPE html>
<html>
......@@ -22,7 +22,7 @@
cloudEnable: false,
baseUrl: location.origin || location.protocol + '//' + location.host,
// 是否启用单点登录
casEnable: true,
casEnable: false,
// cas 基地址
casBaseURL: 'http://192.168.2.38/cas',
services: {
......
......@@ -25,6 +25,7 @@
import { mapGetters } from 'vuex'
import NoticeBar from '@/components/NoticeBar/index'
import { getHomeNoticeList } from "@/api/home"
import {setToken} from "@/utils/util";
export default {
components: {
NoticeBar
......@@ -64,23 +65,11 @@
})
},
logout () {
axios.post(this.BASE_API.ip + "/management/logout").then(() => {
if (process.env.NODE_ENV === 'development') {
localStorage.removeItem('token')
} else {
Cookies.remove('ACCESS_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
}
})
}
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);
})
},
......
/*
* @Description: 项目权限
* @Autor: renchao
* @LastEditTime: 2023-06-13 16:28:25
* @LastEditTime: 2023-06-20 10:07:56
*/
import Vue from 'vue'
import axios from 'axios'
......@@ -9,10 +9,10 @@ import router from './router'
import store from './store'
import Cookies from 'js-cookie'
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 {getToken, getUrlParam, setToken} from "@/utils/util";
NProgress.configure({ showSpinner: false }) // NProgress Configuration
......@@ -23,36 +23,51 @@ router.beforeEach(async (to, from, next) => {
let hasAddDict = store.state.dict.addDict
let hasAddRoute = store.state.permission.addRoutes
// cas操作
const token = localStorage.getItem("token") || Cookies.get('ACCESS_TOKEN');
if (to.path === '/login') {
if (token) {
next('/')
} else {
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('dj-location') + '#' + localStorage.getItem('hash')
} else {
alert(res.data.message)
}
}).catch((e) => {
console.log(e);
});
}
async function permission () {
if (!hasAddDict) {
store.dispatch('dict/generateDic')
}
if (hasAddRoute) {
next()
// next({ ...to, replace: true })
} else {
const { result: getMenuData } = await getMenuInfo()
const accessRoutes = await store.dispatch('permission/generateRoutes', getMenuData)
// 获取用户信息
await store.dispatch('user/getUserInfo')
router.addRoutes([...accessRoutes, { path: '*', redirect: '/404', hidden: true }])
const routeTo = Cookies.get('routerTo')
if (routeTo && routeTo !== '/') {
next({ ...to, replace: true })
} else {
next('/home')
}
}
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('ACCESS_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,44 +75,43 @@ router.beforeEach(async (to, from, next) => {
} else {
permission()
}
async function permission () {
if (!hasAddDict) {
store.dispatch('dict/generateDic')
}
if (hasAddRoute) {
next()
// next({ ...to, replace: true })
} else {
const { result: getMenuData } = await getMenuInfo()
const accessRoutes = await store.dispatch('permission/generateRoutes', getMenuData)
// 获取用户信息
await store.dispatch('user/getUserInfo')
router.addRoutes([...accessRoutes, { path: '*', redirect: '/404', hidden: true }])
const routeTo = Cookies.get('routerTo')
if (routeTo && routeTo !== '/') {
next({ ...to, replace: true })
} else {
next('/home')
}
}
}
} 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('dj-location',locationUrl)
localStorage.setItem('hash',to.fullPath)
window.location.href = window._config.services.management + `/management/cas/status?loginUrl=${window._config.baseUrl}/dj/&hash=/login&`
return
}
}
localStorage.setItem('dj-location',locationUrl)
localStorage.setItem('hash',to.fullPath)
//todo: loginUrl 需要业务系统根据登录页面路由地址获取,这里只是简写
window.location.href = window._config.services.management + `/management/cas/status?loginUrl=${window._config.baseUrl}/dj/&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()
})
......
......@@ -72,6 +72,14 @@ export const constantRoutes = [
}
]
},
// 登录页
{
path: '/login',
component: () => import('@/views/login/index'),
name: 'login',
hidden: true,
meta: { title: '登录' }
},
]
/**
* asyncRoutes
......
......@@ -114,27 +114,6 @@ export function down (index, data) {
}
}
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: 身份证读卡器
* @author: renchao
......
......@@ -2,13 +2,13 @@
/*
* @Description: 此文件主要创建 axios 实例,然后添加请求拦截器和响应拦截器
* @Autor: renchao
* @LastEditTime: 2023-06-13 17:16:13
* @LastEditTime: 2023-06-20 10:12:53
*/
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,7 +27,7 @@ const service = axios.create({
service.interceptors.request.use(
config => {
if (process.env.NODE_ENV === 'development') {
const token = localStorage.getItem('token')
const token = getToken()
// 添加请求头
if (token) {
config.headers['Authorization'] = 'Bearer ' + token
......@@ -67,11 +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('ACCESS_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
<?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
<template>
<div id="login">
<div class="login-logo"><img src="./images/logo-login.png" /></div>
<div class="login-con">
<!-- <div class="login-title">用户登录</div>-->
<div class="login-user" :class="{ 'select-border': change.user }">
<img class="user-icon" src="./images/user.svg" />
<!-- <div class="line-mid"></div>-->
<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" />
<!-- <div class="line-mid"></div>-->
<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-remake">
<i
class="icon iconfont iconfuxuan1 icon-style"
v-show="!selectIcon"
@click="selectRemeber"
></i>
<i
class="icon iconfont iconfuxuan-xuanzhong icon-select"
v-show="selectIcon"
@click="selectRemeber"
></i>
<span class="remake_txt" @click="selectRemeber">记住账号密码</span>
</div> -->
<div id="loginBtn" class="login-btn" @click="goHome">登录</div>
</div>
<div class="reserved-con">
<!-- <div class="reserved-words">版权所有:2020©某某市自然资源和规划</div> -->
<div class="reserved-words line-two">
技术支持:爬山虎科技股份有限公司
</div>
</div>
</div>
</template>
<script>
import {getUrlParam} from "@/utils/util";
import axios from "axios";
export default {
data() {
return {
selectIcon: true,
selectEye: false,
userInfo:{
username: 'admin',
password: '123',
redirectUrl: ''
},
change: {
//边框
user: false,
pass: false,
},
warning: {
user: false,
pass: false,
},
canDo: 1,
};
},
mounted() {
this.initPage();
this.userInfo.redirectUrl = localStorage.getItem('dj-location')
},
methods: {
initPage() {
let userInfo =
localStorage.getItem("userInfo") &&
JSON.parse(localStorage.getItem("userInfo"));
if (userInfo) {
this.userInfo.username = userInfo.username;
this.userInfo.password = userInfo.password;
}
},
selectRemeber() {
this.selectIcon = !this.selectIcon;
},
goHome() {
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)
})
},
selectEyes() {
this.selectEye = !this.selectEye;
},
reduceBorder(type) {
//获取焦点
if (type == "user") {
this.change.user = true;
} else {
this.change.pass = true;
}
},
addBorder(type) {
//失去焦点
if (type == "user") {
this.change.user = false;
if (!this.userInfo.username) {
this.warning.user = true;
} else {
this.warning.user = false;
}
} else {
this.change.pass = false;
if (!this.userInfo.password) {
this.warning.pass = true;
} else {
this.warning.pass = false;
}
}
},
},
};
</script>
<style lang="scss" scoped>
#login {
width: 100vw;
height: 100vh;
background: url("./images/login-bg.png") no-repeat bottom center;
background-size: 100% 100%;
overflow: hidden;
.login-logo {
margin-top: 8%;
height: 38px;
width: 100%;
text-align: center;
}
.login-logo img {
height: 100%;
}
.login-con {
margin: 88px auto;
width: 380px;
}
.login-user {
width: 100%;
height: 46px;
border: 1px solid rgba(155, 155, 155, 1);
box-sizing: border-box;
margin: 38px auto auto auto;
border-radius: 2px;
position: relative;
.user-icon {
float: left;
margin: 13px auto auto 10px;
width: 28px;
height: 18px;
}
.user-input {
width: 80%;
float: left;
font-size: 16px;
outline: 0;
border: none;
color: #4a4a4a;
line-height: 260%;
background-color: transparent;
}
.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;
}
}
.user-mt {
margin-top: 26px;
}
.select-border {
border: 1px solid rgba(0, 113, 255, 1);
}
.login-remake {
width: 320px;
height: 14px;
margin: 0 auto;
margin-top: 26px;
.icon-style {
font-size: 12px;
color: #5b5b5b;
float: left;
line-height: 14px;
cursor: pointer;
}
.icon-select {
font-size: 12px;
color: rgba(0, 127, 255, 1);
float: left;
line-height: 14px;
cursor: pointer;
}
.remake_txt {
font-size: 12px;
line-height: 14px;
color: #5b5b5b;
margin-left: 6px;
float: left;
cursor: pointer;
}
}
.login-btn {
width: 100%;
height: 40px;
background: rgba(0, 127, 255, 1);
border-radius: 4px;
margin: 0 auto;
margin-top: 40px;
font-size: 16px;
line-height: 40px;
text-align: center;
color: #fff;
cursor: pointer;
}
.reserved-con {
margin: 38px auto;
}
.reserved-words {
font-size: 12px;
color: #b4b4b4;
text-align: center;
}
.line-two {
margin-top: 8px;
}
}
</style>
\ No newline at end of file