feat: 名片页面开发

This commit is contained in:
huxuejian 2026-06-23 15:36:34 +08:00
parent 73f94858c9
commit 2f6f0d4abe
18 changed files with 2313 additions and 2 deletions

View File

@ -240,6 +240,13 @@
"navigationBarTitleText": "添加好友",
"disableScroll": true
}
},
{
"path": "business-card",
"style": {
"navigationBarTitleText": "个人名片",
"disableScroll": true
}
}
]
}

1990
pages/team/business-card.vue Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,312 @@
<template>
<view v-if="card" class="business-card" @click="handleClick">
<image class="card-bg" :src="cardBg"></image>
<view class="card-header">
<view class="avatar">
<image :src="card.avatar || '/static/card/avatar.png'" mode="aspectFill"></image>
</view>
<view class="info">
<text class="name">{{ card.externalName || card.anotherName || '' }}</text>
<text v-if="card.hospitalInfo" class="hospital">{{ card.hospitalInfo.name || '' }}</text>
<view class="title-tags">
<text class="title-tag department" v-if="card.deptName">{{ card.deptName }}</text>
<text class="title-tag position" v-if="card.title">{{ card.title }}</text>
</view>
</view>
</view>
<view class="contact-section">
<view class="contact-info">
<!-- <view class="contact-item" v-if="card.externalContact">
<image class="contact-icon" src="/static/card/address.png" mode="aspectFit"></image>
<text class="contact-text">{{ accountInfo.address }}</text>
</view> -->
<view v-if="card.externalContact" class="contact-item">
<image class="contact-icon" src="/static/card/phone.png" mode="aspectFit"></image>
<text class="contact-text">{{ card.externalContact || '' }}</text>
</view>
<view v-if="card.externalEmail" class="contact-item">
<image class="contact-icon" src="/static/card/email.png" mode="aspectFit"></image>
<text class="contact-text">{{ card.externalEmail || '' }}</text>
</view>
</view>
</view>
</view>
</template>
<script setup>
import { computed, onMounted, ref } from "vue";
import { onShow } from '@dcloudio/uni-app'
// import { useCardStore } from "@/stores/card";
// import { useAccountStore } from "@/stores/account";
// import { getDeptStaffDepartments } from "@/api/dept";
const props = defineProps({
card: {
type: [Object, null],
default: null
},
//
onClick: {
type: Function,
default: null,
},
//
cardBg: {
type: String,
default: "/static/card/card-bg2.png",
},
// 'doctor' 使 cardStore 'patient'
mode: {
type: String,
default: "doctor",
validator: (value) => ["doctor", "patient"].includes(value),
},
// 使 store
customAccountInfo: {
type: Object,
default: null,
},
// 使 store
customInstitutionInfo: {
type: Object,
default: null,
},
// 使 store
customDoctorCardStatus: {
type: Object,
default: null,
},
});
const emit = defineEmits(["click"]);
const cardStore = ref({});
const accountStore = ref({});
// 使
const accountInfo = computed(() => {
if (props.customAccountInfo) {
return props.customAccountInfo;
}
return accountStore.getAccountInfo || {};
});
// 使 getDeptStaffDepartments
const deptDisplayName = ref("");
const displayDeptName = computed(() => {
// 退 deptName
return deptDisplayName.value || accountInfo.value.deptName || "";
});
// 使
const institutionInfo = computed(() => {
if (props.customInstitutionInfo) {
return props.customInstitutionInfo;
}
return accountStore.getInstitutionInfo || {};
});
// 使
const doctorCardStatus = computed(() => {
if (props.customDoctorCardStatus) {
return props.customDoctorCardStatus;
}
return accountStore.getDoctorCardStatus || { hasDoctorCard: false };
});
//
const shouldShowDeptName = computed(() => {
if (props.mode === "patient") {
return true; //
}
return cardStore.deptNameVisible; // 使 cardStore
});
//
const shouldShowPosition = computed(() => {
if (props.mode === "patient") {
return true; //
}
return cardStore.positionVisible; // 使 cardStore
});
//
const shouldShowPhone = computed(() => {
if (props.mode === "patient") {
return true; //
}
return cardStore.phoneVisible; // 使 cardStore
});
//
const shouldShowEmail = computed(() => {
if (props.mode === "patient") {
return true; //
}
return cardStore.emailVisible; // 使 cardStore
});
//
const shouldShowAddress = computed(() => {
if (props.mode === "patient") {
return true; //
}
return cardStore.addressVisible; // 使 cardStore
});
//
const handleClick = () => {
if (props.onClick) {
props.onClick();
}
emit("click");
};
// staffId getDeptStaffDepartments
onShow(async () => {
try {
const staffId = accountInfo.value.staffId;
if (!staffId) return;
const res = await getDeptStaffDepartments({ staffId });
if (res && res.success && Array.isArray(res.data) && res.data.length > 0) {
// ["//"]
deptDisplayName.value = res.data.join("、");
}
} catch (error) {
console.error("获取部门显示信息失败:", error);
}
});
</script>
<style scoped lang="scss">
/* 名片展示区域 */
.business-card {
position: relative;
overflow: visible;
border-bottom-left-radius: 16rpx;
border-bottom-right-radius: 16rpx;
font-size: 0;
}
.card-bg {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 0;
display: block;
}
.card-header {
position: relative;
padding: 36rpx 40rpx 10rpx 40rpx;
display: flex;
align-items: center;
margin-bottom: 36rpx;
}
.contact-section {
position: relative;
z-index: 1;
padding: 0 40rpx 56rpx;
display: flex;
justify-content: space-between;
align-items: center;
}
.avatar {
width: 120rpx;
height: 120rpx;
display: flex;
border-radius: 50%;
align-items: center;
justify-content: center;
font-size: 60rpx;
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.1);
flex-shrink: 0;
margin-right: 30rpx;
align-self: center;
image {
width: 100%;
height: 100%;
border-radius: 50%;
}
}
.info {
flex: 1;
display: flex;
flex-direction: column;
justify-content: center;
}
.name {
display: block;
font-size: 36rpx;
font-weight: 500;
margin-bottom: 6rpx;
color: #222;
}
.hospital {
display: block;
font-size: 26rpx;
margin-bottom: 8rpx;
color: #666;
}
.title-tags {
display: flex;
gap: 16rpx;
margin-top: 8rpx;
}
.title-tag {
font-size: 24rpx;
font-weight: 400;
padding: 0 16rpx;
flex-shrink: 0;
border-radius: 28rpx;
display: flex;
align-items: center;
justify-content: center;
}
.title-tag.department {
color: #ff8b00;
border: 1rpx solid #ff8b00;
}
.title-tag.position {
color: #de4f27;
border: 0.5px solid #de4f27;
}
.contact-info {
display: flex;
flex-direction: column;
gap: 10rpx;
align-items: flex-start;
flex: 1;
}
.contact-item {
display: flex;
align-items: center;
gap: 10rpx;
}
.contact-icon {
width: 32rpx;
height: 32rpx;
}
.contact-text {
font-size: 24rpx;
color: #666;
}
</style>

