Files
login/pages/signin.vue
Thien Pham Van 576a50c113 Update Lang
2026-01-27 15:19:21 +07:00

311 lines
11 KiB
Vue
Executable File

<template>
<div class="columns is-centered px-0 mx-0">
<div
:class="`column is-flex is-justify-content-center is-align-items-center wrapper-login is-${
viewport >= 4 ? 4 : 6
}`"
>
<div class="has-background-white px-6 py-6 login-box">
<Logo />
<Caption
:class="`mt-5 pt-${viewport === 1 ? 0 : 3}`"
v-bind="{ title: `${isVietnamese ? 'Đăng nhập' : 'Login'}`, size: 19 }"
></Caption>
<div class="field mt-5">
<label class="label"
>{{ isVietnamese ? 'Tên đăng nhập' : 'User name' }}<b class="ml-1 has-text-danger">*</b></label
>
<div class="control">
<input
class="input"
type="text"
:placeholder="isVietnamese ? 'Nhập tên đăng nhập' : 'Enter username'"
v-model="username"
@keyup.enter="signin()"
/>
</div>
<p
class="help is-danger"
v-if="errors.find((v) => v.name === 'username')"
v-html="errors.find((v) => v.name === 'username').text"
></p>
</div>
<div class="field mt-5">
<label class="label">{{ isVietnamese ? 'Mật khẩu' : 'Password' }}<b class="ml-1 has-text-danger">*</b></label>
<div class="field-body">
<div class="field has-addons">
<p class="control is-expanded">
<input
class="input"
:type="showpass ? 'text' : 'password'"
:placeholder="isVietnamese ? 'Nhập mật khẩu' : 'Enter password'"
v-model="password"
@keyup.enter="signin()"
/>
</p>
<div class="control">
<a
class="button"
@click="showpass = !showpass"
:title="
showpass ? (isVietnamese ? 'Đăng nhập' : 'Login') : isVietnamese ? 'Hiện mật khẩu' : 'Show Password'
"
>
<span class="icon">
<SvgIcon v-bind="{ name: showpass ? 'eye-off.svg' : 'view.svg', type: 'gray' }" />
</span>
</a>
</div>
</div>
</div>
<p class="help is-danger" v-if="errors.find((v) => v.name === 'password')">
{{ errors.find((v) => v.name === 'password').text }}
</p>
</div>
<div class="field is-grouped mt-5 is-align-items-center">
<div class="control is-expanded">
<button class="button is-primary" @click="signin()" @keyup.enter="signin()">
{{ isVietnamese ? 'Đăng nhập' : 'Login' }}
</button>
</div>
<div class="control">
<a class="is-primary" @click="accountRecovery()"
>{{ isVietnamese ? 'Đặt lại mật khẩu' : 'Forgot Password' }}?</a
>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import Bowser from 'bowser';
export default {
head() {
return { title: this.isVietnamese ? 'Đăng nhập' : 'Login' };
},
data() {
return {
fullname: undefined,
username: undefined,
password: undefined,
errors: [],
showpass: false,
registers: [],
type: undefined,
isLoaded: false,
data: undefined,
account: undefined,
};
},
mounted() {
window.addEventListener('keyup', (ev) =>
ev.key === 'Enter' && this.$route.name === 'signup' ? this.signin() : false,
);
if (!this.module) return this.$router.push('/welcome');
console.log('this.$route.query', this.$route.query);
},
computed: {
login: {
get: function () {
return this.$store.state.login;
},
set: function (val) {
this.$store.commit('updateLogin', { login: val });
},
},
registermethod: {
get: function () {
return this.$store.state.registermethod;
},
set: function (val) {
this.$store.commit('updateRegisterMethod', { registermethod: val });
},
},
authmethod: {
get: function () {
return this.$store.state.authmethod;
},
set: function (val) {
this.$store.commit('updateAuthMethod', { authmethod: val });
},
},
authstatus: {
get: function () {
return this.$store.state.authstatus;
},
set: function (val) {
this.$store.commit('updateAuthStatus', { authstatus: val });
},
},
usertype: {
get: function () {
return this.$store.state.usertype;
},
set: function (val) {
this.$store.commit('updateUserType', { usertype: val });
},
},
viewport: {
get: function () {
return this.$store.state.viewport;
},
set: function (val) {
this.$store.commit('updateViewPort', { viewport: val });
},
},
module: {
get: function () {
return this.$store.state['module'];
},
set: function (val) {
this.$store.commit('updateStore', { name: 'module', data: val });
},
},
isVietnamese() {
return navigator.language.toLowerCase().startsWith('vi');
},
},
methods: {
checkError() {
this.errors = [];
if (!this.$empty(this.username)) {
this.username = this.username.trim().toLowerCase();
}
if (this.$empty(this.username)) {
this.errors.push({
name: 'username',
text: this.isVietnamese ? 'Tên đăng nhập không được bỏ trống.' : 'Username is required.',
});
}
if (this.$empty(this.password)) {
this.errors.push({
name: 'password',
text: this.isVietnamese ? 'Mật khẩu không được bỏ trống.' : 'Password is required.',
});
} else if (this.password.length < 6) {
this.errors.push({
name: 'password',
text: this.isVietnamese
? 'Mật khẩu gồm 6 kí tự trở nên bao gồm chữ và số .'
: 'Password must be at least 6 characters long and include letters and numbers.',
});
} else if (!(/\d/.test(this.password) && /[a-zA-Z]/.test(this.password))) {
this.errors.push({
name: 'password',
text: this.isVietnamese
? 'Mật khẩu gồm 6 kí tự trở nên bao gồm chữ và số .'
: 'Password must be at least 6 characters long and include letters and numbers.',
});
}
return this.errors.length > 0 ? true : false;
},
async signin() {
if (this.checkError()) return;
let conn = this.$findapi('login');
conn.params.filter = { username: this.username, password: this.password };
let result = await this.$getapi([conn]);
if (result === 'error') {
return this.$dialog(
`${
this.isVietnamese
? 'Đã xảy ra lỗi. Vui lòng thử lại hoặc liên hệ số hotline để được hỗ trợ.'
: 'An error occurred. Please try again or contact the hotline for support.'
}`,
`${this.isVietnamese ? 'Lỗi kết nối' : 'Connection error'}`,
'Error',
10,
);
}
let data = result.find((v) => v.name === 'login').data.rows;
this.account = data;
this.fillData(data);
},
invalidLogin(data) {
if (!data) {
const text = this.isVietnamese ? 'Tài khoản hoặc mật khẩu không chính xác' : 'Invalid username or password.';
this.errors.push({ name: 'username', text: text });
this.errors.push({ name: 'password', text: text });
} else if (data.blocked) {
this.errors.push({
name: 'username',
text: this.isVietnamese
? 'Tài khoản đang bị khóa. Đăng nhập không thành công'
: 'Your account has been blocked. Login failed.',
});
} else if (data.auth_status === 1) {
this.errors.push({
name: 'username',
text: this.isVietnamese ? `Tài khoản đang chờ xác thực.` : 'Your account is pending verification.',
});
}
return this.errors.length > 0 ? true : false;
},
async fillData(data) {
if (this.invalidLogin(data)) return;
//check permision
if (this.module !== 'website') {
let userapps = await this.$getdata('userapps', { user: data.id, apps__code: this.module }, undefined, true);
if (!userapps) return this.$router.push('/welcome');
}
this.login = data; //store login
if (this.$store.state.link) {
let ele = this.$copy(data);
//get token & redirect link
const browser = Bowser.getParser(window.navigator.userAgent);
let obj = {
browser: browser.getBrowserName(),
browser_version: browser.getBrowserVersion(),
platform: browser.getPlatform().type,
os: browser.getOSName(),
user: data.id,
token: this.$id(),
};
ele.token = obj.token;
await this.$insertapi('authtoken', obj);
let link = this.$store.state.link;
if (data.type === 3 && link.indexOf('y99') >= 0) {
link = link.indexOf('dev') >= 0 ? 'https://dev.ctv.y99.vn' : 'https://ctv.y99.vn';
}
let href = `${link}?username=${ele.username}&token=${ele.token}&fullname=${ele.fullname}&userid=${ele.id}`;
if (ele.avatar) href = `${href}&avatar=${ele.avatar}`;
window.location.href = href;
} else this.redirectUrl();
},
async sendNoti(obj) {
let found = this.$findapi('notiform');
found.params.filter = { code: 'login-alert' };
const result = await this.$getapi([found]);
let data = result[0].data.rows[0];
let content = data.detail;
content = content.replace('[1]', this.username);
content = content.replace('[2]', obj.browser);
content = content.replace('[3]', obj.browser_version);
content = content.replace('[4]', obj.platform);
content = content.replace('[5]', obj.os);
content = content.replace('[6]', this.$dayjs().format('DD/MM/YYYY HH:mm'));
let ele = { title: data.name, content: content, user: [obj.user.toString()], type: 1 };
await this.$insertapi('notification', ele);
},
accountRecovery() {
this.$router.push({ path: '/account/recovery' });
},
async redirectUrl() {
this.$router.push(this.$route.query.href || '/welcome');
},
},
};
</script>
<style>
.wrapper-login {
min-height: 100vh;
}
.wrapper-login .login-box {
width: 100%;
border-radius: 16px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}
</style>