【微信小程序】访客管理

一、访客管理

访客管理是当有朋友到家里做客时,通过在线填写申请单的方式向门卫进行报备,并请求门卫放行。

1.1 访客邀请

填写访客邀请单,需要用户保持登录的状态。

首先来获取表单的数据

  1. 获取到访的房屋信息,仍然用到了 van-action-sheet 组件,获取数据通过坚挺 select 实现:

    // visitor_pkg/pages/form/index.js
    Page({data: {houseList: []},onLoad() {// 获取房屋列表this.getHouseList()},// 获取房屋列表async getHouseList() {// 调用接口const { code, data: houseList } = await wx.http.get('/house')// 检测接口是否调用成功if (code !== 10000) return wx.utils.toast()// 渲染数据this.setData({houseList})},// 获取用户选择的房屋selectHouseInfo(ev) {// 记录获取的数据this.setData({houseId: ev.detail.id,houseInfo: ev.detail.name,})},
    })
    
  2. 获取到访日期,仍然用到了 van-datepicker 组件,通过监听 confirm 事件获取选择的时间:

    // visitor_pkg/pages/form/index.js
    Page({data: {currentDate: Date.now(),maxDate: Date.now() + 1000 * 3600 * 24 * 3,},// 获取用户选择的日期selectDateInfo(ev) {// 记录获取的时间并隐藏弹层this.setData({visitDate: wx.utils.dataFormat(ev.detail),dateLayerVisible: false,})},
    })
    

    在选择时间的时候要求只能提前3天进行申请,即时间的最大值距离今天不能超过 3 天。

其次对表单的数据进行验证:

// visitor_pkg/pages/form/index.js
// 导入验证插件
import wxValidate from 'wechat-validate'
Page({behaviors: [wxValidate],data: {name: '',gender: 1,mobile: '',houseId: '',visitDate: '',},rules: {name: [{required: true, message: '访客姓名不能为空!'},{pattern: /[\u4e00-\u9fa5]{2,5}/, message: '访客姓名只能为中文!'},],mobile: [{required: true, message: '访客手机号不能为空!'},{pattern: /^1[3-8]\d{9}$/, message: '请填写正确的手机号码!'},],houseId: [{required: true, message: '请选择到访的房屋!'}],visitDate: [{required: true, message: '请选择到访的日期!'}],},
})

最后提交表单的数据

// visitor_pkg/pages/form/index.js
// 导入验证插件
import wxValidate from 'wechat-validate'
Page({behaviors: [wxValidate],data: {// ...},rules: {// ...},onLoad() {},getHouseList() {},// 提交表单数据async goPassport() {// 验证表单数据if (!this.validate()) return// 获取接口需要的数据const { name, gender, mobile, houseId, visitDate } = this.data// 调用接口const {code,data: { id },} = await wx.http.post('/visitor', { name, gender, mobile, houseId, visitDate })// 检测接口是否调用成功if (code !== 10000) return wx.utils.toast()// 跳转到访客详情页面wx.reLaunch({url: '/visitor_pkg/pages/passport/index?id=' + id,})},
})

填写完访客邀请后跳转到访客详情页面。

1.2 访客详情

获取访客详情有两种情况:

  1. 用户保持登录状态,根据 ID 调用接口获取访客详情的数据

    接口文档地址

    参考示例代码如下:

    // visitor_pkg/pages/passport/index.js
    Page({data: {passport: {}},onLoad({id}) {// 获取访客详情this.getPassport(id)},// 获取访客详情(通行证)async getPassport(id) {// 检测是否存在 idif (!id) return// 调用接口const { code, data: passport } = await wx.http.get('/visitor/' + id)// 检测接口是否调用成功if (code !== 10000) return wx.utils.toast()// 渲染数据this.setData({ passport })},
    })
    

    把接口返回的详情数据渲染到页面当中:

    <view class="passport"><view class="countdown"><van-count-down wx:if="{{passport.validTime > 0}}" time="{{passport.validTime * 1000}}" /><view wx:else class="van-count-down">00:00:00</view><view class="label">通行证有效时间</view></view><view class="qrcode"><image src="{{passport.url}}"></image><view wx:if="{{passport.validTime === -1}}" class="mask">二维码失效</view></view><view class="description"><view class="house">{{passport.houseInfo}}</view><view class="tips">将此二维码分享给访客,访客扫码即可开门</view></view>
    </view>
    <view class="toolbar"><button class="button-share" open-type="share"><text class="enjoy-icon icon-share"></text><text class="text">分享给朋友</text></button><button class="button-save"><text class="enjoy-icon icon-save"></text><text class="text">保存到本地</text></button>
    </view>
    

    访客详情中的二维码有时效性,当过期后数据 validTime 的值为 -1,此时将不会再展示倒计时组件了,同时二维码上方出现一个半透明的蒙层。

  2. 用户打开的分享页面(新用户未登录)

访客详情页面是允许用户分享给朋友的,此种情况下被分享的用户可能是新用户或处于未登录的状态,此时要获取访客详情数据需要借助另外一个接口,传递的参数为 encryptedData,这个数据在第1次分享时被拼凑到了分享页面的URL后面:

// visitor_pkg/pages/passport/index.js
Page({data: {},onLoad() {},// 自定义分享onShareAppMessage() {// 获取加密数据const { encryptedData } = this.data.passportreturn {title: '查看通行证',path: '/visitor_pkg/pages/passport/index?encryptedData=' + encryptedData,imageUrl: 'https://enjoy-plus.oss-cn-beijing.aliyuncs.com/images/share_poster.png',}},
})

当打开页面检测到 URL 中包含了 encryptedData 数据,则表明是通过分享打开的页面,然后调用接口获取访客详情的数据:

接口文档地址

// visitor_pkg/pages/passport/index.js
Page({onLoad({ id, encryptedData }) {// 获取访客详情this.getPassport(id)this.getPassportShare(encryptedData)},async getPassport(id) {},async getPassportShare(encryptedData) {// 检测是否存在 idif (!encryptedData) return// 调用接口const { code, data: passport } = await wx.http.get('/visitor/share/' + encryptedData)// 检测接口是否调用成功if (code !== 10000) return wx.utils.toast()// 渲染数据this.setData({ passport })},
})

此种情况下渲染数据时就不允许用户再次分享页面了,需要把分享按钮隐藏起来:

<view class="toolbar" wx:if="{{passport.encryptedData}}"><button class="button-share" open-type="share"><text class="enjoy-icon icon-share"></text><text class="text">分享给朋友</text></button><button class="button-save"><text class="enjoy-icon icon-save"></text><text class="text">保存到本地</text></button>
</view>
1.3 保存图片

小程序提供了保存图片到相册的 API,调用 API 来把二维码保存到相册当中。

<view class="toolbar" wx:if="{{passport.encryptedData}}"><button class="button-share" open-type="share"><text class="enjoy-icon icon-share"></text><text class="text">分享给朋友</text></button><button bind:tap="saveQRCode" class="button-save"><text class="enjoy-icon icon-save"></text><text class="text">保存到本地</text></button>
</view>

wx.getImageInfo 通过图片路径来读取图片信息,调用该 API 时需要在小程序管理后台添加 download 域名。

wx.getImageInfo({src: 'https://domain.com/path/xxx.jpg',success(result) {console.log(result)}
})

wx.saveImageToPhotosAlbum 将图片保存到相册,第一次调用会弹出授权窗口。

wx.saveImageToPhotosAlbum({filePath: '待保存的图片路径(通过 wx.getImageInfo 读取到的)',success(result) {console.log(result)}
})

结合项目组合使用这两个 API 来保存图片到相册

// visitor_pkg/pages/passport/index.js
Page({data: {},onLoad() {},// 保存二维码async saveQRCode() {try {// 读取图片信息const { path } = await wx.getImageInfo({// 二维码的图片路径src: this.data.passport.url,})// 保存图片到相册wx.saveImageToPhotosAlbum({ filePath: path })} catch (err) {wx.utils.toast('保存图片失败,稍后重试!')}}
})
1.4 访客列表

在用户保持登录状态时调用接口获取访客列表的数据,此接口支持分页获取数据。

接口文档地址

首先来获取不分页时的列表数据

参考示例代码如下所示:

// visitor_pkg/pages/list/index.js
Page({data: {visitorList: [],isEmpty: false,},onLoad() {// 获取访客列表this.getVisitorList()},// 访客列表接口async getVisitorList(current = 1, pageSize = 5) {// 调用接口const {code,data: {rows: visitorList},} = await wx.http.get('/visitor', {current, pageSize})// 检测接口是否调用成功if (code !== 10000) return wx.utils.toast()// 渲染数据this.setData({isEmpty: visitorList.length === 0,visitorList,})},
})

渲染访客列表数据:

<block wx:if="{{!isEmpty}}"><scroll-view show-scrollbar="{{false}}" enhanced scroll-y><view class="visitor"><view class="visitor-title">我的访客</view><view class="visitor-list"><van-cell-groupwx:for="{{visitorList}}"wx:key="id"border="{{false}}"bind:tap="goPassport"><van-cell size="large" title="{{item.houseInfo}}"><text wx:if="{{item.status === 1}}" class="tag success">生效中</text><text wx:if="{{item.status === 0}}" class="tag cancel">已失效</text></van-cell><van-cell title="访客姓名" border="{{false}}" value="{{item.name}}" /><van-cell title="手机号码" border="{{false}}" value="{{item.mobile}}" /><van-cell title="访问日期" border="{{false}}" value="{{item.visitDate}}" /></van-cell-group></view></view></scroll-view>
</block>
<view wx:else class="blank">您还没有访客记录,请点击<navigator hover-class="none" class="link" url="/visitor_pkg/pages/form/index">添加</navigator>
</view>

在渲染数据时注意列表为空时要给用户一段提示内容,通过 isEmpty 进行判断,访客邀请有两个状态:

  • 0 表示生效中,对应的类名为 success
  • 1 表示已失效,对应的类名为 cancel

其次来分页获取数据,先监听 bind:scrolltolower 事件,当用户滚动页面到达底部时再去请求分页的数据:

<block wx:if="{{!isEmpty}}"><scroll-viewbind:scrolltolower="getMoreVisitor"show-scrollbar="{{false}}"enhancedscroll-y><view class="visitor">....</view></scroll-view>
</block>
<view wx:else class="blank">您还没有访客记录,请点击<navigator hover-class="none" class="link" url="/visitor_pkg/pages/form/index">添加</navigator>
</view>

scrolltolower 事件有可能会在短时间内被重复触发,此种情形下会通过节流函数来避免无意义的请求,节流函数的创建可以使用第三方的库 miniprogram-licia

# 安装 miniprogram-licia
npm install miniprogram-licia

安装完成后再执行 npm 构建就可以使用了。

// visitor_pkg/pages/list/index.js
// 导入 licia 提供的节流函数
import { throttle } from 'miniprogram-licia'
Page({data: {},onLoad() {// 事件回调函数this.getMoreVisitor = throttle(() => {// 创建了节流函数}, 100)}
})

节流函数创建好之后就可以分页获取数据了,先来记录下当前的页面,然后每次调用时将页码加1,最后把新的数据追加到页面中渲染:

Page({data: {// ...},onLoad() {// 事件回调函数this.getMoreVisitor = throttle(() => {// 创建了节流函数this.getVisitorList(++this._current)}, 100)},// 访客列表接口async getVisitorList(current = 1, pageSize = 5) {// 调用接口const {code,data: { rows: visitorList },} = await wx.http.get('/visitor', { current, pageSize })// 检测接口是否调用成功if (code !== 10000) return wx.utils.toast()// 渲染数据this.setData({isEmpty: visitorList.length === 0,visitorList: this.data.visitorList.concat(visitorList),})// 记录下来当前的页面this._current = current},
})

还要考虑所有分页的数据都请求完后就无需再次请求了,可以对比当前页码 current 和总页码 pageTotal 来判断是否还有更多的数据:

Page({data: {// ...},onLoad() {// 事件回调函数this.getMoreVisitor = throttle(() => {// 没有更多数据了...if(!this.data.hasMore) return// 创建了节流函数this.getVisitorList(++this._current)}, 100)},// 访客列表接口async getVisitorList(current = 1, pageSize = 5) {// 调用接口const {code,data: { pageTotal, rows: visitorList },} = await wx.http.get('/visitor', { current, pageSize })// 检测接口是否调用成功if (code !== 10000) return wx.utils.toast()// 渲染数据this.setData({hasMore: current < pageTotalisEmpty: visitorList.length === 0,visitorList: this.data.visitorList.concat(visitorList),})// 记录下来当前的页面this._current = current},
})

到此享+生活的开发就结束了!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/473910.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Ubuntu22.04基于ROS2-Humble安装moveit2教程(亲测)

一、安装ROS2-Humble 1、参考&#xff1a;Ubuntu22.04安装ROS2-humble-CSDN博客 2、确保安装完成 source /opt/ros/humble/setup.bash 方法一&#xff1a;二进制安装 sudo apt install ros-humble-moveit* 方法二&#xff1a;安装源码编译 一、卸载二进制安装包 sudo a…

一些常见网络安全术语

1、黑帽 为非法目的进行黑客攻击的人&#xff0c;通常是为了经济利益。他们进入安全网络以销毁&#xff0c;赎回&#xff0c;修改或窃取数据&#xff0c;或使网络无法用于授权用户。这个名字来源于这样一个事实&#xff1a;老式的黑白西部电影中的恶棍很容易被电影观众识别&…

ISCTF 2024 web

ISCTF 2024 web 小蓝鲨的冒险 源码&#xff1a; <?php error_reporting(0); highlight_file(__FILE__); $a "isctf2024"; $b $_GET["b"]; parse_str($b); echo "小蓝鲨开始闯关&#xff0c;你能帮助他拿到flag吗?<br>"; if ($a…

AIGC----生成对抗网络(GAN)如何推动AIGC的发展

AIGC: 生成对抗网络(GAN)如何推动AIGC的发展 前言 随着人工智能领域的迅猛发展&#xff0c;AI生成内容&#xff08;AIGC&#xff0c;AI Generated Content&#xff09;正成为创意产业和技术领域的重要组成部分。在AIGC的核心技术中&#xff0c;生成对抗网络&#xff08;GAN&am…

删除k8s 或者docker运行失败的脚本

vi delete_exited_containers.sh#!/bin/bash# 列出所有停止的容器并存储到数组 list_exited_containers() {echo -e "\nStopped containers:"containers()# 获取停止的容器信息并存入数组while IFS read -r line; docontainers("$line")done < <(do…

如何在MindMaster思维导图中制作PPT课件?

思维导图是一种利用色彩、图画、线条等图文并茂的形式&#xff0c;来帮助人们增强知识或者事件的记忆。因此&#xff0c;思维导图也被常用于教育领域&#xff0c;比如&#xff1a;教学课件、读书笔记、时间管理等等。那么&#xff0c;在MindMaster免费思维导图软件中&#xff0…

【unity小技巧】一些unity3D灯光的使用与渲染及性能优化方案

文章目录 天空盒反射配置太阳耀斑眩光烘培光照烘培光照时弹出错误&#xff0c;记得勾选模型下面的选择阴影项目配置光源模型模型shader的问题 全局光照混合光照模式混合照明模式减性照明模式Shadowmask照明模式间接烘焙照明模式 环境光遮罩灯光探针反射探针技术关闭反射探针可以…

Linux :进程间通信之管道

一、进程间通信 1.1 是什么和为什么 1、进程间通信是什么&#xff1f;&#xff1f; ——>两个或多个进程实现数据层面的交互&#xff0c;但是由于进程独立性的存在&#xff0c;导致通信的成本比较高。 2、既然通信成本高&#xff0c;那为什么还要通信呢&#xff1f;&…

“乐鑫组件注册表”简介

当启动一个新的开发项目时&#xff0c;开发者们通常会利用库和驱动程序等现有的代码资源。这种做法不仅节省时间&#xff0c;还简化了项目的维护工作。本文将深入探讨乐鑫组件注册表的概念及其核心理念&#xff0c;旨在指导您高效地使用和贡献组件。 概念解析 ESP-IDF 的架构…

ATmaga8单片机Pt100温度计源程序+Proteus仿真设计

目录 1、项目功能 2、仿真图 ​3、程序 资料下载地址&#xff1a;ATmaga8单片机Pt100温度计源程序Proteus仿真设计 1、项目功能 设计Pt100铂电阻测量温度的电路&#xff0c;温度测量范围是0-100摄氏度&#xff0c;要求LCD显示。画出电路图&#xff0c;标注元器件参数&am…

【代码pycharm】动手学深度学习v2-05 线性代数

课程链接-05 线性代数 可以先看完特定轴求和再去看p2 import torch xtorch.tensor([3.0]) ytorch.tensor([2.0]) #标量 print(1.标量只有一个元素&#xff1a;\n,xy,x*y,x/y,x**y) x2torch.arange(4) #向量 print(2.向量视为标量值组成的列表&#xff1a;\n,x2) print(3.访问张…

SpringBoot源码解析(四):解析应用参数args

SpringBoot源码系列文章 SpringBoot源码解析(一)&#xff1a;SpringApplication构造方法 SpringBoot源码解析(二)&#xff1a;引导上下文DefaultBootstrapContext SpringBoot源码解析(三)&#xff1a;启动开始阶段 SpringBoot源码解析(四)&#xff1a;解析应用参数args 目录…

ZSTD 内存泄漏问题

优质博文&#xff1a;IT-BLOG-CN Zstandard&#xff08;简称zstd&#xff09;是一种无损压缩算法&#xff0c;由Facebook开发并开源。它旨在提供高压缩比和高解压速度的平衡&#xff0c;适用于多种数据压缩需求。 特点 【1】高压缩比&#xff1a; zstd能够在保持较高压缩比的…

前端:HTML (学习笔记)【1】

一&#xff0c;网络编程的三大基石 1&#xff0c;URL &#xff08;1&#xff09;url —— 统一资源定位符&#xff1a; 网址——整个互联网中可以唯一且准确的确定一个资源的位置。 【项目外】 网址——https://www.baidu.com/ …

【C++动态规划】3148. 矩阵中的最大得分|1819

本文涉及知识点 C动态规划 LeetCode 3148. 矩阵中的最大得分 给你一个由 正整数 组成、大小为 m x n 的矩阵 grid。你可以从矩阵中的任一单元格移动到另一个位于正下方或正右侧的任意单元格&#xff08;不必相邻&#xff09;。从值为 c1 的单元格移动到值为 c2 的单元格的得…

STM32完全学习——使用标准库点亮LED

一、使用标准库建立工程 &#xff08;1&#xff09;首先我们在ST的网站上面&#xff0c;下载标准库 &#xff08;2&#xff09;将标准外设库加入到项目中 我们一般只会使用到红色标注的那个文件夹&#xff0c;我们一般也只会将这个文件夹导入到工程里面&#xff0c;其他的还有…

解决微信小程序自定义tabbar点击两次才能跳转

在每个页面的js文件下加上此代码&#xff0c;selected属性代表每一个页面的下标&#xff0c;在不同的js文件下&#xff0c;要对应不同的selected值 代码&#xff1a; onShow() { // 确保 TabBar 存在并且设置选中项 if (this.getTabBar && this.getTabBar()) { this.…

学习threejs,使用AnimationMixer实现变形动画

&#x1f468;‍⚕️ 主页&#xff1a; gis分享者 &#x1f468;‍⚕️ 感谢各位大佬 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍⚕️ 收录于专栏&#xff1a;threejs gis工程师 文章目录 一、&#x1f340;前言1.1 ☘️THREE.AnimationMixer 动画…

Solana应用开发常见技术栈

编程语言 Rust Rust是Solana开发中非常重要的编程语言。它具有高性能、内存安全的特点。在Solana智能合约开发中&#xff0c;Rust可以用于编写高效的合约代码。例如&#xff0c;Rust的所有权系统可以帮助开发者避免常见的内存错误&#xff0c;如悬空指针和数据竞争。通过合理利…

【汇编语言】数据处理的两个基本问题(二) —— 解密汇编语言:数据长度与寻址方式的综合应用

文章目录 前言1. 指令要处理的数据有多长&#xff1f;1.1 通过寄存器指明数据的尺寸1.1.1 字操作1.1.2 字节操作 1.2 用操作符X ptr指明内存单元的长度1.2.1 访问字单元1.2.2 访问字节单元1.2.3 为什么要用操作符X ptr指明 1.3 其他方法 2. 寻址方式的综合应用2.1 问题背景&…