feat: 代付做完了
This commit is contained in:
@@ -6,58 +6,24 @@
|
||||
const { parseScene } = require('./utils/scene.js')
|
||||
const { checkAndExecute } = require('./utils/ruleEngine.js')
|
||||
|
||||
const PRODUCTION_URL = 'https://soulapi.quwanzhi.com'
|
||||
const TEST_URL = 'https://souldev.quwanzhi.com'
|
||||
const LOCAL_URL = 'http://localhost:8080'
|
||||
const DEFAULT_APP_ID = 'wxb8bbb2b10dec74aa'
|
||||
const DEFAULT_MCH_ID = '1318592501'
|
||||
const DEFAULT_WITHDRAW_TMPL_ID = 'u3MbZGPRkrZIk-I7QdpwzFxnO_CeQPaCWF2FkiIablE'
|
||||
|
||||
function getRuntimeBootstrapConfig() {
|
||||
try {
|
||||
const accountInfo = wx.getAccountInfoSync?.()
|
||||
const envVersion = accountInfo?.miniProgram?.envVersion || 'release'
|
||||
const extCfg = wx.getExtConfigSync ? (wx.getExtConfigSync() || {}) : {}
|
||||
// 按运行环境自动切换 API 地址
|
||||
let baseUrl
|
||||
if (envVersion === 'release') {
|
||||
baseUrl = PRODUCTION_URL
|
||||
} else if (envVersion === 'trial') {
|
||||
baseUrl = extCfg.apiBaseUrl || wx.getStorageSync('apiBaseUrl') || TEST_URL
|
||||
} else {
|
||||
// develop:不使用 storage,避免被 loadMpConfig 曾写入的生产地址污染;env-switch 仍可运行时覆盖
|
||||
baseUrl = extCfg.apiBaseUrl || LOCAL_URL
|
||||
}
|
||||
return {
|
||||
baseUrl,
|
||||
appId: extCfg.appId || DEFAULT_APP_ID,
|
||||
mchId: extCfg.mchId || DEFAULT_MCH_ID,
|
||||
withdrawSubscribeTmplId: extCfg.withdrawSubscribeTmplId || DEFAULT_WITHDRAW_TMPL_ID
|
||||
}
|
||||
} catch (_) {
|
||||
return {
|
||||
baseUrl: PRODUCTION_URL,
|
||||
appId: DEFAULT_APP_ID,
|
||||
mchId: DEFAULT_MCH_ID,
|
||||
withdrawSubscribeTmplId: DEFAULT_WITHDRAW_TMPL_ID
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const bootstrapConfig = getRuntimeBootstrapConfig()
|
||||
|
||||
App({
|
||||
globalData: {
|
||||
// API 基础地址:优先外部配置/缓存,其次默认生产环境
|
||||
baseUrl: bootstrapConfig.baseUrl,
|
||||
// API 基础地址:开发时修改下面一行切换环境
|
||||
baseUrl: "https://soulapi.quwanzhi.com",
|
||||
// baseUrl: 'http://localhost:8080', // 开发
|
||||
// baseUrl: 'https://souldev.quwanzhi.com', // 测试
|
||||
// 小程序配置 - 真实AppID
|
||||
appId: bootstrapConfig.appId,
|
||||
appId: DEFAULT_APP_ID,
|
||||
|
||||
// 订阅消息:用户点击「申请提现」→「立即提现」时会先弹出订阅授权窗
|
||||
withdrawSubscribeTmplId: bootstrapConfig.withdrawSubscribeTmplId,
|
||||
withdrawSubscribeTmplId: DEFAULT_WITHDRAW_TMPL_ID,
|
||||
|
||||
// 微信支付配置
|
||||
mchId: bootstrapConfig.mchId,
|
||||
mchId: DEFAULT_MCH_ID,
|
||||
|
||||
// 用户信息
|
||||
userInfo: null,
|
||||
@@ -110,14 +76,10 @@ App({
|
||||
// 审核模式:后端 /api/miniprogram/config 返回 auditMode=true 时隐藏所有支付相关UI
|
||||
auditMode: false,
|
||||
// 客服/微信:mp_config 返回 supportWechat
|
||||
supportWechat: '',
|
||||
// API 域名:loadMpConfig 从 config 更新
|
||||
apiDomain: ''
|
||||
supportWechat: ''
|
||||
},
|
||||
|
||||
onLaunch(options) {
|
||||
// 清理已废弃的调试环境 storage(取消环境切换后不再使用)
|
||||
try { wx.removeStorageSync('debug_env_override') } catch (_) {}
|
||||
this.globalData.readSectionIds = wx.getStorageSync('readSectionIds') || []
|
||||
// 获取系统信息
|
||||
this.getSystemInfo()
|
||||
@@ -381,7 +343,7 @@ App({
|
||||
}
|
||||
},
|
||||
|
||||
// 加载 mpConfig(appId、mchId、withdrawSubscribeTmplId、auditMode、supportWechat、apiDomain 等),失败时保留 globalData 默认值
|
||||
// 加载 mpConfig(appId、mchId、withdrawSubscribeTmplId、auditMode、supportWechat 等),失败时保留 globalData 默认值
|
||||
async loadMpConfig() {
|
||||
try {
|
||||
const res = await this.request({ url: '/api/miniprogram/config', silent: true, timeout: 5000 })
|
||||
@@ -390,15 +352,6 @@ App({
|
||||
if (mp.appId) this.globalData.appId = mp.appId
|
||||
if (mp.mchId) this.globalData.mchId = mp.mchId
|
||||
if (mp.withdrawSubscribeTmplId) this.globalData.withdrawSubscribeTmplId = mp.withdrawSubscribeTmplId
|
||||
// 仅正式版使用后端 apiDomain;开发/体验版保持 bootstrap 的 baseUrl,避免被生产地址覆盖
|
||||
try {
|
||||
const envVersion = wx.getAccountInfoSync?.()?.miniProgram?.envVersion || 'release'
|
||||
if (envVersion === 'release' && mp.apiDomain) {
|
||||
this.globalData.baseUrl = mp.apiDomain
|
||||
this.globalData.apiDomain = mp.apiDomain
|
||||
try { wx.setStorageSync('apiBaseUrl', mp.apiDomain) } catch (_) {}
|
||||
}
|
||||
} catch (_) {}
|
||||
this.globalData.auditMode = !!mp.auditMode
|
||||
this.globalData.supportWechat = mp.supportWechat || mp.customerWechat || mp.serviceWechat || ''
|
||||
// 通知当前已加载的页面刷新 auditMode(从后台切回时配置更新后立即生效)
|
||||
|
||||
@@ -24,7 +24,8 @@
|
||||
"pages/profile-edit/profile-edit",
|
||||
"pages/avatar-nickname/avatar-nickname",
|
||||
"pages/gift-pay/detail",
|
||||
"pages/gift-pay/list"
|
||||
"pages/gift-pay/list",
|
||||
"pages/gift-pay/redemption-detail"
|
||||
],
|
||||
"window": {
|
||||
"backgroundTextStyle": "light",
|
||||
@@ -59,9 +60,6 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"usingComponents": {
|
||||
"env-switch": "/components/env-switch/env-switch"
|
||||
},
|
||||
"navigateToMiniProgramAppIdList": [
|
||||
"wx6489c26045912fe1",
|
||||
"wx3d15ed02e98b04e3"
|
||||
|
||||
@@ -83,7 +83,6 @@
|
||||
<text class="section-lock {{section.isFree || isVip || (!section.isPremium && hasFullBook) || purchasedSections.indexOf(section.id) > -1 ? 'lock-open' : 'lock-closed'}}">{{section.isFree || isVip || (!section.isPremium && hasFullBook) || purchasedSections.indexOf(section.id) > -1 ? '○' : '●'}}</text>
|
||||
<text class="section-title {{section.isFree || isVip || (!section.isPremium && hasFullBook) || purchasedSections.indexOf(section.id) > -1 ? '' : 'text-muted'}}">{{section.id}} {{section.title}}</text>
|
||||
<text wx:if="{{section.isNew}}" class="tag tag-new">NEW</text>
|
||||
<text wx:if="{{section.isPremium}}" class="tag tag-vip">增值</text>
|
||||
</view>
|
||||
<view class="section-right">
|
||||
<text wx:if="{{section.isFree}}" class="tag tag-free">免费</text>
|
||||
@@ -133,5 +132,4 @@
|
||||
|
||||
<!-- 底部留白 -->
|
||||
<view class="bottom-space"></view>
|
||||
<env-switch />
|
||||
</view>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Soul创业派对 - 代付详情页
|
||||
* 好友打开后看到订单信息,点击「帮他付款」完成代付
|
||||
* 改造后:发起人支付,好友领取。支持单页模式引导、登录检测。
|
||||
*/
|
||||
const app = getApp()
|
||||
|
||||
@@ -8,42 +8,81 @@ Page({
|
||||
data: {
|
||||
statusBarHeight: 44,
|
||||
requestSn: '',
|
||||
sectionId: '',
|
||||
detail: null,
|
||||
loading: true,
|
||||
paying: false,
|
||||
redeeming: false,
|
||||
isInitiator: false,
|
||||
requesterMsg: '',
|
||||
amountDisplay: '0.00' // 预格式化金额,WXML 中 toFixed 可能不生效
|
||||
amountDisplay: '0.00',
|
||||
isSinglePageMode: false,
|
||||
showLoginModal: false,
|
||||
agreeProtocol: false,
|
||||
// 创建态
|
||||
isCreateMode: false,
|
||||
giftQuantity: 1,
|
||||
unitPrice: 0
|
||||
},
|
||||
|
||||
onLoad(options) {
|
||||
wx.showShareMenu({ menus: ['shareAppMessage', 'shareTimeline'] })
|
||||
this.setData({ statusBarHeight: app.globalData.statusBarHeight || 44 })
|
||||
const requestSn = (options.requestSn || '').trim()
|
||||
if (!requestSn) {
|
||||
wx.showToast({ title: '代付链接无效', icon: 'none' })
|
||||
const sectionId = (options.sectionId || '').trim()
|
||||
const isSinglePage = (wx.getSystemInfoSync?.()?.mode === 'singlePage') || app.globalData.isSinglePageMode
|
||||
this.setData({ requestSn, sectionId, isSinglePageMode: !!isSinglePage })
|
||||
if (requestSn || sectionId) {
|
||||
this.loadDetail()
|
||||
} else {
|
||||
wx.showToast({ title: '链接无效', icon: 'none' })
|
||||
setTimeout(() => wx.switchTab({ url: '/pages/index/index' }), 1500)
|
||||
return
|
||||
}
|
||||
this.setData({ requestSn })
|
||||
this.loadDetail()
|
||||
},
|
||||
|
||||
async loadDetail() {
|
||||
const { requestSn } = this.data
|
||||
if (!requestSn) return
|
||||
const { requestSn, sectionId } = this.data
|
||||
this.setData({ loading: true })
|
||||
const userId = app.globalData.userInfo?.id || ''
|
||||
let url = ''
|
||||
if (requestSn) {
|
||||
url = `/api/miniprogram/gift-pay/detail?requestSn=${encodeURIComponent(requestSn)}${userId ? '&userId=' + encodeURIComponent(userId) : ''}`
|
||||
} else if (sectionId && userId) {
|
||||
url = `/api/miniprogram/gift-pay/detail?sectionId=${encodeURIComponent(sectionId)}&userId=${encodeURIComponent(userId)}`
|
||||
} else if (sectionId) {
|
||||
this.setData({ loading: false })
|
||||
wx.showToast({ title: '请先登录', icon: 'none' })
|
||||
return
|
||||
} else {
|
||||
this.setData({ loading: false })
|
||||
return
|
||||
}
|
||||
try {
|
||||
const res = await app.request(`/api/miniprogram/gift-pay/detail?requestSn=${encodeURIComponent(requestSn)}`)
|
||||
const res = await app.request(url)
|
||||
if (res && res.success) {
|
||||
const myId = app.globalData.userInfo?.id || ''
|
||||
const isInitiator = !!myId && res.initiatorUserId === myId
|
||||
const requesterMsg = isInitiator
|
||||
? '分享给好友,好友打开后即可为你完成支付。'
|
||||
: (res.initiatorMsg || `" 请帮我代付「${res.sectionTitle || res.description || '该商品'}」,非常感谢! "`)
|
||||
const amountDisplay = (res.amount != null && res.amount !== '')
|
||||
? Number(res.amount).toFixed(2)
|
||||
: '0.00'
|
||||
this.setData({ detail: res, loading: false, isInitiator, requesterMsg, amountDisplay })
|
||||
const isCreateMode = res.mode === 'create' || res.action === 'create'
|
||||
const isInitiator = res.isInitiator === true
|
||||
let requesterMsg = ''
|
||||
let amountDisplay = '0.00'
|
||||
if (isCreateMode) {
|
||||
requesterMsg = '输入发放数量,支付后分享给好友免费领取'
|
||||
amountDisplay = (res.unitPrice != null ? Number(res.unitPrice) * (this.data.giftQuantity || 1) : 0).toFixed(2)
|
||||
} else {
|
||||
requesterMsg = isInitiator
|
||||
? (res.action === 'pay' ? '支付后分享给好友,好友打开即可免费领取。' : '分享给好友,好友打开即可免费领取。')
|
||||
: res.initiatorMsg || `" 请帮我代付「${res.sectionTitle || res.description || '该商品'}」,非常感谢! "`
|
||||
amountDisplay = (res.amount != null && res.amount !== '') ? Number(res.amount).toFixed(2) : '0.00'
|
||||
}
|
||||
this.setData({
|
||||
detail: res,
|
||||
loading: false,
|
||||
isInitiator,
|
||||
isCreateMode,
|
||||
requesterMsg,
|
||||
amountDisplay,
|
||||
unitPrice: res.unitPrice != null ? res.unitPrice : 0
|
||||
})
|
||||
if (isCreateMode) this._updateAmountDisplay()
|
||||
} else {
|
||||
this.setData({ loading: false })
|
||||
wx.showToast({ title: res?.error || '加载失败', icon: 'none' })
|
||||
@@ -54,8 +93,34 @@ Page({
|
||||
}
|
||||
},
|
||||
|
||||
async doPay() {
|
||||
// 优先尝试静默获取 openId(有会话时可直接发起支付)
|
||||
onGiftQuantityInput(e) {
|
||||
const raw = (e.detail.value || '').trim()
|
||||
const v = parseInt(raw, 10)
|
||||
this.setData({ giftQuantity: isNaN(v) ? (raw === '' ? '' : this.data.giftQuantity) : v })
|
||||
this._updateAmountDisplay()
|
||||
},
|
||||
_updateAmountDisplay() {
|
||||
const { unitPrice, giftQuantity } = this.data
|
||||
const q = Math.max(0, parseInt(giftQuantity, 10) || 0)
|
||||
const amount = (unitPrice || 0) * q
|
||||
this.setData({ amountDisplay: amount.toFixed(2) })
|
||||
},
|
||||
|
||||
// 发起人支付(改造后:我帮别人付款)
|
||||
async doInitiatorPay() {
|
||||
if (this.data.isSinglePageMode) {
|
||||
wx.showModal({
|
||||
title: '朋友圈单页',
|
||||
content: '当前为朋友圈单页,无法支付。请点击底部「前往小程序」进入完整版后再支付。',
|
||||
showCancel: false
|
||||
})
|
||||
return
|
||||
}
|
||||
const userId = app.globalData.userInfo?.id || ''
|
||||
if (!userId) {
|
||||
wx.showToast({ title: '请先登录后再支付', icon: 'none' })
|
||||
return
|
||||
}
|
||||
let openId = app.globalData.openId || wx.getStorageSync('openId')
|
||||
if (!openId) {
|
||||
wx.showLoading({ title: '获取支付凭证...', mask: true })
|
||||
@@ -63,31 +128,47 @@ Page({
|
||||
wx.hideLoading()
|
||||
}
|
||||
if (!openId) {
|
||||
const { confirm } = await new Promise(r => {
|
||||
wx.showModal({
|
||||
title: '请先登录',
|
||||
content: '登录后可帮他完成代付',
|
||||
confirmText: '去登录',
|
||||
cancelText: '取消',
|
||||
success: res => r(res)
|
||||
})
|
||||
})
|
||||
if (confirm) wx.switchTab({ url: '/pages/my/my' })
|
||||
wx.showToast({ title: '请先登录', icon: 'none' })
|
||||
return
|
||||
}
|
||||
const { requestSn, detail } = this.data
|
||||
if (!requestSn || !detail) return
|
||||
let { requestSn, sectionId, detail, giftQuantity, isCreateMode } = this.data
|
||||
if (!requestSn && isCreateMode && sectionId) {
|
||||
const q = parseInt(giftQuantity, 10)
|
||||
if (isNaN(q) || q !== Math.floor(q) || q < 1) {
|
||||
wx.showToast({ title: '发放份数须为正整数', icon: 'none' })
|
||||
return
|
||||
}
|
||||
const quantity = q
|
||||
wx.showLoading({ title: '创建中...', mask: true })
|
||||
try {
|
||||
const createRes = await app.request({
|
||||
url: '/api/miniprogram/gift-pay/create',
|
||||
method: 'POST',
|
||||
data: { userId, productType: 'section', productId: sectionId, quantity }
|
||||
})
|
||||
if (!createRes?.success || !createRes.requestSn) {
|
||||
throw new Error(createRes?.error || '创建失败')
|
||||
}
|
||||
requestSn = createRes.requestSn
|
||||
this.setData({ requestSn, isCreateMode: false })
|
||||
} catch (e) {
|
||||
wx.hideLoading()
|
||||
wx.showToast({ title: e.message || e.error || '创建失败', icon: 'none' })
|
||||
return
|
||||
}
|
||||
}
|
||||
if (!requestSn) return
|
||||
|
||||
this.setData({ paying: true })
|
||||
wx.showLoading({ title: '创建订单中...', mask: true })
|
||||
try {
|
||||
const res = await app.request({
|
||||
url: '/api/miniprogram/gift-pay/pay',
|
||||
url: '/api/miniprogram/gift-pay/initiator-pay',
|
||||
method: 'POST',
|
||||
data: {
|
||||
requestSn,
|
||||
openId,
|
||||
userId: app.globalData.userInfo?.id || ''
|
||||
userId
|
||||
}
|
||||
})
|
||||
wx.hideLoading()
|
||||
@@ -95,47 +176,131 @@ Page({
|
||||
throw new Error(res?.error || '创建订单失败')
|
||||
}
|
||||
const payParams = res.data.payParams
|
||||
payParams._orderSn = res.data.orderSn
|
||||
|
||||
const orderSn = res.data.orderSn
|
||||
// 与正常章节支付一致:只传 5 个必需参数,不传 appId 等多余字段
|
||||
await new Promise((resolve, reject) => {
|
||||
wx.requestPayment({
|
||||
...payParams,
|
||||
signType: payParams.signType || 'MD5',
|
||||
timeStamp: payParams.timeStamp,
|
||||
nonceStr: payParams.nonceStr,
|
||||
package: payParams.package,
|
||||
signType: payParams.signType || 'RSA',
|
||||
paySign: payParams.paySign,
|
||||
success: resolve,
|
||||
fail: reject
|
||||
})
|
||||
})
|
||||
|
||||
wx.showToast({ title: '代付成功', icon: 'success' })
|
||||
wx.showToast({ title: '支付成功', icon: 'success' })
|
||||
this.setData({ paying: false })
|
||||
setTimeout(() => {
|
||||
wx.navigateBack({ fail: () => wx.switchTab({ url: '/pages/index/index' }) })
|
||||
}, 1500)
|
||||
// 主动同步订单状态(与 read 页一致)
|
||||
if (orderSn) {
|
||||
try {
|
||||
await app.request(`/api/miniprogram/pay?orderSn=${encodeURIComponent(orderSn)}`, { silent: true })
|
||||
} catch (e) {
|
||||
console.warn('[GiftPay] 主动同步订单失败:', e)
|
||||
}
|
||||
}
|
||||
this.loadDetail()
|
||||
} catch (e) {
|
||||
this.setData({ paying: false })
|
||||
const msg = e.message || e.error || e.errMsg || '支付失败'
|
||||
if (e.errMsg && e.errMsg.includes('cancel')) {
|
||||
wx.showToast({ title: '已取消支付', icon: 'none' })
|
||||
} else {
|
||||
const errMsg = e.message || e.error || '支付失败'
|
||||
const isPrepayError = /prepay_id|创建订单|支付请求/i.test(errMsg)
|
||||
if (isPrepayError) {
|
||||
const { confirm } = await new Promise(r => {
|
||||
wx.showModal({
|
||||
title: '订单创建失败',
|
||||
content: errMsg + '\n\n是否重新创建订单并重试?',
|
||||
confirmText: '重新创建订单',
|
||||
cancelText: '取消',
|
||||
success: res => r(res)
|
||||
})
|
||||
})
|
||||
if (confirm) this.doPay()
|
||||
} else {
|
||||
wx.showToast({ title: errMsg, icon: 'none' })
|
||||
}
|
||||
wx.showToast({ title: msg, icon: 'none', duration: 2500 })
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// 好友领取(改造后:免费获得章节)
|
||||
async doRedeem() {
|
||||
if (this.data.isSinglePageMode) {
|
||||
wx.showModal({
|
||||
title: '朋友圈单页',
|
||||
content: '当前为朋友圈单页,无法登录领取。请点击底部「前往小程序」进入完整版后再领取。',
|
||||
showCancel: false
|
||||
})
|
||||
return
|
||||
}
|
||||
const userId = app.globalData.userInfo?.id
|
||||
if (!userId) {
|
||||
this.setData({ showLoginModal: true, agreeProtocol: false })
|
||||
return
|
||||
}
|
||||
await this._doRedeem()
|
||||
},
|
||||
|
||||
async _doRedeem() {
|
||||
const { requestSn } = this.data
|
||||
const userId = app.globalData.userInfo?.id
|
||||
if (!requestSn || !userId) return
|
||||
|
||||
this.setData({ redeeming: true })
|
||||
wx.showLoading({ title: '领取中...', mask: true })
|
||||
try {
|
||||
const res = await app.request({
|
||||
url: '/api/miniprogram/gift-pay/redeem',
|
||||
method: 'POST',
|
||||
data: { requestSn, userId }
|
||||
})
|
||||
wx.hideLoading()
|
||||
this.setData({ redeeming: false })
|
||||
if (res && res.success) {
|
||||
wx.showToast({ title: '领取成功', icon: 'success' })
|
||||
const mid = res.sectionMid || res.sectionId
|
||||
const q = mid ? `mid=${mid}` : `id=${res.sectionId || ''}`
|
||||
setTimeout(() => {
|
||||
wx.navigateTo({ url: `/pages/read/read?${q}` })
|
||||
}, 800)
|
||||
} else {
|
||||
wx.showToast({ title: res?.error || '领取失败', icon: 'none' })
|
||||
}
|
||||
} catch (e) {
|
||||
this.setData({ redeeming: false })
|
||||
wx.hideLoading()
|
||||
wx.showToast({ title: e.message || e.error || '领取失败', icon: 'none' })
|
||||
}
|
||||
},
|
||||
|
||||
closeLoginModal() {
|
||||
this.setData({ showLoginModal: 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' })
|
||||
}
|
||||
},
|
||||
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' })
|
||||
},
|
||||
|
||||
goBack() {
|
||||
app.goBackOrToHome()
|
||||
},
|
||||
@@ -156,9 +321,29 @@ Page({
|
||||
|
||||
onShareAppMessage() {
|
||||
const { requestSn } = this.data
|
||||
const ref = app.getMyReferralCode?.() || app.globalData.userInfo?.referralCode || ''
|
||||
let path = '/pages/gift-pay/detail'
|
||||
if (requestSn) {
|
||||
path = `/pages/gift-pay/detail?requestSn=${requestSn}`
|
||||
if (ref) path += `&ref=${encodeURIComponent(ref)}`
|
||||
}
|
||||
return {
|
||||
title: '好友请你帮忙代付 - Soul创业派对',
|
||||
path: requestSn ? `/pages/gift-pay/detail?requestSn=${requestSn}` : '/pages/gift-pay/detail'
|
||||
title: '好友送你一篇好文 - Soul创业派对',
|
||||
path
|
||||
}
|
||||
},
|
||||
|
||||
onShareTimeline() {
|
||||
const { requestSn } = this.data
|
||||
const ref = app.getMyReferralCode?.() || app.globalData.userInfo?.referralCode || ''
|
||||
let query = ''
|
||||
if (requestSn) {
|
||||
query = `requestSn=${requestSn}`
|
||||
if (ref) query += `&ref=${encodeURIComponent(ref)}`
|
||||
}
|
||||
return {
|
||||
title: '好友送你一篇好文 - Soul创业派对',
|
||||
query: query || ''
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<!-- Soul创业派对 - 代付详情页(参考 yulan:代付视角+发起视角,忽略 nav) -->
|
||||
<!-- Soul创业派对 - 代付详情页(改造后:发起人支付,好友领取) -->
|
||||
<view class="page">
|
||||
<view class="nav-bar" style="padding-top: {{statusBarHeight}}px;">
|
||||
<view class="nav-content">
|
||||
@@ -6,7 +6,7 @@
|
||||
<text class="back-arrow">←</text>
|
||||
</view>
|
||||
<view class="nav-info">
|
||||
<text class="nav-title">{{isInitiator ? '找朋友代付' : '帮他付款'}}</text>
|
||||
<text class="nav-title">{{isInitiator ? '代付分享' : (detail.action === 'redeem' ? '免费领取' : '代付详情')}}</text>
|
||||
</view>
|
||||
<view class="nav-right-placeholder"></view>
|
||||
</view>
|
||||
@@ -31,23 +31,35 @@
|
||||
<text class="hero-title">{{detail.sectionTitle || detail.description || '代付商品'}}</text>
|
||||
<text class="hero-desc" wx:if="{{detail.contentPreview}}">{{detail.contentPreview}}</text>
|
||||
<view class="hero-footer">
|
||||
<view class="hero-amount-wrap">
|
||||
<text class="hero-amount-label">应付金额</text>
|
||||
<view class="hero-amount-wrap" wx:if="{{!isCreateMode}}">
|
||||
<text class="hero-amount-label">{{detail.quantity > 1 ? '应付金额(' + detail.quantity + '份)' : '应付金额'}}</text>
|
||||
<view class="hero-amount-row">
|
||||
<text class="hero-currency">¥</text>
|
||||
<text class="hero-amount">{{amountDisplay}}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="hero-arrow-wrap" bindtap="goToArticle" wx:if="{{detail.productType === 'section' && detail.productId}}">
|
||||
<view class="hero-amount-wrap" wx:elif="{{isCreateMode}}">
|
||||
<text class="hero-amount-label">发放份数</text>
|
||||
<view class="gift-quantity-row">
|
||||
<input class="gift-quantity-input" type="number" value="{{giftQuantity}}" bindinput="onGiftQuantityInput" placeholder="请输入份数"/>
|
||||
<text class="hero-amount-label">份 × ¥{{detail.unitPrice || 0}}</text>
|
||||
</view>
|
||||
<view class="hero-amount-row">
|
||||
<text class="hero-currency">¥</text>
|
||||
<text class="hero-amount">{{amountDisplay}}</text>
|
||||
</view>
|
||||
<view class="create-tip">创建后无法退款</view>
|
||||
</view>
|
||||
<view class="hero-arrow-wrap" bindtap="goToArticle" wx:if="{{!isCreateMode && !isInitiator && detail.productType === 'section' && detail.productId}}">
|
||||
<image class="hero-arrow" src="/assets/icons/arrow-right.svg" mode="aspectFit"/>
|
||||
</view>
|
||||
<view class="hero-arrow-wrap hero-arrow-placeholder" wx:else></view>
|
||||
<view class="hero-arrow-wrap hero-arrow-placeholder" wx:elif="{{!isCreateMode && !isInitiator}}"></view>
|
||||
</view>
|
||||
</view>
|
||||
</section>
|
||||
|
||||
<!-- 发起人信息 -->
|
||||
<section class="requester-card">
|
||||
<!-- 发起人信息(发起人视角不展示) -->
|
||||
<section class="requester-card" wx:if="{{!isCreateMode && !isInitiator}}">
|
||||
<view class="requester-header" bindtap="goToInitiatorProfile">
|
||||
<view class="requester-avatar">
|
||||
<image wx:if="{{detail.initiatorAvatar}}" class="avatar-img" src="{{detail.initiatorAvatar}}" mode="aspectFill"/>
|
||||
@@ -64,8 +76,8 @@
|
||||
</view>
|
||||
</section>
|
||||
|
||||
<!-- 安全徽章 -->
|
||||
<view class="security-badge">
|
||||
<!-- 安全徽章(发起人视角不展示) -->
|
||||
<view class="security-badge" wx:if="{{!isCreateMode && !isInitiator}}">
|
||||
<text class="security-icon">🛡</text>
|
||||
<text class="security-text">安全支付保障 · 资金由平台托管</text>
|
||||
</view>
|
||||
@@ -87,16 +99,55 @@
|
||||
<text class="footer-currency">¥</text>{{amountDisplay}}
|
||||
</text>
|
||||
</view>
|
||||
<!-- 发起人:分享给好友 -->
|
||||
<button wx:if="{{isInitiator}}" class="footer-btn share-btn" open-type="share">
|
||||
<!-- 单页模式:引导前往小程序 -->
|
||||
<view wx:if="{{isSinglePageMode}}" class="footer-tip-single">
|
||||
<text>请点击底部「前往小程序」进入完整版后再操作</text>
|
||||
</view>
|
||||
<!-- 发起人 创建态 或 action=pay:去支付 -->
|
||||
<button wx:elif="{{(isCreateMode || (isInitiator && detail.action === 'pay'))}}" class="footer-btn pay-btn" bindtap="doInitiatorPay" disabled="{{paying}}">
|
||||
<image class="btn-icon" src="/assets/icons/wallet.svg" mode="aspectFit"/>
|
||||
<text>{{paying ? '支付中...' : (isCreateMode ? '去支付' : '立即支付')}}</text>
|
||||
</button>
|
||||
<!-- 发起人 action=share:发送给好友 -->
|
||||
<button wx:elif="{{isInitiator && detail.action === 'share'}}" class="footer-btn share-btn" open-type="share">
|
||||
<image class="btn-icon" src="/assets/icons/share.svg" mode="aspectFit"/>
|
||||
<text>发送给好友</text>
|
||||
</button>
|
||||
<!-- 好友:帮他付款 -->
|
||||
<button wx:else class="footer-btn pay-btn" bindtap="doPay" disabled="{{paying}}">
|
||||
<image class="btn-icon" src="/assets/icons/wallet.svg" mode="aspectFit"/>
|
||||
<text>{{paying ? '支付中...' : '立即帮他付款'}}</text>
|
||||
<!-- 好友 action=redeem:领取并阅读 -->
|
||||
<button wx:elif="{{!isInitiator && detail.action === 'redeem'}}" class="footer-btn redeem-btn" bindtap="doRedeem" disabled="{{redeeming}}">
|
||||
<image class="btn-icon" src="/assets/icons/arrow-right.svg" mode="aspectFit"/>
|
||||
<text>{{redeeming ? '领取中...' : '领取并阅读'}}</text>
|
||||
</button>
|
||||
<!-- 好友 action=alreadyRedeemed:已领取,去阅读 -->
|
||||
<button wx:elif="{{!isInitiator && detail.action === 'alreadyRedeemed'}}" class="footer-btn redeem-btn" bindtap="goToArticle">
|
||||
<image class="btn-icon" src="/assets/icons/arrow-right.svg" mode="aspectFit"/>
|
||||
<text>已领取,去阅读</text>
|
||||
</button>
|
||||
<!-- 好友 action=wait:待发起人支付 -->
|
||||
<view wx:else class="footer-btn footer-btn-disabled">
|
||||
<text>待发起人支付</text>
|
||||
</view>
|
||||
</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">✕</view>
|
||||
<view class="login-icon">🔐</view>
|
||||
<text class="login-title">登录 Soul创业派对</text>
|
||||
<text class="login-desc">登录后可免费领取并阅读</text>
|
||||
<button class="btn-wechat {{agreeProtocol ? '' : 'btn-wechat-disabled'}}" bindtap="handleWechatLogin" disabled="{{!agreeProtocol}}">
|
||||
<text class="btn-wechat-icon">微</text>
|
||||
<text>微信快捷登录</text>
|
||||
</button>
|
||||
<view class="login-agree-row" catchtap="toggleAgree">
|
||||
<view class="agree-checkbox {{agreeProtocol ? 'agree-checked' : ''}}">{{agreeProtocol ? '✓' : ''}}</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>
|
||||
|
||||
@@ -106,5 +157,4 @@
|
||||
<view class="bg-glow bg-glow-2"></view>
|
||||
<view class="bg-dots"></view>
|
||||
</view>
|
||||
<env-switch />
|
||||
</view>
|
||||
|
||||
@@ -186,6 +186,32 @@
|
||||
gap: 4rpx;
|
||||
}
|
||||
|
||||
.gift-quantity-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16rpx;
|
||||
margin: 12rpx 0;
|
||||
}
|
||||
|
||||
.create-tip {
|
||||
margin-top: 16rpx;
|
||||
font-size: 24rpx;
|
||||
color: rgba(255, 255, 255, 0.45);
|
||||
}
|
||||
|
||||
.gift-quantity-input {
|
||||
width: 120rpx;
|
||||
height: 64rpx;
|
||||
padding: 0 20rpx;
|
||||
background: rgba(255, 255, 255, 0.06);
|
||||
border: 1rpx solid rgba(255, 255, 255, 0.1);
|
||||
border-radius: 12rpx;
|
||||
font-size: 32rpx;
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.hero-currency {
|
||||
font-size: 36rpx;
|
||||
font-weight: 700;
|
||||
@@ -420,6 +446,29 @@
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.redeem-btn {
|
||||
background: #14b8a6;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.redeem-btn[disabled] {
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.footer-tip-single {
|
||||
flex: 1;
|
||||
font-size: 24rpx;
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
text-align: center;
|
||||
padding: 0 24rpx;
|
||||
}
|
||||
|
||||
.footer-btn-disabled {
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.footer-btn:active {
|
||||
transform: scale(0.98);
|
||||
}
|
||||
@@ -430,7 +479,8 @@
|
||||
}
|
||||
|
||||
.share-btn .btn-icon,
|
||||
.pay-btn .btn-icon {
|
||||
.pay-btn .btn-icon,
|
||||
.redeem-btn .btn-icon {
|
||||
filter: brightness(0);
|
||||
}
|
||||
|
||||
@@ -479,3 +529,68 @@
|
||||
background-image: radial-gradient(rgba(255,255,255,0.02) 1rpx, transparent 1rpx);
|
||||
background-size: 64rpx 64rpx;
|
||||
}
|
||||
|
||||
/* 登录弹窗 */
|
||||
.modal-overlay {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
background: rgba(0, 0, 0, 0.7);
|
||||
z-index: 1000;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 48rpx;
|
||||
}
|
||||
.modal-content.login-modal {
|
||||
width: 100%;
|
||||
max-width: 600rpx;
|
||||
background: #1c1c1e;
|
||||
border-radius: 32rpx;
|
||||
padding: 48rpx;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
}
|
||||
.modal-close {
|
||||
position: absolute;
|
||||
top: 24rpx;
|
||||
right: 24rpx;
|
||||
font-size: 32rpx;
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
.login-icon { font-size: 96rpx; display: block; margin-bottom: 24rpx; }
|
||||
.login-title { font-size: 36rpx; font-weight: 700; color: #fff; display: block; margin-bottom: 16rpx; }
|
||||
.login-desc { font-size: 26rpx; color: rgba(255, 255, 255, 0.6); display: block; margin-bottom: 48rpx; }
|
||||
.btn-wechat {
|
||||
width: 100%;
|
||||
padding: 28rpx;
|
||||
background: #07c160;
|
||||
color: #fff;
|
||||
font-size: 30rpx;
|
||||
font-weight: 600;
|
||||
border-radius: 24rpx;
|
||||
border: none;
|
||||
}
|
||||
.btn-wechat-disabled { opacity: 0.5; }
|
||||
.btn-wechat-icon { font-weight: 700; margin-right: 8rpx; }
|
||||
.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.3);
|
||||
border-radius: 8rpx;
|
||||
margin-right: 12rpx;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
.agree-checked { background: #14b8a6; border-color: #14b8a6; }
|
||||
.agree-link { color: #14b8a6; }
|
||||
|
||||
@@ -1,15 +1,12 @@
|
||||
/**
|
||||
* Soul创业派对 - 我的代付
|
||||
* Tab: 我发起的 / 我帮付的
|
||||
* Soul创业派对 - 我发起的代付(改造后:仅我发起的,含领取记录)
|
||||
*/
|
||||
const app = getApp()
|
||||
|
||||
Page({
|
||||
data: {
|
||||
statusBarHeight: 44,
|
||||
tab: 'requests',
|
||||
requests: [],
|
||||
payments: [],
|
||||
loading: false
|
||||
},
|
||||
|
||||
@@ -19,17 +16,11 @@ Page({
|
||||
},
|
||||
|
||||
onShow() {
|
||||
if (this.data.requests.length > 0 || this.data.payments.length > 0) {
|
||||
if (this.data.requests.length > 0) {
|
||||
this.loadData()
|
||||
}
|
||||
},
|
||||
|
||||
switchTab(e) {
|
||||
const tab = e.currentTarget.dataset.tab || 'requests'
|
||||
this.setData({ tab })
|
||||
this.loadData()
|
||||
},
|
||||
|
||||
async loadData() {
|
||||
const userId = app.globalData.userInfo?.id || ''
|
||||
if (!userId) {
|
||||
@@ -38,13 +29,8 @@ Page({
|
||||
}
|
||||
this.setData({ loading: true })
|
||||
try {
|
||||
if (this.data.tab === 'requests') {
|
||||
const res = await app.request(`/api/miniprogram/gift-pay/my-requests?userId=${encodeURIComponent(userId)}`)
|
||||
this.setData({ requests: (res && res.list) || [], loading: false })
|
||||
} else {
|
||||
const res = await app.request(`/api/miniprogram/gift-pay/my-payments?userId=${encodeURIComponent(userId)}`)
|
||||
this.setData({ payments: (res && res.list) || [], loading: false })
|
||||
}
|
||||
const res = await app.request(`/api/miniprogram/gift-pay/my-requests?userId=${encodeURIComponent(userId)}`)
|
||||
this.setData({ requests: (res && res.list) || [], loading: false })
|
||||
} catch (e) {
|
||||
this.setData({ loading: false })
|
||||
}
|
||||
@@ -53,18 +39,21 @@ Page({
|
||||
goToDetail(e) {
|
||||
const requestSn = e.currentTarget.dataset.sn
|
||||
if (requestSn) {
|
||||
wx.navigateTo({ url: `/pages/gift-pay/detail?requestSn=${encodeURIComponent(requestSn)}` })
|
||||
wx.navigateTo({ url: `/pages/gift-pay/redemption-detail?requestSn=${encodeURIComponent(requestSn)}` })
|
||||
}
|
||||
},
|
||||
|
||||
shareRequest(e) {
|
||||
e.stopPropagation()
|
||||
wx.showToast({ title: '请点击右上角「...」分享给好友', icon: 'none', duration: 2500 })
|
||||
if (e && typeof e.stopPropagation === 'function') e.stopPropagation()
|
||||
const requestSn = e?.currentTarget?.dataset?.sn
|
||||
if (requestSn) {
|
||||
wx.navigateTo({ url: `/pages/gift-pay/detail?requestSn=${encodeURIComponent(requestSn)}` })
|
||||
}
|
||||
},
|
||||
|
||||
async cancelRequest(e) {
|
||||
e.stopPropagation()
|
||||
const requestSn = e.currentTarget.dataset.sn
|
||||
if (e && typeof e.stopPropagation === 'function') e.stopPropagation()
|
||||
const requestSn = e?.currentTarget?.dataset?.sn
|
||||
if (!requestSn) return
|
||||
const ok = await new Promise(r => {
|
||||
wx.showModal({ title: '取消代付', content: '确定取消该代付请求?', success: res => r(res.confirm) })
|
||||
@@ -78,7 +67,8 @@ Page({
|
||||
})
|
||||
if (res && res.success) {
|
||||
wx.showToast({ title: '已取消', icon: 'success' })
|
||||
this.loadData()
|
||||
const requests = (this.data.requests || []).filter(r => r.requestSn !== requestSn)
|
||||
this.setData({ requests })
|
||||
} else {
|
||||
wx.showToast({ title: res?.error || '取消失败', icon: 'none' })
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<!-- Soul创业派对 - 我的代付 -->
|
||||
<!-- Soul创业派对 - 我的代付(改造后:仅我发起的,含领取记录) -->
|
||||
<view class="page">
|
||||
<view class="nav-bar" style="padding-top: {{statusBarHeight}}px;">
|
||||
<view class="nav-content">
|
||||
@@ -6,59 +6,47 @@
|
||||
<text class="back-arrow">←</text>
|
||||
</view>
|
||||
<view class="nav-info">
|
||||
<text class="nav-title">我的代付</text>
|
||||
<text class="nav-title">我发起的代付</text>
|
||||
</view>
|
||||
<view class="nav-right-placeholder"></view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="tabs" style="padding-top: calc({{statusBarHeight}}px + 88rpx);">
|
||||
<view class="tab {{tab === 'requests' ? 'active' : ''}}" data-tab="requests" bindtap="switchTab">我发起的</view>
|
||||
<view class="tab {{tab === 'payments' ? 'active' : ''}}" data-tab="payments" bindtap="switchTab">我帮付的</view>
|
||||
</view>
|
||||
|
||||
<view class="content">
|
||||
<view class="content" style="padding-top: calc({{statusBarHeight}}px + 88rpx);">
|
||||
<block wx:if="{{loading}}">
|
||||
<view class="loading-box">
|
||||
<view class="loading-spinner"></view>
|
||||
<text class="loading-text">加载中...</text>
|
||||
</view>
|
||||
</block>
|
||||
<block wx:elif="{{tab === 'requests'}}">
|
||||
<block wx:if="{{requests.length === 0}}">
|
||||
<view class="empty">暂无发起的代付</view>
|
||||
</block>
|
||||
<block wx:else>
|
||||
<view class="card" wx:for="{{requests}}" wx:key="requestSn" bindtap="goToDetail" data-sn="{{item.requestSn}}">
|
||||
<view class="card-row">
|
||||
<text class="desc">{{item.description}}</text>
|
||||
<text class="amount">¥{{item.amount}}</text>
|
||||
</view>
|
||||
<view class="card-row">
|
||||
<text class="status {{item.status}}">{{item.status === 'pending' ? '待支付' : item.status === 'paid' ? '已支付' : item.status === 'cancelled' ? '已取消' : '已过期'}}</text>
|
||||
<view class="actions" wx:if="{{item.status === 'pending'}}">
|
||||
<text class="action-text" bindtap="shareRequest" data-sn="{{item.requestSn}}">分享</text>
|
||||
<text class="action-text cancel" bindtap="cancelRequest" data-sn="{{item.requestSn}}">取消</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
<block wx:elif="{{requests.length === 0}}">
|
||||
<view class="empty">暂无发起的代付</view>
|
||||
</block>
|
||||
<block wx:else>
|
||||
<block wx:if="{{payments.length === 0}}">
|
||||
<view class="empty">暂无帮付记录</view>
|
||||
</block>
|
||||
<block wx:else>
|
||||
<view class="card" wx:for="{{payments}}" wx:key="requestSn" bindtap="goToDetail" data-sn="{{item.requestSn}}">
|
||||
<view class="card-row">
|
||||
<text class="desc">{{item.description}}</text>
|
||||
<text class="amount">¥{{item.amount}}</text>
|
||||
<view class="card" wx:for="{{requests}}" wx:key="requestSn" bindtap="goToDetail" data-sn="{{item.requestSn}}">
|
||||
<view class="card-row">
|
||||
<text class="desc">{{item.description}}</text>
|
||||
<text class="amount">¥{{item.amount}}</text>
|
||||
</view>
|
||||
<view class="card-row card-meta">
|
||||
<text class="quantity" wx:if="{{item.quantity > 1}}">{{item.quantity}}份</text>
|
||||
<text class="redeemed" wx:if="{{item.status === 'paid'}}">已领 {{item.redeemedCount || 0}}/{{item.quantity || 1}}</text>
|
||||
<text class="status {{item.status}}">{{item.status === 'pending' || item.status === 'pending_pay' ? '待支付' : item.status === 'paid' ? '已支付' : item.status === 'cancelled' ? '已取消' : '已过期'}}</text>
|
||||
<view class="actions" wx:if="{{item.status === 'pending' || item.status === 'pending_pay'}}">
|
||||
<text class="action-text cancel" catchtap="cancelRequest" data-sn="{{item.requestSn}}">取消</text>
|
||||
</view>
|
||||
<view class="card-row">
|
||||
<text class="status {{item.status}}">{{item.status === 'paid' ? '已支付' : item.status}}</text>
|
||||
<view class="actions" wx:elif="{{item.status === 'paid'}}">
|
||||
<text class="action-text" catchtap="shareRequest" data-sn="{{item.requestSn}}">分享</text>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
<view class="redeem-list" wx:if="{{item.redeemList && item.redeemList.length > 0}}">
|
||||
<text class="redeem-title">领取记录:</text>
|
||||
<view class="redeem-item" wx:for="{{item.redeemList}}" wx:for-item="redeem" wx:key="userId">
|
||||
<text class="redeem-nickname">{{redeem.nickname || '用户'}}</text>
|
||||
<text class="redeem-time">{{redeem.redeemAt}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
@@ -43,28 +43,6 @@
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.tabs {
|
||||
display: flex;
|
||||
padding: 24rpx 32rpx;
|
||||
gap: 24rpx;
|
||||
background: #000;
|
||||
}
|
||||
|
||||
.tab {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
padding: 20rpx;
|
||||
font-size: 28rpx;
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
border-radius: 12rpx;
|
||||
background: #1c1c1e;
|
||||
}
|
||||
|
||||
.tab.active {
|
||||
color: #00CED1;
|
||||
background: rgba(0, 206, 209, 0.15);
|
||||
}
|
||||
|
||||
.content {
|
||||
padding: 0 32rpx 32rpx;
|
||||
}
|
||||
@@ -120,6 +98,46 @@
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.card-meta {
|
||||
flex-wrap: wrap;
|
||||
gap: 12rpx;
|
||||
}
|
||||
|
||||
.quantity, .redeemed {
|
||||
font-size: 24rpx;
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
}
|
||||
|
||||
.redeem-list {
|
||||
margin-top: 16rpx;
|
||||
padding-top: 16rpx;
|
||||
border-top: 1rpx solid rgba(255, 255, 255, 0.08);
|
||||
}
|
||||
|
||||
.redeem-title {
|
||||
font-size: 24rpx;
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
display: block;
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
|
||||
.redeem-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
font-size: 24rpx;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
padding: 4rpx 0;
|
||||
}
|
||||
|
||||
.redeem-nickname {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.redeem-time {
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
font-size: 22rpx;
|
||||
}
|
||||
|
||||
.desc {
|
||||
font-size: 28rpx;
|
||||
color: #fff;
|
||||
|
||||
80
miniprogram/pages/gift-pay/redemption-detail.js
Normal file
80
miniprogram/pages/gift-pay/redemption-detail.js
Normal file
@@ -0,0 +1,80 @@
|
||||
/**
|
||||
* Soul创业派对 - 代付领取详情(发起人查看:文章信息、领取人明细、剩余份数)
|
||||
*/
|
||||
const app = getApp()
|
||||
|
||||
Page({
|
||||
data: {
|
||||
statusBarHeight: 44,
|
||||
requestSn: '',
|
||||
detail: null,
|
||||
loading: true,
|
||||
remaining: 0
|
||||
},
|
||||
|
||||
onLoad(options) {
|
||||
this.setData({ statusBarHeight: app.globalData.statusBarHeight || 44 })
|
||||
const requestSn = (options.requestSn || '').trim()
|
||||
if (!requestSn) {
|
||||
wx.showToast({ title: '链接无效', icon: 'none' })
|
||||
setTimeout(() => wx.navigateBack(), 1500)
|
||||
return
|
||||
}
|
||||
this.setData({ requestSn })
|
||||
this.loadDetail()
|
||||
},
|
||||
|
||||
async loadDetail() {
|
||||
const { requestSn } = this.data
|
||||
const userId = app.globalData.userInfo?.id || ''
|
||||
if (!userId) {
|
||||
this.setData({ loading: false })
|
||||
wx.showToast({ title: '请先登录', icon: 'none' })
|
||||
return
|
||||
}
|
||||
this.setData({ loading: true })
|
||||
try {
|
||||
const res = await app.request(
|
||||
`/api/miniprogram/gift-pay/detail?requestSn=${encodeURIComponent(requestSn)}&userId=${encodeURIComponent(userId)}`
|
||||
)
|
||||
if (res && res.success) {
|
||||
const q = res.quantity || 0
|
||||
const redeemed = res.redeemedCount || 0
|
||||
const remaining = Math.max(0, q - redeemed)
|
||||
this.setData({
|
||||
detail: res,
|
||||
remaining,
|
||||
loading: false
|
||||
})
|
||||
} else {
|
||||
this.setData({ loading: false })
|
||||
wx.showToast({ title: res?.error || '加载失败', icon: 'none' })
|
||||
}
|
||||
} catch (e) {
|
||||
this.setData({ loading: false })
|
||||
wx.showToast({ title: '加载失败', icon: 'none' })
|
||||
}
|
||||
},
|
||||
|
||||
goToDetail() {
|
||||
const { requestSn } = this.data
|
||||
if (requestSn) {
|
||||
wx.navigateTo({ url: `/pages/gift-pay/detail?requestSn=${encodeURIComponent(requestSn)}` })
|
||||
}
|
||||
},
|
||||
|
||||
goToArticle() {
|
||||
const { detail } = this.data
|
||||
if (!detail) return
|
||||
const mid = detail.productMid || 0
|
||||
const id = detail.productId || ''
|
||||
if (detail.productType === 'section' && (mid || id)) {
|
||||
const q = mid ? `mid=${mid}` : `id=${id}`
|
||||
wx.navigateTo({ url: `/pages/read/read?${q}` })
|
||||
}
|
||||
},
|
||||
|
||||
goBack() {
|
||||
app.goBackOrToHome()
|
||||
}
|
||||
})
|
||||
3
miniprogram/pages/gift-pay/redemption-detail.json
Normal file
3
miniprogram/pages/gift-pay/redemption-detail.json
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"usingComponents": {}
|
||||
}
|
||||
71
miniprogram/pages/gift-pay/redemption-detail.wxml
Normal file
71
miniprogram/pages/gift-pay/redemption-detail.wxml
Normal file
@@ -0,0 +1,71 @@
|
||||
<!-- Soul创业派对 - 代付领取详情(文章信息、领取人明细、剩余份数) -->
|
||||
<view class="page">
|
||||
<view class="nav-bar" style="padding-top: {{statusBarHeight}}px;">
|
||||
<view class="nav-content">
|
||||
<view class="nav-back" bindtap="goBack">
|
||||
<text class="back-arrow">←</text>
|
||||
</view>
|
||||
<view class="nav-info">
|
||||
<text class="nav-title">领取详情</text>
|
||||
</view>
|
||||
<view class="nav-right-placeholder"></view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="content" style="padding-top: calc({{statusBarHeight}}px + 88rpx);">
|
||||
<block wx:if="{{loading}}">
|
||||
<view class="loading-box">
|
||||
<view class="loading-spinner"></view>
|
||||
<text class="loading-text">加载中...</text>
|
||||
</view>
|
||||
</block>
|
||||
<block wx:elif="{{detail}}">
|
||||
<!-- 文章信息 -->
|
||||
<section class="article-card">
|
||||
<text class="article-title">{{detail.sectionTitle || detail.description || '代付商品'}}</text>
|
||||
<text class="article-preview" wx:if="{{detail.contentPreview}}">{{detail.contentPreview}}</text>
|
||||
<view class="article-meta">
|
||||
<text class="meta-label">总份数</text>
|
||||
<text class="meta-value">{{detail.quantity || 0}} 份</text>
|
||||
</view>
|
||||
<view class="article-meta">
|
||||
<text class="meta-label">剩余份数</text>
|
||||
<text class="meta-value highlight">{{remaining}} 份</text>
|
||||
</view>
|
||||
<view class="article-actions">
|
||||
<view class="btn-link" bindtap="goToArticle" wx:if="{{detail.productType === 'section' && (detail.productMid || detail.productId)}}">
|
||||
<text>去阅读</text>
|
||||
</view>
|
||||
<view class="btn-link" bindtap="goToDetail">
|
||||
<text>{{detail.status === 'paid' ? '去分享' : detail.status === 'pending_pay' ? '去支付' : '查看详情'}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</section>
|
||||
|
||||
<!-- 领取人明细 -->
|
||||
<section class="redeem-section">
|
||||
<view class="section-header">
|
||||
<text class="section-title">领取记录</text>
|
||||
<text class="section-count" wx:if="{{detail.redeemList && detail.redeemList.length > 0}}">共 {{detail.redeemList.length}} 人</text>
|
||||
</view>
|
||||
<view class="redeem-list" wx:if="{{detail.redeemList && detail.redeemList.length > 0}}">
|
||||
<view class="redeem-item" wx:for="{{detail.redeemList}}" wx:key="userId">
|
||||
<view class="redeem-user">
|
||||
<image class="redeem-avatar" src="{{item.avatar || '/assets/icons/user.svg'}}" mode="aspectFill"/>
|
||||
<text class="redeem-nickname">{{item.nickname || '用户'}}</text>
|
||||
</view>
|
||||
<text class="redeem-time">{{item.redeemAt}}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="redeem-empty" wx:else>
|
||||
<text>暂无领取记录</text>
|
||||
</view>
|
||||
</section>
|
||||
</block>
|
||||
<block wx:else>
|
||||
<view class="empty">
|
||||
<text>代付请求不存在或已处理</text>
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
</view>
|
||||
234
miniprogram/pages/gift-pay/redemption-detail.wxss
Normal file
234
miniprogram/pages/gift-pay/redemption-detail.wxss
Normal file
@@ -0,0 +1,234 @@
|
||||
/* Soul创业派对 - 代付领取详情 */
|
||||
.page {
|
||||
min-height: 100vh;
|
||||
background: #050505;
|
||||
}
|
||||
|
||||
.nav-bar {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 100;
|
||||
background: rgba(5, 5, 5, 0.6);
|
||||
backdrop-filter: blur(40rpx);
|
||||
-webkit-backdrop-filter: blur(40rpx);
|
||||
border-bottom: 1rpx solid rgba(255, 255, 255, 0.05);
|
||||
}
|
||||
|
||||
.nav-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 24rpx;
|
||||
height: 88rpx;
|
||||
}
|
||||
|
||||
.nav-back {
|
||||
width: 72rpx;
|
||||
height: 72rpx;
|
||||
border-radius: 50%;
|
||||
background: rgba(255, 255, 255, 0.06);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.nav-back:active {
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.back-arrow {
|
||||
font-size: 36rpx;
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
}
|
||||
|
||||
.nav-title {
|
||||
font-size: 28rpx;
|
||||
font-weight: 700;
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
letter-spacing: 0.2em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.content {
|
||||
padding: 24rpx 24rpx 80rpx;
|
||||
}
|
||||
|
||||
.loading-box {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 120rpx 0;
|
||||
}
|
||||
|
||||
.loading-spinner {
|
||||
width: 48rpx;
|
||||
height: 48rpx;
|
||||
border: 4rpx solid rgba(20, 184, 166, 0.2);
|
||||
border-top-color: #14b8a6;
|
||||
border-radius: 50%;
|
||||
animation: spin 0.8s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
to { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
.loading-text {
|
||||
margin-top: 24rpx;
|
||||
font-size: 28rpx;
|
||||
color: rgba(255, 255, 255, 0.45);
|
||||
}
|
||||
|
||||
.empty {
|
||||
text-align: center;
|
||||
padding: 80rpx 0;
|
||||
font-size: 28rpx;
|
||||
color: rgba(255, 255, 255, 0.4);
|
||||
}
|
||||
|
||||
/* 文章信息卡片 */
|
||||
.article-card {
|
||||
background: rgba(24, 24, 27, 0.8);
|
||||
border: 1rpx solid rgba(255, 255, 255, 0.1);
|
||||
border-radius: 24rpx;
|
||||
padding: 32rpx;
|
||||
margin-bottom: 24rpx;
|
||||
}
|
||||
|
||||
.article-title {
|
||||
display: block;
|
||||
font-size: 32rpx;
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
line-height: 1.4;
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
|
||||
.article-preview {
|
||||
font-size: 26rpx;
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
line-height: 1.5;
|
||||
margin-bottom: 24rpx;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 3;
|
||||
-webkit-box-orient: vertical;
|
||||
}
|
||||
|
||||
.article-meta {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 12rpx 0;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.meta-label {
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
|
||||
.meta-value {
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
}
|
||||
|
||||
.meta-value.highlight {
|
||||
color: #14b8a6;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.article-actions {
|
||||
display: flex;
|
||||
gap: 24rpx;
|
||||
margin-top: 24rpx;
|
||||
padding-top: 24rpx;
|
||||
border-top: 1rpx solid rgba(255, 255, 255, 0.06);
|
||||
}
|
||||
|
||||
.btn-link {
|
||||
padding: 16rpx 32rpx;
|
||||
background: rgba(20, 184, 166, 0.15);
|
||||
border-radius: 12rpx;
|
||||
font-size: 28rpx;
|
||||
color: #14b8a6;
|
||||
}
|
||||
|
||||
.btn-link:active {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
/* 领取记录 */
|
||||
.redeem-section {
|
||||
background: rgba(24, 24, 27, 0.8);
|
||||
border: 1rpx solid rgba(255, 255, 255, 0.1);
|
||||
border-radius: 24rpx;
|
||||
padding: 32rpx;
|
||||
}
|
||||
|
||||
.section-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 28rpx;
|
||||
font-weight: 600;
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
}
|
||||
|
||||
.section-count {
|
||||
font-size: 24rpx;
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
|
||||
.redeem-list {
|
||||
max-height: 400rpx;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.redeem-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 16rpx 0;
|
||||
border-bottom: 1rpx solid rgba(255, 255, 255, 0.06);
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.redeem-item:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.redeem-user {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16rpx;
|
||||
}
|
||||
|
||||
.redeem-avatar {
|
||||
width: 56rpx;
|
||||
height: 56rpx;
|
||||
border-radius: 50%;
|
||||
background: rgba(255, 255, 255, 0.08);
|
||||
}
|
||||
|
||||
.redeem-nickname {
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
}
|
||||
|
||||
.redeem-time {
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
font-size: 24rpx;
|
||||
}
|
||||
|
||||
.redeem-empty {
|
||||
padding: 40rpx 0;
|
||||
text-align: center;
|
||||
font-size: 26rpx;
|
||||
color: rgba(255, 255, 255, 0.4);
|
||||
}
|
||||
@@ -190,5 +190,4 @@
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<env-switch />
|
||||
</view>
|
||||
|
||||
@@ -325,5 +325,4 @@
|
||||
|
||||
<!-- 底部留白 -->
|
||||
<view class="bottom-space"></view>
|
||||
<env-switch />
|
||||
</view>
|
||||
|
||||
@@ -253,5 +253,4 @@
|
||||
</view>
|
||||
|
||||
<view class="bottom-space"></view>
|
||||
<env-switch />
|
||||
</view>
|
||||
|
||||
@@ -66,6 +66,8 @@ Page({
|
||||
|
||||
// 弹窗
|
||||
showShareModal: false,
|
||||
showGiftModal: false,
|
||||
giftQuantity: 1,
|
||||
showLoginModal: false,
|
||||
agreeProtocol: false,
|
||||
showPosterModal: false,
|
||||
@@ -666,39 +668,18 @@ Page({
|
||||
this.setData({ showShareModal: false })
|
||||
},
|
||||
|
||||
// 找好友代付:创建代付请求后跳转代付页(美团式,在代付页分享)
|
||||
async showGiftShareModal() {
|
||||
// 代付分享:直接跳转代付页,在代付页输入数量并支付(简化流程)
|
||||
showGiftShareModal() {
|
||||
if (!app.globalData.userInfo?.id) {
|
||||
wx.showToast({ title: '请先登录', icon: 'none' })
|
||||
return
|
||||
}
|
||||
const { sectionId, sectionMid } = this.data
|
||||
const productId = sectionId || ''
|
||||
if (!productId) {
|
||||
const { sectionId } = this.data
|
||||
if (!sectionId) {
|
||||
wx.showToast({ title: '章节信息异常', icon: 'none' })
|
||||
return
|
||||
}
|
||||
wx.showLoading({ title: '创建代付请求...', mask: true })
|
||||
try {
|
||||
const res = await app.request({
|
||||
url: '/api/miniprogram/gift-pay/create',
|
||||
method: 'POST',
|
||||
data: {
|
||||
userId: app.globalData.userInfo.id,
|
||||
productType: 'section',
|
||||
productId
|
||||
}
|
||||
})
|
||||
wx.hideLoading()
|
||||
if (res && res.success && res.requestSn) {
|
||||
wx.navigateTo({ url: `/pages/gift-pay/detail?requestSn=${res.requestSn}` })
|
||||
} else {
|
||||
wx.showToast({ title: res?.error || '创建失败', icon: 'none' })
|
||||
}
|
||||
} catch (e) {
|
||||
wx.hideLoading()
|
||||
wx.showToast({ title: '创建失败', icon: 'none' })
|
||||
}
|
||||
wx.navigateTo({ url: `/pages/gift-pay/detail?sectionId=${encodeURIComponent(sectionId)}` })
|
||||
},
|
||||
|
||||
// 复制链接
|
||||
|
||||
@@ -195,10 +195,10 @@
|
||||
<view class="paywall-audit-tip" wx:if="{{auditMode}}">审核中,暂不支持购买</view>
|
||||
|
||||
<text class="paywall-tip" wx:if="{{!auditMode}}">分享给好友一起学习,还能赚取佣金</text>
|
||||
<!-- 代付分享:让好友帮我买(审核模式隐藏) -->
|
||||
<!-- 代付分享:帮好友购买(审核模式隐藏) -->
|
||||
<view class="gift-share-row" bindtap="showGiftShareModal" wx:if="{{isLoggedIn && !auditMode}}">
|
||||
<text class="gift-share-icon">🎁</text>
|
||||
<text class="gift-share-text">找好友代付</text>
|
||||
<text class="gift-share-text">代付分享</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
@@ -314,5 +314,4 @@
|
||||
<view class="fab-share" bindtap="shareToMoments">
|
||||
<text class="fab-moments-icon">🌐</text>
|
||||
</view>
|
||||
<env-switch />
|
||||
</view>
|
||||
|
||||
@@ -618,6 +618,55 @@
|
||||
}
|
||||
.gift-share-icon { font-size: 32rpx; }
|
||||
.gift-share-text { font-size: 28rpx; color: #FFD700; }
|
||||
|
||||
/* 代付分享弹窗 */
|
||||
.gift-modal { padding: 32rpx; }
|
||||
.gift-desc {
|
||||
font-size: 28rpx;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
line-height: 1.5;
|
||||
display: block;
|
||||
margin-bottom: 32rpx;
|
||||
}
|
||||
.gift-form { margin-bottom: 32rpx; }
|
||||
.gift-label {
|
||||
font-size: 26rpx;
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
display: block;
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
.form-input-wrap {
|
||||
padding: 16rpx 24rpx;
|
||||
background: #1F2937;
|
||||
border-radius: 16rpx;
|
||||
}
|
||||
.form-input-inner {
|
||||
width: 100%;
|
||||
font-size: 28rpx;
|
||||
color: #fff;
|
||||
background: transparent;
|
||||
}
|
||||
.gift-actions {
|
||||
display: flex;
|
||||
gap: 24rpx;
|
||||
}
|
||||
.gift-btn {
|
||||
flex: 1;
|
||||
padding: 24rpx;
|
||||
text-align: center;
|
||||
font-size: 30rpx;
|
||||
border-radius: 24rpx;
|
||||
}
|
||||
.gift-cancel {
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
}
|
||||
.gift-confirm {
|
||||
background: #00CED1;
|
||||
color: #000;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.share-modal-desc {
|
||||
font-size: 28rpx;
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
|
||||
@@ -329,5 +329,4 @@
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<env-switch />
|
||||
</view>
|
||||
|
||||
@@ -112,5 +112,4 @@
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<env-switch />
|
||||
</view>
|
||||
|
||||
@@ -177,5 +177,4 @@
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<env-switch />
|
||||
</view>
|
||||
|
||||
@@ -52,5 +52,4 @@
|
||||
</view>
|
||||
|
||||
<view class="bottom-space"></view>
|
||||
<env-switch />
|
||||
</view>
|
||||
@@ -78,5 +78,4 @@
|
||||
</view>
|
||||
|
||||
<view class="bottom-space"></view>
|
||||
<env-switch />
|
||||
</view>
|
||||
|
||||
@@ -23,12 +23,19 @@
|
||||
"condition": {
|
||||
"miniprogram": {
|
||||
"list": [
|
||||
{
|
||||
"name": "pages/gift-pay/list",
|
||||
"pathName": "pages/gift-pay/list",
|
||||
"query": "",
|
||||
"scene": null,
|
||||
"launchMode": "default"
|
||||
},
|
||||
{
|
||||
"name": "代付",
|
||||
"pathName": "pages/gift-pay/detail",
|
||||
"query": "requestSn=GPRMP20260317145140501100",
|
||||
"scene": null,
|
||||
"launchMode": "default"
|
||||
"launchMode": "default",
|
||||
"scene": null
|
||||
},
|
||||
{
|
||||
"name": "唤醒",
|
||||
|
||||
Reference in New Issue
Block a user