更新小程序隐私保护机制,新增手机号一键登录功能,用户需同意隐私协议后方可获取手机号。优化多个页面的登录交互,提升用户体验。调整相关配置以支持新功能。
This commit is contained in:
@@ -95,7 +95,10 @@ App({
|
||||
this._privacyResolve = resolve
|
||||
const pages = getCurrentPages()
|
||||
const cur = pages[pages.length - 1]
|
||||
if (cur && typeof cur.setData === 'function' && cur.route && (cur.route.includes('avatar-nickname') || cur.route.includes('profile-edit'))) {
|
||||
const route = (cur && cur.route) || ''
|
||||
const needPrivacyPages = ['avatar-nickname', 'profile-edit', 'read', 'my', 'gift-pay/detail', 'index', 'settings']
|
||||
const needShow = needPrivacyPages.some(p => route.includes(p))
|
||||
if (cur && typeof cur.setData === 'function' && needShow) {
|
||||
cur.setData({ showPrivacyModal: true })
|
||||
} else {
|
||||
resolve({ event: 'disagree' })
|
||||
@@ -413,12 +416,57 @@ App({
|
||||
this.globalData.hasFullBook = userInfo.hasFullBook || false
|
||||
this.globalData.isVip = userInfo.isVip || false
|
||||
this.globalData.vipExpireDate = userInfo.vipExpireDate || ''
|
||||
// 若手机号为空,后台静默刷新用户资料以同步最新手机号(可能在其他设备/页面已绑定)
|
||||
if (!(userInfo.phone || '').trim()) {
|
||||
this._refreshUserInfoIfPhoneEmpty()
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('检查登录状态失败:', e)
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 手机号登录后:若响应中 user.phone 为空,从 profile 拉取最新资料并更新本地(后端已写入 DB)
|
||||
*/
|
||||
async _syncPhoneFromProfileAfterLogin(userId) {
|
||||
try {
|
||||
if (!userId) return
|
||||
const res = await this.request({ url: `/api/miniprogram/user/profile?userId=${userId}`, silent: true })
|
||||
const profile = res?.data
|
||||
if (!profile) return
|
||||
const phone = (profile.phone || '').trim()
|
||||
if (!phone) return
|
||||
const updated = { ...this.globalData.userInfo, phone }
|
||||
if (profile.wechatId != null) updated.wechatId = profile.wechatId
|
||||
this.globalData.userInfo = updated
|
||||
wx.setStorageSync('userInfo', updated)
|
||||
wx.setStorageSync('user_phone', phone)
|
||||
} catch (_) {}
|
||||
},
|
||||
|
||||
/**
|
||||
* 当本地 userInfo.phone 为空时,静默拉取 profile 并更新(用户可能在设置页或其他入口已绑定手机号)
|
||||
*/
|
||||
async _refreshUserInfoIfPhoneEmpty() {
|
||||
try {
|
||||
const userId = this.globalData.userInfo?.id
|
||||
if (!userId) return
|
||||
const res = await this.request({ url: `/api/miniprogram/user/profile?userId=${userId}`, silent: true })
|
||||
const profile = res?.data
|
||||
if (!profile) return
|
||||
const phone = (profile.phone || '').trim()
|
||||
if (!phone) return
|
||||
const updated = { ...this.globalData.userInfo, phone }
|
||||
if (profile.wechatId != null) updated.wechatId = profile.wechatId
|
||||
this.globalData.userInfo = updated
|
||||
wx.setStorageSync('userInfo', updated)
|
||||
if (phone) wx.setStorageSync('user_phone', phone)
|
||||
} catch (_) {
|
||||
// 静默失败,不影响主流程
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* WSS 在线心跳(占位):登录后连接 ws,发送 auth + 心跳,供管理端统计在线人数
|
||||
* 容错:任意异常均不向外抛出,不影响登录、API 请求等核心功能
|
||||
@@ -1026,6 +1074,13 @@ App({
|
||||
|
||||
wx.setStorageSync('userInfo', user)
|
||||
wx.setStorageSync('token', res.data.token)
|
||||
// 手机号登录后:若用户资料中手机号为空,从 profile 刷新并更新(后端已写入 DB,可能响应中未带回)
|
||||
const phone = (user.phone || '').trim()
|
||||
if (!phone) {
|
||||
this._syncPhoneFromProfileAfterLogin(user.id)
|
||||
} else {
|
||||
wx.setStorageSync('user_phone', phone)
|
||||
}
|
||||
|
||||
// 登录成功后绑定推荐码
|
||||
const pendingRef = wx.getStorageSync('pendingReferralCode') || this.globalData.pendingReferralCode
|
||||
|
||||
@@ -28,7 +28,8 @@
|
||||
"pages/avatar-nickname/avatar-nickname",
|
||||
"pages/gift-pay/detail",
|
||||
"pages/gift-pay/list",
|
||||
"pages/gift-pay/redemption-detail"
|
||||
"pages/gift-pay/redemption-detail",
|
||||
"pages/dev-login/dev-login"
|
||||
],
|
||||
"window": {
|
||||
"backgroundTextStyle": "light",
|
||||
|
||||
80
miniprogram/pages/dev-login/dev-login.js
Normal file
80
miniprogram/pages/dev-login/dev-login.js
Normal file
@@ -0,0 +1,80 @@
|
||||
/**
|
||||
* 卡若创业派对 - 开发登录页
|
||||
* 临时:账户=手机号,密码可空,用于切换为对方账号调试
|
||||
*/
|
||||
const app = getApp()
|
||||
const { checkAndExecute } = require('../../utils/ruleEngine.js')
|
||||
|
||||
Page({
|
||||
data: {
|
||||
statusBarHeight: 44,
|
||||
account: '',
|
||||
password: '',
|
||||
loading: false
|
||||
},
|
||||
|
||||
onLoad() {
|
||||
this.setData({
|
||||
statusBarHeight: app.globalData.statusBarHeight || 44
|
||||
})
|
||||
},
|
||||
|
||||
onAccountInput(e) {
|
||||
this.setData({ account: (e.detail.value || '').trim() })
|
||||
},
|
||||
|
||||
onPasswordInput(e) {
|
||||
this.setData({ password: e.detail.value || '' })
|
||||
},
|
||||
|
||||
goBack() {
|
||||
app.goBackOrToHome()
|
||||
},
|
||||
|
||||
async handleLogin() {
|
||||
const { account, password, loading } = this.data
|
||||
if (!account || loading) return
|
||||
|
||||
const phone = account.replace(/\s/g, '')
|
||||
if (phone.length < 11) {
|
||||
wx.showToast({ title: '请输入11位手机号', icon: 'none' })
|
||||
return
|
||||
}
|
||||
|
||||
this.setData({ loading: true })
|
||||
try {
|
||||
const res = await app.request('/api/miniprogram/dev/login-by-phone', {
|
||||
method: 'POST',
|
||||
data: { phone, password: password || '' }
|
||||
})
|
||||
|
||||
if (res.success && res.data) {
|
||||
const user = res.data.user
|
||||
app.globalData.userInfo = user
|
||||
app.globalData.isLoggedIn = true
|
||||
app.globalData.purchasedSections = user.purchasedSections || []
|
||||
app.globalData.hasFullBook = user.hasFullBook || false
|
||||
app.globalData.isVip = user.isVip || false
|
||||
app.globalData.vipExpireDate = user.vipExpireDate || ''
|
||||
|
||||
wx.setStorageSync('userInfo', user)
|
||||
wx.setStorageSync('token', res.data.token)
|
||||
|
||||
const pendingRef = wx.getStorageSync('pendingReferralCode') || app.globalData.pendingReferralCode
|
||||
if (pendingRef) {
|
||||
app.bindReferralCode(pendingRef)
|
||||
}
|
||||
|
||||
checkAndExecute('after_login', null)
|
||||
setTimeout(() => app.checkVipContactRequiredAndGuide(), 1200)
|
||||
|
||||
wx.showToast({ title: '登录成功', icon: 'success' })
|
||||
setTimeout(() => wx.switchTab({ url: '/pages/index/index' }), 800)
|
||||
}
|
||||
} catch (e) {
|
||||
wx.showToast({ title: e.message || '登录失败', icon: 'none' })
|
||||
} finally {
|
||||
this.setData({ loading: false })
|
||||
}
|
||||
}
|
||||
})
|
||||
7
miniprogram/pages/dev-login/dev-login.json
Normal file
7
miniprogram/pages/dev-login/dev-login.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"usingComponents": {
|
||||
"icon": "/components/icon/icon"
|
||||
},
|
||||
"navigationStyle": "custom",
|
||||
"navigationBarTitleText": "账户密码登录"
|
||||
}
|
||||
51
miniprogram/pages/dev-login/dev-login.wxml
Normal file
51
miniprogram/pages/dev-login/dev-login.wxml
Normal file
@@ -0,0 +1,51 @@
|
||||
<!--开发登录页 - 临时:账户=手机号,密码可空-->
|
||||
<view class="page">
|
||||
<view class="nav-bar" style="padding-top: {{statusBarHeight}}px;">
|
||||
<view class="nav-back" bindtap="goBack">
|
||||
<icon name="chevron-left" size="44" color="rgba(255,255,255,0.6)" customClass="back-icon"></icon>
|
||||
</view>
|
||||
<text class="nav-title">账户密码登录</text>
|
||||
<view class="nav-placeholder"></view>
|
||||
</view>
|
||||
<view style="height: {{statusBarHeight + 44}}px;"></view>
|
||||
|
||||
<view class="content">
|
||||
<view class="tip-banner">
|
||||
<text class="tip-text">开发专用:输入对方手机号登录,密码可留空。仅开发环境可用。</text>
|
||||
</view>
|
||||
|
||||
<view class="form-card">
|
||||
<view class="form-item">
|
||||
<text class="form-label">账户(手机号)</text>
|
||||
<view class="form-input-wrap">
|
||||
<input
|
||||
class="form-input-inner"
|
||||
type="number"
|
||||
placeholder="请输入对方手机号"
|
||||
placeholder-class="input-placeholder"
|
||||
value="{{account}}"
|
||||
bindinput="onAccountInput"
|
||||
maxlength="11"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="form-item">
|
||||
<text class="form-label">密码(可留空)</text>
|
||||
<view class="form-input-wrap">
|
||||
<input
|
||||
class="form-input-inner"
|
||||
type="text"
|
||||
password="{{true}}"
|
||||
placeholder="可选,留空即可"
|
||||
placeholder-class="input-placeholder"
|
||||
value="{{password}}"
|
||||
bindinput="onPasswordInput"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="btn-primary {{!account || loading ? 'btn-disabled' : ''}}" bindtap="handleLogin">
|
||||
{{loading ? '登录中...' : '登录'}}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
23
miniprogram/pages/dev-login/dev-login.wxss
Normal file
23
miniprogram/pages/dev-login/dev-login.wxss
Normal file
@@ -0,0 +1,23 @@
|
||||
/* 开发登录页 */
|
||||
.page { min-height: 100vh; background: #000; padding-bottom: 64rpx; }
|
||||
|
||||
.nav-bar { position: fixed; top: 0; left: 0; right: 0; z-index: 100; background: rgba(0,0,0,0.9); backdrop-filter: blur(40rpx); display: flex; align-items: center; justify-content: space-between; padding: 0 32rpx; height: 88rpx; }
|
||||
.nav-back { width: 64rpx; height: 64rpx; background: #1c1c1e; border-radius: 50%; display: flex; align-items: center; justify-content: center; }
|
||||
.back-icon { font-size: 40rpx; color: rgba(255,255,255,0.6); font-weight: 300; }
|
||||
.nav-title { font-size: 34rpx; font-weight: 600; color: #fff; }
|
||||
.nav-placeholder { width: 64rpx; }
|
||||
|
||||
.content { padding: 24rpx 16rpx; }
|
||||
|
||||
.tip-banner { background: rgba(255,165,0,0.1); border: 2rpx solid rgba(255,165,0,0.3); border-radius: 20rpx; padding: 20rpx 24rpx; margin-bottom: 24rpx; }
|
||||
.tip-text { font-size: 24rpx; color: #FFA500; line-height: 1.5; }
|
||||
|
||||
.form-card { background: #1c1c1e; border-radius: 32rpx; padding: 32rpx; border: 2rpx solid rgba(0,206,209,0.2); }
|
||||
.form-item { margin-bottom: 32rpx; }
|
||||
.form-item:last-of-type { margin-bottom: 48rpx; }
|
||||
.form-label { font-size: 28rpx; color: rgba(255,255,255,0.8); display: block; margin-bottom: 16rpx; }
|
||||
.form-input-wrap { padding: 16rpx 24rpx; background: #1F2937; border: 2rpx solid rgba(255,255,255,0.1); border-radius: 24rpx; }
|
||||
.form-input-inner { width: 100%; font-size: 28rpx; background: transparent; color: #fff; }
|
||||
.input-placeholder { color: rgba(255,255,255,0.25); }
|
||||
.btn-primary { padding: 32rpx; background: linear-gradient(135deg, #00CED1 0%, #20B2AA 100%); color: #000; font-size: 32rpx; font-weight: 600; text-align: center; border-radius: 28rpx; }
|
||||
.btn-disabled { opacity: 0.5; }
|
||||
@@ -19,6 +19,7 @@ Page({
|
||||
isSinglePageMode: false,
|
||||
showLoginModal: false,
|
||||
agreeProtocol: false,
|
||||
showPrivacyModal: false,
|
||||
// 创建态
|
||||
isCreateMode: false,
|
||||
giftQuantity: 1,
|
||||
@@ -265,7 +266,7 @@ Page({
|
||||
},
|
||||
|
||||
closeLoginModal() {
|
||||
this.setData({ showLoginModal: false })
|
||||
this.setData({ showLoginModal: false, showPrivacyModal: false })
|
||||
},
|
||||
toggleAgree() {
|
||||
this.setData({ agreeProtocol: !this.data.agreeProtocol })
|
||||
@@ -284,6 +285,13 @@ Page({
|
||||
wx.showToast({ title: '登录失败', icon: 'none' })
|
||||
}
|
||||
},
|
||||
handleAgreePrivacyForPhone() {
|
||||
if (app._privacyResolve) {
|
||||
app._privacyResolve({ buttonId: 'agree-privacy-btn', event: 'agree' })
|
||||
app._privacyResolve = null
|
||||
}
|
||||
this.setData({ showPrivacyModal: false })
|
||||
},
|
||||
async handlePhoneLogin(e) {
|
||||
if (!e.detail.code) return this.handleWechatLogin()
|
||||
try {
|
||||
|
||||
@@ -152,10 +152,14 @@
|
||||
<view class="login-icon"><icon name="lock" size="80" color="#00CED1"></icon></view>
|
||||
<text class="login-title">登录 卡若创业派对</text>
|
||||
<text class="login-desc">登录后可免费领取并阅读</text>
|
||||
<button class="btn-wechat {{agreeProtocol ? '' : 'btn-wechat-disabled'}}" bindtap="handleWechatLogin" disabled="{{!agreeProtocol}}">
|
||||
<button id="agree-phone-btn" class="btn-wechat {{agreeProtocol ? '' : 'btn-wechat-disabled'}}" open-type="getPhoneNumber|agreePrivacyAuthorization" bindgetphonenumber="handlePhoneLogin" bindagreeprivacyauthorization="handleAgreePrivacyForPhone" disabled="{{!agreeProtocol}}">
|
||||
<text class="btn-wechat-icon">微</text>
|
||||
<text>微信快捷登录</text>
|
||||
<text>手机号一键登录</text>
|
||||
</button>
|
||||
<view class="privacy-wechat-row" wx:if="{{showPrivacyModal}}">
|
||||
<text class="privacy-wechat-desc">为获取手机号,请先同意《用户隐私保护指引》</text>
|
||||
<button id="agree-privacy-btn" class="privacy-agree-btn" open-type="agreePrivacyAuthorization" bindagreeprivacyauthorization="handleAgreePrivacyForPhone">同意</button>
|
||||
</view>
|
||||
<view class="login-agree-row" catchtap="toggleAgree">
|
||||
<view class="agree-checkbox {{agreeProtocol ? 'agree-checked' : ''}}"><icon wx:if="{{agreeProtocol}}" name="check" size="24" color="#34C759"></icon></view>
|
||||
<text class="agree-text">我已阅读并同意</text>
|
||||
|
||||
@@ -637,6 +637,10 @@
|
||||
}
|
||||
.btn-wechat-disabled { opacity: 0.5; }
|
||||
.btn-wechat-icon { font-weight: 700; margin-right: 8rpx; }
|
||||
.privacy-wechat-row { margin: 24rpx 0; padding: 24rpx; background: rgba(0,206,209,0.1); border-radius: 16rpx; }
|
||||
.privacy-wechat-desc { display: block; font-size: 26rpx; color: rgba(255,255,255,0.8); margin-bottom: 16rpx; }
|
||||
.privacy-agree-btn { width: 100%; padding: 20rpx; background: #07C160; color: #fff; font-size: 28rpx; border-radius: 16rpx; border: none; }
|
||||
.privacy-agree-btn::after { border: none; }
|
||||
.login-agree-row {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
@@ -61,6 +61,7 @@ Page({
|
||||
// 链接卡若 - 留资弹窗
|
||||
showLeadModal: false,
|
||||
leadPhone: '',
|
||||
showPrivacyModal: false,
|
||||
|
||||
// 展开状态(首页精选/最新)
|
||||
featuredExpanded: false,
|
||||
@@ -380,7 +381,7 @@ Page({
|
||||
},
|
||||
|
||||
closeLeadModal() {
|
||||
this.setData({ showLeadModal: false, leadPhone: '' })
|
||||
this.setData({ showLeadModal: false, leadPhone: '', showPrivacyModal: false })
|
||||
},
|
||||
|
||||
// 阻止弹窗内部点击事件冒泡到遮罩层
|
||||
@@ -390,6 +391,15 @@ Page({
|
||||
this.setData({ leadPhone: (e.detail.value || '').trim() })
|
||||
},
|
||||
|
||||
// 微信隐私协议同意(getPhoneNumber 需先同意)
|
||||
onAgreePrivacyForLead() {
|
||||
if (app._privacyResolve) {
|
||||
app._privacyResolve({ buttonId: 'agree-privacy-btn', event: 'agree' })
|
||||
app._privacyResolve = null
|
||||
}
|
||||
this.setData({ showPrivacyModal: false })
|
||||
},
|
||||
|
||||
// 一键获取手机号(微信能力),成功后直接提交链接卡若
|
||||
async onGetPhoneNumberForLead(e) {
|
||||
if (e.detail.errMsg !== 'getPhoneNumber:ok') {
|
||||
|
||||
@@ -161,7 +161,11 @@
|
||||
<view class="lead-box" catchtap="stopPropagation">
|
||||
<text class="lead-title">留下联系方式</text>
|
||||
<text class="lead-desc">方便卡若与您联系</text>
|
||||
<button class="lead-get-phone-btn" open-type="getPhoneNumber" bindgetphonenumber="onGetPhoneNumberForLead">一键获取手机号</button>
|
||||
<button id="agree-lead-phone-btn" class="lead-get-phone-btn" open-type="getPhoneNumber|agreePrivacyAuthorization" bindgetphonenumber="onGetPhoneNumberForLead" bindagreeprivacyauthorization="onAgreePrivacyForLead">一键获取手机号</button>
|
||||
<view class="privacy-wechat-row" wx:if="{{showPrivacyModal}}">
|
||||
<text class="privacy-wechat-desc">为获取手机号,请先同意《用户隐私保护指引》</text>
|
||||
<button id="agree-privacy-btn" class="privacy-agree-btn" open-type="agreePrivacyAuthorization" bindagreeprivacyauthorization="onAgreePrivacyForLead">同意</button>
|
||||
</view>
|
||||
<text class="lead-divider">或手动输入</text>
|
||||
<view class="lead-input-wrap">
|
||||
<input class="lead-input" placeholder="请输入手机号" type="number" maxlength="11" value="{{leadPhone}}" bindinput="onLeadPhoneInput"/>
|
||||
|
||||
@@ -900,6 +900,10 @@
|
||||
line-height: normal;
|
||||
}
|
||||
.lead-get-phone-btn::after { border: none; }
|
||||
.privacy-wechat-row { margin: 24rpx 0; padding: 24rpx; background: rgba(0,206,209,0.1); border-radius: 16rpx; }
|
||||
.privacy-wechat-desc { display: block; font-size: 26rpx; color: rgba(255,255,255,0.8); margin-bottom: 16rpx; }
|
||||
.privacy-agree-btn { width: 100%; padding: 20rpx; background: #07C160; color: #fff; font-size: 28rpx; border-radius: 16rpx; border: none; }
|
||||
.privacy-agree-btn::after { border: none; }
|
||||
.lead-divider {
|
||||
display: block;
|
||||
font-size: 24rpx;
|
||||
|
||||
@@ -63,6 +63,7 @@ Page({
|
||||
isLoggingIn: false,
|
||||
// 用户须主动勾选同意协议(审核要求:不得默认同意)
|
||||
agreeProtocol: false,
|
||||
showPrivacyModal: false,
|
||||
|
||||
// 修改昵称弹窗
|
||||
showNicknameModal: false,
|
||||
@@ -715,7 +716,7 @@ Page({
|
||||
// 关闭登录弹窗
|
||||
closeLoginModal() {
|
||||
if (this.data.isLoggingIn) return
|
||||
this.setData({ showLoginModal: false })
|
||||
this.setData({ showLoginModal: false, showPrivacyModal: false })
|
||||
},
|
||||
|
||||
// 微信登录(须已勾选同意协议,且做好错误处理避免审核报错)
|
||||
@@ -742,6 +743,15 @@ Page({
|
||||
}
|
||||
},
|
||||
|
||||
// 微信隐私协议同意(getPhoneNumber 需先同意)
|
||||
handleAgreePrivacyForPhone() {
|
||||
if (app._privacyResolve) {
|
||||
app._privacyResolve({ buttonId: 'agree-privacy-btn', event: 'agree' })
|
||||
app._privacyResolve = null
|
||||
}
|
||||
this.setData({ showPrivacyModal: false })
|
||||
},
|
||||
|
||||
// 手机号登录(需要用户授权)
|
||||
async handlePhoneLogin(e) {
|
||||
// 检查是否有授权code
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
<text wx:else class="guest-avatar-text">{{guestNickname[0] || '游'}}</text>
|
||||
</view>
|
||||
<text class="guest-name">{{guestNickname}}</text>
|
||||
<view class="guest-login-btn" bindtap="showLogin">点击登录</view>
|
||||
<view class="guest-login-btn" bindtap="showLogin">手机号一键登录</view>
|
||||
</view>
|
||||
|
||||
<!-- 已登录:用户卡片(设计稿布局) -->
|
||||
@@ -57,7 +57,7 @@
|
||||
<text class="profile-stat-label">推荐好友</text>
|
||||
</view>
|
||||
<view class="profile-stat" wx:if="{{referralEnabled}}" bindtap="goToReferral">
|
||||
<text class="profile-stat-val">{{earnings === '-' ? '--' : earnings}}</text>
|
||||
<text class="profile-stat-val">{{pendingEarnings === '-' ? '--' : pendingEarnings}}</text>
|
||||
<text class="profile-stat-label">我的收益</text>
|
||||
</view>
|
||||
<view class="profile-stat" wx:if="{{!auditMode}}" bindtap="handleMenuTap" data-id="wallet">
|
||||
@@ -178,10 +178,14 @@
|
||||
<view class="login-icon"><icon name="lock" size="80" color="#00CED1"></icon></view>
|
||||
<text class="login-title">登录 卡若创业派对</text>
|
||||
<text class="login-desc">登录后可购买章节、解锁更多内容</text>
|
||||
<button class="btn-wechat {{agreeProtocol ? '' : 'btn-wechat-disabled'}}" bindtap="handleWechatLogin" disabled="{{isLoggingIn || !agreeProtocol}}">
|
||||
<button id="agree-phone-btn" class="btn-wechat {{agreeProtocol ? '' : 'btn-wechat-disabled'}}" open-type="getPhoneNumber|agreePrivacyAuthorization" bindgetphonenumber="handlePhoneLogin" bindagreeprivacyauthorization="handleAgreePrivacyForPhone" disabled="{{isLoggingIn || !agreeProtocol}}">
|
||||
<text class="btn-wechat-icon">微</text>
|
||||
<text>{{isLoggingIn ? '登录中...' : '微信快捷登录'}}</text>
|
||||
<text>{{isLoggingIn ? '登录中...' : '手机号一键登录'}}</text>
|
||||
</button>
|
||||
<view class="privacy-wechat-row" wx:if="{{showPrivacyModal}}">
|
||||
<text class="privacy-wechat-desc">为获取手机号,请先同意《用户隐私保护指引》</text>
|
||||
<button id="agree-privacy-btn" class="privacy-agree-btn" open-type="agreePrivacyAuthorization" bindagreeprivacyauthorization="handleAgreePrivacyForPhone">同意</button>
|
||||
</view>
|
||||
<view class="login-modal-cancel" bindtap="closeLoginModal">取消</view>
|
||||
<view class="login-agree-row" catchtap="toggleAgree">
|
||||
<view class="agree-checkbox {{agreeProtocol ? 'agree-checked' : ''}}"><icon wx:if="{{agreeProtocol}}" name="check" size="24" color="#34C759"></icon></view>
|
||||
|
||||
@@ -225,6 +225,10 @@
|
||||
.agree-text { color: rgba(255,255,255,0.6); }
|
||||
.agree-link { color: #4FD1C5; text-decoration: underline; padding: 0 4rpx; }
|
||||
.btn-wechat-disabled { opacity: 0.6; }
|
||||
.privacy-wechat-row { margin: 24rpx 0; padding: 24rpx; background: rgba(0,206,209,0.1); border-radius: 16rpx; }
|
||||
.privacy-wechat-desc { display: block; font-size: 26rpx; color: rgba(255,255,255,0.8); margin-bottom: 16rpx; }
|
||||
.privacy-agree-btn { width: 100%; padding: 20rpx; background: #07C160; color: #fff; font-size: 28rpx; border-radius: 16rpx; border: none; }
|
||||
.privacy-agree-btn::after { border: none; }
|
||||
|
||||
/* 头像弹窗 */
|
||||
.avatar-modal .avatar-modal-title { display: block; font-size: 36rpx; font-weight: bold; color: #fff; text-align: center; margin-bottom: 16rpx; }
|
||||
|
||||
@@ -75,6 +75,7 @@ Page({
|
||||
giftRequestSn: '',
|
||||
showLoginModal: false,
|
||||
agreeProtocol: false,
|
||||
showPrivacyModal: false,
|
||||
showPosterModal: false,
|
||||
isPaying: false,
|
||||
isGeneratingPoster: false,
|
||||
@@ -982,7 +983,7 @@ Page({
|
||||
},
|
||||
|
||||
closeLoginModal() {
|
||||
this.setData({ showLoginModal: false })
|
||||
this.setData({ showLoginModal: false, showPrivacyModal: false })
|
||||
},
|
||||
|
||||
toggleAgree() {
|
||||
@@ -1018,6 +1019,16 @@ Page({
|
||||
}
|
||||
},
|
||||
|
||||
// 微信隐私协议同意(getPhoneNumber 需先同意)
|
||||
handleAgreePrivacyForPhone() {
|
||||
const app = getApp()
|
||||
if (app._privacyResolve) {
|
||||
app._privacyResolve({ buttonId: 'agree-privacy-btn', event: 'agree' })
|
||||
app._privacyResolve = null
|
||||
}
|
||||
this.setData({ showPrivacyModal: false })
|
||||
},
|
||||
|
||||
// 【重构】手机号登录(标准流程)
|
||||
async handlePhoneLogin(e) {
|
||||
if (!e.detail.code) {
|
||||
|
||||
@@ -131,7 +131,7 @@
|
||||
<text class="paywall-desc">已阅读50%,登录后查看完整内容</text>
|
||||
|
||||
<view class="login-btn" bindtap="showLoginModal">
|
||||
<text class="login-btn-text">立即登录</text>
|
||||
<text class="login-btn-text">手机号一键登录</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
@@ -341,11 +341,15 @@
|
||||
<text class="login-title">登录 卡若创业派对</text>
|
||||
<text class="login-desc">登录后可购买章节、解锁更多内容</text>
|
||||
|
||||
<button class="btn-wechat {{agreeProtocol ? '' : 'btn-wechat-disabled'}}" bindtap="handleWechatLogin" disabled="{{!agreeProtocol}}">
|
||||
<button id="agree-phone-btn" class="btn-wechat {{agreeProtocol ? '' : 'btn-wechat-disabled'}}" open-type="getPhoneNumber|agreePrivacyAuthorization" bindgetphonenumber="handlePhoneLogin" bindagreeprivacyauthorization="handleAgreePrivacyForPhone" disabled="{{!agreeProtocol}}">
|
||||
<text class="btn-wechat-icon">微</text>
|
||||
<text>微信快捷登录</text>
|
||||
<text>手机号一键登录</text>
|
||||
</button>
|
||||
|
||||
<view class="privacy-wechat-row" wx:if="{{showPrivacyModal}}">
|
||||
<text class="privacy-wechat-desc">为获取手机号,请先同意《用户隐私保护指引》</text>
|
||||
<button id="agree-privacy-btn" class="privacy-agree-btn" open-type="agreePrivacyAuthorization" bindagreeprivacyauthorization="handleAgreePrivacyForPhone">同意</button>
|
||||
</view>
|
||||
<view class="login-agree-row" catchtap="toggleAgree">
|
||||
<view class="agree-checkbox {{agreeProtocol ? 'agree-checked' : ''}}"><icon wx:if="{{agreeProtocol}}" name="check" size="24" color="#34C759"></icon></view>
|
||||
<text class="agree-text">我已阅读并同意</text>
|
||||
|
||||
@@ -1164,6 +1164,10 @@
|
||||
padding: 0 4rpx;
|
||||
}
|
||||
.btn-wechat-disabled { opacity: 0.6; }
|
||||
.privacy-wechat-row { margin: 24rpx 0; padding: 24rpx; background: rgba(0,206,209,0.1); border-radius: 16rpx; }
|
||||
.privacy-wechat-desc { display: block; font-size: 26rpx; color: rgba(255,255,255,0.8); margin-bottom: 16rpx; }
|
||||
.privacy-agree-btn { width: 100%; padding: 20rpx; background: #07C160; color: #fff; font-size: 28rpx; border-radius: 16rpx; border: none; }
|
||||
.privacy-agree-btn::after { border: none; }
|
||||
|
||||
/* ===== 支付中加载 ===== */
|
||||
.loading-box {
|
||||
|
||||
@@ -30,7 +30,8 @@ Page({
|
||||
// 绑定弹窗
|
||||
showBindModal: false,
|
||||
bindType: '', // phone | wechat | alipay
|
||||
bindValue: ''
|
||||
bindValue: '',
|
||||
showPrivacyModal: false
|
||||
},
|
||||
|
||||
onLoad() {
|
||||
@@ -332,6 +333,15 @@ Page({
|
||||
}
|
||||
},
|
||||
|
||||
// 微信隐私协议同意(getPhoneNumber 需先同意)
|
||||
onAgreePrivacyForPhone() {
|
||||
if (app._privacyResolve) {
|
||||
app._privacyResolve({ buttonId: 'agree-privacy-btn', event: 'agree' })
|
||||
app._privacyResolve = null
|
||||
}
|
||||
this.setData({ showPrivacyModal: false })
|
||||
},
|
||||
|
||||
// 一键获取微信手机号(button组件回调)
|
||||
async onGetPhoneNumber(e) {
|
||||
console.log('[Settings] 获取手机号回调:', e.detail)
|
||||
@@ -392,6 +402,11 @@ Page({
|
||||
this.setData({ showBindModal: false })
|
||||
},
|
||||
|
||||
// 跳转账户密码登录页(开发)
|
||||
goToDevLogin() {
|
||||
wx.navigateTo({ url: '/pages/dev-login/dev-login' })
|
||||
},
|
||||
|
||||
// 打开切换账号弹窗(开发)
|
||||
openSwitchAccountModal() {
|
||||
this.setData({
|
||||
|
||||
@@ -32,11 +32,15 @@
|
||||
</view>
|
||||
<view class="bind-right">
|
||||
<icon wx:if="{{phoneNumber}}" name="check" size="36" color="#34C759" customClass="bind-check"></icon>
|
||||
<button wx:else class="get-phone-btn" open-type="getPhoneNumber" bindgetphonenumber="onGetPhoneNumber">
|
||||
<button wx:else id="agree-settings-phone-btn" class="get-phone-btn" open-type="getPhoneNumber|agreePrivacyAuthorization" bindgetphonenumber="onGetPhoneNumber" bindagreeprivacyauthorization="onAgreePrivacyForPhone">
|
||||
一键获取
|
||||
</button>
|
||||
</view>
|
||||
</view>
|
||||
<view class="privacy-wechat-row" wx:if="{{showPrivacyModal}}">
|
||||
<text class="privacy-wechat-desc">为获取手机号,请先同意《用户隐私保护指引》</text>
|
||||
<button id="agree-privacy-btn" class="privacy-agree-btn" open-type="agreePrivacyAuthorization" bindagreeprivacyauthorization="onAgreePrivacyForPhone">同意</button>
|
||||
</view>
|
||||
|
||||
<!-- 微信号 - 简化输入 -->
|
||||
<view class="bind-item">
|
||||
@@ -117,6 +121,13 @@
|
||||
<text class="dev-switch-desc">输入 userId 切换为其他账号调试</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="dev-switch-card" wx:if="{{isDevMode}}" bindtap="goToDevLogin">
|
||||
<view class="dev-switch-inner">
|
||||
<icon name="smartphone" size="40" color="#8e8e93" customClass="dev-switch-icon"></icon>
|
||||
<text class="dev-switch-text">账户密码登录</text>
|
||||
<text class="dev-switch-desc">输入对方手机号登录,密码可留空</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="logout-btn" wx:if="{{isLoggedIn}}" bindtap="handleLogout">退出登录</view>
|
||||
</view>
|
||||
|
||||
@@ -49,6 +49,10 @@
|
||||
line-height: normal;
|
||||
}
|
||||
.get-phone-btn::after { border: none; }
|
||||
.privacy-wechat-row { margin: 24rpx 0; padding: 24rpx; background: rgba(0,206,209,0.1); border-radius: 16rpx; }
|
||||
.privacy-wechat-desc { display: block; font-size: 26rpx; color: rgba(255,255,255,0.8); margin-bottom: 16rpx; }
|
||||
.privacy-agree-btn { width: 100%; padding: 20rpx; background: #07C160; color: #fff; font-size: 28rpx; border-radius: 16rpx; border: none; }
|
||||
.privacy-agree-btn::after { border: none; }
|
||||
|
||||
/* 自动提现卡片 */
|
||||
.auto-withdraw-card { margin-top: 24rpx; }
|
||||
|
||||
@@ -23,12 +23,19 @@
|
||||
"condition": {
|
||||
"miniprogram": {
|
||||
"list": [
|
||||
{
|
||||
"name": "开发登录",
|
||||
"pathName": "pages/dev-login/dev-login",
|
||||
"query": "",
|
||||
"scene": null,
|
||||
"launchMode": "default"
|
||||
},
|
||||
{
|
||||
"name": "pages/member-detail/member-detail",
|
||||
"pathName": "pages/member-detail/member-detail",
|
||||
"query": "id=ogpTW5cVMxd5afBBtXdvmeMO8aho",
|
||||
"scene": null,
|
||||
"launchMode": "default"
|
||||
"launchMode": "default",
|
||||
"scene": null
|
||||
},
|
||||
{
|
||||
"name": "pages/my/my",
|
||||
|
||||
Reference in New Issue
Block a user