<script setup lang="ts">
|
import { fetchMiniFieldConfigs } from '@/api/lookup'
|
import { fetchMyVisitors } from '@/api/visitor'
|
import { FIELD_CODES } from '@/constants/fieldCodes'
|
import type { MiniFieldConfigItem } from '@/types/lookup'
|
import type { MiniVisitorListItem } from '@/types/visitor'
|
|
definePage({
|
name: 'commonVisitors',
|
layout: 'default',
|
style: {
|
navigationStyle: 'custom',
|
},
|
})
|
|
const router = useRouter()
|
const choosePersonAssetBase = '/static/choosePerson'
|
|
const sysInfo = uni.getSystemInfoSync()
|
const statusBarHeight = sysInfo.statusBarHeight || 0
|
const navBarHeight = 44
|
|
const appointmentIcons = {
|
male: '/static/appointment/man.png',
|
female: '/static/appointment/woman.png',
|
company: '/static/appointment/company.png',
|
}
|
|
const visitors = ref<MiniVisitorListItem[]>([])
|
const loading = ref(false)
|
const fieldConfigs = ref<MiniFieldConfigItem[]>([])
|
|
const showName = computed(() => isVisible(FIELD_CODES.VISITOR_NAME))
|
const showGender = computed(() => isVisible(FIELD_CODES.GENDER))
|
const showIdCard = computed(() => isVisible(FIELD_CODES.ID_CARD))
|
const showCompany = computed(() => isVisible(FIELD_CODES.COMPANY))
|
|
function isVisible(code: string) {
|
const config = fieldConfigs.value.find(item => item.fieldCode === code)
|
return config ? config.visible === 1 : true
|
}
|
|
function displayName(item: MiniVisitorListItem) {
|
return showName.value ? item.visitorName || '来访人' : '来访人'
|
}
|
|
function handleEdit(item: MiniVisitorListItem) {
|
uni.navigateTo({
|
url: `/pages/addPerson/index?id=${item.id}&uuid=${item.uuid}`,
|
})
|
}
|
|
function handleBack() {
|
router.back()
|
}
|
|
function handleAdd() {
|
uni.navigateTo({ url: '/pages/addPerson/index' })
|
}
|
|
async function loadVisitors() {
|
loading.value = true
|
try {
|
const [configs, list] = await Promise.all([
|
fetchMiniFieldConfigs(),
|
fetchMyVisitors(),
|
])
|
fieldConfigs.value = configs
|
visitors.value = list
|
}
|
catch (error) {
|
uni.showToast({
|
title: error instanceof Error ? error.message : '加载来访人失败',
|
icon: 'none',
|
})
|
}
|
finally {
|
loading.value = false
|
}
|
}
|
|
onShow(() => {
|
void loadVisitors()
|
})
|
</script>
|
|
<template>
|
<view class="min-h-screen w-full relative box-border bg-[#F6FBFF] overflow-hidden">
|
<image
|
:src="`${choosePersonAssetBase}/bg@2x.png`"
|
class="absolute left-0 top-0 w-full z-0"
|
mode="widthFix"
|
/>
|
|
<view class="relative z-50 w-full" :style="{ height: (statusBarHeight + navBarHeight) + 'px' }">
|
<view class="flex items-center justify-between w-full absolute left-0" :style="{ top: statusBarHeight + 'px', height: navBarHeight + 'px' }">
|
<view class="flex h-full w-[88rpx] items-center justify-center relative z-10" @click="handleBack">
|
<wd-icon name="arrow-left" size="40rpx" color="#ffffff" />
|
</view>
|
<view class="absolute left-0 w-full text-center text-[34rpx] font-medium text-white z-0">
|
常用来访人
|
</view>
|
<view class="w-[88rpx]" />
|
</view>
|
</view>
|
|
<view v-if="!loading && visitors.length === 0" class="absolute top-[268rpx] left-0 w-full z-10 flex flex-col items-center">
|
<image :src="`${choosePersonAssetBase}/noData.png`" class="w-[380rpx] h-[380rpx]" mode="aspectFit" />
|
<text class="text-[28rpx] text-[#B3B3B3]">
|
暂无来访人信息,请先添加~
|
</text>
|
</view>
|
|
<view v-else class="relative z-10 px-[24rpx] pb-[200rpx] mt-[5vh]">
|
<view class="w-full flex flex-col gap-[16rpx]">
|
<view
|
v-for="(item, index) in visitors"
|
:key="item.id"
|
class="relative flex items-center justify-between px-[24rpx] py-[24rpx] bg-white rounded-[8rpx] shadow-[0_4rpx_8rpx_rgba(6,47,108,0.1608)]"
|
>
|
<view class="flex items-center w-[160rpx] shrink-0">
|
<text class="text-[28rpx] text-[#333333] font-medium truncate">{{ displayName(item) }}</text>
|
</view>
|
|
<view class="flex flex-col justify-center flex-1 mx-[20rpx] min-w-0">
|
<view v-if="showGender || showIdCard" class="flex items-center">
|
<image :src="item.gender === '女' ? appointmentIcons.female : appointmentIcons.male" class="w-[32rpx] h-[32rpx] shrink-0" />
|
<text class="ml-[20rpx] text-[28rpx] text-[#B3B3B3] truncate">
|
{{ showIdCard ? (item.idCardMasked || '-') : '-' }}
|
</text>
|
</view>
|
<view v-if="showCompany" class="flex items-center mt-[8rpx]">
|
<image :src="appointmentIcons.company" class="w-[32rpx] h-[32rpx] shrink-0" />
|
<text class="ml-[20rpx] text-[28rpx] text-[#B3B3B3] truncate">{{ item.visitorCompany || '-' }}</text>
|
</view>
|
<text v-if="item.missingFieldCodes?.length" class="mt-[8rpx] text-[22rpx] text-[#F5222D] truncate">
|
缺失:{{ item.missingFieldCodes.join('、') }}
|
</text>
|
</view>
|
|
<view class="w-[40rpx] h-[40rpx] shrink-0 flex items-center justify-center" @click.stop="handleEdit(item)">
|
<image :src="`${choosePersonAssetBase}/edit.png`" class="w-[33rpx] h-[33rpx]" />
|
</view>
|
</view>
|
</view>
|
</view>
|
|
<view class="fixed bottom-[48rpx] left-0 w-full px-[32rpx] box-border z-[100]">
|
<view class="h-[96rpx] rounded-full bg-[#0068FF] flex items-center justify-center shadow-[0_8rpx_24rpx_rgba(0,104,255,0.2)]" @click="handleAdd">
|
<text class="text-[32rpx] text-white font-medium">添加来访人</text>
|
</view>
|
</view>
|
</view>
|
</template>
|
|
<style scoped>
|
</style>
|