498 lines
13 KiB
Vue
498 lines
13 KiB
Vue
<template>
|
||
<clinic-salesperson-page-layout title="推广员工作台" :show-tabbar="true" :tab-index="0">
|
||
<view class="workspace-container">
|
||
|
||
<!-- 极简流线型顶部个人信息区 -->
|
||
<view class="hero-section">
|
||
<view class="brand-info-wrap">
|
||
<view class="brand-text">
|
||
<view class="badge"><text class="badge-text">推广员工作台</text></view>
|
||
<text class="store-name">{{ displayName }}</text>
|
||
<text class="store-sub">{{ storeName }}</text>
|
||
</view>
|
||
<view class="qr-container" @click="openQrCode">
|
||
<image
|
||
v-if="qrCode"
|
||
class="qr-image"
|
||
:src="qrCode"
|
||
mode="aspectFit"
|
||
/>
|
||
<view v-else class="qr-placeholder">
|
||
<!-- 替换电子名片 emoji -->
|
||
<u-icon name="scan" size="48" color="#666"></u-icon>
|
||
</view>
|
||
<text class="qr-hint">电子名片</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 核心资产看板:深色高定质感 -->
|
||
<view class="asset-dashboard">
|
||
<!-- 主资产卡片 (深邃质感) -->
|
||
<view class="primary-asset-card">
|
||
<!-- 装饰性光晕 -->
|
||
<view class="glow-orb glow-top-right"></view>
|
||
<view class="glow-orb glow-bottom-left"></view>
|
||
|
||
<view class="card-content-relative">
|
||
<view class="asset-header">
|
||
<view class="asset-title-wrap">
|
||
<text class="asset-title">待结算收益 (元)</text>
|
||
<view class="asset-status-dot"></view>
|
||
</view>
|
||
<view class="asset-tag">即将入账</view>
|
||
</view>
|
||
|
||
<view class="asset-amount-wrap">
|
||
<text class="asset-currency">¥</text>
|
||
<text class="asset-amount-huge">{{ stats.pending_amount || '0.00' }}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 副指标区:胶囊状悬浮卡片 -->
|
||
<view class="secondary-stats-row">
|
||
<view class="stat-capsule">
|
||
<view class="capsule-icon-wrap bg-blue">
|
||
<!-- 替换已结算 emoji -->
|
||
<u-icon name="rmb-circle-fill" size="36" color="#3B82F6"></u-icon>
|
||
</view>
|
||
<view class="capsule-text-wrap">
|
||
<text class="capsule-label">已结算</text>
|
||
<text class="capsule-value">{{ stats.settled_amount || '0.00' }}</text>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="stat-capsule">
|
||
<view class="capsule-icon-wrap bg-purple">
|
||
<!-- 替换累计获客 emoji -->
|
||
<u-icon name="account-fill" size="36" color="#A855F7"></u-icon>
|
||
</view>
|
||
<view class="capsule-text-wrap">
|
||
<text class="capsule-label">累计获客</text>
|
||
<text class="capsule-value">{{ stats.user_number || 0 }}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 快捷服务区:多彩微拟物质感 -->
|
||
<view class="section-panel">
|
||
<view class="panel-header">
|
||
<text class="panel-title">常用服务</text>
|
||
</view>
|
||
|
||
<view class="service-grid">
|
||
<view
|
||
v-for="(item, index) in enrichedMenuItems"
|
||
:key="item.key"
|
||
class="service-card"
|
||
hover-class="service-card-hover"
|
||
@click="go(item.path)"
|
||
>
|
||
<view class="service-icon-box" :style="{ background: item.theme.bg }">
|
||
<!-- 替换为 uView 动态图标 -->
|
||
<u-icon :name="item.icon" size="38" :color="item.theme.color"></u-icon>
|
||
</view>
|
||
<view class="service-info">
|
||
<text class="service-name">{{ item.label }}</text>
|
||
<text class="service-desc">{{ item.desc }}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
</view>
|
||
</clinic-salesperson-page-layout>
|
||
</template>
|
||
|
||
<script>
|
||
import ClinicSalespersonPageLayout from '@/subPackages/sub_clinic_salesperson/components/clinic-salesperson-page-layout.vue'
|
||
import { getClinicSalespersonMyInfo } from '@/api/clinicSalesperson.js'
|
||
import { openQrCodePreview, buildSalespersonQrPayload } from '@/utils/qrCodePreview.js'
|
||
|
||
const ROOT = '/subPackages/sub_clinic_salesperson'
|
||
|
||
export default {
|
||
components: { ClinicSalespersonPageLayout },
|
||
data() {
|
||
return {
|
||
displayName: '',
|
||
storeName: '',
|
||
qrCode: '',
|
||
profileInfo: null,
|
||
stats: {},
|
||
menuItems: [
|
||
{ key: 'earnings', label: '我的收益', path: `${ROOT}/earnings/index` },
|
||
{ key: 'leads', label: '获客记录', path: `${ROOT}/leads/index` },
|
||
{ key: 'commission', label: '分成记录', path: `${ROOT}/commission/index` },
|
||
{ key: 'settlement', label: '结算记录', path: `${ROOT}/settlement/index` },
|
||
],
|
||
}
|
||
},
|
||
computed: {
|
||
// 动态注入多彩主题和增强文案,使用 uView 图标名称
|
||
enrichedMenuItems() {
|
||
const themes = [
|
||
// 收益:使用钻石/钱包相关图标
|
||
{ bg: 'linear-gradient(135deg, #FFF7ED, #FFEDD5)', color: '#F97316', desc: '查看收益明细', icon: 'red-packet-fill' },
|
||
// 获客:使用目标/数据相关图标
|
||
{ bg: 'linear-gradient(135deg, #EFF6FF, #DBEAFE)', color: '#3B82F6', desc: '客户转化漏斗', icon: 'bag-fill' },
|
||
// 分成:使用图表/比例相关图标
|
||
{ bg: 'linear-gradient(135deg, #FAF5FF, #F3E8FF)', color: '#A855F7', desc: '分佣比例与记录', icon: 'red-packet-fill' },
|
||
// 结算:使用卡片/提现相关图标
|
||
{ bg: 'linear-gradient(135deg, #F0FDF4, #DCFCE7)', color: '#22C55E', desc: '提现与账单', icon: 'rmb-circle-fill' },
|
||
];
|
||
return this.menuItems.map((item, index) => ({
|
||
...item,
|
||
icon: themes[index % themes.length].icon,
|
||
desc: themes[index % themes.length].desc,
|
||
theme: themes[index % themes.length]
|
||
}));
|
||
}
|
||
},
|
||
onShow() {
|
||
this.loadInfo()
|
||
},
|
||
methods: {
|
||
async loadInfo() {
|
||
const wrap = await getClinicSalespersonMyInfo()
|
||
if (!wrap || !wrap.ok) return
|
||
const info = wrap.data || {}
|
||
this.profileInfo = info
|
||
this.displayName = info.salesperson?.nick_name || '推广员'
|
||
this.storeName = info.store?.name || ''
|
||
this.qrCode = info.qr_code || ''
|
||
this.stats = info.stats || {}
|
||
uni.setStorageSync('clinic_salesperson_user', info)
|
||
},
|
||
openQrCode() {
|
||
if (!this.qrCode) {
|
||
uni.showToast({ title: '暂无推广二维码', icon: 'none' })
|
||
return
|
||
}
|
||
const { type, payload } = buildSalespersonQrPayload(this.profileInfo || {
|
||
qr_code: this.qrCode,
|
||
store: { name: this.storeName },
|
||
salesperson: { nick_name: this.displayName },
|
||
})
|
||
openQrCodePreview({ type, payload })
|
||
},
|
||
go(path) {
|
||
uni.navigateTo({ url: path })
|
||
},
|
||
},
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
/* 全局容器背景 */
|
||
.workspace-container {
|
||
padding-bottom: 80rpx;
|
||
background-color: #F4F6F8; /* 更干净的高级浅灰底色 */
|
||
min-height: 100vh;
|
||
}
|
||
|
||
/* ================= 极简顶部英雄区 ================= */
|
||
.hero-section {
|
||
background: linear-gradient(135deg, #6acdbb 0%, #4db6a8 100%);
|
||
padding: 40rpx 40rpx 120rpx; /* 底部预留负边距空间 */
|
||
border-bottom-left-radius: 48rpx;
|
||
border-bottom-right-radius: 48rpx;
|
||
box-shadow: 0 4rpx 20rpx rgba(77, 182, 168, 0.2);
|
||
}
|
||
|
||
.brand-info-wrap {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
}
|
||
|
||
.brand-text {
|
||
flex: 1;
|
||
}
|
||
|
||
.badge {
|
||
display: inline-flex;
|
||
background: rgba(255, 255, 255, 0.15);
|
||
backdrop-filter: blur(8px);
|
||
padding: 6rpx 20rpx;
|
||
border-radius: 30rpx;
|
||
margin-bottom: 20rpx;
|
||
border: 1px solid rgba(255, 255, 255, 0.2);
|
||
}
|
||
|
||
.badge-text {
|
||
font-size: 22rpx;
|
||
color: #fff;
|
||
font-weight: 500;
|
||
letter-spacing: 2rpx;
|
||
}
|
||
|
||
.store-name {
|
||
font-size: 42rpx;
|
||
font-weight: 600;
|
||
color: #fff;
|
||
display: block;
|
||
margin-bottom: 6rpx;
|
||
}
|
||
|
||
.store-sub {
|
||
font-size: 26rpx;
|
||
color: rgba(255, 255, 255, 0.85);
|
||
display: block;
|
||
}
|
||
|
||
.qr-container {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
}
|
||
|
||
.qr-image, .qr-placeholder {
|
||
width: 110rpx;
|
||
height: 110rpx;
|
||
background: #fff;
|
||
border-radius: 24rpx;
|
||
padding: 10rpx;
|
||
box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.1);
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
|
||
/* 移除了无用的 .qr-icon-placeholder 类 */
|
||
|
||
.qr-hint {
|
||
font-size: 20rpx;
|
||
color: rgba(255, 255, 255, 0.9);
|
||
margin-top: 12rpx;
|
||
background: rgba(0, 0, 0, 0.1);
|
||
padding: 4rpx 16rpx;
|
||
border-radius: 20rpx;
|
||
}
|
||
|
||
/* ================= 核心资产看板区 ================= */
|
||
.asset-dashboard {
|
||
margin: -80rpx 30rpx 40rpx;
|
||
position: relative;
|
||
z-index: 10;
|
||
}
|
||
|
||
/* 主卡片:黑金/深色沉浸质感 */
|
||
.primary-asset-card {
|
||
position: relative;
|
||
background: linear-gradient(145deg, #1E293B 0%, #0F172A 100%);
|
||
border-radius: 32rpx;
|
||
padding: 40rpx;
|
||
box-shadow: 0 16rpx 40rpx rgba(15, 23, 42, 0.15);
|
||
overflow: hidden;
|
||
margin-bottom: 24rpx;
|
||
}
|
||
|
||
/* 抽象光晕装饰背景,提升高定感 */
|
||
.glow-orb {
|
||
position: absolute;
|
||
border-radius: 50%;
|
||
filter: blur(40px);
|
||
opacity: 0.4;
|
||
pointer-events: none;
|
||
}
|
||
|
||
.glow-top-right {
|
||
width: 200rpx;
|
||
height: 200rpx;
|
||
background: #4DB6A8;
|
||
top: -50rpx;
|
||
right: -50rpx;
|
||
}
|
||
|
||
.glow-bottom-left {
|
||
width: 150rpx;
|
||
height: 150rpx;
|
||
background: #3B82F6;
|
||
bottom: -40rpx;
|
||
left: -40rpx;
|
||
}
|
||
|
||
.card-content-relative {
|
||
position: relative;
|
||
z-index: 2;
|
||
}
|
||
|
||
.asset-header {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
margin-bottom: 20rpx;
|
||
}
|
||
|
||
.asset-title-wrap {
|
||
display: flex;
|
||
align-items: center;
|
||
}
|
||
|
||
.asset-title {
|
||
font-size: 26rpx;
|
||
color: #94A3B8;
|
||
font-weight: 500;
|
||
}
|
||
|
||
.asset-status-dot {
|
||
width: 12rpx;
|
||
height: 12rpx;
|
||
background-color: #10B981;
|
||
border-radius: 50%;
|
||
margin-left: 12rpx;
|
||
box-shadow: 0 0 8rpx rgba(16, 185, 129, 0.6);
|
||
}
|
||
|
||
.asset-tag {
|
||
font-size: 20rpx;
|
||
color: #F8FAFC;
|
||
background: rgba(255, 255, 255, 0.1);
|
||
padding: 6rpx 16rpx;
|
||
border-radius: 20rpx;
|
||
backdrop-filter: blur(4px);
|
||
border: 1px solid rgba(255, 255, 255, 0.05);
|
||
}
|
||
|
||
.asset-amount-wrap {
|
||
display: flex;
|
||
align-items: baseline;
|
||
color: #F8FAFC; /* 亮白色金额 */
|
||
}
|
||
|
||
.asset-currency {
|
||
font-size: 40rpx;
|
||
font-weight: 600;
|
||
margin-right: 8rpx;
|
||
}
|
||
|
||
.asset-amount-huge {
|
||
font-size: 80rpx;
|
||
font-weight: 700;
|
||
letter-spacing: -2rpx;
|
||
font-family: "DIN Alternate", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
|
||
text-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.2);
|
||
}
|
||
|
||
/* 胶囊副指标区 */
|
||
.secondary-stats-row {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
gap: 20rpx;
|
||
}
|
||
|
||
.stat-capsule {
|
||
flex: 1;
|
||
background: #FFFFFF;
|
||
border-radius: 24rpx;
|
||
padding: 24rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.03);
|
||
}
|
||
|
||
.capsule-icon-wrap {
|
||
width: 64rpx;
|
||
height: 64rpx;
|
||
border-radius: 18rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
margin-right: 20rpx;
|
||
}
|
||
|
||
.bg-blue { background: #EFF6FF; }
|
||
.bg-purple { background: #FAF5FF; }
|
||
/* 移除了无用的 .capsule-icon 类 */
|
||
|
||
.capsule-text-wrap {
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
|
||
.capsule-label {
|
||
font-size: 22rpx;
|
||
color: #64748B;
|
||
margin-bottom: 4rpx;
|
||
}
|
||
|
||
.capsule-value {
|
||
font-size: 32rpx;
|
||
font-weight: 700;
|
||
color: #0F172A;
|
||
font-family: "DIN Alternate", sans-serif;
|
||
}
|
||
|
||
/* ================= 快捷服务区:多彩拟物 ================= */
|
||
.section-panel {
|
||
margin: 0 30rpx;
|
||
background: transparent;
|
||
}
|
||
|
||
.panel-header {
|
||
margin-bottom: 24rpx;
|
||
padding: 0 10rpx;
|
||
}
|
||
|
||
.panel-title {
|
||
font-size: 34rpx;
|
||
font-weight: 700;
|
||
color: #1E293B;
|
||
}
|
||
|
||
.service-grid {
|
||
display: grid;
|
||
grid-template-columns: repeat(2, 1fr);
|
||
gap: 20rpx;
|
||
}
|
||
|
||
.service-card {
|
||
background: #FFFFFF;
|
||
border-radius: 28rpx;
|
||
padding: 30rpx 24rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.02);
|
||
transition: all 0.2s ease;
|
||
border: 1px solid rgba(0, 0, 0, 0.01);
|
||
}
|
||
|
||
.service-card-hover {
|
||
transform: translateY(-2rpx);
|
||
box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.06);
|
||
}
|
||
|
||
.service-icon-box {
|
||
width: 76rpx;
|
||
height: 76rpx;
|
||
border-radius: 22rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
margin-right: 20rpx;
|
||
flex-shrink: 0;
|
||
box-shadow: inset 0 2rpx 4rpx rgba(255, 255, 255, 0.5); /* 顶部微高光,增加拟物质感 */
|
||
}
|
||
|
||
/* 移除了无用的 .service-icon 类 */
|
||
|
||
.service-info {
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
|
||
.service-name {
|
||
font-size: 28rpx;
|
||
font-weight: 600;
|
||
color: #1E293B;
|
||
margin-bottom: 6rpx;
|
||
}
|
||
|
||
.service-desc {
|
||
font-size: 20rpx;
|
||
color: #94A3B8;
|
||
}
|
||
</style> |