UniApp企业级实战:构建智能社区物业管理系统 | 跨平台开发进阶

2025-08-16 0 247

发布日期:2024年4月15日

一、系统架构设计

本教程将开发一个完整的社区物业管理系统,包含以下核心模块:

  • 业主门户:业主认证与信息管理
  • 工单系统:报修投诉全流程跟踪
  • 物业缴费:在线支付与账单管理
  • 智能门禁:蓝牙/NFC开门集成
  • 社区服务:便民服务预约系统

技术栈:UniApp + Vue3 + Pinia + uView UI + 微信云开发

二、项目初始化与工程配置

1. 创建项目并安装依赖

# 使用Vue3/Vite模板创建项目
npx degit dcloudio/uni-preset-vue#vite property-management

# 安装核心依赖
cd property-management
npm install
npm install pinia uview-ui @uni-helper/uni-ui

# 微信云开发扩展
npm install wx-cloud -D

2. 项目目录结构规划

src/
├── api/               # 接口服务
├── components/        # 公共组件
│   ├── property/      # 物业专用组件
│   └── common/        # 通用组件
├── composables/       # 组合式函数
├── pages/             # 页面组件
│   ├── owner/         # 业主端页面
│   └── property/      # 物业端页面
├── static/            # 静态资源
├── store/             # Pinia状态管理
├── styles/            # 全局样式
├── utils/             # 工具函数
├── App.vue            # 应用入口
└── main.js            # 主配置文件

三、核心功能实现

1. 业主身份认证模块

// composables/useOwnerAuth.js
import { ref } from 'vue'
import { useStore } from '@/store/owner'

export function useOwnerAuth() {
    const store = useStore()
    const authStatus = ref('unverified')
    
    // 提交认证信息
    const submitVerification = async (formData) => {
        try {
            const res = await uniCloud.callFunction({
                name: 'owner-verify',
                data: formData
            })
            
            if (res.result.code === 200) {
                authStatus.value = 'pending'
                store.setOwnerInfo(res.result.data)
            }
        } catch (e) {
            uni.showToast({ title: '认证失败', icon: 'error' })
        }
    }
    
    // 检查认证状态
    const checkAuthStatus = async () => {
        const res = await uniCloud.callFunction({
            name: 'check-owner-status'
        })
        authStatus.value = res.result.status
    }
    
    return { authStatus, submitVerification, checkAuthStatus }
}

2. 工单系统实现

// pages/owner/work-order/index.vue
<template>
    <view class="work-order-container">
        <u-tabs :list="tabList" @click="changeTab"></u-tabs>
        
        <scroll-view scroll-y class="order-list">
            <work-order-card 
                v-for="order in filteredOrders"
                :key="order.id"
                :order="order"
                @click="viewDetail(order.id)"
            />
        </scroll-view>
        
        <u-button 
            type="primary" 
            icon="plus" 
            @click="createOrder"
            class="float-button"
        >新建工单</u-button>
    </view>
</template>

<script setup>
import { ref, computed } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
import { useWorkOrderStore } from '@/store/workOrder'

const store = useWorkOrderStore()
const tabList = [
    { name: 'all', label: '全部' },
    { name: 'pending', label: '处理中' },
    { name: 'completed', label: '已完成' }
]
const activeTab = ref('all')

const filteredOrders = computed(() => {
    return store.orders.filter(order => 
        activeTab.value === 'all' || 
        order.status === activeTab.value
    )
})

onLoad(async () => {
    await store.fetchOrders()
})

function viewDetail(id) {
    uni.navigateTo({
        url: `/pages/owner/work-order/detail?id=${id}`
    })
}
</script>

四、智能门禁集成

1. 蓝牙门禁控制

// utils/door-control.js
export class DoorController {
    static async init() {
        // #ifdef MP-WEIXIN
        await this.initWXBLE()
        // #endif
        
        // #ifdef APP-PLUS
        await this.initNativeBLE()
        // #endif
    }
    
    static async openDoor(deviceId) {
        try {
            // 发送开门指令
            const command = this.generateCommand('open')
            await uni.writeBLECharacteristicValue({
                deviceId,
                serviceId: '0000FFE0-0000-1000-8000-00805F9B34FB',
                characteristicId: '0000FFE1-0000-1000-8000-00805F9B34FB',
                value: command
            })
            
            uni.showToast({ title: '开门指令已发送' })
        } catch (e) {
            uni.showToast({ title: '开门失败', icon: 'error' })
        }
    }
    
    static generateCommand(action) {
        const encoder = new TextEncoder()
        return encoder.encode(
            `DOOR:${action}:${Date.now()}`
        )
    }
}

2. 访客二维码生成

// composables/useVisitorQR.js
import { ref } from 'vue'
import QRCode from 'qrcode'

export function useVisitorQR() {
    const qrCode = ref('')
    const generating = ref(false)
    
    const generateQR = async (visitorInfo) => {
        generating.value = true
        
        try {
            // 生成临时访问令牌
            const res = await uniCloud.callFunction({
                name: 'generate-visitor-token',
                data: visitorInfo
            })
            
            // 生成二维码
            qrCode.value = await QRCode.toDataURL(
                JSON.stringify({
                    token: res.result.token,
                    expire: res.result.expire
                }),
                { width: 200 }
            )
        } finally {
            generating.value = false
        }
    }
    
    return { qrCode, generating, generateQR }
}

