|
@@ -0,0 +1,358 @@
|
|
|
+<template>
|
|
|
+ <web-view v-show="!modal.show" ref="faceView" id="faceView" class="faceView" src="/static/face/door.html" bindmessage="receiveMessage" :webview-styles="webviewStyles" @message="onMessage">
|
|
|
+ </web-view>
|
|
|
+
|
|
|
+ <u-modal
|
|
|
+ :show="modal.show"
|
|
|
+ title="配置服务器"
|
|
|
+ :cancelText="'退出应用'"
|
|
|
+ :zoom="false"
|
|
|
+ :showConfirmButton="true"
|
|
|
+ :showCancelButton="true"
|
|
|
+ :closeOnClickOverlay="true"
|
|
|
+ @confirm="modalConfirm"
|
|
|
+ @cancel="modalCancel"
|
|
|
+ @close="modal.show = false"
|
|
|
+ >
|
|
|
+ <view class="slot-content">
|
|
|
+ <view>
|
|
|
+ <view class="mb10 required">服务器地址</view>
|
|
|
+ <view class="mb20">
|
|
|
+ <u-input v-model="form.linkUrl" placeholder="服务器地址(必填)" border="bottom" style="padding: 6px 0px" />
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view>
|
|
|
+ <view class="mb10">服务器端口</view>
|
|
|
+ <view class="mb20">
|
|
|
+ <u-input v-model="form.port" placeholder="服务器端口(非必填)" border="bottom" style="padding: 6px 0px" />
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view>
|
|
|
+ <view class="mb10 required">绑定门禁</view>
|
|
|
+ <view>
|
|
|
+ <u-input
|
|
|
+ v-model="form.doorName"
|
|
|
+ placeholder="门禁(必选)"
|
|
|
+ suffixIcon="arrow-right"
|
|
|
+ suffixIconStyle="color: #909399"
|
|
|
+ border="none"
|
|
|
+ disabledColor="transparent"
|
|
|
+ disabled
|
|
|
+ @click="handlePicker('绑定门禁')"
|
|
|
+ />
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </u-modal>
|
|
|
+
|
|
|
+ <u-picker
|
|
|
+ :show="picker.show"
|
|
|
+ :columns="picker.list"
|
|
|
+ :title="'请选择' + picker.title"
|
|
|
+ keyName="name"
|
|
|
+ visibleItemCount="6"
|
|
|
+ :defaultIndex="[picker.defaultIndex]"
|
|
|
+ :closeOnClickOverlay="true"
|
|
|
+ @close="picker.show = false"
|
|
|
+ @cancel="picker.show = false"
|
|
|
+ @confirm="pickerConfirm"
|
|
|
+ ></u-picker>
|
|
|
+</template>
|
|
|
+<script setup>
|
|
|
+/*----------------------------------依赖引入-----------------------------------*/
|
|
|
+import config from "@/config";
|
|
|
+import { onLoad, onShow, onReady, onHide, onLaunch, onUnload, onNavigationBarButtonTap, onPageScroll } from "@dcloudio/uni-app";
|
|
|
+import { ref, reactive, computed, getCurrentInstance, toRefs, inject, nextTick, watch } from "vue";
|
|
|
+/*----------------------------------接口引入-----------------------------------*/
|
|
|
+import { doorApi } from "@/api/business/door.js";
|
|
|
+import { faceApi } from "./api.js";
|
|
|
+/*----------------------------------组件引入-----------------------------------*/
|
|
|
+/*----------------------------------store引入-----------------------------------*/
|
|
|
+/*----------------------------------公共方法引入-----------------------------------*/
|
|
|
+const { proxy } = getCurrentInstance();
|
|
|
+/*----------------------------------公共变量-----------------------------------*/
|
|
|
+const state = reactive({
|
|
|
+ webviewStyles: {
|
|
|
+ width: "100%",
|
|
|
+ height: "100%",
|
|
|
+ },
|
|
|
+ doooList: [],
|
|
|
+ modal: {
|
|
|
+ show: false,
|
|
|
+ },
|
|
|
+ picker: {
|
|
|
+ show: false,
|
|
|
+ title: "",
|
|
|
+ list: [[]],
|
|
|
+ defaultIndex: 0,
|
|
|
+ },
|
|
|
+ form: {
|
|
|
+ linkUrl: "",
|
|
|
+ port: "",
|
|
|
+ domain: undefined,
|
|
|
+ doorId: undefined,
|
|
|
+ doorName: undefined,
|
|
|
+ },
|
|
|
+});
|
|
|
+const { webviewStyles, doooList, modal, picker, form, inter } = toRefs(state);
|
|
|
+
|
|
|
+// 初始化
|
|
|
+function init() {
|
|
|
+ //#ifdef APP-PLUS
|
|
|
+ proxy.$permission.getPermisson("camera").then((res) => {
|
|
|
+ if (res) {
|
|
|
+ handleChildren({
|
|
|
+ funcName: "开启摄像头",
|
|
|
+ data: {},
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ initNfc();
|
|
|
+ //#endif
|
|
|
+
|
|
|
+ var storage = uni.getStorageSync("storage_face");
|
|
|
+ if (storage) {
|
|
|
+ state.form.domain = storage.domain;
|
|
|
+ state.form.linkUrl = storage.linkUrl.indexOf(":") != -1 ? storage.linkUrl.split(":")[0] : storage.linkUrl;
|
|
|
+ state.form.port = storage.port ? storage.port : "";
|
|
|
+ state.form.doorId = storage.doorId || undefined;
|
|
|
+ state.form.doorName = storage.doorName || undefined;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 初始化NFC开门
|
|
|
+function initNfc() {
|
|
|
+ proxy.$nfc.initNFC();
|
|
|
+ proxy.$nfc.readNFC().then((e) => {
|
|
|
+ openDoor();
|
|
|
+ initNfc();
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * @门禁下拉列表
|
|
|
+ */
|
|
|
+function getdoorList() {
|
|
|
+ doorApi()
|
|
|
+ .Select({
|
|
|
+ current: 1, //页数
|
|
|
+ size: 2000, //条数
|
|
|
+ productCode: "502_USKY", //产品编码
|
|
|
+ deviceStatus: 2, //设备状态;1:在线,2:离线
|
|
|
+ domain: state.form.domain, //域名
|
|
|
+ })
|
|
|
+ .then((requset) => {
|
|
|
+ if (requset.data.records.length > 0) {
|
|
|
+ requset.data.records.forEach((e) => {
|
|
|
+ state.doooList.push({
|
|
|
+ value: e.deviceUuid,
|
|
|
+ name: e.deviceName,
|
|
|
+ });
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * @人脸验证
|
|
|
+ */
|
|
|
+function faceVerify(imageBase) {
|
|
|
+ faceApi()
|
|
|
+ .faceVef({
|
|
|
+ domain: state.form.domain,
|
|
|
+ imageBase: imageBase,
|
|
|
+ })
|
|
|
+ .then((item) => {
|
|
|
+ if (item.data.code === 200 || item.data.code === 201) {
|
|
|
+ proxy.$modal.msg(item.data.msg);
|
|
|
+ openDoor(item.data);
|
|
|
+ } else {
|
|
|
+ proxy.$modal.msg(item.data.msg);
|
|
|
+ }
|
|
|
+ })
|
|
|
+ .catch((err) => {});
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * @门禁开门
|
|
|
+ */
|
|
|
+function openDoor(item) {
|
|
|
+ doorApi()
|
|
|
+ .control({
|
|
|
+ domain: state.form.domain, //域名
|
|
|
+ userId: item.userId,
|
|
|
+ userName: item.faceName,
|
|
|
+ productCode: "502_USKY",
|
|
|
+ deviceUuid: "886e02e86a6f4a9b8e8e5fc0797742b2",
|
|
|
+ commandCode: "door_onoff",
|
|
|
+ commandValue: 1,
|
|
|
+ })
|
|
|
+ .then((item2) => {
|
|
|
+ console.log("开门成功");
|
|
|
+ })
|
|
|
+ .catch((err) => {
|
|
|
+ console.log(err);
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * @弹窗确定按钮事件
|
|
|
+ */
|
|
|
+function modalConfirm() {
|
|
|
+ if (!state.form.linkUrl) {
|
|
|
+ proxy.$modal.msg("请输入链接地址");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!/^[a-zA-Z0-9][a-zA-Z0-9-]{1,61}(?:\.[a-zA-Z0-9]{2,})+$/.test(state.form.linkUrl)) {
|
|
|
+ proxy.$modal.msg("请输入正确的链接地址");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!state.form.doorName) {
|
|
|
+ proxy.$modal.msg("请选择绑定门禁");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ uni.setStorageSync("storage_face", state.form);
|
|
|
+ state.modal.show = false;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * @action弹出框点击事件
|
|
|
+ */
|
|
|
+function handlePicker(value, index, ind) {
|
|
|
+ if (value == "绑定门禁") {
|
|
|
+ state.picker.title = "绑定门禁";
|
|
|
+ state.picker.list = [state.doooList];
|
|
|
+ state.picker.defaultIndex = 0;
|
|
|
+ }
|
|
|
+ state.picker.show = true;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * @action弹出框选择事件
|
|
|
+ */
|
|
|
+function pickerConfirm(e) {
|
|
|
+ if (state.picker.title == "绑定门禁") {
|
|
|
+ state.form.doorId = e.value[0].value;
|
|
|
+ state.form.doorName = e.value[0].name;
|
|
|
+ }
|
|
|
+ state.picker.show = false;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * @弹窗退出按钮事件
|
|
|
+ */
|
|
|
+function modalCancel() {
|
|
|
+ state.modal.show = false;
|
|
|
+ //#ifdef APP-PLUS
|
|
|
+ proxy.$keyListen.quitApp();
|
|
|
+ //#endif
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * @解析父页面传回的数据
|
|
|
+ */
|
|
|
+function analysisData(event) {
|
|
|
+ if ("funcName" in event) {
|
|
|
+ if (event.funcName == "打开配置") {
|
|
|
+ state.modal.show = true;
|
|
|
+ } else if (event.funcName == "人脸识别") {
|
|
|
+ faceVerify(event.data.imageBase);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * @向子页面发送数据
|
|
|
+ */
|
|
|
+function handleChildren(data) {
|
|
|
+ // #ifdef APP-PLUS
|
|
|
+ var pages = getCurrentPages();
|
|
|
+ var currentWebview = pages[pages.length - 1].$getAppWebview();
|
|
|
+ var wv = currentWebview.children()[0];
|
|
|
+ wv.evalJS(`receiveData(${JSON.stringify(data)})`);
|
|
|
+ // #endif
|
|
|
+
|
|
|
+ // #ifdef H5
|
|
|
+ var iframe = document.getElementById("faceView");
|
|
|
+ iframe.contentWindow.postMessage(data, "*");
|
|
|
+ // #endif
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * @接收子页面传过来的值
|
|
|
+ */
|
|
|
+function onMessage(e) {
|
|
|
+ analysisData(e.detail.data[0]);
|
|
|
+}
|
|
|
+// #ifdef H5
|
|
|
+window.onmessage = function (event) {
|
|
|
+ analysisData(event.data);
|
|
|
+};
|
|
|
+// #endif
|
|
|
+
|
|
|
+onLoad((options) => {
|
|
|
+ setTimeout(() => {
|
|
|
+ init();
|
|
|
+ }, 500);
|
|
|
+});
|
|
|
+
|
|
|
+onShow(() => {});
|
|
|
+
|
|
|
+onUnload(() => {});
|
|
|
+
|
|
|
+watch(
|
|
|
+ () => [state.form.linkUrl, state.form.port],
|
|
|
+ (val) => {
|
|
|
+ if (!state.form.linkUrl) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!/^[a-zA-Z0-9][a-zA-Z0-9-]{1,61}(?:\.[a-zA-Z0-9]{2,})+$/.test(state.form.linkUrl)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ var domain = "";
|
|
|
+ if (state.form.linkUrl) {
|
|
|
+ domain = state.form.linkUrl;
|
|
|
+ if (state.form.port) {
|
|
|
+ domain += ":" + state.form.port;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ state.form.domain = domain;
|
|
|
+ config.baseUrl = "http://" + state.form.domain + "/prod-api";
|
|
|
+ getdoorList();
|
|
|
+ }
|
|
|
+);
|
|
|
+</script>
|
|
|
+<style>
|
|
|
+.faceView {
|
|
|
+ width: 100% !important;
|
|
|
+ height: 100% !important;
|
|
|
+}
|
|
|
+
|
|
|
+iframe {
|
|
|
+ width: 100% !important;
|
|
|
+ height: 100% !important;
|
|
|
+ border-width: 0;
|
|
|
+}
|
|
|
+</style>
|
|
|
+<style lang="scss" scoped>
|
|
|
+:deep() {
|
|
|
+ .u-modal {
|
|
|
+ width: 20rem !important;
|
|
|
+
|
|
|
+ &__title {
|
|
|
+ font-size: 18px !important;
|
|
|
+ }
|
|
|
+ .slot-content {
|
|
|
+ font-size: 16px;
|
|
|
+ width: 100%;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|