This commit is contained in:
fengerli
2026-01-30 13:29:15 +08:00
53 changed files with 8008 additions and 2154 deletions

View File

@ -53,6 +53,9 @@
},
onHide: function() {
console.log('App Hide');
},
onError(ex) {
console.error("出现了未知的异常",ex);
}
}
</script>

View File

@ -17,6 +17,13 @@ export function deviceTypeList(params) {
})
}
export function typeAll(){
return request({
url: '/app/xinghan/device/typeAll',
method: 'get'
});
}
// 删除设备列表接口
export function deviceUnbind(id) {
return request({

View File

@ -229,12 +229,12 @@
let linePixls = [];
let item = this.validTxts[i];
console.log("item=",item);
for (var j = 0; j < item.length; j++) {
let result = await drawTxt(item[j]);
linePixls.push(convertCharToMatrix(result.pixelData));
}
console.log("hexs=",linePixls.join(","));
// console.log("hexs=",linePixls.join(","));
arr.push(linePixls);
}

View File

@ -2,7 +2,7 @@
const config = {
// 开发环境
development: {
BASE_URL: 'http://139.224.253.23:8000',
BASE_URL: 'http://192.168.110.57:8000',//http://139.224.253.23:8000
API_PREFIX: '',
// MQTT 配置
MQTT_HOST: 'www.cnxhyc.com',

View File

@ -6,13 +6,13 @@ import uView from 'vk-uview-ui';
// #ifndef VUE3
import Vue from 'vue'
import store from './store/store';
import './uni.promisify.adaptor'
Vue.config.productionTip = false
App.mpType = 'app'
const app = new Vue({
store,
...App
})
Vue.use(uView)

View File

@ -2,7 +2,7 @@
"name" : "星汉物联",
"appid" : "__UNI__A21EF43",
"description" : "设备管控",
"versionName" : "1.0.8",
"versionName" : "1.0.12",
"versionCode" : "100",
"transformPx" : false,
/* 5+App */
@ -99,23 +99,7 @@
},
"push" : {
"unipush" : {
"version" : "2",
"offline" : true,
"hms" : {},
"oppo" : {},
"vivo" : {},
"mi" : {},
"meizu" : {},
"honor" : {},
"icons" : {
"small" : {
"xxhdpi" : "unpackage/res/icons/72x72.png",
"xhdpi" : "unpackage/res/icons/48x48.png",
"hdpi" : "unpackage/res/icons/36x36.png",
"mdpi" : "unpackage/res/icons/24x24.png",
"ldpi" : "unpackage/res/icons/18x18.png"
}
}
"offline" : false
}
}
},

View File

@ -339,6 +339,7 @@
"path" : "pages/102/HBY102",
"style" :
{
"navigationStyle": "custom",
"navigationBarTitleText" : "HBY102"
}
},
@ -362,6 +363,27 @@
{
"navigationBarTitleText" : "HBY018A"
}
},
{
"path" : "pages/6107/BJQ6107",
"style" :
{
"navigationBarTitleText" : "BJQ6107"
}
},
{
"path" : "pages/6155/BJQ6155",
"style" :
{
"navigationBarTitleText" : "BJQ6155"
}
},
{
"path" : "pages/102/HBY102_History",
"style" :
{
"navigationStyle": "custom"
}
}

View File

@ -255,10 +255,7 @@
hideLoading,
updateLoading
} from '@/utils/loading.js'
import {
request,
baseURL
} from '../../utils/request';
import request, { baseURL } from '@/utils/request.js';
import Common from '@/utils/Common.js'
const pagePath = "/pages/100/HBY100";

View File

