删除过时的部署管理端触发词文档,并更新相关索引以反映新的触发词约定,确保文档一致性和准确性。
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"usingComponents": {
|
||||
"icon": "/components/icon/icon"
|
||||
"icon": "/components/icon/icon",
|
||||
"login-modal": "/components/login-modal/login-modal"
|
||||
},
|
||||
"pages": [
|
||||
"pages/chapters/chapters",
|
||||
|
||||
79
miniprogram/components/login-modal/login-modal.js
Normal file
79
miniprogram/components/login-modal/login-modal.js
Normal file
@@ -0,0 +1,79 @@
|
||||
/**
|
||||
* Soul 创业派对 - 公用登录弹窗
|
||||
* 手机号一键登录 + 隐私协议
|
||||
*/
|
||||
Component({
|
||||
properties: {
|
||||
show: { type: Boolean, value: false },
|
||||
desc: { type: String, value: '登录后可购买章节、解锁更多内容' },
|
||||
showPrivacyModal: { type: Boolean, value: false },
|
||||
showCancel: { type: Boolean, value: false }
|
||||
},
|
||||
data: {
|
||||
agreeProtocol: false,
|
||||
isLoggingIn: false
|
||||
},
|
||||
observers: {
|
||||
show(v) {
|
||||
if (!v) this.setData({ agreeProtocol: false, isLoggingIn: false })
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
stopPropagation() {},
|
||||
onClose() {
|
||||
this.triggerEvent('close')
|
||||
},
|
||||
onToggleAgree() {
|
||||
this.setData({ agreeProtocol: !this.data.agreeProtocol })
|
||||
},
|
||||
onOpenUserProtocol() {
|
||||
wx.navigateTo({ url: '/pages/agreement/agreement' })
|
||||
},
|
||||
onOpenPrivacy() {
|
||||
wx.navigateTo({ url: '/pages/privacy/privacy' })
|
||||
},
|
||||
onAgreePrivacy() {
|
||||
const app = getApp()
|
||||
if (app._privacyResolve) {
|
||||
app._privacyResolve({ buttonId: 'agree-privacy-btn', event: 'agree' })
|
||||
app._privacyResolve = null
|
||||
}
|
||||
this.triggerEvent('privacyagree')
|
||||
},
|
||||
async onPhoneLogin(e) {
|
||||
if (!e.detail.code) {
|
||||
return this._fallbackWechatLogin()
|
||||
}
|
||||
const app = getApp()
|
||||
this.setData({ isLoggingIn: true })
|
||||
try {
|
||||
const result = await app.loginWithPhone(e.detail.code)
|
||||
this.setData({ isLoggingIn: false })
|
||||
if (result) {
|
||||
this.triggerEvent('success')
|
||||
} else {
|
||||
wx.showToast({ title: '登录失败,请重试', icon: 'none' })
|
||||
}
|
||||
} catch (err) {
|
||||
this.setData({ isLoggingIn: false })
|
||||
wx.showToast({ title: '登录失败,请重试', icon: 'none' })
|
||||
}
|
||||
},
|
||||
async _fallbackWechatLogin() {
|
||||
const app = getApp()
|
||||
this.setData({ isLoggingIn: true })
|
||||
try {
|
||||
const result = await app.login()
|
||||
this.setData({ isLoggingIn: false })
|
||||
if (result) {
|
||||
this.triggerEvent('success')
|
||||
} else {
|
||||
wx.showToast({ title: '登录失败,请重试', icon: 'none' })
|
||||
}
|
||||
} catch (err) {
|
||||
this.setData({ isLoggingIn: false })
|
||||
wx.showToast({ title: '登录失败,请重试', icon: 'none' })
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
6
miniprogram/components/login-modal/login-modal.json
Normal file
6
miniprogram/components/login-modal/login-modal.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"component": true,
|
||||
"usingComponents": {
|
||||
"icon": "/components/icon/icon"
|
||||
}
|
||||
}
|
||||
27
miniprogram/components/login-modal/login-modal.wxml
Normal file
27
miniprogram/components/login-modal/login-modal.wxml
Normal file
@@ -0,0 +1,27 @@
|
||||
<!-- Soul 创业派对 - 公用登录弹窗 -->
|
||||
<view class="modal-overlay" wx:if="{{show}}" bindtap="onClose">
|
||||
<view class="modal-content login-modal" catchtap="stopPropagation">
|
||||
<view class="modal-close" bindtap="onClose"><icon name="x" size="36" color="#8e8e93"></icon></view>
|
||||
<view class="login-icon"><icon name="lock" size="80" color="#00CED1"></icon></view>
|
||||
<text class="login-title">登录 卡若创业派对</text>
|
||||
<text class="login-desc">{{desc}}</text>
|
||||
|
||||
<button id="agree-phone-btn" class="btn-wechat {{agreeProtocol ? '' : 'btn-wechat-disabled'}}" open-type="getPhoneNumber|agreePrivacyAuthorization" bindgetphonenumber="onPhoneLogin" bindagreeprivacyauthorization="onAgreePrivacy" disabled="{{isLoggingIn || !agreeProtocol}}">
|
||||
<text class="btn-wechat-icon">微</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="onAgreePrivacy">同意</button>
|
||||
</view>
|
||||
<view class="login-modal-cancel" wx:if="{{showCancel}}" bindtap="onClose">取消</view>
|
||||
<view class="login-agree-row" catchtap="onToggleAgree">
|
||||
<view class="agree-checkbox {{agreeProtocol ? 'agree-checked' : ''}}"><icon wx:if="{{agreeProtocol}}" name="check" size="24" color="#34C759"></icon></view>
|
||||
<text class="agree-text">我已阅读并同意</text>
|
||||
<text class="agree-link" catchtap="onOpenUserProtocol">《用户协议》</text>
|
||||
<text class="agree-text">和</text>
|
||||
<text class="agree-link" catchtap="onOpenPrivacy">《隐私政策》</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
136
miniprogram/components/login-modal/login-modal.wxss
Normal file
136
miniprogram/components/login-modal/login-modal.wxss
Normal file
@@ -0,0 +1,136 @@
|
||||
/* Soul 创业派对 - 公用登录弹窗 */
|
||||
.modal-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: rgba(0, 0, 0, 0.7);
|
||||
z-index: 1000;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 48rpx;
|
||||
}
|
||||
.modal-content {
|
||||
width: 100%;
|
||||
max-width: 600rpx;
|
||||
background: #1c1c1e;
|
||||
border-radius: 32rpx;
|
||||
overflow: hidden;
|
||||
}
|
||||
.modal-close {
|
||||
position: absolute;
|
||||
top: 24rpx;
|
||||
right: 24rpx;
|
||||
z-index: 1;
|
||||
padding: 16rpx;
|
||||
}
|
||||
.login-modal {
|
||||
padding: 48rpx 32rpx;
|
||||
text-align: center;
|
||||
}
|
||||
.login-icon {
|
||||
font-size: 80rpx;
|
||||
display: block;
|
||||
margin-bottom: 24rpx;
|
||||
}
|
||||
.login-title {
|
||||
font-size: 36rpx;
|
||||
font-weight: 700;
|
||||
color: #ffffff;
|
||||
display: block;
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
.login-desc {
|
||||
font-size: 26rpx;
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
display: block;
|
||||
margin-bottom: 48rpx;
|
||||
}
|
||||
.btn-wechat {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 16rpx;
|
||||
padding: 28rpx;
|
||||
background: #07C160;
|
||||
color: #ffffff;
|
||||
font-size: 30rpx;
|
||||
font-weight: 600;
|
||||
border-radius: 24rpx;
|
||||
margin-bottom: 20rpx;
|
||||
border: none;
|
||||
}
|
||||
.btn-wechat::after { border: none; }
|
||||
.btn-wechat-icon {
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
background: rgba(255, 255, 255, 0.2);
|
||||
border-radius: 8rpx;
|
||||
font-size: 24rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.btn-wechat-disabled { opacity: 0.6; }
|
||||
.login-modal-cancel {
|
||||
margin-top: 24rpx;
|
||||
padding: 24rpx;
|
||||
font-size: 28rpx;
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
text-align: center;
|
||||
}
|
||||
.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;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-top: 32rpx;
|
||||
font-size: 22rpx;
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
.agree-checkbox {
|
||||
width: 32rpx;
|
||||
height: 32rpx;
|
||||
border: 2rpx solid rgba(255, 255, 255, 0.5);
|
||||
border-radius: 6rpx;
|
||||
margin-right: 12rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 22rpx;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.agree-checked {
|
||||
background: #00CED1;
|
||||
border-color: #00CED1;
|
||||
}
|
||||
.agree-text { color: rgba(255, 255, 255, 0.6); }
|
||||
.agree-link {
|
||||
color: #00CED1;
|
||||
text-decoration: underline;
|
||||
padding: 0 4rpx;
|
||||
}
|
||||
@@ -18,7 +18,6 @@ Page({
|
||||
amountDisplay: '0.00',
|
||||
isSinglePageMode: false,
|
||||
showLoginModal: false,
|
||||
agreeProtocol: false,
|
||||
showPrivacyModal: false,
|
||||
// 创建态
|
||||
isCreateMode: false,
|
||||
@@ -227,7 +226,7 @@ Page({
|
||||
}
|
||||
const userId = app.globalData.userInfo?.id
|
||||
if (!userId) {
|
||||
this.setData({ showLoginModal: true, agreeProtocol: false })
|
||||
this.setData({ showLoginModal: true })
|
||||
return
|
||||
}
|
||||
await this._doRedeem()
|
||||
@@ -265,51 +264,15 @@ Page({
|
||||
}
|
||||
},
|
||||
|
||||
closeLoginModal() {
|
||||
onLoginModalClose() {
|
||||
this.setData({ showLoginModal: false, showPrivacyModal: false })
|
||||
},
|
||||
toggleAgree() {
|
||||
this.setData({ agreeProtocol: !this.data.agreeProtocol })
|
||||
},
|
||||
async handleWechatLogin() {
|
||||
if (!this.data.agreeProtocol) {
|
||||
wx.showToast({ title: '请先阅读并同意用户协议和隐私政策', icon: 'none' })
|
||||
return
|
||||
}
|
||||
try {
|
||||
const result = await app.login()
|
||||
if (!result) return
|
||||
this.setData({ showLoginModal: false, agreeProtocol: false })
|
||||
await this._doRedeem()
|
||||
} catch (e) {
|
||||
wx.showToast({ title: '登录失败', icon: 'none' })
|
||||
}
|
||||
},
|
||||
handleAgreePrivacyForPhone() {
|
||||
if (app._privacyResolve) {
|
||||
app._privacyResolve({ buttonId: 'agree-privacy-btn', event: 'agree' })
|
||||
app._privacyResolve = null
|
||||
}
|
||||
onLoginModalPrivacyAgree() {
|
||||
this.setData({ showPrivacyModal: false })
|
||||
},
|
||||
async handlePhoneLogin(e) {
|
||||
if (!e.detail.code) return this.handleWechatLogin()
|
||||
try {
|
||||
const result = await app.loginWithPhone(e.detail.code)
|
||||
if (!result) return
|
||||
this.setData({ showLoginModal: false })
|
||||
await this._doRedeem()
|
||||
} catch (e) {
|
||||
wx.showToast({ title: '登录失败', icon: 'none' })
|
||||
}
|
||||
},
|
||||
|
||||
stopPropagation() {},
|
||||
openUserProtocol() {
|
||||
wx.navigateTo({ url: '/pages/agreement/agreement' })
|
||||
},
|
||||
openPrivacy() {
|
||||
wx.navigateTo({ url: '/pages/privacy/privacy' })
|
||||
async onLoginModalSuccess() {
|
||||
this.setData({ showLoginModal: false })
|
||||
await this._doRedeem()
|
||||
},
|
||||
|
||||
goBack() {
|
||||
|
||||
@@ -145,30 +145,15 @@
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 登录弹窗(好友领取时未登录) -->
|
||||
<view class="modal-overlay" wx:if="{{showLoginModal}}" bindtap="closeLoginModal">
|
||||
<view class="modal-content login-modal" catchtap="stopPropagation">
|
||||
<view class="modal-close" bindtap="closeLoginModal"><icon name="x" size="36" color="#8e8e93"></icon></view>
|
||||
<view class="login-icon"><icon name="lock" size="80" color="#00CED1"></icon></view>
|
||||
<text class="login-title">登录 卡若创业派对</text>
|
||||
<text class="login-desc">登录后可免费领取并阅读</text>
|
||||
<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>
|
||||
</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>
|
||||
<text class="agree-link" bindtap="openUserProtocol">《用户协议》</text>
|
||||
<text class="agree-text">和</text>
|
||||
<text class="agree-link" bindtap="openPrivacy">《隐私政策》</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 登录弹窗(公用组件) -->
|
||||
<login-modal
|
||||
show="{{showLoginModal}}"
|
||||
desc="登录后可免费领取并阅读"
|
||||
showPrivacyModal="{{showPrivacyModal}}"
|
||||
bind:close="onLoginModalClose"
|
||||
bind:success="onLoginModalSuccess"
|
||||
bind:privacyagree="onLoginModalPrivacyAgree"
|
||||
/>
|
||||
|
||||
<!-- 背景光效 -->
|
||||
<view class="bg-effects">
|
||||
|
||||
@@ -60,9 +60,6 @@ Page({
|
||||
|
||||
// 登录弹窗
|
||||
showLoginModal: false,
|
||||
isLoggingIn: false,
|
||||
// 用户须主动勾选同意协议(审核要求:不得默认同意)
|
||||
agreeProtocol: false,
|
||||
showPrivacyModal: false,
|
||||
|
||||
// 修改昵称弹窗
|
||||
@@ -691,93 +688,23 @@ Page({
|
||||
console.warn('[My] 检测单页模式失败,回退为正常登录弹窗:', e)
|
||||
}
|
||||
try {
|
||||
this.setData({ showLoginModal: true, agreeProtocol: false })
|
||||
this.setData({ showLoginModal: true })
|
||||
} catch (e) {
|
||||
console.error('[My] showLogin error:', e)
|
||||
this.setData({ showLoginModal: true })
|
||||
}
|
||||
},
|
||||
|
||||
// 切换协议勾选(用户主动勾选,非默认同意)
|
||||
toggleAgree() {
|
||||
this.setData({ agreeProtocol: !this.data.agreeProtocol })
|
||||
},
|
||||
|
||||
// 打开用户协议页(审核要求:点击《用户协议》需有响应)
|
||||
openUserProtocol() {
|
||||
wx.navigateTo({ url: '/pages/agreement/agreement' })
|
||||
},
|
||||
|
||||
// 打开隐私政策页(审核要求:点击《隐私政策》需有响应)
|
||||
openPrivacy() {
|
||||
wx.navigateTo({ url: '/pages/privacy/privacy' })
|
||||
},
|
||||
|
||||
// 关闭登录弹窗
|
||||
closeLoginModal() {
|
||||
if (this.data.isLoggingIn) return
|
||||
onLoginModalClose() {
|
||||
this.setData({ showLoginModal: false, showPrivacyModal: false })
|
||||
},
|
||||
|
||||
// 微信登录(须已勾选同意协议,且做好错误处理避免审核报错)
|
||||
async handleWechatLogin() {
|
||||
if (!this.data.agreeProtocol) {
|
||||
wx.showToast({ title: '请先阅读并同意用户协议和隐私政策', icon: 'none' })
|
||||
return
|
||||
}
|
||||
this.setData({ isLoggingIn: true })
|
||||
try {
|
||||
const result = await app.login()
|
||||
if (result) {
|
||||
this.initUserStatus()
|
||||
this.setData({ showLoginModal: false, agreeProtocol: false })
|
||||
wx.showToast({ title: '登录成功', icon: 'success' })
|
||||
} else {
|
||||
wx.showToast({ title: '登录失败,请重试', icon: 'none' })
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('[My] 微信登录错误:', e)
|
||||
wx.showToast({ title: '登录失败,请重试', icon: 'none' })
|
||||
} finally {
|
||||
this.setData({ isLoggingIn: false })
|
||||
}
|
||||
},
|
||||
|
||||
// 微信隐私协议同意(getPhoneNumber 需先同意)
|
||||
handleAgreePrivacyForPhone() {
|
||||
if (app._privacyResolve) {
|
||||
app._privacyResolve({ buttonId: 'agree-privacy-btn', event: 'agree' })
|
||||
app._privacyResolve = null
|
||||
}
|
||||
onLoginModalPrivacyAgree() {
|
||||
this.setData({ showPrivacyModal: false })
|
||||
},
|
||||
|
||||
// 手机号登录(需要用户授权)
|
||||
async handlePhoneLogin(e) {
|
||||
// 检查是否有授权code
|
||||
if (!e.detail.code) {
|
||||
// 用户拒绝授权或获取失败,尝试使用微信登录
|
||||
console.log('手机号授权失败,尝试微信登录')
|
||||
return this.handleWechatLogin()
|
||||
}
|
||||
|
||||
this.setData({ isLoggingIn: true })
|
||||
|
||||
try {
|
||||
const result = await app.loginWithPhone(e.detail.code)
|
||||
if (result) {
|
||||
this.initUserStatus()
|
||||
this.setData({ showLoginModal: false })
|
||||
wx.showToast({ title: '登录成功', icon: 'success' })
|
||||
} else {
|
||||
wx.showToast({ title: '登录失败,请重试', icon: 'none' })
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('手机号登录错误:', e)
|
||||
wx.showToast({ title: '登录失败,请重试', icon: 'none' })
|
||||
} finally {
|
||||
this.setData({ isLoggingIn: false })
|
||||
}
|
||||
onLoginModalSuccess() {
|
||||
this.initUserStatus()
|
||||
this.setData({ showLoginModal: false })
|
||||
wx.showToast({ title: '登录成功', icon: 'success' })
|
||||
},
|
||||
|
||||
// 点击菜单
|
||||
|
||||
@@ -171,31 +171,16 @@
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 登录弹窗 -->
|
||||
<view class="modal-overlay" wx:if="{{showLoginModal}}" bindtap="closeLoginModal">
|
||||
<view class="modal-content login-modal-content" catchtap="stopPropagation">
|
||||
<view class="modal-close" bindtap="closeLoginModal"><icon name="x" size="36" color="#8e8e93"></icon></view>
|
||||
<view class="login-icon"><icon name="lock" size="80" color="#00CED1"></icon></view>
|
||||
<text class="login-title">登录 卡若创业派对</text>
|
||||
<text class="login-desc">登录后可购买章节、解锁更多内容</text>
|
||||
<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>
|
||||
</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>
|
||||
<text class="agree-text">我已阅读并同意</text>
|
||||
<text class="agree-link" catchtap="openUserProtocol">《用户协议》</text>
|
||||
<text class="agree-text">和</text>
|
||||
<text class="agree-link" catchtap="openPrivacy">《隐私政策》</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 登录弹窗(公用组件) -->
|
||||
<login-modal
|
||||
show="{{showLoginModal}}"
|
||||
desc="登录后可购买章节、解锁更多内容"
|
||||
showPrivacyModal="{{showPrivacyModal}}"
|
||||
showCancel="{{true}}"
|
||||
bind:close="onLoginModalClose"
|
||||
bind:success="onLoginModalSuccess"
|
||||
bind:privacyagree="onLoginModalPrivacyAgree"
|
||||
/>
|
||||
|
||||
<!-- 手机/微信号弹窗 -->
|
||||
<view class="modal-overlay contact-modal-overlay" wx:if="{{showContactModal}}" bindtap="closeContactModal">
|
||||
|
||||
@@ -74,7 +74,6 @@ Page({
|
||||
giftPaid: false,
|
||||
giftRequestSn: '',
|
||||
showLoginModal: false,
|
||||
agreeProtocol: false,
|
||||
showPrivacyModal: false,
|
||||
showPosterModal: false,
|
||||
isPaying: false,
|
||||
@@ -975,78 +974,23 @@ Page({
|
||||
console.warn('[Read] 检测单页模式失败,回退为正常登录流程:', e)
|
||||
}
|
||||
try {
|
||||
this.setData({ showLoginModal: true, agreeProtocol: false })
|
||||
this.setData({ showLoginModal: true })
|
||||
} catch (e) {
|
||||
console.error('[Read] showLoginModal error:', e)
|
||||
this.setData({ showLoginModal: true })
|
||||
}
|
||||
},
|
||||
|
||||
closeLoginModal() {
|
||||
onLoginModalClose() {
|
||||
this.setData({ showLoginModal: false, showPrivacyModal: false })
|
||||
},
|
||||
|
||||
toggleAgree() {
|
||||
this.setData({ agreeProtocol: !this.data.agreeProtocol })
|
||||
},
|
||||
|
||||
openUserProtocol() {
|
||||
wx.navigateTo({ url: '/pages/agreement/agreement' })
|
||||
},
|
||||
|
||||
openPrivacy() {
|
||||
wx.navigateTo({ url: '/pages/privacy/privacy' })
|
||||
},
|
||||
|
||||
// 从服务端刷新购买状态,避免登录后误用旧数据导致误解锁
|
||||
// 【重构】微信登录(须先勾选同意协议,符合审核要求)
|
||||
async handleWechatLogin() {
|
||||
if (!this.data.agreeProtocol) {
|
||||
wx.showToast({ title: '请先阅读并同意用户协议和隐私政策', icon: 'none' })
|
||||
return
|
||||
}
|
||||
try {
|
||||
const result = await app.login()
|
||||
if (!result) return
|
||||
|
||||
this.setData({ showLoginModal: false, agreeProtocol: false })
|
||||
await this.onLoginSuccess()
|
||||
wx.showToast({ title: '登录成功', icon: 'success' })
|
||||
|
||||
} catch (e) {
|
||||
console.error('[Read] 登录失败:', e)
|
||||
wx.showToast({ title: '登录失败,请重试', icon: 'none' })
|
||||
}
|
||||
},
|
||||
|
||||
// 微信隐私协议同意(getPhoneNumber 需先同意)
|
||||
handleAgreePrivacyForPhone() {
|
||||
const app = getApp()
|
||||
if (app._privacyResolve) {
|
||||
app._privacyResolve({ buttonId: 'agree-privacy-btn', event: 'agree' })
|
||||
app._privacyResolve = null
|
||||
}
|
||||
onLoginModalPrivacyAgree() {
|
||||
this.setData({ showPrivacyModal: false })
|
||||
},
|
||||
|
||||
// 【重构】手机号登录(标准流程)
|
||||
async handlePhoneLogin(e) {
|
||||
if (!e.detail.code) {
|
||||
return this.handleWechatLogin()
|
||||
}
|
||||
|
||||
try {
|
||||
const result = await app.loginWithPhone(e.detail.code)
|
||||
if (!result) return
|
||||
|
||||
this.setData({ showLoginModal: false })
|
||||
await this.onLoginSuccess()
|
||||
wx.showToast({ title: '登录成功', icon: 'success' })
|
||||
|
||||
} catch (e) {
|
||||
console.error('[Read] 手机号登录失败:', e)
|
||||
wx.showToast({ title: '登录失败', icon: 'none' })
|
||||
}
|
||||
async onLoginModalSuccess() {
|
||||
this.setData({ showLoginModal: false })
|
||||
await this.onLoginSuccess()
|
||||
wx.showToast({ title: '登录成功', icon: 'success' })
|
||||
},
|
||||
|
||||
// 【新增】登录成功后的标准处理流程
|
||||
|
||||
@@ -333,32 +333,15 @@
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 登录弹窗 - 须勾选同意协议,《用户协议》《隐私政策》可点击查看 -->
|
||||
<view class="modal-overlay" wx:if="{{showLoginModal}}" bindtap="closeLoginModal">
|
||||
<view class="modal-content login-modal" catchtap="stopPropagation">
|
||||
<view class="modal-close" bindtap="closeLoginModal"><icon name="x" size="36" color="#8e8e93"></icon></view>
|
||||
<view class="login-icon"><icon name="lock" size="80" color="#00CED1"></icon></view>
|
||||
<text class="login-title">登录 卡若创业派对</text>
|
||||
<text class="login-desc">登录后可购买章节、解锁更多内容</text>
|
||||
|
||||
<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>
|
||||
</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>
|
||||
<text class="agree-link" catchtap="openUserProtocol">《用户协议》</text>
|
||||
<text class="agree-text">和</text>
|
||||
<text class="agree-link" catchtap="openPrivacy">《隐私政策》</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 登录弹窗(公用组件) -->
|
||||
<login-modal
|
||||
show="{{showLoginModal}}"
|
||||
desc="登录后可购买章节、解锁更多内容"
|
||||
showPrivacyModal="{{showPrivacyModal}}"
|
||||
bind:close="onLoginModalClose"
|
||||
bind:success="onLoginModalSuccess"
|
||||
bind:privacyagree="onLoginModalPrivacyAgree"
|
||||
/>
|
||||
|
||||
<!-- 支付中提示 -->
|
||||
<view class="modal-overlay" wx:if="{{isPaying}}" catchtap="">
|
||||
|
||||
@@ -16,7 +16,14 @@
|
||||
* 浏览导师页 → browse_mentor
|
||||
*/
|
||||
|
||||
const app = getApp()
|
||||
function getAppInstance() {
|
||||
try {
|
||||
const a = getApp()
|
||||
return a && a.globalData ? a : null
|
||||
} catch (e) {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
const RULE_COOLDOWN_KEY = 'rule_engine_cooldown'
|
||||
const COOLDOWN_MS = 60 * 1000
|
||||
@@ -60,11 +67,14 @@ function setCooldown(ruleId) {
|
||||
}
|
||||
|
||||
function getUserInfo() {
|
||||
return app.globalData.userInfo || {}
|
||||
const app = getAppInstance()
|
||||
return app ? (app.globalData.userInfo || {}) : {}
|
||||
}
|
||||
|
||||
async function loadRules() {
|
||||
if (_cachedRules && Date.now() - _cacheTs < CACHE_TTL) return _cachedRules
|
||||
const app = getAppInstance()
|
||||
if (!app) return _cachedRules || []
|
||||
try {
|
||||
const res = await app.request({ url: '/api/miniprogram/user-rules', method: 'GET', silent: true })
|
||||
if (res && res.success && res.rules) {
|
||||
@@ -90,7 +100,8 @@ function getRuleInfo(rules, triggerName) {
|
||||
// VIP 用户不触发:统一由 checkVipContactRequiredAndGuide 引导到 profile-edit,避免与主流程冲突
|
||||
function checkRule_FillAvatar(rules) {
|
||||
if (!isRuleEnabled(rules, '注册')) return null
|
||||
if (app.globalData.isVip) return null
|
||||
const app = getAppInstance()
|
||||
if (app && app.globalData.isVip) return null
|
||||
const user = getUserInfo()
|
||||
if (!user.id) return null
|
||||
const avatar = user.avatar || user.avatarUrl || ''
|
||||
@@ -147,7 +158,8 @@ function checkRule_ShareAfter5Chapters(rules) {
|
||||
if (!isRuleEnabled(rules, '累计浏览5章节')) return null
|
||||
const user = getUserInfo()
|
||||
if (!user.id) return null
|
||||
const readCount = (typeof app.getReadCount === 'function' ? app.getReadCount() : (app.globalData.readCount || 0))
|
||||
const app = getAppInstance()
|
||||
const readCount = app ? (typeof app.getReadCount === 'function' ? app.getReadCount() : (app.globalData.readCount || 0)) : 0
|
||||
if (readCount < 5) return null
|
||||
if (isInCooldown('share_after_5')) return null
|
||||
setCooldown('share_after_5')
|
||||
@@ -166,7 +178,8 @@ function checkRule_FillVipInfo(rules) {
|
||||
if (!isRuleEnabled(rules, '完成付款')) return null
|
||||
const user = getUserInfo()
|
||||
if (!user.id) return null
|
||||
if (!(app.globalData.hasFullBook || app.globalData.hasPurchasedFull)) return null
|
||||
const app = getAppInstance()
|
||||
if (!app || !(app.globalData.hasFullBook || app.globalData.hasPurchasedFull)) return null
|
||||
if (user.wechatId && user.address) return null
|
||||
if (isInCooldown('fill_vip_info')) return null
|
||||
setCooldown('fill_vip_info')
|
||||
@@ -218,7 +231,8 @@ function checkRule_Withdraw(rules) {
|
||||
if (!isRuleEnabled(rules, '收益满50元')) return null
|
||||
const user = getUserInfo()
|
||||
if (!user.id) return null
|
||||
const earnings = app.globalData.totalEarnings || 0
|
||||
const app = getAppInstance()
|
||||
const earnings = app ? (app.globalData.totalEarnings || 0) : 0
|
||||
if (earnings < 50) return null
|
||||
if (isInCooldown('withdraw_50')) return null
|
||||
setCooldown('withdraw_50')
|
||||
@@ -280,6 +294,8 @@ function executeRule(rule, pageInstance) {
|
||||
function _trackRuleAction(ruleId, action) {
|
||||
const userId = getUserInfo().id
|
||||
if (!userId) return
|
||||
const app = getAppInstance()
|
||||
if (!app) return
|
||||
app.request({
|
||||
url: '/api/miniprogram/track',
|
||||
method: 'POST',
|
||||
|
||||
Reference in New Issue
Block a user