ykt-team-wxapp/pages/home/customer-archive.vue

373 lines
8.9 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="archive-container">
<view class="mb-10 flex items-center justify-between">
<view class="module-title flex-shrink-0 truncate">
成员档案
</view>
<view class="flex items-center px-10 leading-normal rounded-sm" @click="toManagePage()">
<image class="manage-icon mr-5" src="/static/home/archive-manage.png" mode="aspectFit"></image>
<view style="font-size: 28rpx; color: #065BD6;">档案管理</view>
</view>
</view>
<view v-if="customers.length === 0" class="flex items-center justify-center h-80 border-dashed text-dark rounded">
<uni-icons type="plusempty" size="16" color="#999"></uni-icons>
<view class="text-base text-dark">新建档案</view>
</view>
<scroll-view scroll-x="true">
<view class="flex flex-nowrap pb-5 ">
<view v-for="i in customers" :key="i._id"
class="customer-card flex-shrink-0 mr-15 relative"
:class="current && i._id === current._id ? 'current-customer' : ''" @click="toggle(i)">
<!-- 关系标签 -->
<view v-if="i.relationship" class="relationship-tag"
:class="i.relationship === '本人' ? 'tag-blue' : 'tag-green'">
{{ i.relationship }}
</view>
<view class="flex flex-col items-center">
<view class="customer-name text-lg leading-normal font-semibold whitespace-nowrap "
:class="current && i._id === current._id ? 'text-primary' : 'text-dark'">
{{ i.name }}
</view>
</view>
<!-- 选中状态底部条和三角 -->
<view v-if="current && i._id === current._id" class="active-indicator">
<view class="active-bar"></view>
<view class="active-triangle"></view>
</view>
</view>
</view>
</scroll-view>
<view v-if="canAuth" class="px-10 py-5 mt-5 flex items-center bg-danger rounded-sm">
<view class="mr-5 w-0 flex-grow text-base text-white">
该档案还未授权本服务团队点击右侧授权按钮我们将更精准的为您服务
</view>
<view class="px-12 py-5 text-base rounded-sm text-dark bg-white" @click="auth()">
授权
</view>
</view>
<view v-if="current" class="flex mt-15">
<view class="info-card-new flex-grow mr-10" @click="fillBaseInfo()">
<view class="info-bg info-bg-base"></view>
<view class="info-content">
<view class="flex items-center justify-between mb-8">
<view class="info-title">个人基本信息</view>
<image class="arrow-icon-small" src="/static/home/arrow-right-blue.png" mode="aspectFit"></image>
</view>
<view class="info-subtitle">完善个人信息</view>
</view>
</view>
<view class="info-card-new flex-grow" @click="toHealthList()">
<view class="info-bg info-bg-health"></view>
<view class="info-content">
<view class="flex items-center justify-between mb-8">
<view class="info-title">健康信息</view>
<image class="arrow-icon-small" src="/static/home/arrow-right-blue.png" mode="aspectFit"></image>
</view>
<view class="info-subtitle">上传健康档案</view>
</view>
</view>
</view>
</view>
</template>
<script setup>
import { computed, ref, watch } from 'vue';
import { storeToRefs } from 'pinia'
import useAccount from '@/store/account';
import api from '@/utils/api';
import { toast, confirm } from '@/utils/widget';
const props = defineProps({
corpId: {
type: String,
default: ''
},
customers: {
type: Array,
default: () => []
},
team: {
type: Object,
default: () => ({})
}
})
const emit = defineEmits(['update:customers']);
const { account } = storeToRefs(useAccount());
const current = ref(null);
const customers = ref([]);
const canAuth = computed(() => {
if (current.value && props.team && props.team.teamId) {
const teamIds = Array.isArray(current.value.teamId) ? current.value.teamId : [];
return !teamIds.includes(props.team.teamId);
}
return false
})
function fillBaseInfo() {
if (canAuth.value) {
toast('请先授权本服务团队')
} else {
uni.navigateTo({
url: `/pages/archive/edit-archive?teamId=${props.team.teamId}&corpId=${props.corpId}&id=${current.value._id}`
})
}
}
function toHealthList() {
if (canAuth.value) {
toast('请先授权本服务团队')
} else {
const name = `${current.value.name} ${current.value.relationship ? `(${current.value.relationship})` : ''}`
uni.navigateTo({
url: `/pages/health/list?teamId=${props.team.teamId}&corpId=${props.corpId}&id=${current.value._id}&name=${encodeURIComponent(name)}`
})
}
}
function toggle(i) {
current.value = i;
}
function toManagePage() {
uni.navigateTo({ url: `/pages/archive/archive-manage?corpId=${props.corpId}&teamId=${props.team.teamId}` })
}
async function auth() {
await confirm(`是否授权${props.team.name}提供服务`);
const res = await api('authCustomerToTeam', { corpId: props.corpId, teamId: props.team.teamId, id: current.value._id });
if (res && res.success) {
await toast('授权成功');
getCustomers()
} else {
toast(res?.message || '授权失败');
}
}
async function getCustomers() {
const res = await api('getMiniAppCustomers', { miniAppId: account.value.openid, corpId: props.corpId });
if (res && res.success) {
customers.value = res && Array.isArray(res.data) ? res.data : [];
const customer = customers.value.find(i => current.value && i._id === current.value._id);
current.value = customer || customers.value[0] || null;
// 向父组件传递 customers 数据
emit('update:customers', customers.value);
} else {
toast(res.message || '获取档案失败');
}
}
watch(() => props.corpId, n => {
if (n) {
getCustomers()
} else {
customers.value = [];
}
}, { immediate: true });
</script>
<style scoped>
.archive-container {
padding: 24rpx 30rpx;
margin: 0 30rpx;
background: linear-gradient(181deg, #C2DCFF 1.01%, #FFFFFF 43.31%);
border-radius: 16rpx;
box-shadow:
inset 0 2rpx 0 0 rgba(255, 255, 255, 0.82),
0 8rpx 10rpx 0 rgba(60, 169, 145, 0.06);
}
.manage-icon {
width: 32rpx;
height: 32rpx;
}
.module-title {
color: #000000;
font-size: 36rpx;
font-weight: 600;
line-height: normal;
}
.customer-card {
width: 160rpx;
height: 110rpx;
display: flex;
align-items: center;
justify-content: center;
background: linear-gradient(180deg, #FFFFFF 0%, #E6EFFB 100%);
border-radius: 12rpx;
border: 2rpx solid #AECAF2;
transition: all 0.2s;
position: relative;
}
.current-customer {
background: #FFFFFF;
border: 2rpx solid #065BD6;
}
.relationship-tag {
position: absolute;
top: -2rpx;
right: -10rpx;
padding: 4rpx 16rpx;
font-size: 20rpx;
line-height: normal;
color: #fff;
border-top-left-radius: 16rpx;
border-bottom-left-radius: 16rpx;
z-index: 10;
}
.relationship-tag::after {
content: '';
position: absolute;
right: 0;
bottom: -8rpx;
width: 0;
height: 0;
border-right: 10rpx solid transparent;
}
.tag-blue {
background: #065BD6;
}
.tag-blue::after {
border-top: 8rpx solid #003F96;
}
.tag-green {
background: #1DBF98;
}
.tag-green::after {
border-top: 8rpx solid #0F8C6D;
}
.active-indicator {
position: absolute;
bottom: -2rpx;
left: -2rpx;
right: -2rpx;
height: 10rpx;
z-index: 5;
}
.active-bar {
width: 100%;
height: 100%;
background: #065bd6;
border-bottom-left-radius: 12rpx;
border-bottom-right-radius: 12rpx;
box-sizing: border-box;
}
.active-triangle {
position: absolute;
top: 100%;
left: 50%;
transform: translateX(-50%) rotate(45deg);
width: 12rpx;
height: 12rpx;
background: #065BD6;
margin-top: -8rpx;
}
.customer-age {
color: #999999;
}
.mr-15 {
margin-right: 20rpx;
}
.mt-15 {
margin-top: 24rpx;
}
.mb-8 {
margin-bottom: 12rpx;
}
.info-card-new {
position: relative;
padding: 24rpx;
border-radius: 16rpx;
background: linear-gradient(115deg, #F4F9FF 14.74%, #DBEAFF 66.11%);
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.06);
overflow: hidden;
width: 310rpx;
height: 94rpx;
flex: 1;
}
.info-bg {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
background-repeat: no-repeat;
background-position: right bottom;
background-size: cover;
opacity: 0.95;
pointer-events: none;
}
.info-content {
position: relative;
z-index: 1;
}
.info-bg-base {
background-image: url('/static/home/basic-info-bg.svg');
}
.info-bg-health {
background-image: url('/static/home/health-info-bg.svg');
}
.info-title {
color: #213E80;
font-size: 32rpx;
font-weight: 500;
}
.info-subtitle {
color: #78808F;
font-size: 24rpx;
}
.arrow-icon-small {
width: 24rpx;
height: 24rpx;
flex-shrink: 0;
}
.font-medium {
font-weight: 500;
}
.h-80 {
height: 160rpx;
}
.h-normal {
height: 1.5em;
}
.min-w-100 {
min-width: 200rpx;
}
.rounded-lg {
border-radius: 16rpx;
}
</style>