fjrcloud-community-app/pages/sub/community/daily.vue

303 lines
7.9 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<!-- 物业日常 - 打卡记录页面 -->
<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>