@ -1,5 +1,26 @@
<template>
<view class="content contentBg">
<uni-nav-bar class="nvbar" leftIcon="left" @clickLeft="navigatorBack">
<view slot="left">
<uni-icons type="back" size="23" color="#FFFFFF"></uni-icons>
</view>
<view slot="default" class="center uninavebartext">
{{Status.navbar.title}}
</view>
<view slot="right">
<view class="navbarRight center">
<view class="imgContent" @click.stop="handleRightClick(item,index)"
v-for="item,index in Status.navbar.icons">
<image class="img" :src="item.src" mode="aspectFit"></image>
<view class="baber" v-if="item.math">{{item.math>9?'9+':item.math}}</view>
</view>
</view>
</view>
</uni-nav-bar>
<view class="eq">
<view class="leftImg" @click.stop="previewImg(device.devicePic?device.devicePic:formData.img)">
<image class="img" :src="device.devicePic?device.devicePic:formData.img" mode="aspectFit"></image>
@ -16,7 +37,8 @@
<view class="row">
<image class="img" src="/static/images/6155/DeviceDetail/time.png" mode="aspectFit"></image>
<view class="txt">
<view class="bigTxt">{{formData.sta_charge?dic.sta_charge[formData.sta_charge+'']:"未充电" }}</view>
<view class="bigTxt">{{formData.sta_charge?dic.sta_charge[formData.sta_charge+'']:"未充电" }}
</view>
<view class="smallTxt">设备状态</view>
</view>
</view>
@ -269,6 +291,21 @@
showClose: false
},
usrToggle: false,
navbar: {
icons: [{
src: '/static/images/common/history.png',
callback: this.gotoHistory,
math: 0
},
{
src: '/static/images/common/shape.png',
callback: this.gotoShare
}
],
title: 'HBY102'
},
apiType: ''
},
formData: {
img: '/static/images/common/HBY102.png',
@ -300,7 +337,8 @@
show: true,
img: '/static/images/100/light.png',
activeImg: '/static/images/100/lightActive.png',
group: 'sta_LedType'
group: 'sta_LedType',
permission: '1'
},
{
key: 'led_low_flash',
@ -308,7 +346,8 @@
show: true,
img: '/static/images/102/lowFlash.png',
activeImg: '/static/images/102/lowFlashActive.png',
group: 'sta_LedType'
group: 'sta_LedType',
permission: '1'
},
{
key: 'led_steady',
@ -316,7 +355,8 @@
show: true,
img: '/static/images/102/liting.png',
activeImg: '/static/images/102/litingActive.png',
group: 'sta_LedType'
group: 'sta_LedType',
permission: '1'
},
{
key: 'status_on',
@ -324,7 +364,8 @@
show: true,
img: '/static/images/102/redar.png',
activeImg: '/static/images/102/redarActive.png',
group: 'sta_RadarType'
group: 'sta_RadarType',
permission: '48'
},
{
key: 'E49_on',
@ -332,7 +373,8 @@
show: true,
img: '/static/images/102/line.png',
activeImg: '/static/images/102/lineActive.png',
group: 'sta_Online'
group: 'sta_Online',
permission: '49'
},
{
key: 'led_off',
@ -377,7 +419,8 @@
showConfirm: false
},
groupDevices: [],
warnDevices:[]
warnDevices: [],
permissions: []
}
},
@ -404,9 +447,20 @@
eventChannel.on('detailData', function(data) {
// console.log("收到父页面的参数:" + JSON.stringify(data));
console.log("收到父页面的参数:" + JSON.stringify(data));
var device = data.data;
these.Status.apiType = data.apiType;
if (data.apiType !== 'listA') {
Common.getdeviceShareId(data.data.id).then(res => {
if (res.code == 200) {
if (res.data.permission) {
these.permissions = res.data.permission.split(',');
}
}
});
}
these.device = device;
these.getWarns();
let f = ble.data.LinkedList.find((v) => {
if (v.macAddress == device.deviceMac) {
// console.log("找到设备了", v);
@ -452,6 +506,7 @@
},
onShow() {
this.Status.pageHide = false;
this.getLinkedCnt();
},
computed: {
Distance: function() {
@ -478,8 +533,154 @@
}
},
methods: {
getLinkedCnt() {//获取在线设备的数量
let f = this.getDevice();
// #ifdef APP-PLUS
if (!f) {
return;
}
// #endif
// #ifdef H5
f = {
deviceId: '12345'
}
// #endif
if (ble) {
let buffer = {
ins_Quantity: "query"
};
ble.sendString(f.deviceId, buffer, f.writeServiceId, f.wirteCharactId, 30).then(res=>{
setTimeout(()=>{
this.getWarns();
},1500);
}).catch(()=>{
this.getWarns();
})
}
},
getWarns() {
return new Promise((resolve, reject) => {
if (!these.device.id) {
return;
}
let warnKey = "102_" + these.device.id + "_warning";
let linkKey = "102_" + these.device.id + "_linked";
let p1 = new Promise((succ, err) => {
uni.getStorage({
key: warnKey,
success(res) {
let data = res.data;
let fs = data.filter(v => {
return !v.read
});
succ(fs);
},
fail(ex) {
err(null);
}
});
});
let p2 = new Promise((succ, err) => {
uni.getStorage({
key: linkKey,
success(res) {
console.error("获取到联机数据",res);
let data = res.data;
let fs = data.filter(v => {
return !v.read
});
console.error("未读联机数据",fs);
succ(fs);
},
fail(ex) {
err(null);
}
});
});
Promise.allSettled([p1, p2]).then(results => {
let fs = [];
if (results[0].status == 'fulfilled') {
fs=fs.concat(results[0].value);
}
if (results[1].status == 'fulfilled') {
fs=fs.concat(results[1].value);
}
console.error("获取到未读消息",fs);
these.$set(these.Status.navbar.icons[0], "math", fs.length);
});
});
},
gotoHistory(item, s) {
uni.navigateTo({
url: '/pages/102/HBY102_History',
success: (res) => {
res.eventChannel.emit('detailData', {
data: these.device
});
}
});
},
gotoShare(item, s) {
uni.navigateTo({
url: '/pages/common/share/index',
events: {
ack: function(data) {}
},
success: (res) => {
let json = {
persissonType: '102'
};
Object.assign(json, this.device);
res.eventChannel.emit('share', {
data: json
});
}
})
},
handleRightClick(item, s) {
if (item && item.callback) {
item.callback(item, s);
} else {
uni.showModal({
content: '敬请期待'
})
}
},
navigatorBack() {
uni.navigateBack();
},
actionSett(item, index) {
if (!this.permissions.includes(item.permission) && this.Status.apiType !== 'listA') {
this.showPop({
message: '无操作权限',
iconUrl: "/static/images/6155/DeviceDetail/uploadErr.png",
borderColor: "#e034344d",
buttonBgColor: "#E03434",
okCallback: null,
buttonText: "确定"
})
return;
}
if (item.group == 'sta_LedType') {
this.sosSetting(item, index);
return;
@ -642,6 +843,19 @@
sosSetting(item, isOk) {
if (!this.permissions.includes('46') && this.Status.apiType !== 'listA') {
this.showPop({
message: '无操作权限',
iconUrl: "/static/images/6155/DeviceDetail/uploadErr.png",
borderColor: "#e034344d",
buttonBgColor: "#E03434",
okCallback: null,
buttonText: "确定"
})
return;
}
if (item.key == 'led_alarm' && this.formData.sta_LedType == 'led_alarm') {
return;
}
@ -817,7 +1031,9 @@
let json = recei.ReceiveData(receive, device, pagePath, recArr);
console.log("json=", json)
setTimeout(()=>{
this.getWarns();
},500);
let active = -1;
@ -857,7 +1073,9 @@
console.log("查询设备中", json.sta_sosadd);
this.searchDevice(json.sta_sosadd).catch(ex => {}).then(dev => {
console.log("dev=", dev);
let d=this.warnDevices.find(v=>{return v.mac===json.sta_sosadd});
let d = this.warnDevices.find(v => {
return v.mac === json.sta_sosadd
});
let deviceName = "";
if (dev) {
// this.formData.sta_sosName=dev.deviceName;
@ -869,7 +1087,10 @@
// this.formData.sta_sosName="";
}
if (!d) {
this.warnDevices.push({mac:json.sta_sosadd,name:deviceName});
this.warnDevices.push({
mac: json.sta_sosadd,
name: deviceName
});
}
this.showMsg(msg.join(','));
});
@ -1158,6 +1379,11 @@
</script>
<style>
.uninavebartext {
width: 100%;
font-size: 32rpx;
}
.content {
padding: 30rpx;
box-sizing: border-box;
@ -1919,4 +2145,65 @@
letter-spacing: 0.07px;
}
.navbarRight {
width: 60px;
height: 100%;
}
.navbarRight .imgContent {
width: 36rpx;
height: 36rpx;
position: relative;
}
.navbarRight .imgContent:first-child {
margin-right: 36rpx;
width: 38rpx !important;
height: 38rpx !important;
margin-top: -2rpx;
}
.navbarRight .imgContent .baber {
position: absolute;
z-index: 100;
width: 30rpx;
height: 30rpx;
line-height: 30rpx;
right: -15rpx;
top: -15rpx;
border-radius: 50%;
background: #f12828;
color: #ffffff;
font-family: 'PingFang SC';
font-style: Regular;
font-size: 20rpx;
font-weight: 400;
text-align: center;
overflow: hidden;
white-space: nowrap;
}
.navbarRight .imgContent .img {
width: 100%;
height: 100%;
box-sizing: border-box;
position: relative;
}
.navbarRight .imgContent .img:last-child {
padding: 1rpx;
}
.nvbar {
top: 0px;
}
/deep/ .uni-navbar--fixed {
top: 0px;
}
</style>

1327
pages/102/HBY102_History.vue Normal file

File diff suppressed because it is too large Load Diff

View File

@ -228,7 +228,7 @@
:key="index"
>
<checkbox
v-model="selectedSoundFiles"
:value="file"
@change="handleSoundFileSelect"
/>
@ -356,9 +356,7 @@
laserModeSettings, //激光模式设置
mapReverseGeocoding //地图逆解析
} from '@/api/6170/deviceControl.js'
import {
getDeviceId
} from '../../store/BLETools';
import {
baseURL,
getToken,

View File

@ -107,7 +107,7 @@
<view class="lampMode">
<view class="colorContent">
<view v-for="item,index in dic.groups" class="item"
<view v-for="item,index in formData.groups" class="item"
:class="{active:item.id==formData.sta_GroupType,marginNoLeft:index%3===0}"
@click.stop="groupSetting(item,index)">
@ -125,15 +125,15 @@
<view class="lamp noPadding">
<view class="title">箭头模式</view>
<view class="smlltitle">
箭头朝向
朝向/颜色
</view>
</view>
<view class="arrowContent marginTop10">
<view class="modeSetting">
<view class="arrow" @click.stop="ArrowSet('red_front')"
:class="formData.sta_ArrowType=='red_front'?'active':''">
<view class="arrow" @click.stop="ArrowModeSet('right_off')"
:class="formData.sta_ArrowMode=='right_off'?'active':''">
<view class="outCircle">
<view class="item">
<image class="img nomal" src="/static/images/4877/arrow.png" mode="aspectFit"></image>
@ -141,10 +141,10 @@
</image>
</view>
</view>
<view class="text">红色朝前</view>
<view class="text">朝左</view>
</view>
<view class="arrow" @click.stop="ArrowSet('green_back')"
:class="formData.sta_ArrowType=='green_back'?'active':''">
<view class="arrow" @click.stop="ArrowModeSet('right_on')"
:class="formData.sta_ArrowMode=='right_on'?'active':''">
<view class="outCircle">
<view class="item">
<image class="img nomal translate" src="/static/images/4877/arrow.png" mode="aspectFit">
@ -153,10 +153,37 @@
mode="aspectFit"></image>
</view>
</view>
<view class="text">绿色朝后</view>
<view class="text">朝右</view>
</view>
</view>
<view class="line"></view>
<view class="modeSetting">
<view class="arrow" @click.stop="ArrowSet('red_front')"
:class="formData.sta_ArrowType=='red_front'?'redactive':''">
<view class="outCircle">
<view class="item">
<view class="text">红色</view>
</view>
</view>
</view>
<view class="arrow" @click.stop="ArrowSet('green_back')"
:class="formData.sta_ArrowType=='green_back'?'greenactive':''">
<view class="outCircle">
<view class="item">
<view class="text">绿色</view>
</view>
</view>
</view>
</view>
</view>
<view class="lamp noPadding">
@ -248,10 +275,7 @@
hideLoading,
updateLoading
} from '@/utils/loading.js'
import {
request,
baseURL
} from '../../utils/request';
import request, { baseURL } from '@/utils/request.js';
import {
colors as groupColors
} from '@/api/4877/BJQ4877.js';
@ -346,7 +370,11 @@
sta_GroupType: -1, //配组
sta_ArrowType: '', //箭头方向
warnTime: 0,
sta_Channel: 80
sta_Channel: 31,
sta_ArrowMode:'',
groups: [
]
},
dic: {
SOS: [{
@ -361,10 +389,8 @@
img: '/static/images/4877/fan.png',
activeImg: '/static/images/4877/fanActive.png'
}
],
groups: [
]
},
device: {
id: "",
@ -433,13 +459,22 @@
return false;
});
these.dic.groups = groups;
these.formData.groups = groups;
}
var device = data.data;
these.device = device;
let arr=[{topic:'C/4877_Groups_'+these.device.id,callback:these.getCheckedColors}];
let arr = [{
topic: 'C/4877_Groups_' + these.device.id,
callback: these.getCheckedColors
}
// ,
// {
// topic: 'C/4877_Channel_' + these.device.id,
// callback: these.getChannel
// }
];
mq.init().then(res => {
mq.subscribes(arr).catch(ex => {
console.error("ex=", ex);
@ -496,6 +531,21 @@
},
methods: {
getChannel(rec) {
console.error("收到MQ信道保留消息:", rec);
try {
let str = rec.receive.payloadString;
let json = JSON.parse(str);
if('ins_channel' in json){
this.formData.sta_Channel=json.ins_channel;
these.setBleFormData();
}
} catch (err) {
}
},
getCheckedColors(rec) {
console.error("收到MQ消息:", rec);
try {
@ -511,8 +561,8 @@
return false;
});
these.dic.groups = groups;
these.formData.groups = groups;
console.error("groups=",these.formData.groups);
let checks = groups.map(item => {
return item.id
});
@ -580,6 +630,14 @@
json = JSON.stringify(json);
ble.sendString(f.deviceId, json, f.writeServiceId, f.wirteCharactId, 30).then(res => {
console.log("发送成功");
// mq.sendData('C/4877_Channel_' + these.device.id, JSON.stringify(json), true).then(
// res => {
// console.log("发送成功,", res)
// }).catch(err => {
// console.error("err=", err);
// });
this.setBleFormData();
}).catch(ex => {
this.showMsg(ex.msg);
@ -587,6 +645,31 @@
}, 200)
},
ArrowModeSet(val) {
if (this.formData.sta_SOSType === 'sos') {
this.showMsg("设备强制报警中,请先关闭报警")
return;
}
let f = this.getDevice();
if (!f) {
this.showBleUnConnect();
return;
}
if (this.formData.sta_ArrowMode === val) {
return;
}
var json = {
ins_right_side: val
}
json = JSON.stringify(json);
ble.sendString(f.deviceId, json, f.writeServiceId, f.wirteCharactId, 30).then(res => {
this.formData.sta_ArrowMode = val;
}).catch(ex => {
this.showMsg(ex.msg);
});
},
ArrowSet(val) {
if (this.formData.sta_SOSType === 'sos') {
@ -631,7 +714,7 @@
return false;
});
these.dic.groups = arr;
these.formData.groups = arr;
these.CheckGroupOver(data.allFlag);
}
},
@ -658,7 +741,7 @@
}
json = JSON.stringify(json);
ble.sendString(f.deviceId, json, f.writeServiceId, f.wirteCharactId, 30).then(res => {
this.setBleFormData();
}).catch(ex => {
this.showMsg(ex.msg);
});
@ -1566,7 +1649,7 @@
border-radius: 16rpx;
background: rgba(26, 26, 26, 1);
width: 100%;
padding: 10rpx 0rpx;
padding: 20rpx 0rpx;
}
.modeSetting {
@ -1601,6 +1684,21 @@
}
.modeSetting .arrow .outCircle .text {
margin-top:0rpx !important;
}
.arrowContent .line {
width:calc(100% - 60rpx);
height: 0rpx;
border-bottom:1px solid #ffffff30;
margin: 30rpx ;
}
.modeSetting .arrow .outCircle {
width: 120rpx;
height: 120rpx;
@ -1632,6 +1730,8 @@
align-items: center;
}
.modeSetting .arrow.active .outCircle {
border: 4rpx solid rgba(174, 214, 0, 1);
padding: 4rpx;
@ -1643,6 +1743,35 @@
}
.modeSetting .arrow.redactive .outCircle {
border: 4rpx solid #EC2A2A;
padding: 4rpx;
}
.modeSetting .arrow.redactive .item {
background: #EC2A2A;
border-radius: 50%;
}
.modeSetting .arrow.greenactive .outCircle {
border: 4rpx solid #00BD00;
padding: 4rpx;
}
.modeSetting .arrow.greenactive .item {
background: #00BD00;
border-radius: 50%;
}
.modeSetting .arrow.redactive .item .text,
.modeSetting .arrow.greenactive .item .text{
color:#FFFFFFde !important;
}
.modeSetting .item .img {
width: 52rpx;
height: 56rpx;

View File

@ -240,10 +240,7 @@
hideLoading,
updateLoading
} from '@/utils/loading.js'
import {
request,
baseURL
} from '../../utils/request';
import request, { baseURL } from '@/utils/request.js';
import usrApi from '@/api/670/HBY670.js'
const pagePath = "/pages/4877/BJQ4877";

1968
pages/6107/BJQ6107.vue Normal file

File diff suppressed because it is too large Load Diff

2166
pages/6155/BJQ6155.vue Normal file

File diff suppressed because it is too large Load Diff

View File

@ -4,7 +4,7 @@
<qf-image-cropper :src="src" :showAngle="false" :width="cropWidth" :height="cropHeight" fileType="jpg"
@crop="handleCrop" :gpu="true">
@crop="handleCrop" :areaScale="0.1" :minScale="0.1" :gpu="true">
</qf-image-cropper>
</view>
</template>

View File

@ -234,10 +234,7 @@
hideLoading,
updateLoading
} from '@/utils/loading.js'
import {
request,
baseURL
} from '../../utils/request';
import request, { baseURL } from '@/utils/request.js';
import usrApi from '@/api/670/HBY670.js'
const pagePath = "pages/6331/BJQ6331";

View File

@ -56,6 +56,10 @@
</view>
<view class="modeSetting">
<view class="item" :class="formData.modeCurr=='smalllow'?'active':''"
@click="MainModeSetting('smalllow','staticBattery')">
<view class="p100 center">前置</view>
</view>
<view class="item" :class="formData.modeCurr=='low'?'active':''"
@click="MainModeSetting('low','staticBattery')">
<view class="p100 center">低档</view>
@ -68,10 +72,14 @@
@click="MainModeSetting('hight','staticBattery')">
<view class="p100 center">高档</view>
</view>
<view class="item " :class="formData.modeCurr=='close'?'active':''"
<!-- <view class="item " :class="formData.modeCurr=='close'?'active':''"
@click="MainModeSetting('close','staticBattery')">
<view class="p100 center">关闭</view>
</view>
</view> -->
</view>
<view class="lampMode">
<view class="mode fleft" :class="formData.cMode?'active':''" v-on:click.stop="LampToggle()">
@ -181,10 +189,7 @@
hideLoading,
updateLoading
} from '@/utils/loading.js'
import {
request,
baseURL
} from '../../utils/request';
import request, { baseURL } from '@/utils/request.js';
import usrApi from '@/api/670/HBY670.js'
const pagePath = "/pages/650/HBY650";
@ -335,6 +340,7 @@
these.showBleUnConnect();
console.error("111111");
these.getDetail();
return;
}
@ -355,6 +361,7 @@
these.formData.bleStatu = true;
});
these.setBleFormData();
console.error("222222");
these.getDetail();
@ -566,7 +573,7 @@
getDetail() {
var that = this;
usrApi.getDetail(this.device.id).then(res => {
console.log("res=", res);
console.log("获取人员信息=", res);
if (res && res.code == 200) {
res = res.data;
let personnelInfo = res.personnelInfo;
@ -575,8 +582,24 @@
that.formData.name = personnelInfo.name;
that.formData.job = personnelInfo.position;
that.formData.id = personnelInfo.code
return;
}
}
let phone = uni.getStorageSync('phone');
if (phone === '17671332251') {
console.log("default=",that.device);
that.formData.company = '湖北消防总队';
that.formData.name = '胡红军';
that.formData.job = '中队长';
let arr=that.device.bluetoothName.split('-');
if(arr.length>1){
that.formData.id =arr[arr.length-1];
}else{
that.formData.id =that.device.bluetoothName;
}
}
});
},
@ -594,16 +617,19 @@
},
MainModeSetting: function(type, byteType) {
if (this.formData.modeCurr == type) {
return;
type = 'close';
}
showLoading(this, {
text: "请稍候..."
});
let task = () => {
this.formData.modeCurr = type;
let dataValue = 0x00;
let btype = 0x00;
switch (type) {
case "smalllow":
dataValue = 0x68;
break;
case "low": //低档
dataValue = 0x67;
break;
@ -655,8 +681,7 @@
// 发送数据
ble.sendData(f.deviceId, buffer, f.writeServiceId, f.wirteCharactId, 10).then(() => {
this.formData.modeCurr = type;
console.log("发送成功了");
}).catch((ex) => {
@ -1084,10 +1109,12 @@
hideLoading(these);
return;
}
console.log("baseURL=", baseURL);
console.log("token", token);
console.log("clientID", clientid);
uni.uploadFile({
// url: 'http://114.55.111.217/video/upload',
url: baseURL + "app/video/upload",
url: baseURL + "/app/video/upload",
filePath: videoPath,
name: 'file',
header: {
@ -1115,6 +1142,7 @@
let res = arr[1];
res = JSON.parse(res.data);
if (res.data) {
these.videoHexArray = res.data;
updateLoading(these, {

View File

@ -1,10 +1,21 @@
<template>
<view class="content contentBg">
<custom-navbar :title="Status.navbar.title" :showBack="Status.navbar.showBack" color="#FFFFFF"
:rightIcons="Status.navbar.icons" @icon-click="handleRightClick"></custom-navbar>
<view>
<!-- <custom-navbar :title="Status.navbar.title" :showBack="Status.navbar.showBack" color="#FFFFFF"
:rightIcons="Status.navbar.icons" @icon-click="handleRightClick" backgroundColor="#121212"></custom-navbar>
-->
<uni-nav-bar :border="false" @clickLeft="prevPage" fixed="true" statusBar="true"
background-color="#121212" color="#FFFFFF" :title="Status.navbar.title">
<template v-slot:left><view>
<uni-icons type="left" size="24" color="#FFFFFF"></uni-icons>
</view></template>
<block slot="right">
<view class="navbarRight center">
<image @click.stop="handleRightClick(index,item)" v-for="item,index in Status.navbar.icons" class="img" :src="item.src" mode="aspectFit"></image>
</view>
</block>
</uni-nav-bar>
<view class="eq" :style="{marginTop:Status.navbar.height+'px'}">
<view class="leftImg" @click.stop="previewImg(device.devicePic?device.devicePic:formData.img)">
<image class="img" :src="device.devicePic?device.devicePic:formData.img" mode="aspectFit"></image>
@ -90,8 +101,7 @@
<view :class="getWarnStyle(5)" class="net netfive"></view>
</view>
</view>
<view class="warnnig" :class="formData.qzwarn ?'':'displayNone'"
@click="CloseWarn(true)">
<view class="warnnig" :class="formData.qzwarn ?'':'displayNone'" @click="CloseWarn(true)">
<view>设备强制报警中</view>
<view class="netContent" :class="{'displayNone':!Status.staticWarn.time}">
{{Status.staticWarn.time}}s
@ -219,8 +229,8 @@
<view>
<view class="item">
<input maxlength="16" class="value" style="text-indent: 20rpx;" v-model="formData.msgTxt" placeholder="请输入文字"
placeholder-class="usrplace" />
<input maxlength="16" class="value" style="text-indent: 20rpx;" v-model="formData.msgTxt"
placeholder="请输入文字" placeholder-class="usrplace" />
</view>
</view>
@ -294,11 +304,8 @@
hideLoading,
updateLoading
} from '@/utils/loading.js'
import {
request,
baseURL
} from '../../utils/request';
import lnglatConvert from '@/utils/wgs84_to_gcj02.js'
import request, { baseURL } from '@/utils/request.js';
import lnglatConvert from '@/utils/wgs84_to_gcj02.js';
const pagePath = "/pages/670/HBY670";
var ble = null;
@ -560,6 +567,11 @@
},
methods: {
prevPage() {
uni.navigateBack({
})
},
deviceRecovry(res) {
if (this.Status.pageHide) {
return;
@ -679,7 +691,9 @@
});
},
gotoMap() {
let lnglat = lnglatConvert.wgs84_to_gcj02(this.formData.Lon, this.formData.Lat);
let promise = lnglatConvert.wgs84_to_gcj02(this.formData.Lon, this.formData.Lat);
promise.then(lnglat => {
this.detailData.longitude = lnglat[0];
this.detailData.latitude = lnglat[1];
uni.navigateTo({
@ -693,6 +707,8 @@
});
}
})
});
},
getDetail() {
var that = this;
@ -869,7 +885,8 @@
if (keys.indexOf('sta_BreakNews') > -
1) { //紧急通知
if (json.sta_BreakNews ===
'I get it') // && this.Status.msgOkTime && this.Status.msgOkIntval){
'I get it'
) // && this.Status.msgOkTime && this.Status.msgOkIntval){
{
these.showPop({
showPop: true,
@ -3320,4 +3337,13 @@
.net.active {
background: #FFFFFF !important;
}
.navbarRight .img{
width: 35rpx;
height: 35rpx;
margin-right: 20rpx;
}
.uni-navbar--fixed{
top:0rpx;
}
</style>

View File

@ -483,8 +483,9 @@
if (this.Status.pageHide) {
return;
}
let json = recei.ReceiveData(receive, device, path, recArr);
let json = recei.ReceiveData(receive, device, path, recArr);
console.log("收到消息:",receive.hexs);
if (!json) {
return;
}

View File

@ -46,7 +46,7 @@
var these = null;
var eventChannel = null;
var ble = null;
var inteval=null;
export default {
data() {
return {
@ -118,7 +118,7 @@
onUnload() {
console.log("返回取消订阅");
clearInterval(inteval);
ble.removeAllCallback(pagePath);
},
onLoad(option) {
@ -226,7 +226,7 @@
}
})
let inteval = setInterval(this.initDevice, 10000);
inteval = setInterval(this.initDevice, 10000);
}
@ -291,6 +291,7 @@
}
}
});
clearInterval(inteval);
} else {
deviceInvalid();
}

View File

@ -120,6 +120,7 @@
var ble = null;
var these = null;
var eventChannel = null;
export default {
data() {
return {
@ -334,7 +335,7 @@
//搜索到新设备的回调 (Always active)
ble.addDeviceFound((arr) => {
console.log("--- 收到原始扫描数据 ---", JSON.stringify(arr));
// console.log("--- 收到原始扫描数据 ---", JSON.stringify(arr));
if (these.Status.isPageHidden) {
return;
}
@ -343,7 +344,7 @@
}
arr = arr.devices;
console.log(`本次扫描批次发现 ${arr.length} 个设备`);
// console.log(`本次扫描批次发现 ${arr.length} 个设备`);
for (var i = 0; i < arr.length; i++) {
let device = arr[i];
@ -351,9 +352,9 @@
let f = these.EquipMents.find((v, index) => {
if (v.deviceId == device.deviceId) {
console.log(
`更新设备信号: ${device.name || device.deviceId}, RSSI: ${device.RSSI}`
);
// console.log(
// `更新设备信号: ${device.name || device.deviceId}, RSSI: ${device.RSSI}`
// );
these.$set(these.EquipMents[index], 'RSSI', device.RSSI);
return true;
}
@ -361,7 +362,7 @@
});
if (!f) {
console.log("+++ 发现新设备,准备添加到列表:", JSON.stringify(device));
// console.log("+++ 发现新设备,准备添加到列表:", JSON.stringify(device));
if (these.device && these.device.bluetoothName && device.name) {
if (these.device.bluetoothName === device.name || (device.name && device.name
@ -417,10 +418,16 @@
//收到设备的消息回调
ble.addReceiveCallback((receivData, f, path, arr) => {
console.log("000000");
console.log("000000",receivData);
if (these.Status.isPageHidden) {
return;
}
if(receivData.bytes[0]===0xFC && receivData.hexs.length>=7){
console.log("22222222");
}
if(receivData.str.indexOf('mac address:')>-1 || receivData.str.indexOf('sta_address')>-1
|| (receivData.bytes[0]===0xFC && receivData.bytes.length>=7))
{
console.log("1111111");
if (f.macAddress && these.device) {
console.log("222222");
@ -436,8 +443,7 @@
these.DeviceVerdict(f.deviceId);
}, 0);
}
}
}, pagePath);
}
}
@ -452,7 +458,7 @@
}
startValidDevice();
these.refreshBleList();
});
},
@ -502,6 +508,8 @@
});
},
async refreshBleList() {
const systemInfo = uni.getSystemInfoSync();
if (systemInfo.uniPlatform == 'web') {
return;
@ -521,6 +529,8 @@
}
}
ble.StopSearch().finally(() => {
let disconnectPromises = [];
@ -551,6 +561,9 @@
});
});
});
},
isItemLink: function(item, index) {
let src = '/static/images/BLEAdd/noLink.png';
@ -599,8 +612,6 @@
if (index > -1) {
this.PairEquip.splice(index, 1);
}
}
console.log("f=", f);
@ -708,8 +719,8 @@
});
return;
}
console.log("验证设备")
these.DeviceVerdict(item.deviceId);
// console.log("验证设备")
// these.DeviceVerdict(item.deviceId);
}
let execLink = () => {
return new Promise((resolve, reject) => {

View File

@ -2,9 +2,9 @@
<view class="alltype">
<!-- 车辆列表 -->
<view class="vehicle-list" v-if="vehicles.length>0">
<view v-for="(item, index) in vehicles" :key="index">
<view class="typeContent" v-for="(item, index) in vehicles" :key="index">
<view class="vehicle-item" @click="alltypeInfo(item)">
<image src="/static/images/common/bip.6.png" mode="" class="IMG"></image>
<image :src="item.img" mode="aspectFit" class="IMG"></image>
</view>
<view class="plate-number">{{ item.typeName }}</view>
</view>
@ -20,30 +20,130 @@
<script>
import {
deviceTypeList,
typeAll
} from '@/api/common/index.js'
export default {
data() {
return {
vehicles: [],
typeImgs: [{
"Name": "HBY018A",
"sigName": "018A",
"url": "/static/images/common/018A.png"
},
{
"Name": "HBY102",
"sigName": "102",
"url": "/static/images/common/HBY102.png"
},
{
"Name": "BJQ6075",
"sigName": "6075",
"url": "/static/images/common/BJQ6075.png"
},
{
"Name": "HBY100",
"sigName": "100",
"url": "/static/images/common/HBY100J.png"
},
{
"Name": "BJQ4877",
"sigName": "4877",
"url": "/static/images/common/BJQ4877.png"
},
{
"Name": "BJQ7307",
"sigName": "7307",
"url": "/static/images/common/7307.png"
},
{
"Name": "BJQ7305",
"sigName": "7305",
"url": "/static/images/common/7305.png"
},
{
"Name": "HBY650",
"sigName": "650",
"url": "/static/images/common/HBY650.png"
},
{
"Name": "BJQ6155",
"sigName": "6155",
"url": "/static/images/common/HBY6155.png"
},
{
"Name": "HBY670",
"sigName": "670",
"url": "/static/images/common/HBY670.png"
},
{
"Name": "HBY210",
"sigName": "210",
"url": "/static/images/common/210.png"
},
{
"Name": "BJQ6170",
"sigName": "6170",
"url": "/static/images/common/bip.6.png"
}
]
}
},
methods: {
getTab() {
deviceTypeList({}).then((res) => {
let p1 = deviceTypeList({});
let p2 = typeAll();
Promise.allSettled([p1, p2]).then(result => {
let res = result[0].status === 'fulfilled' ? result[0].value : {};
let res1 = result[1].status === 'fulfilled' ? result[1].value : {};
if (res.code == 200) {
this.vehicles = res.data
if (res1.code != 200) {
for (let i = 0; i < res.data.length; i++) {
let f = this.typeImgs.find(v => {
if (res.data[i].typeName.toLowerCase() === v.Name.toLowerCase()) {
return true;
}
})
return false;
});
if (f) {
res.data[i].img = f.url;
}else{
res.data[i].img = "/static/images/common/bip.6.png";
}
}
} else {
let all = res1.data;
for (let i = 0; i < res.data.length; i++) {
let f = all.find(v => {
if (res.data[i].id === v.deviceTypeId) {
return true;
}
return false;
});
if (f && f.devicePic) {
res.data[i].img = f.devicePic;
}else{
res.data[i].img = "/static/images/common/bip.6.png";
}
}
}
this.vehicles = res.data;
}
});
},
alltypeInfo(item) {
uni.switchTab({
url: '/pages/common/index/index',
success: (res) => {
res.eventChannel.emit('index', {
data: item
});
let eventChannel = this.getOpenerEventChannel();
eventChannel.emit('index', item);
}
})
});
}
},
@ -65,8 +165,10 @@
.vehicle-list {
display: flex;
flex-wrap: wrap;
flex-direction: row;
align-content: center;
justify-content: space-around;
align-items: center;
text-align: center;
}
@ -77,14 +179,17 @@
}
.vehicle-item {
padding: 24rpx 0;
background: rgba(26, 26, 26, 1);
border-radius: 16rpx;
width: 156rpx;
height: 156rpx;
margin-right: 16rpx;
margin-bottom: 16rpx;
line-height: 156rpx;
border-radius: 9px;
width: 140rpx;
height: 140rpx;
margin-bottom: 15rpx;
display: grid;
align-content: center;
justify-content: center;
}
@ -96,6 +201,9 @@
.plate-number {
color: rgba(255, 255, 255, 0.87);
font-size: 27rpx;
font-family: 'PingFang SC';
text-align: center;
}
.noDATA {
@ -103,4 +211,8 @@
color: rgba(255, 255, 255, 0.87);
transform: translate(-0%, 100%);
}
.typeContent {
padding-bottom: 15rpx;
}
</style>

View File

@ -146,11 +146,12 @@
} from '@/api/common/index.js'
import bleTool from '@/utils/BleHelper.js';
import MescrollUni from '@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-uni.vue'
import BleReceive from '@/utils/BleReceive';
var pagePath = 'pages/common/index';
var ble = null;
var timeout = null;
var recei=null;
export default {
components: {
MescrollUni
@ -292,28 +293,39 @@
},
updateBleStatu(deviceId) { //更新列表的蓝牙连接状态
updateBleStatu() { //更新列表的蓝牙连接状态,电池 电量
if (ble) {
for (var i = 0; i < this.deviceList.length; i++) {
let bleStatu = false;
let f = null;
if (ble.data && ble.data.LinkedList) {
ble.data.LinkedList.find(v => {
if (deviceId && v.deviceId != deviceId) {
return false;
}
f = ble.data.LinkedList.find(v => {
if (v.macAddress && v.device && v.device.id) {
if (v.device.id == this.deviceList[i].id && v.Linked) {
bleStatu = true;
return true;
}
return v.device.id == this.deviceList[i].id;
}
return false;
});
}
this.$set(this.deviceList[i], 'bleStatu', bleStatu);
if (f) {
this.$set(this.deviceList[i], 'bleStatu', f.Linked);
if (f.formData) {
let battary = 0;
if ('battary' in f.formData) {
battary = f.formData.battary;
} else if ('sta_PowerPercent' in f.formData) {
battary = f.formData.sta_PowerPercent;
} else if ('sta_battery' in f.formData) {
battary = f.formData.sta_battery;
}
this.$set(this.deviceList[i], 'battery', battary);
}
}
@ -329,15 +341,30 @@
// 所有分享,所有类型
handleshareClick(item) {
this.showshare = false; // 关闭弹窗
var that = this;
switch (item.action) {
case 'type':
uni.navigateTo({
url: '/pages/common/allType/index'
url: '/pages/common/allType/index',
events: {
index(data) {
if (data && data.id) {
that.tabs.find((v, i) => {
if (v.id === data.id) {
that.switchTab(v, i);
return true;
}
return false;
})
}
}
}
});
break;
case 'share':
uni.navigateTo({
url: "/pages/common/allShare/index"
url: "/pages/common/allShare/index",
})
break;
}
@ -430,7 +457,8 @@
this.total = res.total;
// 判断是否加载完成
let hasNext = true;
if (res.rows.length < this.size || this.deviceList.length >= this.total) {
if (res.rows.length < this.size || this.deviceList.length >= this
.total) {
hasNext = false;
} else {
hasNext = true;
@ -470,6 +498,9 @@
case 'scan':
// 扫一扫
uni.scanCode({
autoDecodeCharset:true,
autoZoom:true,
barCodeInput:true,
success: (res) => {
console.log('条码内容:', res);
// 清除之前的数据
@ -484,14 +515,19 @@
if ('imei' in json) {
url =
`/pages/common/qrcode/qrcode?deviceId=${encodeURIComponent(json.imei)}`;
} else if ('blue' in json) {
} else if ('blue' in json || 'ble' in json) {
if(json.ble){
json.blue=json.ble;
}
if(json.blue){
if (!json.blue.includes(':')) {
json.blue = json.blue.replace(
/(.{2})/g, '$1:')
.slice(0, -1)
}
url =
`/pages/common/addBLE/LinkBle?mac=${encodeURIComponent(json.blue)}`;
}
url =`/pages/common/addBLE/LinkBle?mac=${encodeURIComponent(json.blue)}`;
}
} catch (ex) {
@ -519,7 +555,9 @@
},
// 右滑点击事件处理
handleSwipeClick(e, item, index) {
const {content} = e
const {
content
} = e
setTimeout(() => {
console.log(item, 'eeeee');
switch (e.content.text) {
@ -671,7 +709,7 @@
let url = item.detailPageUrl;
// console.log("url=",url);
// if(!url){
//url="/pages/670/HBY670"
// url="/pages/6075/BJQ6075"
// }
uni.navigateTo({
url: url,
@ -717,7 +755,16 @@
.filter(Boolean);
},
},
onShow() {
if (ble) {
//因为vue视图只能后退不能隐藏后再显示
//所以回到首页后将其他所有页面的订阅都删除
ble.removeAllCallbackByRetain(pagePath);
}
},
onLoad() {
console.error("首页加载");
this.getTab()
this.downCallback();
@ -732,7 +779,7 @@
this.downCallback();
});
ble = bleTool.getBleTool();
recei = BleReceive.getBleReceive();
//蓝牙连接成功的回调
ble.addRecoveryCallback((res) => {
console.log("蓝牙连接成功的回调");
@ -757,6 +804,13 @@
this.bleStateBreak();
}, pagePath);
//接收到消息的回调
ble.addReceiveCallback((receive, device, path, recArr) => {
console.error("首页收到消息了");
recei.ReceiveData(receive, device, path, recArr);
this.updateBleStatu();
}, pagePath);
this.getSystemInfoSyncH();
},
@ -765,8 +819,9 @@
uni.$off('refreshDeviceList');
},
onUnload() {
console.log("onUnload...");
uni.$off('deviceStatusUpdate');
ble && ble.removeAllCallback();
ble && ble.removeAllCallback(pagePath);
}
}
@ -1139,6 +1194,7 @@
background-color: rgba(35, 35, 35, 0.87);
color: rgba(255, 255, 255, 1);
}
.mask {
position: fixed;
width: 100%;
@ -1146,6 +1202,7 @@
z-index: 9998;
background-color: #00000000;
}
/* 提示框样式 */
.tooltip-box {
position: fixed;

View File

@ -65,7 +65,7 @@
<script>
import {
deviceShareId,
deviceShareCode,
deviceShareAdd
} from '@/api/6170/share.js'

BIN
static/images/6107/fan.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1003 B

BIN
static/images/6107/ju.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1003 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 522 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 141 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1021 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

File diff suppressed because it is too large Load Diff

View File

@ -1,42 +0,0 @@
// store/index.js
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
const store = new Vuex.Store({
state: {
userInfo: null, // 用户信息
theme: 'light', // 主题
token: '', // 登录凭证
},
mutations: {
setUserInfo(state, userInfo) {
state.userInfo = userInfo;
},
setTheme(state, theme) {
state.theme = theme;
},
setToken(state, token) {
state.token = token;
}
},
actions: {
updateUserInfo({ commit }, userInfo) {
commit('setUserInfo', userInfo);
},
updateTheme({ commit }, theme) {
commit('setTheme', theme);
},
updateToken({ commit }, token) {
commit('setToken', token);
}
},
getters: {
getUserInfo: (state) => state.userInfo,
getTheme: (state) => state.theme,
getToken: (state) => state.token
}
});
export default store;

View File

@ -1,5 +1,7 @@
## 2.0.102024-06-07
- 优化 uni-app x 中,size 属性的类型
## 2.0.122025-08-26
- 优化 uni-app x size 类型问题
## 2.0.112025-08-18
- 修复 图标点击事件返回
## 2.0.92024-01-12
fix: 修复图标大小默认值错误的问题
## 2.0.82023-12-14

View File

@ -11,7 +11,7 @@
* Icons 图标
* @description 用于展示 icon 图标
* @tutorial https://ext.dcloud.net.cn/plugin?id=28
* @property {Number,String} size 图标大小
* @property {Number} size 图标大小
* @property {String} type 图标图案,参考示例
* @property {String} color 图标颜色
* @property {String} customPrefix 自定义图标

View File

@ -85,8 +85,8 @@
}
},
methods: {
_onClick() {
this.$emit('click')
_onClick(e) {
this.$emit('click', e)
}
}
}

View File

@ -1,7 +1,7 @@
{
"id": "uni-icons",
"displayName": "uni-icons 图标",
"version": "2.0.10",
"version": "2.0.12",
"description": "图标组件,用于展示移动端常见的图标,可自定义颜色、大小。",
"keywords": [
"uni-ui",
@ -11,7 +11,9 @@
],
"repository": "https://github.com/dcloudio/uni-ui",
"engines": {
"HBuilderX": "^3.2.14"
"HBuilderX": "^3.2.14",
"uni-app": "^4.08",
"uni-app-x": "^4.61"
},
"directories": {
"example": "../../temps/example_temps"
@ -34,54 +36,74 @@
"permissions": "无"
},
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
"type": "component-vue"
"type": "component-vue",
"darkmode": "x",
"i18n": "x",
"widescreen": "x"
},
"uni_modules": {
"dependencies": ["uni-scss"],
"dependencies": [
"uni-scss"
],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y",
"alipay": "n"
"tcb": "x",
"aliyun": "x",
"alipay": "x"
},
"client": {
"App": {
"app-vue": "y",
"app-nvue": "y",
"app-uvue": "y"
"uni-app": {
"vue": {
"vue2": "",
"vue3": ""
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
"web": {
"safari": "",
"chrome": ""
},
"H5-pc": {
"Chrome": "y",
"IE": "y",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
"app": {
"vue": "",
"nvue": "-",
"android": {
"extVersion": "",
"minVersion": "29"
},
"小程序": {
"微信": "y",
"阿里": "y",
"百度": "y",
"字节跳动": "y",
"QQ": "y",
"钉钉": "y",
"快手": "y",
"飞书": "y",
"京东": "y"
"ios": "√",
"harmony": ""
},
"快应用": {
"华为": "y",
"联盟": "y"
"mp": {
"weixin": "",
"alipay": "",
"toutiao": "√",
"baidu": "√",
"kuaishou": "-",
"jd": "-",
"harmony": "-",
"qq": "√",
"lark": "-"
},
"Vue": {
"vue2": "y",
"vue3": "y"
"quickapp": {
"huawei": "",
"union": ""
}
},
"uni-app-x": {
"web": {
"safari": "√",
"chrome": "√"
},
"app": {
"android": {
"extVersion": "",
"minVersion": "29"
},
"ios": "√",
"harmony": "√"
},
"mp": {
"weixin": "√"
}
}
}
}

View File

@ -0,0 +1,60 @@
## 1.3.172025-09-03
- 修复 内部样式问题
## 1.3.162025-08-18
- 修复 微信小程序 fixed 下避让胶囊优化标题居中默认showMenuButtonWidth 不开启下,右侧插槽会被 胶囊覆盖
- 新增 showMenuButtonWidth 右侧是否避让胶囊,即 显示区域为胶囊左侧,默认不开启,开启后会导致标题不在页面水平居中
## 1.3.152025-06-24
- 适配微信小程序固定导航栏时,右侧插槽避让胶囊按钮
## 1.3.142024-10-15
- 修复 微信小程序中的getSystemInfo警告
## 1.3.112023-03-29
- 修复 自定义状态栏高度闪动BUG
## 1.3.102023-03-29
- 修复 暗黑模式下边线颜色错误的bug
## 1.3.92022-10-13
- 修复 条件编译错误的bug
## 1.3.82022-10-12
- 修复 nvue 环境 fixed 为 true 的情况下,无法置顶的 bug
## 1.3.72022-08-11
- 修复 nvue 环境下 fixed 为 true 的情况下,无法置顶的 bug
## 1.3.62022-06-30
- 修复 组件示例中插槽用法无法显示内容的bug
## 1.3.52022-05-24
- 新增 stat 属性 可开启统计title 上报 仅使用了title 属性且项目开启了uni统计生效
## 1.3.42022-01-24
- 更新 组件示例
## 1.3.32022-01-24
- 新增 left-width/right-width属性 ,可修改左右两侧的宽度
## 1.3.22022-01-18
- 修复 在vue下标题不垂直居中的bug
## 1.3.12022-01-18
- 修复 height 属性类型错误
## 1.3.02022-01-18
- 新增 height 属性,可修改组件高度
- 新增 dark 属性可可开启暗黑模式
- 优化 标题字数过多显示省略号
- 优化 插槽,插入内容可完全覆盖
## 1.2.12022-01-10
- 修复 color 属性不生效的bug
## 1.2.02021-11-19
- 优化 组件UI并提供设计资源详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-nav-bar](https://uniapp.dcloud.io/component/uniui/uni-nav-bar)
## 1.1.02021-07-30
- 组件兼容 vue3如何创建vue3项目详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
## 1.0.112021-05-12
- 新增 组件示例地址
## 1.0.102021-04-30
- 修复 在nvue下fixed为true宽度不能撑满的Bug
## 1.0.92021-04-21
- 优化 添加依赖 uni-icons, 导入后自动下载依赖
## 1.0.82021-04-14
- uni-ui 修复 uni-nav-bar 当 fixed 属性为 true 时铺不满屏幕的 bug
## 1.0.72021-02-25
- 修复 easycom 下,找不到 uni-status-bar 的bug
## 1.0.62021-02-05
- 优化 组件引用关系通过uni_modules引用组件
## 1.0.52021-02-05
- 调整为uni_modules目录规范

View File

@ -0,0 +1,383 @@
<template>
<view class="uni-navbar" :class="{'uni-dark':dark, 'uni-nvue-fixed': fixed}">
<view class="uni-navbar__content" :class="{ 'uni-navbar--fixed': fixed, 'uni-navbar--shadow': shadow, 'uni-navbar--border': border }" :style="{ 'background-color': themeBgColor }">
<status-bar v-if="statusBar" />
<view :style="{ color: themeColor,backgroundColor: themeBgColor ,height:navbarHeight,width:showMenuButtonWidth?navWidth+'px':'100%'}" class="uni-navbar__header">
<view @tap="onClickLeft" class="uni-navbar__header-btns uni-navbar__header-btns-left" :style="{width:leftIconWidth}">
<slot name="left">
<view class="uni-navbar__content_view" v-if="leftIcon.length > 0">
<uni-icons :color="themeColor" :type="leftIcon" size="20" />
</view>
<view :class="{ 'uni-navbar-btn-icon-left': !leftIcon.length > 0 }" class="uni-navbar-btn-text" v-if="leftText.length">
<text :style="{ color: themeColor, fontSize: '12px' }">{{ leftText }}</text>
</view>
</slot>
</view>
<view class="uni-navbar__header-container " @tap="onClickTitle">
<slot>
<view class="uni-navbar__header-container-inner" v-if="title.length>0">
<text class="uni-nav-bar-text uni-ellipsis-1" :style="{color: themeColor }">{{ title }}</text>
</view>
</slot>
</view>
<view @click="onClickRight" class="uni-navbar__header-btns uni-navbar__header-btns-right" :style="{width:rightIconWidth}">
<slot name="right">
<view v-if="rightIcon.length">
<uni-icons :color="themeColor" :type="rightIcon" size="22" />
</view>
<view class="uni-navbar-btn-text" v-if="rightText.length && !rightIcon.length">
<text class="uni-nav-bar-right-text" :style="{ color: themeColor}">{{ rightText }}</text>
</view>
</slot>
</view>
</view>
</view>
<view class="uni-navbar__placeholder" v-if="fixed">
<status-bar v-if="statusBar" />
<view class="uni-navbar__placeholder-view" :style="{ height:navbarHeight}" />
</view>
</view>
</template>
<script>
import statusBar from "./uni-status-bar.vue";
const getVal = (val) => typeof val === 'number' ? val + 'px' : val;
/**
*
*
* NavBar 自定义导航栏
* @description 导航栏组件,主要用于头部导航
* @tutorial https://ext.dcloud.net.cn/plugin?id=52
* @property {Boolean} dark 开启黑暗模式
* @property {String} title 标题文字
* @property {String} leftText 左侧按钮文本
* @property {String} rightText 右侧按钮文本
* @property {String} leftIcon 左侧按钮图标(图标类型参考 [Icon 图标](http://ext.dcloud.net.cn/plugin?id=28) type 属性)
* @property {String} rightIcon 右侧按钮图标(图标类型参考 [Icon 图标](http://ext.dcloud.net.cn/plugin?id=28) type 属性)
* @property {String} color 图标和文字颜色
* @property {String} backgroundColor 导航栏背景颜色
* @property {Boolean} fixed = [true|false] 是否固定顶部
* @property {Boolean} statusBar = [true|false] 是否包含状态栏
* @property {Boolean} shadow = [true|false] 导航栏下是否有阴影
* @property {Boolean} stat 是否开启统计标题上报
* @event {Function} clickLeft 左侧按钮点击时触发
* @event {Function} clickRight 右侧按钮点击时触发
* @event {Function} clickTitle 中间标题点击时触发
*/
export default {
name: "UniNavBar",
components: {
statusBar
},
emits: ['clickLeft', 'clickRight', 'clickTitle'],
props: {
dark: {
type: Boolean,
default: true
},
title: {
type: String,
default: ""
},
leftText: {
type: String,
default: ""
},
rightText: {
type: String,
default: ""
},
leftIcon: {
type: String,
default: ""
},
rightIcon: {
type: String,
default: ""
},
fixed: {
type: [Boolean, String],
default: true
},
color: {
type: String,
default: ""
},
backgroundColor: {
type: String,
default: ""
},
statusBar: {
type: [Boolean, String],
default: true
},
shadow: {
type: [Boolean, String],
default: false
},
border: {
type: [Boolean, String],
default: false
},
height: {
type: [Number, String],
default: 44
},
leftWidth: {
type: [Number, String],
default: 90
},
rightWidth: {
type: [Number, String],
default: 90
},
showMenuButtonWidth: {
type: Boolean,
default: false
},
stat: {
type: [Boolean, String],
default: ''
}
},
data() {
return {
navWidth: 'auto'
}
},
computed: {
themeBgColor() {
if (this.dark) {
// 默认值
if (this.backgroundColor) {
return this.backgroundColor
} else {
return this.dark ? '#121212' : '#FFF'
}
}
return this.backgroundColor || '#FFF'
},
themeColor() {
if (this.dark) {
// 默认值
if (this.color) {
return this.color
} else {
return this.dark ? '#fff' : '#333'
}
}
return this.color || '#333'
},
navbarHeight() {
// #ifdef MP-WEIXIN
if (this.fixed && this.height === 0) {
const menuBtnInfo = uni.getMenuButtonBoundingClientRect()
const winInfo = uni.getWindowInfo()
const statusHeight = winInfo.statusBarHeight
const spaceHeight = menuBtnInfo.top - statusHeight
return getVal(menuBtnInfo.height + spaceHeight * 2)
}
// #endif
// #ifndef MP-WEIXIN
if (this.fixed && this.height === 0) {
return getVal(44)
}
// #endif
return getVal(this.height)
},
leftIconWidth() {
return getVal(this.leftWidth)
},
rightIconWidth() {
return getVal(this.rightWidth)
}
},
created() {
// #ifdef MP-WEIXIN
if (this.fixed) {
const menuBtnInfo = uni.getMenuButtonBoundingClientRect()
this.navWidth = menuBtnInfo.left
}
// #endif
},
mounted() {
if (uni.report && this.stat && this.title !== '') {
uni.report('title', this.title)
}
},
methods: {
onClickLeft() {
this.$emit("clickLeft");
},
onClickRight() {
this.$emit("clickRight");
},
onClickTitle() {
this.$emit("clickTitle");
}
}
};
</script>
<style lang="scss" scoped>
$nav-height: 44px;
.uni-nvue-fixed {
/* #ifdef APP-NVUE */
position: sticky;
/* #endif */
}
.uni-navbar {
// box-sizing: border-box;
}
.uni-nav-bar-text {
/* #ifdef APP-PLUS */
font-size: 34rpx;
/* #endif */
/* #ifndef APP-PLUS */
font-size: 14px;
/* #endif */
}
.uni-nav-bar-right-text {
font-size: 12px;
}
.uni-navbar__content {
position: relative;
// background-color: #fff;
// box-sizing: border-box;
background-color: transparent;
}
.uni-navbar__content_view {
// box-sizing: border-box;
}
.uni-navbar-btn-text {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
justify-content: flex-start;
align-items: center;
line-height: 12px;
}
.uni-navbar__header {
padding: 0 10px;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
height: $nav-height;
font-size: 12px;
box-sizing: border-box;
}
.uni-navbar__header-btns {
/* #ifndef APP-NVUE */
overflow: hidden;
display: flex;
/* #endif */
flex-wrap: nowrap;
flex-direction: row;
width: 120rpx;
// padding: 0 6px;
justify-content: center;
align-items: center;
/* #ifdef H5 */
cursor: pointer;
/* #endif */
}
.uni-navbar__header-btns-left {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
width: 120rpx;
justify-content: flex-start;
align-items: center;
}
.uni-navbar__header-btns-right {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
// width: 150rpx;
// padding-right: 30rpx;
justify-content: flex-end;
align-items: center;
}
.uni-navbar__header-container {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex: 1;
padding: 0 10px;
overflow: hidden;
}
.uni-navbar__header-container-inner {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex: 1;
flex-direction: row;
align-items: center;
justify-content: center;
font-size: 12px;
overflow: hidden;
// box-sizing: border-box;
}
.uni-navbar__placeholder-view {
height: $nav-height;
}
.uni-navbar--fixed {
position: fixed;
z-index: 998;
/* #ifdef H5 */
left: var(--window-left);
right: var(--window-right);
/* #endif */
/* #ifndef H5 */
left: 0;
right: 0;
/* #endif */
}
.uni-navbar--shadow {
box-shadow: 0 1px 6px #ccc;
}
.uni-navbar--border {
border-bottom-width: 1rpx;
border-bottom-style: solid;
border-bottom-color: #eee;
}
.uni-ellipsis-1 {
overflow: hidden;
/* #ifndef APP-NVUE */
white-space: nowrap;
text-overflow: ellipsis;
/* #endif */
/* #ifdef APP-NVUE */
lines: 1;
text-overflow: ellipsis;
/* #endif */
}
// 暗主题配置
.uni-dark {}
</style>

View File

@ -0,0 +1,30 @@
<template>
<view :style="{ height: statusBarHeight }" class="uni-status-bar">
<slot />
</view>
</template>
<script>
export default {
name: 'UniStatusBar',
data() {
return {
// #ifdef MP-WEIXIN
statusBarHeight: uni.getWindowInfo().statusBarHeight + 'px',
// #endif
// #ifndef MP-WEIXIN
statusBarHeight: uni.getSystemInfoSync().statusBarHeight + 'px',
// #endif
}
}
}
</script>
<style lang="scss" >
.uni-status-bar {
// width: 750rpx;
height: 20px;
// height: var(--status-bar-height);
}
</style>

View File

@ -0,0 +1,106 @@
{
"id": "uni-nav-bar",
"displayName": "uni-nav-bar 自定义导航栏",
"version": "1.3.17",
"description": "自定义导航栏组件,主要用于头部导航。",
"keywords": [
"uni-ui",
"导航",
"导航栏",
"自定义导航栏"
],
"repository": "https://github.com/dcloudio/uni-ui",
"engines": {
"HBuilderX": "",
"uni-app": "^4.07",
"uni-app-x": ""
},
"directories": {
"example": "../../temps/example_temps"
},
"dcloudext": {
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
"type": "component-vue",
"darkmode": "x",
"i18n": "x",
"widescreen": "x"
},
"uni_modules": {
"dependencies": [
"uni-scss",
"uni-icons"
],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "x",
"aliyun": "x",
"alipay": "x"
},
"client": {
"uni-app": {
"vue": {
"vue2": "√",
"vue3": "√"
},
"web": {
"safari": "√",
"chrome": "√"
},
"app": {
"vue": "√",
"nvue": "√",
"android": "√",
"ios": "√",
"harmony": "√"
},
"mp": {
"weixin": "√",
"alipay": "√",
"toutiao": "√",
"baidu": "√",
"kuaishou": "-",
"jd": "-",
"harmony": "-",
"qq": "√",
"lark": "-"
},
"quickapp": {
"huawei": "√",
"union": "√"
}
},
"uni-app-x": {
"web": {
"safari": "-",
"chrome": "-"
},
"app": {
"android": "-",
"ios": "-",
"harmony": "-"
},
"mp": {
"weixin": "-"
}
}
}
}
}
}

View File

@ -0,0 +1,15 @@
## NavBar 导航栏
> **组件名uni-nav-bar**
> 代码块: `uNavBar`
导航栏组件,主要用于头部导航。
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-nav-bar)
#### 如使用过程中有任何问题或者您对uni-ui有一些好的建议欢迎加入 uni-ui 交流群871950839

View File

@ -56,7 +56,7 @@ class BleHelper {
isOpenBlue: false, //蓝牙模块是否开启
available: false, //蓝牙状态是否可用
discovering: false, //蓝牙是否正在搜索
searchList: [], //已搜索到的设备列表,
isSubscribe: false, //是否开启了订阅
LinkedList: linkedDevices, //已连接的设备列表
platform: systemInfo.uniPlatform,
@ -71,9 +71,10 @@ class BleHelper {
stateRecoveryCallback: [], //蓝牙适配器恢复可用事件
stateBreakCallback: [] //蓝牙适配器不可用事件
}
this.addReceiveCallback((receive, f, path, recArr) => {
recei.ReceiveData(receive, f, path, recArr);
}, "BleReceiveData");
//蓝牙模块不再订阅,改到首页订阅
// this.addReceiveCallback((receive, f, path, recArr) => {
// recei.ReceiveData(receive, f, path, recArr);
// }, "BleReceiveData");
setTimeout(() => {
this.OpenBlue().then(() => {
@ -229,8 +230,12 @@ class BleHelper {
}
if (key) {
// console.log("key=" + key);
let f = this.cfg[type].findIndex((v) => {
return v.key == key;
let f =-1;
this.cfg[type].find((v,index) => {
if(v.key == key){
f=index;
}
});
if (f > -1) {
// this.cfg[type][f].callback = callback;
@ -253,8 +258,11 @@ class BleHelper {
if (key) {
// console.log("key=" + key);
let f = this.cfg[type].findIndex((v) => {
return v.key == key;
let f =-1;
this.cfg[type].find((v,index) => {
if(v.key == key){
f=index;
}
});
if (f > -1) {
this.cfg[type].splice(f, 1);
@ -268,8 +276,31 @@ class BleHelper {
}
//获取某个事件的所有订阅者,但不包含某些订阅者
getCfgAllKeys(type,retains){
if(!retains){
retains=[];
}
if(!Array.isArray(retains)){
retains=[retains];
}
let keys=null;
for (let index = 0; index < this.cfg[type]; index++) {
let ele = this.cfg[type];
let f=retains.find(v=>{
return v.toLowerCase()==ele.key.toLowerCase();
});
if(!f){
if(!keys){
keys=[ele.key];
}else{
keys.push(ele.key);
}
}
}
return keys;
}
//设置蓝牙恢复连接的回调
addRecoveryCallback(callback, currKey) {
@ -280,6 +311,17 @@ class BleHelper {
removeRecoveryCallback(currKey) {
this.removeCallback(currKey, 'recoveryCallback');
}
//移除所有蓝牙恢复连接的回调,但不包括currkey
removeAllRecoveryCallback(currKey) {
let keys=this.getCfgAllKeys('recoveryCallback',currKey);
if(keys){
for (let i = 0; i < keys.length; i++) {
let key = keys[i];
this.removeRecoveryCallback(key);
}
}
}
//设置蓝牙断开连接的回调
addDisposeCallback(callback, currKey) {
@ -290,6 +332,16 @@ class BleHelper {
removeDisposeCallback(currKey) {
this.removeCallback(currKey, 'bleDisposeCallback');
}
removeAllDisposeCallback(currKey) {
let keys=this.getCfgAllKeys('bleDisposeCallback',currKey);
if(keys){
for (let i = 0; i < keys.length; i++) {
let key = keys[i];
this.removeDisposeCallback(key);
}
}
}
//设置发现新设备的回调
@ -301,6 +353,16 @@ class BleHelper {
removeDeviceFound(currKey) {
this.removeCallback(currKey, 'onDeviceFound');
}
removeAllDeviceFound(currKey) {
let keys=this.getCfgAllKeys('onDeviceFound',currKey);
if(keys){
for (let i = 0; i < keys.length; i++) {
let key = keys[i];
this.removeDeviceFound(key);
}
}
}
//添加接收到数据的回调
addReceiveCallback(callback, currKey) {
@ -311,6 +373,16 @@ class BleHelper {
removeReceiveCallback(currKey) {
this.removeCallback(currKey, 'receivDataCallback');
}
removeAllReceiveCallback(currKey) {
let keys=this.getCfgAllKeys('receivDataCallback',currKey);
if(keys){
for (let i = 0; i < keys.length; i++) {
let key = keys[i];
this.removeReceiveCallback(key);
}
}
}
//添加蓝牙不可用的回调
addStateBreakCallback(callback, currKey) {
@ -321,7 +393,16 @@ class BleHelper {
removeStateBreakCallback(currKey) {
this.removeCallback(currKey, 'stateBreakCallback');
}
removeAllStateBreakCallback(currKey) {
let keys=this.getCfgAllKeys('stateBreakCallback',currKey);
if(keys){
for (let i = 0; i < keys.length; i++) {
let key = keys[i];
this.removeStateBreakCallback(key);
}
}
}
//设置蓝牙适配器恢复可用的回调
addStateRecoveryCallback(callback, currKey) {
@ -332,6 +413,16 @@ class BleHelper {
removeStateRecoveryCallback(currKey) {
this.removeCallback(currKey, 'stateRecoveryCallback');
}
removeAllStateRecoveryCallback(currKey) {
let keys=this.getCfgAllKeys('stateRecoveryCallback',currKey);
if(keys){
for (let i = 0; i < keys.length; i++) {
let key = keys[i];
this.removeStateRecoveryCallback(key);
}
}
}
//清除所有事件回调
removeAllCallback(currKey) {
@ -342,7 +433,15 @@ class BleHelper {
this.removeStateRecoveryCallback(currKey);
this.removeStateBreakCallback(currKey);
}
//清除所有事件回调不包含retain
removeAllCallbackByRetain(retain) {
this.removeAllDeviceFound(retain)
this.removeAllDisposeCallback(retain);
this.removeAllReceiveCallback(retain);
this.removeAllRecoveryCallback(retain);
this.removeAllStateRecoveryCallback(retain);
this.removeAllStateBreakCallback(retain);
}
getError(ex) {
let code = ex.code;
@ -681,7 +780,6 @@ class BleHelper {
if (this.cfg.receivDataCallback.length > 0) {
let path = this.getCurrentPagePath();
// console.log("有人订阅消息")
this.cfg.receivDataCallback.forEach((
rec) => {
@ -690,7 +788,7 @@ class BleHelper {
try {
// console.log("正在处理订阅消息",rec);
rec.callback(recData, f,
path, this.cfg
rec.key, this.cfg
.receivDataCallback
);
// console.log("处理订阅消息完毕");
@ -784,21 +882,24 @@ class BleHelper {
}
BleConnChange() {
let stateTimeout=null;
uni.onBLEConnectionStateChange((res) => {
console.log("蓝牙连接状态变化了", res);
// 检查状态是否真的发生了变化
let ble = this.data.LinkedList.find(dev => {
return res.deviceId === dev.deviceId;
});
if (ble) {
if (ble.Linked === res.connected) {
console.error("专业给UniApp填坑,蓝牙连接状态重复回调");
return;
}
}
console.log("蓝牙连接状态变化了", res);
setTimeout(() => {
clearTimeout(stateTimeout);
stateTimeout=setTimeout(() => {
if (!res.connected) {
console.error("蓝牙已断开", res);
let f = this.data.LinkedList.find((
@ -851,7 +952,7 @@ class BleHelper {
console.log("蓝牙连接已恢复", res);
}
}, 0);
}, 50);
});
}
@ -881,8 +982,7 @@ class BleHelper {
return;
}
res.devices = arr;
this.data.searchList = this.data.searchList.concat(
res);
if (this.cfg.onDeviceFound) {
if (this.cfg.onDeviceFound.length > 0) {
this.cfg.onDeviceFound.forEach((found) => {
@ -907,7 +1007,7 @@ class BleHelper {
this.data.available = false;
this.data.discovering = false;
this.data.isOpenBlue = false;
this.data.searchList = [];
return Promise.resolve();
}
@ -924,7 +1024,7 @@ class BleHelper {
this.data.available = false;
this.data.discovering = false;
this.data.isOpenBlue = false;
this.data.searchList = [];
resolve();
},
fail: (ex) => {
@ -959,20 +1059,15 @@ class BleHelper {
if (this.data.platform == 'web') {
return Promise.resolve({});
}
this.data.searchList = [];
var these = this;
//开始搜索
var Search = () => {
//只搜索合作供应商的服务id
let serviceIds = serviceDic.map(v => {
return v.serviceId
});
//搜索一个服务id的设备循环调用
let RunSearch = (serviceId) => {
let RunSearch = () => {
return new Promise((resolve, reject) => {
uni.startBluetoothDevicesDiscovery({
services: serviceId ? [serviceId] : [],
services:[],
allowDuplicatesKey: true,
success: (res) => {
console.log('开始搜索蓝牙设备成功');
@ -992,14 +1087,8 @@ class BleHelper {
return new Promise((resolve, reject) => {
let promises = [];
// for (let i = 0; i < serviceIds.length; i++) {
// promises.push(RunSearch(serviceIds[i]));
// }
promises.push(RunSearch());
Promise.all(promises).then(resolve).catch(reject);
});
@ -1278,7 +1367,6 @@ class BleHelper {
} else
{
console.error("预设的蓝牙服务和特征中找不到");
for (var i = 0; i < res.services.length; i++) {
@ -1297,7 +1385,7 @@ class BleHelper {
});
} else {
Promise.all(promises)
Promise.allSettled(promises)
.then(results => {
console.log("results= ", results);
if (!s) {
@ -1512,12 +1600,23 @@ class BleHelper {
timeout: 30000,
success: (info) => {
//释放连接锁
delete this.data.connectingDevices[deviceId];
console.log("新连接成功", this.data.LinkedList);
// 处理 MTU 设置
if (plus.os.name === 'Android') {
this.setMtu(deviceId).catch(ex => {
console.error("mtu设置失败=", ex);
});
}
this.getLinkBlue().then((arr) => {
let linkId=new Date().getTime();//本次连接的id
let cr = arr.devices.find(c => {
if (c.deviceId == deviceId) {
c.Linked = true;
c.linkId=linkId
return true;
}
return false;
@ -1525,6 +1624,7 @@ class BleHelper {
if (fIndex > -1) {
this.data.LinkedList[fIndex].Linked = true;
this.data.LinkedList[fIndex].linkId=linkId;
} else {
this.data.LinkedList.push(cr);
}
@ -1558,12 +1658,7 @@ class BleHelper {
});
}
// 处理 MTU 设置
if (plus.os.name === 'Android') {
this.setMtu(deviceId).catch(ex => {
console.error("mtu设置失败=", ex);
});
}
resolve(true);
}).catch((ex) => {
@ -1970,5 +2065,6 @@ export default {
}
return instance;
}
},
constService:serviceDic
}

View File

@ -1,8 +1,11 @@
import Common from '@/utils/Common.js'
class BleReceive {
constructor() {
this.StorageKey = "linkedDevices";
this.HandlerMap = {
'/pages/6155/deviceDetail': this.Receive_6155.bind(this),
'/pages/6155/BJQ6155': this.Receive_6155_XH.bind(this),
'/pages/7305/BJQ7305': this.Receive_6155.bind(this),
'/pages/650/HBY650': this.Receive_650.bind(this),
'/pages/670/HBY670': this.Receive_670.bind(this),
@ -99,6 +102,10 @@ class BleReceive {
staticLevelText = '低档';
modeCurr = "low";
break;
case 0x68:
staticLevelText = '前置';
modeCurr = "smalllow";
break;
case 0x64:
staticLevelText = '关闭';
modeCurr = "close";
@ -419,6 +426,94 @@ class BleReceive {
return data;
}
Receive_6155_XH(receive, f, path, recArr) {
let bytes = receive.bytes;
if (bytes[0] == 0xFB && bytes[1] == 0x64 && bytes.length >= 8) {
try {
let light = null;
let mode = null;
if (bytes[2] === 0x01 && bytes[3] === 0x00) {
light = 0;
mode = 'main';
} else if (bytes[2] === 0x02 && bytes[3] === 0x00) {
light = 1;
mode = 'main';
} else if (bytes[2] === 0x00 && bytes[3] === 0x01) {
light = 2;
mode = 'main';
} else if (bytes[2] === 0x03 && bytes[3] === 0x00) {
light = 0;
mode = 'fu';
} else if (bytes[2] === 0x04 && bytes[3] === 0x00) {
light = 1;
mode = 'fu';
}
if (bytes[2] === 0x05 && bytes[3] === 0x00) {
light = 3;
}
// 解析剩余电量
let batteryLevelByte = bytes[4];
// 电量百分比范围检查
let batteryLevel = Math.max(0, Math.min(100, batteryLevelByte));
//充电状态
let warn = bytes[5];
if (warn == 0x00) {
warn = '未充电';
} else if (warn == 0x01) {
warn = '充电中';
}
// 解析剩余照明时间(第三和第四字节,小端序)
let lightingTime = "";
let HH = Math.max(0, Math.min(100, bytes[6]));
let mm = Math.max(0, Math.min(100, bytes[7]));
lightingTime = HH + "小时" + mm + "分钟";
let formData = {};
formData.mode = mode;
formData.light = light;
formData.battary = batteryLevel;
formData.statu = warn;
formData.xuhang = lightingTime;
let recCnt = recArr.find(v => {
return v.key.replace(/\//g, "").toLowerCase() === f.device.detailPageUrl.replace(/\//g,
'').toLowerCase();
});
if (!recCnt) {
if (batteryLevel <= 20) {
// 会弹出两个框,暂且注释掉这段代码
uni.showModal({
content: "设备'" + f.device.deviceName + "'电量低",
title: "提示"
});
}
}
this.setBleFormData(formData, f);
return formData;
} catch (error) {
console.log('7305数据解析错误:', error);
return null;
}
}
return null;
}
Receive_6155(receive, f, path, recArr) {
let bytes = receive.bytes;
if (bytes[0] == 0xFB && bytes[1] == 0x64 && bytes.length >= 8) {
@ -494,7 +589,8 @@ class BleReceive {
let recCnt = recArr.find(v => {
return v.key.replace(/\//g, "").toLowerCase() === f.device.detailPageUrl.replace(/\//g, '').toLowerCase();
return v.key.replace(/\//g, "").toLowerCase() === f.device.detailPageUrl.replace(/\//g,
'').toLowerCase();
@ -583,8 +679,9 @@ class BleReceive {
let receiveData = {};
try {
// console.log("str=",receive.str);
console.log("订阅消息者:", path);
console.log("设备收到消息:", f);
console.log("消息内容:", receive);
receiveData = JSON.parse(receive.str);
let recCnt = recArr.find(v => {
@ -608,6 +705,134 @@ class BleReceive {
}
}
if (f.device && path === "pages/common/index") { //仅在首页订阅此操作
console.error("1111111111");
let linkKey = "102_" + f.device.id + "_linked";
let warnKey = "102_" + f.device.id + "_warning";
let time = new Date(); //Common.DateFormat(new Date(),'yyyy-MM-dd HH:mmss');
if (receiveData.sta_tomac) { //某个设备上线了
if (receiveData.sta_tomac.indexOf(':') == -1) {
receiveData.sta_tomac = receiveData.sta_tomac.replace(/(.{2})/g, '$1:').slice(0, -
1); //mac地址自动补:
}
uni.getStorageInfo({
success: function(res) {
let arr = [];
let linked = {
linkId: f.linkId,
read: false,
linkEqs: [{
linkTime: time,
linkMac: f.macAddress
}, {
linkTime: time,
linkMac: receiveData.sta_tomac
}]
};
if (res.keys.includes(linkKey)) {
arr = uni.getStorageSync(linkKey);
}
if (arr.length == 0) {
arr.unshift(linked);
} else {
let dev = arr.find(v => {
if (v.linkId == f.linkId) {
let vl = v.linkEqs.find(cvl => {
if(cvl.linkMac === receiveData.sta_tomac){
v.read=false;
cvl.linkTime=time;
return true;
}
return false;
});
if (!vl) {
v.linkEqs.push({
linkTime: time,
linkMac: receiveData.sta_tomac
});
}
return vl;
}
return false;
});
if (!dev) {
arr.unshift(linked);
}
}
console.error("某个设备上线了", arr)
uni.setStorage({
key: linkKey,
data: arr
});
}
});
}
let warnArrs = [];
let guid = Common.guid();
if (receiveData.sta_sosadd) { //某个设备闯入报警
console.error("某个设备闯入报警");
if (receiveData.sta_sosadd.indexOf(':') == -1) {
receiveData.sta_sosadd = receiveData.sta_sosadd.replace(/(.{2})/g, '$1:').slice(0, -
1); //mac地址自动补:
}
warnArrs.push({
linkId: f.linkId,
read: false,
key: guid,
warnType: "闯入报警",
warnMac: receiveData.sta_sosadd,
warnTime: time,
warnName: ""
});
}
if (receiveData.sta_LedType === 'led_alarm' || receiveData.ins_LedType === 'led_alarm') { //强制报警
console.error("强制报警了", f);
warnArrs.push({
linkId: f.linkId,
read: false,
key: guid,
warnType: "强制报警",
warnMac: f.macAddress,
warnTime: time,
warnName: ""
});
}
if (warnArrs.length > 0) {
uni.getStorageInfo({
success: function(res) {
let arr = [];
if (res.keys.includes(warnKey)) {
arr = uni.getStorageSync(warnKey);
arr = warnArrs.concat(arr);
} else {
arr = warnArrs
}
uni.setStorage({
key: warnKey,
data: arr
});
}
});
}
}
} catch (error) {
receiveData = {};
console.log("文本解析失败", error)

View File

@ -218,7 +218,7 @@ export default {
value: "1",
label: "灯光模式",
checked: false,
type: ['6170', '670']
type: ['6170', '670','102']
},
{
value: "2",
@ -282,7 +282,7 @@ export default {
value: "46",
label: "手动报警",
checked: false,
type: ['210']
type: ['210','102']
},
{
value: "47",
@ -290,6 +290,18 @@ export default {
checked: false,
type: ['210']
},
{
value: "48",
label: "物体感应",
checked: false,
type: ['102']
},
{
value: "49",
label: "联机模式",
checked: false,
type: ['102']
},
]
let arr = [];

View File

@ -1,4 +1,3 @@
//地标 转 国测 常量
var x_PI = (3.14159265358979324 * 3000.0) / 180.0;
var PI = 3.1415926535897932384626;
@ -44,8 +43,7 @@ function transformlng(lng, lat) {
//转化纬度
function transformlat(lng, lat) {
var ret =
-100.0 +
var ret = -100.0 +
2.0 * lng +
3.0 * lat +
0.2 * lat * lat +
@ -68,9 +66,57 @@ function transformlat(lng, lat) {
3.0;
return ret;
}
//经纬度互相转换
function convertByNet(lng,lat,from){
//wgs84 to gcj02 地球坐标系 转 火星坐标系
function wgs84_to_gcj02(lng, lat) {
return new Promise((resolve, reject) => {
if(!from){
from='wgs84'
}
let url = 'https://openapi.lddgo.net/base/gtool/api/v1/CoordinateTransform'
uni.request({
url: url,
method: 'POST',
timeout: 10000,
header:{
'content-type':'application/json;charset=UTF-8'
},
data:
{
"from": "wgs84",
"coordinateList": [
{
"sourceLng": lng,
"sourceLat": lat
}
]
}
,
dataType: 'json',
success(res) {
if (res.statusCode == 200) {
if (res.data.code===0) {
console.log("坐标转换接口成功", res);
let lnglag=res.data.data.coordinateList[0];
resolve([lnglag.gLng,lnglag.gLat]);
return;
}
}
console.error("坐标转换异常", res);
resolve(null)
},
fail(err) {
console.error("坐标转换接口出现异常", err);
resolve(null);
}
})
});
}
function wgs84_to_gcj02_old(lng, lat) {
if (out_of_china(lng, lat)) {
return [lng, lat];
} else {
@ -91,14 +137,76 @@ function transformlat(lng, lat) {
return [mglng, mglat];
}
}
//wgs84 to gcj02 wgs84转gcj02,返回Promise
function wgs84_to_gcj02(lng, lat) {
//调用高德的接口进行坐标转换
let convertByGD = () => {
return new Promise((resolve, reject) => {
let url = 'https://restapi.amap.com/v3/assistant/coordinate/convert?locations=' + lng + ',' +
lat + '&coordsys=gps&output=json&key=ca3af8a20d628897020893892bda5ae4'
uni.request({
url: url,
method: 'GET',
timeout: 10000,
dataType: 'json',
success(res) {
if (res.statusCode == 200) {
if (res.data.status == "1" && res.data.infocode=='10000') {
console.log("坐标转换接口成功", res);
resolve(res.data.locations.split(','));
return;
}
}
console.error("坐标转换异常", res);
resolve(null)
},
fail(err) {
console.error("坐标转换接口出现异常", err);
resolve(null);
}
})
});
}
let convertOrains=()=>{
let newLnglat=wgs84_to_gcj02_old(lng,lat);
return Promise.resolve(newLnglat);
}
let task=()=>{
return new Promise((resolve,reject)=>{
let promises=[convertByGD(),convertByNet(lng,lat),convertOrains()];
Promise.allSettled(promises).then(
res=>{
for (let i = 0; i < res.length; i++) {
let item = res[i];
if(item.status==='fulfilled' && item.value){
resolve(item.value);
break;
}
}
}
);
});
}
return task();
}
//gcj02 to wgs84 火星坐标系 转 地球坐标系
function gcj02_to_wgs84(lng, lat) {
function gcj02_to_wgs84_old(lng, lat) {
if (out_of_china(lng, lat)) {
return [lng, lat]
}
else {
} else {
var dlat = transformlat(lng - 105.0, lat - 35.0);
var dlng = transformlng(lng - 105.0, lat - 35.0);
var radlat = lat / 180.0 * PI;
@ -113,10 +221,27 @@ function transformlat(lng, lat) {
}
}
//gcj02转wgs84
function gcj02_to_wgs84(lng, lat){
let task=()=>{
return new Promise((resolve,reject)=>{
convertByNet(lng,lat,'gcj02').then(res=>{
if(res){
resolve(res);
return;
}
resolve(gcj02_to_wgs84_old(lng,lat));
})
});
}
return task();
}
export default {
gcj02_to_wgs84,
wgs84_to_gcj02
}