ykt-team-wxapp/pages/team/business-card.vue
2026-06-29 13:51:48 +08:00

1374 lines
28 KiB
Vue
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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>
<full-page v-if="businessCard">
<view class="card-page">
<view class="card-service-container">
<BusinessCard :card="businessCard" />
<view class="service-section">
<view class="service-grid">
<view class="service-item service-item-1" @click="showTeams()">
<image class="service-item-bg" src="/static/card/jzfwBack.png" mode="scaleToFill"></image>
<image class="service-icon" src="/static/card/jzfwIcon.png" mode="aspectFit"></image>
<text class="service-text">全周期管理</text>
</view>
<view class="service-item service-item-2" @click="openAddressModal">
<image class="service-item-bg" src="/static/card/gwBack.png" mode="scaleToFill"></image>
<image class="service-icon" src="/static/card/gwIcon.png" mode="aspectFit"></image>
<text class="service-text">门诊预约</text>
</view>
<view class="service-item service-item-3" @click="displayPhone()">
<image class="service-item-bg" src="/static/card/gzhBack.png" mode="scaleToFill"></image>
<image class="service-icon" src="/static/card/telephone.svg" mode="aspectFit"></image>
<text class="service-text">联系电话</text>
</view>
<view class="service-item service-item-4" @click="openEmailModal">
<image class="service-item-bg" src="/static/card/sphBack.png" mode="scaleToFill"></image>
<image class="service-icon" src="/static/card/email.svg" mode="aspectFit"></image>
<text class="service-text">邮箱</text>
</view>
</view>
</view>
</view>
<view class="info-container">
<!-- Tab 切换栏 -->
<view class="tab-header">
<view v-if="hospitalInfo" class="tab-item" :class="{ active: activeTab === 'hospital' }"
@click="switchTab('hospital')">
<text class="tab-text">医院信息</text>
</view>
<view class="tab-item" :class="{ active: activeTab === 'intro' }" @click="switchTab('intro')">
<text class="tab-text">个人简介</text>
</view>
</view>
<!-- 医院信息内容 -->
<view v-if="hospitalInfo && activeTab === 'hospital'" class="tab-content"
:class="{ 'tab-content-left': activeTab === 'hospital' }">
<view class="hospital-info">
<view class="hospital-header">
<view class="hospital-logo">
<image :src="hospitalInfo.logo || '/static/card/hospital-icon.png'" mode="aspectFit">
</image>
</view>
<view class="hospital-details">
<text class="hospital-name">
{{ hospitalInfo.name || '未获取到医院名称' }}
</text>
<view class="hospital-tags">
<text class="hospital-tag" :class="getTagClass(index)"
v-for="(tag, index) in (hospitalInfo.tags || [])" :key="tag">{{ tag }}
</text>
</view>
</view>
</view>
<view class="hospital-intro">
<view class="hospital-text-wrapper">
<u-parse v-if="hospitalInfo.introduction" :content="hospitalInfo.introduction"></u-parse>
<!-- <rich-text v-if="hospitalInfo.introduction" :nodes="hospitalInfo.introduction"></rich-text> -->
<text class="hospital-text" v-else>暂无医院介绍信息</text>
<!-- <view class="more-link" @click="openMoreInfoModal">更多>></view> -->
</view>
</view>
</view>
</view>
<!-- 个人简介内容 -->
<view v-if="activeTab === 'intro'" class="tab-content" :class="{ 'tab-content-right': activeTab === 'intro' }">
<view class="intro-content">
<view class="intro-header">
<view class="intro-title-bar"></view>
<text class="intro-title">个人简介</text>
</view>
<text class="intro-text" v-if="businessCard && businessCard.memberTroduce">
{{ businessCard.memberTroduce }}
</text>
<text class="intro-text no-data" v-else>暂无个人简介</text>
</view>
</view>
</view>
</view>
<template #footer>
<view class="bottom-actions">
<button class="edit-btn" @click="addFriend()">
<image class="edit-icon" src="/static/card/edit-card.png" mode="aspectFit"></image>
<text class="edit-text">加好友</text>
</button>
<button class="share-btn" open-type="share">
<text class="share-text">转发名片</text>
</button>
</view>
</template>
</full-page>
<!-- 电话弹窗 -->
<view v-if="showPhoneModal" class="modal-mask" @click="closePhoneModal">
<view class="service-modal-content" @click.stop>
<view class="service-modal-header">
<text class="service-modal-close" @click="closePhoneModal">×</text>
<text class="service-modal-title">电话</text>
</view>
<view class="service-modal-body">
<view class="service-list">
<view class="service-list-item" v-if="businessCard && businessCard.externalContact">
<view class="service-list-text">{{ businessCard.externalContact }}</view>
<view class="flex">
<view class="text-base text-primary mr-10"
@click="setClipboardData(businessCard.externalContact, 'mobile')">
复制
</view>
<view class="text-base text-primary" @click="makePhoneCall(businessCard.externalContact)">拨打</view>
</view>
</view>
<view class="service-list-item" v-else>
<text class="service-list-text no-data">暂无电话信息</text>
<view class="service-list-icon">📞</view>
</view>
</view>
</view>
</view>
</view>
<!-- 邮箱弹窗 -->
<view v-if="showEmailModal" class="modal-mask" @click="closeEmailModal">
<view class="service-modal-content" @click.stop>
<view class="service-modal-header">
<text class="service-modal-close" @click="closeEmailModal">×</text>
<text class="service-modal-title">邮箱</text>
</view>
<view class="service-modal-body">
<view class="service-list">
<view class="service-list-item" v-if="businessCard.externalEmail">
<text class="service-list-text">{{ businessCard.externalEmail }}</text>
<view class="text-base text-primary mr-10" @click="setClipboardData(businessCard.externalEmail, 'email')">
复制
</view>
</view>
<view class="service-list-item" v-else>
<text class="service-list-text no-data">暂无邮箱信息</text>
<view class="service-list-icon"></view>
</view>
</view>
</view>
</view>
</view>
<teams-popup :visible="showTeamPopup" :teams="teams" @close="showTeamPopup = false" />
</template>
<script setup>
import { ref, computed } from 'vue';
import { storeToRefs } from "pinia";
import { onShareAppMessage } from "@dcloudio/uni-app";
import api from '@/utils/api';
import useGuard from '@/hooks/useGuard';
import { toast } from '@/utils/widget.js';
import useAccount from '@/store/account';
import BusinessCard from './components/BusinessCard.vue'
import fullPage from '@/components/full-page.vue'
import TeamsPopup from './components/teams-popup.vue'
import uParse from '@/components/u-parse/u-parse.vue'
const { useShow, useLoad } = useGuard();
const wxAccountStore = useAccount();
const { account } = storeToRefs(useAccount());
const env = __VITE_ENV__;
const shareAppVersion = env.MP_SHARE_WX_APP_VERSION;
const activeTab = ref('hospital') // 'hospital' 或 'intro'
const corpId = ref('');
const userid = ref('')
const businessCard = ref(null);
const teams = ref([])
const hospitalInfo = computed(() => businessCard.value?.hospitalInfo || null);
const showPhoneModal = ref(false)
const showEmailModal = ref(false)
const showTeamPopup = ref(false)
function addFriend() {
uni.navigateTo({
url: `/pages/team/friend?corpId=${corpId.value}&userid=${userid.value}`
})
}
function displayPhone() {
if (businessCard.value.externalContact) {
showPhoneModal.value = true
}
}
function makePhoneCall(phone) {
closePhoneModal()
uni.makePhoneCall({
phoneNumber: phone,
success: () => {
toast('拨打电话成功')
}
})
}
function setClipboardData(data, type) {
if (type === 'mobile') {
showPhoneModal.value = false
} else if (type === 'email') {
showEmailModal.value = false
}
uni.setClipboardData({
data: data,
success: () => {
toast('复制成功')
}
})
}
function switchTab(tab) {
activeTab.value = tab
}
async function getCard() {
const res = await api('getBusinessCard', { userid: userid.value, corpId: corpId.value })
businessCard.value = res && res.data ? res.data : null;
if (!hospitalInfo.value && activeTab.value === 'hospital') {
activeTab.value = 'intro'
}
if (businessCard.value) {
recordBusinessCardVisit()
}
}
async function showTeams() {
const res = await api('getJoinedTeams', { mateId: userid.value, corpId: corpId.value })
teams.value = res && Array.isArray(res.data) ? res.data : [];
if (teams.value.length === 0) {
toast('暂无加入的团队')
} else {
showTeamPopup.value = true
}
}
async function recordBusinessCardVisit() {
try {
const account = await getVisitorAccount();
let visitorExternalUserId = wxAccountStore.externalUserId || "";
if (!visitorExternalUserId && account && account.unionid && account.openid && corpId.value) {
visitorExternalUserId = await wxAccountStore.getExternalUserId(corpId.value) || "";
}
const response = await api('recordBusinessCardBehavior', {
action: "visit",
corpId: corpId.value,
cardUserid: userid.value,
cardDeptName: businessCard.value?.deptName || "",
source: "team-wxapp",
visitorOpenid: account?.openid || wxAccountStore.openid || uni.getStorageSync('openid') || "",
visitorUnionid: account?.unionid || "",
visitorMobile: account?.mobile || "",
visitorExternalUserId,
}, false);
if (!response?.success) {
console.warn("record business card visit failed", response?.message || response);
}
} catch (error) {
console.warn("record business card visit failed", error);
}
}
async function getVisitorAccount() {
let account = wxAccountStore.account || uni.getStorageSync('account') || null;
if (!account) {
account = await wxAccountStore.login('', { silent: true });
}
return account || wxAccountStore.account || uni.getStorageSync('account') || null;
}
useLoad((opt) => {
console.clear()
console.log(account.value)
if (opt.q) {
const href = typeof opt.q === "string" ? decodeURIComponent(opt.q.trim()) : "";
const [, url = ""] = href.split("?");
const data = url.split("&").reduce((acc, cur) => {
if (!cur) return acc;
const [key, value] = cur.split("=");
if (!key) return acc;
acc[key] = value || ''
return acc;
}, {});
console.log(data)
corpId.value = data.corpId || ''
userid.value = data.userid || ''
} else {
corpId.value = opt.corpId
userid.value = opt.userid
}
})
useShow(() => {
getCard()
})
onShareAppMessage((res) => {
if (businessCard.value) {
return {
title: `${businessCard.value.externalName || card.anotherName || ''}】电子名片`,
type: shareAppVersion || 0, // 0 正式版本 | 1 开发版本 | 2 体验版本
path: `/pages/team/business-card?corpId=${corpId.value}&userid=${userid.value}&shareOpenId=${account.value?.openid || ''}`,
imageUrl: 'https://ykt.youcan365.com/uploads/1782455619525-business-card.jpg'
}
}
})
const cardStore = ref({})
const accountStore = ref({})
// 弹窗显示状态
const showAddressModal = ref(false)
const showMoreInfoModal = ref(false)
const showOfficialAccountModal = ref(false)
const showVideoAccountModal = ref(false)
const showShareModal = ref(false)
// 便民服务列表
const services = ref([])
// 获取标签样式类名
const getTagClass = (index) => {
const styles = ['grade', 'center', 'specialty']
return styles[index % 3]
}
// 关闭便民服务弹窗
const closeServiceModal = () => {
showServiceModal.value = false
}
// 关闭电话弹窗
const closePhoneModal = () => {
showPhoneModal.value = false
}
// 打开邮箱弹窗
const openEmailModal = () => {
showEmailModal.value = true
}
// 关闭邮箱弹窗
const closeEmailModal = () => {
showEmailModal.value = false
}
const openAddressModal = () => {
toast('门诊预约功能暂未开放')
// showAddressModal.value = true
}
// 关闭地址弹窗
const closeAddressModal = () => {
showAddressModal.value = false
}
</script>
<style scoped lang="scss">
/* 模态框遮罩层 */
.modal-mask {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background: rgba(0, 0, 0, 0.5);
display: flex;
align-items: flex-end;
justify-content: center;
z-index: 1000;
touch-action: none;
overflow: hidden;
}
.card-page {
background-color: #F8EEE3;
min-height: 100vh;
padding-bottom: 120rpx;
/* 为底部固定按钮栏留出空间 */
}
.card-page::before {
content: '';
position: absolute;
top: -20rpx;
left: 0;
right: 0;
height: 320rpx;
background: linear-gradient(180deg, #EB6625 0%, #F8EEE3 100%);
z-index: 0;
}
/* 名片和服务容器 */
.card-service-container {
border-radius: 20rpx;
overflow: hidden;
position: relative;
}
/* 服务图标区域 */
.service-section {
margin: -10rpx 20rpx 0rpx;
}
.service-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 20rpx;
}
.service-item {
position: relative;
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
padding: 36rpx 40rpx;
background-position: center;
background-repeat: no-repeat;
border-radius: 20rpx;
position: relative;
overflow: hidden;
background-size: 114% 150%;
}
.service-item-bg {
position: absolute;
top: 0;
bottom: 0;
left: -10px;
right: -10px;
width: auto;
height: auto;
z-index: 0;
}
// .service-item-1 {
// background-image: url('/static/card/jzfwBack.png');
// }
// .service-item-2 {
// background-image: url('/static/card/gwBack.png');
// }
// .service-item-3 {
// background-image: url('/static/card/gzhBack.png');
// }
// .service-item-4 {
// background-image: url('/static/card/sphBack.png');
// }
.service-icon {
width: 72rpx;
height: 72rpx;
display: flex;
align-items: center;
justify-content: center;
position: relative;
z-index: 1;
margin-right: 48rpx;
}
.service-text {
font-size: 32rpx;
color: #fff;
text-align: center;
font-weight: 500;
position: relative;
white-space: nowrap;
z-index: 1;
}
/* 禁用状态的样式 */
.service-item.disabled {
opacity: 0.5;
pointer-events: none;
filter: grayscale(50%);
}
.service-icon.disabled {
filter: grayscale(100%);
opacity: 0.6;
}
.service-text.disabled {
color: rgba(255, 255, 255, 0.6);
}
/* 信息容器通用样式 */
.info-container {
overflow: hidden;
margin: 24rpx 20rpx;
position: relative;
padding: 0;
}
/* 人才招聘和导航按钮 */
.action-buttons {
display: flex;
gap: 20rpx;
margin: 20rpx;
}
.action-btn {
flex: 1;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
gap: 12rpx;
padding: 24rpx 20rpx;
border-radius: 10px;
border: 1px solid #ffbf6533;
background: linear-gradient(95deg, #FFF5DB 16.63%, #FFECDE 92.44%);
box-shadow: 0 9px 15.6px 0 #FFF inset;
transition: all 0.3s ease;
}
.action-btn:active {
transform: scale(0.98);
opacity: 0.9;
}
.action-icon {
width: 48rpx;
height: 48rpx;
flex-shrink: 0;
}
.action-text {
font-size: 28rpx;
color: #333;
font-weight: 500;
}
/* Tab 切换栏样式 */
.tab-header {
display: flex;
background-color: #F8EEE3;
border-radius: 20rpx 20rpx 0 0;
padding: 0;
overflow: visible;
position: relative;
}
.tab-item {
flex: 1;
padding: 24rpx 0;
text-align: center;
background: linear-gradient(83deg, #eb662566 15.22%, #faae5766 77.02%);
transition: background 0.3s ease, clip-path 0.3s ease, transform 0.3s ease;
cursor: pointer;
position: relative;
z-index: 1;
}
.tab-item:last-child {
margin-right: 0;
}
/* 未选中的 tab - 左侧 */
.tab-item:first-child:not(.active) {
border-radius: 20rpx 0 0 0;
/* 左边垂直,右边倾斜(上宽下窄),延伸到右侧区域 */
clip-path: polygon(0 0, 100% 0, 92% 100%, 0 100%);
/* 缩小未选中的 tab */
transform: scale(0.95);
}
/* 未选中的 tab - 右侧 */
.tab-item:last-child:not(.active) {
border-radius: 0 20rpx 0 0;
/* 右边垂直,左边倾斜(上宽下窄),延伸到左侧区域 */
clip-path: polygon(0% 0, 100% 0, 100% 100%, 4% 100%);
/* 缩小未选中的 tab */
transform: scale(0.95);
}
/* 选中的 tab - 背景变为白色渐变,上窄下宽,占据另一个 tab 的下底 */
.tab-item.active {
background: linear-gradient(178deg, #FEF4E8 10.53%, #fff 100%);
transition: background 0.3s ease, clip-path 0.3s ease, transform 0.3s ease;
z-index: 2;
/* 选中状态保持正常大小 */
transform: scale(1);
}
/* 选中左侧 tab医院信息左边直角边右边斜边上窄下宽下底宽 */
.tab-item.active:first-child {
border-radius: 20rpx 0 0 0;
/* 左边垂直(直角边),右边倾斜(斜边,上窄下宽),延伸到右侧 tab 区域 */
clip-path: polygon(0 0, 92% 0, 100% 100%, 0 100%);
/* 使用负边距让两个 tab 重叠,消除中间空隙 */
margin-right: -8%;
}
/* 选中右侧 tab个人简介右边直角边左边斜边上窄下宽下底宽 */
.tab-item.active:last-child {
border-radius: 0rpx 20rpx 0 0;
/* 右边垂直(直角边),左边倾斜(斜边,上窄下宽),延伸到左侧 tab 区域 */
clip-path: polygon(8% 0, 100% 0, 100% 100%, 0 100%);
/* 使用负边距让两个 tab 重叠,消除中间空隙 */
margin-left: -8%;
}
.tab-item.active:only-child {
border-radius: 20rpx 20rpx 0 0;
/* 只有一个 tab 时,保持矩形,不需要梯形 */
clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%);
}
.tab-text {
font-size: 32rpx;
color: #333;
font-weight: 500;
position: relative;
display: inline-block;
transition: all 0.3s ease;
}
.tab-item.active .tab-text {
font-weight: bold;
color: #333;
}
/* 选中 tab 文字下方的橙红色下划线 */
.tab-item.active .tab-text::after {
content: '';
position: absolute;
bottom: -4rpx;
left: 0;
width: 100%;
height: 16rpx;
/* 颜色渐变:从深橙红色到浅色 */
background: linear-gradient(90deg, #EF8839 0%, rgba(239, 136, 57, 0.4) 70%, rgba(239, 136, 57, 0.1) 100%);
border-radius: 20rpx;
/* 使用 transform scaleX 实现从粗到细的效果,从左侧开始 */
transform: scaleX(1);
transform-origin: left center;
/* 添加过渡动画 */
transition: transform 0.3s ease;
/* 通过 mask 或 clip-path 实现从粗到细的视觉效果,粗的部分占据更大比例 */
clip-path: polygon(0 0, 100% 0, 97% 100%, 3% 100%);
}
/* Tab 内容区域 */
.tab-content {
padding: 20rpx 40rpx 30rpx;
background-color: #fff;
}
/* 选中左侧 tab医院信息时的内容区域 - 左上角有圆角,底部圆角 */
.tab-content-left {
border-radius: 0 20rpx 20rpx 20rpx;
}
/* 选中右侧 tab个人简介时的内容区域 - 右上角有圆角,底部圆角 */
.tab-content-right {
border-radius: 20rpx 0 20rpx 20rpx;
}
.section-header {
margin-bottom: 30rpx;
}
.section-title-wrapper {
position: relative;
display: inline-block;
margin-bottom: 20rpx;
width: fit-content;
}
.section-title {
font-size: 32rpx;
font-weight: bold;
color: #333;
position: relative;
z-index: 2;
}
.title-decoration {
position: absolute;
bottom: -8rpx;
left: 0;
width: 144rpx;
height: 28rpx;
flex-shrink: 0;
border-radius: 4rpx;
background: linear-gradient(90deg, #FAAE57 0%, rgba(255, 255, 255, 0.64) 100%);
z-index: 1;
}
.hospital-info {
margin-top: 0;
}
.hospital-header {
display: flex;
align-items: flex-start;
gap: 20rpx;
margin-bottom: 20rpx;
}
.hospital-logo {
font-size: 48rpx;
flex-shrink: 0;
width: 80rpx;
height: 80rpx;
display: flex;
align-items: center;
justify-content: center;
}
.hospital-logo image {
width: 100%;
height: 100%;
}
.hospital-details {
flex: 1;
}
.hospital-name {
font-size: 32rpx;
font-weight: bold;
color: #333;
margin-bottom: 16rpx;
display: block;
}
.hospital-tags {
display: flex;
gap: 12rpx;
flex-wrap: wrap;
}
.hospital-tag {
font-size: 20rpx;
font-weight: 400;
padding: 0 16rpx;
line-height: 36rpx;
flex-shrink: 0;
border-radius: 4rpx;
}
.hospital-tag.grade {
border: 1rpx solid #2f8af580;
background: #2f8af51a;
color: #037AFF;
}
.hospital-tag.center {
border: 1rpx solid #fb791e80;
background: #ef88391a;
color: #fb791e;
}
.hospital-tag.specialty {
border: 1rpx solid #12b2b380;
background: #12b2b31a;
color: #12b2b3;
}
/* Banner轮播样式 */
.banner-section {
margin: 30rpx 0;
border-radius: 16rpx;
overflow: hidden;
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
}
.banner-swiper {
width: 100%;
aspect-ratio: 3 / 1;
border-radius: 16rpx;
/* 兼容不支持 aspect-ratio 的浏览器,使用 calc 计算 3:1 比例 */
height: calc(100vw / 3);
}
.banner-item {
width: 100%;
height: 100%;
position: relative;
}
.banner-image {
width: 100%;
height: 100%;
border-radius: 16rpx;
}
.hospital-intro {
display: flex;
/* 解决伪元素height:100%失效的问题 */
margin-bottom: 30rpx;
}
.hospital-text-wrapper {
line-height: 1.6;
position: relative;
}
.hospital-text {
font-size: 28rpx;
color: #666;
line-height: 1.6;
display: block;
letter-spacing: 0.4rpx;
}
.more-link {
color: #ffb366;
position: absolute;
/* 改为绝对定位 */
right: 0;
bottom: 0;
font-size: 24rpx;
font-weight: 500;
background: #fff;
padding-left: 8rpx;
z-index: 1;
/* 确保按钮在最上层 */
}
.more-link::before {
content: '...';
color: #999;
font-size: 14px;
margin-right: 8rpx;
}
.hospital-links {
display: flex;
justify-content: space-between;
}
.link-item {
display: flex;
flex-direction: column;
align-items: center;
gap: 12rpx;
flex: 1;
}
.link-icon {
width: 60rpx;
height: 60rpx;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
}
.link-text {
font-size: 22rpx;
color: #666;
text-align: center;
}
/* 个人擅长内容 */
.expertise-content {
margin-top: 20rpx;
min-height: 120rpx;
}
.expertise-text {
font-size: 26rpx;
color: #666;
line-height: 1.6;
}
.expertise-text.no-data {
color: #999;
}
.intro-content {
margin-top: 0;
min-height: 120rpx;
}
.intro-header {
display: flex;
align-items: center;
margin-bottom: 20rpx;
gap: 12rpx;
}
.intro-title-bar {
width: 6rpx;
height: 32rpx;
background: #EF8839;
border-radius: 3rpx;
}
.intro-title {
font-size: 32rpx;
font-weight: bold;
color: #333;
}
.intro-text {
font-size: 28rpx;
color: #666;
line-height: 1.6;
display: block;
letter-spacing: 0.4rpx;
}
.intro-text.no-data {
color: #999;
}
/* 底部操作按钮 */
.bottom-actions {
padding: 20rpx 40rpx;
display: flex;
gap: 20rpx;
box-shadow: 0 -2rpx 10rpx rgba(0, 0, 0, 0.1);
}
.edit-btn {
flex: 1;
height: 80rpx;
background: #f8f9fa;
border: 2rpx solid #e0e0e0;
border-radius: 100rpx;
display: flex;
align-items: center;
justify-content: center;
gap: 8rpx;
}
.edit-icon {
width: 32rpx;
height: 32rpx;
}
.edit-text {
font-size: 26rpx;
color: #666;
}
.share-btn {
flex: 2;
height: 80rpx;
background: #E86B3E;
border: none;
border-radius: 100rpx;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
}
.share-text {
font-size: 28rpx;
color: #fff;
font-weight: bold;
}
/* 便民服务弹窗样式 */
.service-modal-content {
background: white;
border-radius: 20rpx 20rpx 0 0;
width: 100%;
overflow: hidden;
}
.service-modal-header {
position: relative;
padding: 40rpx 40rpx 20rpx;
text-align: center;
border-bottom: 1rpx solid #f0f0f0;
}
.service-modal-close {
position: absolute;
left: 40rpx;
top: 40rpx;
font-size: 40rpx;
color: #999;
width: 60rpx;
height: 60rpx;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
transition: all 0.3s ease;
}
.service-modal-close:active {
background: #f0f0f0;
}
.service-modal-title {
font-size: 36rpx;
font-weight: bold;
color: #333;
}
.service-modal-body {
padding: 30rpx 40rpx;
}
.service-list {
display: flex;
flex-direction: column;
gap: 20rpx;
}
.service-list-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 25rpx;
}
.service-list-text {
font-size: 28rpx;
color: #333;
font-weight: 500;
}
.service-list-text.no-data {
color: #999;
font-weight: normal;
}
.service-list-icon {
width: 60rpx;
height: 60rpx;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 28rpx;
color: #666;
}
/* 医院介绍弹窗样式 */
.more-info-modal-content {
background: white;
border-radius: 20rpx 20rpx 0 0;
width: 100%;
overflow: hidden;
}
.more-info-modal-header {
position: relative;
padding: 40rpx 40rpx 20rpx;
text-align: center;
border-bottom: 1rpx solid #f0f0f0;
}
.more-info-modal-title {
font-size: 36rpx;
font-weight: bold;
color: #333;
}
.more-info-modal-close {
position: absolute;
right: 40rpx;
top: 40rpx;
font-size: 40rpx;
color: #999;
width: 60rpx;
height: 60rpx;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
transition: all 0.3s ease;
}
.more-info-modal-close:active {
background: #f0f0f0;
}
.more-info-modal-body {
padding: 20rpx 0;
margin-bottom: 20rpx;
max-height: 60vh;
box-sizing: border-box;
width: 100%;
}
.more-info-text {
padding: 0 40rpx;
margin-bottom: 20rpx;
}
.more-info-content {
padding: 0 40rpx;
margin-bottom: 20rpx;
font-size: 26rpx;
color: #666;
line-height: 1.6;
}
.more-info-content :deep(p) {
margin-bottom: 20rpx;
}
.more-info-content :deep(img) {
max-width: 100%;
height: auto;
margin: 20rpx 0;
border-radius: 8rpx;
}
.more-info-content :deep(strong) {
font-weight: bold;
color: #333;
}
.no-data-text {
font-size: 28rpx;
color: #999;
text-align: center;
padding: 60rpx 0;
display: block;
}
.more-info-image {
padding: 0 40rpx;
margin: 30rpx 0;
display: flex;
justify-content: center;
align-items: center;
}
.more-info-text {
font-size: 26rpx;
color: #666;
line-height: 1.6;
margin-bottom: 20rpx;
}
.more-info-text:last-child {
margin-bottom: 40rpx;
}
.more-info-image-placeholder {
width: 100%;
height: 200rpx;
border: 2rpx solid #e0e0e0;
border-radius: 12rpx;
margin: 30rpx 0;
position: relative;
display: flex;
align-items: center;
justify-content: center;
}
.placeholder-lines {
position: relative;
width: 100%;
height: 100%;
}
.line {
position: absolute;
background: #e0e0e0;
width: 2rpx;
height: 100%;
top: 0;
left: 50%;
transform: translateX(-50%);
}
.line-1 {
transform: translateX(-50%) rotate(45deg);
}
.line-2 {
transform: translateX(-50%) rotate(-45deg);
}
/* 链接弹窗样式 */
.link-modal-content {
background: white;
border-radius: 20rpx 20rpx 0 0;
width: 100%;
overflow: hidden;
}
.link-modal-header {
position: relative;
padding: 40rpx 40rpx 20rpx;
text-align: center;
border-bottom: 1rpx solid #f0f0f0;
}
.link-modal-title {
font-size: 36rpx;
font-weight: bold;
color: #333;
}
.link-modal-close {
position: absolute;
right: 40rpx;
top: 40rpx;
font-size: 40rpx;
color: #999;
width: 60rpx;
height: 60rpx;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
transition: all 0.3s ease;
}
.link-modal-close:active {
background: #f0f0f0;
}
.link-modal-body {
padding: 30rpx 40rpx;
text-align: center;
}
.link-modal-desc {
font-size: 26rpx;
color: #666;
line-height: 1.6;
margin-bottom: 30rpx;
display: block;
}
.link-modal-btn {
width: 100%;
height: 80rpx;
background: #ffb366;
color: #fff;
border: none;
border-radius: 16rpx;
font-size: 28rpx;
font-weight: bold;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.3s ease;
}
.link-modal-btn:active {
background: #ffa356;
transform: scale(0.98);
}
.qr-code-placeholder {
margin-bottom: 20rpx;
display: flex;
justify-content: center;
}
.qr-code-image {
width: 360rpx;
height: 360rpx;
border: 2rpx solid #e0e0e0;
border-radius: 12rpx;
overflow: hidden;
}
.qr-code-image image {
width: 100%;
height: 100%;
}
/* 分享弹窗样式 */
.share-modal-content {
background: white;
border-radius: 20rpx 20rpx 0 0;
width: 100%;
overflow: hidden;
}
.share-modal-header {
position: relative;
padding: 40rpx 40rpx 20rpx;
text-align: center;
border-bottom: 1rpx solid #f0f0f0;
}
.share-modal-close {
position: absolute;
left: 40rpx;
top: 40rpx;
font-size: 40rpx;
color: #999;
width: 60rpx;
height: 60rpx;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
transition: all 0.3s ease;
}
.share-modal-close:active {
background: #f0f0f0;
}
.share-modal-title {
font-size: 36rpx;
font-weight: bold;
color: #333;
}
.share-modal-body {
padding: 30rpx 40rpx;
}
.share-options {
display: flex;
justify-content: space-around;
gap: 40rpx;
}
.share-option {
display: flex;
flex-direction: column;
align-items: center;
gap: 20rpx;
flex: 1;
}
.share-icon {
width: 80rpx;
height: 80rpx;
border-radius: 12rpx;
}
.share-option-text {
font-size: 26rpx;
color: #333;
text-align: center;
}
/* 无服务时的样式 */
.no-service {
text-align: center;
padding: 40rpx 0;
}
.no-service-text {
font-size: 28rpx;
color: #999;
}
</style>