NFC
This commit is contained in:
@@ -1,15 +1,12 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="nfc-con">
|
<view class="nfc-con">
|
||||||
<view class="nfc-bg">
|
<view class="nfc-bg">
|
||||||
<view class="nfc-title">
|
<view class="nfc-title">
|
||||||
<uni-icons type="closeempty" size="20" class="nfc-close" @click="handleClose"></uni-icons>NFC识别
|
<uni-icons type="closeempty" size="20" class="nfc-close" @click="handleClose"></uni-icons>NFC识别
|
||||||
</view>
|
</view>
|
||||||
<block v-if="!nfcResult">
|
<block v-if="formData.deviceId==''">
|
||||||
<view class="nfc-pic" @click="readData" v-if="!isReading">
|
<view class="nfc-pic">
|
||||||
<img :src="'static/images/polling/nfc-logo.png'" />
|
<img class="nfc-pic-animal" :src="'static/images/polling/nfc-logo.png'" />
|
||||||
</view>
|
|
||||||
<view class="nfc-pic" v-else>
|
|
||||||
<img class="nfc-pic-animal" :src="'static/images/polling/nfc-logo.png'" />
|
|
||||||
</view>
|
</view>
|
||||||
<view class="nfc-desc">请将设备靠近NFC识别</view>
|
<view class="nfc-desc">请将设备靠近NFC识别</view>
|
||||||
</block>
|
</block>
|
||||||
@@ -25,7 +22,7 @@
|
|||||||
<view>识别时间</view>
|
<view>识别时间</view>
|
||||||
<view>{{parseTime(new Date().getTime(),'{y}年{m}月{d}日 星期{a} {h}:{i}')}}</view>
|
<view>{{parseTime(new Date().getTime(),'{y}年{m}月{d}日 星期{a} {h}:{i}')}}</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="btn-blue" @click="handleConfirm">确定</view>
|
<view class="btn-blue" @click="handleClose">确定</view>
|
||||||
</block>
|
</block>
|
||||||
<block v-else>
|
<block v-else>
|
||||||
<view class="result-header">
|
<view class="result-header">
|
||||||
@@ -35,7 +32,7 @@
|
|||||||
<view class="result-value">
|
<view class="result-value">
|
||||||
可能的失败原因:手机距离NFC设备较远、手机未联网、NFC设备故障……
|
可能的失败原因:手机距离NFC设备较远、手机未联网、NFC设备故障……
|
||||||
</view>
|
</view>
|
||||||
<view class="btn-blue" @click="readData">重新识别</view>
|
<view class="btn-blue" @click="open">重新识别</view>
|
||||||
</block>
|
</block>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@@ -43,285 +40,192 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref,watch } from 'vue'
|
import { ref, onBeforeUnmount,onMounted } from "vue";
|
||||||
import { onLoad,onHide} from '@dcloudio/uni-app';
|
|
||||||
import { parseTime } from '@/utils/datetime.js';
|
import { parseTime } from '@/utils/datetime.js';
|
||||||
|
|
||||||
// 包路径
|
// 定义组件 emits
|
||||||
const package_NdefRecord = 'android.nfc.NdefRecord';
|
const emit = defineEmits(['close',"changeNfc"]);
|
||||||
const package_NdefMessage = 'android.nfc.NdefMessage';
|
|
||||||
const package_TECH_DISCOVERED = 'android.nfc.action.TECH_DISCOVERED';
|
|
||||||
const package_Intent = 'android.content.Intent';
|
|
||||||
const package_Activity = 'android.app.Activity';
|
|
||||||
const package_PendingIntent = 'android.app.PendingIntent';
|
|
||||||
const package_IntentFilter = 'android.content.IntentFilter';
|
|
||||||
const package_NfcAdapter = 'android.nfc.NfcAdapter';
|
|
||||||
const package_Ndef = 'android.nfc.tech.Ndef';
|
|
||||||
const package_NdefFormatable = 'android.nfc.tech.NdefFormatable';
|
|
||||||
const package_Parcelable = 'android.os.Parcelable';
|
|
||||||
const package_String = 'java.lang.String';
|
|
||||||
|
|
||||||
let NfcAdapter;
|
// 状态管理
|
||||||
let NdefRecord;
|
const formData = ref({
|
||||||
let NdefMessage;
|
deviceId: "", //录入的id
|
||||||
let Uri;
|
});
|
||||||
let readyWriteData = false;
|
|
||||||
let readyRead = false;
|
|
||||||
let noNFC = false;
|
|
||||||
let techListsArray = [
|
|
||||||
['android.nfc.tech.IsoDep'],
|
|
||||||
['android.nfc.tech.NfcA'],
|
|
||||||
['android.nfc.tech.NfcB'],
|
|
||||||
['android.nfc.tech.NfcF'],
|
|
||||||
['android.nfc.tech.Nfcf'],
|
|
||||||
['android.nfc.tech.NfcV'],
|
|
||||||
['android.net.Uri'],
|
|
||||||
['android.nfc.tech.NdefFormatable'],
|
|
||||||
['android.nfc.tech.MifareClassi'],
|
|
||||||
['android.nfc.tech.MifareUltralight']
|
|
||||||
];
|
|
||||||
|
|
||||||
let text = '';// 要写入的数据
|
|
||||||
let readResult = '';
|
|
||||||
|
|
||||||
const isReading=ref(false)
|
|
||||||
const readStatus=ref(false);//读取状态 true 成功
|
const readStatus=ref(false);//读取状态 true 成功
|
||||||
const nfcResult=ref('')
|
|
||||||
|
|
||||||
// onLoad(() => {
|
// 变量初始化
|
||||||
// listenNFCStatus();
|
let NfcAdapter = null;
|
||||||
// })
|
let MifareClassic = null;
|
||||||
|
let isListening = false;
|
||||||
|
|
||||||
// 监听NFC状态
|
// 检查NFC状态
|
||||||
const listenNFCStatus=()=>{
|
function open() {
|
||||||
console.log("listenNFCStatus=====begin")
|
try {
|
||||||
try {
|
const main = plus.android.runtimeMainActivity();
|
||||||
let main = plus.android.runtimeMainActivity();
|
NfcAdapter = plus.android.importClass("android.nfc.NfcAdapter");
|
||||||
let Intent = plus.android.importClass('android.content.Intent');
|
const nfcAdapter = NfcAdapter.getDefaultAdapter(main);
|
||||||
let Activity = plus.android.importClass('android.app.Activity');
|
|
||||||
let PendingIntent = plus.android.importClass('android.app.PendingIntent');
|
|
||||||
let IntentFilter = plus.android.importClass('android.content.IntentFilter');
|
|
||||||
Uri = plus.android.importClass('android.net.Uri');
|
|
||||||
NfcAdapter = plus.android.importClass('android.nfc.NfcAdapter');
|
|
||||||
let nfcAdapter = NfcAdapter.getDefaultAdapter(main);
|
|
||||||
|
|
||||||
if(nfcAdapter == null){
|
if (!nfcAdapter) {
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
title: '设备不支持NFC!',
|
icon: "error",
|
||||||
icon: 'none'
|
title: "该设备不支持NFC",
|
||||||
})
|
duration: 5000,
|
||||||
noNFC = true;
|
});
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!nfcAdapter.isEnabled()) {
|
||||||
|
uni.showToast({
|
||||||
|
icon: "error",
|
||||||
|
title: "NFC功能未打开",
|
||||||
|
duration: 5000,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
initNFC();
|
||||||
|
} catch (e) {
|
||||||
|
console.error("打开NFC失败:", e);
|
||||||
|
uni.showToast({
|
||||||
|
icon: "error",
|
||||||
|
title: "初始化NFC失败",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化NFC监听
|
||||||
|
function initNFC() {
|
||||||
|
try {
|
||||||
|
const main = plus.android.runtimeMainActivity();
|
||||||
|
const Intent = plus.android.importClass("android.content.Intent");
|
||||||
|
const Activity = plus.android.importClass("android.app.Activity");
|
||||||
|
const PendingIntent = plus.android.importClass("android.app.PendingIntent");
|
||||||
|
const IntentFilter = plus.android.importClass(
|
||||||
|
"android.content.IntentFilter"
|
||||||
|
);
|
||||||
|
|
||||||
|
// 导入需要的NFC类
|
||||||
|
plus.android.importClass("android.nfc.NdefRecord");
|
||||||
|
plus.android.importClass("android.nfc.NdefMessage");
|
||||||
|
MifareClassic = plus.android.importClass("android.nfc.tech.MifareClassic");
|
||||||
|
NfcAdapter = plus.android.importClass("android.nfc.NfcAdapter");
|
||||||
|
|
||||||
|
const nfcAdapter = NfcAdapter.getDefaultAdapter(main);
|
||||||
|
if (!nfcAdapter || !nfcAdapter.isEnabled()) return;
|
||||||
|
|
||||||
|
// 创建Intent过滤器
|
||||||
|
const ndef = new IntentFilter("android.nfc.action.NDEF_DISCOVERED");
|
||||||
|
const tag = new IntentFilter("android.nfc.action.TAG_DISCOVERED");
|
||||||
|
const tech = new IntentFilter("android.nfc.action.TECH_DISCOVERED");
|
||||||
|
|
||||||
|
const intentFiltersArray = [ndef, tag, tech];
|
||||||
|
|
||||||
|
// 技术列表
|
||||||
|
const techListsArray = [
|
||||||
|
["android.nfc.tech.Ndef"],
|
||||||
|
["android.nfc.tech.IsoDep"],
|
||||||
|
["android.nfc.tech.NfcA"],
|
||||||
|
["android.nfc.tech.NfcB"],
|
||||||
|
["android.nfc.tech.NfcF"],
|
||||||
|
["android.nfc.tech.Nfcf"],
|
||||||
|
["android.nfc.tech.Nfef"],
|
||||||
|
["android.nfc.tech.Ndef"],
|
||||||
|
["android.nfc.tech.NfcV"],
|
||||||
|
["android.nfc.tech.NdefFormatable"],
|
||||||
|
["android.nfc.tech.MifareClassi"],
|
||||||
|
["android.nfc.tech.MifareUltralight"],
|
||||||
|
];
|
||||||
|
|
||||||
|
// 创建PendingIntent
|
||||||
|
const _intent = new Intent(main, main.getClass());
|
||||||
|
_intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
|
||||||
|
const pendingIntent = PendingIntent.getActivity(main, 0, _intent, 0);
|
||||||
|
// 监听NFC事件
|
||||||
|
startNFCListener();
|
||||||
|
|
||||||
|
// 启用前台调度
|
||||||
|
nfcAdapter.enableForegroundDispatch(
|
||||||
|
main,
|
||||||
|
pendingIntent,
|
||||||
|
intentFiltersArray,
|
||||||
|
techListsArray
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
console.error("初始化NFC失败:", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 开始NFC监听
|
||||||
|
function startNFCListener() {
|
||||||
|
if (isListening) return;
|
||||||
|
|
||||||
|
plus.globalEvent.addEventListener("newintent", handleNewIntent);
|
||||||
|
isListening = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 停止NFC监听
|
||||||
|
function stopNFCListener() {
|
||||||
|
if (isListening) {
|
||||||
|
plus.globalEvent.removeEventListener("newintent", handleNewIntent);
|
||||||
|
isListening = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理新的NFC意图
|
||||||
|
function handleNewIntent() {
|
||||||
|
readNFCData();
|
||||||
|
stopNFCListener();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 读取NFC数据
|
||||||
|
function readNFCData() {
|
||||||
|
try {
|
||||||
|
const main = plus.android.runtimeMainActivity();
|
||||||
|
const _intent = main.getIntent();
|
||||||
|
// 只处理 NDEF 数据
|
||||||
|
let rawMsgs = _intent.getParcelableArrayExtra(
|
||||||
|
"android.nfc.extra.NDEF_MESSAGES"
|
||||||
|
);
|
||||||
|
if (rawMsgs && rawMsgs.length > 0) {
|
||||||
|
try {
|
||||||
|
const records = rawMsgs[0].getRecords();
|
||||||
|
const result = records[0].getPayload();
|
||||||
|
// 取 deviceId
|
||||||
|
function bytesToString(result) {
|
||||||
|
return String.fromCharCode(...result);
|
||||||
}
|
}
|
||||||
|
formData.value.deviceId = bytesToString(result).substring(3);
|
||||||
if (!nfcAdapter.isEnabled()) {
|
emit("changeNfc", formData.value.deviceId);
|
||||||
uni.showToast({
|
readStatus.value=true;
|
||||||
title: '请在系统设置中先启用NFC功能!',
|
} catch (e) {
|
||||||
icon: 'none'
|
console.log("读取NDEF数据错误:", e);
|
||||||
});
|
uni.showToast({ title: "读取数据失败,请重新读取", icon: "none" });
|
||||||
noNFC = true;
|
}
|
||||||
return;
|
} else {
|
||||||
}else{
|
uni.showToast({ title: "未识别到NFC标签", icon: "none" });
|
||||||
noNFC = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
let intent = new Intent(main, main.getClass());
|
|
||||||
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
|
|
||||||
let pendingIntent = PendingIntent.getActivity(main, 0, intent, 0);
|
|
||||||
let ndef = new IntentFilter("android.nfc.action.TECH_DISCOVERED");
|
|
||||||
ndef.addDataType("*/*");
|
|
||||||
let intentFiltersArray = [ndef];
|
|
||||||
|
|
||||||
plus.globalEvent.addEventListener('newintent',function() {
|
|
||||||
// console.log('newintent running');
|
|
||||||
// 监听 NFC
|
|
||||||
setTimeout(nfcRuning(), 1000);
|
|
||||||
});
|
|
||||||
plus.globalEvent.addEventListener('pause',function(e) {
|
|
||||||
// console.log('pause running');
|
|
||||||
if (nfcAdapter) {
|
|
||||||
//关闭前台调度系统
|
|
||||||
//恢复默认状态
|
|
||||||
nfcAdapter.disableForegroundDispatch(main);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
plus.globalEvent.addEventListener('resume',function(e) {
|
|
||||||
// console.log('resume running');
|
|
||||||
if (nfcAdapter) {
|
|
||||||
//开启前台调度系统
|
|
||||||
nfcAdapter.enableForegroundDispatch(main, pendingIntent, intentFiltersArray, techListsArray);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
nfcAdapter.enableForegroundDispatch(main, pendingIntent, intentFiltersArray, techListsArray);
|
|
||||||
} catch (e) {
|
|
||||||
console.error(e);
|
|
||||||
}
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error("读取NFC数据失败:", e);
|
||||||
|
uni.showToast({ title: "读取数据失败,请重新读取", icon: "none" });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 运行nfc
|
|
||||||
const nfcRuning=()=>{
|
|
||||||
NdefRecord = plus.android.importClass("android.nfc.NdefRecord");
|
|
||||||
NdefMessage = plus.android.importClass("android.nfc.NdefMessage");
|
|
||||||
let main = plus.android.runtimeMainActivity();
|
|
||||||
let intent = main.getIntent();
|
|
||||||
console.log("action type:" + intent.getAction());
|
|
||||||
if (package_TECH_DISCOVERED == intent.getAction()) {
|
|
||||||
if (readyWriteData) {
|
|
||||||
write(intent);
|
|
||||||
readyWriteData = false;
|
|
||||||
} else if (readyRead) {
|
|
||||||
read(intent);
|
|
||||||
readyRead = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 写入nfc
|
|
||||||
const write=(intent)=>{
|
|
||||||
try {
|
|
||||||
toast('请勿移开标签 正在写入...');
|
|
||||||
console.log("text=" + text);
|
|
||||||
let textBytes = plus.android.invoke(text, "getBytes");
|
|
||||||
// image/jpeg text/plain
|
|
||||||
let uri = Uri.parse(text)
|
|
||||||
let message = new NdefMessage([new NdefRecord.createUri(uri)]);
|
|
||||||
console.log("====message===>", message)
|
|
||||||
let Ndef = plus.android.importClass('android.nfc.tech.Ndef');
|
|
||||||
let NdefFormatable = plus.android.importClass('android.nfc.tech.NdefFormatable');
|
|
||||||
let tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
|
|
||||||
let ndef = Ndef.get(tag);
|
|
||||||
if (ndef != null) {
|
|
||||||
// 待写入的数据长度
|
|
||||||
let size = message.toByteArray().length;
|
|
||||||
ndef.connect();
|
|
||||||
if (!ndef.isWritable()) {
|
|
||||||
toast('tag不允许写入!');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (ndef.getMaxSize() < size) {
|
|
||||||
toast('文件大小超出容量!');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ndef.writeNdefMessage(message);
|
|
||||||
toast('写入数据成功!');
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
let format = NdefFormatable.get(tag);
|
|
||||||
if (format != null) {
|
|
||||||
try {
|
|
||||||
format.connect();
|
|
||||||
format.format(message);
|
|
||||||
toast('格式化tag并且写入message');
|
|
||||||
return;
|
|
||||||
} catch (e) {
|
|
||||||
toast('格式化tag失败.');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
toast('Tag不支持NDEF');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
toast('写入失败');
|
|
||||||
console.log("error=" + e);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
// 读取nfc
|
|
||||||
const read=(intent)=>{
|
|
||||||
toast('请勿移开标签正在读取数据');
|
|
||||||
// NFC id
|
|
||||||
let bytesId = intent.getByteArrayExtra(NfcAdapter.EXTRA_ID);
|
|
||||||
let nfc_id = byteArrayToHexString(bytesId);
|
|
||||||
console.log('nfc_id:', nfc_id);
|
|
||||||
let Parcelable = plus.android.importClass("android.os.Parcelable");
|
|
||||||
let rawmsgs = intent.getParcelableArrayExtra("android.nfc.extra.NDEF_MESSAGES");
|
|
||||||
//let rawmsgs = intent.getParcelableArrayExtra();
|
|
||||||
|
|
||||||
// console.log('rawmsgs:', rawmsgs);
|
|
||||||
if(rawmsgs != null && rawmsgs.length > 0) {
|
|
||||||
let records = rawmsgs[0].getRecords();
|
|
||||||
let result = records[0].getPayload();
|
|
||||||
let data = plus.android.newObject("java.lang.String", result);
|
|
||||||
console.log('data=>'+data);
|
|
||||||
readResult = data;
|
|
||||||
readStatus.value = true;
|
|
||||||
nfcResult.value = data;
|
|
||||||
toast('NFC 数据:' + data);
|
|
||||||
// plus.runtime.openURL(data, function(res) {
|
|
||||||
// console.log("NFC 数据----", res);
|
|
||||||
// });
|
|
||||||
// return data;
|
|
||||||
}else{
|
|
||||||
toast('没有读取到数据');
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 字节转换
|
|
||||||
const byteArrayToHexString=(inarray)=>{ // converts byte arrays to string
|
|
||||||
let i, j, inn;
|
|
||||||
let hex = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"];
|
|
||||||
let out = "";
|
|
||||||
|
|
||||||
for(j = 0; j < inarray.length; ++j) {
|
|
||||||
inn = inarray[j] & 0xff;
|
|
||||||
i = (inn >>> 4) & 0x0f;
|
|
||||||
out += hex[i];
|
|
||||||
i = inn & 0x0f;
|
|
||||||
out += hex[i];
|
|
||||||
}
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 正式调用写入
|
|
||||||
const writeData= ()=>{
|
|
||||||
if(noNFC){
|
|
||||||
toast('请检查设备是否支持并开启 NFC 功能!');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// 监听事件,触发条件
|
|
||||||
readyWriteData = true;
|
|
||||||
toast('请将NFC标签靠近!');
|
|
||||||
}
|
|
||||||
|
|
||||||
// 正式调用读
|
|
||||||
const readData= ()=>{
|
|
||||||
if(noNFC){
|
|
||||||
toast('请检查设备是否支持并开启 NFC 功能!');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// 监听事件,触发条件
|
|
||||||
readyRead = true;
|
|
||||||
isReading.value = true;
|
|
||||||
readStatus.value = false;
|
|
||||||
// toast('请将NFC标签靠近!');
|
|
||||||
}
|
|
||||||
|
|
||||||
// 提示
|
|
||||||
const toast = (content)=>{
|
|
||||||
uni.showToast({
|
|
||||||
title: content,
|
|
||||||
icon: 'none'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 回调父组件
|
|
||||||
const emit = defineEmits(['close','confirm'])
|
|
||||||
const handleClose = ()=>{
|
const handleClose = ()=>{
|
||||||
emit('close');
|
emit('close');
|
||||||
}
|
}
|
||||||
const handleConfirm= ()=>{
|
|
||||||
emit('confirm',nfcResult.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
// 暴露方法给父组件
|
open();
|
||||||
defineExpose({
|
|
||||||
listenNFCStatus
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 组件卸载前清理
|
||||||
|
onBeforeUnmount(() => {
|
||||||
|
stopNFCListener();
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
open
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ const props = defineProps({
|
|||||||
})
|
})
|
||||||
|
|
||||||
const isEnlarged = ref(props.visible);
|
const isEnlarged = ref(props.visible);
|
||||||
const mediaUrl = ref(props.url);//http://192.168.236.184:9000/718ys-test/polling/2483ee76b28b4d43b87c13386dad90bb.jpg
|
const mediaUrl = ref(props.url);
|
||||||
// const mediaType = ref('');//类型
|
// const mediaType = ref('');//类型
|
||||||
// 显示隐藏
|
// 显示隐藏
|
||||||
watch(() => props.visible, (newVal, oldVal) => {
|
watch(() => props.visible, (newVal, oldVal) => {
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ export const AGREEWELCOME_KEY="agreewelcome";
|
|||||||
// clientId 默认写2
|
// clientId 默认写2
|
||||||
export const CLIENT_ID="2";
|
export const CLIENT_ID="2";
|
||||||
// #区分内外网 //1-内网,2-外网
|
// #区分内外网 //1-内网,2-外网
|
||||||
export const NETWORK_ENV=1;
|
export const NETWORK_ENV=2;
|
||||||
|
|
||||||
// miniIo 参数对象
|
// miniIo 参数对象
|
||||||
export const MINIO_KEY="minioKey"
|
export const MINIO_KEY="minioKey"
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
"name" : "718友晟",
|
"name" : "718友晟",
|
||||||
"appid" : "__UNI__4C459F4",
|
"appid" : "__UNI__4C459F4",
|
||||||
"description" : "",
|
"description" : "",
|
||||||
"versionName" : "1.0.0",
|
"versionName" : "1.0.2",
|
||||||
"versionCode" : "100",
|
"versionCode" : "100",
|
||||||
"transformPx" : false,
|
"transformPx" : false,
|
||||||
/* 5+App特有相关 */
|
/* 5+App特有相关 */
|
||||||
@@ -61,7 +61,8 @@
|
|||||||
"<uses-permission android:name=\"android.permission.BROADCAST_PACKAGE_REPLACED\" />",
|
"<uses-permission android:name=\"android.permission.BROADCAST_PACKAGE_REPLACED\" />",
|
||||||
"<uses-permission android:name=\"android.permission.RESTART_PACKAGES\" />",
|
"<uses-permission android:name=\"android.permission.RESTART_PACKAGES\" />",
|
||||||
"<uses-permission android:name=\"android.permission.REQUEST_INSTALL_PACKAGES\" />",
|
"<uses-permission android:name=\"android.permission.REQUEST_INSTALL_PACKAGES\" />",
|
||||||
"<uses-permission android:name=\"android.permission.NFC\" />"
|
"<uses-permission android:name=\"android.permission.NFC\"/>",
|
||||||
|
"<uses-feature android:name=\"android.hardware.nfc\" android:required=\"true\"/>"
|
||||||
],
|
],
|
||||||
"abiFilters" : [ "armeabi-v7a", "arm64-v8a" ],
|
"abiFilters" : [ "armeabi-v7a", "arm64-v8a" ],
|
||||||
"minSdkVersion" : 23,
|
"minSdkVersion" : 23,
|
||||||
|
|||||||
@@ -663,12 +663,6 @@
|
|||||||
"navigationBarTitleText": ""
|
"navigationBarTitleText": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"path": "pages/business/polling/nfcTest/nfcTemplate",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": ""
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"path": "pages/business/polling/nfcTest/index",
|
"path": "pages/business/polling/nfcTest/index",
|
||||||
"style": {
|
"style": {
|
||||||
|
|||||||
@@ -9,11 +9,11 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import nfc from '@/utils/ouu-nfc.js'
|
import nfc from './ouu-nfc.js'
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
inputText: 'https://baidu.com'
|
inputText: 'testtesttesttesttestfdsf'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onLoad() {
|
onLoad() {
|
||||||
|
|||||||
@@ -1,784 +0,0 @@
|
|||||||
<template>
|
|
||||||
<view class="container" @touchstart="touchStart" @touchend="touchEnd">
|
|
||||||
<view class="header">
|
|
||||||
<text class="title">NFC卡片读取器</text>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<view class="content" :class="{ 'landscape-layout': isLandscape }">
|
|
||||||
<!-- NFC读取按钮 - 平板适配:按钮尺寸不小于48px×48px -->
|
|
||||||
<button class="nfc-button" @click="startNFCReading" :disabled="isReading">
|
|
||||||
<text v-if="!isReading">开始NFC读取</text>
|
|
||||||
<view v-else class="loading-wrapper">
|
|
||||||
<view class="loading-spinner"></view>
|
|
||||||
<text>正在读取中...</text>
|
|
||||||
</view>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<!-- 读取状态提示 -->
|
|
||||||
<view class="status-section">
|
|
||||||
<text class="status-text" :class="statusClass">{{ statusMessage }}</text>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 读取结果显示区域 -->
|
|
||||||
<view class="result-section" v-if="nfcResult">
|
|
||||||
<view class="result-header">
|
|
||||||
<text class="result-label">NFC ID:</text>
|
|
||||||
<button class="copy-button" @click="copyToClipboard">复制</button>
|
|
||||||
</view>
|
|
||||||
<text class="result-value">{{ nfcResult }}</text>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 操作提示 -->
|
|
||||||
<view class="instruction">
|
|
||||||
<text class="instruction-title">操作指南:</text>
|
|
||||||
<text class="instruction-text">1. 确保设备NFC功能已开启</text>
|
|
||||||
<text class="instruction-text">2. 将NFC卡片贴近设备感应区域</text>
|
|
||||||
<text class="instruction-text">3. 听到提示音或感受到震动时,表示读取成功</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 底部信息 -->
|
|
||||||
<view class="footer">
|
|
||||||
<text class="footer-text">支持卡片类型: ISO14443A/B, Mifare, NFC-V, FeliCa</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import nfcUtil from "@/utils/hexiii-nfc.js"
|
|
||||||
|
|
||||||
export default {
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
isReading: false,
|
|
||||||
statusMessage: '准备就绪',
|
|
||||||
statusClass: 'status-ready',
|
|
||||||
nfcResult: '',
|
|
||||||
statusHistory: [], // 记录状态历史
|
|
||||||
isLandscape: false, // 是否横屏
|
|
||||||
screenWidth: 0, // 屏幕宽度
|
|
||||||
screenHeight: 0, // 屏幕高度
|
|
||||||
deviceInfo: null, // 设备信息
|
|
||||||
touchStartTime: 0, // 触摸开始时间
|
|
||||||
touchStartX: 0, // 触摸开始X坐标
|
|
||||||
touchStartY: 0 // 触摸开始Y坐标
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
onLoad() {
|
|
||||||
// 获取设备信息
|
|
||||||
this._getDeviceInfo();
|
|
||||||
// 页面加载时检查NFC状态
|
|
||||||
this._checkNFCStatus();
|
|
||||||
// 添加屏幕旋转监听
|
|
||||||
uni.onWindowResize(this._onWindowResize);
|
|
||||||
},
|
|
||||||
|
|
||||||
onShow() {
|
|
||||||
// 页面显示时重新检查NFC状态
|
|
||||||
this._checkNFCStatus();
|
|
||||||
},
|
|
||||||
|
|
||||||
onHide() {
|
|
||||||
// 页面隐藏时暂停NFC监听
|
|
||||||
if (this.isReading) {
|
|
||||||
nfcUtil.stopNFCListening();
|
|
||||||
this.isReading = false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
onUnload() {
|
|
||||||
// 页面卸载时清理NFC资源
|
|
||||||
nfcUtil.cleanupNFC();
|
|
||||||
// 移除屏幕旋转监听
|
|
||||||
uni.offWindowResize(this._onWindowResize);
|
|
||||||
},
|
|
||||||
|
|
||||||
methods: {
|
|
||||||
/**
|
|
||||||
* 获取设备信息
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
_getDeviceInfo() {
|
|
||||||
uni.getSystemInfo({
|
|
||||||
success: (res) => {
|
|
||||||
this.deviceInfo = res;
|
|
||||||
this.screenWidth = res.screenWidth;
|
|
||||||
this.screenHeight = res.screenHeight;
|
|
||||||
// 判断是否为横屏
|
|
||||||
this.isLandscape = res.windowWidth > res.windowHeight;
|
|
||||||
console.log('设备信息:', res);
|
|
||||||
console.log('当前屏幕方向:', this.isLandscape ? '横屏' : '竖屏');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 监听屏幕旋转
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
_onWindowResize(res) {
|
|
||||||
if (res) {
|
|
||||||
const isLandscape = res.windowWidth > res.windowHeight;
|
|
||||||
// 屏幕方向改变时更新状态
|
|
||||||
if (this.isLandscape !== isLandscape) {
|
|
||||||
this.isLandscape = isLandscape;
|
|
||||||
console.log('屏幕旋转为:', isLandscape ? '横屏' : '竖屏');
|
|
||||||
// 屏幕旋转时重新调整布局
|
|
||||||
this._adjustLayoutForOrientation();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据屏幕方向调整布局
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
_adjustLayoutForOrientation() {
|
|
||||||
// 可以在这里进行特定的布局调整
|
|
||||||
// 例如:横屏时调整按钮位置、改变元素大小等
|
|
||||||
// 目前主要通过CSS媒体查询实现,这里预留接口
|
|
||||||
console.log('调整布局适应屏幕方向');
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 开始NFC读取
|
|
||||||
*/
|
|
||||||
async startNFCReading() {
|
|
||||||
// 提供触觉反馈 - 平板用户体验增强
|
|
||||||
this._provideHapticFeedback();
|
|
||||||
|
|
||||||
// 设置读取状态
|
|
||||||
this.isReading = true;
|
|
||||||
this.statusMessage = '等待NFC卡片...';
|
|
||||||
this.statusClass = 'status-waiting';
|
|
||||||
this._addStatusHistory('开始读取NFC');
|
|
||||||
|
|
||||||
try {
|
|
||||||
// 调用NFC读取功能
|
|
||||||
this._addStatusHistory('正在监听NFC信号...');
|
|
||||||
const nfcId = await nfcUtil.listenNFCStatus();
|
|
||||||
|
|
||||||
// 确保ID有效
|
|
||||||
if (nfcId) {
|
|
||||||
// 成功读取,提供触觉反馈
|
|
||||||
this._provideHapticFeedback('success');
|
|
||||||
|
|
||||||
// 播放成功提示音
|
|
||||||
this._playBeepSound();
|
|
||||||
|
|
||||||
// 显示结果并输出到控制台
|
|
||||||
this.nfcResult = nfcId;
|
|
||||||
console.log('NFC读取结果:', nfcId);
|
|
||||||
|
|
||||||
// 更新状态
|
|
||||||
this.statusMessage = '读取成功';
|
|
||||||
this.statusClass = 'status-success';
|
|
||||||
this._addStatusHistory(`成功读取ID: ${nfcId}`);
|
|
||||||
|
|
||||||
// 显示成功提示框
|
|
||||||
uni.showModal({
|
|
||||||
title: '读取成功',
|
|
||||||
content: `NFC ID: ${nfcId}\n\n是否复制到剪贴板?`,
|
|
||||||
showCancel: true,
|
|
||||||
cancelText: '取消',
|
|
||||||
confirmText: '复制',
|
|
||||||
success: (res) => {
|
|
||||||
if (res.confirm) {
|
|
||||||
this.copyToClipboard();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
this.statusMessage = '未读取到NFC数据';
|
|
||||||
this.statusClass = 'status-error';
|
|
||||||
this._addStatusHistory('未读取到NFC数据');
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error('NFC读取错误:', error);
|
|
||||||
|
|
||||||
// 错误情况,提供触觉反馈
|
|
||||||
this._provideHapticFeedback('error');
|
|
||||||
|
|
||||||
// 根据错误类型显示不同的提示
|
|
||||||
let errorMsg = '读取失败';
|
|
||||||
if (error.message.includes('不支持NFC')) {
|
|
||||||
errorMsg = '设备不支持NFC功能';
|
|
||||||
} else if (error.message.includes('未开启')) {
|
|
||||||
errorMsg = '请先在系统设置中开启NFC功能';
|
|
||||||
} else if (error.message.includes('超时')) {
|
|
||||||
errorMsg = '读取超时,请重试';
|
|
||||||
} else {
|
|
||||||
errorMsg = '读取失败: ' + error.message;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.statusMessage = errorMsg;
|
|
||||||
this.statusClass = 'status-error';
|
|
||||||
this._addStatusHistory(`错误: ${error.message}`);
|
|
||||||
|
|
||||||
// 显示错误提示
|
|
||||||
uni.showModal({
|
|
||||||
title: '读取失败',
|
|
||||||
content: errorMsg,
|
|
||||||
showCancel: false,
|
|
||||||
confirmText: '确定'
|
|
||||||
});
|
|
||||||
} finally {
|
|
||||||
// 重置读取状态
|
|
||||||
this.isReading = false;
|
|
||||||
|
|
||||||
// 3秒后重置状态消息
|
|
||||||
setTimeout(() => {
|
|
||||||
if (!this.isReading) {
|
|
||||||
this.statusMessage = '准备就绪';
|
|
||||||
this.statusClass = 'status-ready';
|
|
||||||
}
|
|
||||||
}, 3000);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 复制NFC ID到剪贴板
|
|
||||||
*/
|
|
||||||
copyToClipboard() {
|
|
||||||
if (this.nfcResult) {
|
|
||||||
uni.setClipboardData({
|
|
||||||
data: this.nfcResult,
|
|
||||||
success: () => {
|
|
||||||
uni.showToast({
|
|
||||||
title: '已复制到剪贴板',
|
|
||||||
icon: 'success',
|
|
||||||
duration: 2000
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 检查NFC状态
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
_checkNFCStatus() {
|
|
||||||
try {
|
|
||||||
// 尝试初始化NFC适配器检查状态
|
|
||||||
const main = plus.android.runtimeMainActivity();
|
|
||||||
const NfcAdapter = plus.android.importClass('android.nfc.NfcAdapter');
|
|
||||||
const nfcAdapter = NfcAdapter.getDefaultAdapter(main);
|
|
||||||
|
|
||||||
if (nfcAdapter == null) {
|
|
||||||
this.statusMessage = '设备不支持NFC功能';
|
|
||||||
this.statusClass = 'status-error';
|
|
||||||
} else if (!nfcAdapter.isEnabled()) {
|
|
||||||
this.statusMessage = 'NFC功能未开启,请在系统设置中开启';
|
|
||||||
this.statusClass = 'status-warning';
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.log('NFC状态检查失败,可能在非Android环境');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 提供触觉反馈
|
|
||||||
* @private
|
|
||||||
* @param {string} type - 反馈类型: 'success', 'error'或默认
|
|
||||||
*/
|
|
||||||
_provideHapticFeedback(type = 'default') {
|
|
||||||
try {
|
|
||||||
// 在Android设备上提供震动反馈
|
|
||||||
const VIBRATOR_SERVICE = 'vibrator';
|
|
||||||
const Context = plus.android.importClass('android.content.Context');
|
|
||||||
const main = plus.android.runtimeMainActivity();
|
|
||||||
const vibrator = main.getSystemService(VIBRATOR_SERVICE);
|
|
||||||
|
|
||||||
// 根据类型设置不同的震动模式
|
|
||||||
if (vibrator) {
|
|
||||||
if (type === 'success') {
|
|
||||||
// 成功震动模式: 短震动
|
|
||||||
vibrator.vibrate(100);
|
|
||||||
} else if (type === 'error') {
|
|
||||||
// 错误震动模式: 长震动
|
|
||||||
vibrator.vibrate(300);
|
|
||||||
} else {
|
|
||||||
// 默认震动模式: 轻微震动
|
|
||||||
vibrator.vibrate(50);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
// 如果设备不支持震动或没有权限,忽略错误
|
|
||||||
console.log('无法提供震动反馈:', e.message);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 播放提示音
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
_playBeepSound() {
|
|
||||||
try {
|
|
||||||
// 使用系统默认提示音
|
|
||||||
const AudioManager = plus.android.importClass('android.media.AudioManager');
|
|
||||||
const ToneGenerator = plus.android.importClass('android.media.ToneGenerator');
|
|
||||||
const main = plus.android.runtimeMainActivity();
|
|
||||||
|
|
||||||
const toneGen = new ToneGenerator(AudioManager.STREAM_NOTIFICATION, 100);
|
|
||||||
toneGen.startTone(ToneGenerator.TONE_PROP_BEEP);
|
|
||||||
} catch (e) {
|
|
||||||
// 如果无法播放提示音,忽略错误
|
|
||||||
console.log('无法播放提示音:', e.message);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 添加状态历史记录
|
|
||||||
* @private
|
|
||||||
* @param {string} message - 状态消息
|
|
||||||
*/
|
|
||||||
_addStatusHistory(message) {
|
|
||||||
const timestamp = new Date().toLocaleTimeString();
|
|
||||||
this.statusHistory.push(`[${timestamp}] ${message}`);
|
|
||||||
// 只保留最近10条记录
|
|
||||||
if (this.statusHistory.length > 10) {
|
|
||||||
this.statusHistory.shift();
|
|
||||||
}
|
|
||||||
console.log(`[NFC状态] ${message}`);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 触摸开始事件处理(用于长按等手势识别)
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
touchStart(event) {
|
|
||||||
this.touchStartTime = Date.now();
|
|
||||||
this.touchStartX = event.touches[0].clientX;
|
|
||||||
this.touchStartY = event.touches[0].clientY;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 触摸结束事件处理(用于长按等手势识别)
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
touchEnd(event) {
|
|
||||||
// 可以在这里添加手势识别逻辑
|
|
||||||
// 例如:长按识别、滑动检测等
|
|
||||||
const touchEndTime = Date.now();
|
|
||||||
const touchEndX = event.changedTouches[0].clientX;
|
|
||||||
const touchEndY = event.changedTouches[0].clientY;
|
|
||||||
|
|
||||||
// 计算触摸时间和移动距离
|
|
||||||
const touchDuration = touchEndTime - this.touchStartTime;
|
|
||||||
const distanceX = Math.abs(touchEndX - this.touchStartX);
|
|
||||||
const distanceY = Math.abs(touchEndY - this.touchStartY);
|
|
||||||
|
|
||||||
// 长按检测(超过500ms且移动距离小于10px)
|
|
||||||
if (touchDuration > 500 && distanceX < 10 && distanceY < 10) {
|
|
||||||
console.log('长按操作');
|
|
||||||
// 长按可以触发特殊功能,如显示详细信息
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.container {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
min-height: 100vh;
|
|
||||||
padding: 32rpx;
|
|
||||||
background-color: #f5f5f5;
|
|
||||||
/* 增加背景纹理,提升平板视觉体验 */
|
|
||||||
background-image: linear-gradient(45deg, rgba(0, 0, 0, 0.02) 25%, transparent 25%, transparent 75%, rgba(0, 0, 0, 0.02) 75%, rgba(0, 0, 0, 0.02)),
|
|
||||||
linear-gradient(45deg, rgba(0, 0, 0, 0.02) 25%, transparent 25%, transparent 75%, rgba(0, 0, 0, 0.02) 75%, rgba(0, 0, 0, 0.02));
|
|
||||||
background-size: 200rpx 200rpx;
|
|
||||||
background-position: 0 0, 100rpx 100rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 横屏布局 */
|
|
||||||
.content.landscape-layout {
|
|
||||||
/* 横屏时优化内容区布局 */
|
|
||||||
max-width: 960rpx;
|
|
||||||
margin: 0 auto;
|
|
||||||
/* 为横屏模式添加微妙的阴影效果 */
|
|
||||||
box-shadow: 0 0 20rpx rgba(0, 0, 0, 0.05);
|
|
||||||
background-color: rgba(255, 255, 255, 0.7);
|
|
||||||
border-radius: 16rpx;
|
|
||||||
padding: 40rpx;
|
|
||||||
backdrop-filter: blur(5rpx);
|
|
||||||
}
|
|
||||||
|
|
||||||
.header {
|
|
||||||
text-align: center;
|
|
||||||
margin-bottom: 48rpx;
|
|
||||||
padding: 20rpx 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.title {
|
|
||||||
font-size: 48rpx;
|
|
||||||
font-weight: bold;
|
|
||||||
color: #212121;
|
|
||||||
/* 平板适配:增加文字阴影提升可读性 */
|
|
||||||
text-shadow: 0 2rpx 4rpx rgba(0, 0, 0, 0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.content {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
flex: 1;
|
|
||||||
padding: 32rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* NFC按钮 - 平板适配:按钮高度不小于60px */
|
|
||||||
.nfc-button {
|
|
||||||
width: 600rpx;
|
|
||||||
height: 120rpx;
|
|
||||||
line-height: 120rpx;
|
|
||||||
font-size: 36rpx;
|
|
||||||
background-color: #1976D2;
|
|
||||||
color: white;
|
|
||||||
border-radius: 8rpx;
|
|
||||||
margin-bottom: 48rpx;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
/* 平板适配:增加按钮阴影和触摸反馈 */
|
|
||||||
box-shadow: 0 4rpx 12rpx rgba(25, 118, 210, 0.3);
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
position: relative;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 水波纹效果 - 符合Android设计规范 */
|
|
||||||
.nfc-button::after {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
top: 50%;
|
|
||||||
left: 50%;
|
|
||||||
width: 0;
|
|
||||||
height: 0;
|
|
||||||
border-radius: 50%;
|
|
||||||
background-color: rgba(255, 255, 255, 0.3);
|
|
||||||
transform: translate(-50%, -50%);
|
|
||||||
transition: width 0.6s, height 0.6s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nfc-button:active::after {
|
|
||||||
width: 120%;
|
|
||||||
height: 120%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nfc-button:active {
|
|
||||||
background-color: #1565C0;
|
|
||||||
transform: translateY(2rpx);
|
|
||||||
box-shadow: 0 2rpx 6rpx rgba(25, 118, 210, 0.3);
|
|
||||||
}
|
|
||||||
|
|
||||||
.nfc-button[disabled] {
|
|
||||||
background-color: #90CAF9;
|
|
||||||
box-shadow: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 加载动画 */
|
|
||||||
.loading-wrapper {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
gap: 16rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.loading-spinner {
|
|
||||||
width: 32rpx;
|
|
||||||
height: 32rpx;
|
|
||||||
border: 4rpx solid rgba(255, 255, 255, 0.3);
|
|
||||||
border-top: 4rpx solid white;
|
|
||||||
border-radius: 50%;
|
|
||||||
animation: spin 1s linear infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes spin {
|
|
||||||
0% { transform: rotate(0deg); }
|
|
||||||
100% { transform: rotate(360deg); }
|
|
||||||
}
|
|
||||||
|
|
||||||
.status-section {
|
|
||||||
margin-bottom: 32rpx;
|
|
||||||
padding: 24rpx 32rpx;
|
|
||||||
border-radius: 8rpx;
|
|
||||||
background-color: white;
|
|
||||||
min-width: 500rpx;
|
|
||||||
text-align: center;
|
|
||||||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.08);
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.status-text {
|
|
||||||
font-size: 32rpx;
|
|
||||||
font-weight: 500;
|
|
||||||
transition: color 0.3s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.status-ready {
|
|
||||||
color: #616161;
|
|
||||||
}
|
|
||||||
|
|
||||||
.status-waiting {
|
|
||||||
color: #1976D2;
|
|
||||||
animation: pulse 2s infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes pulse {
|
|
||||||
0% { opacity: 1; }
|
|
||||||
50% { opacity: 0.7; }
|
|
||||||
100% { opacity: 1; }
|
|
||||||
}
|
|
||||||
|
|
||||||
.status-success {
|
|
||||||
color: #4CAF50;
|
|
||||||
}
|
|
||||||
|
|
||||||
.status-error {
|
|
||||||
color: #F44336;
|
|
||||||
}
|
|
||||||
|
|
||||||
.status-warning {
|
|
||||||
color: #FF9800;
|
|
||||||
}
|
|
||||||
|
|
||||||
.result-section {
|
|
||||||
background-color: white;
|
|
||||||
padding: 32rpx;
|
|
||||||
border-radius: 8rpx;
|
|
||||||
margin-bottom: 32rpx;
|
|
||||||
min-width: 500rpx;
|
|
||||||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.08);
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.result-section:hover {
|
|
||||||
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.12);
|
|
||||||
}
|
|
||||||
|
|
||||||
.result-header {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
margin-bottom: 16rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.result-label {
|
|
||||||
font-size: 28rpx;
|
|
||||||
color: #757575;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
.copy-button {
|
|
||||||
min-width: 120rpx;
|
|
||||||
height: 60rpx;
|
|
||||||
line-height: 60rpx;
|
|
||||||
font-size: 24rpx;
|
|
||||||
background-color: #E3F2FD;
|
|
||||||
color: #1976D2;
|
|
||||||
border-radius: 6rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.copy-button:active {
|
|
||||||
background-color: #BBDEFB;
|
|
||||||
}
|
|
||||||
|
|
||||||
.result-value {
|
|
||||||
font-size: 36rpx;
|
|
||||||
font-family: monospace;
|
|
||||||
color: #212121;
|
|
||||||
word-break: break-all;
|
|
||||||
line-height: 1.5;
|
|
||||||
padding: 16rpx;
|
|
||||||
background-color: #FAFAFA;
|
|
||||||
border-radius: 6rpx;
|
|
||||||
border: 1rpx solid #EEEEEE;
|
|
||||||
}
|
|
||||||
|
|
||||||
.instruction {
|
|
||||||
margin-top: 32rpx;
|
|
||||||
background-color: white;
|
|
||||||
padding: 32rpx;
|
|
||||||
border-radius: 8rpx;
|
|
||||||
min-width: 500rpx;
|
|
||||||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.08);
|
|
||||||
}
|
|
||||||
|
|
||||||
.instruction-title {
|
|
||||||
font-size: 32rpx;
|
|
||||||
font-weight: bold;
|
|
||||||
color: #212121;
|
|
||||||
margin-bottom: 16rpx;
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.instruction-text {
|
|
||||||
font-size: 28rpx;
|
|
||||||
color: #757575;
|
|
||||||
line-height: 1.6;
|
|
||||||
display: block;
|
|
||||||
margin-bottom: 12rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.footer {
|
|
||||||
margin-top: 40rpx;
|
|
||||||
padding: 24rpx;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.footer-text {
|
|
||||||
font-size: 24rpx;
|
|
||||||
color: #9E9E9E;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 平板横屏适配 */
|
|
||||||
@media screen and (orientation: landscape) {
|
|
||||||
/* 横屏时优化元素排布 */
|
|
||||||
.container {
|
|
||||||
padding: 24rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.header {
|
|
||||||
margin-bottom: 32rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 在横屏模式下,核心操作区放在右侧,便于右手操作 */
|
|
||||||
.content {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: flex-start;
|
|
||||||
padding-top: 40rpx;
|
|
||||||
min-height: calc(100vh - 100rpx);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 横屏时增大按钮点击区域 */
|
|
||||||
.nfc-button {
|
|
||||||
width: 500rpx;
|
|
||||||
height: 130rpx;
|
|
||||||
line-height: 130rpx;
|
|
||||||
/* 放在屏幕右侧,便于右手操作 */
|
|
||||||
align-self: flex-end;
|
|
||||||
margin-right: 60rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 状态区域也放在右侧 */
|
|
||||||
.status-section {
|
|
||||||
min-width: 600rpx;
|
|
||||||
align-self: flex-end;
|
|
||||||
margin-right: 60rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 结果区域在横屏时更宽,方便查看完整信息 */
|
|
||||||
.result-section {
|
|
||||||
min-width: 800rpx;
|
|
||||||
margin: 32rpx auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 操作指南放在左侧,不干扰核心操作区 */
|
|
||||||
.instruction {
|
|
||||||
position: absolute;
|
|
||||||
left: 40rpx;
|
|
||||||
top: 180rpx;
|
|
||||||
min-width: 400rpx;
|
|
||||||
max-width: 450rpx;
|
|
||||||
padding: 24rpx;
|
|
||||||
background-color: rgba(255, 255, 255, 0.95);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 底部信息在横屏时放在左侧底部 */
|
|
||||||
.footer {
|
|
||||||
position: absolute;
|
|
||||||
left: 40rpx;
|
|
||||||
bottom: 30rpx;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 安卓平板特殊适配 */
|
|
||||||
@media (min-width: 768px) and (min-height: 500px) {
|
|
||||||
/* 优化触控体验:确保所有可点击元素至少有48px x 48px的点击区域 */
|
|
||||||
.nfc-button {
|
|
||||||
min-height: 120rpx; /* 约等于48px在rpx中的值 */
|
|
||||||
min-width: 300rpx;
|
|
||||||
touch-action: manipulation; /* 防止双击缩放,提高点击响应速度 */
|
|
||||||
}
|
|
||||||
|
|
||||||
.copy-button {
|
|
||||||
min-height: 80rpx;
|
|
||||||
min-width: 160rpx;
|
|
||||||
touch-action: manipulation;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 平板上增大字体和间距,提升可读性 */
|
|
||||||
.title {
|
|
||||||
letter-spacing: 2rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.status-text {
|
|
||||||
letter-spacing: 1rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.result-value {
|
|
||||||
letter-spacing: 2rpx;
|
|
||||||
font-size: 42rpx; /* 在平板上进一步增大ID显示字体 */
|
|
||||||
padding: 24rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 大型平板适配(10英寸以上) */
|
|
||||||
@media (min-width: 1024px) {
|
|
||||||
.container {
|
|
||||||
padding: 48rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.title {
|
|
||||||
font-size: 64rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nfc-button {
|
|
||||||
width: 700rpx;
|
|
||||||
height: 150rpx;
|
|
||||||
line-height: 150rpx;
|
|
||||||
font-size: 44rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.status-section,
|
|
||||||
.result-section {
|
|
||||||
min-width: 900rpx;
|
|
||||||
padding: 40rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 大型平板上,优化内容区的最大宽度,避免内容过宽影响阅读 */
|
|
||||||
.content {
|
|
||||||
max-width: 70vw;
|
|
||||||
margin: 0 auto;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 适配不同尺寸的平板 */
|
|
||||||
@media screen and (min-width: 768px) {
|
|
||||||
.title {
|
|
||||||
font-size: 56rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nfc-button {
|
|
||||||
width: 700rpx;
|
|
||||||
height: 140rpx;
|
|
||||||
line-height: 140rpx;
|
|
||||||
font-size: 40rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.status-text {
|
|
||||||
font-size: 36rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.result-value {
|
|
||||||
font-size: 40rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -94,10 +94,20 @@
|
|||||||
<view>{{ item.pointName }}</view>
|
<view>{{ item.pointName }}</view>
|
||||||
</view>
|
</view>
|
||||||
<!-- #ifdef APP-PLUS -->
|
<!-- #ifdef APP-PLUS -->
|
||||||
<view class="r-right" @click.stop="initNFC(item,index)">
|
<view class="r-right r-active" v-if="item.resultContent" @click.stop="initNFC(item,index)">
|
||||||
|
<img :src="'static/images/polling/icon-NFCcode-b.png'" class="img-nfc" />
|
||||||
|
<view>识别成功<view class="r-font">点击再次识别</view></view>
|
||||||
|
</view>
|
||||||
|
<view class="r-right" v-else @click.stop="initNFC(item,index)">
|
||||||
<img :src="'static/images/polling/icon-NFCcode.png'" class="img-nfc" /> 开始识别
|
<img :src="'static/images/polling/icon-NFCcode.png'" class="img-nfc" /> 开始识别
|
||||||
</view>
|
</view>
|
||||||
<!-- #endif -->
|
<!-- #endif -->
|
||||||
|
<!-- #ifndef APP-PLUS -->
|
||||||
|
<view class="r-right r-active">
|
||||||
|
<img :src="'static/images/polling/icon-NFCcode-b.png'" class="img-nfc" />
|
||||||
|
<view>识别成功</view>
|
||||||
|
</view>
|
||||||
|
<!-- #endif -->
|
||||||
</view>
|
</view>
|
||||||
</block>
|
</block>
|
||||||
<!-- 扫码 -->
|
<!-- 扫码 -->
|
||||||
@@ -204,17 +214,21 @@
|
|||||||
@close="handlePreviewClose"
|
@close="handlePreviewClose"
|
||||||
></mediaPreview>
|
></mediaPreview>
|
||||||
|
|
||||||
<!-- NFC 弹窗 -->
|
|
||||||
<NFCTemplate v-if="nfcShow" ref="nfcTemplateRef"
|
<!-- NFC 数据读取 -->
|
||||||
@close="nfcClose"
|
<NFCTemplate
|
||||||
@confirm="nfcConfirm"
|
v-if="nfcShow"
|
||||||
></NFCTemplate>
|
ref="nfcReaderRef"
|
||||||
|
@changeNfc="handleNfcData"
|
||||||
|
@close="nfcClose"
|
||||||
|
/>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref,onMounted,onUnmounted,nextTick,computed,reactive,getCurrentInstance } from 'vue'
|
import { ref,onMounted,onUnmounted,nextTick,computed,reactive,getCurrentInstance } from 'vue'
|
||||||
import { onLoad,onHide} from '@dcloudio/uni-app';
|
import { onLoad,onHide} from '@dcloudio/uni-app';
|
||||||
import { MINIO_KEY } from '@/enums/cacheEnums';
|
import { MINIO_KEY } from '@/enums/cacheEnums';
|
||||||
|
|
||||||
import customHeader from '@/components/customHeader.vue';
|
import customHeader from '@/components/customHeader.vue';
|
||||||
import MescrollUni from 'mescroll-uni/mescroll-uni.vue';
|
import MescrollUni from 'mescroll-uni/mescroll-uni.vue';
|
||||||
import multipleSelect from "@/components/multipleSelect.vue";
|
import multipleSelect from "@/components/multipleSelect.vue";
|
||||||
@@ -222,6 +236,7 @@ import pollingShowModal from "@/components/pollingShowModal.vue";
|
|||||||
import customShowModal from "@/components/customShowModal.vue"
|
import customShowModal from "@/components/customShowModal.vue"
|
||||||
import mediaPreview from "@/components/mediaPreview.vue"
|
import mediaPreview from "@/components/mediaPreview.vue"
|
||||||
import NFCTemplate from "@/components/NFCTemplate.vue"
|
import NFCTemplate from "@/components/NFCTemplate.vue"
|
||||||
|
|
||||||
import { parseTime } from '@/utils/datetime.js';
|
import { parseTime } from '@/utils/datetime.js';
|
||||||
import { formatTaskStatus } from '@/utils/status.js';
|
import { formatTaskStatus } from '@/utils/status.js';
|
||||||
import { taskGroupDetail,submitResult,minioUpload } from '@/api/polling.js'
|
import { taskGroupDetail,submitResult,minioUpload } from '@/api/polling.js'
|
||||||
@@ -370,7 +385,11 @@ const chooseImage = (item) => {
|
|||||||
minioUpload(param).then(res=>{
|
minioUpload(param).then(res=>{
|
||||||
let data = res.data;
|
let data = res.data;
|
||||||
// console.log("444图片上传成功=>",data)
|
// console.log("444图片上传成功=>",data)
|
||||||
imgArr2.value.push(data.fileUrl)
|
// imgArr2.value.push(data.fileUrl)
|
||||||
|
imgArr2.value.push({
|
||||||
|
shortUrl:minioObj.minioThumbUrl +"/"+data.fileName,
|
||||||
|
url:minioObj.minioUrl +"/"+data.fileName,
|
||||||
|
})
|
||||||
imgArr.value.push(data.fileName)//传给后台的路径
|
imgArr.value.push(data.fileName)//传给后台的路径
|
||||||
item.resultContent = imgArr.value.join(",")
|
item.resultContent = imgArr.value.join(",")
|
||||||
})
|
})
|
||||||
@@ -432,7 +451,7 @@ let isVisible= ref(false);//放大处理
|
|||||||
let mediaUrl= ref('');//放大地址
|
let mediaUrl= ref('');//放大地址
|
||||||
let videoShow = ref(true);
|
let videoShow = ref(true);
|
||||||
const showMediaPreview=(item)=>{
|
const showMediaPreview=(item)=>{
|
||||||
console.log("showMediaPreview===")
|
// console.log("showMediaPreview===")
|
||||||
isVisible.value = true;
|
isVisible.value = true;
|
||||||
videoShow.value = false;
|
videoShow.value = false;
|
||||||
mediaUrl.value = item.url
|
mediaUrl.value = item.url
|
||||||
@@ -443,10 +462,8 @@ const handlePreviewClose=()=>{
|
|||||||
}
|
}
|
||||||
|
|
||||||
// nfc 处理
|
// nfc 处理
|
||||||
let cardUID = ref('');
|
|
||||||
let cardValue = ref('');
|
|
||||||
let nfcShow = ref(false);
|
let nfcShow = ref(false);
|
||||||
const nfcTemplateRef = ref(null);
|
const nfcReaderRef = ref(null);
|
||||||
// optionObj.pointList
|
// optionObj.pointList
|
||||||
let nfcIndex = ref(0);
|
let nfcIndex = ref(0);
|
||||||
const initNFC = async(item,index) => {
|
const initNFC = async(item,index) => {
|
||||||
@@ -455,19 +472,22 @@ const initNFC = async(item,index) => {
|
|||||||
// uni.navigateTo({url:'/pages/business/polling/nfcTest/index'})
|
// uni.navigateTo({url:'/pages/business/polling/nfcTest/index'})
|
||||||
// #ifdef APP-PLUS
|
// #ifdef APP-PLUS
|
||||||
setTimeout(()=>{
|
setTimeout(()=>{
|
||||||
// console.log("nfcTemplateRef==",nfcTemplateRef.value)
|
if(nfcReaderRef.value){
|
||||||
if (nfcTemplateRef.value) {
|
nfcReaderRef.value.open();
|
||||||
nfcTemplateRef.value.listenNFCStatus();
|
|
||||||
}
|
}
|
||||||
},500)
|
},50)
|
||||||
// #endif
|
// #endif
|
||||||
}
|
}
|
||||||
const nfcClose = async(item) => {
|
const nfcClose = async(item) => {
|
||||||
nfcShow.value = false;
|
nfcShow.value = false;
|
||||||
}
|
}
|
||||||
const nfcConfirm=(result)=>{
|
|
||||||
console.log("confirm=>",result)
|
const handleNfcData=(data)=>{
|
||||||
optionObj.pointList[nfcIndex].resultContent = result
|
console.log("NFC数据:", data);
|
||||||
|
console.log("NFC数据1111:", optionObj.value.pointList,nfcIndex.value)
|
||||||
|
optionObj.value.pointList[nfcIndex.value].resultContent = data;
|
||||||
|
console.log("NFC数据1111:", optionObj.value.pointList[nfcIndex.value])
|
||||||
|
// nfcShow.value = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 扫二维码
|
// 扫二维码
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
|||||||
{"@platforms":["android","iPhone","iPad"],"id":"__UNI__4C459F4","name":"718友晟","version":{"name":"1.0.0","code":"100"},"description":"","developer":{"name":"","email":"","url":""},"permissions":{"Push":{},"Camera":{},"Barcode":{},"VideoPlayer":{},"UniNView":{"description":"UniNView原生渲染"}},"plus":{"useragent":{"value":"uni-app","concatenate":true},"splashscreen":{"target":"id:1","autoclose":true,"waiting":false,"delay":0},"popGesture":"close","launchwebview":{"id":"1","kernel":"WKWebview"},"compatible":{"ignoreVersion":true},"usingComponents":true,"nvueStyleCompiler":"uni-app","compilerVersion":3,"nativePlugins":{"Tm-TmSafeSaveFileModule":{"__plugin_info__":{"name":"TmSafeSaveFileModule隐私数据保存","description":"TmSafeSaveFileModule隐私数据保存","platforms":"Android","url":"","android_package_name":"","ios_bundle_id":"","isCloud":false,"bought":-1,"pid":"","parameters":{}}}},"statusbar":{"immersed":"supportedDevice","style":"dark","background":"#F8F8F8"},"uniStatistics":{"enable":false},"allowsInlineMediaPlayback":true,"safearea":{"background":"#000000","bottom":{"offset":"auto"}},"uni-app":{"control":"uni-v3","vueVersion":"3","compilerVersion":"4.76","nvueCompiler":"uni-app","renderer":"auto","nvue":{"flex-direction":"column"},"nvueLaunchMode":"normal","webView":{"minUserAgentVersion":"49.0"}},"tabBar":{"position":"bottom","color":"#919191","selectedColor":"#ffffff","borderStyle":"#ffffff","blurEffect":"none","fontSize":"12px","iconWidth":"24px","spacing":"3px","height":"50px","list":[{"pagePath":"pages/home/home","iconPath":"/static/images/tabs/menu-home.png","selectedIconPath":"/static/images/tabs/menu-home-on.png","text":"首页"},{"pagePath":"pages/business/business","iconPath":"/static/images/tabs/menu-business.png","selectedIconPath":"/static/images/tabs/menu-business-on.png","text":"业务中心"},{"pagePath":"pages/notice/notice","iconPath":"/static/images/tabs/menu-info.png","selectedIconPath":"/static/images/tabs/menu-info-on.png","text":"消息"},{"pagePath":"pages/userinfo/userinfo","iconPath":"/static/images/tabs/menu-me.png","selectedIconPath":"/static/images/tabs/menu-me-on.png","text":"我的"}],"backgroundColor":"#000000","selectedIndex":0,"shown":true}},"app-harmony":{"useragent":{"value":"uni-app","concatenate":true},"uniStatistics":{"enable":false},"safearea":{"background":"#000000","bottom":{"offset":"auto"}}},"launch_path":"__uniappview.html"}
|
{"@platforms":["android","iPhone","iPad"],"id":"__UNI__4C459F4","name":"718友晟","version":{"name":"1.0.2","code":"100"},"description":"","developer":{"name":"","email":"","url":""},"permissions":{"Push":{},"Camera":{},"Barcode":{},"VideoPlayer":{},"UniNView":{"description":"UniNView原生渲染"}},"plus":{"useragent":{"value":"uni-app","concatenate":true},"splashscreen":{"target":"id:1","autoclose":true,"waiting":false,"delay":0},"popGesture":"close","launchwebview":{"id":"1","kernel":"WKWebview"},"compatible":{"ignoreVersion":true},"usingComponents":true,"nvueStyleCompiler":"uni-app","compilerVersion":3,"nativePlugins":{"Tm-TmSafeSaveFileModule":{"__plugin_info__":{"name":"TmSafeSaveFileModule隐私数据保存","description":"TmSafeSaveFileModule隐私数据保存","platforms":"Android","url":"","android_package_name":"","ios_bundle_id":"","isCloud":false,"bought":-1,"pid":"","parameters":{}}}},"statusbar":{"immersed":"supportedDevice","style":"dark","background":"#F8F8F8"},"uniStatistics":{"enable":false},"allowsInlineMediaPlayback":true,"safearea":{"background":"#000000","bottom":{"offset":"auto"}},"uni-app":{"control":"uni-v3","vueVersion":"3","compilerVersion":"4.76","nvueCompiler":"uni-app","renderer":"auto","nvue":{"flex-direction":"column"},"nvueLaunchMode":"normal","webView":{"minUserAgentVersion":"49.0"}},"tabBar":{"position":"bottom","color":"#919191","selectedColor":"#ffffff","borderStyle":"#ffffff","blurEffect":"none","fontSize":"12px","iconWidth":"24px","spacing":"3px","height":"50px","list":[{"pagePath":"pages/home/home","iconPath":"/static/images/tabs/menu-home.png","selectedIconPath":"/static/images/tabs/menu-home-on.png","text":"首页"},{"pagePath":"pages/business/business","iconPath":"/static/images/tabs/menu-business.png","selectedIconPath":"/static/images/tabs/menu-business-on.png","text":"业务中心"},{"pagePath":"pages/notice/notice","iconPath":"/static/images/tabs/menu-info.png","selectedIconPath":"/static/images/tabs/menu-info-on.png","text":"消息"},{"pagePath":"pages/userinfo/userinfo","iconPath":"/static/images/tabs/menu-me.png","selectedIconPath":"/static/images/tabs/menu-me-on.png","text":"我的"}],"backgroundColor":"#000000","selectedIndex":0,"shown":true}},"app-harmony":{"useragent":{"value":"uni-app","concatenate":true},"uniStatistics":{"enable":false},"safearea":{"background":"#000000","bottom":{"offset":"auto"}}},"launch_path":"__uniappview.html"}
|
||||||
@@ -1 +1 @@
|
|||||||
.container[data-v-44de363d]{padding:15px;box-sizing:border-box}.container .iframe[data-v-44de363d]{height:100vh;width:100vw;border:none;margin:0}.container .input-box[data-v-44de363d]{border:1px solid #aaa;margin:30px 0;padding:10px;border-radius:100px}.container .btn-box[data-v-44de363d]{display:flex;justify-content:space-between;align-items:center}.container .btn-box .btn-write[data-v-44de363d]{width:100%;height:100px;display:flex;align-items:center;justify-content:center;font-size:20px}.container .btn-box .btn-read[data-v-44de363d]{width:100%;margin-left:20px;height:100px;background-color:#1ee176;color:#fff;display:flex;align-items:center;justify-content:center;font-size:20px}
|
.container[data-v-9948bfd6]{padding:15px;box-sizing:border-box}.container .iframe[data-v-9948bfd6]{height:100vh;width:100vw;border:none;margin:0}.container .input-box[data-v-9948bfd6]{border:1px solid #aaa;margin:30px 0;padding:10px;border-radius:100px}.container .btn-box[data-v-9948bfd6]{display:flex;justify-content:space-between;align-items:center}.container .btn-box .btn-write[data-v-9948bfd6]{width:100%;height:100px;display:flex;align-items:center;justify-content:center;font-size:20px}.container .btn-box .btn-read[data-v-9948bfd6]{width:100%;margin-left:20px;height:100px;background-color:#1ee176;color:#fff;display:flex;align-items:center;justify-content:center;font-size:20px}
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user