248 lines
6.0 KiB
Vue
248 lines
6.0 KiB
Vue
<template>
|
||
<crud-layout :bg="$fileUrl(filePath(SERVICE_IMAGE.blueBg))" ref="crudLayoutRef">
|
||
<div class="integrated-title-card">
|
||
<div class="integrated-title">综合服务</div>
|
||
</div>
|
||
<div class="service-container-card">
|
||
<div class="service-container">
|
||
<div class="service-grid">
|
||
<div v-for="item in services" :key="item.name" class="service-item" @click="goPage(item)">
|
||
<div class="service-icon-wrapper">
|
||
<image :src="$fileUrl(item.icon)" class="service-icon" @error="$fileRetry(item.icon)" />
|
||
<view v-if="item.name === 'todo' && todoCount > 0" class="badge">
|
||
{{ todoCount > 99 ? "99+" : todoCount }}
|
||
</view>
|
||
</div>
|
||
<div class="service-label">{{ item.label }}</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<view
|
||
class="position-absolute bottom-30rpx left-0 right-0 second-text-26 text-center flex items-center justify-center">
|
||
<view>联系热线:</view>
|
||
<view @click="doPhone('18367908152')">18367908152</view>
|
||
<view class="w-10rpx" />
|
||
<view @click="doPhone('15657370065')">15657370065</view>
|
||
</view>
|
||
</crud-layout>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import { onLoad } from "@dcloudio/uni-app"
|
||
import { ref, onMounted, nextTick } from "vue"
|
||
|
||
import { filePath } from "@@/utils/file"
|
||
import { SERVICE_IMAGE } from "@@/constant/index"
|
||
|
||
import integratedApi from "@/sheep/api/integrated"
|
||
import * as hooks from "@@/hooks"
|
||
|
||
const todoCount = ref(0)
|
||
const crudLayoutRef = ref<any>(null)
|
||
|
||
const services = [
|
||
// {
|
||
// name: "todo",
|
||
// label: "工作待办",
|
||
// icon: "/static/icon/todo.png",
|
||
// url: "/pages/integrated/todo/index",
|
||
// },
|
||
// {
|
||
// name: "meeting-booking",
|
||
// label: "会议预定",
|
||
// icon: "/static/icon/meeting-booking.png",
|
||
// url: "/pages/integrated/meeting/index",
|
||
// },
|
||
// {
|
||
// name: "lost-and-found",
|
||
// label: "失物招领",
|
||
// icon: "/static/icon/service_1.png",
|
||
// url: "/pages/integrated/lostAndFound/index",
|
||
// },
|
||
{
|
||
name: "feedback",
|
||
label: "意见反馈",
|
||
icon: "/static/icon/feedback.png",
|
||
url: "/pages/integrated/feedback/index",
|
||
},
|
||
// {
|
||
// name: "repair-report",
|
||
// label: "物业维修",
|
||
// icon: "/static/icon/service_2.png",
|
||
// url: "/pages/integrated/repair/index",
|
||
// },
|
||
{
|
||
name: "notice",
|
||
label: "通知公告",
|
||
icon: "/static/icon/service_3.png",
|
||
url: "/pages/integrated/notice/index",
|
||
},
|
||
{
|
||
name: "visitor",
|
||
label: "访客邀约",
|
||
icon: "/static/icon/visitor.png",
|
||
url: "/pages/integrated/visitor/invitation",
|
||
},
|
||
]
|
||
|
||
// 获取待办数量
|
||
async function fetchTodoCount() {
|
||
try {
|
||
const res = await integratedApi.getTodoList({ current: 1, size: 1 })
|
||
const responseData = res as any
|
||
if (responseData.code === 0 && responseData.data) {
|
||
todoCount.value = responseData.data.total || 0
|
||
}
|
||
} catch (error) {
|
||
console.error("获取待办数量失败:", error)
|
||
todoCount.value = 0
|
||
}
|
||
}
|
||
|
||
onLoad(() => {
|
||
})
|
||
onMounted(() => {
|
||
nextTick(() => {
|
||
crudLayoutRef.value?.checkVerifyDevice?.()
|
||
})
|
||
})
|
||
onMounted(() => {
|
||
fetchTodoCount()
|
||
})
|
||
|
||
function goPage(item) {
|
||
// 访客邀约功能正在开发中
|
||
// if (item.name === "visitor") {
|
||
// uni.showToast({
|
||
// title: "访客邀约功能正在开发中",
|
||
// icon: "none",
|
||
// duration: 2000,
|
||
// })
|
||
// return
|
||
// }
|
||
|
||
if (item.url) {
|
||
uni.navigateTo({ url: item.url })
|
||
}
|
||
}
|
||
|
||
// 联系客服
|
||
const doPhone = (phone: string) => {
|
||
hooks.useMakePhoneCall(phone)
|
||
}
|
||
</script>
|
||
|
||
<style scoped lang="scss">
|
||
.integrated-title-card {
|
||
background: #fff;
|
||
border-radius: 20rpx;
|
||
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.06);
|
||
margin: 32rpx 24rpx 0 24rpx;
|
||
padding: 0 0 8rpx 0;
|
||
}
|
||
|
||
.integrated-title {
|
||
font-size: 38rpx;
|
||
font-weight: bold;
|
||
color: #222;
|
||
text-align: center;
|
||
padding: 36rpx 0 24rpx 0;
|
||
letter-spacing: 2rpx;
|
||
}
|
||
|
||
.service-container-card {
|
||
background: #fff;
|
||
border-radius: 24rpx;
|
||
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.06);
|
||
margin: 24rpx;
|
||
padding-bottom: 32rpx;
|
||
}
|
||
|
||
.service-container {
|
||
padding: 32rpx 0 0 0;
|
||
background: transparent;
|
||
border-radius: 16rpx;
|
||
}
|
||
|
||
.service-grid {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
align-items: center;
|
||
padding: 0 24rpx;
|
||
}
|
||
|
||
.service-item {
|
||
width: 25%;
|
||
margin-bottom: 40rpx;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
transition: transform 0.2s;
|
||
}
|
||
|
||
.service-item:hover {
|
||
transform: translateY(-6rpx) scale(1.06);
|
||
box-shadow: 0 2rpx 12rpx rgba(25, 118, 210, 0.08);
|
||
}
|
||
|
||
.service-icon-wrapper {
|
||
position: relative;
|
||
margin-bottom: 14rpx;
|
||
}
|
||
|
||
.service-icon {
|
||
width: 92rpx;
|
||
height: 92rpx;
|
||
border-radius: 16rpx;
|
||
background: #f5f7fa;
|
||
box-shadow: 0 2rpx 8rpx rgba(25, 118, 210, 0.04);
|
||
transition: box-shadow 0.2s;
|
||
}
|
||
|
||
.badge {
|
||
position: absolute;
|
||
top: -8rpx;
|
||
right: -8rpx;
|
||
background: #ff6b35;
|
||
color: #fff;
|
||
font-size: 20rpx;
|
||
font-weight: bold;
|
||
min-width: 32rpx;
|
||
height: 32rpx;
|
||
border-radius: 16rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
padding: 0 8rpx;
|
||
box-shadow: 0 2rpx 8rpx rgba(255, 107, 53, 0.4);
|
||
border: 2rpx solid #fff;
|
||
animation: pulse 2s infinite;
|
||
}
|
||
|
||
@keyframes pulse {
|
||
0% {
|
||
transform: scale(1);
|
||
}
|
||
|
||
50% {
|
||
transform: scale(1.1);
|
||
}
|
||
|
||
100% {
|
||
transform: scale(1);
|
||
}
|
||
}
|
||
|
||
.service-label {
|
||
font-size: 28rpx;
|
||
color: #333;
|
||
text-align: center;
|
||
letter-spacing: 1rpx;
|
||
}
|
||
|
||
body {
|
||
background: #f5f6fa;
|
||
}
|
||
</style>
|