This commit is contained in:
2025-08-14 11:50:11 +08:00
commit d488db04bc
242 changed files with 34863 additions and 0 deletions

View File

@@ -0,0 +1,269 @@
<template>
<!-- 弹窗容器 -->
<view class="visitor-modal" v-if="visible">
<!-- 遮罩层点击关闭 -->
<view class="modal-mask" @click="closeModal"></view>
<!-- 弹窗内容阻止遮罩层事件穿透 -->
<view class="modal-dialog" @click.stop>
<!-- 头部标题 + 关闭按钮 -->
<view class="dialog-header">
<text class="dialog-title">访客详情</text>
<text class="dialog-close" @click="closeModal">×</text>
</view>
<!-- 主体信息展示 -->
<view class="dialog-body">
<view class="info-item">
<text class="item-label">访客姓名</text>
<text class="item-value">{{ visitorInfo.visitorName || '无' }}</text>
</view>
<view class="info-item">
<text class="item-label">访客电话</text>
<text class="item-value">{{ visitorInfo.visitorPhone || '无' }}</text>
</view>
<view class="info-item">
<text class="item-label">所属公司</text>
<text class="item-value">{{ visitorInfo.visitorUnit || '无' }}</text>
</view>
<view class="info-item">
<text class="item-label">被访人</text>
<text class="item-value">{{ visitorInfo.interviewedPerson || '无' }}</text>
</view>
<view class="info-item">
<text class="item-label">联系电话</text>
<text class="item-value">{{ visitorInfo.interviewedPhone || '无' }}</text>
</view>
<view class="info-item">
<text class="item-label">被访单位</text>
<text class="item-value">{{ visitorInfo.interviewedUnit || '无' }}</text>
</view>
<view class="info-item">
<text class="item-label">拜访事由</text>
<text class="item-value">{{ visitorInfo.visitingReason || '无' }}</text>
</view>
<view class="info-item">
<text class="item-label">拜访时间</text>
<text class="item-value">{{ visitorInfo.visitingBeginTime || '无' }}</text>
</view>
<view class="info-item">
<text class="item-label">是否预约车位</text>
<text class="item-value">{{ visitorInfo.bookingParkingSpace ? '是' : '否' }}</text>
</view>
<view class="info-item">
<text class="item-label">预约状态</text>
<text
class="item-value status-tag"
:class="{
'status-confirmed': visitorInfo.serveStatus === 1,
'status-pending': visitorInfo.serveStatus === 0,
'status-rejected': visitorInfo.serveStatus === 2
}"
>
{{ formatServeStatus(visitorInfo.serveStatus) }}
</text>
</view>
<view class="info-item">
<text class="item-label">提交时间</text>
<text class="item-value">{{ visitorInfo.createTime || '无' }}</text>
</view>
</view>
<!-- 底部审核操作仅待确认时显示 -->
<view class="dialog-footer" v-if="showActionButtons">
<button
class="audit-btn reject"
@click="handleAudit('reject')"
:loading="loading"
>
{{ loading && auditType === 'reject' ? '驳回中...' : '驳回' }}
</button>
<button
class="audit-btn confirm"
@click="handleAudit('confirm')"
:loading="loading"
>
{{ loading && auditType === 'confirm' ? '确认中...' : '确认' }}
</button>
</view>
</view>
</view>
</template>
<script>
export default {
props: {
// 是否显示弹窗
visible: {
type: Boolean,
default: false
},
// 访客数据
visitorInfo: {
type: Object,
default: () => ({})
},
// 是否显示审核按钮(默认仅“待确认”显示)
showActionButtons: {
type: Boolean,
default: false
}
},
data() {
return {
loading: false, // 审核按钮加载状态
auditType: '' // 记录当前审核类型(确认/驳回)
}
},
methods: {
// 关闭弹窗
closeModal() {
this.$emit('close');
},
// 处理审核操作
handleAudit(type) {
this.loading = true;
this.auditType = type;
// 模拟接口请求(实际替换为真实接口)
setTimeout(() => {
this.loading = false;
this.closeModal(); // 关闭弹窗
// 通知父组件更新状态
this.$emit('audit', {
type: type,
visitorId: this.visitorInfo.id // 传递访客ID
});
// 提示用户
uni.showToast({
title: type === 'confirm' ? '确认成功' : '驳回成功',
icon: 'success'
});
}, 1500);
},
// 格式化服务状态
formatServeStatus(status) {
switch (status) {
case 0: return '待确认';
case 1: return '已确认';
case 2: return '已驳回';
default: return '未知';
}
}
}
}
</script>
<style scoped>
/* 弹窗容器 */
.visitor-modal {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
display: flex;
justify-content: flex-end;
align-items: flex-end;
z-index: 999;
}
/* 遮罩层 */
.modal-mask {
position: absolute;
width: 100%;
height: 100%;
}
/* 弹窗内容 */
.modal-dialog {
width: 100%;
background: #fff;
border-radius: 16px 16px 0 0;
overflow: hidden;
transform: translateY(100%);
animation: slideUp 0.3s forwards;
}
/* 弹窗滑入动画 */
@keyframes slideUp {
to {
transform: translateY(0);
}
}
/* 头部 */
.dialog-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 16px;
background: #f8f8f8;
border-bottom: 1px solid #eee;
}
.dialog-title {
font-size: 17px;
font-weight: bold;
}
.dialog-close {
font-size: 24px;
color: #999;
}
/* 主体内容 */
.dialog-body {
padding: 16px;
}
.info-item {
display: flex;
align-items: center;
margin-bottom: 12px;
}
.item-label {
width: 80px;
color: #666;
}
.item-value {
flex: 1;
color: #333;
}
.status-tag {
padding: 2px 8px;
border-radius: 4px;
color: #fff;
}
.status-pending {
background: #ff9900;
}
.status-confirmed {
background: #52c41a;
}
.status-rejected {
background: #ff4d4f;
}
/* 底部操作 */
.dialog-footer {
display: flex;
padding: 16px;
border-top: 1px solid #eee;
}
.audit-btn {
flex: 1;
margin: 0 8px;
padding: 12px 0;
border-radius: 8px;
color: #fff;
}
.reject {
background: #ff4d4f;
}
.confirm {
background: #52c41a;
}
</style>

View File

@@ -0,0 +1,64 @@
<template>
<view class="wrap wrap-home">
<u-navbar :title="title" height="44" :is-back="false">
<!-- #ifdef APP-PLUS --><!-- #endif -->
<view slot="right">
<view style="color: #22262d;font-size: 20px;" class="iconfont icon-setting-two" @click="navTo('/pages/sys/user/setting')"></view>
</view>
<u-avatar class="home-head" :src="avatarUrl" @click="show = true"></u-avatar>
</u-navbar>
</view>
</template>
<script>
export default {
props: {
title: {
type: String,
required: true
}
},
data() {
return {
src: '',
show: false,
};
},
onLoad() {
},
computed: {
avatarUrl() {
var url = this.vuex_config.baseUrl + this.vuex_user.avatar || '/static/aidex/tabbar/my_2.png';
url = this.replaceAll(url,'\\','/');
return url + '?t=' + new Date().getTime();
}
},
methods: {
showPersonalInfo() {
this.show = true
},
navTo(url) {
uni.navigateTo({
url: url
});
}
}
};
</script>
<style lang="scss">
.slot-wrap {
display: flex;
align-items: center;
/* 如果您想让slot内容占满整个导航栏的宽度 */
/* flex: 1; */
/* 如果您想让slot内容与导航栏左右有空隙 */
/* padding: 0 30rpx; */
}
page {
background-color: #ffffff;
}
</style>