pda-cli/src/pages/sys/login/index.vue
HongxuanG d660d6fcf1 feat(storegoods): 新增加工进仓模块并适配智盛ERP
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-23 18:32:02 +08:00

601 lines
16 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>
<!-- <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">
<template v-if="isDevelopment">
<view class="list-call">
<view class="iconfont icon-link" style="font-size: 22px;color:#5473e8;"></view>
<view style="width: 100%;">
<view class="server-selector" @click="showServerPicker">
<text>{{ getApiUrlLabel() }}</text>
<view class="iconfont icon-arrow-down" style="font-size: 16px;"></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>
</template>
<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-picker v-model="showApiUrlPicker" mode="selector" :range="apiUrlList" range-key="label"
@confirm="onApiUrlConfirm" @cancel="showApiUrlPicker = false"></u-picker>
<!-- 版本信息显示 -->
<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'
export default {
data() {
return {
isDevelopment: config.isDevelopment,
showClearIcon: false,
login: {
loading: false,
username: "",
password: ""
},
showApiUrlPicker: false,
// 根据环境设置默认URL和选项
selectedApiUrl: config.isDevelopment ? config.devApiUrlOptions[0].value : config.productionApiUrl,
customApiUrl: 'http://192.168.1.66:50002/hcscm/pda/v1',
apiUrlList: config.isDevelopment ? config.devApiUrlOptions : [],
phoneNo: '',
//username: '',
//password: '',
loginType: 'currentPhone',
showPassword: false,
remember: true,
isValidCodeLogin: false,
validCode: '',
imgValidCodeSrc: null,
list: [{
name: '用户名'
}, {
name: '手机号'
}],
current: 0,
activeColor: '#007aff',
};
},
computed: {
appVersion() {
return manifest.versionName;
},
envName() {
return process.env.VUE_APP_ENV_NAME || '';
}
},
onShow() {
// 只在开发环境读取存储的URL
if (config.isDevelopment) {
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) {
console.log('e', JSON.stringify(e));
const selectedValue = this.apiUrlList[e[0]].value;
console.log('selectedValue', selectedValue)
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);
}
});
},
submit(loginType = '1') {
uni.showLoading({
title: '登录中...'
});
let currentApiUrl;
if (config.isDevelopment) {
// 开发环境使用选择的URL
currentApiUrl = this.selectedApiUrl === 'custom' ? this.customApiUrl : this.selectedApiUrl;
if (!currentApiUrl || currentApiUrl.length === 0) {
this.$u.toast('请输入服务器地址');
return;
}
// 更新store中的URL
this.$store.dispatch('updateApiUrl', currentApiUrl);
} else {
// 生产环境使用固定的生产URL
currentApiUrl = config.productionApiUrl;
}
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((res) => {
console.log('login res', res)
var aLoginUserData = res;
//console.log('--aLoginUserData->>' + JSON.stringify(aLoginUserData));
// 只在开发环境保存 apiurl 到本地存储
if (config.isDevelopment) {
uni.setStorage({
key: 'ApiUrl',
data: currentApiUrl
});
util.updateApiUrl(currentApiUrl);
}
// 保存 token 到本地存储
uni.setStorageSync('RemoteTokenData', aLoginUserData);
uni.setStorage({
key: 'userToken',
data: {
Token: aLoginUserData.token,
}
});
getApp().globalData.Token = aLoginUserData.token;
getApp().globalData.EmployeeID = aLoginUserData.user_id;
getApp().globalData.IsSaleUserStatus = 0;
getApp().globalData.LoginID = aLoginUserData.user_id;
getApp().globalData.LoginName = aLoginUserData.user_name;
getApp().globalData.PlanDepartmentID = aLoginUserData.default_sale_system_id;
getApp().globalData.PlanDepartmentName = aLoginUserData.default_sale_system_name;
getApp().globalData.UserGroup = '';
getApp().globalData.StoreNameID = aLoginUserData.default_physical_warehouse_id;
getApp().globalData.StoreName = aLoginUserData.default_physical_warehouse_name;
getApp().globalData.StoreTypeNo = '';
setTimeout(() => {
uni.reLaunch({
url: '/pages/sys/workbench/index'
});
}, 500);
var that = this
if (that.remember == true) {
if ((this.login.username.length > 0) && (this.login.password.length > 0)) {
uni.setStorage({
key: 'UserInfo',
data: that.login
})
}
}
uni.showToast({
icon: 'none',
title: '登录成功!'
});
this.$store.dispatch('initNotification');
setTimeout(function () {
uni.hideLoading();
}, 1000);
}).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() {
console.log('autoCheckUpgrade 开始执行');
const self = this;
app_upgrade(async (versionCode) => {
console.log('app_upgrade 回调被执行, versionCode:', versionCode);
try {
// 获取应用信息
const appInfo = await new Promise((resolve) => {
plus.runtime.getProperty(plus.runtime.appid, (inf) => {
resolve(inf);
});
});
console.log('appInfo:', appInfo);
const res = await self.$u.api.upgradeCheck({
app_name: config.upgradeName,
current_version: appInfo.version
});
console.log('自动检查版本更新结果:', res);
if (!res || !res.download_url) {
// 当前已是最新版本,不提示
console.log('当前已是最新版本');
return { status: 0 };
}
return {
changelog: res.message + ',最新版本:' + res.latest_version,
status: res.need_update ? 1 : 0, // 0 无新版本 | 1 有新版本
path: res.download_url // 新apk地址
};
} catch (error) {
console.log('检查版本更新失败:', error);
return { status: 0 };
}
}, 1); // 使用 type=1 强制检查,跳过时间戳检查
},
handleBlurInputUrl(e) {
// 只在开发环境处理自定义URL
if (config.isDevelopment) {
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';
.server-selector {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10rpx 0;
border-bottom: 1px solid #eee;
}
.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 10rpx auto;
}
.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;
}
.version-text {
font-size: 24rpx;
color: #999999;
}
.env-text {
font-size: 24rpx;
color: #5473e8;
margin-left: 10rpx;
}
</style>