Compare commits

...

2 Commits

Author SHA1 Message Date
李彪 ad2d48c4ca 刷卡功能对接中 2025-04-28 15:31:01 +08:00
李彪 98d1fdc287 刷卡与安卓交互 2025-04-27 10:17:07 +08:00
5 changed files with 194 additions and 28 deletions

View File

@ -14,3 +14,7 @@ export const GetAreaListApi = (data) =>
// 用户数据 // 用户数据
export const GetUserDataApi = (data) => export const GetUserDataApi = (data) =>
request.get("/api/AdminApp/GetUserData", data); request.get("/api/AdminApp/GetUserData", data);
// Nfc重置
export const ResetNFCApi = (data) =>
request.post("/api/Region/ResetNFC", data);

View File

@ -29,7 +29,7 @@
<image class="card-img" style="width: 130rpx; height: 130rpx" src="/static/adminImg/card4.png"></image> <image class="card-img" style="width: 130rpx; height: 130rpx" src="/static/adminImg/card4.png"></image>
</view> </view>
</view> </view>
<view v-if="true" style="display: flex"> <view v-if="false" style="display: flex">
<u-button type="error" @click="testFn">调试录入卡片</u-button> <u-button type="error" @click="testFn">调试录入卡片</u-button>
</view> </view>
</view> </view>

View File

