303 lines
7.9 KiB
Vue
303 lines
7.9 KiB
Vue
<!-- 物业日常 - 打卡记录页面 -->
|
||
<template>
|
||
<s-layout title="物业日常" :bgStyle="{ backgroundColor:'#F8EDE8' }" navbar="inner" color="#333333">
|
||
<view class="daily-page">
|
||
<!-- 渐变背景装饰 -->
|
||
<view class="gradient-bg"></view>
|
||
|
||
<!-- 固定头部区域:搜索栏 -->
|
||
<view class="page-header">
|
||
<view class="search-wrapper">
|
||
<view class="search-box">
|
||
<image class="search-icon" src="/static/img/guest.png" mode="aspectFit" />
|
||
<input class="search-input" type="text" placeholder="搜索" placeholder-class="search-placeholder" />
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 网格内容区 - 独立滚动 -->
|
||
<scroll-view scroll-y class="content-scroll" :style="{ height: scrollHeight + 'px' }" @scrolltolower="loadMore">
|
||
<view class="grid-container">
|
||
<view
|
||
v-for="(item, index) in dataList"
|
||
:key="item.id"
|
||
class="card-item"
|
||
@tap="handleCardTap(item)"
|
||
>
|
||
<!-- 图片区域 + 底部水印遮罩 -->
|
||
<view class="card-img-wrap">
|
||
<image class="card-img" :src="item.image" mode="aspectFill" />
|
||
<!-- 底部渐变遮罩 + 打卡信息 -->
|
||
<view class="card-overlay">
|
||
<view class="overlay-info">
|
||
<!-- 第一行:打卡人姓名 + 时间 -->
|
||
<view class="info-row row-name">
|
||
<image class="row-icon" src="/static/img/login_img.png" mode="aspectFill" />
|
||
<text class="info-name">{{ item.userName }}</text>
|
||
<text class="info-time">{{ item.time }}</text>
|
||
</view>
|
||
<!-- 第二行:打卡地点 -->
|
||
<view class="info-row row-addr">
|
||
<image class="row-icon" src="/static/img/guest.png" mode="aspectFit" />
|
||
<text class="info-addr">{{ item.address }}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</scroll-view>
|
||
|
||
<!-- 右下角悬浮相机按钮 - 仅物业人员可见 -->
|
||
<view v-if="isStaff" class="fab-camera" @tap="handleCameraTap">
|
||
<image class="camera-img" src="/static/img/login_img.png" mode="aspectFit" />
|
||
</view>
|
||
</view>
|
||
</s-layout>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { ref, onMounted, nextTick, getCurrentInstance } from 'vue';
|
||
|
||
// ==================== 数据定义 ====================
|
||
|
||
// scroll-view 滚动高度(单位 px)
|
||
const scrollHeight = ref(0);
|
||
|
||
// 当前登录用户身份(true=物业人员,false=普通业主)
|
||
const isStaff = ref(true);
|
||
|
||
// 模拟打卡数据列表(来自绑定小区的物业人员打卡记录)
|
||
const dataList = ref([
|
||
{ id: 1, image: 'https://picsum.photos/400/500?random=1', userName: '吴仁贵', time: '2026/01/08 14:52', address: '融侨馨苑12号楼' },
|
||
{ id: 2, image: 'https://picsum.photos/400/480?random=2', userName: '张伟', time: '2026/01/08 15:20', address: '融侨馨苑3号楼' },
|
||
{ id: 3, image: 'https://picsum.photos/400/520?random=3', userName: '李明', time: '2026/01/08 16:05', address: '融侨馨苑8号楼' },
|
||
{ id: 4, image: 'https://picsum.photos/400/490?random=4', userName: '王芳', time: '2026/01/09 09:10', address: '融侨馨苑5号楼' },
|
||
{ id: 5, image: 'https://picsum.photos/400/510?random=5', userName: '赵强', time: '2026/01/09 11:30', address: '融侨馨苑11号楼' },
|
||
{ id: 6, image: 'https://picsum.photos/400/500?random=6', userName: '吴仁贵', time: '2026/01/09 14:00', address: '融侨馨苑12号楼' }
|
||
]);
|
||
|
||
// ==================== 生命周期 ====================
|
||
|
||
onMounted(() => {
|
||
calcScrollHeight();
|
||
});
|
||
|
||
// ==================== 方法 ====================
|
||
|
||
/** 动态计算 scroll-view 高度 */
|
||
function calcScrollHeight() {
|
||
const instance = getCurrentInstance();
|
||
nextTick(() => {
|
||
const sysInfo = uni.getSystemInfoSync();
|
||
uni.createSelectorQuery()
|
||
.in(instance)
|
||
.select('.page-header')
|
||
.boundingClientRect((rect) => {
|
||
if (rect) {
|
||
scrollHeight.value = sysInfo.windowHeight - rect.height - rect.top;
|
||
}
|
||
})
|
||
.exec();
|
||
});
|
||
}
|
||
|
||
/** 点击卡片 - 查看详情 */
|
||
function handleCardTap(item) {
|
||
console.log('查看打卡详情:', item);
|
||
uni.showToast({ title: `查看${item.userName}的打卡记录`, icon: 'none' });
|
||
}
|
||
|
||
/** 物业人员拍照打卡 */
|
||
function handleCameraTap() {
|
||
// 调起相机拍照
|
||
uni.chooseImage({
|
||
count: 1,
|
||
sourceType: ['camera'],
|
||
success: (res) => {
|
||
const tempPath = res.tempFilePaths[0];
|
||
// TODO: 上传图片并创建打卡记录(含水印:姓名、时间、地址)
|
||
uni.showLoading({ title: '上传中...' });
|
||
setTimeout(() => {
|
||
uni.hideLoading();
|
||
uni.showToast({ title: '打卡成功', icon: 'success' });
|
||
// 刷新列表(实际项目中重新请求接口)
|
||
}, 1500);
|
||
},
|
||
fail: () => {
|
||
// 用户取消拍照,不做处理
|
||
}
|
||
});
|
||
}
|
||
|
||
/** 加载更多 */
|
||
function loadMore() {
|
||
console.log('加载更多打卡记录');
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
/* 页面容器 */
|
||
.daily-page {
|
||
position: relative;
|
||
min-height: 100vh;
|
||
}
|
||
|
||
/* 渐变背景 */
|
||
.gradient-bg {
|
||
position: absolute;
|
||
top: -176rpx;
|
||
left: 0;
|
||
right: 0;
|
||
height: calc(100% + 176rpx);
|
||
background: linear-gradient(180deg, #F8EDE8 0%, #FFFFFF 30%);
|
||
z-index: -1;
|
||
}
|
||
|
||
/* 固定头部(搜索栏) */
|
||
.page-header {
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
/* 搜索栏 */
|
||
.search-wrapper {
|
||
padding: 24rpx 32rpx;
|
||
|
||
.search-box {
|
||
display: flex;
|
||
align-items: center;
|
||
height: 72rpx;
|
||
background-color: #FFFFFF;
|
||
border-radius: 36rpx;
|
||
padding: 0 28rpx;
|
||
|
||
.search-icon {
|
||
width: 32rpx;
|
||
height: 32rpx;
|
||
margin-right: 16rpx;
|
||
}
|
||
|
||
.search-input {
|
||
flex: 1;
|
||
font-size: 28rpx;
|
||
color: #333333;
|
||
}
|
||
|
||
:deep(.search-placeholder) {
|
||
color: #999999;
|
||
font-size: 28rpx;
|
||
}
|
||
}
|
||
}
|
||
|
||
/* 列表滚动区域 */
|
||
.content-scroll {
|
||
width: 100%;
|
||
}
|
||
|
||
/* 双列网格容器 */
|
||
.grid-container {
|
||
display: grid;
|
||
grid-template-columns: repeat(2, 1fr);
|
||
gap: 20rpx;
|
||
padding: 0 24rpx 160rpx;
|
||
}
|
||
|
||
/* 卡片 */
|
||
.card-item {
|
||
background-color: #FFFFFF;
|
||
border-radius: 20rpx;
|
||
overflow: hidden;
|
||
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.06);
|
||
|
||
/* 图片容器 */
|
||
.card-img-wrap {
|
||
width: 100%;
|
||
height: 420rpx;
|
||
position: relative;
|
||
|
||
.card-img {
|
||
width: 100%;
|
||
height: 100%;
|
||
display: block;
|
||
}
|
||
|
||
/* 底部渐变遮罩层 */
|
||
.card-overlay {
|
||
position: absolute;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
padding: 20rpx 16rpx 14rpx;
|
||
background: linear-gradient(to top, rgba(0, 0, 0, 0.65) 0%, transparent 100%);
|
||
}
|
||
}
|
||
}
|
||
|
||
/* 遮罩内信息区 */
|
||
.overlay-info {
|
||
.info-row {
|
||
display: flex;
|
||
align-items: center;
|
||
|
||
&:not(:last-child) {
|
||
margin-bottom: 8rpx;
|
||
}
|
||
|
||
.row-icon {
|
||
width: 24rpx;
|
||
height: 24rpx;
|
||
border-radius: 50%;
|
||
margin-right: 8rpx;
|
||
flex-shrink: 0;
|
||
}
|
||
}
|
||
|
||
/* 第一行:姓名 + 时间 */
|
||
.row-name {
|
||
.info-name {
|
||
font-size: 24rpx;
|
||
font-weight: 500;
|
||
color: #FFFFFF;
|
||
margin-right: 12rpx;
|
||
}
|
||
|
||
.info-time {
|
||
font-size: 20rpx;
|
||
color: rgba(255, 255, 255, 0.7);
|
||
}
|
||
}
|
||
|
||
/* 第二行:地址 */
|
||
.row-addr {
|
||
.info-addr {
|
||
font-size: 20rpx;
|
||
color: rgba(255, 255, 255, 0.8);
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
white-space: nowrap;
|
||
}
|
||
}
|
||
}
|
||
|
||
/* 右下角悬浮相机按钮 - 仅物业人员可见 */
|
||
.fab-camera {
|
||
position: fixed;
|
||
right: 40rpx;
|
||
bottom: 120rpx;
|
||
width: 112rpx;
|
||
height: 112rpx;
|
||
background-color: #FFFFFF;
|
||
border-radius: 50%;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
box-shadow: 0 8rpx 28rpx rgba(0, 0, 0, 0.15);
|
||
|
||
.camera-img {
|
||
width: 48rpx;
|
||
height: 48rpx;
|
||
}
|
||
}
|
||
</style>
|