907 lines
36 KiB
Vue
907 lines
36 KiB
Vue
<template>
|
||
<view class="content safe-area-inset-bottom">
|
||
<!-- 全局消息通知组件 -->
|
||
<MessageNotification />
|
||
<image-compress-popup ref="imageCompressPopup" />
|
||
|
||
<!-- 1. 自定义吸顶导航栏 -->
|
||
<view class="custom-nav"
|
||
:class="[
|
||
(storeType === '1' || storeType === 1) ? 'header-pharmacy' : 'header-clinic',
|
||
{ '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>
|
||
<view v-if="!isGuestMode()" class="switch-badge">
|
||
<text class="iconfont icon-qiehuan"></text> 切换
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 2. 头部背景与定位区域 -->
|
||
<view class="header" :class="(storeType === '1' || storeType === 1) ? 'header-pharmacy' : 'header-clinic'"
|
||
: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>
|
||
|
||
<!-- 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>
|
||
|
||
<!-- 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
|
||
:src="item.icon || ((storeType === '1' || storeType === 1) ? 'https://img.icons8.com/fluency/48/pill.png' : 'https://img.icons8.com/fluency/48/doctor-male.png')"
|
||
class="zone-img"
|
||
mode="aspectFit"
|
||
></image>
|
||
</view>
|
||
<text class="zone-text">{{ item.title }}</text>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 3. 核心功能导航 (Nav) -->
|
||
<view class="nav-grid">
|
||
<!-- 诊所模式:2列布局 -->
|
||
<view v-if="storeType === '0' || storeType === 0" class="nav-clinic-grid">
|
||
<view class="nav-card" @click="goYard(1)">
|
||
<view class="nav-content">
|
||
<view class="nav-title" style="color:#4175EE">到店挂号</view>
|
||
<view class="nav-desc">预约专家 不排队</view>
|
||
</view>
|
||
<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>
|
||
<view class="nav-card" @click="goYard(2)">
|
||
<view class="nav-content">
|
||
<view class="nav-title" style="color:#00B578">在线复诊</view>
|
||
<view class="nav-desc">在线选药 极速达</view>
|
||
</view>
|
||
<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>
|
||
|
||
<!-- 药店模式:单列铺满 -->
|
||
<view v-if="storeType === '1' || storeType === 1" class="nav-pharmacy-grid">
|
||
<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>
|
||
|
||
<!-- 4. 诊所模式内容:医生列表 -->
|
||
<view v-if="storeType === '0' || storeType === 0">
|
||
<view class="section-header">
|
||
<view class="section-title">医生推荐</view>
|
||
<view class="section-more" @click="goYard(1)">更多 <text class="iconfont icon-jiantou1" style="font-size: 20rpx;"></text></view>
|
||
</view>
|
||
|
||
<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">
|
||
<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>
|
||
<view class="status-dot"></view>
|
||
</view>
|
||
<view class="doc-info">
|
||
<view class="doc-name-row">
|
||
<text class="doc-name">{{item.name}}</text>
|
||
<text class="doc-title">{{item.title}}</text>
|
||
</view>
|
||
<view class="doc-dept">{{item.depart}} | {{item.store}}</view>
|
||
<view class="doc-skill">
|
||
<text class="skill-tag">擅长</text>
|
||
{{item.good_at}}
|
||
</view>
|
||
</view>
|
||
<!-- <view class="consult-btn">咨询</view>-->
|
||
<!-- <view class="consult-btn">查看</view>-->
|
||
</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">
|
||
<text class="stat-num">{{item.average_response_time || 5}}分钟</text>
|
||
<view class="stat-label">平均响应</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 5. 药店模式内容:热销好药 -->
|
||
<view v-if="storeType === '1' || storeType === 1">
|
||
<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>
|
||
|
||
<!-- 优化后的药品列表:使用计算属性 displayProductList 解决循环报错 -->
|
||
<view class="product-list-container">
|
||
<view class="product-card" @click="goProductDetail(item)" v-for="(item, index) in displayProductList" :key="index">
|
||
<view class="prod-img-box">
|
||
<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>
|
||
</view>
|
||
|
||
<view class="prod-info">
|
||
<view>
|
||
<view class="prod-title">{{ item.drug ? item.drug.drug_name : '' }}</view>
|
||
<view class="tag-row">
|
||
<!-- 只有西药(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>
|
||
<view class="prod-spec">{{ item.drug ? item.drug.specification : '' }}</view>
|
||
</view>
|
||
<view class="prod-bottom">
|
||
<view class="price-box">
|
||
<text class="price-symbol">¥</text>
|
||
<text>{{ item.price || (item.drug && item.drug.drugStoreDrug ? item.drug.drugStoreDrug.price : '0.00') }}</text>
|
||
</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>
|
||
|
||
<!-- 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>
|
||
<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>
|
||
|
||
<!-- 全局组件 -->
|
||
<view class="bg-" v-if="bgShow" @click="bgShow=false">
|
||
<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>
|
||
</template>
|
||
|
||
<script>
|
||
import {
|
||
doctorList,
|
||
getBanner,
|
||
getToken,
|
||
storeChange,
|
||
storeInfo,
|
||
storeList
|
||
} from '../../request/api/api'
|
||
import { getPlatformQualificationsApi } from '../../request/api/platform'
|
||
import { getStoreDrugListBySalespersonApi, getHomeTopProductsApi, getHomeZonesApi, checkOnlineConsultationConfigApi } from "@/request/api/product";
|
||
import request from "@/request/api/request";
|
||
import MessageNotification from "@/components/MessageNotification/MessageNotification.vue";
|
||
import ImageCompressPopup from '@/components/image-compress-popup/image-compress-popup.vue';
|
||
import { registerImageCompressPopup } from '@/utils/image-compress-modal.js';
|
||
import { setGuestMode, isGuestMode, isLoggedIn } from '@/common/utils/auth.js';
|
||
import {silentLogin} from "@/utils/login";
|
||
|
||
export default {
|
||
components: {
|
||
MessageNotification,
|
||
ImageCompressPopup,
|
||
},
|
||
data() {
|
||
return {
|
||
storeId: 0,
|
||
storeType: 0,
|
||
storeinfo: [],
|
||
doctorList: [],
|
||
productList: [],
|
||
homeZones: [],
|
||
topProductsTitle: '热销商品',
|
||
topProductsList: [],
|
||
qualifications: [],
|
||
show: true,
|
||
showed: false,
|
||
shopList: {},
|
||
flag: false,
|
||
headerTitle: "",
|
||
infoList: "",
|
||
list: [],
|
||
info: [],
|
||
bgShow: false,
|
||
isShow_envVersion: true,
|
||
defaultDoctorId: '39',
|
||
statusBarHeight: 20,
|
||
isSticky: false,
|
||
|
||
// 控制金刚区布局模式: 'scroll' (滑动) 或 'wrap' (换行)
|
||
zoneLayoutMode: 'scroll'
|
||
}
|
||
},
|
||
computed: {
|
||
// 解决 template 中复杂表达式导致的渲染错误
|
||
displayProductList() {
|
||
return this.topProductsList.length > 0 ? this.topProductsList : this.productList;
|
||
},
|
||
// 判断是否为guest模式(用于模板)
|
||
isGuestMode() {
|
||
return isGuestMode;
|
||
}
|
||
},
|
||
onLoad() {
|
||
|
||
this.isShow_envVersion = uni.getStorageSync('isShow_envVersion')
|
||
if (this.isShow_envVersion === false) {
|
||
this.getList();
|
||
}
|
||
|
||
try {
|
||
const systemInfo = uni.getSystemInfoSync();
|
||
this.statusBarHeight = systemInfo.statusBarHeight || 20;
|
||
} catch (e) {
|
||
console.error(e);
|
||
}
|
||
},
|
||
onReady() {
|
||
if (this.$refs.imageCompressPopup) {
|
||
registerImageCompressPopup(this.$refs.imageCompressPopup);
|
||
}
|
||
|
||
// console.log('调试静默登陆', isLoggedIn());
|
||
// 判断是否已登录
|
||
if (!isLoggedIn()) {
|
||
// console.log('调试静默登陆2', isLoggedIn());
|
||
// 未登录时设置guest模式标记和store_id
|
||
// setGuestMode();
|
||
|
||
// silentLogin().then((loginResult) => {
|
||
// if (loginResult.success) {
|
||
// } else {
|
||
// console.error('静默登录失败:', loginResult.message);
|
||
// }
|
||
// }).catch((error) => {
|
||
// console.error('静默登录异常:', error);
|
||
// });
|
||
}
|
||
// 未登录时也允许访问,使用默认store_id=11001
|
||
if (!uni.getStorageSync('store_id')) {
|
||
// uni.setStorageSync('store_id', '11001');
|
||
|
||
}
|
||
if (uni.getStorageSync('store_id')) {
|
||
this.getStore();
|
||
} else {
|
||
this.goNewlist()
|
||
}
|
||
},
|
||
onPageScroll(e) {
|
||
if (e.scrollTop > 50) {
|
||
this.isSticky = true;
|
||
} else {
|
||
this.isSticky = false;
|
||
}
|
||
},
|
||
methods: {
|
||
// 处理购物车按钮点击
|
||
handleAddToCart(item) {
|
||
if(item && item.drug) {
|
||
this.goProductDetail(item);
|
||
}
|
||
},
|
||
async goYard(type) {
|
||
// 当 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 });
|
||
|
||
if (configRes.data?.code === 0 || configRes.data?.code === '0') {
|
||
const result = configRes.data?.result;
|
||
|
||
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;
|
||
}
|
||
}
|
||
|
||
// 当 type === 3 (在线复诊) 时,需要先检查门店是否支持在线问诊功能
|
||
if (type === 3) {
|
||
try {
|
||
const storeId = uni.getStorageSync('store_id') || '11001';
|
||
const configRes = await checkOnlineConsultationConfigApi({
|
||
store_id: storeId,
|
||
guest: 1 // 使用 Guest 接口
|
||
});
|
||
|
||
// 直接使用新接口格式(code + result)
|
||
if (configRes.data?.code === 0 || configRes.data?.code === '0') {
|
||
// 获取结果数据,直接使用 result(返回格式:{ code: 0, result: { can_use: false, message: "..." } })
|
||
const result = configRes.data?.result;
|
||
|
||
// 检查是否可以使用在线问诊功能
|
||
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;
|
||
}
|
||
}
|
||
|
||
// 检查通过或非在线复诊类型,正常跳转
|
||
uni.navigateTo({
|
||
url: '/pages/Inquiries/Inquiries?type=' + type
|
||
})
|
||
},
|
||
async golist(type) {
|
||
if (type === 3) {
|
||
// 药店模式直接进入商品页,不检查配置
|
||
return uni.navigateTo({
|
||
url: '/subPackages/product/product?register_type=3'
|
||
});
|
||
}
|
||
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 {
|
||
this.$refs.uToast.show({ title: res.data.msg, type: 'default', icon: false })
|
||
}
|
||
})
|
||
},
|
||
tosearch() {
|
||
uni.navigateTo({ url: '/subPackages/shop/search-home' })
|
||
},
|
||
toStore() {
|
||
uni.navigateTo({ url: '/subPackages/my/mystore' })
|
||
},
|
||
goLookDoctor(id, sts_id) {
|
||
if (!sts_id) { let sts_id = uni.getStorageSync('store_id') }
|
||
setTimeout(() => {
|
||
uni.requestSubscribeMessage({
|
||
tmplIds: ['JdSs08cMSiL17xwwHZ8fZ5UBUqeY0eKAuvyW7n4Fl20', 'OERMugiahk-aKRVH9GHmdJCRBE3yldzEKTzbMCJhY6U', 'p-Ix0uIuwPKxm-_yKDlI8mkI-niUgPtaMUZyAaa5vvA'],
|
||
complete: (res) => {
|
||
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",
|
||
data: { store_id: uni.getStorageSync('store_id') || '11001' }
|
||
}).then((res) => {
|
||
// 使用 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');
|
||
|
||
if (isNewFormat || isOldFormat) {
|
||
// 新接口格式:从 result 取值
|
||
// 老接口格式:从 data 取值
|
||
const responseData = isGuest && res.data.result ? res.data.result : res.data.data;
|
||
|
||
if (responseData && responseData.store) {
|
||
this.storeType = responseData.store['type']
|
||
uni.setStorageSync('store_type', responseData.store['type']) // 存储门店类型
|
||
this.infoList = responseData
|
||
this.headerTitle = responseData.store['name']
|
||
this.getBannered();
|
||
}
|
||
}
|
||
})
|
||
} else {
|
||
this.goNewlist()
|
||
}
|
||
},
|
||
goNewlist() {
|
||
storeList({
|
||
method: "post",
|
||
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)
|
||
uni.setStorageSync('store_id', this.storeinfo[0].store.id)
|
||
this.headerTitle = this.storeinfo[0].store['name']
|
||
this.getBannered();
|
||
}
|
||
} else {
|
||
// 未登录时不跳转,使用默认store_id=11001
|
||
uni.setStorageSync('store_id', '11001');
|
||
this.getBannered();
|
||
}
|
||
})
|
||
},
|
||
getList() {
|
||
this.doctorList = [];
|
||
doctorList({
|
||
method: "post",
|
||
data: { store_id: uni.getStorageSync('store_id') || '11001' }
|
||
}).then((res) => {
|
||
// 使用 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');
|
||
|
||
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) {
|
||
storeChange({ method: "post", data: { store_id: e } }).then((res) => {
|
||
if (res.data.errcode == 0) {
|
||
this.getStore()
|
||
this.getList();
|
||
}
|
||
})
|
||
},
|
||
getBannered() {
|
||
getBanner({
|
||
method: "post",
|
||
data: { store_id: uni.getStorageSync('store_id') || '11001' }
|
||
}).then((res) => {
|
||
// 使用 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');
|
||
|
||
if (isNewFormat || isOldFormat) {
|
||
// 新接口格式:从 result 取值
|
||
// 老接口格式:从 data 取值
|
||
const responseData = isGuest && res.data.result ? res.data.result : res.data.data;
|
||
|
||
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) {
|
||
uni.navigateTo({ url: this.urlInfo[e].external_link })
|
||
} else {
|
||
uni.navigateTo({ url: '/pages/home/home-banner?id=' + this.urlInfo[e].external_link })
|
||
}
|
||
},
|
||
getProductList() {
|
||
getStoreDrugListBySalespersonApi({
|
||
store_id: uni.getStorageSync('store_id') || '11001',
|
||
page: 1,
|
||
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 || [];
|
||
}
|
||
}).catch(() => { this.homeZones = []; })
|
||
},
|
||
getPlatformQualifications() {
|
||
getPlatformQualificationsApi({
|
||
store_id: uni.getStorageSync('store_id') || '11001',
|
||
}).then((res) => {
|
||
if (res.data.code == 0 || res.data.errcode == 0) {
|
||
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) {
|
||
// 获取所有有图片的资质,支持滑动预览
|
||
const allImages = this.qualifications
|
||
.filter(q => q.image)
|
||
.map(q => q.image);
|
||
if (allImages.length > 0 && item.image) {
|
||
uni.previewImage({
|
||
urls: allImages,
|
||
current: item.image
|
||
});
|
||
}
|
||
},
|
||
goProductDetail(item) {
|
||
if(!item || !item.drug) return;
|
||
uni.navigateTo({
|
||
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}`
|
||
});
|
||
},
|
||
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' });
|
||
},
|
||
async getDefaultDoctorId() {
|
||
try {
|
||
const storeId = uni.getStorageSync('store_id');
|
||
if (!storeId) return;
|
||
const res = await request('/xkApi/online-consultation/get-default-doctor-id', {
|
||
method: 'GET',
|
||
data: { store_id: storeId }
|
||
}, 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');
|
||
this.toChang(this.storeId)
|
||
this.getStore();
|
||
this.getList();
|
||
this.getProductList();
|
||
this.getHomeTopProducts();
|
||
this.getHomeZones();
|
||
this.getPlatformQualifications(); // 已补回
|
||
this.getDefaultDoctorId();
|
||
},
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
$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 {
|
||
background-color: #e0e5ec;
|
||
min-height: 100vh;
|
||
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%); }
|
||
}
|
||
|
||
.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; } }
|
||
}
|
||
}
|
||
}
|
||
|
||
/* --- 2. 头部区域 --- */
|
||
.header {
|
||
position: relative;
|
||
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; } }
|
||
}
|
||
|
||
/* --- 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; }
|
||
}
|
||
|
||
/* --- 2.5 金刚区 (Zone) --- */
|
||
.zone-wrapper {
|
||
padding: 0 32rpx 20rpx;
|
||
display: flex;
|
||
/* 默认样式,会被下方 modifier 覆盖 */
|
||
|
||
/* 模式1: 滑动 */
|
||
&.zone-scroll-mode {
|
||
flex-wrap: nowrap;
|
||
overflow-x: auto;
|
||
.zone-item { width: 140rpx; margin-right: 10rpx; }
|
||
}
|
||
|
||
/* 模式2: 换行 */
|
||
&.zone-wrap-mode {
|
||
flex-wrap: wrap;
|
||
justify-content: flex-start;
|
||
.zone-item { width: 20%; margin-bottom: 24rpx; }
|
||
}
|
||
|
||
.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; }
|
||
}
|
||
}
|
||
|
||
.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; }
|
||
.nav-icon-img-64 { position: absolute; right: 30rpx; top: 30rpx; width: 84rpx; height: 84rpx; z-index: 1; }
|
||
}
|
||
}
|
||
|
||
.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; }
|
||
}
|
||
|
||
.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; } }
|
||
}
|
||
}
|
||
|
||
/* --- 5. 药品卡片 (双列瀑布流) --- */
|
||
.product-list-container {
|
||
padding: 0 24rpx; /* 左右边距 */
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 16rpx; /* 卡片间隙 */
|
||
}
|
||
|
||
.product-card {
|
||
background: #fff;
|
||
/* 动态计算宽度,保留中间16rpx间隙 */
|
||
width: calc((100% - 16rpx) / 2);
|
||
padding: 0;
|
||
border-radius: 16rpx;
|
||
display: flex;
|
||
flex-direction: column;
|
||
box-shadow: $card-shadow;
|
||
border: 1rpx solid #f8f8f8;
|
||
overflow: hidden;
|
||
|
||
.prod-img-box {
|
||
width: 100%;
|
||
height: 280rpx; /* 缩小图片高度:原345rpx,减小约19% */
|
||
background: #f8f8f8;
|
||
border-radius: 0;
|
||
margin: 0;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
|
||
.prod-img { width: 100%; height: 100%; border-radius: 0; /* &.prescription-blur { filter: blur(4px); } 暂时禁用模糊 */ }
|
||
}
|
||
|
||
.prod-info {
|
||
flex: 1;
|
||
display: flex; flex-direction: column; justify-content: space-between;
|
||
padding: 12rpx; /* 减小内边距:原16rpx */
|
||
|
||
.prod-title {
|
||
font-size: 26rpx; /* 减小字号:原28rpx */
|
||
font-weight: 600;
|
||
color: #333;
|
||
line-height: 1.4;
|
||
margin-bottom: 8rpx;
|
||
height: 72rpx; /* 减小高度:原80rpx */
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
display: -webkit-box;
|
||
-webkit-line-clamp: 2;
|
||
-webkit-box-orient: vertical;
|
||
}
|
||
|
||
.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 */
|
||
|
||
.prod-bottom {
|
||
display: flex; justify-content: space-between; align-items: flex-end;
|
||
.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 {
|
||
padding: 40rpx 32rpx 40rpx;
|
||
.qualifications-row {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 20rpx;
|
||
.qualification-card {
|
||
background: #fff;
|
||
padding: 24rpx;
|
||
border-radius: 16rpx;
|
||
width: calc((100% - 20rpx) / 2); /* 一行两个 */
|
||
text-align: center;
|
||
box-shadow: 0 4rpx 12rpx rgba(0,0,0,0.03);
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
.qual-icon {
|
||
width: 200rpx;
|
||
height: 140rpx;
|
||
margin-bottom: 16rpx;
|
||
border-radius: 8rpx;
|
||
background: #f8f8f8;
|
||
}
|
||
.qual-name { font-size: 24rpx; color: #333; line-height: 1.4; font-weight: 500; }
|
||
}
|
||
}
|
||
}
|
||
|
||
.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; }
|
||
}
|
||
</style> |