Commit 2e6eae94 authored by 俞嘉婷's avatar 俞嘉婷

feat: 手机号授权

parent d8adb7b6
{
"pages": [
"pages/index/index",
"pages/phoneLogin/phoneLogin",
"pages/privacy/privacy",
"pages/webview/webview"
],
"window": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "Weixin",
"navigationBarTitleText": "廣结好友游园会",
"navigationBarBackgroundColor": "#ffffff"
},
"style": "v2",
......
import requestFun from "./requestFun";
// TODO 'test', 'pre', 'prod'
export const __env__ = "test";
const DEFAULT_PROJECT = {
// 测试环境
'test': {
redirectUrl: 'https://activity.m.duibatest.com.cn/projectx/p94791461/index.html?appID=19487',
rqDomain: "https://activity.m.duibatest.com.cn"
},
// 线上测试
'pre': {
redirectUrl: 'https://99183-activity.dexfu.cn/projectx/pe08eb0d1/index.html?appID=99183',
rqDomain: "https://99183-activity.dexfu.cn"
},
// 线上正式
'prod': {
redirectUrl: 'https://99183-activity.dexfu.cn/projectx/TODO/index.html?appID=99183',
rqDomain: "https://99183-activity.dexfu.cn"
},
}
/** 小程序接口 */
export const dbDomain = DEFAULT_PROJECT[__env__].rqDomain
/** 默认活动h5地址 */
export const default_rUrl = DEFAULT_PROJECT[__env__].redirectUrl
// 小程序授权登陆
export const reqDbLogin = (param) => {
return requestFun({
url: dbDomain + "/wechat/wine/autoLogin",
method: "POST",
// header: {
// "Content-Type": 'application/json'
// },
...param,
})
};
const requestFun = async (dataSouce) => {
wx.showLoading({
mask: true
})
console.log("请求数据 dataSouce", dataSouce)
return await new Promise((resolve, reject) => {
wx.request({
...dataSouce,
success: (res) => {
wx.hideLoading()
console.info("%c res:成功数据", "font-size: 20px; color: #e9a4fc", res);
resolve(res.data);
},
fail: (res) => {
wx.hideLoading()
console.error("res:失败数据", res)
reject(res.data);
}
});
})
}
export default requestFun;
const app = getApp();
import { default_rUrl, reqDbLogin } from "../../db_api/index";
import { createUrl, wxLogin } from "../../utils/util";
Page({
data: {
},
isBindPhone: false,
options: {},
async onLoad(options) {
console.log('页面参数', options)
this.options = options;
// this.goAct();
// options 参数:
// redirect,
// isNeedLogin,
this.options = {
...options,
redirect: encodeURIComponent(options.redirect ? decodeURIComponent(options.redirect) : default_rUrl)
};
this.isLogin();
},
onShow() {
},
async isLogin() {
const res = await wxLogin();
if (res.code) {
const loginRes = await reqDbLogin({
data: {
code: res.code,
redirect: decodeURIComponent(this.options.redirect)
}
})
if (loginRes.success && loginRes.data?.isBindPhone) {
this.isBindPhone = true;
this.goAct();
} else {
this.isBindPhone = false;
}
}
},
goAct() {
// wx.showToast({
// title: "活动暂未开始,敬请期待~",
// icon: 'none',
// duration: 1000
// });
const { env, redirect, isNeedLogin } = this.options
let url = `/pages/webview/webview?isNeedLogin=${isNeedLogin || 1}`;;
if (env) url += `&env=${env}`;
if (redirect) url += `&redirect=${redirect}`;
console.log('跳转链接', url);
wx.redirectTo({ url });
if (!this.isBindPhone) {
wx.navigateTo({
url: createUrl('/pages/phoneLogin/phoneLogin', this.options)
})
return;
}
wx.redirectTo({
url: createUrl('/pages/webview/webview', this.options)
});
},
})
\ No newline at end of file
<view class="container">
<image class="bg" src="https://yun.duiba.com.cn/polaris/bg.6699da2a8d66c0ba1087dc2d2b02c413d984d29a.jpg" bindtap="goAct" />
<image class="btn" src="https://yun.duiba.com.cn/polaris/btn.45304462debe02bf26d2a1292ab39957f66de914.png" bindtap="goAct" />
<view class="container" bindtap="goAct">
<view class="bg" />
<view class="btn" />
</view>
\ No newline at end of file
......@@ -14,6 +14,7 @@
position: absolute;
top: 0rpx;
left: 0rpx;
background: url('https://yun.duiba.com.cn/polaris/bg.6699da2a8d66c0ba1087dc2d2b02c413d984d29a.jpg') no-repeat center top / 100% 100%;
}
.btn {
......@@ -22,4 +23,5 @@
position: absolute;
left: 125rpx;
top: 1200rpx;
background: url('https://yun.duiba.com.cn/polaris/btn.45304462debe02bf26d2a1292ab39957f66de914.png') no-repeat center top / 100% 100%;
}
import { reqDbLogin } from "../../db_api/index";
import { createUrl, wxLogin } from "../../utils/util";
//获取应用实例
const app = getApp()
Page({
data: {
hasPhoneInfo: false,
isAgree: false,
},
options: {},
onLoad: async function (options) {
this.options = options;
},
// 从基础库 2.21.2 开始,对获取手机号的接口进行了安全升级,以下是新版本接口使用指南。
// (旧版本接口目前可以继续使用,但建议开发者使用新版本接口,以增强小程序安全性)
async getPhoneNumber(e) {
console.log('e.detail', e.detail)
wx.showLoading({
title: "加载中...",
mask: true
})
const {
errMsg,
code,
encryptedData,
iv
} = e.detail
if (errMsg == 'getPhoneNumber:ok') { //这里表示获取授权成功
this.setData({
hasPhoneInfo: true,
})
const res = await wxLogin();
if (res.code) {
const loginRes = await reqDbLogin({
data: {
code: res.code,
redirect: decodeURIComponent(this.options.redirect),
phoneEncryptedData: encryptedData,
phoneIv: iv
}
})
if (loginRes.success && loginRes.data?.isBindPhone) {
wx.redirectTo({
url: createUrl('/pages/webview/webview', this.options)
});
}
}
} else {
wx.showToast({
title: '授权手机号失败',
icon: 'none',
duration: 2000
})
}
},
checkboxChange() {
this.setData({
isAgree: !this.data.isAgree,
})
},
judgeAgree() {
wx.showToast({
title: "请先阅读并同意协议",
icon: "none",
});
},
showPrivacy() {
wx.navigateTo({
url: '/pages/privacy/privacy',
})
},
})
\ No newline at end of file
{
"usingComponents": {}
}
\ No newline at end of file
<view>
<view class="phoneLogin">
<view class="login_bg">
<view class="content_bg">
<view class="mainbtn" wx:if="{{isAgree}}">
<button open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber"></button>
</view>
<view class="mainbtn" wx:else bindtap="judgeAgree"></view>
<view class="check_icon {{isAgree ? 'checked' : ''}}" bindtap="checkboxChange"></view>
<view class="check_text_box" bindtap="showPrivacy">
<!-- 我已阅读并同意
<text class="check_text">《隐私协议》《用户协议》</text>
等内容 -->
</view>
</view>
</view>
</view>
</view>
\ No newline at end of file
.phoneLogin {
height: 100%;
}
.phoneLogin image {
width: 100%;
height: 1528rpx;
display: block;
}
.login_bg {
width: 750rpx;
height: 1624rpx;
left: 0rpx;
top: 50%;
transform: translateY(-50%);
position: absolute;
background: url('https://yun.duiba.com.cn/polaris/bg.41e7cf5df923d95daf2d3e26db3998af4f67c7b7.jpg') no-repeat center top / 100% 100%;
}
.content_bg {
left: 7rpx;
top: 566rpx;
width: 733rpx;
height: 634rpx;
position: absolute;
background: url('https://yun.duiba.com.cn/polaris/content_bg.d7f3a8c251c2b52dc74873cfcabba003399e7b25.png') no-repeat center top / 100% 100%;
}
.mainbtn {
left: 154rpx;
top: 175rpx;
width: 427rpx;
height: 112rpx;
position: absolute;
background: url('https://yun.duiba.com.cn/polaris/btn.e89623c785d031dce72af0d1e183459613344149.png') no-repeat center top / 100% 100%;
}
.mainbtn button {
background: transparent;
width: 100%;
height: 100%;
padding: 0;
}
.check_icon {
position: absolute;
top: 390rpx;
left: 108rpx;
width: 36rpx;
height: 36rpx;
background: url('https://yun.duiba.com.cn/polaris/check_icon.90eece0a84a3b1cf47a86784558f79acd49c44d4.png') no-repeat center top / 100% 100%;
}
.check_icon.checked {
background-image: url('https://yun.duiba.com.cn/polaris/checked_icon.eb0154790d8f2d630e74446ab19caf5cdbfc28fb.png');
}
.check_text_box {
position: absolute;
top: 393rpx;
left: 163rpx;
/* color: rgb(0, 0, 0);
font-size: 24rpx;
width: 476rpx;
line-height: 36rpx; */
width: 458rpx;
height: 54rpx;
background: url('https://yun.duiba.com.cn/polaris/privacy_text.bd710d55a1ab3548b84a12751c672e5dda19bee6.png') no-repeat center top / 100% 100%;
}
.check_text_box .check_text {
text-decoration-line: underline;
color: #c75233;
}
\ No newline at end of file
const app = getApp();
Page({
data: {
},
options: {},
async onLoad(options) {
},
onShow() {
},
})
\ No newline at end of file
{
"navigationBarTitleText": "",
"usingComponents": {
}
}
\ No newline at end of file
<view class="privacy_container">
<view class="agreement">
TODO
</view>
</view>
\ No newline at end of file
.privacy_container {
width: 100%;
height: 100%;
background-color: #fff;
padding: 20rpx;
overflow-y: auto;
}
.privacy_container .agreement {
width: 100%;
height: auto;
color: #000;
}
// webview.js
// 获取应用实例
const DEFAULT_PROJECT = {
'test': {
redirectUrl: 'https://activity.m.duibatest.com.cn/projectx/p94791461/index.html?appID=19487',
loginDomain: "https://activity.m.duibatest.com.cn"
},
'pre': {
redirectUrl: 'https://99183-activity.dexfu.cn/projectx/pe08eb0d1/index.html?appID=99183',
loginDomain: "https://99183-activity.dexfu.cn"
},
'prod': {
redirectUrl: 'https://99183-activity.dexfu.cn/projectx/TODO/index.html?appID=99183',
loginDomain: "https://99183-activity.dexfu.cn"
},
}
import { default_rUrl, reqDbLogin } from "../../db_api/index";
import { wxLogin } from "../../utils/util";
// 获取应用实例
Page({
data: {
// 分享信息
......@@ -24,7 +12,6 @@ Page({
link: ''
},
},
env: 'pre', // TODO 'test', 'pre', 'prod'
redirectUrl: '',
options: {},
onLoad(options) {
......@@ -34,54 +21,32 @@ Page({
console.log("options:", options)
this.options = options;
let {
env,
redirect,
isNeedLogin = '1',
} = this.options || {}
if (env) this.env = env;
console.log('DEFAULT_PROJECT[env]', this.env, DEFAULT_PROJECT[this.env])
let redirectUrl = redirect ? decodeURIComponent(redirect) : DEFAULT_PROJECT[this.env]?.redirectUrl;
let redirectUrl = redirect ? decodeURIComponent(redirect) : default_rUrl;
this.redirectUrl = redirectUrl
if (isNeedLogin == '1') {
wx.login({
success: async (res) => {
console.log(111, res)
if (res.code) {
const loginUrl = `${DEFAULT_PROJECT[this.env]?.loginDomain}/wechat/wine/autoLogin`
console.log('免登接口:', loginUrl)
wx.request({
url: loginUrl,
data: {
code: res.code,
redirect: redirectUrl
},
method: 'POST',
success: res => {
console.log('login', res)
if (res.statusCode == 200) {
this.setData({
path: res.data?.data?.redirectUrl,
})
} else {
wx.showToast({
title: '登录失败',
icon: 'none',
duration: 4000
})
}
},
fail: err => {
// console.log(err);
},
complete: res => {
// console.log(res);
}
});
const res = await wxLogin();
if (res.code) {
const loginRes = await reqDbLogin({
data: {
code: res.code,
redirect: redirectUrl
}
})
if (loginRes.success) {
this.setData({ path: loginRes?.data?.redirectUrl })
} else {
wx.showToast({
title: '登录失败',
icon: 'none',
duration: 4000
})
}
})
}
} else if (redirectUrl) {
this.setData({
path: redirectUrl,
......@@ -104,7 +69,7 @@ Page({
onShareAppMessage: function (options) { //分享
const { h5ShareInfo } = this.data;
console.log("onShareAppMessage--------", JSON.stringify(options))
const shareUrl = `pages/dbindex/dbindex?env=${this.env}&isNeedLogin=1&redirect=${encodeURIComponent(
const shareUrl = `pages/index/index?isNeedLogin=1&redirect=${encodeURIComponent(
h5ShareInfo.link || this.redirectUrl
)}`;
......
......@@ -14,6 +14,56 @@ const formatNumber = n => {
return n[1] ? n : `0${n}`
}
const wxLogin = () => {
return new Promise((resolve, reject) => {
wx.login({
success: res => {
console.log('wxLogin success: ', res)
resolve(res);
},
fail: err => {
reject(err);
}
})
});
}
export let createUrl = (baseUrl, params) => {
let paramsStr = ''
// 是否需要编码前缀
let prefix = 'EN_';
for (let key in params) {
// 值为null或者undefined不传改参数
if (params[key] !== null && params[key] !== undefined && params[key] !== '') {
paramsStr += paramsStr ? '&' : '';
let value = params[key];
// 处理需要编码的key-value
if (key.indexOf(prefix) > -1) {
key = key.replace(prefix, '');
value = encodeURIComponent(value);
}
paramsStr += `${key}=${value}`;
}
}
if (!baseUrl) { return paramsStr };
if (!paramsStr) { return baseUrl };
let subStr = '';
// 没有问号
if (baseUrl.lastIndexOf('?') === -1) {
subStr = '?';
} else {
// 最后一个字符
const lastChar = baseUrl.slice(-1);
// 如果最后接在最后一个字符不是? 则加上一个&
if (lastChar !== '&' && lastChar !== '?') {
subStr = '&';
}
}
return baseUrl + subStr + paramsStr;
}
module.exports = {
wxLogin,
createUrl,
formatTime
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment