ykt-team-wxapp/pages/home/customer-archive.vue
2026-02-03 09:59:49 +08:00

256 lines
7.5 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="flex-shrink-0 text-lg font-semibold truncate text-dark">
成员档案
</view>
<view class="flex items-center px-10 leading-normal text-base text-primary rounded-sm" @click="toManagePage()">
<image class="manage-icon mr-5" src="/static/home/档案管理.png" mode="aspectFit"></image>
<view>档案管理</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 min-w-100 mr-10 p-10 rounded-lg relative"
:class="current && i._id === current._id ? 'current-customer' : ''" @click="toggle(i)">
<view class="flex flex-col items-center">
<view class="text-base leading-normal font-semibold whitespace-nowrap mb-5"
:class="current && i._id === current._id ? 'text-primary' : 'text-dark'">
{{ i.name }}
</view>
<view class="flex items-center">
<image v-if="i.sex" class="sex-icon mr-5"
:src="i.sex === '男' ? '/static/icon/male.png' : '/static/home/女性图标.png'"
mode="aspectFit"></image>
<view class="text-base leading-normal"
:class="current && i._id === current._id ? 'text-primary' : 'text-gray'">
{{ i.age > 0 ? i.age + '岁' : '' }}
</view>
</view>
<view v-if="i.relationship" class="relationship-tag flex-shrink-0 px-5 rounded-sm text-sm leading-normal"
:class="current && i._id === current._id ? 'text-primary' : 'text-gray'">
{{ i.relationship }}
</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-10">
<view class="info-card flex-grow mr-10" @click="fillBaseInfo()">
<image class="info-bg" src="/static/home/个人基本信息bg.svg" mode="aspectFit"></image>
<view class="info-content">
<view class="flex items-center justify-between mb-5">
<view class="text-lg text-dark">个人基本信息</view>
<image class="arrow-icon" src="/static/home/右箭头-蓝色.png" mode="aspectFit"></image>
</view>
<view class="text-base text-gray">完善个人信息</view>
</view>
</view>
<view class="info-card flex-grow" @click="toHealthList()">
<image class="info-bg" src="/static/home/健康信息bg.svg" mode="aspectFit"></image>
<view class="info-content">
<view class="flex items-center justify-between mb-5">
<view class="text-lg text-dark">个人健康信息</view>
<image class="arrow-icon" src="/static/home/右箭头-蓝色.png" mode="aspectFit"></image>
</view>
<view class="text-base text-gray">填写健康信息</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(to bottom, #C2DCFF 0%, #FFFFFF 100%);
border-radius: 32rpx;
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.08);
}
.manage-icon {
width: 32rpx;
height: 32rpx;
}
.customer-card {
background: white;
border-radius: 16rpx;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.06);
transition: all 0.3s;
}
.current-customer {
background: linear-gradient(135deg, #E3F2FF 0%, #FFFFFF 100%);
border: 2rpx solid #065BD6;
box-shadow: 0 4rpx 12rpx rgba(6, 91, 214, 0.2);
}
.sex-icon {
width: 32rpx;
height: 32rpx;
}
.relationship-tag {
margin-top: 8rpx;
border: 1rpx solid currentColor;
}
.info-card {
position: relative;
padding: 20rpx;
border-radius: 16rpx;
background: white;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.06);
overflow: hidden;
min-height: 160rpx;
}
.info-bg {
position: absolute;
right: 0;
bottom: 0;
width: 120rpx;
height: 120rpx;
opacity: 0.8;
z-index: 0;
}
.info-content {
position: relative;
z-index: 1;
}
.arrow-icon {
width: 32rpx;
height: 32rpx;
}
.h-80 {
height: 160rpx;
}
.h-normal {
height: 1.5em;
}
.min-w-100 {
min-width: 200rpx;
}
.rounded-lg {
border-radius: 16rpx;
}
</style>