Files
pda-cli/src/pages/sys/login/index.vue
T

646 lines
17 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>
<view class="wrap">
<view class="haotoplogo">
<image src="/static/haotop/image/logo/Start.jpg" mode="aspectFit" class="logoimg"></image>
</view>
<view class="app-name">{{ appName }}</view>
<!-- <div v-if="loginType === 'currentPhone'">-->
<!-- <u-tabs :list="list" :is-scroll="false" :current="current" @change="onClickItem"></u-tabs> -->
<!-- <view v-if="current === 0"> -->
<view class="list">
<view class="list-call env-call">
<view class="iconfont icon-link" style="font-size: 28px;color:#5473e8;"></view>
<view style="width: 100%;">
<view class="server-selector" @click="showServerPicker">
<text>{{ getApiUrlLabel() }}</text>
<view class="iconfont icon-arrow-down"></view>
</view>
</view>
</view>
<view class="list-call" v-if="selectedApiUrl === 'custom'">
<!-- 当选择自定义时显示输入框 -->
<input class="u-input" type="text" v-model="customApiUrl" maxlength="100" placeholder="请输入服务器地址"
@blur="handleBlurInputUrl" />
</view>
<view class="list-call">
<view class="iconfont icon-avatar" style="font-size: 22px;color:#5473e8;"></view>
<input class="u-input" type="text" v-model="login.username" maxlength="32"
:placeholder="$t('login.placeholderAccount')" value="admin" @input="clearInput" />
<u-icon :size="50" v-if="showClearIcon" name="close-circle-fill" color="#c0c4cc" class="u-clear-icon"
@click="clearIcon" />
</view>
<view class="list-call">
<view class="iconfont icon-key" style="font-size: 22px;color:#5473e8;"></view>
<input class="u-input" type="text" v-model="login.password" maxlength="32"
:placeholder="$t('login.placeholderPassword')" :password="!showPassword" value="admin123" />
<image class="u-icon-right" :src="'/static/aidex/login/eye_' + (showPassword ? 'open' : 'close') + '.png'"
@click="showPass()"></image>
</view>
<div style="padding:15rpx 0 0;">
<!-- <view class="register">
<navigator class="register-link" url="forget" open-type="navigate">{{$t('login.forget')}}
</navigator>
<navigator class="register-link" url="reg" open-type="navigate">{{$t('login.reg')}}</navigator>
</view> -->
<u-checkbox v-model="remember" active-color="#5473e8">{{ $t('login.autoLogin') }}</u-checkbox>
</div>
</view>
<button class="button" :disabled="login.loading" @click="submit('1')"
:loading="login.loading"><text>登录</text></button>
<!-- <view class="login-bottom-box">
<u-divider> 更多登录方式 </u-divider>
<view class="oauth2">
<u-icon class="u-icon" size="100" color="#36c956" name="weixin-circle-fill"
@click="wxLogin"></u-icon>
<u-icon class="u-icon" size="100" color="#23a0f0" name="qq-circle-fill"
@click="qqLogin"></u-icon>
</view>
<view class="copyright">
登录即代表您已阅读并同意<u-link href="#">用户协议</u-link> 与 <u-link href="#">隐私政策</u-link>
</view>
</view> -->
<!-- </view> -->
<!-- <view v-if="current === 1">
<view class="list">
<view class="list-call">
<view class="iconfont icon-shouji" style="font-size: 22px;color:#5473e8;"></view>
<u-field v-model="phoneNo" label="+86" placeholder="请填写手机号" style="width: 100%;"
:border-bottom="false" :maxlength="11">
</u-field>
</view>
<div style="padding:25rpx 0 0;">
还没有账号?<navigator class="reg-link" url="reg" open-type="navigate">{{$t('login.reg')}}</navigator>
</div>
</view>
<view class="button" @click="nextStep()"><text>下一步</text></view>
<view class="login-bottom-box">
<u-divider> 更多登录方式 </u-divider>
<view class="oauth2">
<u-icon class="u-icon" size="100" color="#36c956" name="weixin-circle-fill"
@click="wxLogin"></u-icon>
<u-icon class="u-icon" size="100" color="#23a0f0" name="qq-circle-fill"
@click="qqLogin"></u-icon>
</view>
<view class="copyright">
登录即代表您已阅读并同意<u-link href="#">用户协议</u-link> 与 <u-link href="#">隐私政策</u-link>
</view>
</view>
</view> -->
<!-- </div>-->
<!-- <div v-if="loginType !== 'currentPhone'">-->
<!-- <view class="currentPhone-box">-->
<!-- <view class="number-text">183****1005</view>-->
<!-- <view class="other-text">认证服务由中国移动提供。</view>-->
<!-- <u-button type="primary" @click="submit('3')">本机号码一键登录</u-button>-->
<!-- <u-button @click="qiehuanLogin()">其他登录方式</u-button>-->
<!-- </view>-->
<!-- <view class="login-bottom-box">-->
<!-- <view class="copyright">-->
<!-- 登录即代表您已阅读并同意<u-link href="#">用户协议</u-link> 与 <u-link href="#">隐私政策</u-link>-->
<!-- </view>-->
<!-- </view>-->
<!-- </div>-->
<u-select class="login-env-picker" v-model="showApiUrlPicker" :list="apiUrlList" :default-value="apiUrlDefaultIndex"
title="选择服务器" :show-search="false" :item-height="88" :visible-item-count="5"
@confirm="onApiUrlConfirm" @cancel="showApiUrlPicker = false"></u-select>
<!-- 版本信息显示 -->
<view class="version-info">
<text class="version-text">版本: {{ appVersion }}</text>
<text class="env-text" v-if="envName">({{ envName }})</text>
</view>
</view>
</template>
<script>
/**
* Copyright (c) 2013-Now http://aidex.vip All rights reserved.
*/
import config from '@/common/config.js';
import base64 from '@/common/base64.js';
import util from '@/common/util.js';
import md5 from '@/common/md5.js';
import manifest from '@/manifest.json';
import { mapState } from 'vuex'
import app_upgrade from '@/uni_modules/app-upgrade/js_sdk/index.js'
import { applyLoginData, applyUserInformation } from '@/common/userSession.js'
import { ensureScanConfigAfterLogin } from '@/common/scanAutoConfig.js'
export default {
data() {
return {
isDevelopment: config.isDevelopment,
showClearIcon: false,
login: {
loading: false,
username: "",
password: ""
},
showApiUrlPicker: false,
// 登录默认正式环境,本地已选过的地址仍会在 onShow 里恢复
selectedApiUrl: (config.devApiUrlOptions.find(item => item.label === '正式环境') || {}).value || config.productionApiUrl,
customApiUrl: 'http://192.168.1.66:50002/hcscm/pda/v1',
apiUrlList: config.devApiUrlOptions,
phoneNo: '',
//username: '',
//password: '',
loginType: 'currentPhone',
showPassword: false,
remember: true,
isValidCodeLogin: false,
validCode: '',
imgValidCodeSrc: null,
list: [{
name: '用户名'
}, {
name: '手机号'
}],
current: 0,
activeColor: '#007aff',
};
},
computed: {
appName() {
return manifest.name || '';
},
appVersion() {
return manifest.versionName;
},
envName() {
return process.env.VUE_APP_ENV_NAME || '';
},
apiUrlDefaultIndex() {
const list = this.apiUrlList || [];
let index = list.findIndex(item => item.value === this.selectedApiUrl);
if (index < 0) index = list.findIndex(item => item.label === '正式环境');
return [index >= 0 ? index : 0];
}
},
onShow() {
uni.getStorage({
key: 'ApiUrl',
success: (e) => {
util.updateApiUrl(e.data);
this.selectedApiUrl = e.data;
}
});
uni.getStorage({
key: 'UserInfo',
success: (e) => {
console.log("---->>>" + e.data.username + '--->>>' + e.data.password);
this.login.username = e.data.username;
this.login.password = e.data.password;
}
})
},
onLoad() {
// #ifdef APP-PLUS
// 打开APP后自动检查版本更新
this.autoCheckUpgrade();
// #endif
},
methods: {
clearInput: function (event) {
if (event.detail.value.length > 0) {
this.showClearIcon = true;
} else {
this.showClearIcon = false;
}
},
clearIcon: function () {
this.login.username = ''
this.showClearIcon = false;
},
showServerPicker() {
this.showApiUrlPicker = true;
},
getApiUrlLabel() {
if (this.selectedApiUrl === 'custom') {
return '自定义服务器';
}
const option = this.apiUrlList.find(item => item.value === this.selectedApiUrl);
return option ? option.label : '选择服务器';
},
onApiUrlConfirm(e) {
const selectedValue = e && e[0] && e[0].value;
if (selectedValue == null) return;
this.selectedApiUrl = selectedValue;
this.showApiUrlPicker = false;
// 如果不是自定义,直接更新 store
if (selectedValue !== 'custom') {
this.$store.dispatch('updateApiUrl', selectedValue);
}
// 如果是自定义且已有自定义值,更新store
else if (this.customApiUrl) {
this.$store.dispatch('updateApiUrl', this.customApiUrl);
}
},
showPass() {
this.showPassword = !this.showPassword;
},
qiehuanLogin() {
this.loginType = 'other'
},
clickchecked() {
var that = this
this.remember = !this.remember
if (that.remember == true) {
if ((this.login.username.length > 0) && (this.login.password.length > 0)) {
uni.setStorage({
key: 'UserInfo',
data: that.login
})
}
}
},
onClickItem(index) {
this.current = index;
},
refreshImgValidCode(e) {
if (this.vuex_token == '') {
this.$u.api.index().then(res => {
this.imgValidCodeSrc = this.vuex_config.baseUrl + '/validCode?__sid=' +
res.sessionid + '&t=' + new Date().getTime();
});
} else {
this.imgValidCodeSrc = this.vuex_config.baseUrl + '/validCode?__sid=' +
this.vuex_token + '&t=' + new Date().getTime();
}
this.validCode = '';
},
nextStep() {
//验证码登录下一步
uni.showLoading({
title: '正在获取验证码',
mask: true
})
this.$u.api.sendCode({
phoneNo: this.phoneNo,
validCodeType: '2'
})
.then(res => {
if (res.code == '200') {
setTimeout(() => {
uni.navigateTo({
url: '/pages/sys/login/code?phoneNo=' + this.phoneNo
});
}, 500);
} else {
this.$u.toast(res.msg);
setTimeout(() => {
uni.navigateTo({
url: '/pages/sys/login/code?phoneNo=' + this.phoneNo
});
}, 500);
}
});
},
isDefaultPassword(loginData) {
const value = loginData && loginData.is_default_password;
return value === true || value === 1 || value === '1' || value === 'true';
},
enterWorkbench(openPasswordPage) {
const url = openPasswordPage
? '/pages/sys/workbench/index?changePassword=1'
: '/pages/sys/workbench/index';
uni.reLaunch({ url });
},
submit(loginType = '1') {
uni.showLoading({
title: '登录中...'
});
const currentApiUrl = this.selectedApiUrl === 'custom' ? this.customApiUrl : this.selectedApiUrl;
if (!currentApiUrl || currentApiUrl.length === 0) {
this.$u.toast('请输入服务器地址');
return;
}
this.$store.dispatch('updateApiUrl', currentApiUrl);
if (this.login.username.length == 0) {
this.$u.toast('请输入账号');
return;
}
if (this.login.password.length == 0) {
this.$u.toast('请输入密码');
return;
}
console.log('开始请求', currentApiUrl)
this.login.loading = true
// 临时设置baseUrl为当前选择的API URL
const originalBaseUrl = this.$u.http.config.baseUrl;
this.$u.http.setConfig({ baseUrl: currentApiUrl });
this.$u.api.pdaLogin({
'phone': this.login.username,
'password': this.login.password,
}).then(async (res) => {
console.log('login res', res)
var aLoginUserData = res;
//console.log('--aLoginUserData->>' + JSON.stringify(aLoginUserData));
uni.setStorage({
key: 'ApiUrl',
data: currentApiUrl
});
util.updateApiUrl(currentApiUrl);
// 保存 token 到本地存储
uni.setStorageSync('RemoteTokenData', aLoginUserData);
applyLoginData(aLoginUserData);
try {
const userInfo = await this.$u.api.pdaGetInformation();
console.log('information res', userInfo);
applyUserInformation(userInfo);
} catch (infoError) {
console.log('information error', infoError);
}
try {
await ensureScanConfigAfterLogin(this.$u.api);
} catch (scanError) {
console.log('自动匹配扫码设置失败', scanError);
}
if (this.remember == true) {
if ((this.login.username.length > 0) && (this.login.password.length > 0)) {
uni.setStorage({
key: 'UserInfo',
data: this.login
})
}
}
this.$store.dispatch('initNotification');
uni.hideLoading();
if (this.isDefaultPassword(aLoginUserData)) {
uni.showModal({
title: '提示',
content: '当前使用的是默认密码,请及时修改密码',
confirmText: '去修改',
cancelText: '稍后',
success: (modalRes) => {
this.enterWorkbench(!!(modalRes && modalRes.confirm));
},
fail: () => {
this.enterWorkbench(false);
}
});
return;
}
uni.showToast({
icon: 'none',
title: '登录成功!'
});
setTimeout(() => {
this.enterWorkbench(false);
}, 500);
}).catch((error) => {
console.log('login error', error)
uni.showToast({
icon: 'none',
title: '' + (error.msg || error.message || '')
});
setTimeout(function () {
uni.hideLoading();
}, 5000);
// 恢复原始baseUrl
this.$u.http.setConfig({ baseUrl: originalBaseUrl });
}).finally(() => {
this.login.loading = false;
})
},
wxLogin(res) {
this.$u.toast('微信登录');
},
qqLogin() {
this.$u.toast('QQ 登录');
},
// 自动检查版本更新(有新版本才弹窗,已是最新不提示)
autoCheckUpgrade() {
this.runUpgradeCheck({ silentWhenLatest: true });
},
runUpgradeCheck({ silentWhenLatest }) {
const self = this;
app_upgrade(async () => {
try {
const appInfo = await new Promise((resolve) => {
plus.runtime.getProperty(plus.runtime.appid, (inf) => {
resolve(inf);
});
});
const res = await self.$u.api.upgradeCheck({
app_name: config.upgradeName,
current_version: appInfo.version
});
if (!res || !res.download_url) {
if (!silentWhenLatest) {
self.$u.toast('当前版本已是最新版');
}
return { status: 0 };
}
return {
changelog: res.message + ',最新版本:' + res.latest_version,
status: res.need_update ? 1 : 0,
path: res.download_url
};
} catch (error) {
console.log('检查版本更新失败:', error);
if (!silentWhenLatest) {
self.$u.toast('检查更新失败,请稍后重试');
}
return { status: 0 };
}
}, 1);
},
handleBlurInputUrl(e) {
const url = e.detail.value.trim();
if (url) {
this.customApiUrl = url;
uni.setStorage({
key: 'ApiUrl',
data: url
});
util.updateApiUrl(url);
}
},
}
};
</script>
<style lang="scss">
@import 'index.scss';
.env-call {
height: auto;
min-height: 140rpx;
}
.server-selector {
display: flex;
justify-content: space-between;
align-items: center;
min-height: 80rpx;
padding: 16rpx 0;
font-size: 40rpx;
border-bottom: 1px solid #eee;
}
.server-selector .icon-arrow-down {
font-size: 28px;
}
.list-call {
.u-select {
margin-bottom: 10rpx;
}
.u-input {
margin-top: 10rpx;
}
}
.haotoplogo {
width: 300rpx;
height: 150rpx;
// max-width: 5%;
// max-height: 5%;
margin: 10rpx auto 0 auto;
}
.app-name {
margin: 8rpx 0 24rpx;
color: #242820;
font-size: 40rpx;
font-weight: 700;
line-height: 1.3;
text-align: center;
}
.logoimg {
width: 100%;
height: 100%;
}
.logo {
width: 80%;
font-size: 64rpx;
color: #5473e8;
margin: 80rpx auto 80rpx auto;
}
.list-call-icon {
color: #ff0000;
}
.currentPhone-box {
text-align: center;
padding: 40rpx 80rpx;
.number-text {
color: #000000;
font-size: 60rpx;
}
.other-text {
color: #999999;
font-size: 26rpx;
padding: 20rpx 0;
}
.u-btn {
margin: 30rpx auto;
}
.u-hairline-border {
border: 1px solid #fff;
}
}
.register {
display: inline-block;
color: #5473e8;
height: 40rpx;
line-height: 40rpx;
font-size: 28rpx;
float: right;
margin-top: 6rpx;
}
.register-link {
float: right;
padding: 0 16rpx;
}
.reg-link {
display: inline-block;
color: #5473e8;
}
.oauth2 {
display: flex;
flex-direction: row;
justify-content: space-around;
margin: 0rpx 100rpx 30rpx;
image {
height: 80rpx;
width: 80rpx;
}
}
.u-tabs {
padding: 0 70rpx;
}
.version-info {
text-align: center;
margin-top: 30rpx;
display: flex;
justify-content: center;
align-items: center;
flex-wrap: wrap;
padding: 0 24rpx 20rpx;
}
.version-text {
font-size: 32rpx;
color: #999999;
}
.env-text {
font-size: 32rpx;
color: #5473e8;
margin-left: 10rpx;
}
</style>
<style lang="scss" scoped>
.login-env-picker {
::v-deep .u-select__header,
::v-deep .u-select__header__btn {
height: 100rpx;
font-size: 36rpx;
}
::v-deep .u-select__header__title {
font-size: 36rpx;
}
::v-deep .u-select__body__picker-view__item,
::v-deep .u-line-1 {
font-size: 40rpx;
}
}
</style>