feat: sync local changes
This commit is contained in:
parent
ff4c7b7e09
commit
88ffbbc0a3
1
app.json
1
app.json
|
|
@ -16,6 +16,7 @@
|
|||
"pages/chat/chat",
|
||||
"pages/chat-detail/chat-detail",
|
||||
"pages/profile/profile",
|
||||
"pages/membership-benefits/membership-benefits",
|
||||
"pages/login/login",
|
||||
"pages/recharge/recharge",
|
||||
"pages/character-detail/character-detail",
|
||||
|
|
|
|||
47
auto_sync.ps1
Normal file
47
auto_sync.ps1
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
$ErrorActionPreference = "Stop"
|
||||
|
||||
$gitPath = ""
|
||||
$commonPaths = @(
|
||||
"C:\Program Files\Git\bin\git.exe",
|
||||
"C:\Program Files (x86)\Git\bin\git.exe",
|
||||
"$env:LocalAppData\Programs\Git\bin\git.exe",
|
||||
"D:\Git\bin\git.exe",
|
||||
"D:\Program Files\Git\bin\git.exe"
|
||||
)
|
||||
|
||||
foreach ($path in $commonPaths) {
|
||||
if (Test-Path $path) {
|
||||
$gitPath = $path
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if (-not $gitPath) {
|
||||
try {
|
||||
$gitPath = Get-Command git -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Source
|
||||
} catch {}
|
||||
}
|
||||
|
||||
if (-not $gitPath) {
|
||||
Write-Host "Error: Git not found. Please run this in your local terminal where Git is installed." -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
|
||||
Write-Host "Found Git: $gitPath" -ForegroundColor Green
|
||||
|
||||
try {
|
||||
Write-Host "--- Syncing started ---" -ForegroundColor Yellow
|
||||
|
||||
& $gitPath add -A
|
||||
|
||||
$date = Get-Date -Format "yyyy-MM-dd HH:mm"
|
||||
$message = "feat: UI and logic updates ($date)"
|
||||
& $gitPath commit -m $message | Out-Null
|
||||
|
||||
Write-Host "Pushing to remote..." -ForegroundColor Yellow
|
||||
& $gitPath push
|
||||
|
||||
Write-Host "--- Sync successful! ---" -ForegroundColor Green
|
||||
} catch {
|
||||
Write-Host "Error during sync: $($_.Exception.Message)" -ForegroundColor Red
|
||||
}
|
||||
|
|
@ -30,6 +30,7 @@ const ICONS = {
|
|||
'scan': '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="CURRENT" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 7V5a2 2 0 0 1 2-2h2"/><path d="M16 3h2a2 2 0 0 1 2 2v2"/><path d="M20 17v2a2 2 0 0 1-2 2h-2"/><path d="M8 21H6a2 2 0 0 1-2-2v-2"/><path d="M7 12h10"/></svg>',
|
||||
'camera': '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="CURRENT" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14.5 4h-5L8 6H5a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-3l-1.5-2z"/><circle cx="12" cy="13" r="3"/></svg>',
|
||||
'clipboard': '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="CURRENT" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"/><rect x="8" y="2" width="8" height="4" rx="1" ry="1"/></svg>',
|
||||
'credit-card': '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="CURRENT" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="1" y="4" width="22" height="16" rx="2" ry="2"></rect><line x1="1" y1="10" x2="23" y2="10"></line></svg>',
|
||||
'trending-up': '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="CURRENT" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="23 6 13.5 15.5 8.5 10.5 1 18"></polyline><polyline points="17 6 23 6 23 12"></polyline></svg>',
|
||||
'map-pin': '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="CURRENT" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 1 1 18 0z"></path><circle cx="12" cy="10" r="3"></circle></svg>',
|
||||
'heart': '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="CURRENT" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg>',
|
||||
|
|
|
|||
18
git-push.bat
18
git-push.bat
|
|
@ -7,25 +7,19 @@ echo.
|
|||
|
||||
cd /d "%~dp0"
|
||||
|
||||
set /p msg=请输入提交信息(例如: feat: 更新小程序代码):
|
||||
if "%msg%"=="" set msg=chore: sync
|
||||
|
||||
echo [1/5] 添加所有更改...
|
||||
git add -A
|
||||
|
||||
echo.
|
||||
echo [2/5] 提交更改...
|
||||
git commit -m "feat: 更新小程序代码 - 2026-02-02"
|
||||
git commit -m "%msg%"
|
||||
|
||||
echo.
|
||||
echo [3/5] 添加 tag...
|
||||
git tag -a v1.0.0 -m "Version 1.0.0 - 2026-02-02"
|
||||
|
||||
echo.
|
||||
echo [4/5] 推送到远程仓库...
|
||||
echo 请输入密码: zy12345678
|
||||
git push https://zhiyun:zy12345678@git.maimanji.com/adminzy/ai-c.git master --force
|
||||
|
||||
echo.
|
||||
echo [5/5] 推送 tag...
|
||||
git push https://zhiyun:zy12345678@git.maimanji.com/adminzy/ai-c.git v1.0.0
|
||||
echo [3/4] 推送到远程仓库...
|
||||
git push
|
||||
|
||||
echo.
|
||||
echo ========================
|
||||
|
|
|
|||
25
git-push.sh
25
git-push.sh
|
|
@ -1,6 +1,4 @@
|
|||
#!/bin/bash
|
||||
# Git 提交脚本
|
||||
|
||||
cd "$(dirname "$0")"
|
||||
|
||||
echo "========================"
|
||||
|
|
@ -8,24 +6,21 @@ echo "Git 提交脚本"
|
|||
echo "========================"
|
||||
echo ""
|
||||
|
||||
echo "[1/5] 添加所有更改..."
|
||||
read -r -p "请输入提交信息(例如: feat: 更新小程序代码): " msg
|
||||
if [ -z "$msg" ]; then
|
||||
msg="chore: sync"
|
||||
fi
|
||||
|
||||
echo "[1/3] 添加所有更改..."
|
||||
git add -A
|
||||
|
||||
echo ""
|
||||
echo "[2/5] 提交更改..."
|
||||
git commit -m "feat: 更新小程序代码 - 2026-02-02"
|
||||
echo "[2/3] 提交更改..."
|
||||
git commit -m "$msg"
|
||||
|
||||
echo ""
|
||||
echo "[3/5] 添加 tag..."
|
||||
git tag -a v1.0.0 -m "Version 1.0.0 - 2026-02-02"
|
||||
|
||||
echo ""
|
||||
echo "[4/5] 推送到远程仓库..."
|
||||
git push https://zhiyun:zy12345678@git.maimanji.com/adminzy/ai-c.git master --force
|
||||
|
||||
echo ""
|
||||
echo "[5/5] 推送 tag..."
|
||||
git push https://zhiyun:zy12345678@git.maimanji.com/adminzy/ai-c.git v1.0.0
|
||||
echo "[3/3] 推送到远程仓库..."
|
||||
git push
|
||||
|
||||
echo ""
|
||||
echo "========================"
|
||||
|
|
|
|||
BIN
images/logo.jpg
Normal file
BIN
images/logo.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 54 KiB |
BIN
images/logo.png
Normal file
BIN
images/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 201 KiB |
|
|
@ -165,11 +165,11 @@
|
|||
<!-- 底部操作栏 -->
|
||||
<view class="bottom-bar">
|
||||
<view class="bar-left">
|
||||
<!-- 收藏按钮 -->
|
||||
<view class="action-btn" bindtap="onToggleFavorite">
|
||||
<!-- 收藏按钮 - 根据需求隐藏 -->
|
||||
<!-- <view class="action-btn" bindtap="onToggleFavorite">
|
||||
<app-icon name="{{activity.is_favorited ? 'heart-filled' : 'heart'}}" size="56" color="{{activity.is_favorited ? '#FF5252' : '#4A5565'}}" />
|
||||
<text class="action-text">{{activity.is_favorited ? '已收藏' : '收藏'}}</text>
|
||||
</view>
|
||||
</view> -->
|
||||
|
||||
<!-- 分享按钮 -->
|
||||
<button class="action-btn share-btn" open-type="share">
|
||||
|
|
|
|||
|
|
@ -501,7 +501,8 @@ page {
|
|||
.bar-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12rpx;
|
||||
justify-content: flex-start;
|
||||
margin-right: 40rpx;
|
||||
}
|
||||
|
||||
.action-btn {
|
||||
|
|
@ -512,7 +513,7 @@ page {
|
|||
background: transparent;
|
||||
border: none;
|
||||
padding: 0;
|
||||
width: 80rpx;
|
||||
min-width: 80rpx;
|
||||
}
|
||||
|
||||
.share-btn::after {
|
||||
|
|
@ -676,16 +677,20 @@ page {
|
|||
position: absolute;
|
||||
top: 30rpx;
|
||||
right: 30rpx;
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
width: 80rpx;
|
||||
height: 80rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: #F8FAFC;
|
||||
border-radius: 50%;
|
||||
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.qrcode-modal .close-icon {
|
||||
width: 32rpx;
|
||||
height: 32rpx;
|
||||
width: 48rpx;
|
||||
height: 48rpx;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.qrcode-modal .modal-title {
|
||||
|
|
|
|||
|
|
@ -76,11 +76,17 @@
|
|||
|
||||
<!-- 底部操作按钮 -->
|
||||
<view class="action-bar">
|
||||
<view class="action-btn dislike-btn" bindtap="onDislike">
|
||||
<image src="/images/icon-close.png" class="action-btn-icon" mode="aspectFit"></image>
|
||||
<view class="action-group" bindtap="onDislike">
|
||||
<view class="action-btn dislike-btn">
|
||||
<image src="/images/icon-close.png" class="action-btn-icon" mode="aspectFit"></image>
|
||||
</view>
|
||||
<text class="action-label">返回</text>
|
||||
</view>
|
||||
<view class="action-btn chat-btn" bindtap="onChat">
|
||||
<image src="/images/icon-comment.png" class="action-btn-icon" mode="aspectFit"></image>
|
||||
<view class="action-group" bindtap="onChat">
|
||||
<view class="action-btn chat-btn">
|
||||
<image src="/images/icon-comment.png" class="action-btn-icon" mode="aspectFit"></image>
|
||||
</view>
|
||||
<text class="action-label highlight">去聊天</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
|
|
@ -127,7 +133,7 @@
|
|||
</view>
|
||||
<view class="heart-option-info">
|
||||
<text class="heart-option-title">{{unlockHeartsCost}}爱心</text>
|
||||
<text class="heart-option-desc">{{userLovePoints >= unlockHeartsCost ? '余额充足 立即兑换' : '爱心值不足 去充值'}}</text>
|
||||
<text class="heart-option-desc">{{userLovePoints >= unlockHeartsCost ? '余额充足 立即兑换' : '爱心不足 立即充值'}}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="heart-option-btn exchange-btn">兑换</view>
|
||||
|
|
|
|||
|
|
@ -350,13 +350,32 @@
|
|||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 220rpx;
|
||||
background: linear-gradient(to top, #fff 60%, transparent);
|
||||
height: 280rpx;
|
||||
background: linear-gradient(to top, #fff 80%, transparent);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 80rpx;
|
||||
gap: 120rpx;
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
.action-group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 16rpx;
|
||||
}
|
||||
|
||||
.action-label {
|
||||
font-size: 26rpx;
|
||||
font-weight: 600;
|
||||
color: #6a7282;
|
||||
letter-spacing: 2rpx;
|
||||
}
|
||||
|
||||
.action-label.highlight {
|
||||
color: #07C160;
|
||||
}
|
||||
|
||||
.action-btn {
|
||||
|
|
@ -365,38 +384,38 @@
|
|||
justify-content: center;
|
||||
border-radius: 50%;
|
||||
box-shadow: 0 8rpx 24rpx rgba(0,0,0,0.12);
|
||||
transition: transform 0.2s ease;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.action-btn:active {
|
||||
transform: scale(0.95);
|
||||
.action-group:active .action-btn {
|
||||
transform: scale(0.92);
|
||||
}
|
||||
|
||||
/* X按钮 - 不喜欢 */
|
||||
.action-btn.dislike-btn {
|
||||
width: 140rpx;
|
||||
height: 140rpx;
|
||||
width: 130rpx;
|
||||
height: 130rpx;
|
||||
background: #fff;
|
||||
border: 3rpx solid #f3f4f6;
|
||||
}
|
||||
|
||||
.action-btn.dislike-btn .action-btn-icon {
|
||||
width: 64rpx;
|
||||
height: 64rpx;
|
||||
width: 56rpx;
|
||||
height: 56rpx;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
/* 对话按钮 - 微信绿色系 */
|
||||
.action-btn.chat-btn {
|
||||
width: 140rpx;
|
||||
height: 140rpx;
|
||||
width: 130rpx;
|
||||
height: 130rpx;
|
||||
background: #07C160;
|
||||
box-shadow: 0 0 0 6rpx rgba(7, 193, 96, 0.15), 0 12rpx 32rpx rgba(7, 193, 96, 0.35);
|
||||
}
|
||||
|
||||
.action-btn.chat-btn .action-btn-icon {
|
||||
width: 64rpx;
|
||||
height: 64rpx;
|
||||
width: 56rpx;
|
||||
height: 56rpx;
|
||||
filter: brightness(0) invert(1);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -201,7 +201,7 @@
|
|||
<view wx:else class="figma-input-wrap">
|
||||
<input
|
||||
class="figma-text-input"
|
||||
placeholder="{{isUnlocked ? '发消息...' : (freeTime.isActive ? '限时免费畅聊中...' : '发消息...')}}"
|
||||
placeholder="限时免费陪伴中"
|
||||
placeholder-class="figma-input-placeholder"
|
||||
value="{{inputText}}"
|
||||
bindinput="onInput"
|
||||
|
|
@ -372,7 +372,7 @@
|
|||
</view>
|
||||
<view class="option-info">
|
||||
<text class="option-title">{{unlockHeartsCost}} 爱心</text>
|
||||
<text class="option-desc">{{heartCount >= unlockHeartsCost ? '爱心值充足 立即兑换' : '爱心值不足 去充值'}}</text>
|
||||
<text class="option-desc">{{heartCount >= unlockHeartsCost ? '爱心值充足 立即兑换' : '爱心不足 立即充值'}}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="option-btn hearts-btn">
|
||||
|
|
|
|||
|
|
@ -9,8 +9,8 @@
|
|||
|
||||
<!-- 消息列表 -->
|
||||
<scroll-view scroll-y class="message-list">
|
||||
<!-- 免费畅聊时间提醒 (显示在推广收益上方) -->
|
||||
<view class="free-chat-banner" wx:if="{{freeTime && freeTime.isActive && countdownText}}" bindtap="onFreeChatTap">
|
||||
<!-- 免费畅聊时间提醒 (显示在推广收益上方) - 已根据需求隐藏 -->
|
||||
<view class="free-chat-banner" wx:if="{{false && freeTime && freeTime.isActive && countdownText}}" bindtap="onFreeChatTap">
|
||||
<view class="free-chat-banner-content">
|
||||
<image src="/images/icon-clock-red.png" class="banner-clock-icon" mode="aspectFit"></image>
|
||||
<text class="banner-text">剩余 {{countdownText}} 分 可以免费畅聊</text>
|
||||
|
|
|
|||
|
|
@ -338,20 +338,25 @@ page {
|
|||
|
||||
/* 空状态 */
|
||||
.empty-state {
|
||||
padding: 120rpx 32rpx;
|
||||
text-align: center;
|
||||
padding: 160rpx 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.empty-icon {
|
||||
width: 200rpx;
|
||||
height: 200rpx;
|
||||
margin: 0 auto 32rpx;
|
||||
opacity: 0.5;
|
||||
width: 320rpx;
|
||||
height: 320rpx;
|
||||
margin-bottom: 32rpx;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.empty-text {
|
||||
font-size: 28rpx;
|
||||
color: #B39DDB;
|
||||
font-size: 30rpx;
|
||||
color: #94A3B8;
|
||||
font-weight: 500;
|
||||
letter-spacing: 2rpx;
|
||||
}
|
||||
|
||||
/* 二维码弹窗 */
|
||||
|
|
|
|||
|
|
@ -287,6 +287,11 @@ Page({
|
|||
wx.navigateTo({
|
||||
url: '/pages/promote/promote'
|
||||
})
|
||||
} else if (res.cancel) {
|
||||
// 用户点击暂不需要,退出当前页回到上一页
|
||||
wx.navigateBack({
|
||||
delta: 1
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
|
|||
|
|
@ -524,8 +524,7 @@ swiper-item {
|
|||
|
||||
/* 空状态 */
|
||||
.empty-state {
|
||||
padding: 200rpx 0;
|
||||
text-align: center;
|
||||
padding: 160rpx 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
|
@ -533,15 +532,17 @@ swiper-item {
|
|||
}
|
||||
|
||||
.empty-icon {
|
||||
width: 240rpx;
|
||||
height: 240rpx;
|
||||
margin: 0 auto 32rpx;
|
||||
opacity: 0.5;
|
||||
width: 320rpx;
|
||||
height: 320rpx;
|
||||
margin-bottom: 32rpx;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.empty-text {
|
||||
font-size: 32rpx;
|
||||
color: #99A1AF;
|
||||
font-size: 30rpx;
|
||||
color: #94A3B8;
|
||||
font-weight: 500;
|
||||
letter-spacing: 2rpx;
|
||||
}
|
||||
|
||||
/* 列表底部 */
|
||||
|
|
|
|||
|
|
@ -370,19 +370,25 @@ page {
|
|||
|
||||
/* 空状态 */
|
||||
.empty-state {
|
||||
padding: 100rpx 0;
|
||||
text-align: center;
|
||||
padding: 160rpx 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.empty-icon {
|
||||
width: 200rpx;
|
||||
height: 200rpx;
|
||||
opacity: 0.5;
|
||||
width: 320rpx;
|
||||
height: 320rpx;
|
||||
margin-bottom: 32rpx;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.empty-text {
|
||||
font-size: 32rpx;
|
||||
color: #FFBE76;
|
||||
font-size: 30rpx;
|
||||
color: #94A3B8;
|
||||
font-weight: 500;
|
||||
letter-spacing: 2rpx;
|
||||
}
|
||||
|
||||
/* 二维码弹窗 */
|
||||
|
|
|
|||
|
|
@ -77,6 +77,9 @@ Page({
|
|||
showGf100Popup: false,
|
||||
gf100ImageUrl: '',
|
||||
|
||||
// 语音播放状态
|
||||
isVoicePlaying: false,
|
||||
|
||||
// 解锁配置
|
||||
unlockHeartsCost: 500 // 默认解锁爱心成本
|
||||
},
|
||||
|
|
@ -527,8 +530,18 @@ Page({
|
|||
* 移动到下一张卡片
|
||||
*/
|
||||
moveToNext() {
|
||||
const { currentIndex, profiles } = this.data
|
||||
const { currentIndex, profiles, isVoicePlaying } = this.data
|
||||
const nextIndex = currentIndex + 1
|
||||
|
||||
// 切换卡片时,如果正在播放语音,则停止播放
|
||||
if (isVoicePlaying && this.audioContext) {
|
||||
try {
|
||||
console.log('[index] 切换卡片,停止上一个角色的语音')
|
||||
this.audioContext.stop()
|
||||
} catch (e) {
|
||||
console.error('[index] 停止语音失败:', e)
|
||||
}
|
||||
}
|
||||
|
||||
// 如果快到末尾,加载更多
|
||||
if (nextIndex >= profiles.length - 2) {
|
||||
|
|
@ -603,9 +616,17 @@ Page({
|
|||
* 播放语音(优先使用预录制的开场白音频)
|
||||
*/
|
||||
async onPlayVoice() {
|
||||
const { currentIndex, profiles } = this.data
|
||||
const { currentIndex, profiles, isVoicePlaying } = this.data
|
||||
|
||||
if (currentIndex >= profiles.length) return
|
||||
|
||||
// 如果正在播放,则停止
|
||||
if (isVoicePlaying && this.audioContext) {
|
||||
try {
|
||||
this.audioContext.stop()
|
||||
} catch (e) {}
|
||||
return
|
||||
}
|
||||
|
||||
const currentProfile = profiles[currentIndex]
|
||||
|
||||
|
|
@ -695,8 +716,15 @@ Page({
|
|||
|
||||
innerAudioContext.onPlay(() => {
|
||||
console.log('[index] 音频开始播放, volume:', innerAudioContext.volume)
|
||||
this.setData({ isVoicePlaying: true })
|
||||
})
|
||||
|
||||
innerAudioContext.onStop(() => {
|
||||
console.log('[index] 音频停止播放')
|
||||
this.setData({ isVoicePlaying: false })
|
||||
wx.hideToast()
|
||||
})
|
||||
|
||||
innerAudioContext.onTimeUpdate(() => {
|
||||
// 每秒打印一次进度
|
||||
const currentTime = Math.floor(innerAudioContext.currentTime)
|
||||
|
|
@ -708,6 +736,7 @@ Page({
|
|||
|
||||
innerAudioContext.onError((err) => {
|
||||
console.error('[index] 音频播放错误:', JSON.stringify(err))
|
||||
this.setData({ isVoicePlaying: false })
|
||||
wx.hideToast()
|
||||
let errMsg = '播放失败'
|
||||
if (err.errCode === 10001 || err.errCode === -1) {
|
||||
|
|
@ -722,6 +751,7 @@ Page({
|
|||
|
||||
innerAudioContext.onEnded(() => {
|
||||
console.log('[index] 音频播放结束')
|
||||
this.setData({ isVoicePlaying: false })
|
||||
wx.hideToast()
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
<!-- 顶部导航栏 -->
|
||||
<view class="unified-header">
|
||||
<view class="unified-header-left"></view>
|
||||
<text class="unified-header-title">陪伴</text>
|
||||
<text class="unified-header-title">关怀陪伴</text>
|
||||
<view class="unified-header-right"></view>
|
||||
</view>
|
||||
|
||||
|
|
@ -111,8 +111,17 @@
|
|||
<image src="/images/icon-heart{{likedProfiles[profiles[currentIndex].id] ? '-filled' : ''}}.png" class="action-icon" mode="aspectFit"></image>
|
||||
<text class="action-label">喜欢</text>
|
||||
</view>
|
||||
<view class="action-btn voice-btn" catchtap="onPlayVoice">
|
||||
<image src="/images/icon-voice.png" class="action-icon" mode="aspectFit"></image>
|
||||
<view class="action-btn voice-btn {{isVoicePlaying ? 'playing' : ''}}" catchtap="onPlayVoice">
|
||||
<view class="action-icon">
|
||||
<image src="/images/icon-voice.png" class="voice-image" mode="aspectFit"></image>
|
||||
<!-- 模拟跳动的线条 -->
|
||||
<view class="voice-waves" wx:if="{{isVoicePlaying}}">
|
||||
<view class="wave-line"></view>
|
||||
<view class="wave-line"></view>
|
||||
<view class="wave-line"></view>
|
||||
<view class="wave-line"></view>
|
||||
</view>
|
||||
</view>
|
||||
<text class="action-label">声音</text>
|
||||
</view>
|
||||
<view class="action-btn select-btn {{unlockedProfiles[profiles[currentIndex].id] ? 'unlocked' : ''}}" catchtap="onSelectCharacter">
|
||||
|
|
@ -142,7 +151,7 @@
|
|||
</view>
|
||||
<view class="option-info">
|
||||
<text class="option-price">{{unlockHeartsCost}} 爱心</text>
|
||||
<text class="option-desc">{{heartCount >= unlockHeartsCost ? '爱心值充足 立即兑换' : '爱心值不足 去充值'}}</text>
|
||||
<text class="option-desc">{{heartCount >= unlockHeartsCost ? '爱心值充足 立即兑换' : '爱心不足 立即充值'}}</text>
|
||||
</view>
|
||||
<view class="option-btn">兑换</view>
|
||||
</view>
|
||||
|
|
@ -218,7 +227,7 @@
|
|||
</view>
|
||||
<view class="option-info">
|
||||
<text class="option-title">{{unlockHeartsCost}}爱心</text>
|
||||
<text class="option-desc">{{heartCount >= unlockHeartsCost ? '余额充足 立即兑换' : '爱心值不足 去充值'}}</text>
|
||||
<text class="option-desc">{{heartCount >= unlockHeartsCost ? '余额充足 立即兑换' : '爱心不足 立即充值'}}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="option-btn hearts-btn">
|
||||
|
|
|
|||
|
|
@ -320,6 +320,64 @@
|
|||
background: rgba(145, 69, 132, 0.6);
|
||||
border: 3rpx solid rgba(255,255,255,0.3);
|
||||
box-shadow: 0 8rpx 24rpx rgba(145, 69, 132, 0.4);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.voice-image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/* 播放时的波纹/线条跳动效果 */
|
||||
.voice-waves {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 6rpx;
|
||||
background: rgba(145, 69, 132, 0.8);
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.wave-line {
|
||||
width: 6rpx;
|
||||
height: 20rpx;
|
||||
background: #fff;
|
||||
border-radius: 4rpx;
|
||||
animation: waveJump 0.8s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.wave-line:nth-child(2) {
|
||||
animation-delay: 0.1s;
|
||||
height: 40rpx;
|
||||
}
|
||||
|
||||
.wave-line:nth-child(3) {
|
||||
animation-delay: 0.2s;
|
||||
height: 30rpx;
|
||||
}
|
||||
|
||||
.wave-line:nth-child(4) {
|
||||
animation-delay: 0.3s;
|
||||
height: 15rpx;
|
||||
}
|
||||
|
||||
@keyframes waveJump {
|
||||
0%, 100% {
|
||||
transform: scaleY(0.5);
|
||||
opacity: 0.6;
|
||||
}
|
||||
50% {
|
||||
transform: scaleY(1.2);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.voice-btn.playing .action-icon {
|
||||
background: rgba(145, 69, 132, 0.9);
|
||||
box-shadow: 0 0 0 6rpx rgba(145, 69, 132, 0.3), 0 12rpx 32rpx rgba(145, 69, 132, 0.5);
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
.action-btn.liked .action-icon {
|
||||
|
|
|
|||
|
|
@ -48,8 +48,9 @@
|
|||
<view class="loading-tip" wx:if="{{loading}}">加载中...</view>
|
||||
|
||||
<!-- 空状态 -->
|
||||
<view class="empty-tip" wx:if="{{!loading && partnerList.length === 0}}">
|
||||
<text>暂无兴趣搭子数据</text>
|
||||
<view class="empty-state" wx:if="{{!loading && partnerList.length === 0}}">
|
||||
<image src="/images/icon-empty.png" class="empty-icon" mode="aspectFit"></image>
|
||||
<text class="empty-text">暂无兴趣搭子数据</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
|
|
@ -83,7 +84,7 @@
|
|||
<view class="modal-content" catchtap="{{null}}">
|
||||
<!-- 关闭按钮 -->
|
||||
<view class="close-btn" catchtap="onCloseQrcodeModal">
|
||||
<image src="/images/icon-close-gray.png" class="close-icon" mode="aspectFit"></image>
|
||||
<image src="/images/icon-close.png" class="close-icon" mode="aspectFit"></image>
|
||||
</view>
|
||||
|
||||
<!-- 标题 -->
|
||||
|
|
|
|||
|
|
@ -122,12 +122,27 @@ page {
|
|||
color: #999;
|
||||
}
|
||||
|
||||
/* 空状态提示 */
|
||||
.empty-tip {
|
||||
text-align: center;
|
||||
/* 空状态 */
|
||||
.empty-state {
|
||||
padding: 120rpx 0;
|
||||
font-size: 28rpx;
|
||||
color: #999;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.empty-icon {
|
||||
width: 320rpx;
|
||||
height: 320rpx;
|
||||
margin-bottom: 32rpx;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.empty-text {
|
||||
font-size: 30rpx;
|
||||
color: #94A3B8;
|
||||
font-weight: 500;
|
||||
letter-spacing: 2rpx;
|
||||
}
|
||||
|
||||
/* 保留原有的固定分类图标样式作为备用 */
|
||||
|
|
@ -407,24 +422,26 @@ page {
|
|||
position: absolute;
|
||||
top: 32rpx;
|
||||
right: 32rpx;
|
||||
width: 72rpx;
|
||||
height: 72rpx;
|
||||
background: #F1F5F9;
|
||||
width: 80rpx;
|
||||
height: 80rpx;
|
||||
background: #F8FAFC;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: all 0.3s ease;
|
||||
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.close-btn:active {
|
||||
transform: scale(0.9);
|
||||
background: #E2E8F0;
|
||||
background: #F1F5F9;
|
||||
}
|
||||
|
||||
.close-icon {
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
width: 48rpx;
|
||||
height: 48rpx;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
/* 标题 */
|
||||
|
|
|
|||
|
|
@ -16,11 +16,11 @@
|
|||
<view class="logo-section">
|
||||
<view class="logo-wrapper">
|
||||
<view class="logo-circle">
|
||||
<image src="/images/tab-heart.png" class="logo-icon" mode="aspectFit"></image>
|
||||
<image src="/images/logo.jpg" class="logo-icon" mode="aspectFit"></image>
|
||||
</view>
|
||||
</view>
|
||||
<text class="app-name">心伴</text>
|
||||
<text class="app-slogan">你的AI情感陪伴</text>
|
||||
<text class="app-slogan">欢迎您加入心伴俱乐部</text>
|
||||
</view>
|
||||
|
||||
<!-- 登录按钮区域 -->
|
||||
|
|
|
|||
|
|
@ -65,18 +65,14 @@
|
|||
.logo-circle {
|
||||
width: 200rpx;
|
||||
height: 200rpx;
|
||||
background: linear-gradient(135deg, #914584 0%, #B378FE 100%);
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-shadow: 0 20rpx 60rpx rgba(145, 69, 132, 0.3);
|
||||
}
|
||||
|
||||
.logo-icon {
|
||||
width: 100rpx;
|
||||
height: 100rpx;
|
||||
filter: brightness(0) invert(1);
|
||||
width: 200rpx;
|
||||
height: 200rpx;
|
||||
}
|
||||
|
||||
.app-name {
|
||||
|
|
|
|||
103
pages/membership-benefits/membership-benefits.js
Normal file
103
pages/membership-benefits/membership-benefits.js
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
const api = require('../../utils/api');
|
||||
|
||||
Page({
|
||||
data: {
|
||||
statusBarHeight: 20,
|
||||
navBarHeight: 44,
|
||||
totalNavHeight: 64,
|
||||
role: '',
|
||||
level: '',
|
||||
currentPackage: null,
|
||||
loading: true
|
||||
},
|
||||
|
||||
onLoad(options) {
|
||||
const { role, level } = options;
|
||||
const systemInfo = wx.getSystemInfoSync();
|
||||
const statusBarHeight = systemInfo.statusBarHeight || 20;
|
||||
const menuButton = wx.getMenuButtonBoundingClientRect();
|
||||
const navBarHeight = menuButton.height + (menuButton.top - statusBarHeight) * 2;
|
||||
|
||||
this.setData({
|
||||
statusBarHeight,
|
||||
navBarHeight,
|
||||
totalNavHeight: statusBarHeight + navBarHeight,
|
||||
role: role || '',
|
||||
level: level || ''
|
||||
});
|
||||
|
||||
this.loadBenefits();
|
||||
},
|
||||
|
||||
async loadBenefits() {
|
||||
try {
|
||||
const res = await api.payment.getPackages();
|
||||
const body = res.data || {};
|
||||
const list = Array.isArray(body) ? body : body?.data || [];
|
||||
|
||||
if (!list.length) {
|
||||
this.setData({ loading: false });
|
||||
return;
|
||||
}
|
||||
|
||||
// 映射逻辑与 recharge.js 保持一致
|
||||
const allPackages = list.map((p) => {
|
||||
const attrs = p.attributes || {};
|
||||
const benefits = p.benefits || attrs.benefits || [];
|
||||
const gradientStart = p.gradientStart || attrs.gradient_start || '#60A5FA';
|
||||
const gradientEnd = p.gradientEnd || attrs.gradient_end || '#2563EB';
|
||||
const tagColor = p.tagColor || attrs.tag_color || '#1E3A8A';
|
||||
|
||||
let vipType = attrs.type || p.vipType || '';
|
||||
if (vipType === 'monthly') vipType = 'month';
|
||||
if (vipType === 'yearly') vipType = 'year';
|
||||
if (vipType === 'lifetime') vipType = 'svip';
|
||||
|
||||
return {
|
||||
id: p.id,
|
||||
title: p.title,
|
||||
subtitle: p.subtitle || attrs.subtitle || (benefits[0] || ''),
|
||||
benefits,
|
||||
vipType,
|
||||
gradient: `background: linear-gradient(180deg, ${gradientStart}, ${gradientEnd});`,
|
||||
iconGradient: `background: linear-gradient(180deg, ${gradientStart}, ${gradientEnd});`,
|
||||
checkColor: tagColor || gradientEnd
|
||||
};
|
||||
});
|
||||
|
||||
// 根据 role 或 level 寻找匹配的套餐
|
||||
let currentPackage = null;
|
||||
|
||||
if (this.data.role) {
|
||||
// 优先根据 role 匹配 (soulmate, guardian, companion, listener)
|
||||
currentPackage = allPackages.find(p => p.vipType === this.data.role);
|
||||
}
|
||||
|
||||
if (!currentPackage && this.data.level) {
|
||||
// 如果 role 没匹配到,尝试根据 levelText 匹配 (SVIP, VIP)
|
||||
if (this.data.level === 'SVIP') {
|
||||
currentPackage = allPackages.find(p => p.vipType === 'svip');
|
||||
} else if (this.data.level === 'VIP') {
|
||||
currentPackage = allPackages.find(p => p.vipType === 'month' || p.vipType === 'year');
|
||||
}
|
||||
}
|
||||
|
||||
// 如果还是没找到,默认取第一个(兜底)
|
||||
if (!currentPackage && allPackages.length > 0) {
|
||||
currentPackage = allPackages[0];
|
||||
}
|
||||
|
||||
this.setData({
|
||||
currentPackage,
|
||||
loading: false
|
||||
});
|
||||
} catch (err) {
|
||||
console.error('Failed to load benefits:', err);
|
||||
this.setData({ loading: false });
|
||||
}
|
||||
},
|
||||
|
||||
onBack() {
|
||||
wx.navigateBack({ delta: 1 });
|
||||
}
|
||||
});
|
||||
6
pages/membership-benefits/membership-benefits.json
Normal file
6
pages/membership-benefits/membership-benefits.json
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"usingComponents": {
|
||||
"app-icon": "../../components/icon/icon"
|
||||
},
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
60
pages/membership-benefits/membership-benefits.wxml
Normal file
60
pages/membership-benefits/membership-benefits.wxml
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
<view class="page safe-bottom">
|
||||
<!-- 顶部导航栏 -->
|
||||
<view class="unified-header">
|
||||
<view class="unified-header-left" bindtap="onBack">
|
||||
<image src="/images/icon-back.png" class="unified-back-icon" mode="aspectFit"></image>
|
||||
<text class="unified-back-text">返回</text>
|
||||
</view>
|
||||
<text class="unified-header-title">等级权益</text>
|
||||
<view class="unified-header-right"></view>
|
||||
</view>
|
||||
|
||||
<view class="content" style="padding-top: {{totalNavHeight}}px">
|
||||
<!-- 加载中 -->
|
||||
<view class="loading-state" wx:if="{{loading}}">
|
||||
<text>正在加载权益内容...</text>
|
||||
</view>
|
||||
|
||||
<!-- 权益内容 -->
|
||||
<view class="benefits-container" wx:elif="{{currentPackage}}">
|
||||
<view class="package-header" style="{{currentPackage.gradient}}">
|
||||
<view class="header-main">
|
||||
<app-icon name="crown" size="80" color="#ffffff" />
|
||||
<view class="header-info">
|
||||
<text class="package-title">{{currentPackage.title}}</text>
|
||||
<text class="package-subtitle">{{currentPackage.subtitle}}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="header-decoration"></view>
|
||||
</view>
|
||||
|
||||
<view class="benefits-section">
|
||||
<view class="section-title">
|
||||
<view class="title-line"></view>
|
||||
<text>专属权益内容</text>
|
||||
<view class="title-line"></view>
|
||||
</view>
|
||||
|
||||
<view class="benefits-list">
|
||||
<view class="benefit-item" wx:for="{{currentPackage.benefits}}" wx:key="*this">
|
||||
<view class="check-icon">
|
||||
<app-icon name="check" size="36" color="{{currentPackage.checkColor}}" />
|
||||
</view>
|
||||
<text class="benefit-text">{{item}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="footer-tip">
|
||||
<text>如有疑问,请咨询在线客服</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 未找到内容 -->
|
||||
<view class="empty-state" wx:else>
|
||||
<app-icon name="info" size="100" color="#9CA3AF" />
|
||||
<text>暂无该等级的权益说明</text>
|
||||
<button class="btn-reset back-btn" bindtap="onBack">返回我的</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
145
pages/membership-benefits/membership-benefits.wxss
Normal file
145
pages/membership-benefits/membership-benefits.wxss
Normal file
|
|
@ -0,0 +1,145 @@
|
|||
.page {
|
||||
min-height: 100vh;
|
||||
background: #F9FAFB;
|
||||
}
|
||||
|
||||
.content {
|
||||
padding: 32rpx;
|
||||
}
|
||||
|
||||
.loading-state, .empty-state {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding-top: 200rpx;
|
||||
color: #9CA3AF;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.empty-state text {
|
||||
margin-top: 24rpx;
|
||||
margin-bottom: 48rpx;
|
||||
}
|
||||
|
||||
.back-btn {
|
||||
background: #B06AB3;
|
||||
color: #ffffff;
|
||||
padding: 20rpx 60rpx;
|
||||
border-radius: 999rpx;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
/* Package Header */
|
||||
.package-header {
|
||||
border-radius: 48rpx;
|
||||
padding: 60rpx 48rpx;
|
||||
color: #ffffff;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 20rpx 40rpx rgba(0, 0, 0, 0.1);
|
||||
margin-bottom: 48rpx;
|
||||
}
|
||||
|
||||
.header-main {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 32rpx;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.header-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8rpx;
|
||||
}
|
||||
|
||||
.package-title {
|
||||
font-size: 48rpx;
|
||||
font-weight: 900;
|
||||
letter-spacing: 2rpx;
|
||||
}
|
||||
|
||||
.package-subtitle {
|
||||
font-size: 28rpx;
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.header-decoration {
|
||||
position: absolute;
|
||||
right: -40rpx;
|
||||
bottom: -40rpx;
|
||||
width: 240rpx;
|
||||
height: 240rpx;
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
border-radius: 50%;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
/* Benefits Section */
|
||||
.benefits-section {
|
||||
background: #ffffff;
|
||||
border-radius: 40rpx;
|
||||
padding: 48rpx 40rpx;
|
||||
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.02);
|
||||
}
|
||||
|
||||
.section-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 24rpx;
|
||||
margin-bottom: 48rpx;
|
||||
}
|
||||
|
||||
.section-title text {
|
||||
font-size: 32rpx;
|
||||
font-weight: 800;
|
||||
color: #111827;
|
||||
}
|
||||
|
||||
.title-line {
|
||||
flex: 1;
|
||||
height: 2rpx;
|
||||
background: #F3F4F6;
|
||||
max-width: 80rpx;
|
||||
}
|
||||
|
||||
.benefits-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 32rpx;
|
||||
}
|
||||
|
||||
.benefit-item {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 24rpx;
|
||||
}
|
||||
|
||||
.check-icon {
|
||||
width: 48rpx;
|
||||
height: 48rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: rgba(0, 0, 0, 0.03);
|
||||
border-radius: 50%;
|
||||
flex-shrink: 0;
|
||||
margin-top: 4rpx;
|
||||
}
|
||||
|
||||
.benefit-text {
|
||||
font-size: 30rpx;
|
||||
color: #374151;
|
||||
line-height: 1.6;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.footer-tip {
|
||||
text-align: center;
|
||||
margin-top: 60rpx;
|
||||
color: #9CA3AF;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
|
|
@ -447,20 +447,25 @@ page {
|
|||
|
||||
/* 空状态 */
|
||||
.empty-state {
|
||||
padding: 120rpx 32rpx;
|
||||
text-align: center;
|
||||
padding: 160rpx 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.empty-icon {
|
||||
width: 200rpx;
|
||||
height: 200rpx;
|
||||
margin: 0 auto 32rpx;
|
||||
opacity: 0.5;
|
||||
width: 320rpx;
|
||||
height: 320rpx;
|
||||
margin-bottom: 32rpx;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.empty-text {
|
||||
font-size: 28rpx;
|
||||
color: #81C784;
|
||||
font-size: 30rpx;
|
||||
color: #94A3B8;
|
||||
font-weight: 500;
|
||||
letter-spacing: 2rpx;
|
||||
}
|
||||
|
||||
/* 列表底部 */
|
||||
|
|
|
|||
|
|
@ -74,6 +74,9 @@ Page({
|
|||
} else {
|
||||
this.setData({
|
||||
me: { nickname: '未登录', avatar: this.data.defaultAvatar },
|
||||
vip: { levelText: '', levelClass: '' },
|
||||
isDistributor: false,
|
||||
distributorRole: '',
|
||||
balances: { grass: 0, commission: '0.00' },
|
||||
counts: { orders: 0, team: 0, performance: 0 },
|
||||
totalUnread: 0
|
||||
|
|
@ -143,10 +146,13 @@ Page({
|
|||
'partner': { text: '城市合伙人', class: 'vip-partner' }
|
||||
};
|
||||
|
||||
if (user.isDistributor && roleMap[distributorRole]) {
|
||||
if (roleMap[distributorRole]) {
|
||||
const info = roleMap[distributorRole];
|
||||
roleText = info.text;
|
||||
roleClass = info.class;
|
||||
} else if (user.isDistributor) {
|
||||
roleText = '分销商';
|
||||
roleClass = 'vip-normal';
|
||||
} else {
|
||||
// Fallback to VIP
|
||||
const vipLevel = Number(user.vip_level || 0);
|
||||
|
|
@ -159,7 +165,8 @@ Page({
|
|||
this.setData({
|
||||
me: { id, idShort, nickname, avatar, phone },
|
||||
vip: { levelText: roleText || '', levelClass: roleClass },
|
||||
isDistributor: !!user.isDistributor
|
||||
isDistributor: !!user.isDistributor,
|
||||
distributorRole: distributorRole // 保存角色以供权益页面使用
|
||||
});
|
||||
|
||||
// CRITICAL: Update global data and local storage to ensure avatar consistency across pages
|
||||
|
|
@ -287,6 +294,20 @@ Page({
|
|||
wx.navigateTo({ url: '/pages/recharge/recharge' });
|
||||
}
|
||||
},
|
||||
showBenefits() {
|
||||
if (this.requireLogin()) {
|
||||
const { distributorRole, vip } = this.data;
|
||||
// 如果没有角色且不是VIP,则跳转到充值页面
|
||||
if (!distributorRole && !vip.levelText) {
|
||||
this.goRecharge();
|
||||
return;
|
||||
}
|
||||
|
||||
wx.navigateTo({
|
||||
url: `/pages/membership-benefits/membership-benefits?role=${distributorRole || ''}&level=${vip.levelText || ''}`
|
||||
});
|
||||
}
|
||||
},
|
||||
goOrders() {
|
||||
if (this.requireLogin()) {
|
||||
wx.navigateTo({ url: '/pages/orders/orders' });
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
<view class="profile-info">
|
||||
<view class="name-row">
|
||||
<text class="nickname">{{me.nickname}}</text>
|
||||
<view class="vip-badge {{vip.levelClass}}" bindtap="goRecharge" wx:if="{{vip.levelText}}">
|
||||
<view class="vip-badge {{vip.levelClass}}" bindtap="showBenefits" wx:if="{{vip.levelText}}">
|
||||
<app-icon name="crown" size="24" color="#FFFFFF" />
|
||||
<text class="vip-text">{{vip.levelText}}</text>
|
||||
<app-icon name="chevron-right" size="20" color="#FFFFFF" />
|
||||
|
|
@ -168,7 +168,7 @@
|
|||
<view class="menu-item" bindtap="goEdit">
|
||||
<view class="menu-left">
|
||||
<app-icon name="settings" size="44" color="#9CA3AF" />
|
||||
<text class="menu-text">修改资料</text>
|
||||
<text class="menu-text">个人资料</text>
|
||||
</view>
|
||||
<app-icon name="chevron-right" size="36" color="#E5E7EB" />
|
||||
</view>
|
||||
|
|
|
|||
|
|
@ -96,27 +96,32 @@ page {
|
|||
.name-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 24rpx;
|
||||
gap: 16rpx;
|
||||
margin-bottom: 16rpx;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.nickname {
|
||||
font-size: 40rpx;
|
||||
font-size: 36rpx;
|
||||
font-weight: 900;
|
||||
color: #111827;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
max-width: 240rpx;
|
||||
flex-shrink: 1;
|
||||
}
|
||||
|
||||
.vip-badge {
|
||||
background: linear-gradient(90deg, #B06AB3, #8E44AD); /* Default/fallback */
|
||||
padding: 4rpx 20rpx;
|
||||
padding: 4rpx 16rpx;
|
||||
border-radius: 999rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8rpx;
|
||||
gap: 6rpx;
|
||||
box-shadow: 0 2rpx 4rpx rgba(0,0,0,0.1);
|
||||
flex-shrink: 0;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.vip-badge.vip-soulmate {
|
||||
|
|
|
|||
|
|
@ -410,20 +410,25 @@ page {
|
|||
|
||||
/* 空状态 */
|
||||
.empty-state {
|
||||
padding: 120rpx 32rpx;
|
||||
text-align: center;
|
||||
padding: 160rpx 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.empty-icon {
|
||||
width: 200rpx;
|
||||
height: 200rpx;
|
||||
margin: 0 auto 32rpx;
|
||||
opacity: 0.5;
|
||||
width: 320rpx;
|
||||
height: 320rpx;
|
||||
margin-bottom: 32rpx;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.empty-text {
|
||||
font-size: 28rpx;
|
||||
color: #F06292;
|
||||
font-size: 30rpx;
|
||||
color: #94A3B8;
|
||||
font-weight: 500;
|
||||
letter-spacing: 2rpx;
|
||||
}
|
||||
|
||||
/* 列表底部 */
|
||||
|
|
@ -481,18 +486,20 @@ page {
|
|||
position: absolute;
|
||||
top: 32rpx;
|
||||
right: 32rpx;
|
||||
width: 72rpx;
|
||||
height: 72rpx;
|
||||
background: #F1F5F9;
|
||||
width: 80rpx;
|
||||
height: 80rpx;
|
||||
background: #F8FAFC;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.close-icon {
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
width: 48rpx;
|
||||
height: 48rpx;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.modal-title {
|
||||
|
|
|
|||
|
|
@ -117,8 +117,9 @@
|
|||
/>
|
||||
</view>
|
||||
|
||||
<view class="figma-send-btn" wx:if="{{inputText.length > 0}}" bindtap="onSend">
|
||||
<view class="figma-send-btn {{inputText.length > 0 ? 'active' : ''}}" bindtap="onSend">
|
||||
<image src="/images/icon-send.png" class="figma-btn-icon" mode="aspectFit"></image>
|
||||
<text class="send-text">发送</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
|
|
|||
|
|
@ -279,9 +279,9 @@
|
|||
flex: 1;
|
||||
background: #F9FAFB;
|
||||
border: 2rpx solid #F3F4F6;
|
||||
border-radius: 32rpx;
|
||||
border-radius: 40rpx;
|
||||
padding: 0 32rpx;
|
||||
height: 96rpx;
|
||||
height: 120rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
|
@ -289,22 +289,43 @@
|
|||
.figma-text-input {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
font-size: 34rpx;
|
||||
font-size: 38rpx;
|
||||
color: #101828;
|
||||
}
|
||||
|
||||
.figma-send-btn {
|
||||
width: 88rpx;
|
||||
width: 180rpx;
|
||||
height: 88rpx;
|
||||
background: #914584;
|
||||
border-radius: 50%;
|
||||
background: #F3F4F6;
|
||||
border-radius: 44rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 8rpx;
|
||||
flex-shrink: 0;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.figma-send-btn.active {
|
||||
background: #914584;
|
||||
}
|
||||
|
||||
.figma-btn-icon {
|
||||
width: 44rpx;
|
||||
height: 44rpx;
|
||||
width: 36rpx;
|
||||
height: 36rpx;
|
||||
filter: grayscale(1) opacity(0.5);
|
||||
}
|
||||
|
||||
.figma-send-btn.active .figma-btn-icon {
|
||||
filter: brightness(0) invert(1);
|
||||
}
|
||||
|
||||
.send-text {
|
||||
font-size: 28rpx;
|
||||
font-weight: 700;
|
||||
color: #9CA3AF;
|
||||
}
|
||||
|
||||
.figma-send-btn.active .send-text {
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,16 +37,52 @@ Page({
|
|||
try {
|
||||
const statsRes = await request({ url: '/api/commission?action=stats', method: 'GET' });
|
||||
const statsBody = statsRes.data || {};
|
||||
|
||||
let currentRoleText = '守护会员'; // 默认
|
||||
|
||||
// 尝试从本地存储获取当前用户信息来判断角色
|
||||
try {
|
||||
const userStr = wx.getStorageSync('user');
|
||||
if (userStr) {
|
||||
const user = JSON.parse(userStr);
|
||||
// 优先使用 distributorRole,其次 userRole,再次 vip_level
|
||||
const role = user.distributorRole || user.userRole;
|
||||
const roleMap = {
|
||||
'soulmate': '心伴会员',
|
||||
'guardian': '守护会员',
|
||||
'companion': '陪伴会员',
|
||||
'listener': '倾听会员',
|
||||
'partner': '城市合伙人'
|
||||
};
|
||||
if (role && roleMap[role]) {
|
||||
currentRoleText = roleMap[role];
|
||||
} else if (user.isDistributor) {
|
||||
// 如果是分销商但没有明确role,可能是早期数据,根据cardType判断
|
||||
// 但这里更直接用API返回的
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('解析用户信息失败', e);
|
||||
}
|
||||
|
||||
if (statsBody.success) {
|
||||
const d = statsBody.data || {};
|
||||
// 如果API返回了明确的等级名称或类型,优先使用API的
|
||||
if (d.cardType || d.level) {
|
||||
currentRoleText = this.getCardTitle(d.cardType || d.level);
|
||||
}
|
||||
|
||||
this.setData({
|
||||
stats: {
|
||||
todayReferrals: Number(d.todayReferrals || d.today_referrals || 0),
|
||||
totalReferrals: Number(d.totalReferrals || d.total_referrals || 0),
|
||||
totalContribution: Number(d.totalContribution || d.total_contribution || 0).toFixed(2)
|
||||
},
|
||||
cardTitle: this.getCardTitle(d.cardType || d.level || 'guardian_card')
|
||||
cardTitle: currentRoleText
|
||||
});
|
||||
} else {
|
||||
// API不成功,使用本地推断的角色
|
||||
this.setData({ cardTitle: currentRoleText });
|
||||
}
|
||||
|
||||
const res = await request({ url: '/api/commission?action=referrals&page=1&pageSize=50', method: 'GET' });
|
||||
|
|
@ -137,11 +173,17 @@ Page({
|
|||
const map = {
|
||||
'guardian_card': '守护会员',
|
||||
'companion_card': '陪伴会员',
|
||||
'soulmate_card': '心伴会员',
|
||||
'listener_card': '倾听会员',
|
||||
'guardian': '守护会员',
|
||||
'companion': '陪伴会员',
|
||||
'soulmate': '心伴会员',
|
||||
'listener': '倾听会员',
|
||||
'identity_card': '身份会员',
|
||||
'vip': 'VIP会员',
|
||||
'partner': '城市合伙人'
|
||||
};
|
||||
return map[type] || '守护会员';
|
||||
return map[type] || type || '守护会员';
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -453,20 +453,25 @@ page {
|
|||
|
||||
/* 空状态 */
|
||||
.empty-state {
|
||||
padding: 120rpx 32rpx;
|
||||
text-align: center;
|
||||
padding: 160rpx 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.empty-icon {
|
||||
width: 200rpx;
|
||||
height: 200rpx;
|
||||
margin: 0 auto 32rpx;
|
||||
opacity: 0.5;
|
||||
width: 320rpx;
|
||||
height: 320rpx;
|
||||
margin-bottom: 32rpx;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.empty-text {
|
||||
font-size: 28rpx;
|
||||
color: #9575CD;
|
||||
font-size: 30rpx;
|
||||
color: #94A3B8;
|
||||
font-weight: 500;
|
||||
letter-spacing: 2rpx;
|
||||
}
|
||||
|
||||
/* 二维码弹窗 */
|
||||
|
|
|
|||
|
|
@ -53,6 +53,17 @@
|
|||
<button class="btn-reset submit-btn" bindtap="submit" disabled="{{submitting}}">
|
||||
{{submitting ? '处理中...' : '立即提现'}}
|
||||
</button>
|
||||
|
||||
<!-- 提现说明 -->
|
||||
<view class="instruction-section">
|
||||
<view class="instruction-title">提现说明:</view>
|
||||
<view class="instruction-list">
|
||||
<view class="instruction-item">1. 单笔提现10-2000元,支持分多笔申请;</view>
|
||||
<view class="instruction-item">2. 提现扣除一定手续费,实际到账金额实时展示;</view>
|
||||
<view class="instruction-item">3. T+1工作日到账(不含节假日/周末),收款账户需实名一致;</view>
|
||||
<view class="instruction-item">4. 禁止违规获利,否则平台有权拒绝提现。</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- Records Section -->
|
||||
|
|
|
|||
|
|
@ -184,6 +184,39 @@
|
|||
box-shadow: none;
|
||||
}
|
||||
|
||||
/* 提现说明 */
|
||||
.instruction-section {
|
||||
margin-top: 64rpx;
|
||||
padding: 40rpx;
|
||||
background: #F9FAFB;
|
||||
border-radius: 32rpx;
|
||||
border: 2rpx dashed #E5E7EB;
|
||||
margin-bottom: 40rpx;
|
||||
}
|
||||
|
||||
.instruction-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: 800;
|
||||
color: #374151;
|
||||
margin-bottom: 24rpx;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.instruction-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20rpx;
|
||||
}
|
||||
|
||||
.instruction-item {
|
||||
font-size: 28rpx;
|
||||
color: #4B5563;
|
||||
line-height: 1.7;
|
||||
position: relative;
|
||||
padding-left: 4rpx;
|
||||
}
|
||||
|
||||
|
||||
/* Records Section */
|
||||
.records-section {
|
||||
margin-top: 48rpx;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"libVersion": "3.13.1",
|
||||
"projectname": "%E5%BF%83%E4%BC%B4",
|
||||
"projectname": "ai-c",
|
||||
"condition": {},
|
||||
"setting": {
|
||||
"urlCheck": false,
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user