192 lines
5.4 KiB
Vue
192 lines
5.4 KiB
Vue
<template>
|
||
<clinic-page-layout title="我的" :show-tabbar="true" :tab-index="1">
|
||
<view class="mine-container">
|
||
<!-- 资料区:圆形头像 + 姓名 + 角色(对齐医生「我的」) -->
|
||
<view class="profile-panel">
|
||
<view class="avatar-circle">
|
||
<text>{{ avatarText }}</text>
|
||
</view>
|
||
<view class="user-info">
|
||
<text class="user-name">{{ displayName }}</text>
|
||
<view class="role-badge">
|
||
<text class="role-text">诊所管理员</text>
|
||
</view>
|
||
<text v-if="storeName && storeName !== '-'" class="store-line">{{ storeName }}</text>
|
||
</view>
|
||
</view>
|
||
<!-- 会员卡片:功能列表入口上方 -->
|
||
<vip-member-card :vip="vipInfo" />
|
||
<!-- 白色菜单卡:绑定微信 + 切换账号 -->
|
||
<view class="setting-panel">
|
||
<wx-bind-entry ref="wxBindEntry" />
|
||
<account-switch-entry />
|
||
</view>
|
||
<!-- 独立绿色退出按钮 -->
|
||
<view class="logout-wrap">
|
||
<u-button
|
||
:throttle-time="0"
|
||
shape="circle"
|
||
:custom-style="{ backgroundColor: '#6ACDBB', color: '#fff', height: '96rpx' }"
|
||
@click="logout"
|
||
>退出登录</u-button>
|
||
</view>
|
||
</view>
|
||
</clinic-page-layout>
|
||
</template>
|
||
|
||
<script>
|
||
/**
|
||
* 诊所/门店管理员「我的」:布局对齐医生(菜单卡 + 绿色退出)
|
||
* 资料区与功能入口之间展示门店 VIP 会员卡片
|
||
*/
|
||
import ClinicPageLayout from '@/subPackages/sub_clinic_admin/components/clinic-page-layout.vue'
|
||
import VipMemberCard from '@/subPackages/sub_clinic_admin/components/vip-member-card.vue'
|
||
import AccountSwitchEntry from '@/components/account-switch/account-switch-entry.vue'
|
||
import WxBindEntry from '@/components/wx-bind-entry/wx-bind-entry.vue'
|
||
import { getClinicAdminMyInfo } from '@/api/clinicAdmin.js'
|
||
import { clearLoginStorage } from '@/utils/loginSession.js'
|
||
|
||
export default {
|
||
components: { ClinicPageLayout, VipMemberCard, AccountSwitchEntry, WxBindEntry },
|
||
data() {
|
||
return {
|
||
displayName: '',
|
||
storeName: '',
|
||
vipInfo: null,
|
||
}
|
||
},
|
||
computed: {
|
||
avatarText() {
|
||
const n = this.displayName || '管'
|
||
return n.slice(0, 1)
|
||
},
|
||
},
|
||
onShow() {
|
||
this.loadLocalUser()
|
||
this.refreshVip()
|
||
if (this.$refs.wxBindEntry) this.$refs.wxBindEntry.refresh()
|
||
},
|
||
methods: {
|
||
/** 先读本地缓存,保证首屏有基础信息 */
|
||
loadLocalUser() {
|
||
const user = uni.getStorageSync('clinic_admin_user') || {}
|
||
this.displayName = user.nick_name || user.name || user.account || '管理员'
|
||
this.storeName = user.store_name || (user.store && user.store.name) || '-'
|
||
if (user.vip) {
|
||
this.vipInfo = user.vip
|
||
}
|
||
},
|
||
/**
|
||
* 拉取 my-info,刷新 VIP 并写回缓存
|
||
* 为什么单独请求:本地缓存可能滞后于后台开通/到期回落
|
||
*/
|
||
async refreshVip() {
|
||
try {
|
||
const { data, ok } = await getClinicAdminMyInfo()
|
||
if (!ok || !data) return
|
||
const info = data
|
||
if (info.nick_name || info.name) {
|
||
this.displayName = info.nick_name || info.name || this.displayName
|
||
}
|
||
if (info.store_name) {
|
||
this.storeName = info.store_name
|
||
}
|
||
this.vipInfo = info.vip || null
|
||
const cached = uni.getStorageSync('clinic_admin_user') || {}
|
||
uni.setStorageSync('clinic_admin_user', Object.assign({}, cached, info, {
|
||
vip: info.vip || null,
|
||
}))
|
||
} catch (e) {
|
||
// 静默失败:保留本地缓存展示
|
||
console.warn('刷新诊所管理员VIP失败', e)
|
||
}
|
||
},
|
||
logout() {
|
||
uni.showModal({
|
||
title: '提示',
|
||
content: '确定退出登录?',
|
||
confirmColor: '#6ACDBB',
|
||
success: (res) => {
|
||
if (!res.confirm) return
|
||
clearLoginStorage()
|
||
uni.reLaunch({ url: '/pages/login/index' })
|
||
},
|
||
})
|
||
},
|
||
},
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
$theme-primary: #6acdbb;
|
||
$theme-dark: #4db6a8;
|
||
$color-page-bg: #F5F7F8;
|
||
$color-text-title: #222B2A;
|
||
$color-text-muted: #86909C;
|
||
|
||
.mine-container {
|
||
padding: 0 0 60rpx;
|
||
background-color: $color-page-bg;
|
||
min-height: 100vh;
|
||
box-sizing: border-box;
|
||
}
|
||
.profile-panel {
|
||
display: flex;
|
||
align-items: center;
|
||
background-color: #ffffff;
|
||
padding: 60rpx 40rpx 50rpx;
|
||
margin-bottom: 24rpx;
|
||
}
|
||
.avatar-circle {
|
||
width: 128rpx;
|
||
height: 128rpx;
|
||
border-radius: 50%;
|
||
background: linear-gradient(135deg, $theme-primary 0%, $theme-dark 100%);
|
||
box-shadow: 0 8rpx 24rpx rgba(106, 205, 187, 0.25);
|
||
color: #ffffff;
|
||
font-size: 52rpx;
|
||
font-weight: 600;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
flex-shrink: 0;
|
||
}
|
||
.user-info {
|
||
margin-left: 32rpx;
|
||
display: flex;
|
||
flex-direction: column;
|
||
justify-content: center;
|
||
}
|
||
.user-name {
|
||
font-size: 40rpx;
|
||
font-weight: 700;
|
||
color: $color-text-title;
|
||
margin-bottom: 12rpx;
|
||
}
|
||
.role-badge {
|
||
align-self: flex-start;
|
||
background-color: rgba(106, 205, 187, 0.1);
|
||
border: 1rpx solid rgba(106, 205, 187, 0.2);
|
||
padding: 4rpx 16rpx;
|
||
border-radius: 8rpx;
|
||
}
|
||
.role-text {
|
||
font-size: 22rpx;
|
||
color: $theme-dark;
|
||
font-weight: 600;
|
||
}
|
||
.store-line {
|
||
margin-top: 12rpx;
|
||
font-size: 26rpx;
|
||
color: $color-text-muted;
|
||
}
|
||
.setting-panel {
|
||
background-color: #ffffff;
|
||
margin-bottom: 24rpx;
|
||
padding: 8rpx 40rpx 16rpx;
|
||
}
|
||
.logout-wrap {
|
||
padding: 0 40rpx 32rpx;
|
||
}
|
||
</style>
|