Browse Source

完善页面

master
Penny 2 years ago
parent
commit
a0786438dd
  1. 3
      App.vue
  2. 37
      manifest.json
  3. BIN
      nativeplugins/JY-MLScanSDK/android/jy-mlscansdk-release.aar
  4. BIN
      nativeplugins/JY-MLScanSDK/android/mlkit-scanner-release.aar
  5. 28
      nativeplugins/JY-MLScanSDK/package.json
  6. BIN
      nativeplugins/LY-HWScan/android/uniplugin_hwscan-release.aar
  7. 32
      nativeplugins/LY-HWScan/package.json
  8. 29
      pages.json
  9. 98
      pages/history/History.vue
  10. 212
      pages/scan/Barcode.vue
  11. 140
      pages/scan/Book.vue
  12. 235
      pages/scan/Calendar.vue
  13. 214
      pages/scan/Contacts.vue
  14. 241
      pages/scan/Email.vue
  15. 225
      pages/scan/Location.vue
  16. 254
      pages/scan/Product.vue
  17. 301
      pages/scan/Scan.nvue
  18. 146
      pages/scan/Sms.vue
  19. 225
      pages/scan/Tel.vue
  20. 220
      pages/scan/Text.vue
  21. 116
      pages/scan/Url.vue
  22. 175
      pages/scan/Wifi.vue
  23. 2
      pages/setting/Setting.vue
  24. 30
      pages/webview/webview.vue
  25. BIN
      static/album.png
  26. BIN
      static/flashLightOff.png
  27. BIN
      static/flashLightOn.png
  28. BIN
      static/history-default.png
  29. BIN
      static/history-select.png
  30. BIN
      static/scan-default.png
  31. BIN
      static/scan-select.png
  32. BIN
      static/scan.png
  33. BIN
      static/setting-default.png
  34. BIN
      static/setting-select.png
  35. 4
      tuniao-ui/components/tn-button/tn-button.vue
  36. 100
      uni_modules/uni-wifi/package.json
  37. 145
      uni_modules/uni-wifi/readme.md
  38. 3
      uni_modules/uni-wifi/utssdk/app-android/config.json
  39. 864
      uni_modules/uni-wifi/utssdk/app-android/index.uts
  40. 8
      uni_modules/uni-wifi/utssdk/app-ios/Info.plist
  41. 8
      uni_modules/uni-wifi/utssdk/app-ios/UTS.entitlements
  42. 8
      uni_modules/uni-wifi/utssdk/app-ios/config.json
  43. 301
      uni_modules/uni-wifi/utssdk/app-ios/index.uts
  44. 125
      uni_modules/uni-wifi/utssdk/interface.uts
  45. 35
      uni_modules/uni-wifi/utssdk/uni.autotest.js

3
App.vue

@ -13,10 +13,9 @@
</script>
<style lang="scss">
/* #ifndef APP-PLUS*/
/* #ifndef APP-PLUS-NVUE */
@import './tuniao-ui/index.scss';
@import './tuniao-ui/iconfont.css';
/* #endif */
/*每个页面公共css */
</style>

37
manifest.json

