Files
xk-doctor-wx/subPackages/sub_clinic_salesperson/home/index.vue
2026-06-24 07:53:32 +08:00

502 lines
13 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<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: 'transfer', label: '传方', path: '/subPackages/sub_workbench/prescription_v2/index?salesperson_transfer=1&initial_category=1' },
// { key: 'transfer-list', label: '传方记录', path: `${ROOT}/transfer-prescription/list` },
// { 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, #ECFDF5, #D1FAE5)', color: '#10B981', desc: '线下中药传方', icon: 'edit-pen-fill' },
{ bg: 'linear-gradient(135deg, #F0F9FF, #E0F2FE)', color: '#0EA5E9', desc: '历史传方记录', icon: 'file-text-fill' },
// 收益:使用钻石/钱包相关图标
{ 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>