You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

928 lines
24 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<view class="loginBack">
<view class="loginForm">
<view class="welcomeLogin">欢迎登录</view>
<view class="tip">瑜伽汇</view>
<!-- 登录方式切换 Tabs-->
<view class="login-tabs">
<!-- <view class="tab-item" :class="{ active: loginType === 'pwd' }" @click="loginType = 'pwd'">-->
<!-- 密码登录-->
<!-- </view>-->
<view class="tab-item" :class="{ active: loginType === 'sms' }" @click="loginType = 'sms'">
短信登录
</view>
</view>
<view class="formregion">
<uni-forms :model="form" ref="uForm">
<!-- 手机号共用 -->
<uni-forms-item prop="phonenumber">
<uni-easyinput type="number" placeholder="请输入手机号码" v-model="form.phonenumber" @blur="zhhandleBlur"
:inputBorder="false" :clearable="false" :placeholderStyle="placeholderStyle" />
</uni-forms-item>
<!-- &lt;!&ndash; 密码登录:密码 + 图形验证码 &ndash;&gt;-->
<block v-if="loginType === 'pwd'">
<uni-forms-item prop="password">
<uni-easyinput type="password" placeholder="请输入密码" v-model="form.password" @blur="mmhandleBlur"
maxlength="12" :inputBorder="false" :clearable="false" :placeholderStyle="placeholderStyle" />
</uni-forms-item>
<uni-forms-item prop="code">
<uni-easyinput type="text" placeholder="请输入验证码" v-model.trim="form.code" :inputBorder="false"
:clearable="false" :placeholderStyle="placeholderStyle" />
<image :src="checkimg" class="checkimg" mode="scaleToFill"></image>
<view class="codebtn" @click="getcode">看不清?</view>
</uni-forms-item>
<button type="primary" class="logincla" @click="loginpwdDo">登录</button>
</block>
<!-- 短信登录:短信验证码 -->
<block v-if="loginType === 'sms'">
<uni-forms-item prop="smsCode">
<!-- 新增一层相对定位容器,作为绝对定位按钮的参照物 -->
<view class="input-wrap">
<uni-easyinput
type="text"
placeholder="请输入短信验证码"
v-model.trim="form.smsCode"
:inputBorder="false"
:clearable="false"
:placeholderStyle="placeholderStyle"
/>
<view
class="sms-code-btn"
@click="sendSmsCode"
:class="{ disabled: smsCountdown > 0 }"
>
{{ smsCountdown > 0 ? smsCountdown + 's' : '获取验证码' }}
</view>
</view>
</uni-forms-item>
<button type="primary" class="logincla" @click="loginSmsDo">登录</button>
</block>
<view v-if="iflogin" class="loginno">登录中..</view>
<!-- <view class="regcon">
<view class="regtxtr" @click="gotoregister">注册账号 → </view>
</view> -->
<view class="xycon">
<view class="sitem">
<view class="selbtn">
<uni-data-checkbox multiple v-model="checkbox1" :localdata="checkboxitem"></uni-data-checkbox>
</view>
<view class="conright">
<text class="sname">
我已阅读并同意
</text>
<text class="adress" @click="gotofw">
</text>
<text class="sname">
</text>
<text class="adress" @click="gotoys">
</text>
</view>
</view>
</view>
<view class="regcon">
<!-- <view class="regtxtr" @click="gotoregister"> </view>-->
</view>
</uni-forms>
</view>
<u-toast ref="uToast" />
</view>
</view>
</template>
<script>
// #ifdef APP-PLUS
// const jpushModule = uni.requireNativePlugin('JG-JPush');
// #endif
import {myCache} from '../../utils/utils.js';
export default {
data() {
return {
checkimg: require("@/static/image/check.jpg"),
placeholderStyle:"font-size: 28rpx;color: #c3c4c6; text",
form: {
phonenumber:"",
password:"",
smsCode: "", // 短信验证码
code:"",
uuid:"",
registerId:"", // 设备id
position:"123.357586,41.862907", // 默认拾取 三朵兰瑜伽默认坐标
},
iflogin:false,
gcj02:"1",
address:'',
longitude:'', // 经度
latitude:'', // 维度
checkbox1: [1],
checkboxitem: [{
text: '',
value: 1,
}],
ifxy: false, // 是否选择协议
loginType:'sms',
smsCountdown: 0, // 短信验证码倒计时
smsTimer: null, // 定时器
}
},
onLoad(){
this.getcheckImg();
this.getsystemInfo();
this.getPosition();
},
methods: {
gotoregister() {
// 注册账号
uni.navigateTo({
url: `/pages/login/register`
});
},
gotopwd() {
// 修改密码
uni.navigateTo({
url: `/pages/user/pwdset`
});
},
// 获取定位
getPosition(){
const _this=this;
uni.getLocation({
type:'gcj02',//'gcj02','wgs84', // 返回的坐标类型wgs84 表示国际标准的经纬度
geocode:true,
success: function (res) {
console.log(res);
console.log('当前位置的经度:' + res.longitude);
console.log('当前位置的纬度:' + res.latitude);
_this.form.position=res.latitude+','+res.longitude;
_this.$forceUpdate();
},
fail: function (err) {
console.log('获取位置失败:' + err.errMsg);
uni.showModal({
title: '提示',
content: '请在设置中开启定位服务,注册默认地址信息!',
showCancel: false,
success: function (res) {
if (res.confirm) {
console.log('用户点击确定');
// #ifdef APP-PLUS
// 跳转到设置页面
plus.device.vendor = 'apple'; // 如果是iOS系统
if (plus.os.name == 'iOS') {
plus.runtime.openURL('prefs:root=LOCATION_SERVICES');
} else {
plus.runtime.openURL('package:' + plus.android.runtimeMainActivity());
}
// #endif
}
}
});
_this.form.position="123.357586,41.862907";
_this.$forceUpdate();
}
});
},
// 获取设备信息
getsystemInfo(){
const info = uni.getSystemInfoSync();
const platform = info.platform; // 手机安卓还是苹果
if (info.platform === 'ios') {
// ios
console.log('iOS 设备唯一标识:', info.deviceId);
}
else{
//安卓
console.log('设备信息ID:',info.deviceId);
}
this.form.registerId=info.deviceId;
this.$forceUpdate();
// const iosApp = info.platform;
console.log('iOS 设备名称:', info.model);
console.log('iOS 系统版本:', info.system);
console.log('iOS 设备唯一标识:', info.deviceId);
console.log('iOS 设备像素比:', info.devicePixelRatio);
console.log('iOS 设备屏幕宽度:', info.screenWidth);
console.log('iOS 设备屏幕高度:', info.screenHeight);
console.log('iOS 设备方向:', info.deviceOrientation);
// uni.showModal({
// title: '提示',
// content: info.deviceId,
// success(res) {
// if (res.confirm) {
// console.log('用户点击了确定');
// } else if (res.cancel) {
// console.log('用户点击了取消');
// }
// }
// });
},
async getcheckImg(){
// 验证图片信息
const {data: res} = await uni.$http.get('/captchaImage');
if (res&&res.img&&res.uuid) {
this.checkimg= 'data:image/png;base64,'+res.img;
this.form.uuid=res.uuid;
this.$forceUpdate();
}
},
// 判断密码是否合规
mmhandleBlur(e){
console.log(e)
if(e.detail.value&&e.detail.value.length<6){
// if(e.detail.value&&!this.checkMM(e.detail.value)){
// '6-20',
// '8-203'
// this.$refs.uToast.show({
// title: "6-202",
// type: 'error',
// duration: 2000
// });
}
},
//
checkMM(mm) {
// if (!(/^(?!([a-zA-Z]+|\d+)$)[a-zA-Z\d]{6,20}$/.test(mm))) {
// // if (!(/((^(?=.*[a-z])(?=.*[A-Z])(?=.*[^A-Za-z0-9])[\da-zA-Z_\W]{8,20}$)|(^(?=.*\d)(?=.*[A-Z])(?=.*[^A-Za-z0-9])[\da-zA-Z_\W]{8,20}$)|(^(?=.*\d)(?=.*[a-z])(?=.*[^A-Za-z0-9])[\da-zA-Z_\W]{8,20}$)|(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])[\da-zA-Z_\W]{8,20}$))/.test(mm))) {
// return false;
// }
return true;
},
//
zhhandleBlur(e){
console.log(e)
//
if(!this.$u.test.mobile(e.detail.value)){
this.$refs.uToast.show({
title: '',
type: 'warning',
duration: 2000
});
}
},
async getcode(){
uni.showLoading({
title: '...'
});
const {data: res} = await uni.$http.get('/captchaImage');
console.log(res);
if(res&&res.img&&res.uuid){
this.checkimg= 'data:image/png;base64,'+res.img;
this.form.uuid=res.uuid;
this.$forceUpdate();
}
else{
this.$refs.uToast.show({
title: "",
type: 'error',
duration: 2000
});
}
},
//
checkPhone(phone) {
if (!(/^1[3456789]\d{9}$/.test(phone))) {
return false;
}
return true;
},
//
chooseLocation(){
var _this=this;
uni.chooseLocation({
success: (data)=> {
console.log(data)
_this.gcj02="1";
var adrname = ((data.name===undefined||data.name===null)?'':data.name);
_this.address = ((data.address===undefined||data.address===null)?'':data.address) + adrname;
_this.latitude=data.latitude;
_this.longitude=data.longitude;
_this.form.position=_this.latitude+','+_this.longitude;
_this.$forceUpdate();
},
fail:(Error)=> {
_this.gcj02="1";
_this.address = "";
_this.latitude="";
_this.longitude="";
_this.form.position="";
_this.$forceUpdate();
}
});
},
login() {
// 测试
// myCache('token', "12345678");
// myCache('user', {
// phonenumber:"测试人",
// userid:"1",
// userphone:"18900000001",
// avatar:"/static/image/girl.png"
// });
// this.$refs.uToast.show({
// title: '登录成功',
// type: 'success',
// isTab: true,
// duration: 2000,
// url: '/pages/index/index'
// });
// 正式
this.loginpwdDo();
},
// 密码登录
async loginpwdDo(){
// 是否阅读协议
if(!this.checkxy()){
return false;
}
// 手机号码 密码是否输入
if(!this.form.phonenumber){
this.$refs.uToast.show({
title: "请输入手机号码!",
type: 'warn',
duration: 2000
});
return false;
}
if(!this.form.password){
this.$refs.uToast.show({
title: "请输入密码!",
type: 'warn',
duration: 2000
});
return false;
}
if(!this.form.code){
this.$refs.uToast.show({
title: "请输入验证码!",
type: 'warn',
duration: 2000
});
return false;
}
if(uni.getStorageSync("register_id")){
this.form.registerId=uni.getStorageSync("register_id");
this.$forceUpdate();
}
uni.setStorageSync('iftoken', "1");
uni.showLoading({
title: '正在登录...'
});
console.log("login--登录参数",this.form)
const {data: res} = await uni.$http.post('/api/login',this.form);
if(res&&res.code=="200"){
uni.setStorageSync("loginindex", "1");
uni.setStorageSync("token", res.token);
// 保存用户登录信息
this.getUserInfo();
// 保护用户门店信息
this.loadshop();
this.$refs.uToast.show({
title: '登录成功',
type: 'success',
isTab: true,
duration: 2000,
url: '/pages/index/index'
});
}
else{
if(res.msg=='验证码错误'){
// 重新获取验证码
this.getcode();
}
// uni.setStorageSync('token', this.form.uuid);
this.$refs.uToast.show({
title: res.msg?res.msg: "此账号登录失败!请重试!",
type: 'error',
duration: 2000
});
}
},
// 验证码登录
async getUserInfo(){
var _this=this;
const {data: res} = await uni.$http.get('/api/getInfo');
if(res&&res.appLoginUser){
var user=res.appLoginUser;
myCache('user',{
userid:user.userId,
nickName:user.nickName,
username:user.userName,
userphone:user.phoneNumber,
signature:user.signature,
avatar:user.avatar
});
myCache('userInfo',user);
myCache('phone',user.phoneNumber);
}
if(res&&res.visitStore){
var shop=res.visitStore;
myCache('shop',shop);
myCache('myshop',shop.storeName);
myCache('myshopid',shop.id);
// var shoplist=[shop]
// myCache('shoplist',shoplist);
}
getApp().$vm.init(user.userId)
},
checkxy(){
console.log(this.checkbox1);
if(this.checkbox1.length>0&&this.checkbox1[0]){
return true;
}
else{
uni.showModal({
title: '提示',
content: '请阅读并同意用户服务协议、隐私政策条款!',
cancelText: '取消',
confirmText: '确定',
success: ress => {
if (ress.confirm) {
}
}
});
return false;
}
},
async loadshop(){
// 获取门店
const {data: res} = await uni.$http.post('/api/index/getStores');
if(res.data&&res.data.length>0){
myCache('shoplist',res.data);
}
else{
console.log("shoplist")
var shop=myCache('shop');
var shoplist=shop?[shop]:[];
myCache('shoplist',shoplist);
}
},
async getUserShopList(){
var _this=this;
const {data: res} = await uni.$http.get('/api/getStoreList');
console.log(res);
if(res&&res.appLoginUser){
var user=res.appLoginUser;
myCache('user',{
userid:user.userId,
nickName:user.nickName,
username:user.userName,
userphone:user.phoneNumber,
avatar:user.avatar
});
myCache('userInfo',user);
myCache('phone',user.phoneNumber);
}
if(res&&res.visitStore){
var shop=res.visitStore;
myCache('shop',shop);
myCache('myshop',shop.storeName);
myCache('myshopid',shop.id);
var shoplist=[shop]
myCache('shoplist',shoplist);
}
},
gotofw(){
uni.navigateTo({
url: `/pages/user/infofw`
});
},
gotoys(){
uni.navigateTo({
url: `/pages/user/infoys`
});
},
// ========== 短信验证码相关 ==========
/**
* 发送短信验证码
*/
async sendSmsCode() {
// 1. 校验手机号
const phone = this.form.phonenumber;
if (!this.$u.test.mobile(phone)) {
this.$refs.uToast.show({
title: '请输入正确的手机号码',
type: 'warning',
duration: 2000
});
return;
}
console.log(12)
// 2. 防止重复点击(倒计时中)
if (this.smsCountdown > 0) {
return;
}
console.log(34)
// 3. 调用发送接口
uni.showLoading({
title: '发送中...'
});
try {
console.log(56)
const {
data: res
} = await uni.$http.post('/sms/sendCode', {
phone: phone
});
console.log(78)
uni.hideLoading();
console.log(9)
if (res && res.code === 200) {
this.$refs.uToast.show({
title: '验证码已发送',
type: 'success',
duration: 2000
});
// 开始倒计时
this.startCountdown();
} else {
this.$refs.uToast.show({
title: res.msg || '发送失败,请重试',
type: 'error',
duration: 2000
});
}
} catch (e) {
uni.hideLoading();
this.$refs.uToast.show({
title: '发送失败,请检查网络',
type: 'error',
duration: 2000
});
}
},
/**
* 开始60秒倒计时
*/
startCountdown() {
this.smsCountdown = 60;
if (this.smsTimer) {
clearInterval(this.smsTimer);
}
this.smsTimer = setInterval(() => {
this.smsCountdown--;
if (this.smsCountdown <= 0) {
clearInterval(this.smsTimer);
this.smsTimer = null;
}
}, 1000);
},
/**
* 短信验证码登录
*/
async loginSmsDo() {
const phone = this.form.phonenumber;
const smsCode = this.form.smsCode;
// 是否阅读协议
if(!this.checkxy()){
return false;
}
if (!this.$u.test.mobile(phone)) {
this.$refs.uToast.show({
title: '请输入正确的手机号码',
type: 'warning',
duration: 2000
});
return;
}
if (!smsCode || smsCode.length !== 6) {
this.$refs.uToast.show({
title: '请输入6位短信验证码',
type: 'warning',
duration: 2000
});
return;
}
if (uni.getStorageSync("register_id")) {
this.form.registerId = uni.getStorageSync("register_id");
}
uni.setStorageSync('iftoken', "1");
uni.showLoading({
title: '登录中...'
});
try {
const {
data: res
} = await uni.$http.post('/api/sms/login', {
phonenumber: phone,
smsCode: smsCode,
registerId: this.form.registerId,
position: this.form.position
});
if (res && res.code === 200) {
uni.setStorageSync("loginindex", "1");
uni.setStorageSync("token", res.token);
// 保存用户信息
this.getUserInfo();
this.loadshop();
this.$refs.uToast.show({
title: '登录成功',
type: 'success',
isTab: true,
duration: 2000,
url: '/pages/index/index'
});
} else {
this.$refs.uToast.show({
title: res.msg || '登录失败,请重试',
type: 'error',
duration: 2000
});
}
} catch (e) {
uni.hideLoading();
this.$refs.uToast.show({
title: '登录失败,请检查网络',
type: 'error',
duration: 2000
});
}
},
}
}
</script>
<style>
</style>
<style lang="scss" scoped>
::v-deep .u-checkbox__label{
color:#bdbfc1
}
::v-deep .uni-easyinput__content-input {
width: 500rpx;
height: 80rpx;
background: #fff;
box-shadow: 0rpx 12rpx 64rpx 2rpx rgba(137, 150, 95, 0.3);
border-radius: 254rpx 254rpx 254rpx 254rpx;
}
::v-deep .uni-easyinput__content{
border-radius: 254rpx 254rpx 254rpx 254rpx;
text-indent: 20rpx;
}
/* ====== 新增 Tabs 样式 ====== */
.login-tabs {
display: flex;
justify-content: center;
background: #fff;
border-radius: 10px 10px 0 0;
padding: 10rpx 0 0 0;
margin-top: 10rpx;
.tab-item {
flex: 1;
text-align: center;
font-size: 30rpx;
padding: 20rpx 0;
color: #999;
border-bottom: 6rpx solid transparent;
transition: all 0.3s;
&.active {
color: #00a89b;
border-bottom-color: #00a89b;
font-weight: 600;
}
}
}
/* ====== 短信验证码按钮 ====== */
.sms-code-btn {
position: absolute;
top: 12rpx; /* 与 codebtn 对齐 */
width: 180rpx;
right: 20rpx;
display: block;
display: flex; /* 改为 flex */
align-items: center; /* 垂直居中 */
justify-content: center; /* 水平居中 */
color: #00a89b;
height: 60rpx;
line-height: 60rpx;
font-size: 26rpx;
padding: 0 20rpx;
background: #f0f0f0; /* 浅灰底,便于区分 */
border-radius: 30rpx;
/* 移除 transform避免基准偏移 */
&.disabled {
color: #999;
background: #e8e8e8;
}
}
.lttxt{
font-size: 30rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 400;
color:#333333;
line-height: 38rpx;
height: 45rpx;
margin: 30rpx auto;
text-align: center;
}
.timetxt{
position: absolute;
top:20rpx;
right: 28rpx;
display: block;
font-size: 36rpx;
color:#00a89b;
line-height: 38rpx;
height: 45rpx;
margin-left: 50rpx;
}
.checkimg{
position: absolute;
top: 8rpx;
right: 130rpx;
width: 160rpx;
height: 66rpx;
}
.codebtn{
position: absolute;
top:12rpx;
right: 20rpx;
display: block;
color:#00a89b;
height: 60rpx;
line-height: 60rpx;
font-size: 26rpx;
padding: 0 10rpx;
}
.regcon{
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
margin-top: 36rpx;
.regtxt{
color:#00a89b;
font-size: 28rpx;
display: flex;
align-items: center;
}
.regtxtl{
color:#00a89b;
width: 2rpx;
height: 26rpx;
font-size: 26rpx;
margin-left: 10rpx;
margin-right: 10rpx;
border-right: 1rpx solid #00a89b;
display: flex;
align-items: center;
}
.regtxtr{
color:#00a89b;
height: 28rpx;
font-size: 28rpx;
display: flex;
align-items: center;
margin-right: 10rpx;
}
}
.loginno{
display: block;
background-color:rgba(137, 150, 95, 0.3);
width: 100%;
line-height: 2;
margin-top: 30rpx;
border-radius:12rpx;
font-size: 30rpx;
text-align: center;
box-sizing:border-box;
}
.logincla{
display: block;
font-family: $font-family;
width: 100%;
line-height: 2;
}
.loginBack {
color: #fff;
height: 100vh;
padding:60rpx 50rpx 200rpx 50rpx;
width: 100%;
overflow: hidden;
background-size: 100% 100%;
background-image: url('../../static/image/lgbg.jpg');
.inpuIcon {
width: 46rpx;
height: 46rpx;
margin-right: 30rpx;
}
.formregion {
width: 100%;
padding: 30px 50rpx 20rpx;
background-color: #fff;
border-radius: 0 0 10px 10px;
margin-top: 10rpx;
position: relative;
display: block;
overflow: hidden;
.logo{
position: absolute;
top: -20rpx;
left: 0;
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.define {
width: 120rpx;
height: 120rpx;
}
}
}
.welcomeLogin {
font-size: 30rpx;
letter-spacing: 2rpx;
padding: 20rpx 0 10rpx;
margin: 0 auto;
width: 100%;
}
.tip{
font-weight: 600;
font-size: 42rpx;
letter-spacing: 4rpx;
padding: 0 0 40rpx 0;
}
.xycon{
display: flex;
align-items: center;
justify-content: center;
padding: 20rpx 0 0;
width: 100%;
.sitem {
display: flex;
flex-direction: row;
.conright{
flex: 1;
margin: 10rpx 0;
margin-left: -36rpx;
}
.selbtn{
width: 80rpx;
display: flex;
justify-content: center;
align-items: center;
margin-left: 10rpx;
}
.sname{
font-size: 24rpx;
font-weight: 400;
color: #23262F;
line-height: 36rpx;
}
.adress{
font-size: 24rpx;
font-weight: 400;
color: #00a89b;
line-height: 36rpx;
}
}
}
</style>