五、物业缴费系统

1. 账单列表与支付

// pages/owner/payment/index.vue
<template>
    <view class="payment-container">
        <u-sticky bgColor="#fff">
            <u-tabs :list="years" @click="changeYear"></u-tabs>
        </u-sticky>
        
        <view class="bill-list">
            <bill-card 
                v-for="bill in filteredBills"
                :key="bill.id"
                :bill="bill"
                @pay="handlePay(bill)"
            />
        </view>
    </view>
</template>

<script setup>
import { ref, computed } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
import { usePaymentStore } from '@/store/payment'

const store = usePaymentStore()
const years = ref(['2024', '2023', '2022'])
const activeYear = ref('2024')

const filteredBills = computed(() => {
    return store.bills.filter(bill => 
        bill.year === activeYear.value
    )
})

onLoad(async () => {
    await store.fetchBills()
})

async function handlePay(bill) {
    try {
        const res = await uni.requestPayment({
            provider: 'wxpay',
            orderInfo: await store.generateOrder(bill)
        })
        
        if (res[0].errMsg === 'requestPayment:ok') {
            await store.updateBillStatus(bill.id)
            uni.showToast({ title: '支付成功' })
        }
    } catch (e) {
        uni.showToast({ title: '支付取消', icon: 'none' })
    }
}
</script>

2. 支付状态同步

// store/payment.js
import { defineStore } from 'pinia'
import { ref } from 'vue'

export const usePaymentStore = defineStore('payment', () => {
    const bills = ref([])
    
    async function fetchBills() {
        const res = await uniCloud.callFunction({
            name: 'get-owner-bills'
        })
        bills.value = res.result.data
    }
    
    async function updateBillStatus(billId) {
        await uniCloud.callFunction({
            name: 'update-bill-status',
            data: { billId }
        })
        await fetchBills()
    }
    
    return { bills, fetchBills, updateBillStatus }
})

六、多端适配方案

1. 平台特定组件封装

// components/common/ImageUploader.vue
<template>
    <view class="uploader">
        <!-- 微信小程序专用上传 -->
        <!-- #ifdef MP-WEIXIN -->
        <button 
            class="upload-btn"
            open-type="chooseMedia"
            @choose="handleWxChoose"
        >上传图片</button>
        <!-- #endif -->
        
        <!-- App端上传 -->
        <!-- #ifdef APP-PLUS -->
        <button 
            class="upload-btn"
            @click="handleNativeUpload"
        >上传图片</button>
        <!-- #endif -->
        
        <!-- H5端上传 -->
        <!-- #ifdef H5 -->
        <input 
            type="file" 
            accept="image/*"
            @change="handleH5Upload"
        >
        <!-- #endif -->
    </view>
</template>

<script setup>
function handleWxChoose(e) {
    // 微信小程序上传逻辑
}

function handleNativeUpload() {
    // App端上传逻辑
}

function handleH5Upload(e) {
    // H5上传逻辑
}
</script>

2. 响应式布局设计

// composables/useResponsive.js
import { ref, onMounted, onUnmounted } from 'vue'

export function useResponsive() {
    const screenWidth = ref(uni.getSystemInfoSync().screenWidth)
    const isMobile = computed(() => screenWidth.value  screenWidth.value >= 768 && screenWidth.value  screenWidth.value >= 992)
    
    const updateSize = () => {
        screenWidth.value = uni.getSystemInfoSync().screenWidth
    }
    
    onMounted(() => {
        uni.onWindowResize(updateSize)
    })
    
    onUnmounted(() => {
        uni.offWindowResize(updateSize)
    })
    
    return { isMobile, isTablet, isDesktop }
}

七、性能优化实践

1. 图片懒加载与缓存

// 图片懒加载配置
<image 
    lazy-load 
    :src="imageUrl" 
    mode="aspectFill"
    @load="handleImageLoad"
    @error="handleImageError"
></image>

// 数据缓存策略
async function getCachedData(key, fetchFunc) {
    try {
        const cached = uni.getStorageSync(key)
        if (cached) {
            return JSON.parse(cached)
        }
        
        const freshData = await fetchFunc()
        uni.setStorageSync(key, JSON.stringify(freshData))
        return freshData
    } catch (e) {
        return fetchFunc()
    }
}

2. 组件按需加载

// 动态导入重型组件
const HeavyComponent = defineAsyncComponent(() =>
    import('./HeavyComponent.vue')
)

// 路由懒加载
const routes = [
    {
        path: '/complex-page',
        component: () => import('@/pages/complex-page.vue')
    }
]

八、总结与扩展

通过本教程,您已经掌握了:

  1. UniApp企业级应用架构设计
  2. 复杂业务模块的实现方法
  3. 硬件设备集成方案
  4. 多端适配与性能优化

扩展学习方向:

  • 物业数据可视化分析
  • AI工单自动分类
  • WebSocket实时通知
  • 微前端架构改造
UniApp企业级实战:构建智能社区物业管理系统 | 跨平台开发进阶
收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

淘吗网 uniapp UniApp企业级实战:构建智能社区物业管理系统 | 跨平台开发进阶 https://www.taomawang.com/web/uniapp/856.html

下一篇:

已经没有下一篇了!

常见问题

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务