|
|
|
@ -1,214 +1,717 @@
|
|
|
|
|
|
|
|
<!-- #ifdef H5 -->
|
|
|
|
|
|
|
|
<!-- 可选:引入微信JS-SDK,用于更高级的微信功能 -->
|
|
|
|
|
|
|
|
<!-- <script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script> -->
|
|
|
|
|
|
|
|
<!-- #endif -->
|
|
|
|
|
|
|
|
|
|
|
|
<template>
|
|
|
|
<template>
|
|
|
|
<view class="container">
|
|
|
|
<view class="container">
|
|
|
|
<view class="header">
|
|
|
|
<view class="header">
|
|
|
|
<div class="line">您好,</div>
|
|
|
|
<div class="line">您好,</div>
|
|
|
|
<div class="line">欢迎使用电梯图纸生成平台</div>
|
|
|
|
<div class="line">欢迎使用电梯图纸生成平台</div>
|
|
|
|
</view>
|
|
|
|
</view>
|
|
|
|
<div class="main">
|
|
|
|
<div class="main">
|
|
|
|
<view class="form">
|
|
|
|
<view class="form">
|
|
|
|
<uv-form labelAlign="right" labelWidth="50" labelPosition="top" :model="userInfo" :rules="rules"
|
|
|
|
<uv-form
|
|
|
|
ref="form">
|
|
|
|
labelAlign="right"
|
|
|
|
<uv-form-item prop="phone">
|
|
|
|
labelWidth="50"
|
|
|
|
<div class="formLabel">
|
|
|
|
labelPosition="top"
|
|
|
|
<img class="img" src="/static/imgs/phone.png" alt="">
|
|
|
|
:model="userInfo"
|
|
|
|
手机号
|
|
|
|
:rules="rules"
|
|
|
|
</div>
|
|
|
|
ref="form"
|
|
|
|
<uv-input v-model="userInfo.phone" color="#000" border="bottom"
|
|
|
|
>
|
|
|
|
:placeholderStyle="{color:'#666778'}" placeholder="请输入用户名">
|
|
|
|
<uv-form-item prop="phone">
|
|
|
|
</uv-input>
|
|
|
|
<div class="formLabel">
|
|
|
|
</uv-form-item>
|
|
|
|
<img class="img" src="/static/imgs/phone.png" alt="" />
|
|
|
|
<uv-form-item prop="password">
|
|
|
|
手机号
|
|
|
|
<div class="formLabel">
|
|
|
|
</div>
|
|
|
|
<img class="img" src="/static/imgs/code.png" alt="">
|
|
|
|
<uv-input
|
|
|
|
验证码
|
|
|
|
v-model="userInfo.phone"
|
|
|
|
</div>
|
|
|
|
color="#000"
|
|
|
|
<uv-input v-model="userInfo.password" color="#000" border="bottom"
|
|
|
|
border="bottom"
|
|
|
|
:placeholderStyle="{color:'#666778'}" placeholder="请输入验证码">
|
|
|
|
:placeholderStyle="{ color: '#666778' }"
|
|
|
|
<template v-slot:suffix>
|
|
|
|
placeholder="请输入用户名"
|
|
|
|
<uv-code ref="codeRef" @change="codeChange" seconds="20" changeText="X秒重新获取"></uv-code>
|
|
|
|
></uv-input>
|
|
|
|
<text style="color:#4D82FD" @click="getCode">{{tips}}</text>
|
|
|
|
</uv-form-item>
|
|
|
|
</template>
|
|
|
|
<uv-form-item prop="password">
|
|
|
|
</uv-input>
|
|
|
|
<div class="formLabel">
|
|
|
|
</uv-form-item>
|
|
|
|
<img class="img" src="/static/imgs/code.png" alt="" />
|
|
|
|
</uv-form>
|
|
|
|
验证码
|
|
|
|
</view>
|
|
|
|
</div>
|
|
|
|
<uv-button @click="login" customStyle="margin-top:30px" text="登录" color="#3F70FF"></uv-button>
|
|
|
|
<uv-input
|
|
|
|
<div class="wechatBox">
|
|
|
|
v-model="userInfo.password"
|
|
|
|
<uv-divider text="第三方登录"></uv-divider>
|
|
|
|
color="#000"
|
|
|
|
<uv-icon name="weixin-circle-fill" color="#5fc157" size="50"></uv-icon>
|
|
|
|
border="bottom"
|
|
|
|
</div>
|
|
|
|
:placeholderStyle="{ color: '#666778' }"
|
|
|
|
</div>
|
|
|
|
placeholder="请输入验证码"
|
|
|
|
</view>
|
|
|
|
>
|
|
|
|
|
|
|
|
<template v-slot:suffix>
|
|
|
|
|
|
|
|
<uv-code
|
|
|
|
|
|
|
|
ref="codeRef"
|
|
|
|
|
|
|
|
@change="codeChange"
|
|
|
|
|
|
|
|
seconds="20"
|
|
|
|
|
|
|
|
changeText="X秒重新获取"
|
|
|
|
|
|
|
|
></uv-code>
|
|
|
|
|
|
|
|
<text style="color: #4d82fd" @click="getCode">{{ tips }}</text>
|
|
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
</uv-input>
|
|
|
|
|
|
|
|
</uv-form-item>
|
|
|
|
|
|
|
|
</uv-form>
|
|
|
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
<uv-button
|
|
|
|
|
|
|
|
@click="login"
|
|
|
|
|
|
|
|
customStyle="margin-top:30px"
|
|
|
|
|
|
|
|
text="登录"
|
|
|
|
|
|
|
|
color="#3F70FF"
|
|
|
|
|
|
|
|
></uv-button>
|
|
|
|
|
|
|
|
<div class="wechatBox" v-if="showWechatLogin">
|
|
|
|
|
|
|
|
<uv-divider text="第三方登录"></uv-divider>
|
|
|
|
|
|
|
|
<uv-icon
|
|
|
|
|
|
|
|
name="weixin-circle-fill"
|
|
|
|
|
|
|
|
color="#5fc157"
|
|
|
|
|
|
|
|
size="50"
|
|
|
|
|
|
|
|
@click="wechatLogin"
|
|
|
|
|
|
|
|
></uv-icon>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 微信登录绑定手机号弹窗 -->
|
|
|
|
|
|
|
|
<uv-popup
|
|
|
|
|
|
|
|
ref="popup"
|
|
|
|
|
|
|
|
mode="center"
|
|
|
|
|
|
|
|
:closeOnClickOverlay="false"
|
|
|
|
|
|
|
|
:round="10"
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
<view class="bind-phone-modal">
|
|
|
|
|
|
|
|
<view class="modal-header">
|
|
|
|
|
|
|
|
<view class="modal-title">绑定手机号</view>
|
|
|
|
|
|
|
|
<view class="modal-subtitle">为了您的账户安全,请绑定手机号</view>
|
|
|
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<view class="modal-form">
|
|
|
|
|
|
|
|
<uv-form
|
|
|
|
|
|
|
|
:model="bindPhoneInfo"
|
|
|
|
|
|
|
|
:rules="bindPhoneRules"
|
|
|
|
|
|
|
|
ref="bindPhoneForm"
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
<uv-form-item prop="phone">
|
|
|
|
|
|
|
|
<uv-input
|
|
|
|
|
|
|
|
v-model="bindPhoneInfo.phone"
|
|
|
|
|
|
|
|
placeholder="请输入手机号"
|
|
|
|
|
|
|
|
type="number"
|
|
|
|
|
|
|
|
maxlength="11"
|
|
|
|
|
|
|
|
border="surround"
|
|
|
|
|
|
|
|
></uv-input>
|
|
|
|
|
|
|
|
</uv-form-item>
|
|
|
|
|
|
|
|
<uv-form-item prop="code">
|
|
|
|
|
|
|
|
<uv-input
|
|
|
|
|
|
|
|
v-model="bindPhoneInfo.code"
|
|
|
|
|
|
|
|
placeholder="请输入验证码"
|
|
|
|
|
|
|
|
border="surround"
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
<template v-slot:suffix>
|
|
|
|
|
|
|
|
<uv-code
|
|
|
|
|
|
|
|
ref="bindCodeRef"
|
|
|
|
|
|
|
|
@change="bindCodeChange"
|
|
|
|
|
|
|
|
seconds="60"
|
|
|
|
|
|
|
|
changeText="X秒重新获取"
|
|
|
|
|
|
|
|
></uv-code>
|
|
|
|
|
|
|
|
<text
|
|
|
|
|
|
|
|
style="color: #4d82fd; font-size: 12px"
|
|
|
|
|
|
|
|
@click="getBindCode"
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
{{ bindCodeTips }}
|
|
|
|
|
|
|
|
</text>
|
|
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
</uv-input>
|
|
|
|
|
|
|
|
</uv-form-item>
|
|
|
|
|
|
|
|
</uv-form>
|
|
|
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<view class="modal-actions">
|
|
|
|
|
|
|
|
<!-- <uv-button
|
|
|
|
|
|
|
|
type="default"
|
|
|
|
|
|
|
|
@click="closeBindPhoneModal"
|
|
|
|
|
|
|
|
customStyle="margin-right: 12px;"
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
取消
|
|
|
|
|
|
|
|
</uv-button> -->
|
|
|
|
|
|
|
|
<uv-button
|
|
|
|
|
|
|
|
type="primary"
|
|
|
|
|
|
|
|
@click="confirmBindPhone"
|
|
|
|
|
|
|
|
:loading="bindingPhone"
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
确认绑定
|
|
|
|
|
|
|
|
</uv-button>
|
|
|
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
</uv-popup>
|
|
|
|
|
|
|
|
</view>
|
|
|
|
</template>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<script setup>
|
|
|
|
<script setup>
|
|
|
|
import {
|
|
|
|
import { ref, onMounted } from "vue";
|
|
|
|
ref
|
|
|
|
import {
|
|
|
|
} from "vue";
|
|
|
|
HOME_PATH,
|
|
|
|
import {
|
|
|
|
LOGIN_PATH,
|
|
|
|
HOME_PATH,
|
|
|
|
isTabBarPath,
|
|
|
|
LOGIN_PATH,
|
|
|
|
removeQueryString,
|
|
|
|
isTabBarPath,
|
|
|
|
} from "@/router";
|
|
|
|
removeQueryString,
|
|
|
|
import { useAuthStore, useUserStore } from "@/store";
|
|
|
|
} from "@/router";
|
|
|
|
import { onLoad } from "@dcloudio/uni-app";
|
|
|
|
import {
|
|
|
|
|
|
|
|
useAuthStore,
|
|
|
|
import RPC from "@/utils/request";
|
|
|
|
useUserStore
|
|
|
|
|
|
|
|
} from "@/store";
|
|
|
|
const authStore = useAuthStore();
|
|
|
|
import {
|
|
|
|
const userStore = useUserStore();
|
|
|
|
onLoad
|
|
|
|
|
|
|
|
} from "@dcloudio/uni-app";
|
|
|
|
// 环境判断
|
|
|
|
|
|
|
|
const showWechatLogin = ref(false);
|
|
|
|
import RPC from "@/utils/request"
|
|
|
|
|
|
|
|
|
|
|
|
// 微信登录绑定手机号相关
|
|
|
|
const authStore = useAuthStore()
|
|
|
|
// const showBindPhoneModal = ref(false);
|
|
|
|
const userStore = useUserStore()
|
|
|
|
const popup = ref(null);
|
|
|
|
|
|
|
|
const bindingPhone = ref(false);
|
|
|
|
const tips = ref('获取验证码')
|
|
|
|
const bindCodeTips = ref("获取验证码");
|
|
|
|
const codeChange = (text) => {
|
|
|
|
const bindCodeRef = ref(null);
|
|
|
|
tips.value = text
|
|
|
|
const bindPhoneForm = ref(null);
|
|
|
|
}
|
|
|
|
const bindPhoneInfo = ref({
|
|
|
|
const codeRef = ref(null)
|
|
|
|
phone: "",
|
|
|
|
const getCode = () => {
|
|
|
|
code: "",
|
|
|
|
|
|
|
|
});
|
|
|
|
if(!userInfo.phone) {
|
|
|
|
const bindPhoneRules = ref({
|
|
|
|
uni.showToast({
|
|
|
|
phone: [
|
|
|
|
title:'请填写手机号',
|
|
|
|
{
|
|
|
|
icon:'none'
|
|
|
|
required: true,
|
|
|
|
});
|
|
|
|
message: "请输入手机号",
|
|
|
|
return
|
|
|
|
trigger: ["blur", "change"],
|
|
|
|
}
|
|
|
|
},
|
|
|
|
if (codeRef.value.canGetCode) {
|
|
|
|
{
|
|
|
|
// 模拟向后端请求验证码
|
|
|
|
pattern: /^1[3-9]\d{9}$/,
|
|
|
|
uni.showLoading({
|
|
|
|
message: "请输入正确的手机号",
|
|
|
|
title: '正在获取验证码'
|
|
|
|
trigger: ["blur", "change"],
|
|
|
|
})
|
|
|
|
},
|
|
|
|
setTimeout(() => {
|
|
|
|
],
|
|
|
|
uni.hideLoading();
|
|
|
|
code: {
|
|
|
|
// 这里此提示会被this.start()方法中的提示覆盖
|
|
|
|
required: true,
|
|
|
|
uni.showToast({
|
|
|
|
message: "请输入验证码",
|
|
|
|
title:'验证码已发送',
|
|
|
|
trigger: ["blur", "change"],
|
|
|
|
icon:'none'
|
|
|
|
},
|
|
|
|
});
|
|
|
|
});
|
|
|
|
// 通知验证码组件内部开始倒计时
|
|
|
|
|
|
|
|
codeRef.value.start();
|
|
|
|
const tips = ref("获取验证码");
|
|
|
|
}, 2000);
|
|
|
|
const codeChange = (text) => {
|
|
|
|
} else {
|
|
|
|
tips.value = text;
|
|
|
|
uni.showToast({
|
|
|
|
};
|
|
|
|
title:'倒计时结束后再发送',
|
|
|
|
const codeRef = ref(null);
|
|
|
|
icon:'none'
|
|
|
|
const getCode = () => {
|
|
|
|
})
|
|
|
|
if (!userInfo.phone) {
|
|
|
|
}
|
|
|
|
uni.showToast({
|
|
|
|
}
|
|
|
|
title: "请填写手机号",
|
|
|
|
|
|
|
|
icon: "none",
|
|
|
|
|
|
|
|
});
|
|
|
|
const form = ref(null)
|
|
|
|
return;
|
|
|
|
const userInfo = ref({
|
|
|
|
}
|
|
|
|
phone: '',
|
|
|
|
if (codeRef.value.canGetCode) {
|
|
|
|
password: '',
|
|
|
|
// 模拟向后端请求验证码
|
|
|
|
})
|
|
|
|
uni.showLoading({
|
|
|
|
const rules = ref({
|
|
|
|
title: "正在获取验证码",
|
|
|
|
'phone': {
|
|
|
|
});
|
|
|
|
required: true,
|
|
|
|
setTimeout(() => {
|
|
|
|
message: '请填写手机号',
|
|
|
|
uni.hideLoading();
|
|
|
|
trigger: ['blur', 'change']
|
|
|
|
// 这里此提示会被this.start()方法中的提示覆盖
|
|
|
|
},
|
|
|
|
uni.showToast({
|
|
|
|
'password': {
|
|
|
|
title: "验证码已发送",
|
|
|
|
required: true,
|
|
|
|
icon: "none",
|
|
|
|
message: '请填写验证码',
|
|
|
|
});
|
|
|
|
trigger: ['blur', 'change']
|
|
|
|
// 通知验证码组件内部开始倒计时
|
|
|
|
}
|
|
|
|
codeRef.value.start();
|
|
|
|
})
|
|
|
|
}, 2000);
|
|
|
|
let redirect = HOME_PATH;
|
|
|
|
} else {
|
|
|
|
onLoad((options) => {
|
|
|
|
uni.showToast({
|
|
|
|
if (options.redirect && removeQueryString(options.redirect) !== LOGIN_PATH) {
|
|
|
|
title: "倒计时结束后再发送",
|
|
|
|
redirect = decodeURIComponent(options.redirect)
|
|
|
|
icon: "none",
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
const login = async () => {
|
|
|
|
|
|
|
|
await form.value.validate()
|
|
|
|
const form = ref(null);
|
|
|
|
console.log(userInfo.value)
|
|
|
|
const userInfo = ref({
|
|
|
|
// RPC.post('/account/login', {
|
|
|
|
phone: "",
|
|
|
|
// username: userInfo.value.name,
|
|
|
|
password: "",
|
|
|
|
// password: userInfo.value.password,
|
|
|
|
});
|
|
|
|
// }, {
|
|
|
|
const rules = ref({
|
|
|
|
// custom: {
|
|
|
|
phone: [
|
|
|
|
// loading: true,
|
|
|
|
{
|
|
|
|
// loadingText: '正在登录...'
|
|
|
|
required: true,
|
|
|
|
// },
|
|
|
|
message: "请输入手机号",
|
|
|
|
// }).then(res => {
|
|
|
|
trigger: ["blur", "change"],
|
|
|
|
// authStore.setAccessToken(res.token)
|
|
|
|
},
|
|
|
|
// userStore.setUserInfo(res)
|
|
|
|
{
|
|
|
|
// uni.$uv.route({
|
|
|
|
pattern: /^1[3-9]\d{9}$/,
|
|
|
|
// type: isTabBarPath(redirect) ? "switchTab" : "redirectTo",
|
|
|
|
message: "请输入正确的手机号",
|
|
|
|
// url: redirect,
|
|
|
|
trigger: ["blur", "change"],
|
|
|
|
// });
|
|
|
|
},
|
|
|
|
// })
|
|
|
|
],
|
|
|
|
authStore.setAccessToken('accessToken')
|
|
|
|
password: {
|
|
|
|
setTimeout(() => {
|
|
|
|
required: true,
|
|
|
|
uni.$uv.route({
|
|
|
|
message: "请填写验证码",
|
|
|
|
type: isTabBarPath(redirect) ? "switchTab" : "redirectTo",
|
|
|
|
trigger: ["blur", "change"],
|
|
|
|
url: redirect,
|
|
|
|
},
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}, 800);
|
|
|
|
let redirect = HOME_PATH;
|
|
|
|
}
|
|
|
|
onLoad((options) => {
|
|
|
|
|
|
|
|
if (options.redirect && removeQueryString(options.redirect) !== LOGIN_PATH) {
|
|
|
|
|
|
|
|
redirect = decodeURIComponent(options.redirect);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 检查运行环境
|
|
|
|
|
|
|
|
const checkEnvironment = () => {
|
|
|
|
|
|
|
|
// #ifdef MP-WEIXIN
|
|
|
|
|
|
|
|
// 微信小程序环境
|
|
|
|
|
|
|
|
showWechatLogin.value = true;
|
|
|
|
|
|
|
|
// #endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// #ifdef H5
|
|
|
|
|
|
|
|
// H5环境,检查是否在微信内
|
|
|
|
|
|
|
|
const ua = navigator.userAgent.toLowerCase();
|
|
|
|
|
|
|
|
const isWechat = ua.indexOf("micromessenger") !== -1;
|
|
|
|
|
|
|
|
showWechatLogin.value = isWechat;
|
|
|
|
|
|
|
|
// #endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// #ifdef APP-PLUS
|
|
|
|
|
|
|
|
// App环境,不显示微信登录
|
|
|
|
|
|
|
|
showWechatLogin.value = false;
|
|
|
|
|
|
|
|
// #endif
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 微信登录
|
|
|
|
|
|
|
|
const wechatLogin = () => {
|
|
|
|
|
|
|
|
// #ifdef MP-WEIXIN
|
|
|
|
|
|
|
|
// 微信小程序登录
|
|
|
|
|
|
|
|
// uni.login({
|
|
|
|
|
|
|
|
// provider: "weixin",
|
|
|
|
|
|
|
|
// success: (loginRes) => {
|
|
|
|
|
|
|
|
// console.log("微信登录成功:", loginRes);
|
|
|
|
|
|
|
|
// // 获取用户信息
|
|
|
|
|
|
|
|
// uni.getUserProfile({
|
|
|
|
|
|
|
|
// desc: "用于完善用户资料",
|
|
|
|
|
|
|
|
// success: (userRes) => {
|
|
|
|
|
|
|
|
// console.log("获取用户信息成功:", userRes);
|
|
|
|
|
|
|
|
// // 显示绑定手机号弹窗
|
|
|
|
|
|
|
|
// showBindPhoneModal.value = true;
|
|
|
|
|
|
|
|
// },
|
|
|
|
|
|
|
|
// fail: (err) => {
|
|
|
|
|
|
|
|
// console.error("获取用户信息失败:", err);
|
|
|
|
|
|
|
|
// uni.showToast({
|
|
|
|
|
|
|
|
// title: "获取用户信息失败",
|
|
|
|
|
|
|
|
// icon: "none",
|
|
|
|
|
|
|
|
// });
|
|
|
|
|
|
|
|
// },
|
|
|
|
|
|
|
|
// });
|
|
|
|
|
|
|
|
// },
|
|
|
|
|
|
|
|
// fail: (err) => {
|
|
|
|
|
|
|
|
// console.error("微信登录失败:", err);
|
|
|
|
|
|
|
|
// uni.showToast({
|
|
|
|
|
|
|
|
// title: "微信登录失败",
|
|
|
|
|
|
|
|
// icon: "none",
|
|
|
|
|
|
|
|
// });
|
|
|
|
|
|
|
|
// },
|
|
|
|
|
|
|
|
// });
|
|
|
|
|
|
|
|
popup.value.open();
|
|
|
|
|
|
|
|
// #endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// #ifdef H5
|
|
|
|
|
|
|
|
// H5微信登录
|
|
|
|
|
|
|
|
if (typeof WeixinJSBridge !== "undefined") {
|
|
|
|
|
|
|
|
// 在微信内,使用微信JS-SDK进行授权登录
|
|
|
|
|
|
|
|
wechatH5Login();
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
uni.showToast({
|
|
|
|
|
|
|
|
title: "请在微信中打开",
|
|
|
|
|
|
|
|
icon: "none",
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// #endif
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 获取绑定手机号验证码
|
|
|
|
|
|
|
|
const getBindCode = () => {
|
|
|
|
|
|
|
|
if (!bindPhoneInfo.value.phone) {
|
|
|
|
|
|
|
|
uni.showToast({
|
|
|
|
|
|
|
|
title: "请输入手机号",
|
|
|
|
|
|
|
|
icon: "none",
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!/^1[3-9]\d{9}$/.test(bindPhoneInfo.value.phone)) {
|
|
|
|
|
|
|
|
uni.showToast({
|
|
|
|
|
|
|
|
title: "请输入正确的手机号",
|
|
|
|
|
|
|
|
icon: "none",
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (bindCodeRef.value.canGetCode) {
|
|
|
|
|
|
|
|
uni.showLoading({
|
|
|
|
|
|
|
|
title: "正在获取验证码",
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 调用发送验证码API
|
|
|
|
|
|
|
|
// RPC.post('/api/sms/send', {
|
|
|
|
|
|
|
|
// phone: bindPhoneInfo.value.phone,
|
|
|
|
|
|
|
|
// type: 'bind'
|
|
|
|
|
|
|
|
// }).then(() => {
|
|
|
|
|
|
|
|
// uni.hideLoading()
|
|
|
|
|
|
|
|
// uni.showToast({
|
|
|
|
|
|
|
|
// title: '验证码已发送',
|
|
|
|
|
|
|
|
// icon: 'success'
|
|
|
|
|
|
|
|
// })
|
|
|
|
|
|
|
|
// bindCodeRef.value.start()
|
|
|
|
|
|
|
|
// }).catch(() => {
|
|
|
|
|
|
|
|
// uni.hideLoading()
|
|
|
|
|
|
|
|
// uni.showToast({
|
|
|
|
|
|
|
|
// title: '发送失败,请重试',
|
|
|
|
|
|
|
|
// icon: 'none'
|
|
|
|
|
|
|
|
// })
|
|
|
|
|
|
|
|
// })
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 模拟发送验证码
|
|
|
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
|
|
|
uni.hideLoading();
|
|
|
|
|
|
|
|
uni.showToast({
|
|
|
|
|
|
|
|
title: "验证码已发送",
|
|
|
|
|
|
|
|
icon: "success",
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
bindCodeRef.value.start();
|
|
|
|
|
|
|
|
}, 1500);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
uni.showToast({
|
|
|
|
|
|
|
|
title: "倒计时结束后再发送",
|
|
|
|
|
|
|
|
icon: "none",
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 绑定验证码倒计时回调
|
|
|
|
|
|
|
|
const bindCodeChange = (text) => {
|
|
|
|
|
|
|
|
bindCodeTips.value = text;
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// H5微信登录方法
|
|
|
|
|
|
|
|
const wechatH5Login = () => {
|
|
|
|
|
|
|
|
// #ifdef H5
|
|
|
|
|
|
|
|
// 构建微信授权URL
|
|
|
|
|
|
|
|
const appId = "YOUR_WECHAT_APP_ID"; // 替换为你的微信公众号AppID
|
|
|
|
|
|
|
|
const redirectUri = encodeURIComponent(
|
|
|
|
|
|
|
|
window.location.origin + "/pages/login/login"
|
|
|
|
|
|
|
|
); // 授权回调地址
|
|
|
|
|
|
|
|
const scope = "snsapi_userinfo"; // 授权作用域
|
|
|
|
|
|
|
|
const state = "STATE" + Date.now(); // 防止CSRF攻击的随机字符串
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 检查是否已经有授权码
|
|
|
|
|
|
|
|
const urlParams = new URLSearchParams(window.location.search);
|
|
|
|
|
|
|
|
const code = urlParams.get("code");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (code) {
|
|
|
|
|
|
|
|
// 已经获得授权码,处理登录
|
|
|
|
|
|
|
|
handleWechatH5Callback(code);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
// 跳转到微信授权页面
|
|
|
|
|
|
|
|
const authUrl = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appId}&redirect_uri=${redirectUri}&response_type=code&scope=${scope}&state=${state}#wechat_redirect`;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
uni.showLoading({
|
|
|
|
|
|
|
|
title: "正在跳转微信授权...",
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 跳转到微信授权页面
|
|
|
|
|
|
|
|
window.location.href = authUrl;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// #endif
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 处理微信H5授权回调
|
|
|
|
|
|
|
|
const handleWechatH5Callback = async (code) => {
|
|
|
|
|
|
|
|
// #ifdef H5
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
uni.showLoading({
|
|
|
|
|
|
|
|
title: "正在获取用户信息...",
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 调用后端接口,通过code获取用户信息
|
|
|
|
|
|
|
|
// const result = await RPC.post('/api/wechat/h5-login', {
|
|
|
|
|
|
|
|
// code: code
|
|
|
|
|
|
|
|
// });
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 模拟获取用户信息
|
|
|
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
|
|
|
uni.hideLoading();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 模拟获取到的用户信息
|
|
|
|
|
|
|
|
const userInfo = {
|
|
|
|
|
|
|
|
openid: "mock_openid_" + Date.now(),
|
|
|
|
|
|
|
|
nickname: "微信用户",
|
|
|
|
|
|
|
|
headimgurl: "/static/imgs/avatar.png",
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
console.log("微信H5登录成功,用户信息:", userInfo);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 显示绑定手机号弹窗
|
|
|
|
|
|
|
|
popup.value.open();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 清除URL中的code参数
|
|
|
|
|
|
|
|
const url = new URL(window.location);
|
|
|
|
|
|
|
|
url.searchParams.delete("code");
|
|
|
|
|
|
|
|
url.searchParams.delete("state");
|
|
|
|
|
|
|
|
window.history.replaceState(
|
|
|
|
|
|
|
|
{},
|
|
|
|
|
|
|
|
document.title,
|
|
|
|
|
|
|
|
url.pathname + url.search
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
}, 1500);
|
|
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
|
|
uni.hideLoading();
|
|
|
|
|
|
|
|
console.error("微信H5登录失败:", error);
|
|
|
|
|
|
|
|
uni.showToast({
|
|
|
|
|
|
|
|
title: "微信登录失败,请重试",
|
|
|
|
|
|
|
|
icon: "none",
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// #endif
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 初始化微信JS-SDK(可选,用于更高级的功能)
|
|
|
|
|
|
|
|
const initWechatJSSDK = () => {
|
|
|
|
|
|
|
|
// #ifdef H5
|
|
|
|
|
|
|
|
// 如果需要使用微信JS-SDK的其他功能,可以在这里初始化
|
|
|
|
|
|
|
|
// 需要先引入微信JS-SDK:https://res.wx.qq.com/open/js/jweixin-1.6.0.js
|
|
|
|
|
|
|
|
// 示例配置(需要后端提供签名等信息)
|
|
|
|
|
|
|
|
// if (typeof wx !== 'undefined') {
|
|
|
|
|
|
|
|
// wx.config({
|
|
|
|
|
|
|
|
// debug: false,
|
|
|
|
|
|
|
|
// appId: 'YOUR_WECHAT_APP_ID',
|
|
|
|
|
|
|
|
// timestamp: timestamp,
|
|
|
|
|
|
|
|
// nonceStr: nonceStr,
|
|
|
|
|
|
|
|
// signature: signature,
|
|
|
|
|
|
|
|
// jsApiList: ['chooseImage', 'uploadImage', 'getLocation'] // 需要使用的JS接口列表
|
|
|
|
|
|
|
|
// });
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// wx.ready(() => {
|
|
|
|
|
|
|
|
// console.log('微信JS-SDK初始化成功');
|
|
|
|
|
|
|
|
// });
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// wx.error((res) => {
|
|
|
|
|
|
|
|
// console.error('微信JS-SDK初始化失败:', res);
|
|
|
|
|
|
|
|
// });
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// #endif
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 确认绑定手机号
|
|
|
|
|
|
|
|
const confirmBindPhone = async () => {
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
await bindPhoneForm.value.validate();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bindingPhone.value = true;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 调用绑定手机号API
|
|
|
|
|
|
|
|
// const result = await RPC.post('/api/wechat/bind-phone', {
|
|
|
|
|
|
|
|
// phone: bindPhoneInfo.value.phone,
|
|
|
|
|
|
|
|
// code: bindPhoneInfo.value.code,
|
|
|
|
|
|
|
|
// wechatCode: wechatLoginCode // 微信登录返回的code
|
|
|
|
|
|
|
|
// })
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 模拟绑定过程
|
|
|
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
|
|
|
bindingPhone.value = false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
uni.showToast({
|
|
|
|
|
|
|
|
title: "绑定成功",
|
|
|
|
|
|
|
|
icon: "success",
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 设置登录状态
|
|
|
|
|
|
|
|
authStore.setAccessToken("wechat_access_token");
|
|
|
|
|
|
|
|
// userStore.setUserInfo(result.userInfo)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
closeBindPhoneModal();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 跳转到首页
|
|
|
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
|
|
|
uni.$uv.route({
|
|
|
|
|
|
|
|
type: isTabBarPath(redirect) ? "switchTab" : "redirectTo",
|
|
|
|
|
|
|
|
url: redirect,
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}, 1000);
|
|
|
|
|
|
|
|
}, 2000);
|
|
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
|
|
console.error("绑定手机号失败:", error);
|
|
|
|
|
|
|
|
bindingPhone.value = false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 关闭绑定手机号弹窗
|
|
|
|
|
|
|
|
const closeBindPhoneModal = () => {
|
|
|
|
|
|
|
|
popup.value.close();
|
|
|
|
|
|
|
|
bindPhoneInfo.value = {
|
|
|
|
|
|
|
|
phone: "",
|
|
|
|
|
|
|
|
code: "",
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
bindCodeTips.value = "获取验证码";
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const login = async () => {
|
|
|
|
|
|
|
|
await form.value.validate();
|
|
|
|
|
|
|
|
console.log(userInfo.value);
|
|
|
|
|
|
|
|
// RPC.post('/account/login', {
|
|
|
|
|
|
|
|
// username: userInfo.value.name,
|
|
|
|
|
|
|
|
// password: userInfo.value.password,
|
|
|
|
|
|
|
|
// }, {
|
|
|
|
|
|
|
|
// custom: {
|
|
|
|
|
|
|
|
// loading: true,
|
|
|
|
|
|
|
|
// loadingText: '正在登录...'
|
|
|
|
|
|
|
|
// },
|
|
|
|
|
|
|
|
// }).then(res => {
|
|
|
|
|
|
|
|
// authStore.setAccessToken(res.token)
|
|
|
|
|
|
|
|
// userStore.setUserInfo(res)
|
|
|
|
|
|
|
|
// uni.$uv.route({
|
|
|
|
|
|
|
|
// type: isTabBarPath(redirect) ? "switchTab" : "redirectTo",
|
|
|
|
|
|
|
|
// url: redirect,
|
|
|
|
|
|
|
|
// });
|
|
|
|
|
|
|
|
// })
|
|
|
|
|
|
|
|
authStore.setAccessToken("accessToken");
|
|
|
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
|
|
|
uni.$uv.route({
|
|
|
|
|
|
|
|
type: isTabBarPath(redirect) ? "switchTab" : "redirectTo",
|
|
|
|
|
|
|
|
url: redirect,
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}, 800);
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
onMounted(() => {
|
|
|
|
|
|
|
|
checkEnvironment();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// #ifdef H5
|
|
|
|
|
|
|
|
// 检查是否是微信授权回调
|
|
|
|
|
|
|
|
const urlParams = new URLSearchParams(window.location.search);
|
|
|
|
|
|
|
|
const code = urlParams.get("code");
|
|
|
|
|
|
|
|
if (code && showWechatLogin.value) {
|
|
|
|
|
|
|
|
handleWechatH5Callback(code);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 可选:初始化微信JS-SDK
|
|
|
|
|
|
|
|
// initWechatJSSDK();
|
|
|
|
|
|
|
|
// #endif
|
|
|
|
|
|
|
|
});
|
|
|
|
</script>
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
|
<style lang="scss" scoped>
|
|
|
|
.container {
|
|
|
|
.container {
|
|
|
|
height: 100vh;
|
|
|
|
height: 100vh;
|
|
|
|
display: flex;
|
|
|
|
display: flex;
|
|
|
|
flex-direction: column;
|
|
|
|
flex-direction: column;
|
|
|
|
background: linear-gradient(124.92deg, rgba(77, 130, 253, 1) 7.66%, rgba(85, 184, 254, 1) 89.55%);
|
|
|
|
background: linear-gradient(
|
|
|
|
|
|
|
|
124.92deg,
|
|
|
|
.header {
|
|
|
|
rgba(77, 130, 253, 1) 7.66%,
|
|
|
|
height: 15vh;
|
|
|
|
rgba(85, 184, 254, 1) 89.55%
|
|
|
|
color: #fff;
|
|
|
|
);
|
|
|
|
display: flex;
|
|
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
.header {
|
|
|
|
padding-left: 7vw;
|
|
|
|
height: 15vh;
|
|
|
|
font-size: 16px;
|
|
|
|
color: #fff;
|
|
|
|
justify-content: center;
|
|
|
|
display: flex;
|
|
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
.line {
|
|
|
|
padding-left: 7vw;
|
|
|
|
margin: 6px 0;
|
|
|
|
font-size: 16px;
|
|
|
|
}
|
|
|
|
justify-content: center;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.line {
|
|
|
|
.main {
|
|
|
|
margin: 6px 0;
|
|
|
|
flex: 1;
|
|
|
|
}
|
|
|
|
background-color: #fff;
|
|
|
|
}
|
|
|
|
border-radius: 20px 20px 0 0;
|
|
|
|
|
|
|
|
padding: 7vw;
|
|
|
|
.main {
|
|
|
|
.formLabel {
|
|
|
|
flex: 1;
|
|
|
|
display: flex;
|
|
|
|
background-color: #fff;
|
|
|
|
align-items: center;
|
|
|
|
border-radius: 20px 20px 0 0;
|
|
|
|
margin-bottom: 4px;
|
|
|
|
padding: 7vw;
|
|
|
|
.img {
|
|
|
|
.formLabel {
|
|
|
|
width: 20px;
|
|
|
|
display: flex;
|
|
|
|
height: 20px;
|
|
|
|
align-items: center;
|
|
|
|
margin-right: 6px;
|
|
|
|
margin-bottom: 4px;
|
|
|
|
}
|
|
|
|
.img {
|
|
|
|
}
|
|
|
|
width: 20px;
|
|
|
|
.wechatBox {
|
|
|
|
height: 20px;
|
|
|
|
position: fixed;
|
|
|
|
margin-right: 6px;
|
|
|
|
width: 100%;
|
|
|
|
}
|
|
|
|
left: 0;
|
|
|
|
}
|
|
|
|
bottom: 15vh;
|
|
|
|
.wechatBox {
|
|
|
|
display: flex;
|
|
|
|
position: fixed;
|
|
|
|
flex-direction: column;
|
|
|
|
width: 100%;
|
|
|
|
align-items: center;
|
|
|
|
left: 0;
|
|
|
|
}
|
|
|
|
bottom: 15vh;
|
|
|
|
}
|
|
|
|
display: flex;
|
|
|
|
}
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.uv-icon {
|
|
|
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
|
|
|
transition: transform 0.2s;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
&:active {
|
|
|
|
|
|
|
|
transform: scale(0.95);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.bind-phone-modal {
|
|
|
|
|
|
|
|
width: 320px;
|
|
|
|
|
|
|
|
padding: 24px;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.modal-header {
|
|
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
|
|
margin-bottom: 24px;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.modal-title {
|
|
|
|
|
|
|
|
font-size: 18px;
|
|
|
|
|
|
|
|
font-weight: bold;
|
|
|
|
|
|
|
|
color: #333;
|
|
|
|
|
|
|
|
margin-bottom: 8px;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.modal-subtitle {
|
|
|
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
|
|
|
color: #666;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.modal-form {
|
|
|
|
|
|
|
|
margin-bottom: 24px;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.uv-form-item {
|
|
|
|
|
|
|
|
margin-bottom: 16px;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.modal-actions {
|
|
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
|
|
gap: 12px;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.uv-button {
|
|
|
|
|
|
|
|
flex: 1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
</style>
|
|
|
|
</style>
|
|
|
|
|
|
|
|
|
|
|
|
<style lang="scss">
|
|
|
|
<style lang="scss">
|
|
|
|
.wechatBox {
|
|
|
|
.wechatBox {
|
|
|
|
.uv-divider {
|
|
|
|
.uv-divider {
|
|
|
|
margin-bottom: 30px;
|
|
|
|
margin-bottom: 30px;
|
|
|
|
width: 90%;
|
|
|
|
width: 90%;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
</style>
|
|
|
|
</style>
|