This commit is contained in:
zjf committed 2025-04-15 17:27:23 +08:00
1 parent 3d48021257
commit a866ac71c0
6 files changed
+21741

No files matched your search

+21333
View File
File diff suppressed because it is too large. Load diff
+11
View File
@@ -340,6 +340,17 @@
}
}
]
},
{
"root": "pages/integrated",
"pages": [
{
"path": "visitor/myvisitor",
"style": {
"navigationBarTitleText": "访客记录"
}
}
]
}
],
"globalStyle": {
+343
View File
@@ -0,0 +1,343 @@
<template>
<view class="visitor-list">
<!-- 顶部标签页 -->
<view class="tabs">
<view
v-for="(tab, index) in tabs"
:key="index"
class="tab-item"
:class="{ active: currentTab === index }"
@tap="switchTab(index)"
>
<text>{{ tab }}</text>
</view>
</view>
<!-- 访客记录列表 -->
<scroll-view
scroll-y
class="list-content"
@scrolltolower="loadMore"
>
<view
v-for="(item, index) in visitorList"
:key="index"
class="visitor-item"
>
<view class="item-header">
<text class="visit-time">{{ item.visitTime }}</text>
<text :class="['status-tag', getStatusClass(item.status)]">{{ getStatusText(item.status) }}</text>
</view>
<view class="item-content">
<view class="info-row">
<text class="label">拜访部门:</text>
<text class="value">{{ item.deptName }}</text>
</view>
<view class="info-row">
<text class="label">拜访人:</text>
<text class="value">{{ item.name }}</text>
</view>
<view class="info-row">
<text class="label">手机号:</text>
<text class="value">{{ item.mobile }}</text>
</view>
</view>
<view class="item-footer" v-if="item.status === '0' || item.status === '1'">
<view class="cancel-btn" @tap="handleCancel(item)">取消</view>
</view>
</view>
<!-- 加载状态 -->
<view v-if="loading" class="loading">加载中...</view>
<view v-if="!loading && !hasMore" class="no-more">没有更多数据了</view>
</scroll-view>
</view>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue'
// 标签页配置
const tabs = ['全部', '待审核', '待到访', '已到访']
const currentTab = ref(0)
// 列表数据
const visitorList = ref<any[]>([])
const loading = ref(false)
const hasMore = ref(true)
const page = ref(1)
const pageSize = 10
// 切换标签页
const switchTab = (index: number) => {
if (currentTab.value === index) return
currentTab.value = index
page.value = 1
visitorList.value = []
hasMore.value = true
getVisitorList()
}
// 获取访客记录列表
const getVisitorList = async () => {
if (loading.value || !hasMore.value) return
loading.value = true
try {
// TODO: 替换为实际的API调用
const res = await mockFetchData()
if (page.value === 1) {
visitorList.value = res.list
} else {
visitorList.value.push(...res.list)
}
hasMore.value = res.list.length === pageSize
page.value++
} catch (error) {
console.error('获取访客记录失败:', error)
uni.showToast({
title: '获取数据失败',
icon: 'none'
})
} finally {
loading.value = false
}
}
// 加载更多
const loadMore = () => {
getVisitorList()
}
// 获取状态文本
const getStatusText = (status: string) => {
const statusMap: Record<string, string> = {
'0': '待审核',
'1': '待到访',
'2': '已到访',
'3': '已过期'
}
return statusMap[status] || status
}
// 获取状态样式类
const getStatusClass = (status: string) => {
const statusClassMap: Record<string, string> = {
'0': 'status-pending',
'1': 'status-waiting',
'2': 'status-visited',
'3': 'status-expired'
}
return statusClassMap[status] || ''
}
// 模拟数据获取
const mockFetchData = () => {
return new Promise((resolve) => {
setTimeout(() => {
resolve({
list: [
{
visitTime: '2023/02/13 周一 11:00',
status: '0',
deptName: 'XXXX丁地1',
name: 'AAA',
mobile: '13590291111'
},
{
visitTime: '2023/02/13 周一 08:00',
status: '1',
deptName: 'XXXX丁地2',
name: 'BBB',
mobile: '13090291111'
},
// 更多数据...
]
})
}, 500)
})
}
// 添加取消方法
const handleCancel = (item: any) => {
uni.showModal({
title: '提示',
content: '确定要取消此次预约吗?',
success: async (res) => {
if (res.confirm) {
try {
// TODO: 调用取消预约的接口
// const result = await cancelVisit(item.id)
uni.showToast({
title: '取消成功',
icon: 'success'
})
// 刷新列表
page.value = 1
visitorList.value = []
getVisitorList()
} catch (error) {
uni.showToast({
title: '取消失败',
icon: 'none'
})
}
}
}
})
}
onMounted(() => {
getVisitorList()
})
</script>
<style lang="scss" scoped>
.visitor-list {
min-height: 100vh;
background: #F7F8FA;
}
.tabs {
display: flex;
background: #fff;
padding: 0 32rpx;
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 1;
}
.tab-item {
flex: 1;
height: 88rpx;
display: flex;
align-items: center;
justify-content: center;
font-size: 28rpx;
color: #666;
position: relative;
&.active {
color: #1989FA;
font-weight: 500;
&::after {
content: '';
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%);
width: 40rpx;
height: 4rpx;
background: #1989FA;
border-radius: 2rpx;
}
}
}
.list-content {
padding: 108rpx 32rpx 32rpx;
}
.visitor-item {
background: #fff;
border-radius: 12rpx;
padding: 24rpx;
margin-bottom: 20rpx;
.item-content {
margin: 20rpx 0;
}
}
.item-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20rpx;
}
.visit-time {
font-size: 28rpx;
color: #333;
font-weight: 500;
}
.status-tag {
font-size: 24rpx;
padding: 4rpx 16rpx;
border-radius: 4rpx;
&.status-pending {
color: #1989FA;
background: rgba(25, 137, 250, 0.1);
}
&.status-waiting {
color: #FF9900;
background: rgba(255, 153, 0, 0.1);
}
&.status-visited {
color: #07C160;
background: rgba(7, 193, 96, 0.1);
}
&.status-expired {
color: #999;
background: rgba(153, 153, 153, 0.1);
}
}
.info-row {
display: flex;
margin-bottom: 16rpx;
&:last-child {
margin-bottom: 0;
}
.label {
font-size: 26rpx;
color: #666;
width: 140rpx;
}
.value {
font-size: 26rpx;
color: #333;
flex: 1;
}
}
.item-footer {
margin-top: 20rpx;
padding-top: 20rpx;
border-top: 1rpx solid #F5F5F5;
display: flex;
justify-content: flex-end;
}
.cancel-btn {
padding: 12rpx 32rpx;
border: 1rpx solid #DCDEE0;
border-radius: 32rpx;
font-size: 26rpx;
color: #666;
&:active {
opacity: 0.8;
}
}
.loading, .no-more {
text-align: center;
font-size: 24rpx;
color: #999;
padding: 20rpx 0;
}
</style>
+1
View File
@@ -77,6 +77,7 @@ const state = reactive<{
// { text: "跨单位就餐", icon: "/static/icon/service_1.png", router: "/pages/apply/stride-list" },
{ text: "人脸管理", icon: "/static/icon/service_5.png", router: "/pages/human-face/list" },
{ text: "访客", icon: "/static/icon/service_5.png", router: "/pages/integrated/visitor/index" },
{ text: "访客记录", icon: "/static/icon/service_5.png", router: "/pages/integrated/visitor/myvisitor" },
// { text: "意见反馈", icon: "/static/icon/service_5.png", router: "/pages/integrated/feedback/index" }
],
appInfo: "",
+26
View File
@@ -0,0 +1,26 @@
import request from '@/sheep/utils/request'
const deptApi = {
// 获取部门树形数据
getSimpleTree: () =>
request({
url: "/admin/dept/simpleTree",
method: "GET",
custom: {
showLoading: false,
},
}),
// 获取部门下的用户列表
getUserList: (deptId: string) =>
request({
url: "/admin/user/getUserIdListByDeptId",
method: "GET",
params: { deptId },
custom: {
showLoading: false,
},
}),
}
export default deptApi
+27
View File
@@ -0,0 +1,27 @@
import request from '@/sheep/utils/request'
const visitorApi = {
// 保存访客信息
save: (data: any) =>
request({
url: "/integrated/visitors/app/save",
method: "POST",
data,
custom: {
showLoading: false,
},
}),
// 获取部门树形数据
getSimpleTree: () =>
request({
url: "/admin/dept/simpleTree",
method: "GET",
custom: {
showLoading: false,
},
}),
}
export default visitorApi