Files
xk-doctor-wx/subPackages/sub_clinic_admin/home/index.vue
2026-06-05 12:28:36 +08:00

331 lines
9.3 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-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">{{ storeName }}</text>
<text class="store-sub">欢迎回来今天也要高效工作</text>
</view>
<!-- 诊所专属二维码 -->
<view class="qr-container" @click="openStoreQrCode">
<image
v-if="storeQrCode"
class="qr-image"
:src="storeQrCode"
mode="aspectFit"
/>
<view v-else class="qr-placeholder">
<u-icon name="scan" size="48" color="#666"></u-icon>
</view>
<text class="qr-hint">诊所名片</text>
</view>
</view>
</view>
<!-- 主体内容区快捷服务多彩微拟物双列卡片 -->
<view class="content-wrapper">
<view v-for="section in sections" :key="section.key" class="section-panel">
<view class="panel-header">
<text class="panel-title">{{ section.title }}</text>
</view>
<view class="service-grid">
<view
v-for="item in section.items"
: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 }">
<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>
</view>
</clinic-page-layout>
</template>
<script>
import ClinicPageLayout from '@/subPackages/sub_clinic_admin/components/clinic-page-layout.vue'
import { getWarehouseProductTypeOptions, getClinicAdminStoreQr } from '@/api/clinicAdmin.js'
import { openQrCodePreview, buildClinicQrPayload } from '@/utils/qrCodePreview.js'
// 全局主题色池
const GLOBAL_THEMES = [
{ bg: 'linear-gradient(135deg, #FFF7ED, #FFEDD5)', color: '#F97316' }, // 橙金
{ bg: 'linear-gradient(135deg, #EFF6FF, #DBEAFE)', color: '#3B82F6' }, // 科技蓝
{ bg: 'linear-gradient(135deg, #FAF5FF, #F3E8FF)', color: '#A855F7' }, // 优雅紫
{ bg: 'linear-gradient(135deg, #F0FDF4, #DCFCE7)', color: '#22C55E' }, // 安全绿
]
// 补充了 desc 字段以适配新的 UI
const FINANCE_MENUS = [
{ key: 'withdrawal', label: '提现管理', desc: '提现流水查询', icon: 'red-packet-fill', theme: GLOBAL_THEMES[0], path: '/subPackages/sub_clinic_admin/withdrawal/index' },
{ key: 'reconciliation', label: '对账单', desc: '财务对账明细', icon: 'file-text-fill', theme: GLOBAL_THEMES[1], path: '/subPackages/sub_clinic_admin/reconciliation/index' },
]
const BUSINESS_MENUS = [
{ key: 'order', label: '商品订单', desc: '全平台订单概览', icon: 'bag-fill', theme: GLOBAL_THEMES[3], path: '/subPackages/sub_clinic_admin/order/index' },
]
const WAREHOUSE_FALLBACK = {
key: 'warehouse',
label: '仓库管理',
desc: '库存管理中心',
icon: 'car-fill',
theme: { bg: 'linear-gradient(135deg, #F3F4F6, #E5E7EB)', color: '#6B7280' }, // 占位灰
path: '/subPackages/sub_clinic_admin/warehouse/index',
}
export default {
components: { ClinicPageLayout },
data() {
return {
storeName: '',
storeQrCode: '',
storeQrData: null,
warehouseMenus: [WAREHOUSE_FALLBACK],
}
},
computed: {
sections() {
return [
{ key: 'finance', title: '财务管理', items: FINANCE_MENUS },
{ key: 'business', title: '业务管理', items: BUSINESS_MENUS },
{ key: 'warehouse', title: '仓库管理', items: this.warehouseMenus },
]
},
},
onShow() {
const user = uni.getStorageSync('clinic_admin_user') || {}
this.storeName = user.store_name || (user.store && user.store.name) || user.nick_name || '诊所管理'
this.loadStoreQr()
this.loadWarehouseMenus()
},
methods: {
async loadStoreQr() {
this.storeQrCode = ''
this.storeQrData = null
const wrap = await getClinicAdminStoreQr()
if (!wrap || !wrap.ok) return
const store = wrap.data || {}
if (!store.qr_code) return
this.storeQrData = store
this.storeQrCode = store.qr_code
if (store.name) this.storeName = store.name
},
openStoreQrCode() {
if (!this.storeQrCode || !this.storeQrData) {
uni.showToast({ title: '诊所尚未生成二维码', icon: 'none' })
return
}
const { type, payload } = buildClinicQrPayload(this.storeQrData)
openQrCodePreview({ type, payload })
},
loadWarehouseMenus() {
getWarehouseProductTypeOptions().then(w => {
const raw = w.data
const options = Array.isArray(raw) ? raw : []
const warehouseMenus = options.map((opt, index) => {
const value = opt.value != null ? opt.value : opt.id
const label = opt.label || opt.name || '仓库'
const title = label.indexOf('仓库') >= 0 ? label : label
// 为动态仓库分配不同的主题色
const theme = GLOBAL_THEMES[index % GLOBAL_THEMES.length]
return {
key: 'warehouse-' + value,
label: title,
desc: `${title}库存管理`, // 增强描述
icon: 'car-fill', // 统一使用车辆图标代表仓库物流
theme: theme,
path: '/subPackages/sub_clinic_admin/warehouse/index?type=' + encodeURIComponent(value) + '&label=' + encodeURIComponent(title),
}
})
this.warehouseMenus = warehouseMenus.length ? warehouseMenus : [WAREHOUSE_FALLBACK]
}).catch(() => {
this.warehouseMenus = [WAREHOUSE_FALLBACK]
})
},
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 60rpx;
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-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;
}
/* ================= 主体内容区:快捷服务 ================= */
.content-wrapper {
margin-top: 30rpx; /* 轻微向上偏移,与顶部区域产生连接感 */
position: relative;
z-index: 10;
}
.section-panel {
margin: 0 30rpx 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-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>