View File

@ -96,7 +96,6 @@ const teammate = computed(() => {
const friendlyMember = computed(() => {
const friendlyMembers = team.value && Array.isArray(team.value.friendlyMembers) ? team.value.friendlyMembers : [];
debugger
return friendlyMembers.reduce((data, item) => {
data[item] = true;
return data

BIN
static/card/avatar.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

BIN
static/card/card-bg2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 276 KiB

BIN
static/card/edit-card.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
static/card/email.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 886 B

1
static/card/email.svg Normal file
View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1781663573063" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="11885" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M838.954667 234.666667H170.666667c-3.626667 0-7.168 0.448-10.56 1.322666l323.690666 323.669334a21.333333 21.333333 0 0 0 30.165334 0L838.954667 234.666667z m46.144 14.186666l-260.693334 260.693334 262.933334 262.912c5.44-7.168 8.661333-16.106667 8.661333-25.792V277.333333c0-10.944-4.117333-20.906667-10.88-28.48zM843.861333 789.333333l-249.6-249.621333-50.133333 50.133333a64 64 0 0 1-90.517333 0l-50.112-50.133333L156.373333 786.88c4.48 1.578667 9.28 2.453333 14.314667 2.453333h673.194667zM128.661333 754.218667L373.333333 509.525333 129.578667 265.813333A42.709333 42.709333 0 0 0 128 277.333333v469.333334c0 2.56 0.213333 5.098667 0.661333 7.552zM170.666667 192h682.666666a85.333333 85.333333 0 0 1 85.333334 85.333333v469.333334a85.333333 85.333333 0 0 1-85.333334 85.333333H170.666667a85.333333 85.333333 0 0 1-85.333334-85.333333V277.333333a85.333333 85.333333 0 0 1 85.333334-85.333333z" fill="#ffffff" p-id="11886"></path></svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
static/card/gwBack.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

BIN
static/card/gwIcon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 866 B

BIN
static/card/gzhBack.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

BIN
static/card/jzfwBack.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

BIN
static/card/jzfwIcon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

BIN
static/card/phone.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
static/card/sphBack.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1781663513850" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="10787" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M731.9 631.3c15.5-30.6 46.8-71.9-20-96.3-66.8-24.4-74.7 1-90.8 32.6-11.2 22.1-65.1 1.6-113.7-22.4-48.6-24-97.5-54.2-86.3-76.3 16.1-31.6 32-53-27.8-91.1-59.9-38.1-74.8 11.3-90.3 41.9-18 35.3 40.4 125.4 171.6 190.2 131.1 64.6 239.3 56.6 257.3 21.4z m0 0" p-id="10788" fill="#ffffff"></path><path d="M511 959c-60.4 0-119-11.8-174.2-35.2-53.3-22.5-101.2-54.8-142.3-95.9-41.1-41.1-73.4-89-95.9-142.3-23.3-55.2-35.2-113.8-35.2-174.2 0-60.4 11.8-119 35.2-174.2 22.5-53.3 54.8-101.2 95.9-142.3 41.1-41.1 89-73.4 142.3-95.9C391.9 75.7 450.6 63.8 511 63.8c60.4 0 119 11.8 174.2 35.2 53.3 22.5 101.2 54.8 142.3 95.9 41.1 41.1 73.4 89 95.9 142.3 23.3 55.2 35.2 113.8 35.2 174.2 0 60.4-11.8 119-35.2 174.2-22.5 53.3-54.8 101.2-95.9 142.3-41.1 41.1-89 73.4-142.3 95.9C630 947.1 571.4 959 511 959z m0-851.3c-222.6 0-403.7 181.1-403.7 403.7S288.4 915.1 511 915.1 914.7 734 914.7 511.4 733.6 107.7 511 107.7z" fill="#ffffff" p-id="10789"></path></svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -15,7 +15,8 @@ const urlsConfig = {
getTeamMemberAvatarsAndName: "getTeamMemberAvatarsAndName",
getMiniAppHomeStats: "getMiniAppHomeStats",
getResponsiblePerson: 'getTeamResponsiblePerson',
relateWxappTeamByExternalUserId: 'relateWxappTeamByExternalUserId'
relateWxappTeamByExternalUserId: 'relateWxappTeamByExternalUserId',
getBusinessCard: 'getBusinessCard'
},
knowledgeBase: {