后端 API:AI 对话/报告/余额告警 等服务与路由;小程序 tabBar 配置与分润相关能力;出站推送 Webhook 与管理端调试;飞书留资、小程序数据分析 等支撑;多份 数据库迁移(AI 聊天、灵魂文章、tabBar、分润等)。 管理端 / 超管:看板、用户/订单/分销/财务、设置与 小程序 tabBar 管理、分润规则、灵魂文章、AI 配置与监控 等大量页面与能力扩展;主题与布局更新。 抖音小程序:与微信侧在 结果页/购买/个人中心 等方向做了同步或优化。 另含 部署/脚本、开发文档 等配套更新。 邀请码与解锁:后端 分销/邀请码 接口与 add_invite_codes 等 SQL;小程序侧 邀请码弹窗组件、个人中心/推广/多类结果页 的填写入口与 解锁门控(inviteCodeGate、unlockGate);并补充 《小程序解锁引导与邀请码方案》 文档。 超管后台:路由与 企业中心(EnterpriseHub) 等交互与结构优化。 小程序体验:在 首页结果、推广、各测评结果页 上继续打磨;与 邀请码门控、审核门控 小步联动。
255 lines
11 KiB
Plaintext
255 lines
11 KiB
Plaintext
<!--pages/profile/index.wxml-->
|
||
<view class="page tabbar-pad">
|
||
|
||
<!-- 顶部栏 -->
|
||
<view class="topbar">
|
||
<text class="topbar-title">我的</text>
|
||
<view class="topbar-actions">
|
||
<!-- <view class="settings-btn" bindtap="goToSettings">
|
||
<text class="settings-icon">⚙️</text>
|
||
</view> -->
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 用户卡片:未登录点击登录,已登录点击进入个人资料(合并双态) -->
|
||
<view class="user-card" bindtap="onUserCardTap">
|
||
<!-- 头像区:已登录显示用户头像 + 在线点,未登录仅字母圆 -->
|
||
<view class="avatar-wrap">
|
||
<view class="avatar-ring">
|
||
<image wx:if="{{hasLogin && userInfo && (userInfo.avatarUrl || userInfo.avatar)}}"
|
||
class="avatar-img"
|
||
src="{{userInfo.avatarUrl || userInfo.avatar}}"
|
||
mode="aspectFill"/>
|
||
<view wx:else class="avatar-letter-wrap" style="background:{{avatarBgColor}}">
|
||
<text class="avatar-letter">{{avatarLetter}}</text>
|
||
</view>
|
||
</view>
|
||
<view wx:if="{{hasLogin}}" class="online-dot"></view>
|
||
</view>
|
||
|
||
<!-- 元信息:已登录昵称+标签;未登录登录提示 -->
|
||
<view class="user-meta">
|
||
<block wx:if="{{hasLogin}}">
|
||
<text class="nickname-text">{{nicknameDisplay || '点击设置昵称'}}</text>
|
||
<scroll-view scroll-x class="tags-scroll">
|
||
<view class="tags-row">
|
||
<view class="tag tag-purple" wx:if="{{mbtiType && permMbti}}">
|
||
<text class="tag-text">{{mbtiType}}</text>
|
||
</view>
|
||
<view class="tag tag-sbti" wx:if="{{sbtiType && permSbti}}">
|
||
<text class="tag-text">{{sbtiType}}</text>
|
||
</view>
|
||
<view class="tag tag-blue" wx:if="{{discType && permDisc}}">
|
||
<text class="tag-text">{{discType}}</text>
|
||
</view>
|
||
<view class="tag tag-orange" wx:if="{{pdpType && permPdp}}">
|
||
<text class="tag-text">{{pdpType}}</text>
|
||
</view>
|
||
<view class="tag tag-gray" wx:if="{{showEmptyPersonalityTags}}">
|
||
<text class="tag-text">暂无测试记录</text>
|
||
</view>
|
||
</view>
|
||
</scroll-view>
|
||
</block>
|
||
<block wx:else>
|
||
<text class="user-name" wx:if="{{loginLoading}}">登录中...</text>
|
||
<text class="user-name" wx:elif="{{loginFailed}}">登录失败,点击重试</text>
|
||
<text class="user-name" wx:else>点击登录</text>
|
||
<text class="user-sub">登录后查看你的测试结果</text>
|
||
</block>
|
||
</view>
|
||
|
||
<text class="chevron">›</text>
|
||
</view>
|
||
|
||
<!-- 数据条:测试数 / 邀请 / 收益 / 可提现(营销数据融入身份,不再独立突兀卡) -->
|
||
<view class="user-stats" wx:if="{{hasLogin}}">
|
||
<view class="user-stat" bindtap="goToHistory">
|
||
<text class="user-stat__v">{{testCount || 0}}</text>
|
||
<text class="user-stat__l">测评记录</text>
|
||
</view>
|
||
<view
|
||
class="user-stat"
|
||
wx:if="{{promoDistributionEnabled && !reviewMode && !mpAuditMode && permDistribution}}"
|
||
bindtap="goToPromo"
|
||
>
|
||
<text class="user-stat__v">{{promoTotalInvite || 0}}</text>
|
||
<text class="user-stat__l">邀请好友</text>
|
||
</view>
|
||
<!-- 第三格:可提现 → 分销中心 -->
|
||
<view
|
||
class="user-stat user-stat--highlight"
|
||
wx:if="{{promoDistributionEnabled && !reviewMode && !mpAuditMode && permDistribution}}"
|
||
bindtap="goToPromo"
|
||
>
|
||
<text class="user-stat__v">¥{{promoWithdrawable || '0.00'}}</text>
|
||
<text class="user-stat__l">可提现 ›</text>
|
||
</view>
|
||
<!-- 第四格:累计 → 提现记录 -->
|
||
<view
|
||
class="user-stat user-stat--sub"
|
||
wx:if="{{promoDistributionEnabled && !reviewMode && !mpAuditMode && permDistribution}}"
|
||
bindtap="goToPromoWithdrawals"
|
||
>
|
||
<text class="user-stat__v user-stat__v--sm">¥{{promoTotalEarned || '0.00'}}</text>
|
||
<text class="user-stat__l">累计 ›</text>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- <view
|
||
class="invite-strip"
|
||
wx:if="{{hasLogin && permDistribution && !reviewMode && !mpAuditMode}}"
|
||
bindtap="onInviteStripTap"
|
||
>
|
||
<view class="invite-strip__text">
|
||
<text class="invite-strip__label">我的邀请码</text>
|
||
<text wx:if="{{myInviteCodeLoadState === 'loading'}}" class="invite-strip__muted">加载中…</text>
|
||
<text wx:elif="{{myInviteCodeLoadState === 'error'}}" class="invite-strip__err">{{myInviteCodeErrMsg}}</text>
|
||
<text wx:elif="{{myInviteCodeLoadState === 'ready' && myInviteCode}}" class="invite-strip__code">{{myInviteCode}}</text>
|
||
<text wx:else class="invite-strip__err">{{myInviteCodeHint}}</text>
|
||
</view>
|
||
<view class="invite-strip__side">
|
||
<button
|
||
wx:if="{{myInviteCodeLoadState === 'ready' && myInviteCode}}"
|
||
class="invite-strip__copy"
|
||
hover-class="none"
|
||
catchtap="copyMyInviteCode"
|
||
>复制</button>
|
||
<text wx:elif="{{myInviteCodeLoadState === 'error'}}" class="invite-strip__retry-hint">点击重试</text>
|
||
<text wx:else class="invite-strip__hint">{{myInviteCodeLoadState === 'loading' ? '请稍候' : '解锁付费前填写 ›'}}</text>
|
||
</view>
|
||
</view> -->
|
||
|
||
<!-- <view
|
||
class="invite-fill-row"
|
||
wx:if="{{hasLogin && permDistribution && !reviewMode && !mpAuditMode}}"
|
||
bindtap="openInviteCodeFill"
|
||
>
|
||
<text class="invite-fill-row__label">我有好友邀请码</text>
|
||
<text class="invite-fill-row__arrow">›</text>
|
||
</view> -->
|
||
|
||
<!-- 我的测评:最新测试横滑 + 功能图标网格(Soul 风:图标网格代替长列表) -->
|
||
<view class="section px-section" wx:if="{{hasLogin}}">
|
||
<view class="sec-head">
|
||
<text class="sec-head__title">我的测评</text>
|
||
<view class="sec-head__link" bindtap="goToHistory">
|
||
<text>全部<text wx:if="{{testCount > 0}}"> · {{testCount}}</text></text>
|
||
<text class="sec-head__chev">›</text>
|
||
</view>
|
||
</view>
|
||
<view class="depth-unified-card">
|
||
<scroll-view wx:if="{{showLatestTestRow}}" scroll-x class="cards-scroll cards-scroll--in-card" enhanced show-scrollbar="{{false}}">
|
||
<view class="cards-row cards-row--in-card">
|
||
<view class="result-card card-purple {{mbtiType ? '' : 'result-card--placeholder'}}" bindtap="viewMBTI" wx:if="{{permMbti}}">
|
||
<view class="card-deco"></view>
|
||
<view class="card-icon-wrap card-icon-purple">
|
||
<text class="card-icon">🧠</text>
|
||
</view>
|
||
<text class="card-label">MBTI性格</text>
|
||
<text class="card-value">{{mbtiType || '未测评'}}</text>
|
||
<text class="card-time">{{mbtiTime || '—'}}</text>
|
||
</view>
|
||
<view class="result-card card-sbti {{sbtiType ? '' : 'result-card--placeholder'}}" bindtap="viewSBTI" wx:if="{{permSbti}}">
|
||
<view class="card-deco"></view>
|
||
<view class="card-icon-wrap card-icon-sbti">
|
||
<text class="card-icon">🎭</text>
|
||
</view>
|
||
<text class="card-label">SBTI</text>
|
||
<text class="card-value">{{sbtiType || '未测评'}}</text>
|
||
<text class="card-time">{{sbtiTime || '—'}}</text>
|
||
</view>
|
||
<view class="result-card card-orange {{pdpType ? '' : 'result-card--placeholder'}}" bindtap="viewPDP" wx:if="{{permPdp}}">
|
||
<view class="card-deco"></view>
|
||
<view class="card-icon-wrap card-icon-orange">
|
||
<text class="card-icon">🦁</text>
|
||
</view>
|
||
<text class="card-label">PDP行为</text>
|
||
<text class="card-value">{{pdpType || '未测评'}}</text>
|
||
<text class="card-time">{{pdpTime || '—'}}</text>
|
||
</view>
|
||
<view class="result-card card-blue {{discType ? '' : 'result-card--placeholder'}}" bindtap="viewDISC" wx:if="{{permDisc}}">
|
||
<view class="card-deco"></view>
|
||
<view class="card-icon-wrap card-icon-blue">
|
||
<text class="card-icon">📊</text>
|
||
</view>
|
||
<text class="card-label">DISC测评</text>
|
||
<text class="card-value">{{discType || '未测评'}}</text>
|
||
<text class="card-time">{{discTime || '—'}}</text>
|
||
</view>
|
||
<view class="result-card card-teal {{(gallupPreview || aiType) ? '' : 'result-card--placeholder'}}" bindtap="viewGallup" wx:if="{{!reviewMode && !mpAuditMode && permFace}}">
|
||
<view class="card-deco"></view>
|
||
<view class="card-icon-wrap card-icon-teal">
|
||
<text class="card-icon">⭐</text>
|
||
</view>
|
||
<text class="card-label">盖洛普优势</text>
|
||
<text class="card-value card-value--small">{{gallupPreview || (aiType ? '见面相报告' : '未测评')}}</text>
|
||
<text class="card-time">{{aiTime || '—'}}</text>
|
||
</view>
|
||
<view class="result-card card-rose {{aiType ? '' : 'result-card--placeholder'}}" bindtap="viewAI" wx:if="{{!reviewMode && !mpAuditMode && permFace}}">
|
||
<view class="card-deco"></view>
|
||
<view class="card-icon-wrap card-icon-rose">
|
||
<text class="card-icon">👁️</text>
|
||
</view>
|
||
<text class="card-label">面相分析</text>
|
||
<text class="card-value">{{aiType || '未测评'}}</text>
|
||
<text class="card-time">{{aiTime || '—'}}</text>
|
||
</view>
|
||
</view>
|
||
</scroll-view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 快捷入口图标网格(Soul 风:2×N 图标 + 短标题) -->
|
||
<view class="section px-section" wx:if="{{hasLogin}}">
|
||
<view class="quick-grid quick-grid--4">
|
||
<view class="quick-grid__item" bindtap="goToTestSelect">
|
||
<view class="quick-grid__ic quick-grid__ic--purple">🧠</view>
|
||
<text class="quick-grid__label">性格测试</text>
|
||
</view>
|
||
<view class="quick-grid__item" bindtap="goToOrders">
|
||
<view class="quick-grid__ic quick-grid__ic--emerald">🧾</view>
|
||
<text class="quick-grid__label">我的订单</text>
|
||
</view>
|
||
<view class="quick-grid__item" wx:if="{{showDeepPricingEntry}}" bindtap="goToDeepService">
|
||
<view class="quick-grid__ic quick-grid__ic--indigo">💎</view>
|
||
<text class="quick-grid__label">了解自己</text>
|
||
</view>
|
||
<view class="quick-grid__item" bindtap="goToMatchJob">
|
||
<view class="quick-grid__ic quick-grid__ic--blue">💼</view>
|
||
<text class="quick-grid__label">匹配工作</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- Soul 引流:超管「我的页展示首条」+ 当前推荐第 1 篇 -->
|
||
<view class="section px-section profile-reco-wrap" wx:if="{{hasLogin && profileRecoShow}}">
|
||
<view
|
||
class="profile-reco-card"
|
||
hover-class="profile-reco-card--press"
|
||
bindtap="onTapProfileReco"
|
||
data-id="{{profileRecoArticle.id}}"
|
||
data-url="{{profileRecoArticle.url}}"
|
||
data-title="{{profileRecoArticle.title}}"
|
||
data-source-id="{{profileRecoArticle.sourceId}}"
|
||
>
|
||
<text class="profile-reco-label">{{profileRecoSectionLabel}}</text>
|
||
<view class="profile-reco-row">
|
||
<text class="profile-reco-title">{{profileRecoArticle.title}}</text>
|
||
<text class="profile-reco-chev">›</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 分销/提现入口已上移至数据条下方(promo-quick-bar) -->
|
||
|
||
<invite-code-dialog
|
||
visible="{{showInviteCodeDialog}}"
|
||
bind:skip="onInviteCodeSkip"
|
||
bind:success="onInviteCodeSuccess"
|
||
/>
|
||
|
||
<view class="bottom-safe"></view>
|
||
<custom-tab-bar />
|
||
</view>
|