555 lines
15 KiB
Vue
555 lines
15 KiB
Vue
<template>
|
||
<view class="loginBox" v-if="!loading">
|
||
<view class="logo">
|
||
<up-avatar :src="logo" size="100"></up-avatar>
|
||
</view>
|
||
<!-- <view class="error">
|
||
<view>login错误日志:{{login_error}}</view>
|
||
<view>接口错误日志:{{error}}</view>
|
||
<view>返回信息:{{authResult}}</view>
|
||
<view>用户信息:{{infoRes}}</view>
|
||
<view>小程序返回参数:{{args}}</view>
|
||
</view> -->
|
||
|
||
<view class="cont">
|
||
<view class="oneBox" v-if="first_method == 'wx'">
|
||
<view class="btn" @click="wxLogin">
|
||
<up-icon name="weixin-fill" color="#fff" size="26"></up-icon>
|
||
<text> 微信登录</text>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="twoBox" v-else-if="first_method == 'iphone'">
|
||
<view class="row">
|
||
<up-input v-model="mobile" placeholder="请输入手机号码" border="bottom" clearable>
|
||
<template #prefix><text class="iconfont icon-tel"></text></template>
|
||
</up-input>
|
||
</view>
|
||
<view class="row">
|
||
<up-input v-model="veri_code" placeholder="请输入短信验证码" border="bottom" clearable>
|
||
<template #prefix><text class="iconfont icon-code"></text></template>
|
||
<template #suffix>
|
||
<up-code ref="uCodeRef" @change="codeChange" seconds="60" changeText="X秒重新获取" :keep-running="true"></up-code>
|
||
<up-button @tap="getCode" :text="tips" type="error" size="mini"></up-button>
|
||
</template>
|
||
</up-input>
|
||
</view>
|
||
<view class="btn" @click="iphoneLogin">登录</view>
|
||
</view>
|
||
|
||
<view class="twoBox" v-else-if="first_method == 'mima'">
|
||
<view class="row">
|
||
<up-input v-model="mobile" placeholder="请输入手机号码" border="bottom" clearable>
|
||
<template #prefix><text class="iconfont icon-tel"></text></template>
|
||
</up-input>
|
||
</view>
|
||
<view class="row">
|
||
<up-input v-model="password" placeholder="请输入登录密码" border="bottom" clearable type="password">
|
||
<template #prefix><text class="iconfont icon-pwd"></text></template>
|
||
</up-input>
|
||
</view>
|
||
<view class="btn" @click="pwdLogin">登录</view>
|
||
</view>
|
||
|
||
|
||
<view class="text">
|
||
<up-checkbox @change="changeCheck"
|
||
label="登录即代表同意" name="agree" shape="circle" :activeColor="Color" :checked="Checked" :iconSize="10" :usedAlone="true" :size="14" :labelSize="12" labelColor="#444" />
|
||
|
||
<text @click="toPage(1, '用户协议')">《用户协议》</text>和<text @click="toPage(2, '隐私政策')">《隐私政策》</text>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="btmBox" v-if="showOther">
|
||
<view class="title">其他登录方式</view>
|
||
<view class="link">
|
||
<view class="icon" @click="first_method = 'iphone'" v-if="first_method != 'iphone'">
|
||
<text class="iconfont icon-iphone"></text>
|
||
<text>短信验证码登录</text>
|
||
</view>
|
||
<view class="icon" @click="first_method = 'mima'" v-if="first_method != 'mima'">
|
||
<text class="iconfont icon-mima"></text>
|
||
<text>账号密码登录</text>
|
||
</view>
|
||
|
||
<view class="icon" @click="first_method = 'wx'" v-if="first_method != 'wx' && existWx">
|
||
<text class="iconfont icon-weixin"></text>
|
||
<text>微信登录</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
</template>
|
||
|
||
<script>
|
||
import { ref, reactive, toRefs } from 'vue'
|
||
import { get, post } from '@/api/request.js'
|
||
import { showToast, getShopInfo } from '@/components/common.js'
|
||
import API from '@/api/index'
|
||
|
||
export default {
|
||
setup() {
|
||
const data = reactive({
|
||
logo: uni.getStorageSync('logo'),
|
||
Checked: false,
|
||
Color: uni.getStorageSync('theme_color'),
|
||
shopId: uni.getStorageSync('shop_id'),
|
||
error: '',
|
||
login_error: '',
|
||
authResult: '',
|
||
infoRes: '',
|
||
args: '',
|
||
showOther: false,
|
||
first_method: 'wx',
|
||
mobile: '',
|
||
veri_code: '',
|
||
tips: '',
|
||
loading: false,
|
||
password: '',
|
||
existWx: true
|
||
})
|
||
|
||
// 小程序登陆
|
||
const miniLogin = () => {
|
||
if(data.Checked) {
|
||
// 跳转小程序登陆
|
||
var shares = null
|
||
plus.share.getServices(function(s){
|
||
shares = {}
|
||
for(var i in s){
|
||
var t = s[i]
|
||
shares[t.id] = t
|
||
}
|
||
shares['weixin'].launchMiniProgram({
|
||
id: 'gh_a2bdca31e535',
|
||
type: 0, // 0 正式版, 1 测试版, 2 体验版
|
||
path: 'pages/index/interim?from=app'
|
||
})
|
||
}, function(e) {
|
||
console.log("获取分享服务列表失败:" + e.message)
|
||
})
|
||
} else {
|
||
showToast('请勾选《用户协议》和《隐私政策》')
|
||
}
|
||
}
|
||
|
||
// 微信登陆
|
||
const wxLogin = () => {
|
||
if(data.Checked) {
|
||
// 直接登录
|
||
uni.showLoading({
|
||
title: '正在登录...',
|
||
mask: true
|
||
})
|
||
uni.login({
|
||
provider: 'weixin',
|
||
onlyAuthorize: true,
|
||
success: (res) => {
|
||
const { code } = res
|
||
console.log(111, res)
|
||
data.authResult = JSON.stringify(res)
|
||
uni.request({
|
||
method: 'POST',
|
||
url: API.url + '/api/v1/auth/login',
|
||
data: { code, from: 'uni-app' },
|
||
header: {
|
||
Authorization: uni.getStorageSync('token') || '',
|
||
accept: "application/json",
|
||
appid: API.appId
|
||
},
|
||
success: (val) => {
|
||
console.log(val)
|
||
if(!Array.isArray(val.data)) {
|
||
data.infoRes = JSON.stringify(val.data)
|
||
if(val.data.access_token) {
|
||
let token = val.data.token_type + ' ' + val.data.access_token
|
||
uni.setStorageSync('token', token)
|
||
uni.setStorageSync('subscribe', val.data.is_subscribe)
|
||
uni.setStorageSync('avatar', val.data.avatar)
|
||
uni.setStorageSync('nickname', val.data.nickname)
|
||
uni.setStorageSync('role', 0)
|
||
uni.setStorageSync('login_type', 'mini-app')
|
||
uni.setStorageSync('is_vip', val.data.is_vip)
|
||
uni.setStorageSync('is_new', val.data.is_new)
|
||
uni.setStorageSync('is_authorized', val.data.is_authorized)
|
||
uni.setStorageSync('is_default_avatar', val.data.is_default_avatar)
|
||
uni.setStorageSync('sessionKey', val.data.session_key)
|
||
uni.setStorageSync('saveTime', Date.now()) // 存储时间
|
||
uni.setStorageSync('expires_in', val.data.expires_in * 1000) // 失效时间
|
||
getShopInfo().then((ress) => {
|
||
uni.reLaunch({
|
||
url: '/pages/index/index'
|
||
})
|
||
uni.hideLoading()
|
||
})
|
||
}
|
||
}
|
||
},
|
||
fail: (err) => {
|
||
console.log('uni.request fail', err)
|
||
data.error = JSON.stringify(err)
|
||
uni.hideLoading()
|
||
}
|
||
})
|
||
},
|
||
fail: (err) => {
|
||
console.log('uni.login fail', err)
|
||
data.login_error = JSON.stringify(err)
|
||
uni.hideLoading()
|
||
}
|
||
})
|
||
} else {
|
||
showToast('请勾选《用户协议》和《隐私政策》')
|
||
}
|
||
}
|
||
|
||
const toPage = (id, text) => {
|
||
uni.navigateTo({ url: '/pages/mine/aboutUs/article?type=' + id + '&text=' + text })
|
||
}
|
||
|
||
const changeCheck = (e) => {
|
||
data.Checked = e
|
||
}
|
||
|
||
function loginByUnionId(params) {
|
||
uni.login({
|
||
provider: 'weixin',
|
||
onlyAuthorize: true,
|
||
success: (res) => {
|
||
const { code } = res
|
||
unionidLogin(code, params.shop_id, params.unionid)
|
||
},
|
||
fail: (err) => {
|
||
console.log('uni.login fail', err)
|
||
data.login_error = JSON.stringify(err)
|
||
}
|
||
})
|
||
}
|
||
|
||
function unionidLogin(code, shop_id, unionid_open) {
|
||
uni.request({
|
||
method: 'POST',
|
||
url: API.url + '/api/v1/auth/login',
|
||
data: {
|
||
code: code,
|
||
from: 'mini-app',
|
||
shop_id: shop_id,
|
||
unionid_open: unionid_open
|
||
},
|
||
header: {
|
||
Authorization: uni.getStorageSync('token') || '',
|
||
accept: "application/json",
|
||
appid: API.appId
|
||
},
|
||
success: (val) => {
|
||
console.log('uni.request success', val)
|
||
if(val.data && val.data.access_token) {
|
||
let token = val.data.token_type + ' ' + val.data.access_token
|
||
uni.setStorageSync('token', token)
|
||
uni.setStorageSync('subscribe', val.data.is_subscribe)
|
||
uni.setStorageSync('avatar', val.data.avatar)
|
||
uni.setStorageSync('nickname', val.data.nickname)
|
||
uni.setStorageSync('role', 0)
|
||
uni.setStorageSync('login_type', 'mini-app')
|
||
uni.setStorageSync('is_vip', val.data.is_vip)
|
||
uni.setStorageSync('is_new', val.data.is_new)
|
||
uni.setStorageSync('is_authorized', val.data.is_authorized)
|
||
uni.setStorageSync('is_default_avatar', val.data.is_default_avatar)
|
||
uni.setStorageSync('sessionKey', val.data.session_key)
|
||
uni.setStorageSync('saveTime', Date.now()) // 存储时间
|
||
uni.setStorageSync('expires_in', val.data.expires_in * 1000) // 失效时间
|
||
getShopInfo().then((ress) => {
|
||
uni.reLaunch({
|
||
url: '/pages/index/index'
|
||
})
|
||
})
|
||
}
|
||
},
|
||
fail: (err) => {
|
||
data.error = JSON.stringify(err)
|
||
console.log('uni.request fail', err)
|
||
}
|
||
})
|
||
}
|
||
|
||
const uCodeRef = ref(null)
|
||
|
||
function iphoneLogin() {
|
||
if(!data.mobile) {
|
||
return showToast('请输入手机号码')
|
||
} else if(!data.veri_code) {
|
||
return showToast('请输入短信验证码')
|
||
}
|
||
if(data.Checked) {
|
||
uni.showLoading({
|
||
title: '正在登录...',
|
||
mask: true
|
||
})
|
||
let params = {
|
||
mobile: data.mobile,
|
||
uuid: uni.getStorageSync('uuid'),
|
||
code: data.veri_code
|
||
}
|
||
post('/api/app/login/mobile/code/validate', params).then(async(res) => {
|
||
if(res.data.from == 'mini-app') { // 已经注册过小程序
|
||
await unionidLogin('abcdefg', res.data.shop_id, res.data.unionid_open)
|
||
uni.hideLoading()
|
||
} else {
|
||
uni.setStorageSync('avatar', res.data.avatar)
|
||
uni.setStorageSync('nickname', res.data.nickname)
|
||
uni.setStorageSync('shop_id', res.data.shop_id)
|
||
uni.setStorageSync('login_type', res.data.from)
|
||
uni.setStorageSync('unionid_open', res.data.unionid_open)
|
||
uni.hideLoading()
|
||
uni.reLaunch({
|
||
url: '/pages/index/index'
|
||
})
|
||
}
|
||
})
|
||
} else {
|
||
showToast('请勾选《用户协议》和《隐私政策》')
|
||
}
|
||
}
|
||
|
||
function pwdLogin() {
|
||
if(!data.mobile) {
|
||
return showToast('请输入手机号码')
|
||
} else if(!data.password) {
|
||
return showToast('请输入登录密码')
|
||
}
|
||
if(data.Checked) {
|
||
uni.showLoading({
|
||
title: '正在登录...',
|
||
mask: true
|
||
})
|
||
let params = {
|
||
mobile: data.mobile,
|
||
password: data.password
|
||
}
|
||
post('/api/app/login/mobile/loginByPwd', params).then(async(res) => {
|
||
if(res.data.login_code == 0) { // 已经注册过小程序
|
||
await unionidLogin('abcdefg', data.shopId, res.data.unionid_open)
|
||
uni.hideLoading()
|
||
} else {
|
||
showToast('账号不存在')
|
||
}
|
||
}).catch((err) => {
|
||
console.log(err)
|
||
uni.hideLoading()
|
||
showToast('账号密码错误')
|
||
})
|
||
} else {
|
||
showToast('请勾选《用户协议》和《隐私政策》')
|
||
}
|
||
}
|
||
|
||
const getCode = () => {
|
||
var reg_tel = /(^1[3-9]\d{9}$)|(^((0\d{2,3})-)(\d{7,8})(-(\d{3,}))?$)|(^(400)-(\d{3})-(\d{4})(.)(\d{1,4})$)|(^(400)-(\d{3})-(\d{4}$))/
|
||
if (!data.mobile || !reg_tel.test(data.mobile)) {
|
||
showToast('请输入正确的手机号码')
|
||
return
|
||
}
|
||
if (uCodeRef.value.canGetCode) {
|
||
uni.showLoading({
|
||
title: '正在获取验证码',
|
||
mask: true
|
||
})
|
||
post('/api/app/login/mobile/code', {mobile: data.mobile}).then((res) => {
|
||
uni.hideLoading()
|
||
uni.setStorageSync('uuid', res.data.uuid)
|
||
showToast('验证码已发送')
|
||
uCodeRef.value.start()
|
||
}).catch(() => {
|
||
uni.hideLoading()
|
||
if(res.message) {
|
||
showToast(res.message)
|
||
}
|
||
})
|
||
}
|
||
}
|
||
|
||
const codeChange = (text) => {
|
||
data.tips = text
|
||
}
|
||
|
||
function checkApp(){
|
||
if(plus.runtime.isApplicationExist({pname:'com.tencent.mm', action:'weixin://'})) {
|
||
console.log("安装了微信")
|
||
data.existWx = true
|
||
} else {
|
||
console.log("微信应用未安装")
|
||
data.first_method = 'iphone'
|
||
data.existWx = false
|
||
}
|
||
}
|
||
|
||
return {
|
||
uCodeRef,
|
||
...toRefs(data),
|
||
wxLogin,
|
||
toPage,
|
||
changeCheck,
|
||
loginByUnionId,
|
||
miniLogin,
|
||
iphoneLogin,
|
||
getCode,
|
||
codeChange,
|
||
unionidLogin,
|
||
pwdLogin,
|
||
checkApp
|
||
}
|
||
},
|
||
async onLoad(options) {
|
||
// await this.$onLaunched
|
||
if (plus.os.name === 'iOS') {
|
||
this.showOther = true
|
||
this.checkApp()
|
||
}
|
||
|
||
let login_type = uni.getStorageSync('login_type')
|
||
if(login_type == 'mobile') { // 已经手机号登陆,未授权微信
|
||
uni.redirectTo({
|
||
url: '/pages/user/authorize'
|
||
})
|
||
} else {
|
||
this.loading = false
|
||
}
|
||
},
|
||
onShow() {
|
||
let args = plus.runtime.arguments
|
||
if (args) {
|
||
console.log(args)
|
||
this.args = args
|
||
this.loginByUnionId(JSON.parse(args))
|
||
plus.runtime.arguments = null
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.loginBox{
|
||
width: 100%;
|
||
height: 100vh;
|
||
overflow: hidden;
|
||
box-sizing: border-box;
|
||
padding-top: 100rpx;
|
||
position: relative;
|
||
.logo{
|
||
display: flex;
|
||
justify-content: center;
|
||
}
|
||
.cont{
|
||
.text{
|
||
font-size: 24rpx;
|
||
text-align: center;
|
||
color: #444;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
text{
|
||
color: #155BD4;
|
||
}
|
||
}
|
||
}
|
||
.oneBox{
|
||
padding-top: 45%;
|
||
.btn{
|
||
width: 90%;
|
||
height: 100rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
background-color: #68CC46;
|
||
color: #fff;
|
||
border-radius: 100rpx;
|
||
margin: 24rpx auto;
|
||
|
||
}
|
||
}
|
||
.twoBox{
|
||
padding: 30% 20px 0;
|
||
.row{
|
||
margin-bottom: 15px;
|
||
.iconfont{
|
||
color: #666;
|
||
}
|
||
}
|
||
.btn{
|
||
width: 90%;
|
||
height: 80rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
background-color: v-bind('Color');
|
||
color: #fff;
|
||
border-radius: 80rpx;
|
||
margin: 24rpx auto;
|
||
|
||
}
|
||
}
|
||
.btmBox{
|
||
position: absolute;
|
||
bottom: 80rpx;
|
||
width: 100%;
|
||
left: 0;
|
||
.title{
|
||
font-size: 24rpx;
|
||
color: #999;
|
||
text-align: center;
|
||
}
|
||
.link{
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
font-size: 32rpx;
|
||
color: #666;
|
||
margin-top: 20rpx;
|
||
.icon{
|
||
display: flex;
|
||
align-items: center;
|
||
font-size: 26rpx;
|
||
padding: 0 14rpx;
|
||
height: 30rpx;
|
||
&:first-child{
|
||
border-right: 1px solid #aaa;
|
||
}
|
||
.iconfont{
|
||
font-size: 36rpx;
|
||
&.icon-iphone{
|
||
color: #1890FF;
|
||
}
|
||
&.icon-mima{
|
||
color: #FFB300;
|
||
}
|
||
&.icon-weixin{
|
||
color: #28C445;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
.box{
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
margin-top: 30rpx;
|
||
.icon{
|
||
width: 32px;
|
||
height: 32px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
text{
|
||
color: #28C445;
|
||
font-size: 32px;
|
||
&.icon-iphone{
|
||
color: #1890FF;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
</style>
|