SmartParks_uniapp/pages/sys/user/myVisitor/myVisitor.vue

460 lines
12 KiB
Vue
Raw 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>
<view class="visitor-container">
<!-- tab栏 -->
<view class="visitor-tabs">
<view v-for="(tab, idx) in tabs" :key="idx" :class="['visitor-tab', {active: idx === activeTab}]"
@click="changeTab(idx)">
{{ tab }}
<view v-if="idx === activeTab" class="tab-underline"></view>
</view>
</view>
<!-- 列表区 -->
<view class="visitor-list">
<view v-for="(item, idx) in list" :key="idx" class="visitor-card" @click="showVisitorDetail(item)">
<view class="card-row">
<view class="card-type">{{ item.type }}</view>
<view class="card-status" :class="item.statusClass">{{ item.status }}</view>
</view>
<view class="card-info">{{ item.name }}
<text class="card-phone">{{ item.phone }}</text>
<text class="card-divider"></text>
<text class="card-address">{{ item.address }}</text>
</view>
<view class="card-time">{{ item.time }}</view>
</view>
</view>
<!-- 底部按钮 -->
<button class="visitor-btn-fixed" @click="goCreateVisitor">访客邀约</button>
<view v-if="showDetail" class="visitor-detail-mask" @click.self="closeVisitorDetail">
<view class="visitor-detail-dialog">
<view class="visitor-detail-title-row">
<text class="visitor-detail-title">访客详情</text>
<image src="/static/ic_close_01.png" class="visitor-detail-close" @click="closeVisitorDetail" />
</view>
<view class="visitor-detail-info">
<view>{{ detailData.name }} {{ detailData.phone }}</view>
<view>{{ detailData.idCard || '5021119740208****' }}</view>
<view>车牌号:{{ detailData.carNumber || '渝A·H1455' }}</view>
<view>来访时间:{{ detailData.time }}</view>
<view>访问地址:{{ detailData.address || '服务中心1栋8楼6871' }}</view>
<image :src="detailData.statusClass === 'orange' ? '/static/ic_my_visitor_01.png' : '/static/ic_my_visitor_02.png'" class="visitor-detail-status-img" />
</view>
<button class="visitor-detail-btn">修改</button>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
tabs: ['我的预约', '我的邀约', '全部记录'],
activeTab: 1,
tabData: [
[],
[],
[]
], // 每个tab的数据
tabLoaded: [false, false, false], // 每个tab是否已加载
loading: false,
showDetail: false,
detailData: {},
}
},
computed: {
list() {
return this.tabData[this.activeTab];
}
},
created() {
this.loadTabData(this.activeTab); // 初始化加载当前tab数据
},
methods: {
goBack() {
uni.navigateBack();
},
goCreateVisitor() {
uni.navigateTo({
url: '/pages/sys/user/myVisitor/creatVisitor'
});
},
async changeTab(idx) {
this.activeTab = idx;
if (!this.tabLoaded[idx]) {
await this.loadTabData(idx);
}
},
async loadTabData(idx) {
this.loading = true;
// 模拟接口请求不同tab返回不同mock数据
let data = [];
if (idx === 0) {
data = [{
type: '商务合作',
status: '待处理',
statusClass: 'orange',
name: '张小晓',
phone: '18725468789',
address: '8栋2楼309',
time: '2025-07-06 15:28:16'
},
{
type: '送货上门',
status: '已到访',
statusClass: 'green',
name: '张小晓',
phone: '18725468789',
address: '8栋2楼309',
time: '2025-07-06 15:28:16'
},
{
type: '送货上门',
status: '未到访',
statusClass: 'green',
name: '张小晓',
phone: '18725468789',
address: '8栋2楼309',
time: '2025-07-06 15:28:16'
},
{ type: '商务合作', status: '待处理', statusClass: 'orange', name: '刘小备', phone: '18725468789', address: '8栋2楼309', time: '2025-07-06 15:28:16' },
{ type: '送货上门', status: '已到访', statusClass: 'green', name: '关小羽', phone: '18725468789', address: '8栋2楼309', time: '2025-07-06 15:28:16' },
{ type: '送货上门', status: '未到访', statusClass: 'green', name: '张小飞', phone: '18725468789', address: '8栋2楼309', time: '2025-07-06 15:28:16' },
{ type: '商务合作', status: '待处理', statusClass: 'orange', name: '曹小操', phone: '18725468789', address: '8栋2楼309', time: '2025-07-06 15:28:16' },
{ type: '送货上门', status: '已到访', statusClass: 'green', name: '孙小权', phone: '18725468789', address: '8栋2楼309', time: '2025-07-06 15:28:16' },
{ type: '送货上门', status: '未到访', statusClass: 'green', name: '周小瑜', phone: '18725468789', address: '8栋2楼309', time: '2025-07-06 15:28:16' }
];
} else if (idx === 1) {
data = [{
type: '商务合作',
status: '待处理',
statusClass: 'orange',
name: '李明',
phone: '13812345678',
address: '5栋1楼101',
time: '2025-07-07 10:00:00'
},
{
type: '送货上门',
status: '已到访',
statusClass: 'green',
name: '王五',
phone: '13987654321',
address: '6栋3楼202',
time: '2025-07-07 11:00:00'
},
{ type: '商务合作', status: '待处理', statusClass: 'orange', name: '赵六', phone: '13812345678', address: '5栋1楼101', time: '2025-07-07 10:00:00' },
{ type: '送货上门', status: '已到访', statusClass: 'green', name: '钱七', phone: '13987654321', address: '6栋3楼202', time: '2025-07-07 11:00:00' },
{ type: '商务合作', status: '待处理', statusClass: 'orange', name: '孙八', phone: '13812345678', address: '5栋1楼101', time: '2025-07-07 10:00:00' },
{ type: '送货上门', status: '已到访', statusClass: 'green', name: '周九', phone: '13987654321', address: '6栋3楼202', time: '2025-07-07 11:00:00' }
];
} else {
data = [{
type: '商务合作',
status: '已结束',
statusClass: 'gray',
name: '张小晓',
phone: '18725468789',
address: '8栋2楼309',
time: '2025-07-06 15:28:16'
},
{
type: '送货上门',
status: '已结束',
statusClass: 'gray',
name: '李明',
phone: '13812345678',
address: '5栋1楼101',
time: '2025-07-07 10:00:00'
},
{
type: '送货上门',
status: '已结束',
statusClass: 'gray',
name: '王五',
phone: '13987654321',
address: '6栋3楼202',
time: '2025-07-07 11:00:00'
},
{ type: '商务合作', status: '已结束', statusClass: 'gray', name: '张小晓', phone: '18725468789', address: '8栋2楼309', time: '2025-07-06 15:28:16' },
{ type: '送货上门', status: '已结束', statusClass: 'gray', name: '李明', phone: '13812345678', address: '5栋1楼101', time: '2025-07-07 10:00:00' },
{ type: '送货上门', status: '已结束', statusClass: 'gray', name: '王五', phone: '13987654321', address: '6栋3楼202', time: '2025-07-07 11:00:00' },
{ type: '商务合作', status: '已结束', statusClass: 'gray', name: '张小晓', phone: '18725468789', address: '8栋2楼309', time: '2025-07-06 15:28:16' },
{ type: '送货上门', status: '已结束', statusClass: 'gray', name: '李明', phone: '13812345678', address: '5栋1楼101', time: '2025-07-07 10:00:00' },
{ type: '送货上门', status: '已结束', statusClass: 'gray', name: '王五', phone: '13987654321', address: '6栋3楼202', time: '2025-07-07 11:00:00' }
];
}
// 模拟网络延迟
await new Promise(res => setTimeout(res, 300));
this.$set(this.tabData, idx, data);
this.$set(this.tabLoaded, idx, true);
this.loading = false;
},
showVisitorDetail(item) {
this.detailData = item;
this.showDetail = true;
},
closeVisitorDetail() {
this.showDetail = false;
}
}
}
</script>
<style scoped>
.visitor-container {
height: 100vh;
background: #f7f7f7;
display: flex;
flex-direction: column;
}
.visitor-navbar {
width: 100%;
height: 120rpx;
padding-top: 40rpx;
display: flex;
align-items: center;
justify-content: center;
position: relative;
background: #fff;
flex-shrink: 0; /* 防止被压缩 */
}
.visitor-back {
position: absolute;
left: 37rpx;
width: 15rpx;
height: 33rpx;
}
.visitor-title {
font-size: 36rpx;
color: #000;
}
.visitor-tabs {
display: flex;
align-items: center;
justify-content: space-around;
background: #fff;
height: 80rpx;
border-bottom: 1px solid #f0f0f0;
flex-shrink: 0; /* 防止被压缩 */
}
.visitor-tab {
flex: 1;
text-align: center;
font-size: 30rpx;
color: #888;
position: relative;
font-weight: 500;
padding: 0 0 10rpx 0;
/* tab点击事件 */
cursor: pointer;
}
.visitor-tab.active {
color: #2186FF;
font-weight: bold;
}
.tab-underline {
width: 60rpx;
height: 6rpx;
background: #2186FF;
border-radius: 3rpx;
margin: 0 auto;
margin-top: 8rpx;
}
.visitor-list {
margin: 25rpx 0 0 0;
padding: 0 35rpx;
flex: 1; /* 占据所有剩余空间 */
overflow-y: auto; /* 内容超出时,开启垂直滚动 */
padding-bottom: 200rpx; /* 为底部按钮留出空间 */
}
.visitor-card {
background: #fff;
border-radius: 16rpx;
margin-bottom: 24rpx;
padding: 20rpx 40rpx 70rpx 12rpx;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.03);
}
.card-row {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 28rpx;
}
.card-type {
font-weight: 600;
font-size: 26rpx;
padding: 10rpx 45rpx 10rpx 12rpx;
border-radius: 15rpx;
color: #fff;
background: linear-gradient(90deg, #007CFF 0%, #FFFFFF 100%);
display: inline-block;
}
.card-status {
font-size: 28rpx;
}
.card-status.orange {
color: #F3831F;
}
.card-status.green {
color: #07C78E;
}
.card-status.gray {
color: #8F8F8F;
}
.card-info {
font-size: 26rpx;
color: #333;
margin-bottom: 8rpx;
display: flex;
align-items: center;
}
.card-phone {
margin: 0 8rpx 0 8rpx;
}
.card-divider {
width: 1rpx;
height: 40rpx;
background: #DCDCDC;
display: inline-block;
margin: 0 12rpx;
vertical-align: middle;
content: '';
}
.card-address {
margin-left: 0;
}
.card-time {
font-size: 28rpx;
color: #626262;
}
.visitor-btn {
width: 90vw;
height: 80rpx;
background: #0090FF;
color: #fff;
font-size: 32rpx;
border: none;
border-radius: 40rpx;
margin: 60rpx auto 0 auto;
display: block;
font-weight: bold;
box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.18);
}
.visitor-btn-fixed {
position: fixed;
left: 0;
right: 0;
bottom: 100rpx;
margin: 0 auto;
width: 90vw;
height: 80rpx;
background: #0090FF;
color: #fff;
font-size: 32rpx;
border: none;
border-radius: 40rpx;
display: block;
font-weight: bold;
box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.18);
z-index: 99;
}
.visitor-detail-mask {
position: fixed;
left: 0;
top: 0;
width: 100vw;
height: 100vh;
background: rgba(0,0,0,0.5);
z-index: 9999;
display: flex;
align-items: center;
justify-content: center;
}
.visitor-detail-dialog {
width: 66vw;
background: #fff;
border-radius: 36rpx;
box-shadow: 0 8rpx 32rpx rgba(0,0,0,0.12);
padding: 48rpx 36rpx 36rpx 36rpx;
position: relative;
display: flex;
flex-direction: column;
align-items: center;
}
.visitor-detail-title-row {
width: 100%;
display: flex;
align-items: center;
justify-content: center;
position: relative;
margin-bottom: 52rpx;
}
.visitor-detail-title {
font-size: 36rpx;
color: #000;
}
.visitor-detail-close {
position: absolute;
right: 0;
top: 0;
width: 22rpx;
height: 22rpx;
}
.visitor-detail-info {
width: 100%;
font-size: 28rpx;
color: #222;
margin-bottom: 80rpx;
display: flex;
flex-direction: column;
gap: 28rpx;
position: relative;
}
.visitor-detail-status-img {
position: absolute;
right: 0;
bottom: -40rpx;
width: 160rpx;
height: 160rpx;
z-index: 1;
pointer-events: none;
}
.visitor-detail-btn {
width: 320rpx;
height: 80rpx;
background: linear-gradient(90deg, #0090FF 0%, #2E9FFF 100%);
color: #fff;
font-size: 32rpx;
border: none;
border-radius: 40rpx;
margin-bottom: 30rpx;
display: block;
font-weight: bold;
box-shadow: 0 8rpx 24rpx rgba(0,0,0,0.18);
}
</style>