Files
xk-client-wx/pages/home/home.vue

1347 lines
49 KiB
Vue
Raw Normal View History

2024-09-19 12:51:35 +08:00
<template>
<view class="content safe-area-inset-bottom">
2026-01-07 14:21:29 +08:00
<!-- 全局消息通知组件 -->
<MessageNotification />
2026-05-30 16:54:01 +08:00
<image-compress-popup ref="imageCompressPopup" />
2026-07-02 14:11:24 +08:00
2025-12-31 10:18:07 +08:00
<!-- 1. 自定义吸顶导航栏 -->
<view class="custom-nav"
:class="[
2026-01-12 12:36:50 +08:00
(storeType === '1' || storeType === 1) ? 'header-pharmacy' : 'header-clinic',
2025-12-31 10:18:07 +08:00
{ 'nav-sticky': isSticky }
]"
:style="{ paddingTop: statusBarHeight + 'px', height: (statusBarHeight + 44) + 'px' }">
<view class="nav-content">
<view class="store-info" @click="toStore">
<text class="store-name u-line-1">{{infoList.store['name'] || storeinfo[0].store['name'] || info.name || '请选择门店'}}</text>
2026-01-12 12:36:50 +08:00
<view v-if="!isGuestMode()" class="switch-badge">
2025-12-31 10:18:07 +08:00
<text class="iconfont icon-qiehuan"></text> 切换
</view>
</view>
</view>
</view>
2025-12-31 10:18:07 +08:00
<!-- 2. 头部背景与定位区域 -->
2026-01-12 12:36:50 +08:00
<view class="header" :class="(storeType === '1' || storeType === 1) ? 'header-pharmacy' : 'header-clinic'"
2025-12-31 10:18:07 +08:00
:style="{ paddingTop: (statusBarHeight + 44 + 10) + 'px' }">
<view class="bg-circle"></view>
<view class="location-bar">
<text class="iconfont icon-dizhi"></text>
<text class="u-line-1">{{infoList.store['position'] || storeinfo[0].store.position || info.position || '定位获取中...'}}</text>
</view>
</view>
2025-12-31 10:18:07 +08:00
<!-- 3. 轮播图区域 -->
<view class="banner-section">
<view class="banner-card">
<u-swiper
:list="list"
:img-mode="'aspectFill'"
:height="300"
:interval="4000"
@click="toBanner"
border-radius="16"
mode="rect"
indicator-pos="bottomRight"
></u-swiper>
</view>
</view>
2025-12-31 10:18:07 +08:00
<!-- 2.5 金刚区 (Zone) - 支持滑动/换行切换 -->
<view v-if="homeZones.length > 0" class="zone-wrapper" :class="zoneLayoutMode === 'scroll' ? 'zone-scroll-mode' : 'zone-wrap-mode'">
<view v-for="(item, index) in homeZones" :key="index" class="zone-item" @click="goZoneList(item)">
<view class="zone-icon-box">
<image
2026-01-12 12:36:50 +08:00
:src="item.icon || ((storeType === '1' || storeType === 1) ? 'https://img.icons8.com/fluency/48/pill.png' : 'https://img.icons8.com/fluency/48/doctor-male.png')"
2025-12-31 10:18:07 +08:00
class="zone-img"
mode="aspectFit"
></image>
</view>
2025-12-31 10:18:07 +08:00
<text class="zone-text">{{ item.title }}</text>
</view>
2025-12-31 10:18:07 +08:00
</view>
2025-12-31 10:18:07 +08:00
<!-- 3. 核心功能导航 (Nav) -->
<view class="nav-grid">
<!-- 诊所模式2列布局 -->
2026-01-12 12:36:50 +08:00
<view v-if="storeType === '0' || storeType === 0" class="nav-clinic-grid">
2026-07-02 14:11:24 +08:00
<view class="nav-card" @click="goYard(0)">
2025-12-31 10:18:07 +08:00
<view class="nav-content">
<view class="nav-title" style="color:#4175EE">到店挂号</view>
<view class="nav-desc">预约专家 不排队</view>
</view>
2026-05-15 16:42:32 +08:00
<image src="https://xiaokang88.oss-cn-hangzhou.aliyuncs.com/xk-client-wx/static/home/bg1.png" class="nav-icon-img-64" mode="aspectFit"></image>
</view>
2026-02-02 16:10:46 +08:00
<view class="nav-card" @click="goYard(2)">
2025-12-31 10:18:07 +08:00
<view class="nav-content">
<view class="nav-title" style="color:#00B578">在线复诊</view>
<view class="nav-desc">在线选药 极速达</view>
</view>
2026-05-15 16:42:32 +08:00
<image src="https://xiaokang88.oss-cn-hangzhou.aliyuncs.com/xk-client-wx/static/home/bg2.png" class="nav-icon-img-64" mode="aspectFit"></image>
</view>
</view>
2025-12-31 10:18:07 +08:00
<!-- 药店模式单列铺满 -->
2026-01-12 12:36:50 +08:00
<view v-if="storeType === '1' || storeType === 1" class="nav-pharmacy-grid">
2025-12-31 10:18:07 +08:00
<view class="nav-card" @click="golist(3)">
<view class="nav-content">
<view class="nav-title" style="color:#298DFF">预约购药</view>
<view class="nav-desc">正品保障 · 种类齐全 · 快速配送</view>
</view>
<image src="https://img.icons8.com/3d-fluency/94/delivery-scooter.png" class="nav-icon-img" style="width:140rpx; height:140rpx; right:20rpx; bottom:10rpx;" mode="aspectFit"></image>
</view>
</view>
</view>
2024-09-19 12:51:35 +08:00
2026-07-02 14:11:24 +08:00
<!-- 待支付挂号提醒 -->
<view
v-if="unpaidRegisterCount > 0"
class="unpaid-banner unpaid-banner--register"
@click="onUnpaidRegisterBannerClick"
>
<text class="unpaid-banner-text">您有 {{ unpaidRegisterCount }} 个待支付挂号订单点击前往查看</text>
<text class="iconfont icon-jiantou1 unpaid-banner-arrow"></text>
</view>
<!-- 待支付商品订单提醒 -->
<view
v-if="unpaidProductOrderCount > 0"
class="unpaid-banner unpaid-banner--product"
@click="onUnpaidProductOrderBannerClick"
>
<text class="unpaid-banner-text">您有 {{ unpaidProductOrderCount }} 个待支付商品订单点击前往查看</text>
<text class="iconfont icon-jiantou1 unpaid-banner-arrow"></text>
</view>
<!-- 4. 诊所模式内容特色药方 -->
<view v-if="(storeType === '0' || storeType === 0) && specialPrescription.enabled" class="tea-section-wrap">
<!-- 特色药方异形卡片模块 -->
<view class="tea-section">
<view class="irregular-card">
<!-- 左侧凸起 Tab右侧带下坡过渡 -->
<view class="card-tab">
<view class="card-tab-slope"></view>
</view>
<!-- 悬浮艺术字标题位于凸起与卡片的衔接处 -->
<image
:src="specialPrescription.title_image"
class="main-title"
mode="widthFix"
></image>
<!-- 主体区域 -->
<view class="card-body">
<!-- 悬浮 IP 小熊 -->
<image
:src="specialPrescription.mascot_image"
class="main-mascot"
mode="widthFix"
></image>
<view class="tea-subtitle">
<view class="subtitle-icon"></view>
<text>{{ specialPrescription.subtitle || '精选时令养生茶饮' }}</text>
</view>
<!-- 横向滑动列表 -->
<scroll-view scroll-x class="tea-scroll" :show-scrollbar="false" :enable-passive="false">
<view class="tea-list">
<navigator
v-if="detailUrl(tea)"
class="tea-item"
v-for="(tea, tIndex) in specialPrescription.items"
2026-07-07 08:50:17 +08:00
:key="tIndex"
2026-07-02 14:11:24 +08:00
:url="detailUrl(tea)"
hover-class="tea-item--active"
>
<view class="tea-image-wrap">
<image
v-if="tea.cover_image"
:src="tea.cover_image"
class="tea-image"
mode="aspectFill"
></image>
<text v-else class="tea-image-placeholder">特色方</text>
</view>
<view class="tea-info-wrap">
<view class="tea-name u-line-1">{{ tea.name }}</view>
<view class="tea-tags">
<text class="tea-tag" v-for="(tag, gIndex) in (tea.tags || []).slice(0, 2)" :key="gIndex">{{ tag }}</text>
</view>
<view class="tea-price" v-if="tea.price_available !== false">
<text class="tea-price-symbol">¥</text>{{ tea.price_per_dose }}
</view>
<view class="tea-price tea-price--unavailable" v-else>暂无报价</view>
</view>
</navigator>
</view>
</scroll-view>
<!-- 底部操作区 -->
<view class="tea-bottom-area">
<view class="days-left-tag">热卖养生茶</view>
<view class="tea-action-button" @click="goTeaList">查看全部药方</view>
</view>
</view>
</view>
</view>
</view>
<!-- 诊所模式医生列表 -->
2026-01-12 12:36:50 +08:00
<view v-if="storeType === '0' || storeType === 0">
2026-07-02 14:11:24 +08:00
<!-- 医生列表 -->
2025-12-31 10:18:07 +08:00
<view class="section-header">
<view class="section-title">医生推荐</view>
2026-07-02 14:11:24 +08:00
<view class="section-more" @click="goYard(0)">更多 <text class="iconfont icon-jiantou1" style="font-size: 20rpx;"></text></view>
</view>
2024-09-19 12:51:35 +08:00
2025-12-31 10:18:07 +08:00
<view class="doctor-card" @click="goLookDoctor(item.id)" v-for="(item,index) in doctorList" :key="item.id">
<view class="doc-main">
<view class="doc-avatar-box">
2026-05-15 16:42:32 +08:00
<image :src="item.avatar || 'https://xiaokang88.oss-cn-hangzhou.aliyuncs.com/xk-client-wx/static/mine/avatar_1.png'" mode="aspectFill" class="doc-avatar"></image>
2025-12-31 10:18:07 +08:00
<view class="status-dot"></view>
</view>
2025-12-31 10:18:07 +08:00
<view class="doc-info">
<view class="doc-name-row">
<text class="doc-name">{{item.name}}</text>
<text class="doc-title">{{item.title}}</text>
</view>
2025-12-31 10:18:07 +08:00
<view class="doc-dept">{{item.depart}} | {{item.store}}</view>
<view class="doc-skill">
<text class="skill-tag">擅长</text>
{{item.good_at}}
</view>
</view>
2026-07-02 14:11:24 +08:00
<!-- <view class="consult-btn">咨询</view>-->
<!-- <view class="consult-btn">查看</view>-->
2025-12-31 10:18:07 +08:00
</view>
<view class="doc-stats-bar">
<view class="stat-item">
<text class="stat-num">{{item.inquiry_num || '0'}}</text>
<view class="stat-label">问诊量</view>
</view>
<view class="stat-item">
<text class="stat-num">{{item.accept_percent || '100%'}}</text>
<view class="stat-label">接诊率</view>
</view>
<view class="stat-item">
2026-01-12 12:36:50 +08:00
<text class="stat-num">{{item.average_response_time || 5}}分钟</text>
2025-12-31 10:18:07 +08:00
<view class="stat-label">平均响应</view>
</view>
</view>
</view>
</view>
2024-09-19 12:51:35 +08:00
2025-12-31 10:18:07 +08:00
<!-- 5. 药店模式内容热销好药 -->
2026-01-12 12:36:50 +08:00
<view v-if="storeType === '1' || storeType === 1">
2025-12-31 10:18:07 +08:00
<view class="section-header">
<view class="section-title">{{ topProductsTitle || '热销好药' }}</view>
<view class="section-more" @click="golist(3)">更多 <text class="iconfont icon-jiantou1" style="font-size: 20rpx;"></text></view>
</view>
2025-12-31 10:18:07 +08:00
<!-- 优化后的药品列表使用计算属性 displayProductList 解决循环报错 -->
<view class="product-list-container">
2025-12-31 10:18:07 +08:00
<view class="product-card" @click="goProductDetail(item)" v-for="(item, index) in displayProductList" :key="index">
<view class="prod-img-box">
2026-05-15 16:42:32 +08:00
<image :src="(item.drug && item.drug.image) ? item.drug.image : 'https://xiaokang88.oss-cn-hangzhou.aliyuncs.com/xk-client-wx/static/mine/avatar_1.png'" mode="aspectFill" class="prod-img" :class="{ 'prescription-blur': item.drug && item.drug.type == 2 && (item.drug.is_otc === 0 || item.drug.is_otc === '0') }"></image>
2025-12-31 10:18:07 +08:00
</view>
<view class="prod-info">
<view>
<view class="prod-title">{{ item.drug ? item.drug.drug_name : '' }}</view>
<view class="tag-row">
2026-01-13 13:36:55 +08:00
<!-- 只有西药type == 2才显示OTC/Rx标签 -->
<text v-if="item.drug && item.drug.type == 2" class="otc-tag" :class="item.drug.is_otc ? 'otc-green' : 'otc-red'">{{item.drug.is_otc ? 'OTC' : 'Rx'}}</text>
</view>
2025-12-31 10:18:07 +08:00
<view class="prod-spec">{{ item.drug ? item.drug.specification : '' }}</view>
</view>
2025-12-31 10:18:07 +08:00
<view class="prod-bottom">
<view class="price-box">
2025-12-31 10:18:07 +08:00
<text class="price-symbol">¥</text>
<text>{{ item.price || '0.00' }}</text>
2025-12-31 10:18:07 +08:00
</view>
<!-- 简化点击事件防止 template 编译错误 -->
<view class="buy-btn" @click.stop="handleAddToCart(item)">
<u-icon name="shopping-cart" color="#ffffff" size="32"></u-icon>
</view>
</view>
</view>
</view>
</view>
2025-12-31 10:18:07 +08:00
<!-- 6. 资质证明 -->
<view class="qualifications-section">
<view class="section-header" style="margin: 0 0 20rpx 0; padding: 0;">
<view class="section-title">店铺资质</view>
<view class="section-more" @click="goPlatformInfo">更多 <text class="iconfont icon-jiantou1" style="font-size: 20rpx;"></text></view>
</view>
2025-12-31 10:18:07 +08:00
<view class="qualifications-row">
<view class="qualification-card" v-for="(item, index) in qualifications" :key="index" @click="previewQualification(item)">
<image
:src="item.image || (index === 0 ? 'https://img.icons8.com/fluency/48/certificate.png' : 'https://img.icons8.com/fluency/48/contract.png')"
class="qual-icon"
mode="aspectFit">
</image>
<text class="qual-name">{{ item.name }}</text>
</view>
</view>
</view>
</view>
2025-12-31 10:18:07 +08:00
<!-- 全局组件 -->
<view class="bg-" v-if="bgShow" @click="bgShow=false">
2026-05-15 16:42:32 +08:00
<image src="https://xiaokang88.oss-cn-hangzhou.aliyuncs.com/xk-client-wx/static/home/bg.png" mode="widthFix"></image>
</view>
<u-toast ref="uToast" />
</view>
2024-09-19 12:51:35 +08:00
</template>
<script>
import {
doctorList,
getBanner,
getToken,
storeChange,
storeInfo,
2026-07-02 14:11:24 +08:00
storeList,
fetchUnpaidProductOrderListApi,
} from '../../request/api/api'
import { getPlatformQualificationsApi } from '../../request/api/platform'
2025-12-25 14:28:25 +08:00
import { getStoreDrugListBySalespersonApi, getHomeTopProductsApi, getHomeZonesApi, checkOnlineConsultationConfigApi } from "@/request/api/product";
2026-07-02 14:11:24 +08:00
import { getSpecialPrescriptionHomeApi } from '@/request/api/specialPrescription';
import { fetchUnpaidRegisterListApi } from '@/request/api/register';
2025-12-24 16:19:14 +08:00
import request from "@/request/api/request";
2026-01-07 14:21:29 +08:00
import MessageNotification from "@/components/MessageNotification/MessageNotification.vue";
2026-05-30 16:54:01 +08:00
import ImageCompressPopup from '@/components/image-compress-popup/image-compress-popup.vue';
import { registerImageCompressPopup } from '@/utils/image-compress-modal.js';
2026-01-12 12:36:50 +08:00
import { setGuestMode, isGuestMode, isLoggedIn } from '@/common/utils/auth.js';
2026-01-15 12:33:46 +08:00
import {silentLogin} from "@/utils/login";
export default {
2026-01-07 14:21:29 +08:00
components: {
2026-05-30 16:54:01 +08:00
MessageNotification,
ImageCompressPopup,
2026-01-07 14:21:29 +08:00
},
data() {
return {
storeId: 0,
storeType: 0,
storeinfo: [],
doctorList: [],
2025-12-31 10:18:07 +08:00
productList: [],
homeZones: [],
topProductsTitle: '热销商品',
2025-12-31 10:18:07 +08:00
topProductsList: [],
qualifications: [],
show: true,
showed: false,
shopList: {},
flag: false,
headerTitle: "",
infoList: "",
list: [],
info: [],
bgShow: false,
2025-12-24 16:19:14 +08:00
isShow_envVersion: true,
2025-12-31 10:18:07 +08:00
defaultDoctorId: '39',
statusBarHeight: 20,
isSticky: false,
// 控制金刚区布局模式: 'scroll' (滑动) 或 'wrap' (换行)
2026-07-02 14:11:24 +08:00
zoneLayoutMode: 'scroll',
unpaidRegisterCount: 0,
unpaidRegisterList: [],
unpaidProductOrderCount: 0,
unpaidProductOrderList: [],
// 特色药方API
specialPrescription: {
enabled: false,
doctor_id: 0,
title_image: '',
mascot_image: '',
subtitle: '',
items: [],
},
2025-12-31 10:18:07 +08:00
}
},
computed: {
// 解决 template 中复杂表达式导致的渲染错误
displayProductList() {
return this.topProductsList.length > 0 ? this.topProductsList : this.productList;
2026-01-12 12:36:50 +08:00
},
// 判断是否为guest模式用于模板
isGuestMode() {
return isGuestMode;
}
},
onLoad() {
2026-07-02 14:11:24 +08:00
this.isShow_envVersion = uni.getStorageSync('isShow_envVersion')
if (this.isShow_envVersion === false) {
this.getList();
}
2025-12-31 10:18:07 +08:00
try {
const systemInfo = uni.getSystemInfoSync();
this.statusBarHeight = systemInfo.statusBarHeight || 20;
} catch (e) {
console.error(e);
}
},
onReady() {
2026-05-30 16:54:01 +08:00
if (this.$refs.imageCompressPopup) {
registerImageCompressPopup(this.$refs.imageCompressPopup);
}
2026-01-15 12:33:46 +08:00
2026-05-15 16:28:11 +08:00
// console.log('调试静默登陆', isLoggedIn());
2026-01-15 12:33:46 +08:00
// 判断是否已登录
if (!isLoggedIn()) {
2026-05-15 16:28:11 +08:00
// console.log('调试静默登陆2', isLoggedIn());
2026-01-15 12:33:46 +08:00
// 未登录时设置guest模式标记和store_id
// setGuestMode();
// silentLogin().then((loginResult) => {
// if (loginResult.success) {
// } else {
// console.error('静默登录失败:', loginResult.message);
// }
// }).catch((error) => {
// console.error('静默登录异常:', error);
// });
}
2026-01-12 12:36:50 +08:00
// 未登录时也允许访问使用默认store_id=11001
if (!uni.getStorageSync('store_id')) {
2026-01-15 12:33:46 +08:00
// uni.setStorageSync('store_id', '11001');
2026-01-12 12:36:50 +08:00
}
if (uni.getStorageSync('store_id')) {
this.getStore();
} else {
this.goNewlist()
}
2025-12-31 10:18:07 +08:00
},
onPageScroll(e) {
if (e.scrollTop > 50) {
this.isSticky = true;
} else {
this.isSticky = false;
}
},
methods: {
2026-07-02 14:11:24 +08:00
async fetchUnpaidCounts() {
if (!isLoggedIn()) {
this.unpaidRegisterCount = 0;
this.unpaidRegisterList = [];
this.unpaidProductOrderCount = 0;
this.unpaidProductOrderList = [];
return;
}
try {
const [registerList, productList] = await Promise.all([
fetchUnpaidRegisterListApi(),
fetchUnpaidProductOrderListApi(),
]);
this.unpaidRegisterList = registerList;
this.unpaidRegisterCount = registerList.length;
this.unpaidProductOrderList = productList;
this.unpaidProductOrderCount = productList.length;
} catch (e) {
console.error('fetchUnpaidCounts', e);
this.unpaidRegisterCount = 0;
this.unpaidRegisterList = [];
this.unpaidProductOrderCount = 0;
this.unpaidProductOrderList = [];
}
},
onUnpaidRegisterBannerClick() {
if (this.unpaidRegisterCount === 1 && this.unpaidRegisterList[0]) {
const id = this.unpaidRegisterList[0].id;
uni.navigateTo({
url: `/subPackages/doctor/doctor-userinfo?step=2&register_id=${id}`,
});
return;
}
uni.navigateTo({
url: '/subPackages/my/myappiont',
});
},
onUnpaidProductOrderBannerClick() {
if (this.unpaidProductOrderCount === 1 && this.unpaidProductOrderList[0]) {
const id = this.unpaidProductOrderList[0].id;
uni.navigateTo({
url: `/subPackages/my/my-drug/drug-info?id=${id}`,
});
return;
}
uni.navigateTo({
url: '/subPackages/my/my-drug/drug-list?index=1',
});
},
2025-12-31 10:18:07 +08:00
// 处理购物车按钮点击
handleAddToCart(item) {
if(item && item.drug) {
this.goProductDetail(item);
}
},
2026-01-15 12:33:46 +08:00
async goYard(type) {
2026-02-02 16:10:46 +08:00
// 当 type === 2 (诊所在线问诊) 时,直接获取委托诊所和医生信息并跳转到挂号页面
if (type === 2) {
try {
const storeId = uni.getStorageSync('store_id') || '11001';
const { getClinicOnlineConsultationInfoApi } = await import('@/request/api/product');
const configRes = await getClinicOnlineConsultationInfoApi({ store_id: storeId });
2026-07-02 14:11:24 +08:00
2026-02-02 16:10:46 +08:00
if (configRes.data?.code === 0 || configRes.data?.code === '0') {
const result = configRes.data?.result;
2026-07-02 14:11:24 +08:00
2026-02-02 16:10:46 +08:00
if (result?.can_use && result?.delegate_doctor_id) {
// 直接跳转到就诊人选择页面传递医生ID和挂号类型
uni.navigateTo({
url: `/subPackages/doctor/doctor-userinfo?id=${result.delegate_doctor_id}&r_type=2&delegate_store_id=${result.delegate_store_id || storeId}`
});
return;
} else {
uni.showToast({
title: result?.message || '该门店暂不支持在线问诊功能',
icon: 'none',
duration: 2000
});
return;
}
} else {
uni.showToast({
title: configRes.data?.message || '获取在线问诊信息失败',
icon: 'none',
duration: 2000
});
return;
}
} catch (error) {
console.error('获取在线问诊信息失败:', error);
uni.showToast({
title: '获取在线问诊信息失败',
icon: 'none',
duration: 2000
});
return;
}
}
2026-07-02 14:11:24 +08:00
2026-01-15 12:33:46 +08:00
// 当 type === 3 (在线复诊) 时,需要先检查门店是否支持在线问诊功能
if (type === 3) {
try {
const storeId = uni.getStorageSync('store_id') || '11001';
2026-07-02 14:11:24 +08:00
const configRes = await checkOnlineConsultationConfigApi({
2026-01-15 12:33:46 +08:00
store_id: storeId,
guest: 1 // 使用 Guest 接口
});
2026-07-02 14:11:24 +08:00
2026-01-15 12:33:46 +08:00
// 直接使用新接口格式code + result
if (configRes.data?.code === 0 || configRes.data?.code === '0') {
// 获取结果数据,直接使用 result返回格式{ code: 0, result: { can_use: false, message: "..." } }
const result = configRes.data?.result;
2026-07-02 14:11:24 +08:00
2026-01-15 12:33:46 +08:00
// 检查是否可以使用在线问诊功能
if (!result?.can_use) {
// 显示后端返回的提示信息(使用 result 中的 message
uni.showToast({
title: result?.message || '该门店暂不支持在线问诊功能',
icon: 'none',
duration: 2000
});
return; // 阻止跳转
}
} else {
// API调用失败显示错误信息
uni.showToast({
title: configRes.data?.message || '检查在线问诊配置失败',
icon: 'none',
duration: 2000
});
return;
}
} catch (error) {
console.error('检查在线问诊配置失败:', error);
uni.showToast({
title: '检查在线问诊配置失败',
icon: 'none',
duration: 2000
});
return;
}
}
2026-07-02 14:11:24 +08:00
2026-01-15 12:33:46 +08:00
// 检查通过或非在线复诊类型,正常跳转
uni.navigateTo({
url: '/pages/Inquiries/Inquiries?type=' + type
})
},
2025-12-25 14:28:25 +08:00
async golist(type) {
if (type === 3) {
2026-01-07 14:21:29 +08:00
// 药店模式直接进入商品页,不检查配置
return uni.navigateTo({
url: '/subPackages/product/product?register_type=3'
});
2025-02-13 10:39:12 +08:00
}
uni.navigateTo({
url: '/pages/Inquiries/Inquiries?type=' + type
})
},
getH5() {
getToken({
method: "post",
data: {
user_id: uni.getStorageSync('user_id'),
avatarurl: uni.getStorageSync('userinfo')['avatarurl'],
mobile: uni.getStorageSync('userinfo')['mobile'],
nickname: uni.getStorageSync('userinfo')['nickname'],
openid: uni.getStorageSync('userinfo')['openid'],
session_key: uni.getStorageSync('userinfo')['session_key'],
store_id: uni.getStorageSync('store_id') || '11001',
},
}).then((res) => {
if (res.data.errcode == 0) {
uni.setStorageSync('token_platform_id', res.data.data.token)
} else {
2025-12-31 10:18:07 +08:00
this.$refs.uToast.show({ title: res.data.msg, type: 'default', icon: false })
}
})
},
tosearch() {
2025-12-31 10:18:07 +08:00
uni.navigateTo({ url: '/subPackages/shop/search-home' })
},
toStore() {
2025-12-31 10:18:07 +08:00
uni.navigateTo({ url: '/subPackages/my/mystore' })
},
goLookDoctor(id, sts_id) {
2025-12-31 10:18:07 +08:00
if (!sts_id) { let sts_id = uni.getStorageSync('store_id') }
setTimeout(() => {
uni.requestSubscribeMessage({
2025-12-31 10:18:07 +08:00
tmplIds: ['JdSs08cMSiL17xwwHZ8fZ5UBUqeY0eKAuvyW7n4Fl20', 'OERMugiahk-aKRVH9GHmdJCRBE3yldzEKTzbMCJhY6U', 'p-Ix0uIuwPKxm-_yKDlI8mkI-niUgPtaMUZyAaa5vvA'],
complete: (res) => {
2025-12-31 10:18:07 +08:00
uni.navigateTo({ url: '/subPackages/doctor/doctor-detail?store_id=' + sts_id + '&id=' + id })
}
})
}, 200)
},
getStore() {
if (uni.getStorageSync('store_id')) {
this.show = false
storeInfo({
method: "post",
2025-12-31 10:18:07 +08:00
data: { store_id: uni.getStorageSync('store_id') || '11001' }
}).then((res) => {
2026-01-12 12:36:50 +08:00
// 使用 guest_mode 判断 + code/errcode 双重保险
const isGuest = isGuestMode();
const isNewFormat = isGuest && (res.data.code === 0 || res.data.code === '0');
const isOldFormat = !isGuest && (res.data.errcode === 0 || res.data.errcode === '0');
2026-07-02 14:11:24 +08:00
2026-01-12 12:36:50 +08:00
if (isNewFormat || isOldFormat) {
// 新接口格式:从 result 取值
// 老接口格式:从 data 取值
const responseData = isGuest && res.data.result ? res.data.result : res.data.data;
2026-07-02 14:11:24 +08:00
2026-01-12 12:36:50 +08:00
if (responseData && responseData.store) {
this.storeType = responseData.store['type']
uni.setStorageSync('store_type', responseData.store['type']) // 存储门店类型
this.infoList = responseData
this.headerTitle = responseData.store['name']
2026-07-02 14:11:24 +08:00
this.getBannered();
2026-01-12 12:36:50 +08:00
}
}
})
} else {
this.goNewlist()
}
},
goNewlist() {
storeList({
method: "post",
2025-12-31 10:18:07 +08:00
data: { store_id: uni.getStorageSync('store_id') || '11001' }
}).then((res) => {
if (res.data.errcode == 0) {
this.show = res.data.data.open_issue
this.showed = this.show
if (this.isShow_envVersion) {
this.shopList = res.data.data.list
this.getBannered();
} else {
this.storeinfo = res.data.data.list.filter((item) => item.is_online == 1)
2026-01-15 12:33:46 +08:00
uni.setStorageSync('store_id', this.storeinfo[0].store.id)
this.headerTitle = this.storeinfo[0].store['name']
this.getBannered();
}
} else {
2026-01-15 12:33:46 +08:00
// 未登录时不跳转使用默认store_id=11001
uni.setStorageSync('store_id', '11001');
2026-01-12 12:36:50 +08:00
this.getBannered();
}
})
},
getList() {
this.doctorList = [];
doctorList({
method: "post",
2025-12-31 10:18:07 +08:00
data: { store_id: uni.getStorageSync('store_id') || '11001' }
}).then((res) => {
2026-01-12 12:36:50 +08:00
// 使用 guest_mode 判断 + code/errcode 双重保险
const isGuest = isGuestMode();
const isNewFormat = isGuest && (res.data.code === 0 || res.data.code === '0');
const isOldFormat = !isGuest && (res.data.errcode === 0 || res.data.errcode === '0');
2026-07-02 14:11:24 +08:00
2026-01-12 12:36:50 +08:00
if (isNewFormat || isOldFormat) {
// 新接口格式:从 result 取值
// 老接口格式:从 data 取值
const responseData = isGuest && res.data.result ? res.data.result : res.data.data;
this.doctorList = (responseData.list || []).slice(0, 5)
}
})
},
toChang(e) {
2025-12-31 10:18:07 +08:00
storeChange({ method: "post", data: { store_id: e } }).then((res) => {
if (res.data.errcode == 0) {
this.getStore()
this.getList();
}
})
},
getBannered() {
getBanner({
method: "post",
2025-12-31 10:18:07 +08:00
data: { store_id: uni.getStorageSync('store_id') || '11001' }
}).then((res) => {
2026-01-12 12:36:50 +08:00
// 使用 guest_mode 判断 + code/errcode 双重保险
const isGuest = isGuestMode();
const isNewFormat = isGuest && (res.data.code === 0 || res.data.code === '0');
const isOldFormat = !isGuest && (res.data.errcode === 0 || res.data.errcode === '0');
2026-07-02 14:11:24 +08:00
2026-01-12 12:36:50 +08:00
if (isNewFormat || isOldFormat) {
// 新接口格式:从 result 取值
// 老接口格式:从 data 取值
const responseData = isGuest && res.data.result ? res.data.result : res.data.data;
2026-07-02 14:11:24 +08:00
2026-01-12 12:36:50 +08:00
if (responseData) {
this.info = responseData
this.urlInfo = responseData.nav || []
this.storeType = responseData.type
this.list = (responseData.nav || []).map((item) => { return item.pic })
}
}
})
},
toBanner(e) {
if (!this.urlInfo[e].external_link) return
if (this.urlInfo[e].link_type == 1 && this.isShow_envVersion == false) {
2025-12-31 10:18:07 +08:00
uni.navigateTo({ url: this.urlInfo[e].external_link })
} else {
2025-12-31 10:18:07 +08:00
uni.navigateTo({ url: '/pages/home/home-banner?id=' + this.urlInfo[e].external_link })
}
},
getProductList() {
getStoreDrugListBySalespersonApi({
store_id: uni.getStorageSync('store_id') || '11001',
page: 1,
2025-12-31 10:18:07 +08:00
limit: 3
}).then((res) => {
if (res.data.code == 0) {
this.productList = res.data.result.records;
}
})
},
getHomeTopProducts() {
getHomeTopProductsApi({
store_id: uni.getStorageSync('store_id') || '11001',
}).then((res) => {
if (res.data.code == 0 && res.data.result) {
const result = res.data.result;
this.topProductsTitle = result.title || '热销商品';
this.topProductsList = result.list || [];
}
})
},
getHomeZones() {
getHomeZonesApi({
store_id: uni.getStorageSync('store_id') || '11001',
}).then((res) => {
if (res.data.code == 0) {
this.homeZones = res.data.result || res.data.data || [];
}
2025-12-31 10:18:07 +08:00
}).catch(() => { this.homeZones = []; })
},
getPlatformQualifications() {
getPlatformQualificationsApi({
store_id: uni.getStorageSync('store_id') || '11001',
}).then((res) => {
if (res.data.code == 0 || res.data.errcode == 0) {
2025-12-31 10:58:22 +08:00
const result = res.data.data || res.data.result || {};
// 适配新的返回格式(包含 store_name 和 list
if (result.store_name !== undefined) {
this.qualifications = result.list || [];
} else {
// 兼容旧格式(直接返回数组)
this.qualifications = Array.isArray(result) ? result : [];
}
}
})
},
previewQualification(item) {
2025-12-31 10:58:22 +08:00
// 获取所有有图片的资质,支持滑动预览
const allImages = this.qualifications
2026-07-02 14:11:24 +08:00
.filter(q => q.image)
.map(q => q.image);
2025-12-31 10:58:22 +08:00
if (allImages.length > 0 && item.image) {
uni.previewImage({
2025-12-31 10:58:22 +08:00
urls: allImages,
current: item.image
});
}
},
2025-12-31 10:18:07 +08:00
goProductDetail(item) {
if(!item || !item.drug) return;
uni.navigateTo({
2025-12-31 10:18:07 +08:00
url: `/subPackages/product/symptoms?id=${item.drug.id}&drug_name=${item.drug.drug_name}&is_otc=${item.drug.is_otc}&image=${item.drug.image}&price=${item.price}`
});
2025-12-24 16:19:14 +08:00
},
2025-12-31 10:18:07 +08:00
goZoneList(zone) {
if (!zone || !zone.type) return;
uni.navigateTo({ url: `/subPackages/product/product?zone_type=${zone.type}` });
},
goPlatformInfo() {
uni.navigateTo({ url: '/pages/index/platform-info' });
},
2026-07-02 14:11:24 +08:00
// 跳转到全部药方 / 养生茶饮列表
goTeaList() {
uni.navigateTo({
url: '/subPackages/special-prescription/list',
});
},
goTeaDetail(tea) {
const id = Number(tea?.id);
if (!id) return;
uni.navigateTo({
url: `/subPackages/special-prescription/detail?id=${id}`,
});
},
detailUrl(tea) {
const id = Number(tea?.id);
if (!id) return '';
return `/subPackages/special-prescription/detail?id=${id}`;
},
fetchSpecialPrescriptionHome() {
getSpecialPrescriptionHomeApi({
store_id: uni.getStorageSync('store_id') || '11001',
}).then((res) => {
if (res.data?.code === 0 || res.data?.code === '0') {
const result = res.data.result || {};
this.specialPrescription = {
enabled: !!result.enabled,
doctor_id: result.doctor_id || 0,
title_image: result.title_image || '',
mascot_image: result.mascot_image || '',
subtitle: result.subtitle || '',
items: result.items || [],
};
}
}).catch(() => {
this.specialPrescription.enabled = false;
});
},
2025-12-24 16:19:14 +08:00
async getDefaultDoctorId() {
try {
2025-12-25 11:19:38 +08:00
const storeId = uni.getStorageSync('store_id');
2025-12-31 10:18:07 +08:00
if (!storeId) return;
2025-12-24 16:19:14 +08:00
const res = await request('/xkApi/online-consultation/get-default-doctor-id', {
2025-12-25 11:19:38 +08:00
method: 'GET',
data: { store_id: storeId }
2025-12-24 16:19:14 +08:00
}, 0);
if (res.data && res.data.result && res.data.result.doctor_id) {
this.defaultDoctorId = res.data.result.doctor_id;
}
} catch (error) {
console.error('获取默认医生ID失败:', error);
}
}
},
onShow() {
this.storeId = uni.getStorageSync('store_id');
2026-05-15 16:28:11 +08:00
this.toChang(this.storeId)
this.getStore();
this.getList();
2025-12-31 10:18:07 +08:00
this.getProductList();
this.getHomeTopProducts();
this.getHomeZones();
this.getPlatformQualifications(); // 已补回
this.getDefaultDoctorId();
2026-07-02 14:11:24 +08:00
this.fetchUnpaidCounts();
this.fetchSpecialPrescriptionHome();
},
}
2024-09-19 12:51:35 +08:00
</script>
<style lang="scss" scoped>
2025-12-31 10:18:07 +08:00
$primary-color: #4175EE;
$secondary-color: #00B578;
$text-main: #222222;
$text-sub: #999999;
$bg-body: #F5F7FA;
$card-radius: 24rpx;
$card-shadow: 0 8rpx 20rpx rgba(0, 0, 0, 0.04);
.content {
2025-12-31 10:18:07 +08:00
background-color: #e0e5ec;
min-height: 100vh;
2025-12-31 10:18:07 +08:00
width: 750rpx;
background-color: $bg-body;
padding-bottom: 30rpx;
/* --- 1. 自定义吸顶导航栏 --- */
.custom-nav {
position: fixed;
top: 0; left: 0; width: 100%; z-index: 999;
padding-left: 32rpx; padding-right: 200rpx;
box-sizing: border-box;
background: transparent;
transition: all 0.4s ease;
&.nav-sticky {
box-shadow: 0 4rpx 16rpx rgba(0,0,0,0.1);
&.header-clinic { background: linear-gradient(160deg, #298DFF 0%, #6BAFFF 100%); }
&.header-pharmacy { background: linear-gradient(160deg, #00B578 0%, #8BE3C3 100%); }
}
2025-12-31 10:18:07 +08:00
.nav-content {
display: flex; align-items: center; height: 100%;
.store-info {
display: flex; align-items: center;
.store-name { font-size: 36rpx; font-weight: 800; color: #fff; margin-right: 20rpx; text-shadow: 0 2rpx 4rpx rgba(0,0,0,0.1); max-width: 400rpx; }
.switch-badge { font-size: 20rpx; background: rgba(255,255,255,0.9); color: $primary-color; padding: 6rpx 16rpx; border-radius: 24rpx; font-weight: bold; display: flex; align-items: center; .iconfont { font-size: 20rpx; margin-right: 4rpx; } }
}
}
}
2025-12-31 10:18:07 +08:00
/* --- 2. 头部区域 --- */
.header {
position: relative;
2025-12-31 10:18:07 +08:00
padding-left: 32rpx; padding-right: 32rpx; padding-bottom: 160rpx;
border-radius: 0 0 60rpx 60rpx; overflow: hidden; transition: all 0.5s ease;
&.header-clinic { background: linear-gradient(180deg, #298DFF 0%, #6BAFFF 80%, #F5F7FA 100%); }
&.header-pharmacy { background: linear-gradient(180deg, #00B578 0%, #8BE3C3 80%, #F5F7FA 100%); }
.bg-circle { position: absolute; top: -100rpx; right: -100rpx; width: 400rpx; height: 400rpx; background: rgba(255,255,255,0.15); border-radius: 50%; filter: blur(80rpx); }
.location-bar { display: inline-flex; align-items: center; background: rgba(255,255,255,0.3); backdrop-filter: blur(16rpx); padding: 10rpx 24rpx; border-radius: 40rpx; border: 2rpx solid rgba(255,255,255,0.4); color: #fff; font-size: 26rpx; max-width: 600rpx; margin-top: 20rpx; .iconfont { font-size: 26rpx; margin-right: 12rpx; } }
}
2025-12-31 10:18:07 +08:00
/* --- 3. 轮播图 --- */
.banner-section {
margin-top: -120rpx; padding: 0 32rpx; position: relative; z-index: 10; margin-bottom: 40rpx;
.banner-card { width: 100%; height: 300rpx; border-radius: 32rpx; box-shadow: 0 30rpx 70rpx rgba(41, 141, 255, 0.25); overflow: hidden; }
}
2025-12-31 10:18:07 +08:00
/* --- 2.5 金刚区 (Zone) --- */
.zone-wrapper {
padding: 0 32rpx 20rpx;
display: flex;
2025-12-31 10:18:07 +08:00
/* 默认样式,会被下方 modifier 覆盖 */
2025-12-31 10:18:07 +08:00
/* 模式1: 滑动 */
&.zone-scroll-mode {
flex-wrap: nowrap;
overflow-x: auto;
.zone-item { width: 140rpx; margin-right: 10rpx; }
}
2025-12-31 10:18:07 +08:00
/* 模式2: 换行 */
&.zone-wrap-mode {
flex-wrap: wrap;
justify-content: flex-start;
.zone-item { width: 20%; margin-bottom: 24rpx; }
}
2025-12-31 10:18:07 +08:00
.zone-item {
flex-shrink: 0; text-align: center; display: flex; flex-direction: column; align-items: center;
&:active { transform: scale(0.95); }
.zone-icon-box {
width: 100rpx; height: 100rpx;
background: linear-gradient(180deg, #FFFFFF 0%, #F5F9FF 100%);
border-radius: 36rpx;
display: flex; align-items: center; justify-content: center;
box-shadow: 0 8rpx 24rpx rgba(65, 117, 238, 0.08);
margin-bottom: 12rpx;
.zone-img { width: 56rpx; height: 56rpx; }
}
.zone-text { font-size: 24rpx; color: #555; font-weight: 500; }
}
}
2025-12-31 10:18:07 +08:00
.nav-grid {
padding: 32rpx;
.nav-clinic-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 24rpx; }
.nav-pharmacy-grid { display: block; .nav-card { width: 100%; height: 200rpx; } }
.nav-card {
height: 180rpx; border-radius: 32rpx; background-color: #fff; position: relative; overflow: hidden;
box-shadow: 0 8rpx 30rpx rgba(0,0,0,0.03); display: flex; flex-direction: column; justify-content: center; padding-left: 32rpx;
&:active { transform: scale(0.98); }
&::before { content: ''; position: absolute; top: 0; bottom: 0; left: 0; right: 0; background: linear-gradient(90deg, #FDFEFF 0%, rgba(255,255,255,0) 100%); z-index: 1; }
.nav-content { position: relative; z-index: 2; .nav-title { font-size: 36rpx; font-weight: 800; margin-bottom: 8rpx; } .nav-desc { font-size: 22rpx; color: #888; } }
.nav-icon-img { position: absolute; right: 0; bottom: 0; width: 128rpx; height: 128rpx; z-index: 1; }
2025-12-31 10:58:22 +08:00
.nav-icon-img-64 { position: absolute; right: 30rpx; top: 30rpx; width: 84rpx; height: 84rpx; z-index: 1; }
}
}
2026-07-02 14:11:24 +08:00
.unpaid-banner {
display: flex;
align-items: center;
justify-content: space-between;
margin: 16rpx 32rpx 0;
padding: 24rpx 28rpx;
border-radius: 16rpx;
&--register {
background: linear-gradient(90deg, rgba(65, 117, 238, 0.08) 0%, rgba(65, 117, 238, 0.04) 100%);
border: 1rpx solid rgba(65, 117, 238, 0.2);
.unpaid-banner-text,
.unpaid-banner-arrow {
color: #4175EE;
}
}
&--product {
background: linear-gradient(90deg, rgba(0, 181, 120, 0.08) 0%, rgba(0, 181, 120, 0.04) 100%);
border: 1rpx solid rgba(0, 181, 120, 0.25);
.unpaid-banner-text,
.unpaid-banner-arrow {
color: #00B578;
}
}
.unpaid-banner-text {
flex: 1;
font-size: 26rpx;
line-height: 1.5;
}
.unpaid-banner-arrow {
font-size: 24rpx;
margin-left: 12rpx;
}
}
2025-12-31 10:18:07 +08:00
.section-header {
padding: 0 32rpx; margin: 20rpx 0 32rpx; display: flex; justify-content: space-between; align-items: center;
.section-title { font-size: 36rpx; font-weight: 800; color: #333; position: relative; padding-left: 24rpx; &::before { content: ''; position: absolute; left: 0; top: 8rpx; bottom: 8rpx; width: 8rpx; background: $primary-color; border-radius: 4rpx; } }
.section-more { font-size: 26rpx; color: #999; display: flex; align-items: center; }
}
2024-09-19 12:51:35 +08:00
2026-07-02 14:11:24 +08:00
/* --- 特色药方 / 养生茶饮异形卡片 --- */
.tea-section {
padding: 57rpx 32rpx 12rpx;
.irregular-card {
position: relative;
display: flex;
flex-direction: column;
align-items: flex-start;
}
/* 左侧凸起 Tab */
.card-tab {
width: 220rpx;
height: 40rpx;
background: #FFFFFF;
border-radius: 24rpx 24rpx 0 0;
position: relative;
z-index: 2;
margin-bottom: -1rpx;
}
/* 凸起右侧的下坡过渡(凹角) */
.card-tab-slope {
position: absolute;
right: -40rpx;
bottom: 0;
width: 40rpx;
height: 40rpx;
/* 使用径向渐变模拟内凹的下坡曲线 */
background-image: radial-gradient(circle at 100% 0%, transparent 40rpx, #FFFFFF 40rpx);
}
/* 悬浮艺术字标题:坐落在凸起与卡片衔接处 */
.main-title {
position: absolute;
left: 8rpx;
top: -120rpx;
width: 210rpx;
height: 128rpx;
z-index: 6;
pointer-events: none;
}
/* 主体区域 */
.card-body {
background: #FFFFFF;
width: 100%;
padding: 24rpx 24rpx 24rpx;
border-radius: 0 24rpx 24rpx 24rpx;
position: relative;
z-index: 1;
box-sizing: border-box;
box-shadow: 0 12rpx 32rpx rgba(65, 117, 238, 0.16);
}
/* 悬浮 IP 小熊 */
.main-mascot {
position: absolute;
right: 12rpx;
top: -140rpx;
width: 217rpx;
height: 168rpx;
z-index: 10;
pointer-events: none;
}
.tea-subtitle {
font-size: 28rpx;
color: #333;
font-weight: bold;
margin-bottom: 20rpx;
padding-right: 150rpx;
display: flex;
align-items: center;
.subtitle-icon {
width: 6rpx;
height: 26rpx;
background: #4175EE;
border-radius: 3rpx;
margin-right: 12rpx;
}
}
/* 横向滑动列表 */
.tea-scroll {
width: 100%;
white-space: nowrap;
margin: 0 -24rpx;
box-sizing: border-box;
position: relative;
z-index: 5;
}
.tea-list {
display: inline-flex;
padding: 4rpx 24rpx 12rpx;
position: relative;
z-index: 5;
}
.tea-item {
display: inline-flex;
flex-direction: column;
width: 176rpx;
margin-right: 16rpx;
background: #FFFFFF;
border-radius: 16rpx;
overflow: hidden;
border: 1rpx solid #F0F0F0;
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.05);
position: relative;
z-index: 5;
&:last-child { margin-right: 0; }
&:active,
&.tea-item--active { transform: scale(0.97); }
.tea-image-wrap {
width: 100%;
height: 132rpx;
background: linear-gradient(135deg, #F5F7FA 0%, rgba(65, 117, 238, 0.08) 100%);
display: flex;
align-items: center;
justify-content: center;
.tea-image { width: 100%; height: 100%; }
.tea-image-placeholder { font-size: 22rpx; color: #4175EE; }
}
.tea-info-wrap {
padding: 12rpx;
display: flex;
flex-direction: column;
}
.tea-name {
font-size: 24rpx;
color: #333;
font-weight: 600;
margin-bottom: 8rpx;
}
.tea-tags {
display: flex;
margin-bottom: 8rpx;
.tea-tag {
font-size: 18rpx;
color: #4175EE;
background: rgba(65, 117, 238, 0.1);
padding: 1rpx 8rpx;
border-radius: 4rpx;
margin-right: 6rpx;
}
}
.tea-price {
color: #FF5722;
font-size: 28rpx;
font-weight: 800;
.tea-price-symbol { font-size: 20rpx; margin-right: 2rpx; }
&--unavailable {
color: #999;
font-size: 22rpx;
font-weight: 500;
}
}
}
/* 底部操作区 */
.tea-bottom-area {
position: relative;
margin-top: 16rpx;
.days-left-tag {
position: absolute;
top: -20rpx;
right: 20rpx;
background: #FFC107;
color: #8C6A00;
font-size: 20rpx;
font-weight: bold;
padding: 6rpx 18rpx;
border-radius: 16rpx 16rpx 16rpx 0;
z-index: 2;
border: 2rpx solid #fff;
box-shadow: 0 4rpx 12rpx rgba(255, 193, 7, 0.3);
}
.tea-action-button {
width: 100%;
text-align: center;
padding: 20rpx 0;
border-radius: 40rpx;
background: linear-gradient(90deg, #4175EE 0%, #298DFF 100%);
color: #fff;
font-size: 28rpx;
font-weight: bold;
box-sizing: border-box;
box-shadow: 0 8rpx 24rpx rgba(65, 117, 238, 0.3);
&:active { transform: scale(0.98); }
}
}
}
2025-12-31 10:18:07 +08:00
.doctor-card {
background: #fff; margin: 0 32rpx 32rpx; border-radius: $card-radius; box-shadow: $card-shadow; overflow: hidden;
&:active { transform: scale(0.99); }
.doc-main {
padding: 32rpx; display: flex; position: relative;
.doc-avatar-box { position: relative; margin-right: 24rpx; .doc-avatar { width: 112rpx; height: 112rpx; border-radius: 50%; background: #eee; border: 4rpx solid #fff; box-shadow: 0 4rpx 16rpx rgba(0,0,0,0.1); } .status-dot { position: absolute; bottom: 4rpx; right: 4rpx; width: 24rpx; height: 24rpx; background: $secondary-color; border: 4rpx solid #fff; border-radius: 50%; } }
.doc-info { flex: 1; .doc-name-row { display: flex; align-items: baseline; margin-bottom: 8rpx; .doc-name { font-size: 34rpx; font-weight: 700; color: #333; margin-right: 16rpx; } .doc-title { font-size: 22rpx; color: #666; background: #F0F2F5; padding: 4rpx 12rpx; border-radius: 8rpx; } } .doc-dept { font-size: 24rpx; color: #888; margin-bottom: 16rpx; } .doc-skill { font-size: 24rpx; color: #666; line-height: 1.4; display: -webkit-box; -webkit-line-clamp: 1; -webkit-box-orient: vertical; overflow: hidden; .skill-tag { color: $primary-color; background: rgba(65, 117, 238, 0.1); padding: 0 8rpx; border-radius: 4rpx; margin-right: 8rpx; } } }
.consult-btn { position: absolute; top: 32rpx; right: 32rpx; background: $primary-color; color: #fff; font-size: 24rpx; padding: 12rpx 28rpx; border-radius: 40rpx; box-shadow: 0 8rpx 20rpx rgba(65, 117, 238, 0.3); }
}
.doc-stats-bar {
background: #F8FBFF; padding: 20rpx 0; display: flex; border-top: 2rpx solid #f0f0f0;
.stat-item { flex: 1; text-align: center; border-right: 2rpx solid #eee; &:last-child { border: none; } .stat-num { font-size: 32rpx; font-weight: 700; color: #333; display: block; } .stat-label { font-size: 20rpx; color: #999; margin-top: 4rpx; } }
}
}
2025-12-31 10:18:07 +08:00
/* --- 5. 药品卡片 (双列瀑布流) --- */
.product-list-container {
2026-01-07 14:21:29 +08:00
padding: 0 24rpx; /* 左右边距 */
2025-12-31 10:18:07 +08:00
display: flex;
flex-wrap: wrap;
2026-01-07 14:21:29 +08:00
gap: 16rpx; /* 卡片间隙 */
}
2025-12-31 10:18:07 +08:00
.product-card {
background: #fff;
2026-01-07 14:21:29 +08:00
/* 动态计算宽度保留中间16rpx间隙 */
width: calc((100% - 16rpx) / 2);
2025-12-31 10:18:07 +08:00
padding: 0;
2026-01-07 14:21:29 +08:00
border-radius: 16rpx;
display: flex;
2025-12-31 10:18:07 +08:00
flex-direction: column;
box-shadow: $card-shadow;
border: 1rpx solid #f8f8f8;
overflow: hidden;
2025-12-31 10:18:07 +08:00
.prod-img-box {
width: 100%;
2026-01-07 14:21:29 +08:00
height: 280rpx; /* 缩小图片高度原345rpx减小约19% */
background: #f8f8f8;
2025-12-31 10:18:07 +08:00
border-radius: 0;
margin: 0;
display: flex;
2025-12-31 10:18:07 +08:00
align-items: center;
justify-content: center;
2026-01-07 14:21:29 +08:00
.prod-img { width: 100%; height: 100%; border-radius: 0; /* &.prescription-blur { filter: blur(4px); } 暂时禁用模糊 */ }
2025-12-31 10:18:07 +08:00
}
2025-12-31 10:18:07 +08:00
.prod-info {
flex: 1;
display: flex; flex-direction: column; justify-content: space-between;
2026-01-07 14:21:29 +08:00
padding: 12rpx; /* 减小内边距原16rpx */
2025-12-31 10:18:07 +08:00
.prod-title {
2026-01-07 14:21:29 +08:00
font-size: 26rpx; /* 减小字号原28rpx */
2025-12-31 10:18:07 +08:00
font-weight: 600;
color: #333;
line-height: 1.4;
2026-01-07 14:21:29 +08:00
margin-bottom: 8rpx;
height: 72rpx; /* 减小高度原80rpx */
2025-12-31 10:18:07 +08:00
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
2026-01-07 14:21:29 +08:00
.tag-row { display: flex; margin-bottom: 8rpx; .otc-tag { font-size: 18rpx; padding: 0rpx 6rpx; border-radius: 4rpx; font-weight: 700; border: 1rpx solid transparent; &.otc-green { color: $secondary-color; background: #E6F7F0; border-color: #A3E6CD; } &.otc-red { color: #FF4D4F; background: #FFF0F0; border-color: #FFCDCD; } } }
.prod-spec { font-size: 18rpx; color: #999; margin-bottom: 12rpx;} /* 减小字号原20rpx */
2025-12-31 10:18:07 +08:00
.prod-bottom {
display: flex; justify-content: space-between; align-items: flex-end;
2026-01-07 14:21:29 +08:00
.price-box { color: #FF4D4F; font-weight: 800; font-size: 30rpx; .price-symbol { font-size: 20rpx; margin-right: 2rpx; } } /* 减小字号原34rpx/22rpx */
.buy-btn { background: linear-gradient(135deg, #4175EE 0%, #298DFF 100%); color: #fff; width: 52rpx; height: 52rpx; border-radius: 50%; display: flex; align-items: center; justify-content: center; box-shadow: 0 4rpx 12rpx rgba(65, 117, 238, 0.3); } /* 减小尺寸原56rpx */
}
}
}
.qualifications-section {
2026-01-07 14:21:29 +08:00
padding: 40rpx 32rpx 40rpx;
2025-12-31 10:18:07 +08:00
.qualifications-row {
2026-07-02 14:11:24 +08:00
display: flex;
2025-12-31 10:58:22 +08:00
flex-wrap: wrap;
gap: 20rpx;
2025-12-31 10:18:07 +08:00
.qualification-card {
2026-07-02 14:11:24 +08:00
background: #fff;
padding: 24rpx;
border-radius: 16rpx;
2025-12-31 10:58:22 +08:00
width: calc((100% - 20rpx) / 2); /* 一行两个 */
2026-07-02 14:11:24 +08:00
text-align: center;
box-shadow: 0 4rpx 12rpx rgba(0,0,0,0.03);
display: flex;
flex-direction: column;
2025-12-31 10:58:22 +08:00
align-items: center;
2026-07-02 14:11:24 +08:00
.qual-icon {
width: 200rpx;
height: 140rpx;
margin-bottom: 16rpx;
2025-12-31 10:58:22 +08:00
border-radius: 8rpx;
background: #f8f8f8;
}
.qual-name { font-size: 24rpx; color: #333; line-height: 1.4; font-weight: 500; }
}
}
}
2025-12-31 10:18:07 +08:00
.u-line-1 { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.bg- { position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; background: rgba(0,0,0,0.5); z-index: 999; display: flex; align-items: center; justify-content: center; }
}
2026-07-02 14:11:24 +08:00
</style>