@ -18,28 +18,35 @@
},
/* */
"modules" : {
"SQLite" : {}
"SQLite" : {},
"Barcode" : {},
"Camera" : {},
"Share" : {}
},
/* */
"distribute" : {
/* android */
"android" : {
"permissions" : [
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
"<uses-feature android:name=\"android.hardware.camera\"/>",
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\"/>",
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.RECEIVE_BOOT_COMPLETED\"/>",
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
"<uses-feature android:name=\"android.hardware.camera\"/>",
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>",
"<uses-permission android:name=\"android.permission.RECEIVE_USER_PRESENT\"/>"
],
"minSdkVersion" : 21,
"targetSdkVersion" : 32
@ -50,14 +57,16 @@
},
/* SDK */
"sdkConfigs" : {
"ad" : {}
"ad" : {},
"share" : {},
"statics" : {}
}
},
"nativePlugins" : {
"JY-MLScanSDK" : {
"LY-HWScan" : {
"__plugin_info__" : {
"name" : "JY-MLScanSDK模块",
"description" : "JY-MLScanSDK",
"name" : "LYHWScan",
"description" : "uni原生华为扫描插件",
"platforms" : "Android",
"url" : "",
"android_package_name" : "",

BIN
nativeplugins/JY-MLScanSDK/android/jy-mlscansdk-release.aar

Binary file not shown.

BIN
nativeplugins/JY-MLScanSDK/android/mlkit-scanner-release.aar

Binary file not shown.

28
nativeplugins/JY-MLScanSDK/package.json

@ -1,28 +0,0 @@
{
"name": "JY-MLScanSDK模块",
"id": "JY-MLScanSDK",
"version": "1.0.0",
"description": "JY-MLScanSDK",
"_dp_type": "nativeplugin",
"_dp_nativeplugin": {
"android": {
"plugins": [{
"type": "module",
"name": "JY-MLScanSDK",
"class": "com.jiyi.jy_mlscansdk.JYMLScanSDKModule"
}],
"integrateType": "aar",
"dependencies": [
"com.google.mlkit:barcode-scanning:16.2.0",
"androidx.camera:camera-core:1.0.1",
"androidx.camera:camera-camera2:1.0.1",
"androidx.camera:camera-lifecycle:1.0.1",
"androidx.camera:camera-view:1.0.0-alpha25"
],
"compileOptions": {
"sourceCompatibility": "1.8",
"targetCompatibility": "1.8"
}
}
}
}

BIN
nativeplugins/LY-HWScan/android/uniplugin_hwscan-release.aar

Binary file not shown.

32
nativeplugins/LY-HWScan/package.json

@ -0,0 +1,32 @@
{
"name": "LYHWScan",
"id": "LY-HWScan",
"version": "1.0.8",
"description": "uni原生华为扫描插件",
"_dp_type": "nativeplugin",
"_dp_nativeplugin": {
"android": {
"plugins": [{
"type": "module",
"name": "LY-HWScan",
"class": "com.lianyunzhihui.uniplugin_hwscan.HWScanModule"
}, {
"type": "component",
"name": "ly-hwscan",
"class": "com.lianyunzhihui.uniplugin_hwscan.HWScan"
}],
"hooksClass": "",
"integrateType": "aar",
"dependencies": [
"androidx.localbroadcastmanager:localbroadcastmanager:1.0.0",
"androidx.core:core:1.1.0",
"androidx.fragment:fragment:1.1.0",
"androidx.appcompat:appcompat:1.1.0",
"androidx.recyclerview:recyclerview:1.1.0",
"com.alibaba:fastjson:1.2.83",
"com.huawei.hms:scanplus:2.9.0.300"
],
"minSdkVersion": "21"
}
}
}

29
pages.json

@ -10,6 +10,13 @@
"enablePullDownRefresh": false
}
},
{
"path": "pages/webview/webview",
"style": {
"navigationBarTitleText": "Browser",
"enablePullDownRefresh": false
}
},
// {
// "path": "pages/create/Create",
// "style": {
@ -119,26 +126,26 @@
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "ScanCode",
"navigationBarBackgroundColor": "#F8F8F8",
"backgroundColor": "#F8F8F8"
"navigationBarBackgroundColor": "#0186ff",
"backgroundColor": "#0186ff"
},
"uniIdRouter": {},
//tab
"tabBar": {
"color": "#7A7E83",
"selectedColor": "#1296DB",
"color": "#e6e6e6",
"selectedColor": "#F8F8F8",
"borderStyle": "black",
"backgroundColor": "#F8F8F8",
"backgroundColor": "#0186ff",
"list": [{
"pagePath": "pages/scan/Scan",
"iconPath": "static/art-default.png",
"selectedIconPath": "static/art-select.png",
"iconPath": "static/scan-default.png",
"selectedIconPath": "static/scan-select.png",
"text": "Scan"
},
{
"pagePath": "pages/history/History",
"iconPath": "static/art-default.png",
"selectedIconPath": "static/art-select.png",
"iconPath": "static/history-default.png",
"selectedIconPath": "static/history-select.png",
"text": "History"
},
// {
@ -149,8 +156,8 @@
// },
{
"pagePath": "pages/setting/Setting",
"iconPath": "static/art-default.png",
"selectedIconPath": "static/art-select.png",
"iconPath": "static/setting-default.png",
"selectedIconPath": "static/setting-select.png",
"text": "Setting"
}
]

98
pages/history/History.vue

@ -100,40 +100,7 @@
"label":"URL"
},
],
historyList: []
// historyList:[
// {
// "icon":"grid-item-icon tn-icon-empty-network",
// "text":"15936215478",
// "sort":"0",
// "label":"WIFI"
// },
// {
// "icon":"grid-item-icon tn-icon-empty-network",
// "text":"15936215478",
// "sort":"1",
// "label":"WIFI"
// },
// {
// "icon":"grid-item-icon tn-icon-empty-network",
// "text":"15936215478",
// "sort":"2",
// "label":"WIFI"
// },
// {
// "icon":"grid-item-icon tn-icon-empty-network",
// "text":"15936215478",
// "sort":"3",
// "label":"WIFI"
// },
// {
// "icon":"grid-item-icon tn-icon-empty-network",
// "text":"15936215478",
// "sort":"4",
// "label":"WIFI"
// }
// ]
}
},
async onShow() {
@ -151,31 +118,31 @@
//
getHistory(category,data){
console.log("123")
//console.log('category',category)
console.log('data', data)
let that = this;
if(category === 'Contacts'){
that.jumpToPage('/pages/scan/Contacts','history',data);
that.jumpToPage('/pages/scan/Contacts','history', data);
}else if(category === 'Email'){
that.jumpToPage('/pages/scan/Email','history',data);
that.jumpToPage('/pages/scan/Email','history', data);
}else if(category === 'Tel'){
that.jumpToPage('/pages/scan/Tel','history',data);
that.jumpToPage('/pages/scan/Tel','history', data);
}else if(category === 'Product'){
that.jumpToPage('/pages/scan/Product','history',data);
that.jumpToPage('/pages/scan/Product','history', data);
}else if(category === 'Sms'){
that.jumpToPage('/pages/scan/Sms','history',data);
that.jumpToPage('/pages/scan/Sms','history', data);
}else if(category === 'Text'){
that.jumpToPage('/pages/scan/Text','history',data);
that.jumpToPage('/pages/scan/Text','history', data);
}else if(category === 'Url'){
that.jumpToPage('/pages/scan/Url','history',data);
that.jumpToPage('/pages/scan/Url','history', data);
}else if(category === 'Wifi'){
that.jumpToPage('/pages/scan/Wifi','history',data);
that.jumpToPage('/pages/scan/Wifi','history', data);
}else if(category === 'Location'){
that.jumpToPage('/pages/scan/Location','history',data);
that.jumpToPage('/pages/scan/Location','history', data);
}else if(category === 'Calendar'){
that.jumpToPage('/pages/scan/Calendar','history',data);
that.jumpToPage('/pages/scan/Calendar','history', data);
}else if(category === 'Book'){
that.jumpToPage('/pages/scan/Book','history',data);
that.jumpToPage('/pages/scan/Book','history', data);
}
},
@ -190,10 +157,6 @@
async openSqlite(){
try{
let b = await openSqlite()
// uni.showToast({
// title:"open db success",
// icon:"none"
// })
console.log('db打开了');
}catch(e){
console.error("open db error",e)
@ -213,29 +176,38 @@
//
async getData(){
let that = this;
try{
let where = {}
let res = await getPageList(this.tableName,this.options,where,"id desc")
console.log("加载数据",res)
this.historyList = res.data.data.records
this.pages = res.data.data.pages
this.total = res.data.data.total
let res = await getPageList(that.tableName,that.options,where,"id desc")
//console.log("",res)
// for (let data of res.data.data.records) {
// //console.log('data',data)
// let content = JSON.parse(data.content)
// //console.log('content',content)
// data.content = content;
// }
that.historyList = res.data.data.records
console.log('historyList',that.historyList)
that.pages = res.data.data.pages
that.total = res.data.data.total
}catch(e){
// uni.showToast({
// title:"",
// icon:"none"
// });
uni.showToast({
title:"get History Data error",
icon:"none"
});
console.error("error",e)
}
},
//
async changeData(){
let that = this;
// fid id
try{
let res = await getPageList(this.tableName,{current:1,size:1},{},"fid desc")
let res = await getPageList(that.tableName,{current:1,size:1},{},"fid desc")
console.log("最后一页数据",res.data.data)
await updateSql(this.tableName,{title:"updated data"},{fid:res.data.data.records[0].fid})
await updateSql(that.tableName,{title:"updated data"},{fid:res.data.data.records[0].fid})
uni.showToast({
title:"update ok",
icon:"none"
@ -259,7 +231,9 @@
align-items: center;
justify-content: center;
background-color: #000000;
height:100%;
// height:1400rpx;
height: 100vh;
overflow: scroll;
.headLine{
color: royalblue;

212
pages/scan/Barcode.vue

@ -1,17 +1,27 @@
<template>
<view class="content">
<tn-avatar src="/static/logo.png" class="icon" size="xl"></tn-avatar>
<tn-avatar class="icon tn-icon-qr-barcode" size="xl"></tn-avatar>
<tn-list-view :card="true" unlined="all" class="listView">
<tn-list-cell class="listItem-1">
<view>{{ barcodeInfo.ssid }}</view>
<view>{{ barcodeInfo.message }}</view>
</tn-list-cell>
<tn-list-cell class="listItem">
<tn-grid align="center" :col="col">
<block v-for="(item, index) in fastToolList" :key="index">
<tn-grid-item class="toolItem">
<view :class="item.icon"></view>
<block>
<tn-grid-item class="toolItem" @click="openWeb()">
<view class="tn-icon-search"></view>
<view class="cutline"></view>
<view class="toolText">{{ item.text }}</view>
<view class="toolText">Web Search</view>
</tn-grid-item>
<tn-grid-item class="toolItem" @click="share()">
<view class="tn-icon-share-triangle"></view>
<view class="cutline"></view>
<view class="toolText">Share</view>
</tn-grid-item>
<tn-grid-item class="toolItem" @click="copyValue()">
<view class="tn-icon-copy-fill"></view>
<view class="cutline"></view>
<view class="toolText">Copy</view>
</tn-grid-item>
</block>
</tn-grid>
@ -19,7 +29,7 @@
<view class="cutline"></view>
<tn-list-cell class="listItem-ad">我是谷歌ad部分</tn-list-cell>
<tn-list-cell class="listItemBottom">
<image src="/static/logo.png" class="buttomImg"/>
<image :src="textImgUrl" class="buttomImg"/>
</tn-list-cell>
</tn-list-view>
<text class="bottomText">Feedback or Suggestion</text>
@ -33,35 +43,165 @@
return {
col: 3,
barcodeInfo:{},
fastToolList:[
{
"index": 0,
"text":"Web Search",
"icon": "tn-icon-search"
},
{
"index": 1,
"text":"Copy",
"icon": "tn-icon-copy-fill"
},
{
"index": 2,
"text":"Share",
"icon": "tn-icon-share-triangle"
}
]
tableName: 'scan_code',
textImgUrl: '',
}
},
async onLoad(option) {
console.log('onLoadOption',option)
let that = this;
//db
await that.openSqlite();
//
await that.createTable();
//scan,history
if(option.category === 'scan'){
//db
await that.initData(option.data);
}else{
//
await that.getHistoryData(option.data);
}
},
onLoad(option) {
onHide() {
let that = this;
that.initData(option);
that.closedb();
},
methods: {
initData(option){
//
share(){
uni.shareWithSystem({
summary: '',
href: 'https://uniapp.dcloud.io',
success(){
//
uni.showToast({
title: 'share success!'
});
},
fail(){
//
uni.showToast({
title: 'share fail!'
});
}
})
},
//
openWeb(){
let that = this;
console.log('that.barcodeInfo.message',that.barcodeInfo.message)
uni.navigateTo({
url: '/pages/webview/webview?url=https://www.baidu.com/s?wd=' + that.barcodeInfo.message
//url: '/pages/webview/webview?url=http://www.google.com?wd=' + that.textInfo.message
});
},
//copy
copyValue(){
let that = this;
let data = JSON.parse(option.data);
//console.log('')
uni.setClipboardData({
data: that.barcodeInfo.message,
success() {
uni.showToast({
title: 'copy success!'
});
}
})
},
//
async openSqlite(){
try{
let b = await openSqlite()
console.log('db打开了');
}catch(e){
console.error("open db error",e)
}
},
//
closedb(){
try{
closedb()
console.log('db关闭了');
}catch(e){
console.error("close db error",e)
}
},
//
async createTable(){
let sql = this.createTableSql_outbound()
try{
let exist = await isTable(this.tableName)
console.log("表是否存在",exist)
if(!exist){
let res = await executeSql(sql)
console.log("新增表scancode",res)
}else{
console.log("表scancode已存在")
}
}catch(e){
uni.showToast({
title:"insert table error",
icon:"none"
})
console.error("新增表报错scancode",e)
}
},
//
async writeToDb(type,params){
try{
let data = {
category: type,
content: params
}
let b = await addSql(this.tableName,data)
console.log("数据添加成功!")
}catch(e){
console.error("insert data error!",e)
}
},
//
createTableSql_outbound(){
return "CREATE TABLE IF NOT EXISTS `scan_code` (" +
" `id` INTEGER PRIMARY KEY AUTOINCREMENT," +
" `category` varchar(50) DEFAULT NULL ," +
" `content` text DEFAULT NULL ," +
" `createTime` datetime DEFAULT CURRENT_TIMESTAMP ," +
" `updateTime` datetime DEFAULT NULL default(datetime('now','localtime'))" +
"); "
},
//
async initData(option){
//console.log('initoption',option)
let that = this;
let data = JSON.parse(option);
let insertData = {
message : data.message,
imgUrl: data.imgUrl
}
that.barcodeInfo = insertData;
that.textImgUrl = 'file://'+that.barcodeInfo.imgUrl;
//db
await that.writeToDb("Barcode",that.barcodeInfo);
},
//
async getHistoryData(params){
//console.log('historyparams',params)
let that = this;
const data = JSON.parse(params);
that.barcodeInfo = data;
console.log('barcodeInfo',that.barcodeInfo)
that.textImgUrl = 'file://'+that.barcodeInfo.imgUrl;
}
}
}
@ -74,13 +214,13 @@
align-items: center;
justify-content: center;
background-color: #000000;
height:100%;
height:100vh;
.listView{
z-index: 0;
position: relative;
width: 660rpx;
height:1000rpx;
height:1300rpx;
margin-top: 100rpx;
background-color: #141b29;
@ -105,12 +245,13 @@
//border: 2px solid red;
background-color: #141b29;
font-size: 60rpx;
color: #8f8f94;
height: 120rpx;
text-align: center;
.toolText{
font-size: 24rpx;
color: #fff;
color: #8f8f94;
}
}
@ -144,8 +285,11 @@
.icon{
z-index: 1;
position: absolute;
margin-top: -960rpx;
margin-top: -620rpx;
background-color: #3e444d;
font-size: 120rpx;
color: #fff;
text-align: center;
}

140
pages/scan/Book.vue

@ -1,6 +1,6 @@
<template>
<view class="content">
<tn-avatar src="/static/logo.png" class="icon" size="xl"></tn-avatar>
<tn-avatar class="icon tn-icon-book" size="xl"></tn-avatar>
<tn-list-view :card="true" unlined="all" class="listView">
<tn-list-cell class="listItem-1">
<view>{{ bookInfo.display }}</view>
@ -33,6 +33,7 @@
return {
col: 4,
bookInfo:{},
tableName: 'scan_code',
fastToolList:[
{
"index": 0,
@ -57,16 +58,129 @@
]
}
},
onLoad(option) {
async onLoad(option) {
console.log('onLoadOption',option)
let that = this;
that.initData(option);
//db
await that.openSqlite();
//
await that.createTable();
//scan,history
if(option.category === 'scan'){
//db
await that.initData(option.data);
}else{
//
await that.getHistoryData(option.data);
}
},
onHide() {
let that = this;
that.closedb();
},
methods: {
initData(option){
//
async openSqlite(){
try{
let b = await openSqlite()
// uni.showToast({
// title:"open db success",
// icon:"none"
// })
console.log('db打开了');
}catch(e){
console.error("open db error",e)
}
},
//
closedb(){
try{
closedb()
console.log('db关闭了');
}catch(e){
console.error("close db error",e)
}
},
//
async createTable(){
let sql = this.createTableSql_outbound()
try{
let exist = await isTable(this.tableName)
console.log("表是否存在",exist)
if(!exist){
let res = await executeSql(sql)
// uni.showToast({
// title:"insert table ok",
// icon:"none"
// })
console.log("新增表scancode",res)
}else{
// uni.showToast({
// title:"table exist",
// icon:"none"
// })
console.log("表scancode已存在")
}
}catch(e){
uni.showToast({
title:"insert table error",
icon:"none"
})
console.error("新增表报错scancode",e)
}
},
//
async writeToDb(type,params){
try{
let data = {
category: type,
content: params
}
let b = await addSql(this.tableName,data)
console.log("数据添加成功!")
}catch(e){
console.error("insert data error!",e)
}
},
//
createTableSql_outbound(){
return "CREATE TABLE IF NOT EXISTS `scan_code` (" +
" `id` INTEGER PRIMARY KEY AUTOINCREMENT," +
" `category` varchar(50) DEFAULT NULL ," +
" `content` text DEFAULT NULL ," +
" `createTime` datetime DEFAULT CURRENT_TIMESTAMP ," +
" `updateTime` datetime DEFAULT NULL default(datetime('now','localtime'))" +
"); "
},
//
async initData(option){
//console.log('initoption',option)
let that = this;
let data = JSON.parse(option);
that.bookInfo = data;
//console.log('initwifiInfo',that.wifiInfo)
//console.log('password',that.wifiInfo.password)
//console.log('ssid',that.wifiInfo.ssid)
//db
await that.writeToDb("Book",that.bookInfo);
},
//
async getHistoryData(params){
//console.log('historyparams',params)
let that = this;
let data = JSON.parse(option.data);
const data = JSON.parse(params);
//console.log('historydata',data)
that.bookInfo = data;
console.log('bookInfo',that.bookInfo)
//console.log('HistotyWifiInfo',that.wifiInfo)
//console.log('password',wifiInfo.password)
//console.log('ssid',wifiInfo.ssid)
}
}
}
@ -79,13 +193,13 @@
align-items: center;
justify-content: center;
background-color: #000000;
height:100%;
height:100vh;
.listView{
z-index: 0;
position: relative;
width: 660rpx;
height: 1000rpx;
height: 1300rpx;
margin-top: 100rpx;
background-color: #141b29;
@ -110,13 +224,14 @@
//border: 2px solid red;
background-color: #141b29;
font-size: 60rpx;
color: #8f8f94;
height: 120rpx;
text-align: center;
.toolText{
font-size: 24rpx;
color: #fff;
color: #8f8f94;
}
}
@ -150,8 +265,11 @@
.icon{
z-index: 1;
position: absolute;
margin-top: -960px;
margin-top: -620rpx;
background-color: #3e444d;
font-size: 120rpx;
color: #fff;
text-align: center;
}

235
pages/scan/Calendar.vue

@ -1,21 +1,32 @@
<template>
<view class="content">
<tn-avatar src="/static/logo.png" class="icon" size="xl"></tn-avatar>
<tn-avatar class="icon tn-icon-calendar" size="xl"></tn-avatar>
<tn-list-view :card="true" unlined="all" class="listView">
<tn-list-cell class="listItem-1">
<view>Subject: {{ calendarInfo.summary }}</view>
<view>Start: {{ calendarInfo.start }}</view>
<view>End: {{ calendarInfo.end }}</view>
<view>Note: {{ calendarInfo.desc }}</view>
<view>Address: {{ calendarInfo.location }}</view>
<view>Subject: {{ calendarInfo.Theme }}</view>
<view>Start: {{ calendarInfo.startTime.Year +'-'+ calendarInfo.startTime.Month +'-'+ calendarInfo.startTime.Day
+' '+ calendarInfo.startTime.Hours +':'+ calendarInfo.startTime.Minutes +':'+ calendarInfo.startTime.Seconds}}</view>
<view>End: {{ calendarInfo.closeTime }}</view>
<view>Note: {{ calendarInfo.AbstractInfo }}</view>
<view>Address: {{ calendarInfo.PlaceInfo }}</view>
</tn-list-cell>
<tn-list-cell class="listItem">
<tn-grid align="center" :col="col">
<block v-for="(item, index) in fastToolList" :key="index">
<tn-grid-item class="toolItem">
<view :class="item.icon"></view>
<block>
<tn-grid-item class="toolItem" @click="addEvent()">
<view class="tn-icon-calendar"></view>
<view class="cutline"></view>
<view class="toolText">{{ item.text }}</view>
<view class="toolText">Add to events</view>
</tn-grid-item>
<tn-grid-item class="toolItem" @click="share()">
<view class="tn-icon-share-triangle"></view>
<view class="cutline"></view>
<view class="toolText">Share</view>
</tn-grid-item>
<tn-grid-item class="toolItem" @click="copyValue()">
<view class="tn-icon-copy-fill"></view>
<view class="cutline"></view>
<view class="toolText">Copy</view>
</tn-grid-item>
</block>
</tn-grid>
@ -23,7 +34,7 @@
<view class="cutline"></view>
<tn-list-cell class="listItem-ad">我是谷歌ad部分</tn-list-cell>
<tn-list-cell class="listItemBottom">
<image src="/static/logo.png" class="buttomImg"/>
<image :src="textImgUrl" class="buttomImg"/>
</tn-list-cell>
</tn-list-view>
<text class="bottomText">Feedback or Suggestion</text>
@ -35,42 +46,170 @@
export default {
data() {
return {
col: 4,
col: 3,
calendarInfo:{},
fastToolList:[
{
"index": 0,
"text":"Add to events",
"icon": "tn-icon-calendar"
},
{
"index": 1,
"text":"Send email",
"icon": "tn-icon-email"
},
{
"index": 2,
"text":"Copy",
"icon": "tn-icon-copy-fill"
},
{
"index": 3,
"text":"Share",
"icon": "tn-icon-share-triangle"
}
]
tableName: 'scan_code',
textImgUrl: '',
}
},
async onLoad(option) {
console.log('onLoadOption',option)
let that = this;
//db
await that.openSqlite();
//
await that.createTable();
//scan,history
if(option.category === 'scan'){
//db
await that.initData(option.data);
}else{
//
await that.getHistoryData(option.data);
}
},
onLoad(option) {
onHide() {
let that = this;
that.initData(option);
that.closedb();
},
methods: {
initData(option){
//
addEvent(){
},
//
share(){
uni.shareWithSystem({
summary: '',
href: 'https://uniapp.dcloud.io',
success(){
//
uni.showToast({
title: 'share success!'
});
},
fail(){
//
uni.showToast({
title: 'share fail!'
});
}
})
},
//copy
copyValue(){
let that = this;
//console.log('')
uni.setClipboardData({
data: that.calendarInfo,
success() {
uni.showToast({
title: 'copy success!'
});
}
})
},
//
async openSqlite(){
try{
let b = await openSqlite()
console.log('db打开了');
}catch(e){
console.error("open db error",e)
}
},
//
closedb(){
try{
closedb()
console.log('db关闭了');
}catch(e){
console.error("close db error",e)
}
},
//
async createTable(){
let sql = this.createTableSql_outbound()
try{
let exist = await isTable(this.tableName)
console.log("表是否存在",exist)
if(!exist){
let res = await executeSql(sql)
console.log("新增表scancode",res)
}else{
console.log("表scancode已存在")
}
}catch(e){
uni.showToast({
title:"insert table error",
icon:"none"
})
console.error("新增表报错scancode",e)
}
},
//
async writeToDb(type,params){
try{
let data = {
category: type,
content: params
}
let b = await addSql(this.tableName,data)
console.log("数据添加成功!")
}catch(e){
console.error("insert data error!",e)
}
},
//
createTableSql_outbound(){
return "CREATE TABLE IF NOT EXISTS `scan_code` (" +
" `id` INTEGER PRIMARY KEY AUTOINCREMENT," +
" `category` varchar(50) DEFAULT NULL ," +
" `content` text DEFAULT NULL ," +
" `createTime` datetime DEFAULT CURRENT_TIMESTAMP ," +
" `updateTime` datetime DEFAULT NULL default(datetime('now','localtime'))" +
"); "
},
//
async initData(option){
//console.log('initoption',option)
let that = this;
let data = JSON.parse(option);
let insertData = {
AbstractInfo : data.AbstractInfo,
PlaceInfo: data.PlaceInfo,
Sponsor: data.Sponsor,
Theme: data.Theme,
Condition: data.Condition,
closeTime: data.closeTime,
startTime: data.startTime,
imgUrl: data.imgUrl
}
that.calendarInfo = insertData;
that.textImgUrl = 'file://'+that.calendarInfo.imgUrl;
//db
await that.writeToDb("Calendar",that.calendarInfo);
},
//
async getHistoryData(params){
//console.log('historyparams',params)
let that = this;
let data = JSON.parse(option.data);
const data = JSON.parse(params);
that.calendarInfo = data;
console.log('calendarInfo',that.calendarInfo)
that.textImgUrl = 'file://'+that.calendarInfo.imgUrl;
}
}
}
@ -83,13 +222,13 @@
align-items: center;
justify-content: center;
background-color: #000000;
height:100%;
height:100vh;
.listView{
z-index: 0;
position: relative;
width: 660rpx;
height: 1000rpx;
height: 1300rpx;
margin-top: 100rpx;
background-color: #141b29;
@ -107,6 +246,7 @@
height: 160rpx;
//margin-top: 30px;
//padding-top: 30px;
width: 660rpx;
background-color: #141b29;
color: #fff;
@ -114,14 +254,16 @@
//border: 2px solid red;
background-color: #141b29;
font-size: 60rpx;
color: #8f8f94;
height: 120rpx;
text-align: center;
// margin-left: 20rpx;
// margin-right: 20rpx;
.toolText{
font-size: 24rpx;
color: #fff;
color: #8f8f94;
}
}
@ -154,8 +296,11 @@
.icon{
z-index: 1;
position: absolute;
margin-top: -960rpx;
margin-top: -620rpx;
background-color: #3e444d;
font-size: 120rpx;
color: #fff;
text-align: center;
}
.bottomText{

214
pages/scan/Contacts.vue

@ -1,22 +1,37 @@
<template>
<view class="content">
<tn-avatar src="/static/logo.png" class="icon" size="xl"></tn-avatar>
<tn-avatar class="icon tn-icon-my" size="xl"></tn-avatar>
<tn-list-view :card="true" unlined="all" class="listView">
<tn-list-cell class="listItem-1">
<view>Name: {{ contactsInfo.name.formattedName }}</view>
<view>Name: {{ contactsInfo.peopleName.FullName }}</view>
<view>Tel: {{ contactsInfo.phones[0].number }}</view>
<view>E-mail: {{ contactsInfo.emails[0].address }}</view>
<view>Address: {{ contactsInfo.addresses[0].addressLines[0] }}</view>
<view>Note: {{ contactsInfo.title }}</view>
<view>Org: {{ contactsInfo.organization }}</view>
<view>Note: {{ contactsInfo.Title }}</view>
<view>Org: {{ contactsInfo.Company }}</view>
</tn-list-cell>
<tn-list-cell class="listItem">
<tn-grid align="center" :col="col">
<block v-for="(item, index) in fastToolList" :key="index">
<tn-grid-item class="toolItem">
<view :class="item.icon"></view>
<block>
<tn-grid-item class="toolItem" @click="addContact()">
<view class="tn-icon-my-circle-fill"></view>
<view class="cutline"></view>
<view class="toolText">{{ item.text }}</view>
<view class="toolText">Add to contacts</view>
</tn-grid-item>
<tn-grid-item class="toolItem" @click="sendEmail()">
<view class="tn-icon-email"></view>
<view class="cutline"></view>
<view class="toolText">Send email</view>
</tn-grid-item>
<tn-grid-item class="toolItem" @click="call()">
<view class="tn-icon-copy-fill"></view>
<view class="cutline"></view>
<view class="toolText">Call</view>
</tn-grid-item>
<tn-grid-item class="toolItem" @click="copyValue()">
<view class="tn-icon-copy-fill"></view>
<view class="cutline"></view>
<view class="toolText">Copy</view>
</tn-grid-item>
</block>
</tn-grid>
@ -24,7 +39,7 @@
<view class="cutline"></view>
<tn-list-cell class="listItem-ad">我是谷歌ad部分</tn-list-cell>
<tn-list-cell class="listItemBottom">
<image src="/static/logo.png" class="buttomImg"/>
<image :src="textImgUrl" class="buttomImg"/>
</tn-list-cell>
</tn-list-view>
<text class="bottomText">Feedback or Suggestion</text>
@ -38,40 +53,153 @@
return {
col: 4,
contactsInfo:{},
fastToolList:[
{
"index": 0,
"text":"Add to contacts",
"icon": "tn-icon-my-circle-fill"
},
{
"index": 1,
"text":"Call",
"icon": "tn-icon-tel"
},
{
"index": 2,
"text":"Copy",
"icon": "tn-icon-copy-fill"
},
{
"index": 3,
"text":"Share",
"icon": "tn-icon-share-triangle"
}
]
tableName: 'scan_code',
textImgUrl: '',
}
},
async onLoad(option) {
console.log('onLoadOption',option)
let that = this;
//db
await that.openSqlite();
//
await that.createTable();
//scan,history
if(option.category === 'scan'){
//db
await that.initData(option.data);
}else{
//
await that.getHistoryData(option.data);
}
},
onLoad(option) {
onHide() {
let that = this;
that.initData(option);
that.closedb();
},
methods: {
initData(option){
//
addContact(){
},
//email
sendEmail(){
},
//
call(){
},
//copy
copyValue(){
let that = this;
let data = JSON.parse(option.data);
//console.log('')
uni.setClipboardData({
data: that.contactsInfo,
success() {
uni.showToast({
title: 'copy success!'
});
}
})
},
//
async openSqlite(){
try{
let b = await openSqlite()
console.log('db打开了');
}catch(e){
console.error("open db error",e)
}
},
//
closedb(){
try{
closedb()
console.log('db关闭了');
}catch(e){
console.error("close db error",e)
}
},
//
async createTable(){
let sql = this.createTableSql_outbound()
try{
let exist = await isTable(this.tableName)
console.log("表是否存在",exist)
if(!exist){
let res = await executeSql(sql)
console.log("新增表scancode",res)
}else{
console.log("表scancode已存在")
}
}catch(e){
uni.showToast({
title:"insert table error",
icon:"none"
})
console.error("新增表报错scancode",e)
}
},
//
async writeToDb(type,params){
try{
let data = {
category: type,
content: params
}
let b = await addSql(this.tableName,data)
console.log("数据添加成功!")
}catch(e){
console.error("insert data error!",e)
}
},
//
createTableSql_outbound(){
return "CREATE TABLE IF NOT EXISTS `scan_code` (" +
" `id` INTEGER PRIMARY KEY AUTOINCREMENT," +
" `category` varchar(50) DEFAULT NULL ," +
" `content` text DEFAULT NULL ," +
" `createTime` datetime DEFAULT CURRENT_TIMESTAMP ," +
" `updateTime` datetime DEFAULT NULL default(datetime('now','localtime'))" +
"); "
},
//
async initData(option){
console.log('initoption',option)
let that = this;
let data = JSON.parse(option);
let insertData = {
Company : data.Company,
ContactLinks: data.ContactLinks,
peopleName: data.peopleName,
imgUrl: data.imgUrl
}
that.contactsInfo = insertData;
that.textImgUrl = 'file://'+that.contactsInfo.imgUrl;
//db
await that.writeToDb("Contacts",that.contactsInfo);
},
//
async getHistoryData(params){
//console.log('historyparams',params)
let that = this;
const data = JSON.parse(params);
that.contactsInfo = data;
console.log('contactsInfo',that.contactsInfo)
that.textImgUrl = 'file://'+that.contactsInfo.imgUrl;
}
}
}
@ -84,13 +212,13 @@
align-items: center;
justify-content: center;
background-color: #000000;
height:100%;
height:100vh;
.listView{
z-index: 0;
position: relative;
width: 660rpx;
height: 1000rpx;
height: 1300rpx;
margin-top: 100rpx;
background-color: #141b29;
@ -115,12 +243,13 @@
//border: 2px solid red;
background-color: #141b29;
font-size: 60rpx;
color: #8f8f94;
height: 120rpx;
text-align: center;
.toolText{
font-size: 24rpx;
color: #fff;
color: #8f8f94;
}
}
@ -153,8 +282,11 @@
.icon{
z-index: 1;
position: absolute;
margin-top: -960rpx;
margin-top: -620rpx;
background-color: #3e444d;
font-size: 120rpx;
color: #fff;
text-align: center;
}
.bottomText{

241
pages/scan/Email.vue

@ -1,19 +1,34 @@
<template>
<view class="content">
<tn-avatar src="/static/logo.png" class="icon" size="xl"></tn-avatar>
<tn-avatar class="icon tn-icon-email" size="xl"></tn-avatar>
<tn-list-view :card="true" unlined="all" class="listView">
<tn-list-cell class="listItem-1">
<view>To: {{ emailInfo.address }}</view>
<view>Subject: {{ emailInfo.subject }}</view>
<view>Content: {{ emailInfo.body }}</view>
<view>To: {{ emailInfo.addressInfo }}</view>
<view>Subject: {{ emailInfo.SubjectInfo }}</view>
<view>Content: {{ emailInfo.BodyInfo }}</view>
</tn-list-cell>
<tn-list-cell class="listItem">
<tn-grid align="center" :col="col">
<block v-for="(item, index) in fastToolList" :key="index">
<tn-grid-item class="toolItem">
<view :class="item.icon"></view>
<block>
<tn-grid-item class="toolItem" @click="sendEmail()">
<view class="tn-icon-email"></view>
<view class="cutline"></view>
<view class="toolText">{{ item.text }}</view>
<view class="toolText">Send email</view>
</tn-grid-item>
<tn-grid-item class="toolItem" @click="addContact()">
<view class="tn-icon-my-circle-fill"></view>
<view class="cutline"></view>
<view class="toolText">Add to contacts</view>
</tn-grid-item>
<tn-grid-item class="toolItem" @click="share()">
<view class="tn-icon-share-triangle"></view>
<view class="cutline"></view>
<view class="toolText">Share</view>
</tn-grid-item>
<tn-grid-item class="toolItem" @click="copyValue()">
<view class="tn-icon-copy-fill"></view>
<view class="cutline"></view>
<view class="toolText">Copy</view>
</tn-grid-item>
</block>
</tn-grid>
@ -21,7 +36,7 @@
<view class="cutline"></view>
<tn-list-cell class="listItem-ad">我是谷歌ad部分</tn-list-cell>
<tn-list-cell class="listItemBottom">
<image src="/static/logo.png" class="buttomImg"/>
<image :src="textImgUrl" class="buttomImg"/>
</tn-list-cell>
</tn-list-view>
<text class="bottomText">Feedback or Suggestion</text>
@ -35,40 +50,179 @@
return {
col: 4,
emailInfo:{},
fastToolList:[
{
"index": 0,
"text":"Send email",
"icon": "tn-icon-email"
},
{
"index": 1,
"text":"Add to contacts",
"icon": "tn-icon-my-circle-fill"
},
{
"index": 2,
"text":"Copy",
"icon": "tn-icon-copy-fill"
},
{
"index": 3,
"text":"Share",
"icon": "tn-icon-share-triangle"
}
]
tableName: 'scan_code',
textImgUrl: '',
}
},
onLoad(option) {
async onLoad(option) {
console.log('onLoadOption',option)
let that = this;
that.initData(option);
//db
await that.openSqlite();
//
await that.createTable();
//scan,history
if(option.category === 'scan'){
//db
await that.initData(option.data);
}else{
//
await that.getHistoryData(option.data);
}
},
onHide() {
let that = this;
that.closedb();
},
methods: {
initData(option){
//
sendEmail(){
},
//
addContact(){
},
//
share(){
uni.shareWithSystem({
summary: '',
href: 'https://uniapp.dcloud.io',
success(){
//
uni.showToast({
title: 'share success!'
});
},
fail(){
//
uni.showToast({
title: 'share fail!'
});
}
})
},
//copy
copyValue(){
let that = this;
//console.log('')
uni.setClipboardData({
data: that.emailInfo,
success() {
uni.showToast({
title: 'copy success!'
});
}
})
},
//
async openSqlite(){
try{
let b = await openSqlite()
// uni.showToast({
// title:"open db success",
// icon:"none"
// })
console.log('db打开了');
}catch(e){
console.error("open db error",e)
}
},
//
closedb(){
try{
closedb()
console.log('db关闭了');
}catch(e){
console.error("close db error",e)
}
},
//
async createTable(){
let sql = this.createTableSql_outbound()
try{
let exist = await isTable(this.tableName)
console.log("表是否存在",exist)
if(!exist){
let res = await executeSql(sql)
// uni.showToast({
// title:"insert table ok",
// icon:"none"
// })
console.log("新增表scancode",res)
}else{
// uni.showToast({
// title:"table exist",
// icon:"none"
// })
console.log("表scancode已存在")
}
}catch(e){
uni.showToast({
title:"insert table error",
icon:"none"
})
console.error("新增表报错scancode",e)
}
},
//
async writeToDb(type,params){
try{
let data = {
category: type,
content: params
}
let b = await addSql(this.tableName,data)
console.log("数据添加成功!")
}catch(e){
console.error("insert data error!",e)
}
},
//
createTableSql_outbound(){
return "CREATE TABLE IF NOT EXISTS `scan_code` (" +
" `id` INTEGER PRIMARY KEY AUTOINCREMENT," +
" `category` varchar(50) DEFAULT NULL ," +
" `content` text DEFAULT NULL ," +
" `createTime` datetime DEFAULT CURRENT_TIMESTAMP ," +
" `updateTime` datetime DEFAULT NULL default(datetime('now','localtime'))" +
"); "
},
//
async initData(option){
//console.log('initoption',option)
let that = this;
let data = JSON.parse(option);
let insertData = {
addressInfo : data.addressInfo,
SubjectInfo: data.SubjectInfo,
BodyInfo: data.BodyInfo,
imgUrl: data.imgUrl
}
that.emailInfo = insertData;
that.textImgUrl = 'file://'+that.emailInfo.imgUrl;
//db
await that.writeToDb("Email",that.emailInfo);
},
//
async getHistoryData(params){
//console.log('historyparams',params)
let that = this;
let data = JSON.parse(option.data);
const data = JSON.parse(params);
that.emailInfo = data;
console.log('emailInfo',that.emailInfo)
that.textImgUrl = 'file://'+that.emailInfo.imgUrl;
}
}
}
@ -81,13 +235,13 @@
align-items: center;
justify-content: center;
background-color: #000000;
height:100%;
height:100vh;
.listView{
z-index: 0;
position: relative;
width: 660rpx;
height: 1000rpx;
height: 1300rpx;
margin-top: 100rpx;
background-color: #141b29;
@ -112,14 +266,14 @@
//border: 2px solid red;
background-color: #141b29;
font-size: 60rpx;
color: #8f8f94;
height: 120rpx;
text-align: center;
.toolText{
font-size: 24rpx;
color: #fff;
color: #8f8f94;
}
}
@ -153,8 +307,11 @@
.icon{
z-index: 1;
position: absolute;
margin-top: -960rpx;
margin-top: -620rpx;
background-color: #3e444d;
font-size: 120rpx;
color: #fff;
text-align: center;
}
.bottomText{

225
pages/scan/Location.vue

@ -1,18 +1,33 @@
<template>
<view class="content">
<tn-avatar src="/static/logo.png" class="icon" size="xl"></tn-avatar>
<tn-avatar class="icon tn-icon-location" size="xl"></tn-avatar>
<tn-list-view :card="true" unlined="all" class="listView">
<tn-list-cell class="listItem-1">
<view>Lng: {{ locationInfo.lng }}</view>
<view>Lat: {{ locationInfo.lat }}</view>
<view>Lng: {{ locationInfo.Longitude }}</view>
<view>Lat: {{ locationInfo.Latitude }}</view>
</tn-list-cell>
<tn-list-cell class="listItem">
<tn-grid align="center" :col="col">
<block v-for="(item, index) in fastToolList" :key="index">
<tn-grid-item class="toolItem">
<view :class="item.icon"></view>
<block>
<tn-grid-item class="toolItem" @click="showMap()">
<view class="tn-icon-map"></view>
<view class="cutline"></view>
<view class="toolText">{{ item.text }}</view>
<view class="toolText">Show map</view>
</tn-grid-item>
<tn-grid-item class="toolItem" @click="getDirection()">
<view class="tn-icon-share"></view>
<view class="cutline"></view>
<view class="toolText">Navigation</view>
</tn-grid-item>
<tn-grid-item class="toolItem" @click="share()">
<view class="tn-icon-share-triangle"></view>
<view class="cutline"></view>
<view class="toolText">Share</view>
</tn-grid-item>
<tn-grid-item class="toolItem" @click="copyValue()">
<view class="tn-icon-copy-fill"></view>
<view class="cutline"></view>
<view class="toolText">Copy</view>
</tn-grid-item>
</block>
</tn-grid>
@ -20,7 +35,7 @@
<view class="cutline"></view>
<tn-list-cell class="listItem-ad">我是谷歌ad部分</tn-list-cell>
<tn-list-cell class="listItemBottom">
<image src="/static/logo.png" class="buttomImg"/>
<image :src="textImgUrl" class="buttomImg"/>
</tn-list-cell>
</tn-list-view>
<text class="bottomText">Feedback or Suggestion</text>
@ -34,40 +49,166 @@
return {
col: 4,
locationInfo:{},
fastToolList:[
{
"index": 0,
"text":"Show on map",
"icon": "tn-icon-map"
},
{
"index": 1,
"text":"Navigation",
"icon": "tn-icon-share"
},
{
"index": 2,
"text":"Copy",
"icon": "tn-icon-copy-fill"
},
{
"index": 3,
"text":"Share",
"icon": "tn-icon-share-triangle"
}
]
tableName: 'scan_code',
textImgUrl: '',
}
},
onLoad(option) {
async onLoad(option) {
console.log('onLoadOption',option)
let that = this;
that.initData(option);
//db
await that.openSqlite();
//
await that.createTable();
//scan,history
if(option.category === 'scan'){
//db
await that.initData(option.data);
}else{
//
await that.getHistoryData(option.data);
}
},
onHide() {
let that = this;
that.closedb();
},
methods: {
initData(option){
//
showMap(){
},
//
getDirection(){
},
//
share(){
uni.shareWithSystem({
summary: '',
href: 'https://uniapp.dcloud.io',
success(){
//
uni.showToast({
title: 'share success!'
});
},
fail(){
//
uni.showToast({
title: 'share fail!'
});
}
})
},
//copy
copyValue(){
let that = this;
let data = JSON.parse(option.data);
//console.log('')
uni.setClipboardData({
data: that.locationInfo,
success() {
uni.showToast({
title: 'copy success!'
});
}
})
},
//
async openSqlite(){
try{
let b = await openSqlite()
console.log('db打开了');
}catch(e){
console.error("open db error",e)
}
},
//
closedb(){
try{
closedb()
console.log('db关闭了');
}catch(e){
console.error("close db error",e)
}
},
//
async createTable(){
let sql = this.createTableSql_outbound()
try{
let exist = await isTable(this.tableName)
console.log("表是否存在",exist)
if(!exist){
let res = await executeSql(sql)
console.log("新增表scancode",res)
}else{
console.log("表scancode已存在")
}
}catch(e){
uni.showToast({
title:"insert table error",
icon:"none"
})
console.error("新增表报错scancode",e)
}
},
//
async writeToDb(type,params){
try{
let data = {
category: type,
content: params
}
let b = await addSql(this.tableName,data)
console.log("数据添加成功!")
}catch(e){
console.error("insert data error!",e)
}
},
//
createTableSql_outbound(){
return "CREATE TABLE IF NOT EXISTS `scan_code` (" +
" `id` INTEGER PRIMARY KEY AUTOINCREMENT," +
" `category` varchar(50) DEFAULT NULL ," +
" `content` text DEFAULT NULL ," +
" `createTime` datetime DEFAULT CURRENT_TIMESTAMP ," +
" `updateTime` datetime DEFAULT NULL default(datetime('now','localtime'))" +
"); "
},
//
async initData(option){
//console.log('initoption',option)
let that = this;
let data = JSON.parse(option);
let insertData = {
Longitude : data.Longitude,
Latitude: data.Latitude,
imgUrl: data.imgUrl
}
that.locationInfo = insertData;
that.textImgUrl = 'file://'+that.locationInfo.imgUrl;
//db
await that.writeToDb("Location",that.locationInfo);
},
//
async getHistoryData(params){
//console.log('historyparams',params)
let that = this;
const data = JSON.parse(params);
that.locationInfo = data;
console.log('locationInfo',that.locationInfo)
that.textImgUrl = 'file://'+that.locationInfo.imgUrl;
}
}
}
@ -80,13 +221,13 @@
align-items: center;
justify-content: center;
background-color: #000000;
height:100%;
height:100vh;
.listView{
z-index: 0;
position: relative;
width: 660rpx;
height: 1000rpx;
height: 1300rpx;
margin-top: 100rpx;
background-color: #141b29;
@ -111,6 +252,7 @@
//border: 2px solid red;
background-color: #141b29;
font-size: 60rpx;
color: #8f8f94;
height: 120rpx;
text-align: center;
@ -118,7 +260,7 @@
.toolText{
font-size: 24rpx;
color: #fff;
color: #8f8f94;
}
}
@ -151,8 +293,11 @@
.icon{
z-index: 1;
position: absolute;
margin-top: -960rpx;
margin-top: -620rpx;
background-color: #3e444d;
font-size: 120rpx;
color: #fff;
text-align: center;
}
.bottomText{

254
pages/scan/Product.vue

@ -1,17 +1,32 @@
<template>
<view class="content">
<tn-avatar src="/static/logo.png" class="icon" size="xl"></tn-avatar>
<tn-avatar class="icon tn-icon-all" size="xl"></tn-avatar>
<tn-list-view :card="true" unlined="all" class="listView">
<tn-list-cell class="listItem-1">
<view>code: {{ productInfo.display }}</view>
<view>code: {{ productInfo.message }}</view>
</tn-list-cell>
<tn-list-cell class="listItem">
<tn-grid align="center" :col="col">
<block v-for="(item, index) in fastToolList" :key="index">
<tn-grid-item class="toolItem">
<view :class="item.icon"></view>
<block class="block1">
<tn-grid-item class="toolItem" @click="openShoping()">
<view class="tn-icon-shop"></view>
<view class="cutline"></view>
<view class="toolText">{{ item.text }}</view>
<view class="toolText">View in store</view>
</tn-grid-item>
<tn-grid-item class="toolItem" @click="openWeb()">
<view class="tn-icon-search"></view>
<view class="cutline"></view>
<view class="toolText">Web Search</view>
</tn-grid-item>
<tn-grid-item class="toolItem" @click="copyValue()">
<view class="tn-icon-copy-fill"></view>
<view class="cutline"></view>
<view class="toolText">Copy</view>
</tn-grid-item>
<tn-grid-item class="toolItem" @click="share()">
<view class="tn-icon-share-triangle"></view>
<view class="cutline"></view>
<view class="toolText">Share</view>
</tn-grid-item>
</block>
</tn-grid>
@ -19,7 +34,7 @@
<view class="cutline"></view>
<tn-list-cell class="listItem-ad">我是谷歌ad部分</tn-list-cell>
<tn-list-cell class="listItemBottom">
<image src="/static/logo.png" class="buttomImg"/>
<image :src="textImgUrl" class="buttomImg"/>
</tn-list-cell>
</tn-list-view>
<text class="bottomText">Feedback or Suggestion</text>
@ -31,37 +46,177 @@
export default {
data() {
return {
col: 3,
col: 4,
productInfo:{},
fastToolList:[
{
"index": 0,
"text":"Web Search",
"icon": "tn-icon-search"
},
{
"index": 1,
"text":"View in store",
"icon": "tn-icon-shop"
},
{
"index": 2,
"text":"Copy",
"icon": "tn-icon-copy-fill"
}
]
tableName: 'scan_code',
textImgUrl: '',
}
},
onLoad(option) {
async onLoad(option) {
console.log('onLoadOption',option)
let that = this;
that.initData(option);
//db
await that.openSqlite();
//
await that.createTable();
//scan,history
if(option.category === 'scan'){
//db
await that.initData(option.data);
}else{
//
await that.getHistoryData(option.data);
}
},
onHide() {
let that = this;
that.closedb();
},
methods: {
initData(option){
//
openShoping(){
let that = this;
let data = JSON.parse(option.data);
console.log('that.textInfo.message',that.productInfo.message)
uni.navigateTo({
url: '/pages/webview/webview?url=https://www.amazon.com/s?k=' + that.productInfo.message
//url: '/pages/webview/webview?url=http://www.google.com?wd=' + that.textInfo.message
});
},
//
share(){
uni.shareWithSystem({
summary: '',
href: 'https://uniapp.dcloud.io',
success(){
//
uni.showToast({
title: 'share success!'
});
},
fail(){
//
uni.showToast({
title: 'share fail!'
});
}
})
},
//
openWeb(){
let that = this;
console.log('that.textInfo.message',that.productInfo.message)
uni.navigateTo({
url: '/pages/webview/webview?url=https://www.baidu.com/s?wd=' + that.productInfo.message
//url: '/pages/webview/webview?url=http://www.google.com?wd=' + that.textInfo.message
});
},
//copy
copyValue(){
let that = this;
//console.log('')
uni.setClipboardData({
data: that.productInfo.message,
success() {
uni.showToast({
title: 'copy success!'
});
}
})
},
//
async openSqlite(){
try{
let b = await openSqlite()
console.log('db打开了');
}catch(e){
console.error("open db error",e)
}
},
//
closedb(){
try{
closedb()
console.log('db关闭了');
}catch(e){
console.error("close db error",e)
}
},
//
async createTable(){
let sql = this.createTableSql_outbound()
try{
let exist = await isTable(this.tableName)
console.log("表是否存在",exist)
if(!exist){
let res = await executeSql(sql)
console.log("新增表scancode",res)
}else{
console.log("表scancode已存在")
}
}catch(e){
uni.showToast({
title:"insert table error",
icon:"none"
})
console.error("新增表报错scancode",e)
}
},
//
async writeToDb(type,params){
try{
let data = {
category: type,
content: params
}
let b = await addSql(this.tableName,data)
console.log("数据添加成功!")
}catch(e){
console.error("insert data error!",e)
}
},
//
createTableSql_outbound(){
return "CREATE TABLE IF NOT EXISTS `scan_code` (" +
" `id` INTEGER PRIMARY KEY AUTOINCREMENT," +
" `category` varchar(50) DEFAULT NULL ," +
" `content` text DEFAULT NULL ," +
" `createTime` datetime DEFAULT CURRENT_TIMESTAMP ," +
" `updateTime` datetime DEFAULT NULL default(datetime('now','localtime'))" +
"); "
},
//
async initData(option){
//console.log('initoption',option)
let that = this;
let data = JSON.parse(option);
let insertData = {
message : data.message,
imgUrl: data.imgUrl
}
that.productInfo = insertData;
that.textImgUrl = 'file://'+that.productInfo.imgUrl;
//db
await that.writeToDb("Product",that.productInfo);
},
//
async getHistoryData(params){
//console.log('historyparams',params)
let that = this;
const data = JSON.parse(params);
that.productInfo = data;
console.log('productInfo',that.productInfo)
that.textImgUrl = 'file://'+that.productInfo.imgUrl;
}
}
}
@ -74,13 +229,14 @@
align-items: center;
justify-content: center;
background-color: #000000;
height:100%;
height:100vh;
.listView{
//border: 2px solid yellow;
z-index: 0;
position: relative;
width: 660rpx;
height: 1000rpx;
height: 1300rpx;
margin-top: 100rpx;
background-color: #141b29;
@ -96,26 +252,30 @@
.listItem{
//border: 2px solid yellow;
height: 160rpx;
width: 660rpx;
//margin-top: 30px;
//padding-top: 30px;
background-color: #141b29;
color: #fff;
}
.toolItem{
//border: 2px solid red;
background-color: #141b29;
font-size: 60rpx;
height: 120rpx;
text-align: center;
.toolText{
font-size: 24rpx;
color: #fff;
}
}
.toolItem{
//border: 2px solid red;
background-color: #141b29;
font-size: 60rpx;
color: #8f8f94;
height: 120rpx;
text-align: center;
.toolText{
font-size: 24rpx;
color: #8f8f94;
}
}
.listItem-ad{
background-color: #141b29;
text-align: center;
@ -144,8 +304,11 @@
.icon{
z-index: 1;
position: absolute;
margin-top: -960rpx;
margin-top: -620rpx;
background-color: #3e444d;
font-size: 120rpx;
color: #fff;
text-align: center;
}
@ -162,3 +325,4 @@
}
</style>

301
pages/scan/Scan.nvue

@ -1,52 +1,175 @@
<template>
<div class="content">
<view class="content">
<view style="width: 750rpx;flex: 1;position: relative;">
<ly-hwscan ref="scanComponent" style="width: 750rpx;position: absolute;left: 0;top: 0;bottom: 0;" :scanSize="scanSize" :scanResultImage="scanResultImage" :showScanFrame="showScanFrame" :scanType="scanType" :showScanLine="showScanLine" :scanLineColor="scanLineColor" :lineAnimationDuration="lineAnimationDuration"
:continue="scanContinue" @scanResult="scanResult" :sleepTime="sleep">
</ly-hwscan>
<view class="bg">
<text class="scanTitle">Scan the QR code in the box</text>
<!-- 这个是在识别区域的位置后续自定义扫码框都在这里面 大小需要和scanSize相同单位是px-->
<!-- <view class="scan_frame"> -->
<image class="scan_frame" src="../../static/scan.png"></image>
<!-- </view> -->
<!-- 扫码框下方图片按钮 -->
<view class="scan_frame_bottom_btn">
<image class="btn" src="../../static/flashLightOn.png" @click="lightOff()" v-if="flashLightFlag === true"></image>
<image class="btn" src="../../static/flashLightOff.png" @click="lightOn()" v-if="flashLightFlag === false"></image>
<image class="btn" src="../../static/album.png" @click="photoAlbum()"></image>
</view>
</view>
</view>
<!-- <button @click="scanCode()">扫码</button> -->
<tn-button shape="round" backgroundColor="#01BEFF" fontColor="#080808" @click="jumpToPage('/pages/scan/Barcode')">跳转Barcode页面</tn-button>
<tn-button shape="round" @click="jumpToPage('/pages/scan/Book')">跳转Book页面</tn-button>
<tn-button shape="round" @click="jumpToPage('/pages/scan/Calendar')">跳转Calendar页面</tn-button>
<tn-button shape="round" @clicksss="jumpToPage('/pages/scan/Contacts')">跳转Contacts页面</tn-button>
<tn-button shape="round" @click="jumpToPage('/pages/scan/Email')">跳转Email页面</tn-button>
<tn-button shape="round" @click="jumpToPage('/pages/scan/Location')">跳转Location页面</tn-button>
<tn-button shape="round" @click="jumpToPage('/pages/scan/Paypal')">跳转Paypal页面</tn-button>
<tn-button shape="round" @click="jumpToPage('/pages/scan/Product')">跳转Product页面</tn-button>
<tn-button shape="round" @click="jumpToPage('/pages/scan/Sms')">跳转Sms页面</tn-button>
<tn-button shape="round" @click="jumpToPage('/pages/scan/Tel')">跳转Tel页面</tn-button>
<tn-button shape="round" @click="jumpToPage('/pages/scan/Text')">跳转Text页面</tn-button>
<tn-button shape="round" @click="jumpToPage('/pages/scan/Url')">跳转Url页面</tn-button>
<tn-button shape="round" @click="jumpToPage('/pages/scan/Wifi')">跳转Wifi页面</tn-button>
<button @click="scanCode()">扫码</button>
<button type="primary" @click="clearData()">清空数据</button>
<button type="primary" @click="deleteTable()">删除数据表</button>
<tn-button shape="round" @click="jumpToPage('/pages/scan/Book','history',{})">跳转Book页面</tn-button>
<tn-button shape="round" @click="jumpToPage('/pages/scan/Calendar','history',{})">跳转Calendar页面</tn-button>
<tn-button shape="round" @clicksss="jumpToPage('/pages/scan/Contacts','history',{})">跳转Contacts页面</tn-button>
<tn-button shape="round" @click="jumpToPage('/pages/scan/Email','history',{})">跳转Email页面</tn-button>
<tn-button shape="round" @click="jumpToPage('/pages/scan/Location','history',{})">跳转Location页面</tn-button>
<tn-button shape="round" @click="jumpToPage('/pages/scan/Paypal','history',{})">跳转Paypal页面</tn-button>
<tn-button shape="round" @click="jumpToPage('/pages/scan/Product','history',{})">跳转Product页面</tn-button>
<tn-button shape="round" @click="jumpToPage('/pages/scan/Sms','history',{})">跳转Sms页面</tn-button>
<tn-button shape="round" @click="jumpToPage('/pages/scan/Tel','history',{})">跳转Tel页面</tn-button>
<tn-button shape="round" @click="jumpToPage('/pages/scan/Text','history',{})">跳转Text页面</tn-button>
<tn-button shape="round" @click="jumpToPage('/pages/scan/Url','history',{})">跳转Url页面</tn-button>
<tn-button shape="round" @click="jumpToPage('/pages/scan/Wifi','history',{})">跳转Wifi页面</tn-button>
<!-- <button type="primary" @click="clearData()">清空数据 </button>
<button type="primary" @click="deleteTable()">删除数据表</button> -->
<!-- <button @click="writeToDb()">添加数据</button> -->
<!-- <tn-button type="primary" @click="writeToDb()">添加数据</tn-button> -->
<!-- <tn-toast ref="toast"></tn-toast> -->
</div>
</view>
</template>
<script>
import { openSqlite,executeSql,closedb} from "@/utils/database";
const hwscan = uni.requireNativePlugin('LY-HWScan')
export default {
data() {
return {
title: 'Scan',
tableName:"scan_code"
tableName:"scan_code",
// 识别区域size
scanSize:{//单位px
width:250,
height:250
},
showScanLine:true,//显示扫码线
scanLineColor:"#0186FF",//扫描线背景色
lineAnimationDuration:"3",//扫描线动画时间
showScanFrame:false,//显示测试扫描框 用于调试扫描区域
scanResultImage: true, //是否返回扫描图片--默认不返回(仅Android有效)
scanType: [],//设置可扫描的码制式
scanContinue: false,
sleep: 1,//连续扫描间隔
code: "",
path:'',//扫描图片
flashLightFlag: true
}
},
created() {
// this.scanCode();
},
async onShow(){
let that = this;
//打开db
await that.openSqlite();
if(this.$refs.scanComponent){
this.$refs.scanComponent.remoteResume();
}
},
onHide() {
let that = this;
that.closedb();
if(this.$refs.scanComponent){
this.$refs.scanComponent.remotePause();
}
},
onUnload() {
// this.$refs.scanComponent.releaseAssets()
},
methods: {
// 识别完成回调 ------ res.detail.data是组装好的数据
scanResult(res) {
console.log(res.detail.data)
this.analyserCode(res.detail.data);
// uni.navigateTo({
// url:'./showSanResult?info='+JSON.stringify(res.detail.data)
// })
// hwscan.clearCacheWithFilePath(this.path,res=>{
// uni.showToast({
// title: res.result?"删除成功":"删除失败",
// icon: 'none',
// duration: 1500
// })
// })
// uni.$emit("commonScanResult", {
// result: res.detail.result,
// path :this.path
// });
// uni.navigateBack()
},
analyserCode(res){
let that = this;
let result = JSON.parse(JSON.stringify(res))
console.log('result',result)
let type = result.scanType;
console.log('type',type)
if(type === 'contact_detail'){
that.jumpToPage('/pages/scan/Contacts','scan',JSON.stringify(result))
}else if(type === 'email'){
that.jumpToPage('/pages/scan/Email','scan',JSON.stringify(result))
}else if(type === 3){
that.jumpToPage('/pages/scan/Book','scan',JSON.stringify(result))
}else if(type === 'tel_phone'){
that.jumpToPage('/pages/scan/Tel','scan',JSON.stringify(result))
}else if(type === 'article'){
that.jumpToPage('/pages/scan/Product','scan',JSON.stringify(result))
}else if(type === 'sms'){
that.jumpToPage('/pages/scan/Sms','scan',JSON.stringify(result))
}else if(type === 'text'){
that.jumpToPage('/pages/scan/Text','scan',JSON.stringify(result))
}else if(type === 'url'){
that.jumpToPage('/pages/scan/Url','scan',JSON.stringify(result))
}else if(type === 'wifi'){
that.jumpToPage('/pages/scan/Wifi','scan',JSON.stringify(result))
}else if(type === 'location'){
that.jumpToPage('/pages/scan/Location','scan',JSON.stringify(result))
}else if(type === 'event_info'){
that.jumpToPage('/pages/scan/Calendar','scan',JSON.stringify(result))
}else if(type === 'isbn'){
that.jumpToPage('/pages/scan/Barcode','scan',JSON.stringify(result))
}
},
//暂停扫描
pauseScan() {
this.$refs.scanComponent.pauseScan();
},
//恢复扫描
resumeScan() {
this.$refs.scanComponent.resumeScan();
},
//跳相册
photoAlbum() {
this.$refs.scanComponent.pictureScan();
},
//开启闪光灯
lightOn() {
this.flashLightFlag = true
this.$refs.scanComponent.switchLight();
},
//关闭闪光灯
lightOff() {
this.flashLightFlag = false
this.$refs.scanComponent.switchLight();
},
releaseAssets() {
this.$refs.scanComponent.releaseAssets();
},
// 打开数据库
async openSqlite(){
try{
@ -113,75 +236,95 @@
},
//mlkit扫码
scanCode(){
let that = this;
var mlscan = uni.requireNativePlugin("JY-MLScanSDK");
//console.log(mlscan)
mlscan.startScan(res=> {
that.analyserCode(res);
// uni.showToast({
// icon:'none',
// title:JSON.stringify(res)
// })
// scanCode(){
// let that = this;
// var mlscan = uni.requireNativePlugin("JY-MLScanSDK");
// //console.log(mlscan)
// mlscan.startScan(res=> {
// that.analyserCode(res);
// // uni.showToast({
// // icon:'none',
// // title:JSON.stringify(res)
// // })
})
},
// })
// },
analyserCode(res){
let that = this;
let result = JSON.parse(JSON.stringify(res))
console.log('result',result)
let data = JSON.parse(result.data)
console.log('data',data)
let type = data[0].type
console.log('type',type)
let data2 = data[0].data
console.log('data2',data2)
// let data3 = JSON.stringify(data[0].data)
// console.log('data3',data3)
if(result.errorCode != "0"){
uni.showToast({
icon:'none',
title: 'scan error!'
})
}else{
if(type === 1){
that.jumpToPage('/pages/scan/Contacts','scan',JSON.stringify(data2))
}else if(type === 2){
that.jumpToPage('/pages/scan/Email','scan',JSON.stringify(data2))
}else if(type === 3){
that.jumpToPage('/pages/scan/Book','scan',JSON.stringify(data2))
}else if(type === 4){
that.jumpToPage('/pages/scan/Tel','scan',JSON.stringify(data2))
}else if(type === 5){
that.jumpToPage('/pages/scan/Product','scan',JSON.stringify(data2))
}else if(type === 6){
that.jumpToPage('/pages/scan/Sms','scan',JSON.stringify(data2))
}else if(type === 7){
that.jumpToPage('/pages/scan/Text','scan',JSON.stringify(data2))
}else if(type === 8){
that.jumpToPage('/pages/scan/Url','scan',JSON.stringify(data2))
}else if(type === 9){
that.jumpToPage('/pages/scan/Wifi','scan',JSON.stringify(data2))
}else if(type === 10){
that.jumpToPage('/pages/scan/Location','scan',JSON.stringify(data2))
}else if(type === 11){
that.jumpToPage('/pages/scan/Calendar','scan',JSON.stringify(data2))
}
}
}
}
}
</script>
<style lang="scss">
// .content {
// display: flex;
// flex-direction: column;
// align-items: center;
// justify-content: center;
// }
.content {
width: 750rpx;
flex: 1;
background-color: #ffffff;
align-items: center;
justify-content: center;
position: relative;
}
.bg{
width: 750rpx;
flex: 1;
background-color: #00ffffff;
position: relative;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.btn_view {
display: flex;
flex-direction: column;
position: absolute;
left: 0;
bottom: 0;
width: 750rpx;
}
// .scan_frame{
// width: 300px;
// height: 300px;
// background-color: #00FFFFFF;
// }
.scanTitle {
font-size: 36rpx;
//margin-top: 50rpx;
color: #ffffff;
}
.scan_frame {
width: 450px;
height: 450px;
}
.scan_frame_bottom_btn{
position: absolute;
display: flex;
flex-direction: row;
width: 750rpx;
left: 0;
margin-top: 300px;
padding-left: 30px;
padding-right: 30px;
justify-content: space-between;
}
.btn{
width: 100rpx;
height: 100rpx;
margin-top: 200rpx;
background-color: #707070;
border-radius: 100%;
}
</style>

146
pages/scan/Sms.vue

@ -1,18 +1,18 @@
<template>
<view class="content">
<tn-avatar src="/static/logo.png" class="icon" size="xl"></tn-avatar>
<tn-avatar class="icon tn-icon-message" size="xl"></tn-avatar>
<tn-list-view :card="true" unlined="all" class="listView">
<tn-list-cell class="listItem-1">
<view>Tel: {{ smsInfo.phoneNumber }}</view>
<view>Content: {{ smsInfo.message }}</view>
<view>Tel: {{ smsInfo.destPhoneNumber }}</view>
<view>Content: {{ smsInfo.msgContent }}</view>
</tn-list-cell>
<tn-list-cell class="listItem">
<tn-grid align="center" :col="col">
<block v-for="(item, index) in fastToolList" :key="index">
<tn-grid-item class="toolItem">
<view :class="item.icon"></view>
<block>
<tn-grid-item class="toolItem" @click="openWeb()">
<view class="tn-icon-search"></view>
<view class="cutline"></view>
<view class="toolText">{{ item.text }}</view>
<view class="toolText">Web Search</view>
</tn-grid-item>
</block>
</tn-grid>
@ -20,7 +20,7 @@
<view class="cutline"></view>
<tn-list-cell class="listItem-ad">我是谷歌ad部分</tn-list-cell>
<tn-list-cell class="listItemBottom">
<image src="/static/logo.png" class="buttomImg"/>
<image :src="textImgUrl" class="buttomImg"/>
</tn-list-cell>
</tn-list-view>
<text class="bottomText">Feedback or Suggestion</text>
@ -34,6 +34,8 @@
return {
col: 4,
smsInfo:{},
tableName: 'scan_code',
textImgUrl: '',
fastToolList:[
{
"index": 0,
@ -58,16 +60,117 @@
]
}
},
onLoad(option) {
async onLoad(option) {
console.log('onLoadOption',option)
let that = this;
that.initData(option);
//db
await that.openSqlite();
//
await that.createTable();
//scan,history
if(option.category === 'scan'){
//db
await that.initData(option.data);
}else{
//
await that.getHistoryData(option.data);
}
},
onHide() {
let that = this;
that.closedb();
},
methods: {
initData(option){
//
async openSqlite(){
try{
let b = await openSqlite()
console.log('db打开了');
}catch(e){
console.error("open db error",e)
}
},
//
closedb(){
try{
closedb()
console.log('db关闭了');
}catch(e){
console.error("close db error",e)
}
},
//
async createTable(){
let sql = this.createTableSql_outbound()
try{
let exist = await isTable(this.tableName)
console.log("表是否存在",exist)
if(!exist){
let res = await executeSql(sql)
console.log("新增表scancode",res)
}else{
console.log("表scancode已存在")
}
}catch(e){
uni.showToast({
title:"insert table error",
icon:"none"
})
console.error("新增表报错scancode",e)
}
},
//
async writeToDb(type,params){
try{
let data = {
category: type,
content: params
}
let b = await addSql(this.tableName,data)
console.log("数据添加成功!")
}catch(e){
console.error("insert data error!",e)
}
},
//
createTableSql_outbound(){
return "CREATE TABLE IF NOT EXISTS `scan_code` (" +
" `id` INTEGER PRIMARY KEY AUTOINCREMENT," +
" `category` varchar(50) DEFAULT NULL ," +
" `content` text DEFAULT NULL ," +
" `createTime` datetime DEFAULT CURRENT_TIMESTAMP ," +
" `updateTime` datetime DEFAULT NULL default(datetime('now','localtime'))" +
"); "
},
//
async initData(option){
//console.log('initoption',option)
let that = this;
let data = JSON.parse(option);
let insertData = {
destPhoneNumber: data.destPhoneNumber,
msgContent : data.msgContent,
imgUrl: data.imgUrl
}
that.smsInfo = insertData;
that.textImgUrl = 'file://'+that.smsInfo.imgUrl;
//db
await that.writeToDb("Sms",that.smsInfo);
},
//
async getHistoryData(params){
//console.log('historyparams',params)
let that = this;
let data = JSON.parse(option.data);
const data = JSON.parse(params);
that.smsInfo = data;
console.log('smsInfo',that.smsInfo)
that.textImgUrl = 'file://'+that.smsInfo.imgUrl;
}
}
}
@ -80,13 +183,13 @@
align-items: center;
justify-content: center;
background-color: #000000;
height:100%;
height:100vh;
.listView{
z-index: 0;
position: relative;
width: 660rpx;
height: 1000rpx;
height: 1300rpx;
margin-top: 100rpx;
background-color: #141b29;
@ -111,14 +214,16 @@
//border: 2px solid red;
background-color: #141b29;
font-size: 60rpx;
color: #8f8f94;
height: 120rpx;
text-align: center;
margin-left: 20rpx;
margin-right: 20rpx;
.toolText{
font-size: 24rpx;
color: #fff;
color: #8f8f94;
}
}
@ -151,8 +256,11 @@
.icon{
z-index: 1;
position: absolute;
margin-top: -960rpx;
margin-top: -620rpx;
background-color: #3e444d;
font-size: 120rpx;
color: #fff;
text-align: center;
}
.bottomText{

225
pages/scan/Tel.vue

@ -1,17 +1,32 @@
<template>
<view class="content">
<tn-avatar src="/static/logo.png" class="icon" size="xl"></tn-avatar>
<tn-avatar class="icon tn-icon-tel" size="xl"></tn-avatar>
<tn-list-view :card="true" unlined="all" class="listView">
<tn-list-cell class="listItem-1">
<view>Telephone number: {{ telInfo.number }}</view>
<view>Telephone number: {{ telInfo.TelPhoneNumber }}</view>
</tn-list-cell>
<tn-list-cell class="listItem">
<tn-grid align="center" :col="col">
<block v-for="(item, index) in fastToolList" :key="index">
<tn-grid-item class="toolItem">
<view :class="item.icon"></view>
<block>
<tn-grid-item class="toolItem" @click="addConnect()">
<view class="tn-icon-my-circle-fill"></view>
<view class="cutline"></view>
<view class="toolText">{{ item.text }}</view>
<view class="toolText">Add to contacts</view>
</tn-grid-item>
<tn-grid-item class="toolItem" @click="call()">
<view class="tn-icon-tel"></view>
<view class="cutline"></view>
<view class="toolText">Call</view>
</tn-grid-item>
<tn-grid-item class="toolItem" @click="share()">
<view class="tn-icon-share-triangle"></view>
<view class="cutline"></view>
<view class="toolText">Share</view>
</tn-grid-item>
<tn-grid-item class="toolItem" @click="copyValue()">
<view class="tn-icon-copy-fill"></view>
<view class="cutline"></view>
<view class="toolText">Copy</view>
</tn-grid-item>
</block>
</tn-grid>
@ -19,7 +34,7 @@
<view class="cutline"></view>
<tn-list-cell class="listItem-ad">我是谷歌ad部分</tn-list-cell>
<tn-list-cell class="listItemBottom">
<image src="/static/logo.png" class="buttomImg"/>
<image :src="textImgUrl" class="buttomImg"/>
</tn-list-cell>
</tn-list-view>
<text class="bottomText">Feedback or Suggestion</text>
@ -33,40 +48,165 @@
return {
col: 4,
telInfo:{},
fastToolList:[
{
"index": 0,
"text":"Call",
"icon": "tn-icon-tel"
},
{
"index": 1,
"text":"Add to contacts",
"icon": "tn-icon-my-circle-fill"
},
{
"index": 2,
"text":"Copy",
"icon": "tn-icon-copy-fill"
},
{
"index": 3,
"text":"Share",
"icon": "tn-icon-share-triangle"
}
]
tableName: 'scan_code',
textImgUrl: '',
}
},
onLoad(option) {
async onLoad(option) {
console.log('onLoadOption',option)
let that = this;
that.initData(option);
//db
await that.openSqlite();
//
await that.createTable();
//scan,history
if(option.category === 'scan'){
//db
await that.initData(option.data);
}else{
//
await that.getHistoryData(option.data);
}
},
onHide() {
let that = this;
that.closedb();
},
methods: {
initData(option){
//
addConnect(){
},
//
call(){
},
//
share(){
uni.shareWithSystem({
summary: '',
href: 'https://uniapp.dcloud.io',
success(){
//
uni.showToast({
title: 'share success!'
});
},
fail(){
//
uni.showToast({
title: 'share fail!'
});
}
})
},
//copy
copyValue(){
let that = this;
let data = JSON.parse(option.data);
//console.log('')
uni.setClipboardData({
data: telInfo.TelPhoneNumber,
success() {
uni.showToast({
title: 'copy success!'
});
}
})
},
//
async openSqlite(){
try{
let b = await openSqlite()
console.log('db打开了');
}catch(e){
console.error("open db error",e)
}
},
//
closedb(){
try{
closedb()
console.log('db关闭了');
}catch(e){
console.error("close db error",e)
}
},
//
async createTable(){
let sql = this.createTableSql_outbound()
try{
let exist = await isTable(this.tableName)
console.log("表是否存在",exist)
if(!exist){
let res = await executeSql(sql)
console.log("新增表scancode",res)
}else{
console.log("表scancode已存在")
}
}catch(e){
uni.showToast({
title:"insert table error",
icon:"none"
})
console.error("新增表报错scancode",e)
}
},
//
async writeToDb(type,params){
try{
let data = {
category: type,
content: params
}
let b = await addSql(this.tableName,data)
console.log("数据添加成功!")
}catch(e){
console.error("insert data error!",e)
}
},
//
createTableSql_outbound(){
return "CREATE TABLE IF NOT EXISTS `scan_code` (" +
" `id` INTEGER PRIMARY KEY AUTOINCREMENT," +
" `category` varchar(50) DEFAULT NULL ," +
" `content` text DEFAULT NULL ," +
" `createTime` datetime DEFAULT CURRENT_TIMESTAMP ," +
" `updateTime` datetime DEFAULT NULL default(datetime('now','localtime'))" +
"); "
},
//
async initData(option){
//console.log('initoption',option)
let that = this;
let data = JSON.parse(option);
let insertData = {
TelPhoneNumber : data.TelPhoneNumber,
imgUrl: data.imgUrl
}
that.telInfo = insertData;
that.textImgUrl = 'file://'+that.telInfo.imgUrl;
//db
await that.writeToDb("Tel",that.telInfo);
},
//
async getHistoryData(params){
//console.log('historyparams',params)
let that = this;
const data = JSON.parse(params);
//console.log('historydata',data)
that.telInfo = data;
console.log('telInfo',that.telInfo)
that.textImgUrl = 'file://'+that.telInfo.imgUrl;
}
}
}
@ -79,13 +219,13 @@
align-items: center;
justify-content: center;
background-color: #000000;
height:100%;
height:100vh;
.listView{
z-index: 0;
position: relative;
width: 660rpx;
height: 1000rpx;
height: 1300rpx;
margin-top: 100rpx;
background-color: #141b29;
@ -110,14 +250,16 @@
//border: 2px solid red;
background-color: #141b29;
font-size: 60rpx;
color: #8f8f94;
height: 120rpx;
text-align: center;
margin-left: 20rpx;
margin-right: 20rpx;
.toolText{
font-size: 24rpx;
color: #fff;
color: #8f8f94;
}
}
@ -150,8 +292,11 @@
.icon{
z-index: 1;
position: absolute;
margin-top: -960rpx;
margin-top: -620rpx;
background-color: #3e444d;
font-size: 120rpx;
color: #fff;
text-align: center;
}
.bottomText{

220
pages/scan/Text.vue

@ -1,17 +1,27 @@
<template>
<view class="content">
<tn-avatar src="/static/logo.png" class="icon" size="xl"></tn-avatar>
<tn-avatar class="icon tn-icon-level" size="xl"></tn-avatar>
<tn-list-view :card="true" unlined="all" class="listView">
<tn-list-cell class="listItem-1">
<view>{{ textInfo.display }}</view>
<view>{{ textInfo.message }}</view>
</tn-list-cell>
<tn-list-cell class="listItem">
<tn-grid align="center" :col="col">
<block v-for="(item, index) in fastToolList" :key="index">
<tn-grid-item class="toolItem">
<view :class="item.icon"></view>
<block>
<tn-grid-item class="toolItem" @click="openWeb()">
<view class="tn-icon-search"></view>
<view class="cutline"></view>
<view class="toolText">{{ item.text }}</view>
<view class="toolText">Web Search</view>
</tn-grid-item>
<tn-grid-item class="toolItem" @click="share()">
<view class="tn-icon-share-triangle"></view>
<view class="cutline"></view>
<view class="toolText">Share</view>
</tn-grid-item>
<tn-grid-item class="toolItem" @click="copyValue()">
<view class="tn-icon-copy-fill"></view>
<view class="cutline"></view>
<view class="toolText">Copy</view>
</tn-grid-item>
</block>
</tn-grid>
@ -19,7 +29,7 @@
<view class="cutline"></view>
<tn-list-cell class="listItem-ad">我是谷歌ad部分</tn-list-cell>
<tn-list-cell class="listItemBottom">
<image src="/static/logo.png" class="buttomImg"/>
<image :src="textImgUrl" class="buttomImg"/>
</tn-list-cell>
</tn-list-view>
<text class="bottomText">Feedback or Suggestion</text>
@ -33,40 +43,165 @@
return {
col: 4,
textInfo:{},
fastToolList:[
{
"index": 0,
"text":"Web Search",
"icon": "tn-icon-search"
},
{
"index": 1,
"text":"Send email",
"icon": "tn-icon-email"
},
{
"index": 2,
"text":"Copy",
"icon": "tn-icon-copy-fill"
},
{
"index": 3,
"text":"Share",
"icon": "tn-icon-share-triangle"
}
]
tableName: 'scan_code',
textImgUrl: '',
}
},
async onLoad(option) {
//console.log('onLoadOption',option)
let that = this;
//db
await that.openSqlite();
//
await that.createTable();
//scan,history
if(option.category === 'scan'){
//db
await that.initData(option.data);
}else{
//
await that.getHistoryData(option.data);
}
},
onLoad(option) {
onHide() {
let that = this;
that.initData(option);
that.closedb();
},
methods: {
initData(option){
//
share(){
uni.shareWithSystem({
summary: '',
href: 'https://uniapp.dcloud.io',
success(){
//
uni.showToast({
title: 'share success!'
});
},
fail(){
//
uni.showToast({
title: 'share fail!'
});
}
})
},
//
openWeb(){
let that = this;
console.log('that.textInfo.message',that.textInfo.message)
uni.navigateTo({
url: '/pages/webview/webview?url=https://www.baidu.com/s?wd=' + that.textInfo.message
//url: '/pages/webview/webview?url=http://www.google.com?wd=' + that.textInfo.message
});
},
//copy
copyValue(){
let that = this;
//console.log('')
uni.setClipboardData({
data: that.textInfo.message,
success() {
uni.showToast({
title: 'copy success!'
});
}
})
},
//
async openSqlite(){
try{
let b = await openSqlite()
console.log('db打开了');
}catch(e){
console.error("open db error",e)
}
},
//
closedb(){
try{
closedb()
console.log('db关闭了');
}catch(e){
console.error("close db error",e)
}
},
//
async createTable(){
let sql = this.createTableSql_outbound()
try{
let exist = await isTable(this.tableName)
console.log("表是否存在",exist)
if(!exist){
let res = await executeSql(sql)
console.log("新增表scancode",res)
}else{
console.log("表scancode已存在")
}
}catch(e){
uni.showToast({
title:"insert table error",
icon:"none"
})
console.error("新增表报错scancode",e)
}
},
//
async writeToDb(type,params){
try{
let data = {
category: type,
content: params
}
let b = await addSql(this.tableName,data)
console.log("数据添加成功!")
}catch(e){
console.error("insert data error!",e)
}
},
//
createTableSql_outbound(){
return "CREATE TABLE IF NOT EXISTS `scan_code` (" +
" `id` INTEGER PRIMARY KEY AUTOINCREMENT," +
" `category` varchar(50) DEFAULT NULL ," +
" `content` text DEFAULT NULL ," +
" `createTime` datetime DEFAULT CURRENT_TIMESTAMP ," +
" `updateTime` datetime DEFAULT NULL default(datetime('now','localtime'))" +
"); "
},
//
async initData(option){
//console.log('initoption',option)
let that = this;
let data = JSON.parse(option.data);
let data = JSON.parse(option);
//console.log('data',data)
let insertData = {
message : data.message,
imgUrl: data.imgUrl
}
that.textInfo = insertData;
that.textImgUrl = 'file://'+that.textInfo.imgUrl;
//db
await that.writeToDb("Text",that.textInfo);
},
//
async getHistoryData(params){
//console.log('historyparams',params)
let that = this;
const data = JSON.parse(params);
//console.log('historydata',data)
that.textInfo = data;
console.log('textInfo',that.textInfo)
that.textImgUrl = 'file://'+that.textInfo.imgUrl;
}
}
}
@ -79,13 +214,13 @@
align-items: center;
justify-content: center;
background-color: #000000;
height:100%;
height:100vh;
.listView{
z-index: 0;
position: relative;
width: 660rpx;
height: 1000rpx;
height: 1300rpx;
margin-top: 100rpx;
background-color: #141b29;
@ -106,18 +241,21 @@
background-color: #141b29;
color: #fff;
.toolItem{
//border: 2px solid red;
background-color: #141b29;
font-size: 60rpx;
color: #8f8f94;
height: 120rpx;
text-align: center;
margin-left: 20rpx;
margin-right: 20rpx;
.toolText{
font-size: 24rpx;
color: #fff;
color: #8f8f94;
}
}
@ -150,7 +288,11 @@
.icon{
z-index: 1;
position: absolute;
margin-top: -960rpx;
margin-top: -620rpx;
background-color: #3e444d;
font-size: 120rpx;
color: #fff;
text-align: center;
}

116
pages/scan/Url.vue

@ -1,17 +1,27 @@
<template>
<view class="content">
<tn-avatar src="/static/logo.png" class="icon" size="xl"></tn-avatar>
<tn-avatar class="icon tn-icon-link" size="xl"></tn-avatar>
<tn-list-view :card="true" unlined="all" class="listView">
<tn-list-cell class="listItem-1">
<view>Url: {{ urlInfo.url }}</view>
<view>Url: {{ urlInfo.LinkValue }}</view>
</tn-list-cell>
<tn-list-cell class="listItem">
<tn-grid align="center" :col="col">
<block v-for="(item, index) in fastToolList" :key="index">
<tn-grid-item class="toolItem">
<view :class="item.icon"></view>
<block>
<tn-grid-item class="toolItem" @click="openUrl()">
<view class="tn-icon-plane"></view>
<view class="cutline"></view>
<view class="toolText">{{ item.text }}</view>
<view class="toolText">Open</view>
</tn-grid-item>
<tn-grid-item class="toolItem" @click="share()">
<view class="tn-icon-share-triangle"></view>
<view class="cutline"></view>
<view class="toolText">Share</view>
</tn-grid-item>
<tn-grid-item class="toolItem" @click="copyValue()">
<view class="tn-icon-copy-fill"></view>
<view class="cutline"></view>
<view class="toolText">Copy</view>
</tn-grid-item>
</block>
</tn-grid>
@ -19,7 +29,7 @@
<view class="cutline"></view>
<tn-list-cell class="listItem-ad">我是谷歌ad部分</tn-list-cell>
<tn-list-cell class="listItemBottom">
<image src="/static/logo.png" class="buttomImg"/>
<image :src="textImgUrl" class="buttomImg"/>
</tn-list-cell>
</tn-list-view>
<text class="bottomText">Feedback or Suggestion</text>
@ -34,6 +44,7 @@
col: 3,
urlInfo:{},
tableName: 'scan_code',
textImgUrl: '',
fastToolList:[
{
"index": 0,
@ -73,15 +84,54 @@
that.closedb();
},
methods: {
//url
openUrl(){
let that = this;
uni.navigateTo({
url: '/pages/webview/webview?url=' + that.urlInfo.LinkValue
});
},
//
share(){
uni.shareWithSystem({
summary: '',
href: 'https://uniapp.dcloud.io',
success(){
//
uni.showToast({
title: 'share success!'
});
},
fail(){
//
uni.showToast({
title: 'share fail!'
});
}
})
},
//url
copyValue(){
let that = this;
//console.log('')
uni.setClipboardData({
data: that.urlInfo.LinkValue,
success() {
uni.showToast({
title: 'copy success!'
});
}
})
},
//
async openSqlite(){
try{
let b = await openSqlite()
// uni.showToast({
// title:"open db success",
// icon:"none"
// })
console.log('db打开了');
console.log('urlDb打开了');
}catch(e){
console.error("open db error",e)
}
@ -91,7 +141,7 @@
closedb(){
try{
closedb()
console.log('db关闭了');
console.log('urlDb关闭了');
}catch(e){
console.error("close db error",e)
}
@ -106,16 +156,8 @@
console.log("表是否存在",exist)
if(!exist){
let res = await executeSql(sql)
// uni.showToast({
// title:"insert table ok",
// icon:"none"
// })
console.log("新增表scancode",res)
}else{
// uni.showToast({
// title:"table exist",
// icon:"none"
// })
console.log("表scancode已存在")
}
}catch(e){
@ -135,7 +177,7 @@
content: params
}
let b = await addSql(this.tableName,data)
console.log("数据添加成功!")
console.log("数据添加成功!",data)
}catch(e){
console.error("insert data error!",e)
}
@ -156,18 +198,24 @@
async initData(params){
let that = this;
let data = JSON.parse(params);
that.urlInfo = data;
console.log('urlInfo',that.urlInfo)
let insertData = {
LinkValue : data.LinkValue,
imgUrl: data.imgUrl
}
that.urlInfo = insertData;
that.textImgUrl = 'file://'+that.urlInfo.imgUrl;
//console.log('urlInfo',that.urlInfo)
//db
await that.writeToDb("URL",that.urlInfo.url);
await that.writeToDb("Url",that.urlInfo);
},
//
async getHistoryData(params){
console.log(params)
let that = this;
let data = JSON.parse(params);
that.urlInfo = data;
console.log('HistotyUrlInfo',that.urlInfo)
that.textImgUrl = 'file://'+that.urlInfo.imgUrl;
}
}
}
@ -180,13 +228,13 @@
align-items: center;
justify-content: center;
background-color: #000000;
height:100%;
height:100vh;
.listView{
z-index: 0;
position: relative;
width: 660rpx;
height: 1000rpx;
height: 1300rpx;
margin-top: 100rpx;
background-color: #141b29;
@ -211,12 +259,15 @@
//border: 2px solid red;
background-color: #141b29;
font-size: 60rpx;
color: #8f8f94;
height: 120rpx;
text-align: center;
margin-left: 20rpx;
margin-right: 20rpx;
.toolText{
font-size: 24rpx;
color: #fff;
color: #8f8f94;
}
}
@ -250,8 +301,11 @@
.icon{
z-index: 1;
position: absolute;
margin-top: -960rpx;
margin-top: -620rpx;
background-color: #3e444d;
font-size: 120rpx;
color: #fff;
text-align: center;
}

175
pages/scan/Wifi.vue

@ -1,18 +1,28 @@
<template>
<view class="content">
<tn-avatar src="/static/logo.png" class="icon" size="xl"></tn-avatar>
<tn-avatar class="icon tn-icon-wifi" size="xl"></tn-avatar>
<tn-list-view :card="true" unlined="all" class="listView">
<tn-list-cell class="listItem-1">
<view>Network name: {{ wifiInfo.ssid }}</view>
<view>Network name: {{ wifiInfo.ssidNumber }}</view>
<view>Password: {{ wifiInfo.password }}</view>
</tn-list-cell>
<tn-list-cell class="listItem">
<tn-grid align="center" :col="col">
<block v-for="(item, index) in fastToolList" :key="index">
<tn-grid-item class="toolItem">
<view :class="item.icon"></view>
<block>
<tn-grid-item class="toolItem" @click="connectWifi()">
<view class="tn-icon-wifi"></view>
<view class="cutline"></view>
<view class="toolText">{{ item.text }}</view>
<view class="toolText">Connect to Wifi</view>
</tn-grid-item>
<tn-grid-item class="toolItem" @click="share()">
<view class="tn-icon-share-triangle"></view>
<view class="cutline"></view>
<view class="toolText">Share</view>
</tn-grid-item>
<tn-grid-item class="toolItem" @click="copyPassword()">
<view class="tn-icon-coupon"></view>
<view class="cutline"></view>
<view class="toolText">Copy password</view>
</tn-grid-item>
</block>
</tn-grid>
@ -20,7 +30,7 @@
<view class="cutline"></view>
<tn-list-cell class="listItem-ad">我是谷歌ad部分</tn-list-cell>
<tn-list-cell class="listItemBottom">
<image src="/static/logo.png" class="buttomImg"/>
<image :src="textImgUrl" class="buttomImg"/>
</tn-list-cell>
</tn-list-view>
<text class="bottomText">Feedback or Suggestion</text>
@ -34,43 +44,91 @@
return {
col: 4,
wifiInfo:{},
fastToolList:[
{
"index": 0,
"text":"Connect to Wifi",
"icon": "tn-icon-wifi"
},
{
"index": 1,
"text":"Copy password",
"icon": "tn-icon-coupon"
},
{
"index": 2,
"text":"Copy",
"icon": "tn-icon-copy-fill"
},
{
"index": 3,
"text":"Share",
"icon": "tn-icon-share-triangle"
}
]
tableName: 'scan_code',
textImgUrl: ''
}
},
onLoad(option) {
async onLoad(option) {
console.log('onLoadOption',option)
let that = this;
that.initData(option);
//db
await that.openSqlite();
//
await that.createTable();
//scan,history
if(option.category === 'scan'){
//db
await that.initData(option.data);
}else{
//
await that.getHistoryData(option.data);
}
},
onHide() {
let that = this;
that.closedb();
},
methods: {
//wifi
connectWifi(){
let that = this;
uni.connectWifi({
SSID: that.wifiInfo.ssidNumber,
password: that.wifiInfo.password,
//maunal: false//,android 10 maunal
success() {
uni.showToast({
title: 'connect success!'
});
},
fail(e){
uni.showToast({
title: e
});
}
});
},
//
share(){
uni.shareWithSystem({
summary: '',
href: 'https://uniapp.dcloud.io',
success(){
//
uni.showToast({
title: 'share success!'
});
},
fail(){
//
uni.showToast({
title: 'share fail!'
});
}
})
},
//copy
copyPassword(){
let that = this;
//console.log('')
uni.setClipboardData({
data: that.wifiInfo.password,
success() {
uni.showToast({
title: 'copy success!',
duration: 3000
});
}
})
},
//
async openSqlite(){
try{
let b = await openSqlite()
// uni.showToast({
// title:"open db success",
// icon:"none"
// })
console.log('db打开了');
}catch(e){
console.error("open db error",e)
@ -96,16 +154,8 @@
console.log("表是否存在",exist)
if(!exist){
let res = await executeSql(sql)
// uni.showToast({
// title:"insert table ok",
// icon:"none"
// })
console.log("新增表scancode",res)
}else{
// uni.showToast({
// title:"table exist",
// icon:"none"
// })
console.log("表scancode已存在")
}
}catch(e){
@ -144,22 +194,28 @@
//
async initData(option){
console.log('initoption',option)
let that = this;
let data = JSON.parse(option.data);
that.wifiInfo = data;
console.log('wifiInfo',that.wifiInfo)
console.log('password',that.wifiInfo.password)
console.log('ssid',that.wifiInfo.ssid)
let data = JSON.parse(option);
let insertData = {
ssidNumber: data.ssidNumber,
password : data.password,
imgUrl: data.imgUrl
}
that.wifiInfo = insertData;
that.textImgUrl = 'file://'+that.wifiInfo.imgUrl;
//db
await that.writeToDb("WIFI",that.wifiInfo);
await that.writeToDb("Wifi",that.wifiInfo);
},
//
async getHistoryData(params){
//console.log('historyparams',params)
let that = this;
let data = JSON.parse(params);
const data = JSON.parse(params);
//console.log('historydata',data)
that.wifiInfo = data;
console.log('HistotyWifiInfo',that.wifiInfo)
that.textImgUrl = 'file://'+that.wifiInfo.imgUrl;
}
}
}
@ -172,13 +228,13 @@
align-items: center;
justify-content: center;
background-color: #000000;
height:100%;
height:100vh;
.listView{
z-index: 0;
position: relative;
width: 660rpx;
height: 1000rpx;
height: 1300rpx;
margin-top: 100rpx;
background-color: #141b29;
@ -203,14 +259,16 @@
//border: 2px solid red;
background-color: #141b29;
font-size: 60rpx;
color: #8f8f94;
height: 120rpx;
text-align: center;
margin-left: 20rpx;
margin-right: 20rpx;
.toolText{
font-size: 24rpx;
color: #fff;
color: #8f8f94;
}
}
@ -244,8 +302,11 @@
.icon{
z-index: 1;
position: absolute;
margin-top: -960rpx;
margin-top: -620rpx;
background-color: #3e444d;
font-size: 120rpx;
color: #fff;
text-align: center;
}

2
pages/setting/Setting.vue

@ -249,7 +249,7 @@
align-items: center;
justify-content: center;
background-color: #000000;
height:100%;
height:100vh;

30
pages/webview/webview.vue

@ -0,0 +1,30 @@
<template>
<view>
<web-view :src="url"></web-view>
</view>
</template>
<script>
export default {
data() {
return {
url: ''
}
},
onLoad(option) {
let that = this;
that.url = option.url
console.log('that.url',that.url)
},
onHide() {
},
methods: {
}
}
</script>
<style>
</style>

BIN
static/album.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

BIN
static/flashLightOff.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

BIN
static/flashLightOn.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

BIN
static/history-default.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

BIN
static/history-select.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

BIN
static/scan-default.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

BIN
static/scan-select.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

BIN
static/scan.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

BIN
static/setting-default.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

BIN
static/setting-select.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

4
tuniao-ui/components/tn-button/tn-button.vue

@ -275,14 +275,18 @@
.tn-btn {
position: relative;
/* #ifndef APP-PLUS-NVUE */
display: inline-flex;
/* #endif */
align-items: center;
justify-content: center;
box-sizing: border-box;
line-height: 1;
text-align: center;
text-decoration: none;
/* #ifndef APP-PLUS-NVUE */
overflow: visible;
/* #endif */
transform: translate(0rpx, 0rpx);
// background-color: $tn-mai
border-radius: 12rpx;

100
uni_modules/uni-wifi/package.json

@ -0,0 +1,100 @@
{
"id": "uni-wifi",
"displayName": "uni-wifi",
"version": "1.0.4",
"description": "wifi管理",
"keywords": [
"wifi"
],
"repository": "",
"engines": {
"HBuilderX": "^3.6.11"
},
"dcloudext": {
"type": "uts",
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "插件不采集任何数据",
"permissions": "Android平台:\n<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>\n<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>\n<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\"/>\n<uses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\"/>\niOS平台:\niOS13及以上平台获取Wifi信息需要定位权限"
},
"npmurl": ""
},
"uni_modules": {
"uni-ext-api":{
"uni": {
"startWifi": "startWifi",
"stopWifi": "stopWifi",
"connectWifi":"connectWifi",
"getConnectedWifi": "getConnectedWifi",
"getWifiList":"getWifiList",
"onGetWifiList":"onGetWifiList",
"offGetWifiList":"offGetWifiList",
"onWifiConnected":"onWifiConnected",
"offWifiConnected":"offWifiConnected",
"onWifiConnectedWithPartialInfo":"onWifiConnectedWithPartialInfo",
"offWifiConnectedWithPartialInfo":"offWifiConnectedWithPartialInfo"
}
},
"dependencies": [],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y"
},
"client": {
"Vue": {
"vue2": "y",
"vue3": "y"
},
"App": {
"app-android": {
"minVersion": "19"
},
"app-ios": {
"minVersion": "9"
}
},
"H5-mobile": {
"Safari": "n",
"Android Browser": "n",
"微信浏览器(Android)": "n",
"QQ浏览器(Android)": "n"
},
"H5-pc": {
"Chrome": "n",
"IE": "n",
"Edge": "n",
"Firefox": "n",
"Safari": "n"
},
"小程序": {
"微信": "n",
"阿里": "n",
"百度": "n",
"字节跳动": "n",
"QQ": "n",
"钉钉": "n",
"快手": "n",
"飞书": "n",
"京东": "n"
},
"快应用": {
"华为": "n",
"联盟": "n"
}
}
}
}
}

145
uni_modules/uni-wifi/readme.md

@ -0,0 +1,145 @@
## 使用说明
Wi-Fi功能模块
### App-iOS平台注意事项
- iOS平台App获取Wi-Fi信息需要开启“Access WiFi information”能力
登录苹果开发者网站,在“Certificates, Identifiers & Profiles”页面选择“Identifiers”中选择对应的App ID,确保开启“Access WiFi information”,保存后重新生成profile文件
- iOS13及以上系统,获取当前连接的Wi-Fi信息需要先获取系统定位权限,因此在iOS13及以上系统使用此接口时,会触发定位权限申请的弹窗
### App-Android平台注意事项
- 如果是自定义基座,需要具备下面的权限
```
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
```
###uni.startWifi(OBJECT)
初始化Wi-Fi模块。
> 使用文档:[https://uniapp.dcloud.net.cn/api/system/wifi.html#startwifi](https://uniapp.dcloud.net.cn/api/system/wifi.html#startwifi)
### uni.stopWifi(OBJECT)
关闭 Wi-Fi 模块。
> 使用文档:[https://uniapp.dcloud.net.cn/api/system/wifi.html#stopwifi](https://uniapp.dcloud.net.cn/api/system/wifi.html#stopwifi)
### uni.getConnectedWifi(OBJECT)
获取已连接的 Wi-Fi 信息
> 使用文档:[https://uniapp.dcloud.net.cn/api/system/wifi.html#getconnectedwifi](https://uniapp.dcloud.net.cn/api/system/wifi.html#getconnectedwifi)
### uni.getWifiList(OBJECT)
请求获取 Wi-Fi 列表。wifiList 数据会在 onGetWifiList 注册的回调中返回。
> 使用文档:[https://uniapp.dcloud.net.cn/api/system/wifi.html#getWifiList](https://uniapp.dcloud.net.cn/api/system/wifi.html#getWifiList)
**平台差异说明**
|App-Android|App-iOS|
|:-:|:-:|
|√|x|
### uni.onGetWifiList(CALLBACK)
监听获取到 Wi-Fi 列表数据事件。
> 使用文档:[https://uniapp.dcloud.net.cn/api/system/wifi.html#onGetWifiList](https://uniapp.dcloud.net.cn/api/system/wifi.html#onGetWifiList)
**平台差异说明**
|App-Android|App-iOS|
|:-:|:-:|
|√|x|
### uni.offGetWifiList(CALLBACK)
移除获取到 Wi-Fi 列表数据事件的监听函数。
> 使用文档:[https://uniapp.dcloud.net.cn/api/system/wifi.html#offGetWifiList](https://uniapp.dcloud.net.cn/api/system/wifi.html#offGetWifiList)
**平台差异说明**
|App-Android|App-iOS|
|:-:|:-:|
|√|x|
### uni.connectWifi(OBJECT)
连接 Wi-Fi。若已知 Wi-Fi 信息,可以直接利用该接口连接。
> 使用文档:[https://uniapp.dcloud.net.cn/api/system/wifi.html#connectWifi](https://uniapp.dcloud.net.cn/api/system/wifi.html#connectWifi)
**平台差异说明**
|App-Android|App-iOS|
|:-:|:-:|
|√|x|
### uni.onWifiConnected(CALLBACK)
监听连接上 Wi-Fi 的事件。
> 使用文档:[https://uniapp.dcloud.net.cn/api/system/wifi.html#onWifiConnected](https://uniapp.dcloud.net.cn/api/system/wifi.html#onWifiConnected)
**平台差异说明**
|App-Android|App-iOS|
|:-:|:-:|
|√|x|
### uni.offWifiConnected(CALLBACK)
移除连接上 Wi-Fi 的事件的监听函数。
> 使用文档:[https://uniapp.dcloud.net.cn/api/system/wifi.html#offWifiConnected](https://uniapp.dcloud.net.cn/api/system/wifi.html#offWifiConnected)
**平台差异说明**
|App-Android|App-iOS|
|:-:|:-:|
|√|x|
### uni.onWifiConnectedWithPartialInfo(CALLBACK)
监听连接上 Wi-Fi 的事件。
> 使用文档:[https://uniapp.dcloud.net.cn/api/system/wifi.html#onWifiConnectedWithPartialInfo](https://uniapp.dcloud.net.cn/api/system/wifi.html#onWifiConnectedWithPartialInfo)
**平台差异说明**
|App-Android|App-iOS|
|:-:|:-:|
|√|x|
### uni.offWifiConnectedWithPartialInfo(CALLBACK)
移除连接上 Wi-Fi 的事件的监听函数。
> 使用文档:[https://uniapp.dcloud.net.cn/api/system/wifi.html#offWifiConnectedWithPartialInfo](https://uniapp.dcloud.net.cn/api/system/wifi.html#offWifiConnectedWithPartialInfo)
**平台差异说明**
|App-Android|App-iOS|
|:-:|:-:|
|√|x|

3
uni_modules/uni-wifi/utssdk/app-android/config.json

@ -0,0 +1,3 @@
{
"minSdkVersion": "19"
}

864
uni_modules/uni-wifi/utssdk/app-android/index.uts

@ -0,0 +1,864 @@
import Context from "android.content.Context";
import { UTSAndroid } from "io.dcloud.uts";
import WifiManager from "android.net.wifi.WifiManager";
import WifiInfo from "android.net.wifi.WifiInfo";
import Manifest from "android.Manifest";
import PackageManager from "android.content.pm.PackageManager";
import ScanResult from "android.net.wifi.ScanResult";
import BroadcastReceiver from "android.content.BroadcastReceiver";
import ActivityCompat from "androidx.core.app.ActivityCompat";
import IntentFilter from "android.content.IntentFilter";
import JSONObject from "com.alibaba.fastjson.JSONObject";
import Intent from "android.content.Intent";
import Thread from "java.lang.Thread";
import WifiConfiguration from 'android.net.wifi.WifiConfiguration';
import AuthAlgorithm from 'android.net.wifi.WifiConfiguration.AuthAlgorithm';
import KeyMgmt from 'android.net.wifi.WifiConfiguration.KeyMgmt';
import TextUtils from 'android.text.TextUtils';
import Build from 'android.os.Build';
import { UniWifiResult, GetConnectedWifiOptions, WifiConnectOption, WifiOption, UniWifiInfo } from "../interface.uts"
/**
* 全局数据储存
*/
class Global {
static mReceiver : CustomBroadcastReceiver | null = null;
static WIFI_AUTH_OPEN : string = "";
static WIFI_AUTH_ROAM : String = "[ESS]";
// 扫描wifi结果
static scanList : AndroidUniWifiInfo[] = []
// 获取wifi列表监听
static onGetWifiListCallback : UTSCallback | null = null
static supendGetWifiSuccess : ((res: UniWifiResult) => void) | null = null
static supendGetWifiComplete : ((res: UniWifiResult) => void) | null = null
// wifi链接监听
static onWifiConnectCallbackList : UTSCallback[] = []
static onWifiConnectWithPartialInfoCallbackList : UTSCallback[] = []
}
/**
* 是否是标准的16进制字符
*/
function isHex(key : string) : boolean {
for (var i = key.length - 1; i >= 0; i--) {
let c = key.charAt(i);
if (!(c >= '0' && c <= '9' || c >= 'A' && c <= 'F' || c >= 'a'
&& c <= 'f')) {
return false;
}
}
return true;
}
/**
* 判断是否是wep格式的key
*/
function isHexWepKey(wepKey : string) : boolean {
let len = wepKey.length;
// WEP-40, WEP-104, and some vendors using 256-bit WEP (WEP-232?)
if (len != 10 && len != 26 && len != 58) {
return false;
}
return isHex(wepKey);
}
/**
* android 平台特有的Wifi信息对象,主要是加了加密信息这个字段
*/
export type AndroidUniWifiInfo = {
SSID : string;
BSSID ?: string;
secure : boolean;
signalStrength : number;
frequency : number;
securityType : string;
}
function wrapUniWifiInfoFromAndroid(androidInfo : AndroidUniWifiInfo) : UniWifiInfo {
let ret : UniWifiInfo = {
SSID: androidInfo.SSID,
BSSID: androidInfo.BSSID,
secure: androidInfo.secure,
signalStrength: androidInfo.signalStrength,
frequency: androidInfo.frequency,
}
return ret
}
/**
* 从扫描结果中提取统一的wifi数据结构
*/
function wrapUniWifiInfoFromScan(scanResult : ScanResult) : AndroidUniWifiInfo {
let ret : AndroidUniWifiInfo = {
SSID: "",
secure: false,
signalStrength: 0,
frequency: 0,
securityType: "NONE"
}
if (scanResult != null) {
// 如果是通过扫描列表得到的数据,进行封装
ret.BSSID = scanResult.BSSID;
ret.SSID = scanResult.SSID;
ret.signalStrength = scanResult.level;
ret.frequency = scanResult.frequency;
// 是否安全,微信的标准是是否需要密码。 来源:https://developers.weixin.qq.com/community/develop/doc/00064cf1790458db19cddf9925ac00?highLine=WifiInfo
ret.secure = false;
let capabilities = scanResult.capabilities.trim();
if ((capabilities.equals(Global.WIFI_AUTH_OPEN) || capabilities.equals(Global.WIFI_AUTH_ROAM))) {
ret.secure = false;
} else {
ret.secure = true;
}
/*扩展字段*/
ret.securityType = getSecurityType(scanResult);
}
return ret
}
/**
* 从链接信息中提取统一的wifi数据结构
*/
function wrapUniWifiInfoFromConnectInfo(connectInfo : WifiInfo) : UniWifiInfo {
let ret : UniWifiInfo = {
SSID: "",
secure: false,
signalStrength: 0,
frequency: 0,
}
if (connectInfo.getSSID() != null) {
let s = connectInfo.getSSID();
// 微信不带,这里需要去掉引号
if (s.length > 2 && s.charAt(0) == '"' && s.charAt(s.length - 1) == '"') {
s = s.substring(1, s.length - 1);
}
ret.SSID = s;
}
ret.BSSID = connectInfo.getBSSID();
//Android返回的值是-100~0,而微信API规范是0~100,值越大信号越好,需要+100拉齐
ret.signalStrength = connectInfo.getRssi() + 100;
ret.frequency = connectInfo.getFrequency();
return ret
}
/**
* 连接wifi时使用,根据用户输入内容包装为系统需要的wifi配置对象
**/
@Suppress("DEPRECATION")
function wrapWifiConfiguration(SSID : string, password ?: string, passwordType : string) : WifiConfiguration {
let config = new WifiConfiguration();
config.status = WifiConfiguration.Status.ENABLED;
config.allowedAuthAlgorithms.clear();
config.allowedGroupCiphers.clear();
config.allowedKeyManagement.clear();
config.allowedPairwiseCiphers.clear();
config.allowedProtocols.clear();
config.SSID = "\"".concat(SSID).concat("\"");
// nopass
if ("NONE".equals(passwordType) || password == null) {
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
}
// wep
else if ("WEP".equals(passwordType)) {
if (password != null && !TextUtils.isEmpty(password)) {
if (isHexWepKey(password)) {
config.wepKeys[0] = password;
} else {
config.wepKeys[0] = "\"".concat(password).concat("\"");
}
}
config.allowedAuthAlgorithms.set(AuthAlgorithm.OPEN);
config.allowedAuthAlgorithms.set(AuthAlgorithm.SHARED);
config.allowedKeyManagement.set(KeyMgmt.NONE);
config.wepTxKeyIndex = 0;
}
// wpa
else if ("WPA".equals(passwordType)) {
config.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
config.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
config.preSharedKey = "\"".concat(password).concat("\"");
}
return config;
}
/**
* 判断当前wifi的加密类型
*/
function getSecurityType(result : ScanResult) : string {
if (result.capabilities.contains("WEP")) {
return "WEP";
} else if (result.capabilities.contains("PSK")) {
return "WPA";
} else if (result.capabilities.contains("EAP")) {
return "EAP";
}
return "NONE";
}
function zeroCountNum(source ?: string) : number {
if (source == null) {
return 0
}
var splitted = source.split(":")
var countNum = 0;
for (perItem in splitted) {
if (perItem == "00") {
countNum += 1
}
}
return countNum
}
class AsyncConnectionThread extends Thread{
mWifiManager : WifiManager | null = null;
constructor(wifi:WifiManager){
super();
this.mWifiManager = wifi
}
override run(){
let uniWifiInfo : UniWifiInfo = {
SSID: "",
secure: false,
signalStrength: 0,
frequency: 0,
}
// BroadcastReceiver 中不能执行耗时任务,需要使用setTimeout
// @ts-ignore
let winfo = this.mWifiManager!.getConnectionInfo();
while (winfo.bssid == null || zeroCountNum(winfo.bssid) > 4) {
Thread.sleep(1000)
winfo = this.mWifiManager!.getConnectionInfo();
}
// 封装成数据对象
uniWifiInfo = wrapUniWifiInfoFromConnectInfo(winfo)
let res = {
errMsg: 'onWifiConnected:ok',
errCode: 0,
wifi: uniWifiInfo
}
// wifi状态可用了,分发当前的链接状态给已注册的监听集合
for (let perCallback in Global.onWifiConnectCallbackList) {
perCallback(res);
}
// 封装仅SSID 数据对象
var connectedWithPartialInfo = {
SSID: uniWifiInfo.SSID
}
for (let perCallback in Global.onWifiConnectWithPartialInfoCallbackList) {
perCallback(connectedWithPartialInfo);
}
}
}
/**
* 自定义wifi变化广播监听器
*/
@Suppress("UNUSED_PARAMETER", "DEPRECATION")
class CustomBroadcastReceiver extends BroadcastReceiver {
mWifiManager : WifiManager | null = null;
constructor(wifiManager : WifiManager) {
super();
this.mWifiManager = wifiManager;
}
override onReceive(_context : Context, intent : Intent) : void {
if (intent.action == WifiManager.WIFI_STATE_CHANGED_ACTION) {
let state =
intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, WifiManager.WIFI_STATE_UNKNOWN)
if (state == WifiManager.WIFI_STATE_ENABLED) {
// 获取当前的connectInfo 并且进行数据封装
// let uniWifiInfo = new UniWifiInfo(null)
//做一些异步操作
new AsyncConnectionThread(this.mWifiManager!!).start()
}
}
if (intent.action == WifiManager.SCAN_RESULTS_AVAILABLE_ACTION) {
startWifiScaning = false;
let ret : UniWifiResult = {
errCode: 0,
errSubject: "uni-getWifiList",
errMsg: "getWifiList:ok"
}
if(Global.supendGetWifiSuccess != null){
Global.supendGetWifiSuccess?.(ret)
}
if(Global.supendGetWifiComplete != null){
Global.supendGetWifiComplete?.(ret)
}
// wifi 扫描结果回调
let results = this.mWifiManager!.scanResults;
if (results != null) {
Global.scanList = []
for (let scanResult in results) {
if (scanResult.SSID == null) {
continue;
}
Global.scanList.push(wrapUniWifiInfoFromScan(scanResult));
}
// 挨个通知,所有的监听器
if(Global.onGetWifiListCallback != null){
const data = new JSONObject();
data["wifiList"] = Global.scanList
Global.onGetWifiListCallback?.(data);
}
// for (let perCallback in Global.onGetWifiListCallback) {
// const data = new JSONObject();
// data["wifiList"] = Global.scanList
// perCallback(data);
// }
}
}
}
}
/************************* 下面是对外提供的函数 *************************/
/**
* start wifi是否正在扫描
*/
var startWifiScaning = false
/**
* 开启wifi
*/
@Suppress("DEPRECATION")
export function startWifi(option : WifiOption) {
// 需要先开启wifi,才能使用后续的功能
let requestCode = 1001;
let permissionWifi = arrayOf("android.permission.ACCESS_FINE_LOCATION");
var result : UniWifiResult = {
errCode: 12001,
errMsg: "startWifi:premission loss",
errSubject: "uni-startWifi"
}
// 检查权限
if (ActivityCompat.checkSelfPermission(UTSAndroid.getUniActivity()!, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(UTSAndroid.getUniActivity()!, permissionWifi, requestCode)
// 尚不具备权限,返回错误
option.fail?.(result)
option.complete?.(result)
return;
}
// 具备了权限,继续前进
let wifiManager : WifiManager =
UTSAndroid.getAppContext()!.getSystemService(Context.WIFI_SERVICE) as WifiManager
// 用户没有开启wifi 总开关
if (!wifiManager.isWifiEnabled()) {
// wifi 没开启
result.errCode = 12005;
result.errMsg = "wifi not turned on";
option.fail?.(result);
option.complete?.(result);
return;
}
// 初始化wifi 状态广播监听,后续所有的api,均基于此
if(Global.mReceiver != null){
// 说明已经注册过了
result.errCode = 0
result.errMsg = "startWifi:ok"
option.success?.(result)
option.complete?.(result)
return
}
Global.mReceiver = new CustomBroadcastReceiver(wifiManager)
let filter = new IntentFilter()
filter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)
// @ts-ignore
filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION)
// @ts-ignore
filter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION);
UTSAndroid.getUniActivity()!.registerReceiver(Global.mReceiver, filter)
/**
* activity 被销毁时,取消注册
*/
UTSAndroid.onAppActivityDestroy(function () {
if (Global.mReceiver != null) {
UTSAndroid.getUniActivity()!.unregisterReceiver(Global.mReceiver)
Global.mReceiver = null
Global.scanList = []
Global.onGetWifiListCallback = null
Global.onWifiConnectCallbackList = []
Global.onWifiConnectWithPartialInfoCallbackList = []
}
});
startWifiScaning = true
// 开始扫描
wifiManager.startScan()
result.errCode = 0
result.errMsg = "startWifi:ok"
option.success?.(result)
option.complete?.(result)
}
/**
* 获取wifi列表
*/
@Suppress("DEPRECATION")
export function getWifiList(option : WifiOption) {
var result : UniWifiResult = {
errCode: 12000,
errMsg: "getWifiList:fail:not invoke startWifi",
errSubject: "uni-getWifiList"
}
if (Global.mReceiver == null) {
// 还没调用startWifi 提示报错
option.fail?.(result)
option.complete?.(result)
return
}
let wifiManager : WifiManager =
UTSAndroid.getAppContext()!.getSystemService(Context.WIFI_SERVICE) as WifiManager
Global.supendGetWifiSuccess = option.success
Global.supendGetWifiComplete = option.complete
wifiManager.startScan()
}
/**
* wifi 链接成功的回调注册
*/
export function onWifiConnected(callback : UTSCallback) {
Global.onWifiConnectCallbackList.push(callback)
}
export function onWifiConnectedWithPartialInfo(callback : UTSCallback) {
Global.onWifiConnectWithPartialInfoCallbackList.push(callback)
}
/**
* wifi 链接成功的回调取消注册
*/
export function offWifiConnected(callback? : UTSCallback) {
if(callback == null){
Global.onWifiConnectCallbackList = []
return
}
let callbackIndex = Global.onWifiConnectCallbackList.indexOf(callback)
if (callbackIndex >= 0) {
Global.onWifiConnectCallbackList.splice(callbackIndex, 1);
}
}
/**
* 不具备详细信息的wifi 反注册
*/
export function offWifiConnectedWithPartialInfo(callback? : UTSCallback) {
if(callback == null){
Global.onWifiConnectWithPartialInfoCallbackList = []
return
}
let callbackIndex = Global.onWifiConnectWithPartialInfoCallbackList.indexOf(callback)
if (callbackIndex >= 0) {
Global.onWifiConnectWithPartialInfoCallbackList.splice(callbackIndex, 1);
}
}
/**
* 注册Wifi列表的监听事件
*/
export function onGetWifiList(callback : UTSCallback) {
Global.onGetWifiListCallback = callback
}
/**
* 取消注册Wifi列表的监听事件
*/
export function offGetWifiList(callback? : UTSCallback) {
Global.onGetWifiListCallback = null
Global.supendGetWifiComplete = null
Global.supendGetWifiSuccess = null
}
/**
* 真正执行wifi链接逻辑
*/
function realWifiConnect(option : WifiConnectOption,result : UniWifiResult){
if (Global.mReceiver == null || Global.scanList.length < 1) {
option.fail?.(result)
option.complete?.(result)
return
}
// 执行后续的逻辑
let scanWifiInfo : AndroidUniWifiInfo | null = null
for (let scanResult in Global.scanList) {
if (scanResult.SSID.equals(option.SSID)) {
scanWifiInfo = scanResult
}
}
if (scanWifiInfo == null) {
// 不在扫描列表中返回错误
option.fail?.(result)
option.complete?.(result)
return
}
let wifiConfigration = wrapWifiConfiguration(scanWifiInfo.SSID, option.password, scanWifiInfo.securityType);
wifiConfigration.BSSID = scanWifiInfo.BSSID
let wifiManager : WifiManager =
UTSAndroid.getAppContext()!.getSystemService(Context.WIFI_SERVICE) as WifiManager
// 如果已经存在了指定wifi 配置,移除之
let targetExistConfig : WifiConfiguration | null = null
let existingConfigs = wifiManager.getConfiguredNetworks();
for (let existingConfig in existingConfigs) {
if (existingConfig.SSID.equals("\"" + option.SSID + "\"")) {
targetExistConfig = existingConfig
}
}
// 如果wifi已经保存了当前ssid的配置,可能是别的应用添加的。android系统要求,需要删除掉重新添加
if (targetExistConfig != null) {
let removeRet = wifiManager.removeNetwork(targetExistConfig.networkId);
if (!removeRet) {
// add since 2023-03-28,如果当前系统大于等于android10, 则明确当前系统不支持
if(Build.VERSION.SDK_INT > 28){
// 系统大于android 9
result.errCode = 12001
result.errMsg = "connectWifi:system not support"
}else{
// 移除之前的配置失败了,返回错误,需要用户手动取消保存一下
result.errCode = 12013
result.errMsg = "connectWifi:wifi config may be expired"
}
option.fail?.(result)
option.complete?.(result)
return
}
}
let currentConnect = wifiManager.getConnectionInfo()
if (currentConnect.networkId >= 0) {
wifiManager.disableNetwork(currentConnect.networkId)
} else {
wifiManager.removeNetwork(currentConnect.networkId)
}
wifiManager.disconnect()
let connected = false;
try {
let netID = wifiManager.addNetwork(wifiConfigration);
// 如果-1 说明没添加上,报错即可
if (netID < 0) {
result.errCode = 12002
result.errMsg = "connectWifi:password error Wi-Fi"
option.fail?.(result)
option.complete?.(result)
return
}
let enabled = wifiManager.enableNetwork(netID, true);
if (!enabled) {
result.errCode = 12007
result.errMsg = "connectWifi:user denied"
option.fail?.(result)
option.complete?.(result)
return
}
connected = wifiManager.reconnect();
} catch (e) {
connected = false;
console.log(e);
}
if (!connected) {
// 出错了,返回错误
// 兜底的报错
result.errCode = 12010
result.errMsg = "connectWifi:fail:unknown error"
option.fail?.(result)
option.complete?.(result)
return
}
wifiManager.saveConfiguration()
//scanWifiInfo 根据 partialInfo 填充给返回字段
if (option.partialInfo != null && option.partialInfo == true) {
let wifiPartialInfo : UniWifiInfo = {
SSID: scanWifiInfo.SSID
}
result.wifi = wifiPartialInfo
} else {
result.wifi = wrapUniWifiInfoFromAndroid(scanWifiInfo)
}
// result.wifi = scanWifiInfo.toUTSJSON(option.partialInfo)
result.errCode = 0
result.errMsg = "connectWifi:ok"
option.success?.(result)
option.complete?.(result)
}
/**
* 链接指定wifi
*/
@Suppress("UNUSED_PARAMETER", "DEPRECATION")
export function connectWifi(option : WifiConnectOption) {
var result : UniWifiResult = {
errCode: 12000,
errMsg: "connectWifi:fail:not invoke startWifi",
errSubject: "uni-connectWifi",
}
if (option.maunal == true) {
// 指定了手动模式
let manunalIntent = new Intent(android.provider.Settings.ACTION_WIFI_SETTINGS);
UTSAndroid.getUniActivity()!.startActivity(manunalIntent);
result.errCode = 0
result.errMsg = "connectWifi:ok"
option.success?.(result)
option.complete?.(result)
return
}
// add since 2022-03-28 ,增加逻辑,如果正在扫描中,则可以等待5s
if(startWifiScaning){
let taskCount = 0
let taskId:number = 0
taskId = setInterval(function(){
taskCount += 1;
if(taskCount >= 5 || startWifiScaning == false){
// 超过10s了。或者扫描过程结束了
clearInterval(taskId)
realWifiConnect(option,result)
}
},2000)
UTSAndroid.onAppActivityDestroy(function () {
clearInterval(taskId)
});
}else{
realWifiConnect(option,result)
}
}
/**
* 关闭wifi
*/
export function stopWifi(option : WifiOption) {
// 需要先开启wifi,才能使用后续的功能
if (Global.mReceiver == null) {
var result : UniWifiResult = {
errCode: 12000,
errSubject: "uni-stopWifi",
errMsg: "stopWifi:not init"
}
option.fail?.(result)
option.complete?.(result)
return
}
try {
UTSAndroid.getUniActivity()!.unregisterReceiver(Global.mReceiver)
} catch (e) {
// 多次调用
//TODO handle the exception
}
Global.onGetWifiListCallback = null
Global.onWifiConnectWithPartialInfoCallbackList = []
Global.onWifiConnectCallbackList = []
Global.mReceiver = null
let result : UniWifiResult = {
errCode: 0,
errSubject: "uni-stopWifi",
errMsg: "stopWifi:ok"
}
option.success?.(result)
option.complete?.(result)
}
/**
* 获取当前连接中的wifi信息
*/
@Suppress("DEPRECATION")
export function getConnectedWifi(option : GetConnectedWifiOptions) {
let wifiInfo : UniWifiInfo = {
SSID: ""
}
var res : UniWifiResult = {
errCode: 12000,
errMsg: "getConnectedWifi:fail:not invoke startWifi",
errSubject: "uni-getConnectedWifi",
}
if (Global.mReceiver == null) {
// 还没调用startWifi 提示报错
option.fail?.(res)
option.complete?.(res)
return
}
// 需要先校验权限,没有位置权限无法获取wifi
if (ActivityCompat.checkSelfPermission(UTSAndroid.getUniActivity()!, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// 尚不具备权限,返回错误
res.errCode = 12001
res.errMsg = "getConnectedWifi:permission loss"
option.fail?.(res)
option.complete?.(res)
return;
}
const context = UTSAndroid.getAppContext();
if (context != null) {
const wm = context.getSystemService(
Context.WIFI_SERVICE
) as WifiManager;
// 测试android 12上可以使用
//@ts-ignore
const winfo = wm.getConnectionInfo();
wifiInfo = wrapUniWifiInfoFromConnectInfo(winfo);
// 判断一下是否wifi 关闭了
if (option.partialInfo != null && option.partialInfo == true) {
let ret : UniWifiInfo = {
SSID: wifiInfo.SSID
}
res.wifi = ret;
} else {
if (wifiInfo.BSSID == null || zeroCountNum(wifiInfo.BSSID) > 3) {
res.errCode = 12005
res.errMsg = "getConnectedWifi:fail:wifi is disable"
option.fail?.(res)
option.complete?.(res)
return
}
res.wifi = wifiInfo;
}
res.errCode = 0
res.errMsg = "getConnectedWifi:ok"
option.success?.(res)
option.complete?.(res)
return
}
option.fail?.(res)
option.complete?.(res)
}

8
uni_modules/uni-wifi/utssdk/app-ios/Info.plist

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSLocationWhenInUseUsageDescription</key>
<string>使用期间获取位置权限</string>
</dict>
</plist>

8
uni_modules/uni-wifi/utssdk/app-ios/UTS.entitlements

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.developer.networking.wifi-info</key>
<true/>
</dict>
</plist>

8
uni_modules/uni-wifi/utssdk/app-ios/config.json

@ -0,0 +1,8 @@
{
"frameworks": [
"CoreLocation",
"SystemConfiguration"
],
"validArchitectures": [
"arm64", "armv7" ],"deploymentTarget": "9"
}

301
uni_modules/uni-wifi/utssdk/app-ios/index.uts

@ -0,0 +1,301 @@
import { CLLocationManager, CLAuthorizationStatus, CLLocationManagerDelegate } from 'CoreLocation'
import { CaptiveNetwork, kCNNetworkInfoKeySSID, kCNNetworkInfoKeyBSSID } from 'SystemConfiguration.CaptiveNetwork';
import { NSArray, NSDictionary } from 'Foundation';
import { CFString } from 'CoreFoundation';
import { UIDevice } from 'UIKit';
import { WifiOption, WifiConnectOption, GetConnectedWifiOptions, UniWifiInfo, UniWifiResult, UniWifiCallback, StartWifi, StopWifi, GetWifiList, OnGetWifiList, OffGetWifiList, GetConnectedWifi, ConnectWifi, OnWifiConnected, OnWifiConnectedWithPartialInfo, OffWifiConnected, OnOffWifiConnectedWithPartialInfo, SetWifiList } from "../interface.uts"
/*
* 系统定位权限获取类
*/
class LocationPromiseService implements CLLocationManagerDelegate {
static promiseCompletionHandler: ((res: boolean)=>void)[] = []
manager?: CLLocationManager
constructor(manager?: CLLocationManager) {
this.manager = manager
}
initlizeManager(): boolean {
if (this.manager == null) {
this.manager = new CLLocationManager()
this.manager!.delegate = this
}
return true
}
locationManager(manager: CLLocationManager, @argumentLabel("didChangeAuthorization") status: CLAuthorizationStatus) {
if (status == CLAuthorizationStatus.authorizedAlways || status == CLAuthorizationStatus.authorizedWhenInUse) {
LocationPromiseService.promiseCompletionHandler.forEach((handler): void => {
handler(true)
})
} else if (status == CLAuthorizationStatus.notDetermined) {
manager.requestWhenInUseAuthorization()
} else if (status == CLAuthorizationStatus.denied) {
LocationPromiseService.promiseCompletionHandler.forEach((handler): void => {
handler(false)
})
}
}
requestPromise(@escaping completion: (res: boolean)=>void) {
let status: CLAuthorizationStatus = CLLocationManager.authorizationStatus()
if (status == CLAuthorizationStatus.notDetermined) {
if (this.initlizeManager() == true) {
this.manager!.requestWhenInUseAuthorization()
LocationPromiseService.promiseCompletionHandler.push(completion)
}
} else if (status == CLAuthorizationStatus.authorizedAlways || status == CLAuthorizationStatus.authorizedWhenInUse) {
completion(true)
} else if (status == CLAuthorizationStatus.denied) {
if (CLLocationManager.locationServicesEnabled() == false && this.initlizeManager() == true) {
this.manager!.requestWhenInUseAuthorization()
LocationPromiseService.promiseCompletionHandler.push(completion)
}
}
}
}
const locationPromiseService: LocationPromiseService = new LocationPromiseService(null)
/*
* 获取系统定位权限
*/
function requestLocationPromise(@escaping completion: (res: boolean)=>void) {
locationPromiseService.requestPromise(completion)
}
/*
* 获取当前连接的wifi信息(通过定位权限)
*/
function fetchConnectedWifiWithLocationPromise(option: GetConnectedWifiOptions) {
let arr = CNCopySupportedInterfaces()
let wifiInfo: UniWifiInfo = {
BSSID: "",
SSID: "",
secure: false,
signalStrength: 0,
frequency: 0
}
if (arr != null) {
let list = arr! as NSArray
let index = 0
while (index < list.count) {
let item = list[index]
let interfaceName = item as string
let dic = CNCopyCurrentNetworkInfo(interfaceName as CFString)
if (dic != null) {
let dict = dic! as NSDictionary
let SSID = dict[kCNNetworkInfoKeySSID as string]
let BSSID = dict[kCNNetworkInfoKeyBSSID as string]
if (SSID != null && BSSID != null) {
let ssid = SSID! as string
let bssid = BSSID! as string
wifiInfo.SSID = ssid
wifiInfo.BSSID = bssid
wifiInfo.secure = false
wifiInfo.signalStrength = 0
wifiInfo.frequency = 0
break;
}
}
index++
}
if (wifiInfo.BSSID!.length > 0 && wifiInfo.SSID.length > 0) {
let res: UniWifiResult = {
errSubject: "uni-getConnectedWifi",
errCode: 0,
errMsg: "getConnectedWifi:ok",
wifi: wifiInfo,
}
option.success?.(res)
option.complete?.(res)
}else {
const res: UniWifiResult = {
errSubject: "uni-getConnectedWifi",
errCode: 12010,
errMsg: "getConnectedWifi:system internal error",
wifi: null
}
option.fail?.(res)
option.complete?.(res)
}
}else {
const res: UniWifiResult = {
errSubject: "uni-getConnectedWifi",
errCode: 12010,
errMsg: "getConnectedWifi:system internal error",
wifi: null
}
option.fail?.(res)
option.complete?.(res)
}
}
/*
* 保存全局数据信息
*/
class UniWiFiModuleGloabInfo {
static alreadyStartWifi: boolean = false
}
/* =================================== 对外暴露的接口 ==============================================*/
/*
* 初始化wifi模块
*/
export const startWifi: StartWifi = function (option: WifiOption) {
UniWiFiModuleGloabInfo.alreadyStartWifi = true
let res: UniWifiResult = {
errSubject: "uni-startWifi",
errCode: 0,
errMsg: "startWifi:ok",
wifi: null
}
option.success?.(res)
option.complete?.(res)
}
/*
* 停止wifi模块
*/
export const stopWifi: StopWifi = function (option: WifiOption) {
UniWiFiModuleGloabInfo.alreadyStartWifi = false
LocationPromiseService.promiseCompletionHandler = []
let res: UniWifiResult = {
errSubject: "uni-stopWifi",
errCode: 0,
errMsg: "stopWifi:ok",
wifi: null
}
option.success?.(res)
option.complete?.(res)
}
/*
* 获取wifi列表, 在调用之前需要引导用户跳转到系统设置-WIFI设置页面,系统搜索周边wifi后app才能接收到回调
*/
export const getWifiList: GetWifiList = function (option: WifiOption) {
let res: UniWifiResult = {
errSubject: "uni-getWifiList",
errCode: 12001,
errMsg: "getWifiList:system not support",
wifi: null
}
option.fail?.(res)
option.complete?.(res)
}
/* 获取wifi列表的回调
* note: 请在getWifiList方法的回调里调用该方法
*/
export const onGetWifiList: OnGetWifiList = function (callback: UniWifiCallback) {
}
/*
* 注销获取wifi列表的回调
*/
export const offGetWifiList: OffGetWifiList = function (callback: UniWifiCallback) {
}
/*
* 获取当前连接的wifi信息
*/
export const getConnectedWifi: GetConnectedWifi = function (option: GetConnectedWifiOptions) {
if (UniWiFiModuleGloabInfo.alreadyStartWifi == false) {
let res: UniWifiResult = {
errSubject: "uni-getConnectedWifi",
errCode: 12000,
errMsg: "getConnectedWifi:not init",
wifi: null
}
option.fail?.(res)
option.complete?.(res)
} else{
if (UIDevice.current.systemVersion >= "13.0") {
requestLocationPromise((success) => {
if (success == true) {
fetchConnectedWifiWithLocationPromise(option)
}else {
let res: UniWifiResult = {
errSubject: "uni-getConnectedWifi",
errCode: 12007,
errMsg: "getConnectedWifi:user denied",
wifi: null
}
option.fail?.(res)
option.complete?.(res)
}
})
} else{
fetchConnectedWifiWithLocationPromise(option)
}
}
}
/*
* 连接wifi
*/
export const connectWifi: ConnectWifi = function (option: WifiConnectOption) {
let res: UniWifiResult = {
errSubject: "uni-connectWifi",
errCode: 12001,
errMsg: "connectWifi:system not support",
wifi: null
}
option.fail?.(res)
option.complete?.(res)
}
/*
* 连上wifi事件的监听函数
*/
export const onWifiConnected: OnWifiConnected = function (callback: UniWifiCallback) {
}
/*
* 连上wifi事件的监听函数, wifiInfo仅包含ssid
*/
export const onWifiConnectedWithPartialInfo: OnWifiConnectedWithPartialInfo = function (callback: UniWifiCallback) {
}
/*
* 移除连接上wifi的事件的监听函数,不传此参数则移除所有监听函数。
*/
export const offWifiConnected: OffWifiConnected = function (callback: UniWifiCallback | null) {
}
/*
* 移除连接上wifi的事件的监听函数,不传此参数则移除所有监听函数。
*/
export const onOffWifiConnectedWithPartialInfo: OnOffWifiConnectedWithPartialInfo = function (callback: UniWifiCallback | null) {
}
/*
* 设置 wifiList 中 AP 的相关信息。在 onGetWifiList 回调后调用,iOS特有接口。
*/
export const setWifiList: SetWifiList = function (option: WifiOption) {
let res: UniWifiResult = {
errSubject: "uni-setWifiList",
errCode: 12001,
errMsg: "setWifiList:system not support",
wifi: null
}
option.fail?.(res)
option.complete?.(res)
}

125
uni_modules/uni-wifi/utssdk/interface.uts

@ -0,0 +1,125 @@
/**
* Wifi 函数通用入参封装
*/
export type WifiOption = {
success?: (res: UniWifiResult) => void;
fail?: (res: UniWifiResult) => void;
complete?: (res: UniWifiResult) => void;
};
/**
* Wifi 链接参数封装
*/
export type WifiConnectOption = {
SSID?: string;
BSSID?: string;
password?: string;
maunal?: boolean;
partialInfo?: boolean; //ios不生效
success?: (res: UniWifiResult) => void;
fail?: (res: UniWifiResult) => void;
complete?: (res: UniWifiResult) => void;
}
/**
* 获取当前链接的wifi信息
*/
export type GetConnectedWifiOptions = {
partialInfo?: boolean
success?: (res: UniWifiResult) => void
fail?: (res: UniWifiResult) => void
complete?: (res: UniWifiResult) => void
}
/*
* 对外暴露的wifi信息
*/
export type UniWifiInfo = {
SSID: string;
BSSID?: string;
secure?: boolean;
signalStrength?: number;
frequency?: number;
}
export type UniWifiResult = {
errCode : number,
errSubject : string,
errMsg : string,
wifi: UniWifiInfo | null
}
export type UniWifiCallback = () => void
export type StartWifi = (option: WifiOption) => void
export type StopWifi = (option: WifiOption) => void
export type GetWifiList = (option: WifiOption) => void
export type OnGetWifiList = (callback: UniWifiCallback) => void
export type OffGetWifiList = (callback: UniWifiCallback) => void
export type GetConnectedWifi = (option: GetConnectedWifiOptions) => void
export type ConnectWifi = (option: WifiConnectOption) => void
export type OnWifiConnected = (callback: UniWifiCallback) => void
export type OnWifiConnectedWithPartialInfo = (callback: UniWifiCallback) => void
export type OffWifiConnected = (callback: UniWifiCallback | null) => void
export type OnOffWifiConnectedWithPartialInfo = (callback: UniWifiCallback | null) => void
export type SetWifiList = (option: WifiOption) => void
interface Uni {
startWifi : StartWifi,
stopWifi : StopWifi,
/**
* @autotest {
generated: false,
pollution: false,
cases:[
{
before: 'startWifi',
after: 'stopWifi',
input: [{
maunal:false,
SSID:"Xiaomi_20D0",
password:"streamApp!2016",
}],
output:{
callbackType: 'success',
value: { errCode: 12013 ,errMsg: "connectWifi:wifi config may be expired",errSubject: "uni-connectWifi"}
}
}
]
}
*/
connectWifi: ConnectWifi,
/**
* @autotest {
generated: false,
cases:[
{
before: 'startWifi',
after: 'stopWifi'
}
]
}
*/
getWifiList : GetWifiList,
onGetWifiList : OnGetWifiList,
offGetWifiList : OffGetWifiList,
getConnectedWifi : GetConnectedWifi,
onWifiConnected : OnWifiConnected,
onWifiConnectedWithPartialInfo : OnWifiConnectedWithPartialInfo,
offWifiConnected : OffWifiConnected,
onOffWifiConnectedWithPartialInfo : OnOffWifiConnectedWithPartialInfo,
setWifiList : SetWifiList,
}

35
uni_modules/uni-wifi/utssdk/uni.autotest.js

@ -0,0 +1,35 @@
function startWifi() {
return new Promise((resolve, reject) => {
uni.startWifi({
success: () => {
console.log('startWifi success');
resolve()
},
fail: () => {
console.log('startWifi fail');
reject()
}
})
})
}
function stopWifi() {
return new Promise((resolve, reject) => {
uni.stopWifi({
success: () => {
console.log('stopWifi success');
resolve()
},
fail: () => {
console.log('stopWifi success');
fail()
}
})
})
}
module.exports = {
startWifi,
stopWifi
}
Loading…
Cancel
Save