1771 行
53 KiB
Vue
1771 行
53 KiB
Vue
<!-- 团队作战管理中心 -->
|
||
<template>
|
||
<s-layout title="我的团队" :class="state.scrollTop ? 'team-wrap' : ''" navbar="inner">
|
||
<!-- 头部看板区 -->
|
||
<view
|
||
class="header-box"
|
||
:style="[
|
||
{
|
||
marginTop: '-' + Number(statusBarHeight + 88) + 'rpx',
|
||
paddingTop: Number(statusBarHeight + 108) + 'rpx',
|
||
},
|
||
]"
|
||
>
|
||
<!-- 推荐人 -->
|
||
<view v-if="userInfo.parent_user" class="referrer-box ss-flex ss-col-center">
|
||
<text class="referrer-label">推荐人:</text>
|
||
<image
|
||
class="referrer-avatar ss-m-r-10"
|
||
:src="sheep.$url.cdn(userInfo.parent_user.avatar)"
|
||
mode="aspectFill"
|
||
></image>
|
||
<text class="referrer-name">{{ userInfo.parent_user.nickname }}</text>
|
||
</view>
|
||
|
||
<!-- 专属邀请码与拓展卡片 -->
|
||
<view class="invite-action-card ss-flex ss-row-between ss-col-center">
|
||
<view class="invite-code-wrap ss-flex ss-col-center">
|
||
<text class="invite-label">专属邀请码:</text>
|
||
<text class="invite-code">HL{{ userInfo.id || '---' }}</text>
|
||
<button class="ss-reset-button copy-code-btn ss-m-l-10" @tap="onCopyInviteCode">复制</button>
|
||
</view>
|
||
<view class="invite-btn-group ss-flex ss-col-center">
|
||
<button class="ss-reset-button invite-btn-poster ss-flex ss-col-center" @tap="onOpenShareModal">
|
||
<uni-icons type="image" size="14" color="#ffffff"></uni-icons>
|
||
<text class="ss-m-l-6">邀请海报</text>
|
||
</button>
|
||
<button class="ss-reset-button invite-btn-link ss-m-l-12 ss-flex ss-col-center" @tap="onCopyShareLink">
|
||
<uni-icons type="link" size="14" color="#ff6000"></uni-icons>
|
||
<text class="ss-m-l-6">复制链接</text>
|
||
</button>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 团队核心数据总览卡片(直推人数 与 团队总人数) -->
|
||
<view class="team-data-box ss-flex ss-col-center ss-row-between">
|
||
<!-- 直推人数卡片 -->
|
||
<view class="data-card ss-flex-1 ss-m-r-16">
|
||
<view class="item-title">
|
||
{{ currentDrillUser ? (currentDrillUser.nickname + '的直推(人)') : '直推人数(人)' }}
|
||
</view>
|
||
<view class="total-num text-orange">
|
||
{{ getDirectCount() }}
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 团队总人数卡片 -->
|
||
<view class="data-card ss-flex-1">
|
||
<view class="item-title">
|
||
{{ currentDrillUser ? (currentDrillUser.nickname + '的团队(人)') : '团队总人数(人)' }}
|
||
</view>
|
||
<view class="total-num">
|
||
{{ getTeamCount() }}
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 团队收益与业绩统计大盘 -->
|
||
<view class="team-wealth-box ss-flex ss-col-center ss-row-between">
|
||
<view class="wealth-card ss-flex-1 ss-m-r-16">
|
||
<view class="wealth-title">团队贡献总收益(元)</view>
|
||
<view class="wealth-num text-orange">¥{{ state.summary.team_total_reward || '0.00' }}</view>
|
||
<view class="wealth-sub">本月贡献: ¥{{ state.summary.team_month_reward || '0.00' }}</view>
|
||
</view>
|
||
<view class="wealth-card ss-flex-1">
|
||
<view class="wealth-title">团队自购总业绩(元)</view>
|
||
<view class="wealth-num text-gold">¥{{ state.summary.team_total_consume || '0.00' }}</view>
|
||
<view class="wealth-sub">团队累计订单: {{ state.summary.team_order_count || 0 }} 笔</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 30天自购保活健康度胶囊条 -->
|
||
<view class="health-bar ss-flex ss-row-between ss-col-center">
|
||
<view class="health-title">保活健康度:</view>
|
||
<view class="health-pills ss-flex ss-col-center">
|
||
<view
|
||
class="health-pill pill-active"
|
||
:class="{ 'pill-selected': state.currentFilter === 'active' }"
|
||
@tap="onToggleStatusFilter('active')"
|
||
>
|
||
<text class="status-dot dot-green"></text>
|
||
<text class="pill-label">正常活跃 {{ state.summary.active_count || 0 }}</text>
|
||
</view>
|
||
<view
|
||
class="health-pill pill-expiring"
|
||
:class="{ 'pill-selected': state.currentFilter === 'expiring' }"
|
||
@tap="onToggleStatusFilter('expiring')"
|
||
>
|
||
<text class="status-dot dot-yellow"></text>
|
||
<text class="pill-label">临期预警 {{ state.summary.expiring_count || 0 }}</text>
|
||
</view>
|
||
<view
|
||
class="health-pill pill-inactive"
|
||
:class="{ 'pill-selected': state.currentFilter === 'inactive' }"
|
||
@tap="onToggleStatusFilter('inactive')"
|
||
>
|
||
<text class="status-dot dot-gray"></text>
|
||
<text class="pill-label">已暂停 {{ state.summary.inactive_count || 0 }}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 吸顶控制台(搜索 + 层级Tab + 快捷筛选) -->
|
||
<su-sticky bgColor="#ffffff">
|
||
<view class="control-panel">
|
||
<!-- 搜索输入栏 -->
|
||
<view class="search-bar-box ss-flex ss-col-center">
|
||
<view class="search-input-wrap ss-flex ss-col-center ss-flex-1">
|
||
<uni-icons type="search" size="18" color="#999999"></uni-icons>
|
||
<input
|
||
class="search-input"
|
||
type="text"
|
||
v-model="state.keyword"
|
||
confirm-type="search"
|
||
placeholder="搜索成员昵称 / 手机号 / ID"
|
||
placeholder-class="search-placeholder"
|
||
@confirm="onSearchConfirm"
|
||
/>
|
||
<view v-if="state.keyword" class="clear-btn" @tap="onClearKeyword">
|
||
<uni-icons type="clear" size="16" color="#bbbbbb"></uni-icons>
|
||
</view>
|
||
</view>
|
||
<button class="ss-reset-button search-btn" @tap="onSearchConfirm">搜索</button>
|
||
</view>
|
||
|
||
<!-- 层级下钻路径与导航栏 -->
|
||
<view v-if="state.drillStack.length === 0" class="drill-nav-bar root-nav ss-flex ss-row-between ss-col-center">
|
||
<view class="nav-left ss-flex ss-col-center">
|
||
<view class="nav-icon-box ss-flex ss-row-center ss-col-center">
|
||
<uni-icons type="personadd-filled" size="14" color="#ff6000"></uni-icons>
|
||
</view>
|
||
<text class="nav-root-title ss-m-l-10">我的直推团队</text>
|
||
<text class="nav-root-count ss-m-l-8">({{ state.pagination.total || 0 }}人)</text>
|
||
</view>
|
||
<view class="nav-hint ss-flex ss-col-center">
|
||
<text class="hint-text">点击成员可下钻其直推</text>
|
||
<uni-icons type="forward" size="12" color="#999999"></uni-icons>
|
||
</view>
|
||
</view>
|
||
|
||
<view v-else class="drill-nav-bar in-drill-nav ss-flex ss-row-between ss-col-center">
|
||
<view class="drill-back-btn ss-flex ss-col-center" @tap="onDrillBack">
|
||
<uni-icons type="left" size="16" color="#ff6000"></uni-icons>
|
||
<text class="back-text">返回上一层</text>
|
||
</view>
|
||
<view class="drill-breadcrumb ss-flex ss-col-center ss-flex-1 ss-m-x-12">
|
||
<scroll-view scroll-x :show-scrollbar="false" class="breadcrumb-scroll">
|
||
<view class="breadcrumb-inner ss-flex ss-col-center">
|
||
<text class="crumb-link" @tap="onDrillRoot">我的直推</text>
|
||
<template v-for="(node, index) in state.drillStack" :key="node.id">
|
||
<text class="crumb-sep">/</text>
|
||
<text
|
||
class="crumb-node"
|
||
:class="{ 'crumb-current': index === state.drillStack.length - 1 }"
|
||
@tap="onJumpDrillIndex(index)"
|
||
>
|
||
{{ node.nickname }}
|
||
</text>
|
||
</template>
|
||
</view>
|
||
</scroll-view>
|
||
</view>
|
||
<button class="ss-reset-button drill-reset-btn" @tap="onDrillRoot">回到我的</button>
|
||
</view>
|
||
|
||
<!-- 快捷多维胶囊筛选条 -->
|
||
<scroll-view class="filter-scroll-wrap" scroll-x :show-scrollbar="false">
|
||
<view class="filter-scroll-content ss-flex ss-col-center">
|
||
<view
|
||
v-for="pill in filterPills"
|
||
:key="pill.value"
|
||
class="filter-chip"
|
||
:class="{ 'chip-active': state.currentFilter === pill.value && state.currentSort === 'createtime' }"
|
||
@tap="onFilterChipChange(pill.value)"
|
||
>
|
||
{{ pill.label }}
|
||
</view>
|
||
<view class="chip-divider"></view>
|
||
<view
|
||
v-for="sortItem in sortOptions"
|
||
:key="sortItem.value"
|
||
class="filter-chip sort-chip"
|
||
:class="{ 'chip-active': state.currentSort === sortItem.value }"
|
||
@tap="onSortOptionChange(sortItem.value)"
|
||
>
|
||
{{ sortItem.label }}
|
||
</view>
|
||
</view>
|
||
</scroll-view>
|
||
</view>
|
||
</su-sticky>
|
||
|
||
<!-- 成员卡片列表 -->
|
||
<view class="member-list-box ss-p-t-20">
|
||
<view
|
||
v-for="item in state.pagination.data"
|
||
:key="item.id"
|
||
class="member-card"
|
||
@tap="onOpenMemberDetail(item)"
|
||
>
|
||
<!-- 成员卡片头部 -->
|
||
<view class="member-card-header ss-flex ss-col-center ss-row-between">
|
||
<view class="member-base ss-flex ss-col-center">
|
||
<image
|
||
class="member-avatar"
|
||
:src="sheep.$url.cdn(item.avatar)"
|
||
mode="aspectFill"
|
||
></image>
|
||
<view class="member-profile ss-m-l-16">
|
||
<view class="member-name-row ss-flex ss-col-center">
|
||
<text class="member-name ss-line-1">{{ item.nickname || '微信用户' }}</text>
|
||
<text class="level-badge badge-direct">直推成员</text>
|
||
</view>
|
||
<view class="member-sub-info ss-flex ss-col-center ss-m-t-4" v-if="item.mobile_hide || item.id">
|
||
<text class="member-phone" v-if="item.mobile_hide">{{ item.mobile_hide }}</text>
|
||
<text class="member-id-tag ss-m-l-8">ID: {{ item.id }}</text>
|
||
</view>
|
||
<view class="member-meta-row ss-flex ss-col-center ss-m-t-8">
|
||
<!-- 身份徽章 -->
|
||
<view v-if="memberLevelName(item)" class="tag-box ss-flex ss-col-center">
|
||
<image
|
||
v-if="item.agent?.level_info?.image"
|
||
class="tag-img"
|
||
:src="sheep.$url.cdn(item.agent.level_info.image)"
|
||
mode="aspectFill"
|
||
></image>
|
||
<text class="tag-title">{{ memberLevelName(item) }}</text>
|
||
</view>
|
||
<view
|
||
v-if="item.agent?.is_venue || item.agent?.identities?.includes('venue')"
|
||
class="mini-tag tag-venue"
|
||
>
|
||
{{ roleNames.venue || '酒道馆' }}
|
||
</view>
|
||
<view
|
||
v-if="item.agent?.is_county || item.agent?.identities?.includes('county')"
|
||
class="mini-tag tag-county"
|
||
>
|
||
{{ roleNames.county || '区县代理' }}
|
||
</view>
|
||
<view
|
||
v-if="item.agent?.is_partner || item.agent?.identities?.includes('partner')"
|
||
class="mini-tag tag-partner"
|
||
>
|
||
{{ roleNames.partner || '合伙股东' }}
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 活跃状态指示灯 -->
|
||
<view class="status-indicator">
|
||
<view v-if="item.active_status === 'active'" class="status-pill pill-green">
|
||
<text class="status-dot dot-green"></text>
|
||
<text>活跃中</text>
|
||
</view>
|
||
<view v-else-if="item.active_status === 'expiring'" class="status-pill pill-amber">
|
||
<text class="status-dot dot-yellow"></text>
|
||
<text>剩 {{ item.days_remaining }} 天</text>
|
||
</view>
|
||
<view v-else class="status-pill pill-gray">
|
||
<text class="status-dot dot-gray"></text>
|
||
<text>奖励已暂停</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 经营指标看板 -->
|
||
<view class="metrics-grid ss-flex ss-col-center ss-row-between ss-m-t-20">
|
||
<view
|
||
class="metric-col ss-flex-col ss-col-center"
|
||
:class="{ 'metric-clickable': Number(item.child_user_count_1) > 0 }"
|
||
@tap.stop="Number(item.child_user_count_1) > 0 && onDrillDown(item)"
|
||
>
|
||
<view class="metric-val-wrap ss-flex ss-col-center">
|
||
<text class="metric-val" :class="{ 'text-orange': Number(item.child_user_count_1) > 0 }">
|
||
{{ item.child_user_count_1 || 0 }}
|
||
</text>
|
||
<text v-if="Number(item.child_user_count_1) > 0" class="drill-tag ss-m-l-6">下钻</text>
|
||
</view>
|
||
<view class="metric-lbl">直推好友(人)</view>
|
||
</view>
|
||
<view class="metric-divider"></view>
|
||
<view class="metric-col ss-flex-col ss-col-center">
|
||
<view class="metric-val">{{ item.order_count || 0 }}</view>
|
||
<view class="metric-lbl">累计订单(单)</view>
|
||
</view>
|
||
<view class="metric-divider"></view>
|
||
<view class="metric-col ss-flex-col ss-col-center">
|
||
<view class="metric-val">¥{{ item.consume_amount || '0.00' }}</view>
|
||
<view class="metric-lbl">自购业绩(元)</view>
|
||
</view>
|
||
<view class="metric-divider"></view>
|
||
<view class="metric-col ss-flex-col ss-col-center">
|
||
<view class="metric-val">
|
||
{{ item.agent?.direct_order_seq !== undefined ? '第' + item.agent.direct_order_seq + '单' : '--' }}
|
||
</view>
|
||
<view class="metric-lbl">提成循环序号</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 底部快捷触达与操作栏 -->
|
||
<view class="member-card-footer ss-flex ss-col-center ss-row-between ss-m-t-20">
|
||
<view class="register-time">
|
||
注册时间:{{ formatTime(item.createtime) }}
|
||
</view>
|
||
<view class="actions-wrap ss-flex ss-col-center">
|
||
<button
|
||
v-if="Number(item.child_user_count_1) > 0"
|
||
class="ss-reset-button action-btn btn-drill"
|
||
@tap.stop="onDrillDown(item)"
|
||
>
|
||
<uni-icons type="staff-filled" size="13" color="#ff6000"></uni-icons>
|
||
<text class="ss-m-l-4">下钻团队</text>
|
||
</button>
|
||
<button
|
||
v-if="item.mobile_raw"
|
||
class="ss-reset-button action-btn btn-call ss-m-l-10"
|
||
@tap.stop="onMakePhoneCall(item.mobile_raw)"
|
||
>
|
||
<uni-icons type="phone-filled" size="13" color="#ff6000"></uni-icons>
|
||
<text class="ss-m-l-4">拨打</text>
|
||
</button>
|
||
<button
|
||
v-if="item.mobile_raw || item.mobile_hide"
|
||
class="ss-reset-button action-btn btn-copy ss-m-l-10"
|
||
@tap.stop="onCopyText(item.mobile_raw || item.mobile_hide, '手机号已复制')"
|
||
>
|
||
<uni-icons type="paperclip" size="13" color="#666666"></uni-icons>
|
||
<text class="ss-m-l-4">复制</text>
|
||
</button>
|
||
<button
|
||
class="ss-reset-button action-btn btn-reward ss-m-l-10"
|
||
@tap.stop="onJumpRewards(item.id, item.nickname)"
|
||
>
|
||
<uni-icons type="wallet" size="13" color="#ff6000"></uni-icons>
|
||
<text class="ss-m-l-4">收益</text>
|
||
</button>
|
||
<button
|
||
class="ss-reset-button action-btn btn-detail ss-m-l-10"
|
||
@tap.stop="onOpenMemberDetail(item)"
|
||
>
|
||
<text>详情</text>
|
||
<uni-icons type="right" size="12" color="#999999"></uni-icons>
|
||
</button>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 空状态处理与行动引导 -->
|
||
<view v-if="state.pagination.total === 0 && state.loadStatus !== 'loading'" class="empty-wrap">
|
||
<!-- 搜索或筛选结果为空 -->
|
||
<view v-if="state.keyword || state.currentFilter !== 'all' || state.drillStack.length > 0" class="filter-empty ss-flex-col ss-col-center">
|
||
<s-empty icon="/static/data-empty.png" text="未找到符合条件的成员"></s-empty>
|
||
<button class="ss-reset-button reset-filter-btn ss-m-t-20" @tap="resetFilters">
|
||
重置所有筛选
|
||
</button>
|
||
</view>
|
||
<!-- 真实无团队成员空状态:引导裂变海报 -->
|
||
<view v-else class="team-empty ss-flex-col ss-col-center ss-p-b-60">
|
||
<s-empty icon="/static/data-empty.png" text="您还没有团队成员,快去邀请好友加入吧!"></s-empty>
|
||
<button class="ss-reset-button invite-cta-btn ss-m-t-30" @tap="onOpenShareModal">
|
||
<text class="cicon-forward ss-m-r-10"></text>
|
||
立即生成邀请海报
|
||
</button>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 加载更多指示器 -->
|
||
<uni-load-more
|
||
v-if="state.pagination.total > 0"
|
||
:status="state.loadStatus"
|
||
:content-text="{
|
||
contentdown: '上拉加载更多',
|
||
contentrefresh: '正在加载...',
|
||
nomore: '没有更多成员了',
|
||
}"
|
||
/>
|
||
|
||
<!-- 成员画像与经营管理抽屉 -->
|
||
<su-popup
|
||
:show="state.showDetail"
|
||
type="bottom"
|
||
round="24"
|
||
@close="state.showDetail = false"
|
||
showClose
|
||
>
|
||
<view v-if="state.currentMember" class="drawer-content ss-p-x-32 ss-p-b-40 ss-p-t-30">
|
||
<view class="drawer-header ss-flex ss-col-center ss-m-b-24">
|
||
<image
|
||
class="drawer-avatar ss-m-r-20"
|
||
:src="sheep.$url.cdn(state.currentMember.avatar)"
|
||
mode="aspectFill"
|
||
></image>
|
||
<view class="drawer-user-info">
|
||
<view class="drawer-nickname ss-flex ss-col-center">
|
||
<text class="ss-font-32 ss-bold ss-m-r-12">{{ state.currentMember.nickname }}</text>
|
||
<text class="level-badge badge-direct">直推成员</text>
|
||
</view>
|
||
<view class="drawer-sub ss-flex ss-col-center ss-m-t-8">
|
||
<text class="user-id">ID: {{ state.currentMember.id }}</text>
|
||
<text class="dot-split">·</text>
|
||
<text class="user-phone">手机: {{ state.currentMember.mobile_hide || '未绑定' }}</text>
|
||
<text class="dot-split">·</text>
|
||
<text class="join-time">{{ formatTime(state.currentMember.createtime) }} 加入</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 身份体系卡 -->
|
||
<view class="drawer-section ss-m-b-24">
|
||
<view class="section-title">业务身份</view>
|
||
<view class="section-box identity-box ss-flex ss-col-center ss-flex-wrap">
|
||
<view class="id-pill tag-box ss-flex ss-col-center ss-m-r-12 ss-m-b-10">
|
||
<image
|
||
v-if="state.currentMember.agent?.level_info?.image"
|
||
class="tag-img"
|
||
:src="sheep.$url.cdn(state.currentMember.agent.level_info.image)"
|
||
mode="aspectFill"
|
||
></image>
|
||
<text class="tag-title">{{ memberLevelName(state.currentMember) || '普通会员' }}</text>
|
||
</view>
|
||
<view
|
||
v-if="state.currentMember.agent?.is_venue || state.currentMember.agent?.identities?.includes('venue')"
|
||
class="id-pill mini-tag tag-venue ss-m-r-12 ss-m-b-10"
|
||
>
|
||
{{ roleNames.venue || '酒道馆' }}
|
||
</view>
|
||
<view
|
||
v-if="state.currentMember.agent?.is_county || state.currentMember.agent?.identities?.includes('county')"
|
||
class="id-pill mini-tag tag-county ss-m-r-12 ss-m-b-10"
|
||
>
|
||
{{ roleNames.county || '区县代理' }}
|
||
</view>
|
||
<view
|
||
v-if="state.currentMember.agent?.is_partner || state.currentMember.agent?.identities?.includes('partner')"
|
||
class="id-pill mini-tag tag-partner ss-m-r-12 ss-m-b-10"
|
||
>
|
||
{{ roleNames.partner || '合伙股东' }}
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 30天收益保活详情 -->
|
||
<view class="drawer-section ss-m-b-24">
|
||
<view class="section-title ss-flex ss-row-between ss-col-center">
|
||
<text>30天收益保活状态</text>
|
||
<text
|
||
class="status-text-bold"
|
||
:class="{
|
||
'text-green': state.currentMember.active_status === 'active',
|
||
'text-yellow': state.currentMember.active_status === 'expiring',
|
||
'text-gray': state.currentMember.active_status === 'inactive',
|
||
}"
|
||
>
|
||
{{
|
||
state.currentMember.active_status === 'active'
|
||
? '正常领取中'
|
||
: state.currentMember.active_status === 'expiring'
|
||
? '临期预警(剩' + state.currentMember.days_remaining + '天)'
|
||
: '业务奖励已暂停'
|
||
}}
|
||
</text>
|
||
</view>
|
||
<view class="section-box active-detail-box">
|
||
<view class="detail-line ss-flex ss-row-between">
|
||
<text class="line-label">最近有效订单时间:</text>
|
||
<text class="line-val">
|
||
{{ formatLastOrderTime(state.currentMember.agent?.last_self_order_time) }}
|
||
</text>
|
||
</view>
|
||
<view class="detail-line ss-flex ss-row-between ss-m-t-12">
|
||
<text class="line-label">推荐提成序号:</text>
|
||
<text class="line-val">
|
||
{{ state.currentMember.agent?.direct_order_seq !== undefined ? '当前第 ' + state.currentMember.agent.direct_order_seq + ' 单' : '0 单' }}
|
||
</text>
|
||
</view>
|
||
<view class="notice-tip ss-m-t-16">
|
||
💡 规则提示:近 30 日内需有本人订单方可正常享受收益。如已暂停,次日完成自购后即可自动恢复。
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 经营产出看板 -->
|
||
<view class="drawer-section ss-m-b-24">
|
||
<view class="section-title">团队与业绩产出</view>
|
||
<view class="section-box performance-box ss-flex ss-row-between">
|
||
<view class="perf-col ss-flex-col ss-col-center">
|
||
<view class="perf-num">{{ state.currentMember.child_user_count_1 || 0 }}</view>
|
||
<view class="perf-lbl">直推下级(人)</view>
|
||
</view>
|
||
<view class="perf-col ss-flex-col ss-col-center">
|
||
<view class="perf-num">{{ state.currentMember.order_count || 0 }}</view>
|
||
<view class="perf-lbl">累计成单(笔)</view>
|
||
</view>
|
||
<view class="perf-col ss-flex-col ss-col-center">
|
||
<view class="perf-num">¥{{ state.currentMember.consume_amount || '0.00' }}</view>
|
||
<view class="perf-lbl">自购贡献(元)</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 下钻查看直推团队卡片 -->
|
||
<view
|
||
v-if="Number(state.currentMember.child_user_count_1) > 0"
|
||
class="drawer-drill-card ss-m-b-24 ss-flex ss-row-between ss-col-center"
|
||
@tap="onDrillFromDrawer(state.currentMember)"
|
||
>
|
||
<view class="drill-card-left ss-flex ss-col-center">
|
||
<view class="drill-icon-box ss-flex ss-row-center ss-col-center">
|
||
<uni-icons type="staff-filled" size="20" color="#ff6000"></uni-icons>
|
||
</view>
|
||
<view class="drill-info ss-m-l-16">
|
||
<view class="drill-title">下钻查看 Ta 的直推团队</view>
|
||
<view class="drill-desc">Ta 名下共有 {{ state.currentMember.child_user_count_1 }} 位直推成员</view>
|
||
</view>
|
||
</view>
|
||
<view class="drill-card-right ss-flex ss-col-center">
|
||
<text class="drill-btn-text">立即进入</text>
|
||
<uni-icons type="right" size="14" color="#ff6000"></uni-icons>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 触达与管理动作条 -->
|
||
<view class="drawer-actions ss-flex ss-col-center ss-row-between">
|
||
<button
|
||
v-if="state.currentMember.mobile_raw"
|
||
class="ss-reset-button drawer-btn drawer-btn-primary ss-flex-1 ss-m-r-16"
|
||
@tap="onMakePhoneCall(state.currentMember.mobile_raw)"
|
||
>
|
||
<uni-icons type="phone-filled" size="16" color="#ffffff"></uni-icons>
|
||
<text class="ss-m-l-8">呼叫成员</text>
|
||
</button>
|
||
<button
|
||
v-if="state.currentMember.mobile_raw || state.currentMember.mobile_hide"
|
||
class="ss-reset-button drawer-btn drawer-btn-sub ss-flex-1 ss-m-r-16"
|
||
@tap="onCopyText(state.currentMember.mobile_raw || state.currentMember.mobile_hide, '手机号已复制')"
|
||
>
|
||
<uni-icons type="paperclip" size="16" color="#ff6000"></uni-icons>
|
||
<text class="ss-m-l-8">复制电话</text>
|
||
</button>
|
||
<button
|
||
class="ss-reset-button drawer-btn drawer-btn-outline ss-flex-1"
|
||
@tap="onJumpRewards(state.currentMember.id, state.currentMember.nickname)"
|
||
>
|
||
<uni-icons type="list" size="16" color="#666666"></uni-icons>
|
||
<text class="ss-m-l-8">查收益流水</text>
|
||
</button>
|
||
</view>
|
||
</view>
|
||
</su-popup>
|
||
</s-layout>
|
||
</template>
|
||
|
||
<script setup>
|
||
import sheep from '@/sheep';
|
||
import { onLoad, onShow, onReachBottom, onPullDownRefresh, onPageScroll } from '@dcloudio/uni-app';
|
||
import { computed, reactive } from 'vue';
|
||
import { showShareModal } from '@/sheep/hooks/useModal';
|
||
import _ from 'lodash';
|
||
|
||
const statusBarHeight = sheep.$platform.device.statusBarHeight * 2;
|
||
const agentInfo = computed(() => sheep.$store('user').agentInfo);
|
||
const userInfo = computed(() => sheep.$store('user').userInfo);
|
||
const headerBg = sheep.$url.css('/assets/addons/shopro/uniapp/user/withdraw_bg.png');
|
||
|
||
const roleNames = computed(() => {
|
||
return (
|
||
userInfo.value?.custom_role_names ||
|
||
userInfo.value?.role_names ||
|
||
agentInfo.value?.custom_role_names ||
|
||
agentInfo.value?.role_names ||
|
||
{}
|
||
);
|
||
});
|
||
|
||
// 控制吸顶及页面滚动
|
||
onPageScroll((e) => {
|
||
state.scrollTop = e.scrollTop > 100;
|
||
});
|
||
|
||
const filterPills = computed(() => [
|
||
{ label: '全部', value: 'all' },
|
||
{ label: roleNames.value.partner || '合伙股东', value: 'partner' },
|
||
{ label: '正常活跃', value: 'active' },
|
||
{ label: '临期预警', value: 'expiring' },
|
||
{ label: '已暂停', value: 'inactive' },
|
||
]);
|
||
|
||
const sortOptions = [
|
||
{ label: '最新加入', value: 'createtime' },
|
||
{ label: '裂变最多', value: 'child_count' },
|
||
{ label: '消费最高', value: 'consume' },
|
||
];
|
||
|
||
const state = reactive({
|
||
scrollTop: false,
|
||
keyword: '',
|
||
drillStack: [], // 下钻栈:[{ id, nickname, avatar, child_user_count_1 }]
|
||
currentFilter: 'all', // all, partner, active, expiring, inactive
|
||
currentSort: 'createtime', // createtime, child_count, consume
|
||
showDetail: false,
|
||
currentMember: null,
|
||
summary: {
|
||
total_count: 0,
|
||
active_count: 0,
|
||
expiring_count: 0,
|
||
inactive_count: 0,
|
||
partner_count: 0,
|
||
team_total_consume: '0.00',
|
||
team_total_reward: '0.00',
|
||
team_month_reward: '0.00',
|
||
team_order_count: 0,
|
||
},
|
||
pagination: {
|
||
data: [],
|
||
current_page: 1,
|
||
total: 0,
|
||
last_page: 1,
|
||
},
|
||
loadStatus: '',
|
||
});
|
||
|
||
// 当前正在下钻的目标成员
|
||
const currentDrillUser = computed(() => {
|
||
if (!state.drillStack || state.drillStack.length === 0) return null;
|
||
return state.drillStack[state.drillStack.length - 1];
|
||
});
|
||
|
||
// 获取直推人数(支持当前团队与多级下钻)
|
||
function getDirectCount() {
|
||
if (currentDrillUser.value) {
|
||
return (
|
||
state.summary.direct_count ??
|
||
state.summary.total_count ??
|
||
currentDrillUser.value.child_user_count_1 ??
|
||
0
|
||
);
|
||
}
|
||
const count = Number(agentInfo.value?.child_user_count_1 || 0);
|
||
if (count > 0) return count;
|
||
if (state.summary.direct_count !== undefined && state.summary.direct_count > 0) {
|
||
return state.summary.direct_count;
|
||
}
|
||
return Number(state.pagination.total || 0);
|
||
}
|
||
|
||
// 获取团队总人数(支持当前团队与多级下钻)
|
||
function getTeamCount() {
|
||
if (currentDrillUser.value) {
|
||
return (
|
||
state.summary.team_count ??
|
||
currentDrillUser.value.child_user_count_all ??
|
||
state.summary.direct_count ??
|
||
state.summary.total_count ??
|
||
0
|
||
);
|
||
}
|
||
const count = Number(agentInfo.value?.child_user_count_all || 0);
|
||
if (count > 0) return count;
|
||
if (state.summary.team_count !== undefined && state.summary.team_count > 0) {
|
||
return state.summary.team_count;
|
||
}
|
||
return getDirectCount();
|
||
}
|
||
|
||
function memberLevelName(item) {
|
||
const rNames =
|
||
item?.agent?.custom_role_names ||
|
||
item?.agent?.role_names ||
|
||
roleNames.value ||
|
||
{};
|
||
if (item?.agent?.maker_level_name) {
|
||
return item.agent.maker_level_name;
|
||
}
|
||
if (item?.agent?.identity_text) {
|
||
return item.agent.identity_text;
|
||
}
|
||
const rawName = item?.agent?.level_info?.name;
|
||
if (rawName) {
|
||
if (rNames.maker && rawName.includes('创客')) {
|
||
return rawName.replace('创客', rNames.maker);
|
||
}
|
||
if (rNames.taster && rawName.includes('品酒师')) {
|
||
return rawName.replace('品酒师', rNames.taster);
|
||
}
|
||
return rawName;
|
||
}
|
||
return item?.agent?.identity_text || '';
|
||
}
|
||
|
||
function formatTime(timestamp) {
|
||
if (!timestamp) return '--';
|
||
const date = new Date(Number(timestamp) * 1000);
|
||
const y = date.getFullYear();
|
||
const m = String(date.getMonth() + 1).padStart(2, '0');
|
||
const d = String(date.getDate()).padStart(2, '0');
|
||
return `${y}-${m}-${d}`;
|
||
}
|
||
|
||
function formatLastOrderTime(timestamp) {
|
||
if (!timestamp || Number(timestamp) === 0) {
|
||
return '近 30 日内暂无本人自购记录';
|
||
}
|
||
const date = new Date(Number(timestamp) * 1000);
|
||
const y = date.getFullYear();
|
||
const m = String(date.getMonth() + 1).padStart(2, '0');
|
||
const d = String(date.getDate()).padStart(2, '0');
|
||
const h = String(date.getHours()).padStart(2, '0');
|
||
const min = String(date.getMinutes()).padStart(2, '0');
|
||
return `${y}-${m}-${d} ${h}:${min}`;
|
||
}
|
||
|
||
// 头部卡片联动
|
||
function onSelectHeaderTab(filter) {
|
||
state.currentFilter = filter;
|
||
state.currentSort = 'createtime';
|
||
getTeamList(1);
|
||
}
|
||
|
||
// 状态胶囊切换
|
||
function onToggleStatusFilter(status) {
|
||
if (state.currentFilter === status) {
|
||
state.currentFilter = 'all';
|
||
} else {
|
||
state.currentFilter = status;
|
||
}
|
||
getTeamList(1);
|
||
}
|
||
|
||
// 筛选胶囊切换
|
||
function onFilterChipChange(filter) {
|
||
if (state.currentFilter === filter && state.currentSort === 'createtime') return;
|
||
state.currentFilter = filter;
|
||
state.currentSort = 'createtime';
|
||
getTeamList(1);
|
||
}
|
||
|
||
// 排序切换
|
||
function onSortOptionChange(sort) {
|
||
if (state.currentSort === sort) return;
|
||
state.currentSort = sort;
|
||
getTeamList(1);
|
||
}
|
||
|
||
// 搜索处理
|
||
function onSearchConfirm() {
|
||
getTeamList(1);
|
||
}
|
||
|
||
function onClearKeyword() {
|
||
state.keyword = '';
|
||
getTeamList(1);
|
||
}
|
||
|
||
function resetFilters() {
|
||
state.keyword = '';
|
||
state.currentFilter = 'all';
|
||
state.currentSort = 'createtime';
|
||
state.drillStack = [];
|
||
getTeamList(1);
|
||
}
|
||
|
||
// 成员下钻逻辑
|
||
function onDrillDown(member) {
|
||
if (!member || !member.id) return;
|
||
if (state.drillStack.some((item) => item.id === member.id)) {
|
||
sheep.$helper.toast('当前已在此成员层级中');
|
||
return;
|
||
}
|
||
state.drillStack.push({
|
||
id: member.id,
|
||
nickname: member.nickname || '直推成员',
|
||
avatar: member.avatar,
|
||
child_user_count_1: member.child_user_count_1 || 0,
|
||
});
|
||
state.keyword = '';
|
||
getTeamList(1);
|
||
}
|
||
|
||
function onDrillBack() {
|
||
if (state.drillStack.length === 0) return;
|
||
state.drillStack.pop();
|
||
state.keyword = '';
|
||
getTeamList(1);
|
||
}
|
||
|
||
function onDrillRoot() {
|
||
if (state.drillStack.length === 0) return;
|
||
state.drillStack = [];
|
||
state.keyword = '';
|
||
getTeamList(1);
|
||
}
|
||
|
||
function onJumpDrillIndex(index) {
|
||
if (index >= state.drillStack.length - 1) return;
|
||
state.drillStack = state.drillStack.slice(0, index + 1);
|
||
state.keyword = '';
|
||
getTeamList(1);
|
||
}
|
||
|
||
function onDrillFromDrawer(member) {
|
||
state.showDetail = false;
|
||
onDrillDown(member);
|
||
}
|
||
|
||
// 触达动作
|
||
function onMakePhoneCall(phone) {
|
||
if (!phone) {
|
||
sheep.$helper.toast('未提供联系电话');
|
||
return;
|
||
}
|
||
uni.makePhoneCall({
|
||
phoneNumber: phone,
|
||
fail: () => {
|
||
sheep.$helper.toast('取消拨打');
|
||
},
|
||
});
|
||
}
|
||
|
||
function onCopyText(text, tip = '已复制') {
|
||
if (!text) return;
|
||
sheep.$helper.copyText(text);
|
||
}
|
||
|
||
function onOpenMemberDetail(item) {
|
||
state.currentMember = item;
|
||
state.showDetail = true;
|
||
}
|
||
|
||
function onJumpRewards(buyerId, buyerName = '') {
|
||
state.showDetail = false;
|
||
const nameParam = buyerName ? `&buyer_name=${encodeURIComponent(buyerName)}` : '';
|
||
sheep.$router.go(`/pages/commission/rewards?buyer_id=${buyerId}${nameParam}`);
|
||
}
|
||
|
||
function onCopyInviteCode() {
|
||
if (!userInfo.value?.id) {
|
||
sheep.$helper.toast('请先登录');
|
||
return;
|
||
}
|
||
const code = `HL${userInfo.value.id}`;
|
||
sheep.$helper.copyText(code, '专属邀请码已复制');
|
||
}
|
||
|
||
function onCopyShareLink() {
|
||
if (!userInfo.value?.id) {
|
||
sheep.$helper.toast('请先登录');
|
||
return;
|
||
}
|
||
const shareQuery = sheep.$platform.share.buildSpmQuery({
|
||
page: '1',
|
||
query: '0',
|
||
});
|
||
const shareUrl = sheep.$platform.share.buildSpmPath(shareQuery);
|
||
sheep.$helper.copyText(shareUrl, '专属推广链接已复制');
|
||
}
|
||
|
||
function onOpenShareModal() {
|
||
showShareModal();
|
||
}
|
||
|
||
// 列表数据请求
|
||
async function getTeamList(page = 1, list_rows = 10) {
|
||
state.loadStatus = 'loading';
|
||
const params = {
|
||
page,
|
||
list_rows,
|
||
drill_user_id: currentDrillUser.value ? currentDrillUser.value.id : 0,
|
||
filter_type: state.currentFilter,
|
||
sort: state.currentSort,
|
||
keyword: state.keyword,
|
||
};
|
||
let res = await sheep.$api.commission.team(params);
|
||
if (res.code === 1) {
|
||
const rows = res.data?.data || [];
|
||
state.pagination = {
|
||
...res.data,
|
||
data: page === 1 ? rows : _.concat(state.pagination.data, rows),
|
||
};
|
||
if (res.data?.summary) {
|
||
state.summary = res.data.summary;
|
||
}
|
||
if (state.pagination.current_page < state.pagination.last_page) {
|
||
state.loadStatus = 'more';
|
||
} else {
|
||
state.loadStatus = 'noMore';
|
||
}
|
||
} else {
|
||
sheep.$helper.toast(res.msg || '获取团队列表失败');
|
||
state.loadStatus = 'noMore';
|
||
}
|
||
}
|
||
|
||
async function refreshHeader() {
|
||
await Promise.all([sheep.$store('user').getAgentInfo(), sheep.$store('user').getInfo()]);
|
||
}
|
||
|
||
async function refreshPage() {
|
||
await Promise.all([refreshHeader(), getTeamList(1)]);
|
||
}
|
||
|
||
onLoad(() => {
|
||
refreshPage();
|
||
});
|
||
|
||
onShow(() => {
|
||
refreshHeader();
|
||
});
|
||
|
||
onPullDownRefresh(async () => {
|
||
await refreshPage();
|
||
uni.stopPullDownRefresh();
|
||
});
|
||
|
||
onReachBottom(() => {
|
||
if (state.loadStatus !== 'noMore') {
|
||
getTeamList(state.pagination.current_page + 1);
|
||
}
|
||
});
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.header-box {
|
||
box-sizing: border-box;
|
||
padding: 0 20rpx 24rpx 20rpx;
|
||
width: 750rpx;
|
||
z-index: 3;
|
||
position: relative;
|
||
background: v-bind(headerBg) no-repeat,
|
||
linear-gradient(90deg, var(--ui-BG-Main), var(--ui-BG-Main-gradient));
|
||
background-size: 750rpx 100%;
|
||
|
||
// 推荐人
|
||
.referrer-box {
|
||
font-size: 26rpx;
|
||
font-weight: 500;
|
||
color: #ffffff;
|
||
padding: 10rpx 8rpx 20rpx 8rpx;
|
||
|
||
.referrer-avatar {
|
||
width: 38rpx;
|
||
height: 38rpx;
|
||
border-radius: 50%;
|
||
border: 2rpx solid rgba(255, 255, 255, 0.6);
|
||
}
|
||
.referrer-name {
|
||
font-weight: bold;
|
||
}
|
||
}
|
||
|
||
// 专属邀请码卡片
|
||
.invite-action-card {
|
||
background: rgba(255, 255, 255, 0.2);
|
||
backdrop-filter: blur(10px);
|
||
border-radius: 16rpx;
|
||
padding: 12rpx 20rpx;
|
||
margin-bottom: 20rpx;
|
||
|
||
.invite-code-wrap {
|
||
.invite-label {
|
||
font-size: 24rpx;
|
||
color: #ffffff;
|
||
font-weight: 500;
|
||
}
|
||
.invite-code {
|
||
font-size: 28rpx;
|
||
font-weight: bold;
|
||
color: #ffffff;
|
||
font-family: OPPOSANS;
|
||
letter-spacing: 1rpx;
|
||
}
|
||
.copy-code-btn {
|
||
font-size: 20rpx;
|
||
padding: 4rpx 14rpx;
|
||
border-radius: 16rpx;
|
||
background: #ffffff;
|
||
color: #ff6000;
|
||
font-weight: 500;
|
||
}
|
||
}
|
||
|
||
.invite-btn-group {
|
||
.invite-btn-poster {
|
||
height: 48rpx;
|
||
padding: 0 16rpx;
|
||
border-radius: 24rpx;
|
||
background: #ff6000;
|
||
color: #ffffff;
|
||
font-size: 22rpx;
|
||
font-weight: 500;
|
||
}
|
||
.invite-btn-link {
|
||
height: 48rpx;
|
||
padding: 0 16rpx;
|
||
border-radius: 24rpx;
|
||
background: #ffffff;
|
||
color: #ff6000;
|
||
font-size: 22rpx;
|
||
font-weight: 500;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 团队信息总览
|
||
.team-data-box {
|
||
.data-card {
|
||
background: #ffffff;
|
||
border-radius: 20rpx;
|
||
padding: 22rpx 24rpx;
|
||
box-sizing: border-box;
|
||
box-shadow: 0 4rpx 14rpx rgba(0, 0, 0, 0.03);
|
||
|
||
.item-title {
|
||
font-size: 24rpx;
|
||
font-weight: 500;
|
||
color: #999999;
|
||
line-height: 32rpx;
|
||
margin-bottom: 12rpx;
|
||
}
|
||
|
||
.total-num {
|
||
font-size: 44rpx;
|
||
font-weight: bold;
|
||
color: #333333;
|
||
font-family: OPPOSANS;
|
||
line-height: 48rpx;
|
||
|
||
&.text-orange {
|
||
color: #ff6000;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// 团队收益与业绩看板
|
||
.team-wealth-box {
|
||
margin-top: 20rpx;
|
||
|
||
.wealth-card {
|
||
background: #ffffff;
|
||
border-radius: 20rpx;
|
||
padding: 18rpx 20rpx;
|
||
box-sizing: border-box;
|
||
|
||
.wealth-title {
|
||
font-size: 22rpx;
|
||
color: #999999;
|
||
line-height: 28rpx;
|
||
margin-bottom: 6rpx;
|
||
}
|
||
.wealth-num {
|
||
font-size: 32rpx;
|
||
font-weight: bold;
|
||
font-family: OPPOSANS;
|
||
line-height: 38rpx;
|
||
margin-bottom: 6rpx;
|
||
|
||
&.text-orange {
|
||
color: #ff6000;
|
||
}
|
||
&.text-gold {
|
||
color: #c48a3a;
|
||
}
|
||
}
|
||
.wealth-sub {
|
||
font-size: 20rpx;
|
||
color: #888888;
|
||
line-height: 24rpx;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 健康度胶囊条
|
||
.health-bar {
|
||
margin-top: 20rpx;
|
||
background: rgba(255, 255, 255, 0.2);
|
||
backdrop-filter: blur(10px);
|
||
border-radius: 36rpx;
|
||
padding: 10rpx 18rpx;
|
||
|
||
.health-title {
|
||
font-size: 22rpx;
|
||
color: #ffffff;
|
||
font-weight: 500;
|
||
}
|
||
|
||
.health-pills {
|
||
gap: 10rpx;
|
||
|
||
.health-pill {
|
||
display: flex;
|
||
align-items: center;
|
||
padding: 6rpx 14rpx;
|
||
border-radius: 20rpx;
|
||
background: rgba(255, 255, 255, 0.85);
|
||
font-size: 20rpx;
|
||
line-height: 22rpx;
|
||
color: #444444;
|
||
transition: all 0.2s;
|
||
|
||
&.pill-selected {
|
||
background: #ffffff;
|
||
font-weight: bold;
|
||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.15);
|
||
transform: scale(1.04);
|
||
}
|
||
|
||
.pill-label {
|
||
margin-left: 6rpx;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// 状态圆点
|
||
.status-dot {
|
||
width: 12rpx;
|
||
height: 12rpx;
|
||
border-radius: 50%;
|
||
display: inline-block;
|
||
|
||
&.dot-green {
|
||
background: #10b981;
|
||
box-shadow: 0 0 6rpx #10b981;
|
||
}
|
||
&.dot-yellow {
|
||
background: #f59e0b;
|
||
box-shadow: 0 0 6rpx #f59e0b;
|
||
}
|
||
&.dot-gray {
|
||
background: #9ca3af;
|
||
}
|
||
}
|
||
|
||
// 控制台
|
||
.control-panel {
|
||
background: #ffffff;
|
||
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05);
|
||
|
||
// 搜索框
|
||
.search-bar-box {
|
||
padding: 18rpx 24rpx 12rpx 24rpx;
|
||
|
||
.search-input-wrap {
|
||
background: #f5f5f7;
|
||
border-radius: 32rpx;
|
||
height: 64rpx;
|
||
padding: 0 20rpx;
|
||
|
||
.search-input {
|
||
flex: 1;
|
||
margin-left: 12rpx;
|
||
font-size: 24rpx;
|
||
color: #333333;
|
||
}
|
||
|
||
.search-placeholder {
|
||
color: #a0a0a0;
|
||
font-size: 24rpx;
|
||
}
|
||
|
||
.clear-btn {
|
||
padding: 8rpx;
|
||
}
|
||
}
|
||
|
||
.search-btn {
|
||
margin-left: 16rpx;
|
||
font-size: 26rpx;
|
||
color: #ff6000;
|
||
font-weight: 500;
|
||
padding: 8rpx 12rpx;
|
||
}
|
||
}
|
||
|
||
// 下钻导航与面包屑
|
||
.drill-nav-bar {
|
||
border-bottom: 1rpx solid #f2f2f2;
|
||
padding: 16rpx 24rpx;
|
||
|
||
&.root-nav {
|
||
background: #fafbfc;
|
||
.nav-left {
|
||
.nav-icon-box {
|
||
width: 36rpx;
|
||
height: 36rpx;
|
||
border-radius: 50%;
|
||
background: #fff0e6;
|
||
}
|
||
.nav-root-title {
|
||
font-size: 26rpx;
|
||
font-weight: bold;
|
||
color: #222222;
|
||
}
|
||
.nav-root-count {
|
||
font-size: 24rpx;
|
||
color: #ff6000;
|
||
font-weight: 500;
|
||
font-family: OPPOSANS;
|
||
}
|
||
}
|
||
.nav-hint {
|
||
.hint-text {
|
||
font-size: 22rpx;
|
||
color: #999999;
|
||
margin-right: 4rpx;
|
||
}
|
||
}
|
||
}
|
||
|
||
&.in-drill-nav {
|
||
background: #fff8f2;
|
||
.drill-back-btn {
|
||
padding: 8rpx 14rpx;
|
||
border-radius: 24rpx;
|
||
background: #ffffff;
|
||
border: 1rpx solid #ffd8bf;
|
||
box-shadow: 0 2rpx 6rpx rgba(255, 96, 0, 0.08);
|
||
|
||
.back-text {
|
||
font-size: 24rpx;
|
||
font-weight: bold;
|
||
color: #ff6000;
|
||
margin-left: 4rpx;
|
||
}
|
||
}
|
||
|
||
.drill-breadcrumb {
|
||
min-width: 0;
|
||
overflow: hidden;
|
||
|
||
.breadcrumb-scroll {
|
||
white-space: nowrap;
|
||
width: 100%;
|
||
}
|
||
|
||
.breadcrumb-inner {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
|
||
.crumb-link {
|
||
font-size: 24rpx;
|
||
color: #666666;
|
||
}
|
||
|
||
.crumb-sep {
|
||
font-size: 22rpx;
|
||
color: #bbbbbb;
|
||
margin: 0 8rpx;
|
||
}
|
||
|
||
.crumb-node {
|
||
font-size: 24rpx;
|
||
color: #666666;
|
||
|
||
&.crumb-current {
|
||
color: #ff6000;
|
||
font-weight: bold;
|
||
background: #fff0e6;
|
||
padding: 2rpx 12rpx;
|
||
border-radius: 12rpx;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.drill-reset-btn {
|
||
font-size: 22rpx;
|
||
color: #ff6000;
|
||
padding: 6rpx 14rpx;
|
||
border-radius: 20rpx;
|
||
background: rgba(255, 96, 0, 0.1);
|
||
font-weight: 500;
|
||
white-space: nowrap;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 筛选滚动条
|
||
.filter-scroll-wrap {
|
||
white-space: nowrap;
|
||
padding: 14rpx 20rpx;
|
||
box-sizing: border-box;
|
||
|
||
.filter-scroll-content {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 12rpx;
|
||
}
|
||
|
||
.filter-chip {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
padding: 8rpx 20rpx;
|
||
background: #f5f5f7;
|
||
border-radius: 24rpx;
|
||
font-size: 22rpx;
|
||
color: #666666;
|
||
transition: all 0.2s;
|
||
|
||
&.chip-active {
|
||
background: #fff0e6;
|
||
color: #ff6000;
|
||
font-weight: bold;
|
||
}
|
||
|
||
&.sort-chip {
|
||
background: #f0f4f8;
|
||
color: #4a5568;
|
||
|
||
&.chip-active {
|
||
background: #e2e8f0;
|
||
color: #1a202c;
|
||
font-weight: bold;
|
||
}
|
||
}
|
||
}
|
||
|
||
.chip-divider {
|
||
width: 1rpx;
|
||
height: 28rpx;
|
||
background: #e2e8f0;
|
||
margin: 0 6rpx;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 成员卡片列表
|
||
.member-list-box {
|
||
padding: 20rpx;
|
||
|
||
.member-card {
|
||
background: #ffffff;
|
||
border-radius: 18rpx;
|
||
padding: 24rpx;
|
||
margin-bottom: 20rpx;
|
||
box-shadow: 0 4rpx 14rpx rgba(0, 0, 0, 0.03);
|
||
position: relative;
|
||
|
||
.member-card-header {
|
||
.member-avatar {
|
||
width: 88rpx;
|
||
height: 88rpx;
|
||
border-radius: 50%;
|
||
border: 2rpx solid #ffefe0;
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
.member-name-row {
|
||
.member-name {
|
||
font-size: 28rpx;
|
||
font-weight: bold;
|
||
color: #333333;
|
||
max-width: 220rpx;
|
||
}
|
||
|
||
.level-badge {
|
||
margin-left: 10rpx;
|
||
padding: 2rpx 10rpx;
|
||
border-radius: 8rpx;
|
||
font-size: 20rpx;
|
||
line-height: 28rpx;
|
||
|
||
&.badge-direct {
|
||
background: #fff3e0;
|
||
color: #ff6f00;
|
||
}
|
||
&.badge-indirect {
|
||
background: #e0f2fe;
|
||
color: #0284c7;
|
||
}
|
||
}
|
||
}
|
||
|
||
.member-sub-info {
|
||
font-size: 20rpx;
|
||
color: #999999;
|
||
font-family: OPPOSANS;
|
||
|
||
.member-phone {
|
||
color: #666666;
|
||
font-size: 22rpx;
|
||
}
|
||
.member-id-tag {
|
||
background: #f3f4f6;
|
||
color: #9ca3af;
|
||
padding: 2rpx 8rpx;
|
||
border-radius: 6rpx;
|
||
font-size: 18rpx;
|
||
}
|
||
}
|
||
|
||
.member-meta-row {
|
||
gap: 8rpx;
|
||
}
|
||
|
||
.status-pill {
|
||
display: flex;
|
||
align-items: center;
|
||
padding: 6rpx 16rpx;
|
||
border-radius: 20rpx;
|
||
font-size: 20rpx;
|
||
font-weight: 500;
|
||
|
||
&.pill-green {
|
||
background: #ecfdf5;
|
||
color: #059669;
|
||
border: 1rpx solid #a7f3d0;
|
||
}
|
||
&.pill-amber {
|
||
background: #fffbeb;
|
||
color: #d97706;
|
||
border: 1rpx solid #fde68a;
|
||
}
|
||
&.pill-gray {
|
||
background: #f3f4f6;
|
||
color: #6b7280;
|
||
border: 1rpx solid #e5e7eb;
|
||
}
|
||
|
||
text:last-child {
|
||
margin-left: 6rpx;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 指标网格
|
||
.metrics-grid {
|
||
background: #fafafc;
|
||
border-radius: 12rpx;
|
||
padding: 16rpx 10rpx;
|
||
|
||
.metric-col {
|
||
flex: 1;
|
||
text-align: center;
|
||
|
||
&.metric-clickable {
|
||
cursor: pointer;
|
||
&:active {
|
||
opacity: 0.8;
|
||
}
|
||
}
|
||
|
||
.metric-val {
|
||
font-size: 28rpx;
|
||
font-weight: bold;
|
||
color: #222222;
|
||
font-family: OPPOSANS;
|
||
line-height: 34rpx;
|
||
|
||
&.text-orange {
|
||
color: #ff6000;
|
||
}
|
||
}
|
||
|
||
.drill-tag {
|
||
font-size: 18rpx;
|
||
color: #ff6000;
|
||
background: #fff0e6;
|
||
padding: 2rpx 8rpx;
|
||
border-radius: 6rpx;
|
||
line-height: 22rpx;
|
||
font-weight: normal;
|
||
}
|
||
|
||
.metric-lbl {
|
||
font-size: 20rpx;
|
||
color: #999999;
|
||
margin-top: 4rpx;
|
||
}
|
||
}
|
||
|
||
.metric-divider {
|
||
width: 1rpx;
|
||
height: 36rpx;
|
||
background: #ebebed;
|
||
}
|
||
}
|
||
|
||
// 底部操作栏
|
||
.member-card-footer {
|
||
border-top: 1rpx solid #f5f5f5;
|
||
padding-top: 16rpx;
|
||
|
||
.register-time {
|
||
font-size: 22rpx;
|
||
color: #999999;
|
||
}
|
||
|
||
.actions-wrap {
|
||
.action-btn {
|
||
height: 48rpx;
|
||
padding: 0 16rpx;
|
||
border-radius: 24rpx;
|
||
font-size: 22rpx;
|
||
display: inline-flex;
|
||
align-items: center;
|
||
|
||
&.btn-drill {
|
||
background: linear-gradient(90deg, #fff0e6, #ffe6d6);
|
||
color: #ff6000;
|
||
font-weight: bold;
|
||
border: 1rpx solid #ffd8bf;
|
||
}
|
||
&.btn-call {
|
||
background: #fff0e6;
|
||
color: #ff6000;
|
||
}
|
||
&.btn-copy {
|
||
background: #f3f4f6;
|
||
color: #4b5563;
|
||
}
|
||
&.btn-reward {
|
||
background: #fff7ed;
|
||
color: #ea580c;
|
||
}
|
||
&.btn-detail {
|
||
background: #ffffff;
|
||
color: #666666;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// 身份徽章样式
|
||
.tag-box {
|
||
background: #c48a3a;
|
||
border-radius: 18rpx;
|
||
padding: 2rpx 10rpx;
|
||
display: inline-flex;
|
||
align-items: center;
|
||
|
||
.tag-img {
|
||
width: 28rpx;
|
||
height: 28rpx;
|
||
margin-right: 6rpx;
|
||
border-radius: 50%;
|
||
}
|
||
|
||
.tag-title {
|
||
font-size: 18rpx;
|
||
font-weight: 500;
|
||
color: #ffffff;
|
||
line-height: 24rpx;
|
||
}
|
||
}
|
||
|
||
.mini-tag {
|
||
padding: 2rpx 10rpx;
|
||
height: 30rpx;
|
||
line-height: 30rpx;
|
||
border-radius: 15rpx;
|
||
font-size: 18rpx;
|
||
color: #ffffff;
|
||
display: inline-flex;
|
||
align-items: center;
|
||
|
||
&.tag-venue {
|
||
background: #c48a3a;
|
||
}
|
||
&.tag-county {
|
||
background: #b45309;
|
||
}
|
||
&.tag-partner {
|
||
background: #dc2626;
|
||
}
|
||
}
|
||
|
||
// 空状态
|
||
.empty-wrap {
|
||
padding: 40rpx 0;
|
||
|
||
.reset-filter-btn {
|
||
padding: 14rpx 36rpx;
|
||
background: #f3f4f6;
|
||
border-radius: 30rpx;
|
||
font-size: 24rpx;
|
||
color: #4b5563;
|
||
}
|
||
|
||
.invite-cta-btn {
|
||
padding: 18rpx 50rpx;
|
||
background: linear-gradient(90deg, #ff6000, #ff8533);
|
||
color: #ffffff;
|
||
border-radius: 36rpx;
|
||
font-size: 28rpx;
|
||
font-weight: bold;
|
||
box-shadow: 0 6rpx 20rpx rgba(255, 96, 0, 0.25);
|
||
}
|
||
}
|
||
|
||
// 抽屉详情
|
||
.drawer-content {
|
||
.drawer-header {
|
||
.drawer-avatar {
|
||
width: 100rpx;
|
||
height: 100rpx;
|
||
border-radius: 50%;
|
||
border: 4rpx solid #ffefe0;
|
||
}
|
||
.user-id {
|
||
font-size: 22rpx;
|
||
color: #888888;
|
||
}
|
||
.dot-split {
|
||
margin: 0 8rpx;
|
||
color: #bbbbbb;
|
||
}
|
||
.join-time {
|
||
font-size: 22rpx;
|
||
color: #888888;
|
||
}
|
||
}
|
||
|
||
.drawer-section {
|
||
.section-title {
|
||
font-size: 26rpx;
|
||
font-weight: bold;
|
||
color: #333333;
|
||
margin-bottom: 12rpx;
|
||
}
|
||
|
||
.section-box {
|
||
background: #f9fafb;
|
||
border-radius: 14rpx;
|
||
padding: 20rpx;
|
||
|
||
&.active-detail-box {
|
||
.line-label {
|
||
font-size: 24rpx;
|
||
color: #6b7280;
|
||
}
|
||
.line-val {
|
||
font-size: 24rpx;
|
||
font-weight: 500;
|
||
color: #1f2937;
|
||
}
|
||
.notice-tip {
|
||
font-size: 22rpx;
|
||
color: #92400e;
|
||
background: #fef3c7;
|
||
border-radius: 8rpx;
|
||
padding: 10rpx 14rpx;
|
||
line-height: 32rpx;
|
||
}
|
||
}
|
||
|
||
&.performance-box {
|
||
.perf-col {
|
||
flex: 1;
|
||
text-align: center;
|
||
.perf-num {
|
||
font-size: 32rpx;
|
||
font-weight: bold;
|
||
color: #111827;
|
||
font-family: OPPOSANS;
|
||
}
|
||
.perf-lbl {
|
||
font-size: 22rpx;
|
||
color: #6b7280;
|
||
margin-top: 6rpx;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.status-text-bold {
|
||
font-size: 24rpx;
|
||
font-weight: bold;
|
||
|
||
&.text-green {
|
||
color: #059669;
|
||
}
|
||
&.text-yellow {
|
||
color: #d97706;
|
||
}
|
||
&.text-gray {
|
||
color: #6b7280;
|
||
}
|
||
}
|
||
|
||
.drawer-drill-card {
|
||
background: linear-gradient(135deg, #fff7ed 0%, #ffedd5 100%);
|
||
border: 1rpx solid #fed7aa;
|
||
border-radius: 16rpx;
|
||
padding: 20rpx 24rpx;
|
||
transition: all 0.2s;
|
||
|
||
&:active {
|
||
opacity: 0.9;
|
||
transform: scale(0.99);
|
||
}
|
||
|
||
.drill-card-left {
|
||
.drill-icon-box {
|
||
width: 56rpx;
|
||
height: 56rpx;
|
||
border-radius: 28rpx;
|
||
background: #ffffff;
|
||
box-shadow: 0 4rpx 10rpx rgba(255, 96, 0, 0.15);
|
||
}
|
||
|
||
.drill-info {
|
||
.drill-title {
|
||
font-size: 26rpx;
|
||
font-weight: bold;
|
||
color: #9a3412;
|
||
line-height: 34rpx;
|
||
}
|
||
.drill-desc {
|
||
font-size: 22rpx;
|
||
color: #c2410c;
|
||
margin-top: 4rpx;
|
||
line-height: 28rpx;
|
||
}
|
||
}
|
||
}
|
||
|
||
.drill-card-right {
|
||
.drill-btn-text {
|
||
font-size: 24rpx;
|
||
font-weight: bold;
|
||
color: #ea580c;
|
||
margin-right: 4rpx;
|
||
}
|
||
}
|
||
}
|
||
|
||
.drawer-actions {
|
||
.drawer-btn {
|
||
height: 72rpx;
|
||
border-radius: 36rpx;
|
||
font-size: 26rpx;
|
||
font-weight: 500;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
|
||
&.drawer-btn-primary {
|
||
background: #ff6000;
|
||
color: #ffffff;
|
||
}
|
||
&.drawer-btn-sub {
|
||
background: #fff0e6;
|
||
color: #ff6000;
|
||
}
|
||
&.drawer-btn-outline {
|
||
background: #f3f4f6;
|
||
color: #4b5563;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
</style>
|