shop_app/pages/user/login.vue

555 lines
15 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="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>&nbsp;微信登录</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>&nbsp;
<text>短信验证码登录</text>
</view>
<view class="icon" @click="first_method = 'mima'" v-if="first_method != 'mima'">
<text class="iconfont icon-mima"></text>&nbsp;
<text>账号密码登录</text>
</view>
<view class="icon" @click="first_method = 'wx'" v-if="first_method != 'wx' && existWx">
<text class="iconfont icon-weixin"></text>&nbsp;
<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>