|
|
@@ -1,5 +1,5 @@
|
|
|
<template>
|
|
|
-<div class="conatiner">
|
|
|
+ <div class="conatiner">
|
|
|
<div class="login-wrap">
|
|
|
<div class="top">
|
|
|
<!-- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1440 320"><path fill="#1890ff" fill-opacity="1" d="M0,288L48,266.7C96,245,192,203,288,202.7C384,203,480,245,576,245.3C672,245,768,203,864,202.7C960,203,1056,245,1152,272C1248,299,1344,309,1392,314.7L1440,320L1440,0L1392,0C1344,0,1248,0,1152,0C1056,0,960,0,864,0C768,0,672,0,576,0C480,0,384,0,288,0C192,0,96,0,48,0L0,0Z"></path></svg> -->
|
|
|
@@ -11,29 +11,14 @@
|
|
|
</div>
|
|
|
<a-tabs v-model:activeKey="activeKey" @change="tabsChange">
|
|
|
<a-tab-pane key="1" tab="账号登陆">
|
|
|
- <a-form
|
|
|
- :model="formState"
|
|
|
- name="basic"
|
|
|
- layout="vertical"
|
|
|
- autocomplete="off"
|
|
|
- @finish="onFinish"
|
|
|
- @finishFailed="onFinishFailed"
|
|
|
- size="large"
|
|
|
- >
|
|
|
- <a-form-item
|
|
|
- label="账号"
|
|
|
- name="phonenumber"
|
|
|
- :rules="[{ required: true, message: '请输入账号' }]"
|
|
|
- >
|
|
|
+ <a-form :model="formState" name="basic" layout="vertical" autocomplete="off" @finish="onFinish"
|
|
|
+ @finishFailed="onFinishFailed" size="large">
|
|
|
+ <a-form-item label="账号" name="phonenumber" :rules="[{ required: true, message: '请输入账号' }]">
|
|
|
<a-input v-model:value="formState.phonenumber" placeholder="请输入账号" />
|
|
|
</a-form-item>
|
|
|
|
|
|
- <a-form-item
|
|
|
- label="密码"
|
|
|
- name="password"
|
|
|
- :rules="[{ required: true, message: '请输入密码!' }]"
|
|
|
- >
|
|
|
- <a-input-password v-model:value="formState.password" placeholder="请输入密码"/>
|
|
|
+ <a-form-item label="密码" name="password" :rules="[{ required: true, message: '请输入密码!' }]">
|
|
|
+ <a-input-password v-model:value="formState.password" placeholder="请输入密码" />
|
|
|
</a-form-item>
|
|
|
|
|
|
<a-form-item name="remember">
|
|
|
@@ -46,33 +31,19 @@
|
|
|
</a-form>
|
|
|
</a-tab-pane>
|
|
|
<a-tab-pane key="2" tab="手机号登录" force-render>
|
|
|
- <a-form
|
|
|
- :model="formState"
|
|
|
- name="basic"
|
|
|
- layout="vertical"
|
|
|
- autocomplete="off"
|
|
|
- @finish="onPhoneLoginFinish"
|
|
|
- @finishFailed="onFinishFailed"
|
|
|
- size="large"
|
|
|
- >
|
|
|
- <a-form-item
|
|
|
- label="手机号"
|
|
|
- name="phonenumber"
|
|
|
- :rules="[{ required: true, message: '请输入手机号' }]"
|
|
|
- >
|
|
|
- <a-input v-model:value="formState.phonenumber" placeholder="请输入手机号"/>
|
|
|
+ <a-form :model="formState" name="basic" layout="vertical" autocomplete="off" @finish="onPhoneLoginFinish"
|
|
|
+ @finishFailed="onFinishFailed" size="large">
|
|
|
+ <a-form-item label="手机号" name="phonenumber" :rules="[{ required: true, message: '请输入手机号' }]">
|
|
|
+ <a-input v-model:value="formState.phonenumber" placeholder="请输入手机号" />
|
|
|
</a-form-item>
|
|
|
|
|
|
- <a-form-item
|
|
|
- label="验证码"
|
|
|
- name="password"
|
|
|
- :rules="[{ required: true, message: '请输入验证码!' }]"
|
|
|
- >
|
|
|
- <a-input v-model:value="formState.password" placeholder="请输入验证码">
|
|
|
- <template #suffix>
|
|
|
- <span style="cursor: pointer;" @click.native="countDown">{{count === 0?'点击获取验证码':count+ 's'}}</span>
|
|
|
- </template>
|
|
|
- </a-input>
|
|
|
+ <a-form-item label="验证码" name="password" :rules="[{ required: true, message: '请输入验证码!' }]">
|
|
|
+ <a-input v-model:value="formState.password" placeholder="请输入验证码">
|
|
|
+ <template #suffix>
|
|
|
+ <span style="cursor: pointer;" @click.native="countDown">{{ count === 0 ? '点击获取验证码' : count + 's'
|
|
|
+ }}</span>
|
|
|
+ </template>
|
|
|
+ </a-input>
|
|
|
</a-form-item>
|
|
|
|
|
|
<a-form-item>
|
|
|
@@ -81,7 +52,7 @@
|
|
|
</a-form>
|
|
|
</a-tab-pane>
|
|
|
</a-tabs>
|
|
|
-
|
|
|
+
|
|
|
</div>
|
|
|
</div>
|
|
|
<a-layout-footer class="footer">
|
|
|
@@ -90,11 +61,11 @@
|
|
|
</div>
|
|
|
</template>
|
|
|
<script>
|
|
|
-import { defineComponent, reactive,ref,createVNode } from 'vue';
|
|
|
+import { defineComponent, reactive, ref, createVNode } from 'vue';
|
|
|
import { useRouter } from "vue-router";
|
|
|
-import Api from '@/api/api'
|
|
|
+import Api from '@/api/api'
|
|
|
import md5 from 'js-md5'
|
|
|
-import { message,Modal } from 'ant-design-vue';
|
|
|
+import { message, Modal } from 'ant-design-vue';
|
|
|
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
|
|
|
import { useAuthStore } from '@/stores/modules/auth'
|
|
|
import { useRouteTabsStore } from '@/stores/modules/routeTabs'
|
|
|
@@ -118,38 +89,38 @@ export default defineComponent({
|
|
|
|
|
|
login()
|
|
|
};
|
|
|
- const onPhoneLoginFinish = (values)=>{
|
|
|
+ const onPhoneLoginFinish = (values) => {
|
|
|
loginByCode()
|
|
|
}
|
|
|
const onFinishFailed = (errorInfo) => {
|
|
|
console.log('Failed:', errorInfo);
|
|
|
};
|
|
|
- const checkAccountList = (res)=>{
|
|
|
+ const checkAccountList = (res) => {
|
|
|
if (res.code === 1) {
|
|
|
if (res.account_list[0].status == 'INACTIVE')
|
|
|
return message.error('当前账号已停用!')
|
|
|
-
|
|
|
+
|
|
|
loading.value = false
|
|
|
accountList.value = res.account_list
|
|
|
- store.defaultAccount(res.account_list[0],(mod)=>{
|
|
|
+ store.defaultAccount(res.account_list[0], (mod) => {
|
|
|
|
|
|
const loginTips = localStorage.getItem('loginTips')
|
|
|
|
|
|
if (res.remindchangepassword == 1) {
|
|
|
Modal.confirm({
|
|
|
- centered:true,
|
|
|
- zIndex:9999,
|
|
|
+ centered: true,
|
|
|
+ zIndex: 9999,
|
|
|
title: '提醒',
|
|
|
icon: createVNode(ExclamationCircleOutlined),
|
|
|
content: res.remindchangepassword_str,
|
|
|
okText: '确定',
|
|
|
onOk: () => {
|
|
|
sessionStorage.setItem('openPasDialog', '1')
|
|
|
- router.replace({ name: 'landing'});
|
|
|
+ router.replace({ name: 'landing' });
|
|
|
}
|
|
|
});
|
|
|
} else {
|
|
|
- router.replace({ name: 'landing'});
|
|
|
+ router.replace({ name: 'landing' });
|
|
|
}
|
|
|
})
|
|
|
} else {
|
|
|
@@ -157,46 +128,74 @@ export default defineComponent({
|
|
|
message.error(res.msg)
|
|
|
}
|
|
|
}
|
|
|
- const login = async ()=>{
|
|
|
+ const login = async () => {
|
|
|
loading.value = true
|
|
|
const res = await Api.loginbyaccount({
|
|
|
- "accountno":formState.phonenumber,
|
|
|
- "password":md5(formState.password),
|
|
|
+ "accountno": formState.phonenumber,
|
|
|
+ "password": md5(formState.password),
|
|
|
"systemclient": "web"
|
|
|
})
|
|
|
|
|
|
checkAccountList(res)
|
|
|
};
|
|
|
- const countDown = async ()=> {
|
|
|
+ const countDown = async () => {
|
|
|
if (!formState.phonenumber) return message.error('请输入手机号!')
|
|
|
if (count.value > 0) return false
|
|
|
await loginCode()
|
|
|
count.value = 60
|
|
|
- var down = setInterval(()=>{
|
|
|
- count.value --
|
|
|
- count.value === 0? clearInterval(down):''
|
|
|
- },1000)
|
|
|
+ var down = setInterval(() => {
|
|
|
+ count.value--
|
|
|
+ count.value === 0 ? clearInterval(down) : ''
|
|
|
+ }, 1000)
|
|
|
};
|
|
|
- const loginCode = async ()=> {
|
|
|
+ const loginCode = async () => {
|
|
|
const res = await Api.loginCode({
|
|
|
- "phonenumber":formState.phonenumber,
|
|
|
+ "phonenumber": formState.phonenumber,
|
|
|
"systemclient": "web"
|
|
|
})
|
|
|
- res.code == 1?'':message.error(res.msg)
|
|
|
+ res.code == 1 ? '' : message.error(res.msg)
|
|
|
};
|
|
|
- const loginByCode = async ()=>{
|
|
|
+ const loginByCode = async () => {
|
|
|
loading.value = true
|
|
|
const res = await Api.login({
|
|
|
- "phonenumber":formState.phonenumber,
|
|
|
- "password":md5(formState.password),
|
|
|
+ "phonenumber": formState.phonenumber,
|
|
|
+ "password": md5(formState.password),
|
|
|
"systemclient": "web"
|
|
|
})
|
|
|
checkAccountList(res)
|
|
|
}
|
|
|
- const tabsChange = ()=>{
|
|
|
+ const tabsChange = () => {
|
|
|
formState.phonenumber = null,
|
|
|
- formState.password = null
|
|
|
+ formState.password = null
|
|
|
+ }
|
|
|
+ const getRouteParams = () => {
|
|
|
+ const cur = router.currentRoute.value || {};
|
|
|
+ const query = cur.query || {};
|
|
|
+ let accesstoken = query.accesstoken || '';
|
|
|
+ let username = query.username || '';
|
|
|
+
|
|
|
+ if (!accesstoken || !username) {
|
|
|
+ const hash = window.location.hash || '';
|
|
|
+ const qIndex = hash.indexOf('?');
|
|
|
+ if (qIndex !== -1) {
|
|
|
+ const queryString = hash.slice(qIndex + 1);
|
|
|
+ // 规范化:将额外的 '?' 替换为 '&',以兼容错误格式
|
|
|
+ const normalized = queryString.replace(/\?/g, '&');
|
|
|
+ const params = new URLSearchParams(normalized);
|
|
|
+ accesstoken = accesstoken || params.get('accesstoken') || '';
|
|
|
+ username = username || params.get('username') || '';
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return { accesstoken, username };
|
|
|
+ };
|
|
|
+ const ssoLogin = async () => {
|
|
|
+ const { accesstoken, username } = getRouteParams();
|
|
|
+ console.log(accesstoken, username)
|
|
|
+ if (!accesstoken || !username) return
|
|
|
+ const res = await Api.ssologin({ "accountno": username, "password": accesstoken, "systemclient": "web" })
|
|
|
+ checkAccountList(res)
|
|
|
}
|
|
|
+ ssoLogin()
|
|
|
return {
|
|
|
formState,
|
|
|
onFinish,
|
|
|
@@ -209,7 +208,7 @@ export default defineComponent({
|
|
|
tabsChange
|
|
|
};
|
|
|
},
|
|
|
- mounted () {
|
|
|
+ mounted() {
|
|
|
sessionStorage.clear()
|
|
|
localStorage.clear();
|
|
|
historyRoutes.value = []
|
|
|
@@ -217,82 +216,96 @@ export default defineComponent({
|
|
|
});
|
|
|
</script>
|
|
|
<style>
|
|
|
-.login-form .ant-form-item .ant-form-item-label >label,.login-form .ant-checkbox-wrapper {
|
|
|
- color:#fff
|
|
|
+.login-form .ant-form-item .ant-form-item-label>label,
|
|
|
+.login-form .ant-checkbox-wrapper {
|
|
|
+ color: #fff
|
|
|
}
|
|
|
+
|
|
|
.login-form .ant-tabs {
|
|
|
- color:#fff !important;
|
|
|
+ color: #fff !important;
|
|
|
}
|
|
|
</style>
|
|
|
<style scoped>
|
|
|
-.conatiner{
|
|
|
+.conatiner {
|
|
|
background: url('@/assets/bg.jpg');
|
|
|
background-size: cover;
|
|
|
}
|
|
|
-.title{
|
|
|
+
|
|
|
+.title {
|
|
|
height: 33px;
|
|
|
margin: 0 0 30px;
|
|
|
font-size: 1.25rem;
|
|
|
font-weight: 600;
|
|
|
- animation: showup 3s forwards ;
|
|
|
+ animation: showup 3s forwards;
|
|
|
}
|
|
|
-.login-wrap{
|
|
|
+
|
|
|
+.login-wrap {
|
|
|
overflow: hidden;
|
|
|
}
|
|
|
-.login-wrap .top{
|
|
|
- width:100%;
|
|
|
+
|
|
|
+.login-wrap .top {
|
|
|
+ width: 100%;
|
|
|
/* background:#f3f4f591 */
|
|
|
}
|
|
|
-.login-wrap .top{
|
|
|
- height:calc(100vh - 70px);
|
|
|
- width:100%;
|
|
|
+
|
|
|
+.login-wrap .top {
|
|
|
+ height: calc(100vh - 70px);
|
|
|
+ width: 100%;
|
|
|
}
|
|
|
-.login-wrap svg{
|
|
|
+
|
|
|
+.login-wrap svg {
|
|
|
height: 70%;
|
|
|
}
|
|
|
-.login-form{
|
|
|
+
|
|
|
+.login-form {
|
|
|
position: absolute;
|
|
|
right: 50%;
|
|
|
- top:50vh;
|
|
|
+ top: 50vh;
|
|
|
width: 500px;
|
|
|
margin-right: -250px;
|
|
|
margin-top: -244px;
|
|
|
padding: 30px;
|
|
|
- background-color: rgba(0,0,0,.2);
|
|
|
+ background-color: rgba(0, 0, 0, .2);
|
|
|
border-radius: 5px;
|
|
|
- box-shadow: 2px 8px 8px 0 rgba(0,0,0,.2);
|
|
|
- color:#fff;
|
|
|
+ box-shadow: 2px 8px 8px 0 rgba(0, 0, 0, .2);
|
|
|
+ color: #fff;
|
|
|
z-index: 9999;
|
|
|
}
|
|
|
-.input-wrap{
|
|
|
+
|
|
|
+.input-wrap {
|
|
|
width: 100%;
|
|
|
}
|
|
|
-.color-info{
|
|
|
- font-weight:300
|
|
|
+
|
|
|
+.color-info {
|
|
|
+ font-weight: 300
|
|
|
}
|
|
|
+
|
|
|
.footer {
|
|
|
- height:70px;
|
|
|
- line-height:70px;
|
|
|
+ height: 70px;
|
|
|
+ line-height: 70px;
|
|
|
font-size: 14px;
|
|
|
text-align: center;
|
|
|
/* background:#1677ff; */
|
|
|
- color:#fff !important;
|
|
|
-
|
|
|
+ color: #fff !important;
|
|
|
+
|
|
|
}
|
|
|
+
|
|
|
@keyframes typingH {
|
|
|
0% {
|
|
|
height: 0px;
|
|
|
}
|
|
|
+
|
|
|
100% {
|
|
|
height: 300px;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@media(max-width: 1600px) {
|
|
|
- .login-form{
|
|
|
+ .login-form {
|
|
|
transform: scale(.8);
|
|
|
}
|
|
|
- .introduce{
|
|
|
+
|
|
|
+ .introduce {
|
|
|
font-size: 15px;
|
|
|
}
|
|
|
}
|