2022-01-24 11:54:47 +08:00

322 lines
12 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="page-login">
<PageTitle :title="$L('登录')"/>
<div class="login-body">
<div class="login-logo no-dark-mode"></div>
<div class="login-box">
<div class="login-title">{{welcomeTitle}}</div>
<div v-if="loginType=='reg'" class="login-subtitle">{{$L('输入您的信息以创建帐户。')}}</div>
<div v-else class="login-subtitle">{{$L('输入您的凭证以访问您的帐户。')}}</div>
<div class="login-input">
<Input v-if="$Electron && cacheServerUrl" :value="$A.getDomain(cacheServerUrl)" prefix="ios-globe-outline" size="large" readonly clearable @on-clear="clearServerUrl"/>
<Input v-model="email" prefix="ios-mail-outline" :placeholder="$L('输入您的电子邮件')" size="large" @on-enter="onLogin" @on-blur="onBlur" />
<Input v-if="loginType=='login'"
v-model="password" prefix="ios-lock-outline" :placeholder="$L('输入您的密码')" type="password"
size="large"
@on-enter="onLogin" />
<Poptip v-else :content="$L('密码必须包含数字字母大小写或者特殊字符的组合长度在6~32位之间')" :transfer="true">
<Input v-model="password" prefix="ios-lock-outline" :placeholder="$L('输入您的密码')" type="password"
size="large"
@on-enter="onLogin" />
</Poptip>
<Input v-if="loginType=='reg'" v-model="password2" prefix="ios-lock-outline" :placeholder="$L('输入确认密码')" type="password" size="large" @on-enter="onLogin" />
<Input v-if="loginType=='reg' && needInvite" v-model="invite" class="login-code" :placeholder="$L('请输入注册邀请码')" type="text" size="large" @on-enter="onLogin"><span slot="prepend">&nbsp;{{$L('邀请码')}}&nbsp;</span></Input>
<Input v-if="loginType=='login' && codeNeed" v-model="code" class="login-code" :placeholder="$L('输入图形验证码')" size="large" @on-enter="onLogin">
<Icon type="ios-checkmark-circle-outline" class="login-icon" slot="prepend"></Icon>
<div slot="append" class="login-code-end" @click="reCode"><img :src="codeUrl"/></div>
</Input>
<Button type="primary" :loading="loadIng > 0 || loginJump" size="large" long @click="onLogin">{{$L(loginText)}}</Button>
<div v-if="loginType=='reg'" class="login-switch">{{$L('已经有帐号?')}}<a href="javascript:void(0)" @click="loginType='login'">{{$L('登录帐号')}}</a></div>
<div v-else class="login-switch">{{$L('还没有帐号?')}}<a href="javascript:void(0)" @click="loginType='reg'">{{$L('注册帐号')}}</a></div>
</div>
</div>
<div class="login-bottom">
<Dropdown trigger="click" @on-click="setLanguage" transfer>
<div class="login-language">
{{currentLanguage}}
<i class="taskfont">&#xe689;</i>
</div>
<Dropdown-menu slot="list">
<Dropdown-item v-for="(item, key) in languageList" :key="key" :name="key" :selected="getLanguage() === key">{{item}}</Dropdown-item>
</Dropdown-menu>
</Dropdown>
<div class="login-forgot">{{$L('忘记密码了?')}}<a href="javascript:void(0)" @click="forgotPassword">{{$L('重置密码')}}</a></div>
</div>
</div>
<div v-if="$Electron" class="login-right-bottom">
<Button icon="ios-globe-outline" type="primary" @click="inputServerUrl">{{$L('自定义服务器')}}</Button>
</div>
</div>
</template>
<script>
import {mapState} from "vuex";
export default {
data() {
return {
loadIng: 0,
codeNeed: false,
codeUrl: $A.apiUrl('users/login/codeimg'),
loginType: 'login',
loginJump: false,
email: $A.getStorageString("cacheLoginEmail") || '',
password: '',
password2: '',
code: '',
invite: '',
demoAccount: {},
needInvite: false,
}
},
mounted() {
this.getDemoAccount();
//
if (this.$Electron) {
this.chackServerUrl().catch(() => {});
} else {
this.clearServerUrl();
}
},
deactivated() {
this.loginJump = false;
this.password = "";
this.password2 = "";
this.code = "";
this.invite = "";
},
computed: {
...mapState(['cacheServerUrl']),
currentLanguage() {
return this.languageList[this.languageType] || 'Language'
},
welcomeTitle() {
let title = window.systemInfo.title || "Dootask";
if (title == "PublicDooTask") {
return "Public DooTask"
} else {
return "Welcome " + title
}
},
loginText() {
let text = this.loginType == 'login' ? '登录' : '注册';
if (this.loginJump) {
text += "成功..."
}
return text
}
},
watch: {
loginType(val) {
if (val == 'reg') {
this.getNeedInvite();
}
}
},
methods: {
getDemoAccount() {
if (this.isNotServer()) {
return;
}
this.$store.dispatch("call", {
url: 'system/demo',
}).then(({data}) => {
this.demoAccount = data;
if (data.account) {
this.email = data.account;
this.password = data.password;
}
}).catch(() => {
this.demoAccount = {};
});
},
getNeedInvite() {
this.$store.dispatch("call", {
url: 'users/reg/needinvite',
}).then(({data}) => {
this.needInvite = !!data.need;
}).catch(() => {
this.needInvite = false;
});
},
forgotPassword() {
$A.modalWarning("请联系管理员!");
},
reCode() {
this.codeUrl = $A.apiUrl('users/login/codeimg?_=' + Math.random())
},
inputServerUrl() {
$A.modalInput({
title: "自定义服务器",
value: this.cacheServerUrl,
placeholder: "请输入服务器地址",
onOk: (value, cb) => {
if (value) {
if (!$A.leftExists(value, "http://") && !$A.leftExists(value, "https://")) {
value = "http://" + value;
}
if (!$A.rightExists(value, "/api/")) {
value = value + ($A.rightExists(value, "/") ? "api/" : "/api/");
}
this.$store.dispatch("call", {
url: value + 'system/setting',
}).then(() => {
this.setServerUrl(value)
}).catch(({msg}) => {
$A.modalError(msg || "服务器地址无效", 301);
cb()
});
return;
}
this.clearServerUrl();
}
});
},
chackServerUrl(tip) {
return new Promise((resolve, reject) => {
if (this.$Electron && this.isNotServer()) {
if (tip === true) {
$A.messageWarning("请设置服务器")
}
this.inputServerUrl()
reject()
} else {
resolve()
}
})
},
setServerUrl(value) {
if (value != this.cacheServerUrl) {
$A.setStorage("cacheServerUrl", value)
window.location.reload();
}
},
clearServerUrl() {
this.setServerUrl("")
},
isNotServer() {
let apiHome = $A.getDomain(window.systemInfo.apiUrl)
return apiHome == "" || apiHome == "public"
},
onBlur() {
if (this.loginType != 'login' || !this.email) {
this.codeNeed = false;
return;
}
this.loadIng++;
this.$store.dispatch("call", {
url: 'users/login/needcode',
data: {
email: this.email,
},
}).then(() => {
this.loadIng--;
this.reCode();
this.codeNeed = true;
}).catch(() => {
this.loadIng--;
this.codeNeed = false;
});
},
onLogin() {
this.chackServerUrl(true).then(() => {
if (!this.email) {
return;
}
if (!this.password) {
return;
}
if (this.loginType == 'reg') {
if (this.password != this.password2) {
$A.noticeError("确认密码输入不一致");
return;
}
}
this.loadIng++;
this.$store.dispatch("call", {
url: 'users/login',
data: {
type: this.loginType,
email: this.email,
password: this.password,
code: this.code,
invite: this.invite,
},
}).then(({data}) => {
this.loadIng--;
$A.setStorage("cacheLoginEmail", this.email)
this.$store.dispatch("handleClearCache", data).then(() => {
this.goNext1();
}).catch(() => {
this.goNext1();
});
}).catch(({data, msg}) => {
this.loadIng--;
$A.noticeError({
desc: msg,
duration: 10
});
if (data.code === 'need') {
this.reCode();
this.codeNeed = true;
}
});
})
},
goNext1() {
this.loginJump = true;
if (this.loginType == 'login') {
this.goNext2();
} else {
// 新注册自动创建项目
this.$store.dispatch("call", {
url: 'project/add',
data: {
name: this.$L('个人项目'),
desc: this.$L('注册时系统自动创建项目,你可以自由删除。')
},
}).then(() => {
this.goNext2();
}).catch(() => {
this.goNext2();
});
}
},
goNext2() {
let fromUrl = decodeURIComponent($A.getObject(this.$route.query, 'from'));
if (fromUrl) {
window.location.replace(fromUrl);
} else {
this.goForward({path: '/manage/dashboard'}, true);
}
}
}
}
</script>