@ -8,8 +8,8 @@
<view class="dialog-content"> <view class="dialog-content">
<!-- 头部标题和标签 --> <!-- 头部标题和标签 -->
<view class="dialog-header"> <view class="dialog-header">
<text class="title">{{currentRow.name}}</text> <text class="title">{{ currentRow.name }}</text>
<u-tag class="tag" text="室内" mode="light" /> <!-- <u-tag class="tag" text="室内" mode="light" /> -->
<!-- <u-tag <!-- <u-tag
class="tag" class="tag"
:text="areaType" :text="areaType"
@ -25,8 +25,9 @@
</view> </view>
<!-- 副标题 - 负责人 --> <!-- 副标题 - 负责人 -->
<view class="dialog-subtitle"> 区域主负责人{{ "张三" }} </view> <!-- <view class="dialog-subtitle"> 区域主负责人张三 </view> -->
<view>传入参数{{ showMsg }}</view>
<view>接口返回结果{{ resData }}</view>
<!-- 已存在卡片时显示图片 --> <!-- 已存在卡片时显示图片 -->
<view class="dialog-image-container" v-if="isChange === true"> <view class="dialog-image-container" v-if="isChange === true">
<!-- 替换为实际的图片路径 --> <!-- 替换为实际的图片路径 -->
@ -48,7 +49,8 @@
<view v-if="step === 1">1.请将标签卡贴靠设备NFC识别处</view> <view v-if="step === 1">1.请将标签卡贴靠设备NFC识别处</view>
<view v-if="step === 2">2.如果确定将该卡片写入该区域,请将标签卡贴靠设备xNFC识别处否则请退出</view> <view v-if="step === 2">2.如果确定将该卡片写入该区域,请将标签卡贴靠设备xNFC识别处否则请退出</view>
<view v-if="step === 3">3.请再次将标签卡贴靠设备NFC识别处</view> <view v-if="step === 3">3.请再次将标签卡贴靠设备NFC识别处</view>
<view v-if="step === 4">{{lookData}}</view> <!-- <view v-if="step === 3">{{ lookData }}</view> -->
<!-- <view v-if="step === 4">{{ lookData }}</view> -->
</view> </view>
<!-- 底部按钮 --> <!-- 底部按钮 -->
@ -60,7 +62,7 @@
</template> </template>
<script> <script>
import { loginApi } from '@/api/apiList' import { ResetNFCApi } from '@/api/apiAdmin'
export default { export default {
props: { props: {
// / // /
@ -80,17 +82,35 @@ export default {
return { return {
isChange: false, isChange: false,
step: 0, step: 0,
lookData: {} lookData: {},
resData: {},
showMsg: ''
} }
}, },
mounted() { mounted() {
window.nfcInitFn = this.nfcInitFn // window.nfcInitFn = this.nfcInitFn
}, },
onLoad() {}, onLoad() { },
methods: { methods: {
nfcInitFn(data) { async nfcInitFn(data) {
if (!data) { if (!data) {
return uni.showToast({ title: '未传入参数 initFn', icon: 'none' }) uni.showToast({ title: '未传入参数nfcInitFn', icon: 'none' })
return
}
this.showMsg = data
// uni.showModal({
// title: "",
// content: JSON.stringify(data) || '',
// success: function (res) {
// },
// });
if (data.step === 8) {
uni.showToast({ title: '刷卡失败', icon: 'none' })
return
}
if (this.isChange === true) {
uni.showToast({ title: '请点击更换绑定后刷卡', icon: 'none' })
return
} }
if (data.step === 1) { if (data.step === 1) {
this.step = 1 this.step = 1
@ -100,6 +120,53 @@ export default {
} }
if (data.step === 3) { if (data.step === 3) {
this.step = 3 this.step = 3
this.lookData = data
const req = {
"AreaId": data.areaId,
"pwd": data.pwd,
"isAdd": !this.currentRow.state,
// "isAdd": true,
}
console.log(req, '重置nfc--req')
console.log(666);
// uni.showLoading({ title: '...' })
const res = await ResetNFCApi(req).catch(e => e)
if (!res.succeed) {
uni.showToast({ title: res.error || '绑定失败', icon: 'none' })
}
this.resData = res;
try {
if (isAndroid && AndroidJs) {
console.log("%c%s", "color:red", "安卓--调用方法");
const reqRow = {
name: "resetNFCRes",
data: res,
};
console.log(reqRow, 'reqRow--')
AndroidJs.func(JSON.stringify(reqRow)); //
} else {
console.log("%c%s", "color:red", "苹果--调用方法");
const reqRow = {
name: "back-iphone",
data: "",
};
window.webkit.messageHandlers.func.postMessage(JSON.stringify(reqRow)); // ios
}
} catch (e) {
console.log(e, "e-----判断安卓苹果类型出错");
}
return
// uni.hideLoading()
console.log(res, '重置nfc')
this.resData = res;
if (res.succeed) {
uni.showToast({ title: '绑定成功', icon: 'none' })
} else {
uni.showToast({ title: res.error || '绑定失败', icon: 'none' })
}
return
} }
if (data.step === 4) { if (data.step === 4) {
this.lookData = data this.lookData = data
@ -121,6 +188,33 @@ export default {
nfcChange() { nfcChange() {
this.isChange = false this.isChange = false
this.step = 1 this.step = 1
console.log(this.currentRow, 'this.currentRow--')
//
let u = navigator.userAgent;
let isAndroid = u.indexOf("Android") > -1 || u.indexOf("Adr") > -1; //android
try {
if (isAndroid && AndroidJs) {
console.log("%c%s", "color:red", "安卓--调用方法");
const reqRow = {
name: "area",
data: {
// state: this.currentRow.state,
state: true,
areaId: this.currentRow.id,
},
};
AndroidJs.func(JSON.stringify(reqRow)); //
} else {
console.log("%c%s", "color:red", "苹果--调用方法");
const reqRow = {
name: "back-iphone",
data: "",
};
window.webkit.messageHandlers.func.postMessage(JSON.stringify(reqRow)); // ios
}
} catch (e) {
console.log(e, "e-----判断安卓苹果类型出错");
}
// this.$emit('changeBinding') // this.$emit('changeBinding')
// this.closeDialogInternal(); // // this.closeDialogInternal(); //
}, },
@ -136,6 +230,18 @@ export default {
this.$emit('close') // 使 :visible @close this.$emit('close') // 使 :visible @close
} }
} }
},
watch: {
visible(newVal) {
if (newVal) {
console.log('打开');
window.nfcInitFn = this.nfcInitFn
} else {
console.log('关闭');
// nfcInitFn
window.nfcInitFn = null
}
}
} }
} }
</script> </script>
@ -148,7 +254,8 @@ export default {
right: 0; right: 0;
bottom: 0; bottom: 0;
background-color: rgba(0, 0, 0, 0.5); background-color: rgba(0, 0, 0, 0.5);
z-index: 999; /* 确保遮罩在底层 */ z-index: 999;
/* 确保遮罩在底层 */
} }
.dialog-container { .dialog-container {
@ -156,9 +263,11 @@ export default {
top: 50%; top: 50%;
left: 50%; left: 50%;
transform: translate(-50%, -50%); transform: translate(-50%, -50%);
width: 90%; /* 或者根据需要设置固定宽度 */ width: 90%;
/* 或者根据需要设置固定宽度 */
// max-width: 600rpx; // max-width: 600rpx;
z-index: 1000; /* 确保弹窗在遮罩上 */ z-index: 1000;
/* 确保弹窗在遮罩上 */
} }
.dialog-content { .dialog-content {
@ -174,7 +283,8 @@ export default {
.dialog-header { .dialog-header {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; /* 居中显示 */ justify-content: center;
/* 居中显示 */
width: 100%; width: 100%;
margin-bottom: 16rpx; margin-bottom: 16rpx;
@ -211,18 +321,23 @@ export default {
// border: 1px solid red; // border: 1px solid red;
height: auto; height: auto;
margin-bottom: 30rpx; margin-bottom: 30rpx;
.dialog-image { .dialog-image {
width: 100%; width: 100%;
width: 200rpx; /* 根据图片调整 */ width: 200rpx;
height: auto; /* 让图片自适应高度 */ /* 根据图片调整 */
height: auto;
/* 让图片自适应高度 */
} }
} }
.change-binding { .change-binding {
font-size: 28rpx; font-size: 28rpx;
color: #4a90e2; /* 蓝色链接颜色 */ color: #4a90e2;
/* 蓝色链接颜色 */
// margin-bottom: 50rpx; // margin-bottom: 50rpx;
cursor: pointer; /* 鼠标悬停显示手型 */ cursor: pointer;
/* 鼠标悬停显示手型 */
} }
.dialog-footer { .dialog-footer {
@ -233,12 +348,14 @@ export default {
width: 100%; width: 100%;
height: 88rpx; height: 88rpx;
line-height: 88rpx; line-height: 88rpx;
background-color: #4879e6; /* 蓝色按钮背景 */ background-color: #4879e6;
/* 蓝色按钮背景 */
color: #ffffff; color: #ffffff;
font-size: 32rpx; font-size: 32rpx;
border-radius: 0 0 24rpx 24rpx; border-radius: 0 0 24rpx 24rpx;
border: none; border: none;
text-align: center; text-align: center;
// H5 // H5
&::after { &::after {
border: none; border: none;
@ -248,5 +365,4 @@ export default {
/* 可以添加按钮按下的效果 */ /* 可以添加按钮按下的效果 */
// .confirm-button:active { // .confirm-button:active {
// background-color: #4879e6; // background-color: #4879e6;
// } // }</style>
</style>

View File

@ -12,10 +12,12 @@
</view> </view>
</view> </view>
<!-- tabs --> <!-- tabs -->
<u-tabs class="tabs-box" bg-color="#F6F8FC" :list="tabsList" :is-scroll="true" :current="tabCurrent" @change="tabChangeFn"></u-tabs> <u-tabs class="tabs-box" bg-color="#F6F8FC" :list="tabsList" :is-scroll="true" :current="tabCurrent"
@change="tabChangeFn"></u-tabs>
<!-- 搜索 --> <!-- 搜索 -->
<view class="search-box"> <view class="search-box">
<u-input class="search-input" v-model="keyword" :clearable="false" border placeholder="搜索名称" @keyup.enter="searchFn"></u-input> <u-input class="search-input" v-model="keyword" :clearable="false" border placeholder="搜索名称"
@keyup.enter="searchFn"></u-input>
<u-icon name="search" class="search-icon" size="40" @click="searchFn"></u-icon> <u-icon name="search" class="search-icon" size="40" @click="searchFn"></u-icon>
<view class="select-box" @click="selectFn"> <view class="select-box" @click="selectFn">
<view> <view>
@ -26,7 +28,8 @@
</view> </view>
<!-- tip --> <!-- tip -->
<view v-if="sonList.length" class="tip-box">{{sonForm.countData}}个子区域其中{{sonForm.countData - sonForm.bindData}}个未绑定</view> <view v-if="sonList.length" class="tip-box">{{ sonForm.countData }}个子区域其中{{ sonForm.countData -
sonForm.bindData }}个未绑定</view>
<!-- 列表 --> <!-- 列表 -->
<view class="list-box"> <view class="list-box">
<scroll-view :scroll-y="true" class="scroll-Y"> <scroll-view :scroll-y="true" class="scroll-Y">
@ -42,7 +45,8 @@
<!-- 筛选的下拉 --> <!-- 筛选的下拉 -->
<u-action-sheet :list="options" title="请选择" @click="changeFn" v-model:value="selectShow"></u-action-sheet> <u-action-sheet :list="options" title="请选择" @click="changeFn" v-model:value="selectShow"></u-action-sheet>
<!-- 弹窗 --> <!-- 弹窗 -->
<bind-dialog ref="dialogRef" :visible="showDialog" @close="showDialog = false" :currentRow="currentRow" @changeBinding="onChangeBinding" @confirm="onConfirm"></bind-dialog> <bind-dialog ref="dialogRef" :visible="showDialog" @close="showDialog = false" :currentRow="currentRow"
@changeBinding="onChangeBinding" @confirm="onConfirm"></bind-dialog>
<u-tabbar :list="vuex_tabbar"></u-tabbar> <u-tabbar :list="vuex_tabbar"></u-tabbar>
</view> </view>
@ -110,10 +114,47 @@ export default {
}, },
methods: { methods: {
dialogShowFn(row) { dialogShowFn(row) {
//
let u = navigator.userAgent;
let isAndroid = u.indexOf("Android") > -1 || u.indexOf("Adr") > -1; //android
console.log(row.state, 'row.state--')
//
if (row.state === false) {
try {
if (isAndroid && AndroidJs) {
console.log("%c%s", "color:red", "安卓--调用方法");
const reqRow = {
name: "area",
data: {
// state: row.state,
state: true,
areaId: row.id,
},
};
console.log(reqRow, 'reqRow--')
AndroidJs.func(JSON.stringify(reqRow)); //
} else {
console.log("%c%s", "color:red", "苹果--调用方法");
const reqRow = {
name: "back-iphone",
data: "",
};
window.webkit.messageHandlers.func.postMessage(JSON.stringify(reqRow)); // ios
}
} catch (e) {
console.log(e, "e-----判断安卓苹果类型出错");
}
}
console.log(JSON.parse(JSON.stringify(row)), 'row--') console.log(JSON.parse(JSON.stringify(row)), 'row--')
this.currentRow = row this.currentRow = row
this.$refs.dialogRef.isChange = row.state // this.$refs.dialogRef.isChange = row.state //
this.$refs.dialogRef.resData = ''
this.$refs.dialogRef.showMsg = ''
this.$refs.dialogRef.step = 0 // this.$refs.dialogRef.step = 0 //
if (row.state === false) {
this.$refs.dialogRef.step = 1 //
}
this.showDialog = true this.showDialog = true
}, },
async getDataFn() { async getDataFn() {
@ -233,12 +274,14 @@ export default {
// border: 1px solid red; // border: 1px solid red;
// margin-top: 20rpx; // margin-top: 20rpx;
padding: 20rpx; padding: 20rpx;
.search-icon { .search-icon {
position: absolute; position: absolute;
right: 210rpx; right: 210rpx;
top: 50%; top: 50%;
transform: translateY(-50%); transform: translateY(-50%);
} }
.search-input { .search-input {
background-color: white; background-color: white;
border-radius: 50rpx; border-radius: 50rpx;

View File

@ -18,6 +18,7 @@
</template> </template>
<script> <script>
import bcrypt from "bcryptjs"; import bcrypt from "bcryptjs";
import { jwtDecode } from "jwt-decode";
import { loginApi } from "@/api/apiList"; import { loginApi } from "@/api/apiList";
export default { export default {
data() { data() {
@ -74,6 +75,8 @@ export default {
} }
let token = res.data; let token = res.data;
uni.setStorageSync("token", "Bearer " + token); uni.setStorageSync("token", "Bearer " + token);
console.log(jwtDecode(token), "解析的token信息");
// return
console.log(type, "type--"); console.log(type, "type--");
if (type === "user") { if (type === "user") {
const normalTabBar = [ const normalTabBar = [