init
This commit is contained in:
269
components/VisitorDetailModal.vue
Normal file
269
components/VisitorDetailModal.vue
Normal 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>
|
64
components/headnavbar/index.vue
Normal file
64
components/headnavbar/index.vue
Normal 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>
|
Reference in New Issue
Block a user