1
0
forked from dyf/APP

Compare commits

...

6 Commits

20 changed files with 900 additions and 115 deletions

View File

@ -6,7 +6,8 @@
"type" : "uni-app:app-ios"
},
{
"playground" : "standard",
"customPlaygroundType" : "local",
"playground" : "custom",
"type" : "uni-app:app-android"
}
]

View File

@ -1,3 +1,29 @@
{
"prompt" : "template"
"version" : "1",
"prompt" : "template",
"title" : "服务协议和隐私政策",
"message" : "  请你务必审慎阅读、充分理解“服务协议”和“隐私政策”各条款,包括但不限于:为了更好的向你提供服务,我们需要收集你的设备标识、操作日志等信息用于分析、优化应用性能。<br/>  你可阅读<a href=\"https://dmsapp.skf.com.cn/HummerService/Resource/Template/1765175615670.html\">《服务协议》</a>和<a href=\"https://dmsapp.skf.com.cn/HummerService/Resource/Template/1765176086420.html\">《隐私政策》</a>了解详细信息。如果你同意,请点击下面按钮开始接受我们的服务。",
"buttonAccept" : "同意并接受",
"buttonRefuse" : "暂不同意",
"hrefLoader" : "system",
"backToExit" : "false",
"disagreeMode" : {
"support" : false,
"loadNativePlugins" : false,
"visitorEntry" : false,
"showAlways" : true
},
"styles" : {
"backgroundColor" : "#FFFFFF",
"borderRadius" : "5px",
"title" : {
"color" : "#FFFFFF"
},
"buttonAccept" : {
"color" : "#b9e203"
},
"buttonRefuse" : {
"color" : "#555555"
}
}
}

View File

@ -57,7 +57,8 @@
],
"minSdkVersion" : 21,
"abiFilters" : [ "armeabi-v7a", "arm64-v8a", "x86" ],
"schemes" : ""
"schemes" : "",
"targetSdkVersion" : 30
},
/* ios */
"ios" : {
@ -139,7 +140,8 @@
}
},
"splashscreen" : {
"useOriginalMsgbox" : true
"useOriginalMsgbox" : true,
"androidStyle" : "common"
}
}
},

View File

@ -348,6 +348,13 @@
{
"navigationBarTitleText" : "HBY102"
}
},
{
"path" : "pages/common/user/logOff",
"style" :
{
"navigationBarTitleText" : "注销账号"
}
}

View File

@ -8,7 +8,7 @@
<custom-navbar :title="navTitle" :showBack="true" color="#FFFFFF" :rightIcons="[
{src: '/static/images/210/ls.png'},
...(isRightIconVisible ? [{src: '/static/images/common/shape.png'}] : [])
]" @right-click="shareUp" @icon-click="handleIconClick"></custom-navbar>
]" @icon-click="handleIconClick"></custom-navbar>
<view class="device-detail-container" :style="{ paddingTop: navBarHeight + 'px' }">
<!-- 设备电量信息 -->
@ -410,9 +410,9 @@
this.lightModeB = false;
},
// 上传文件
uploadFile(){},
uploadFile() {},
// 删除文件
deleteQ(){},
deleteQ() {},
// 打开弹框
showPopup(type) {
this.currentPopup = {
@ -596,40 +596,37 @@
this.lightModeA = false;
// console.log("保存的时间:", time);
},
handleIconClick(index) {
// 历史记录
if (index === 0) {
handleIconClick(s,e) {
if (s === 0) {
console.log("消息");
uni.navigateTo({
url: '/pages/210/historyRecords/index',
events: {
ack: function(data) {}
},
url: '/pages/670/History',
success: (res) => {
res.eventChannel.emit('share', {
data: this.itemInfo,
res.eventChannel.emit('detailData', {
data: these.device,
});
}
})
} else {
return;
} else if (s === 1) {
console.log("分享");
uni.navigateTo({
url: '/pages/6170/share/index',
url: '/pages/common/share/index',
events: {
ack: function(data) {}
},
success: (res) => {
let json = {
persissonType: '210'
};
Object.assign(json, this.device);
res.eventChannel.emit('share', {
data: this.itemInfo,
data: json
});
}
})
}
},
// 分享
shareUp() {
},
// 操作说明
operatingInst() {
uni.navigateTo({
@ -1284,11 +1281,12 @@
display: flex;
cursor: pointer;
align-items: center;
margin-bottom:20rpx;
margin-bottom: 20rpx;
}
.uploadIMG{
width:68rpx;
height:68rpx;
.uploadIMG {
width: 68rpx;
height: 68rpx;
margin-right: 20rpx;
}

View File

@ -108,7 +108,7 @@
<view class="lampMode">
<view class="colorContent">
<view v-for="item,index in dic.groups" class="item"
:class="{active:item.id===formData.sta_GroupType,marginNoLeft:index%3===0}"
:class="{active:item.id==formData.sta_GroupType,marginNoLeft:index%3===0}"
@click.stop="groupSetting(item,index)">
<view class="polygon" :style="{backgroundColor:item.hex}">
@ -256,6 +256,7 @@
colors as groupColors
} from '@/api/4877/BJQ4877.js';
import MqTool from '@/utils/MqHelper.js'
const pagePath = "/pages/4877/BJQ4877";
@ -264,6 +265,7 @@
var recei = null;
var interval = null;
var slidTime = null;
var mq=null;
export default {
data() {
return {
@ -380,7 +382,7 @@
latitude: null,
longitude: null,
alarmStatus: null,
detailPageUrl: "/pages/650/HBY650",
detailPageUrl: "/pages/4877/BJQ4877",
showConfirm: false
},
}
@ -389,12 +391,19 @@
onUnload() {
console.log("页面卸载,释放资源");
ble.removeAllCallback(pagePath);
if(mq){
mq.unSubscribes();
mq.disconnect();
}
ble=null;
mq=null;
clearInterval(interval);
},
onLoad: function() {
these = this;
recei = BleReceive.getBleReceive();
ble = BleTool.getBleTool();
mq=MqTool.getMqTool();
this.dic.gropus = [];
@ -410,7 +419,7 @@
eventChannel.on('detailData', function(data) {
console.log("收到父页面的参数:" + JSON.stringify(data));
// console.log("收到父页面的参数:" + JSON.stringify(data));
let checkIds = uni.getStorageSync("4877CheckColor_" + data.data.id);
if (checkIds && checkIds.length) {
@ -429,6 +438,14 @@
}
var device = data.data;
these.device = device;
let arr=[{topic:'C/4877_Groups_'+these.device.id,callback:these.getCheckedColors}];
mq.init().then(res=>{
mq.subscribes(arr).catch(ex=>{
console.error("ex=",ex);
});
})
let f = ble.data.LinkedList.find((v) => {
if (v.macAddress == device.deviceMac) {
// console.log("找到设备了", v);
@ -457,6 +474,8 @@
these.formData.bleStatu = false;
these.formData.deviceId = f.deviceId;
these.formData.warnTime=null;
these.formData.sta_SOSType='sos_off';
ble.LinkBlue(f.deviceId, f.writeServiceId, f.wirteCharactId, f.notifyCharactId).then(res => {
these.formData.bleStatu = true;
});
@ -477,6 +496,39 @@
},
methods: {
getCheckedColors(rec){
console.error("收到MQ消息:",rec);
try{
let str=rec.receive.payloadString;
let arr=JSON.parse(str);
let groups = groupColors.filter((v,index) => {
if(arr[index]===1){
return true;
}
return false;
});
these.dic.groups = groups;
let checks = groups.map(item => {
return item.id
});
uni.setStorage({
key: "4877CheckColor_" + this.device.id,
data: checks
});
}catch(err){
}
},
ShowChannelEdit() {
this.Status.ShowEditChannel = true;
this.showPop({
@ -596,7 +648,11 @@
return;
}
mq.sendData('C/4877_Groups_'+these.device.id,JSON.stringify(arr),true).then(res=>{
console.log("发送成功,",res)
}).catch(err=>{
console.error("err=",err);
});
var json = {
ins_GroupType: arr
}
@ -659,6 +715,21 @@
}
groupSet();
},
SOSEvt(){
if (this.formData.sta_SOSType == 'sos') {
this.formData.sta_ArrowType='arrow_off';
this.formData.warnTime = 0;
clearInterval(interval);
interval = setInterval(() => {
this.formData.warnTime += 1;
}, 1000)
}else{
clearInterval(interval);
interval=null;
this.formData.warnTime = 0;
}
},
sosSetting(item, index) {
let f = this.getDevice();
@ -679,14 +750,8 @@
ble.sendString(f.deviceId, json, f.writeServiceId, f.wirteCharactId, 30).then(res => {
this.formData.sta_GroupType = -1;
this.formData.sta_SOSType = json.ins_SOSType
if (this.formData.sta_SOSType == 'sos') {
this.formData.warnTime = 0;
clearInterval(interval);
interval = setInterval(() => {
this.formData.warnTime += 1;
}, 1000)
}
these.SOSEvt();
})
.catch(ex => {
@ -857,9 +922,15 @@
this.formData[key] = data[key];
}
});
let msg = [];
if (data.sta_SOSType == 'sos') {
msg.push("设备声光报警中");
}
if('sta_SOSType' in data){
these.SOSEvt();
}
if (data.sta_PowerPercent <= 20) {
msg.push("设备电量低");

View File

@ -834,7 +834,6 @@
initMQ() {
return new Promise((resolve, reject) => {
if (mqttClient) {
// console.log("无需再次初始化")
resolve();
@ -953,7 +952,7 @@
if ("sta_LightGrade" in json) {
let lightingLevelText = json.sta_LightGrade === 1 ? 'hight' : json.sta_LightGrade === 2 ? 'low' :
let lightingLevelText = json.sta_LightGrade === 1 ? 'qiang' : json.sta_LightGrade === 2 ? 'ruo' :
'close';
receiveData.lightCurr = lightingLevelText;
}

View File

@ -602,7 +602,7 @@
}
console.log("f=", f);
if (f.macAddress) {
if (f && f.macAddress) {
if (f.macAddress != these.device.deviceMac) {
@ -650,7 +650,7 @@
}
return false;
});
if (!f.macAddress) {
if (!(f && f.macAddress)) {
removeLink();
updateLoading(these, {
text: "出现错误,未收到设备Mac地址"

View File

@ -43,8 +43,8 @@
<!-- 协议内容 -->
<view class="popup-content">
为了更好的保障您的合法权益请您阅读并同意以下协议
<text class="protocol-link" @click="openProtocol('user')">用户服务协议</text>
<text class="protocol-link" @click="openProtocol('privacy')">隐私政策</text>
<text class="protocol-link" @click="goToPage('agreement')">用户服务协议</text>
<text class="protocol-link" @click="goToPage('privacy')">隐私政策</text>
</view>
<!-- 按钮组 -->
<view class="popup-buttons">

View File

@ -398,9 +398,25 @@
// 处理新的扫码结果
const cleanedResult = res.result.trim();
console.log('扫码结果:', cleanedResult);
let url=`/pages/common/qrcode/qrcode?deviceId=${encodeURIComponent(cleanedResult)}`;
try{
let json=JSON.parse(cleanedResult);
if('imei' in json){
url=`/pages/common/qrcode/qrcode?deviceId=${encodeURIComponent(json.imei)}`;
}else if('blue' in json){
if(!json.blue.includes(':')){
json.blue=json.blue.replace(
/(.{2})/g, '$1:')
.slice(0, -1)
}
url=`/pages/common/addBLE/LinkBle?mac=${encodeURIComponent(json.blue)}`;
}
}catch(ex){
}
// 跳转并传递扫描结果
uni.navigateTo({
url: `/pages/common/qrcode/qrcode?deviceId=${encodeURIComponent(cleanedResult)}`
url: url
});
},
fail: (err) => {
@ -461,7 +477,7 @@
// 关闭所有滑动项
this.$refs.swipeAction.closeAll();
ble && ble.DropDevice(data.id);
ble && ble.DropDevice(null,data.id);
} else {
uni.showToast({
title: res.msg,
@ -980,6 +996,8 @@
margin-left: 15rpx;
padding: 10rpx 0rpx;
font-size: 28rpx;
text-align: left;
text-indent: 5rpx;
}
.svg {

View File

@ -49,8 +49,8 @@
<!-- 协议内容 -->
<view class="popup-content">
为了更好的保障您的合法权益请您阅读并同意以下协议
<text class="protocol-link" @click="openProtocol('user')">用户服务协议</text>
<text class="protocol-link" @click="openProtocol('privacy')">隐私政策</text>
<text class="protocol-link" @click="goToPage('agreement')">用户服务协议</text>
<text class="protocol-link" @click="goToPage('privacy')">隐私政策</text>
</view>
<!-- 按钮组 -->
<view class="popup-buttons">
@ -78,7 +78,7 @@
agreed: false,
isCounting: false,
countdown: 0,
isChecked: true,
isChecked: false,
showAgreement: false, // 控制弹窗显示
isCodeLogin: false,
}

View File

@ -1,7 +1,107 @@
<template>
<view class="device-page">
<view class="deviceTitle">欢迎你使用我们的产品和服务!本用户协议(以下简称"协议")由你(以下简称"用户")[公司名称](以下简称"我们""本公司")就使用[产品名称]的相关事宜共同订立
欢迎你使用我们的产品和服务!本用户协议(以下简称"协议")由你(以下简称"用户")[公司名称](以下简称"我们""本公司")就使用[产品名称]的相关事宜共同订立</view>
<view class="title">星汉物联App联隐私政策</view>
<view class="smalltitle">
更新日期2025-09-23
</view>
<view class="smalltitle">
生效日期2025-10-08
</view>
<view class="smalltitle">
开发者名称 湖北星汉研创科技有限公司
</view>
<view class="smalltitle">
应用名称 星汉物联
</view>
<view class="smalltitle marginBottom">
联系方式 cnxhyc123@163.com
</view>
<view class="smalltitle">
1. 导言与声明
</view>
<view class="smalltitle">
我们深知个人信息对您的重要性并承诺保护您的隐私本政策旨在说明我们在您使用[应用名称]如何收集使用存储共享和保护您的个人信息以及您享有的权利请仔细阅读您继续使用我们的服务即表示同意本政策的内容如您是未成年人请在监护人指导下阅读
</view>
<view class="smalltitle marginBottom">
重要提示根据工业和信息化部的要求应用在首次启动时必须通过弹窗等方式清晰展示隐私政策并提供明确的同意拒绝选项不能设置默认勾选也不能使用好的我知道了等模糊表述
</view>
<view class="smalltitle">
2. 我们如何收集和使用您的个人信息
</view>
<view class="smalltitle marginBottom">
我们仅会出于以下合法正当必要的目的收集您的信息
</view>
<view class="smalltitle marginBottom">
<view class="deviceTitle">(1).账号信息手机号码验证码,用于注册登陆</view>
<view class="deviceTitle">(2).蓝牙,用于设备连接后的通信控制</view>
<view class="deviceTitle">(3).相机/相册权限,拍摄的照片或视频用于上传给设备扫码等</view>
<view class="deviceTitle">(4).设备标识信息IMEIAndroid IDMACOAID软件安装列表,用于日志查询统计分析识别您的设备预防恶意程序及反作弊提高服务安全性</view>
<view class="deviceTitle">(5).GPS或网络位置,用于基于位置的服务如地图导航位置偏移预警</view>
<view class="deviceTitle">(6).麦克风,我们的智能设备支持播放语音需要录音以上传给设备</view>
<view class="deviceTitle">(7).根据SDK功能可能收集设备信息位置信息等我们会对合作的第三方SDK进行严格评估并要求其遵守相关法规具体清单见下文</view>
</view>
<view class="smalltitle marginBottom">
3. 第三方SDK清单核心合规项
</view>
<view class="smalltitle marginBottom">
<view class="deviceTitle">(1).地图SDK(com.amap.api.maps),所属公司:北京高德图强科技有限公司,隐私政策链接:https://lbs.amap.com/pages/privacy/</view>
<view class="deviceTitle">(2).定位SDK(com.amap.api.location),所属公司:北京高德图强科技有限公司,隐私政策链接:https://lbs.amap.com/pages/privacy/</view>
<view class="deviceTitle">(3).移动智能终端补充设备标识体系统一调用SDK(com.bun.miitmdid),所属公司:中国信息通信研究院,隐私政策链接:https://www.msa-alliance.cn/col.jsp?id=122</view>
<view class="deviceTitle">(4).轻量版地图SDK(com.amap.api.maps.utils),所属公司:北京高德图强科技有限公司,隐私政策链接:https://lbs.amap.com/pages/privacy/</view>
</view>
<view class="smalltitle">
4. 信息的存储与安全
</view>
<view class="smalltitle">
存储地点原则上我们在中国境内存储您的个人信息
</view>
<view class="smalltitle">
存储期限我们仅为实现服务目的所必需的时限内或法律规定的期限内存储您的信息在您注销账号后我们将在合理期限内删除或匿名化处理您的个人信息
</view>
<view class="smalltitle marginBottom">
安全措施我们采取加密技术访问控制等多种安全措施保护您的信息但请注意任何安全措施都无法做到100%无风险
</view>
<view class="smalltitle">
5. 您的权利
</view>
<view class="smalltitle">
您对自己的个人信息享有以下权利您可以通过如何联系我们章节的渠道向我们提出申请
</view>
<view class="smalltitle">
查询与复制查询和获取您的个人信息副本
</view>
<view class="smalltitle">
更正与删除更正不准确的信息或要求删除您的个人信息
</view>
<view class="smalltitle">
撤回同意设置中关闭相机位置等系统权限撤回对相关功能的信息收集授权
</view>
<view class="smalltitle marginBottom">
注销账号我们提供账号注销功能注销后我们将停止提供服务并处理您的个人信息
</view>
<view class="smalltitle">
6. 隐私政策的更新
</view>
<view class="smalltitle marginBottom">
我们可能会适时更新本政策重大变更如处理目的类型方式发生实质性改变我们会重新以弹窗等方式征得您的同意您可以通过文首的生效日期识别更新情况
</view>
<view class="smalltitle">
7. 如何联系我们
</view>
<view class="smalltitle">
如果您对本政策有任何疑问意见或投诉或需要行使您的个人信息权利请通过以下方式联系我们
请邮件发件至cnxhyc123@163.com我们承诺在15个工作日内回复您的请求
</view>
</view>
</template>
@ -16,10 +116,41 @@
min-height: 100vh;
background-color: rgb(18, 18, 18);
padding: 30rpx;
}
.deviceTitle{
color: rgba(255, 255, 255, 0.87);
color:#ffffffde;
line-height: 45mnrpx;
font-size: 28rpx;
}
.deviceTitle {
margin-bottom: 20rpx;
text-indent: 50rpx;
}
.title {
text-align: center;
}
.smalltitle {
font-size: 14px;
}
.marginBottom {
margin-bottom: 30px;
;
}
.table {
border-collapse: collapse;
width: 100%;
}
.th, .td {
border: 1px solid #ddd;
padding: 8px;
text-align: left;
}
.th {
background-color: #f2f2f2;
}
</style>

View File

@ -46,8 +46,8 @@
<!-- 协议内容 -->
<view class="popup-content">
为了更好的保障您的合法权益请您阅读并同意以下协议
<text class="protocol-link" @click="openProtocol('user')">用户服务协议</text>
<text class="protocol-link" @click="openProtocol('privacy')">隐私政策</text>
<text class="protocol-link" @click="goToPage('agreement')">用户服务协议</text>
<text class="protocol-link" @click="goToPage('privacy')">隐私政策</text>
</view>
<!-- 按钮组 -->
<view class="popup-buttons">

View File

@ -32,6 +32,11 @@
<text class="title">关于我们</text>
<uni-icons type="right" size="25" color="rgba(255, 255, 255, 0.4)" class="uniIcon"></uni-icons>
</view>
<view class="menu-item" @click="logOff">
<image src="/static/images/common/wm.png" class="icon"></image>
<text class="title">注销账号</text>
<uni-icons type="right" size="25" color="rgba(255, 255, 255, 0.4)" class="uniIcon"></uni-icons>
</view>
<view class="menu-item" @click="account">
<image src="/static/images/common/wm.png" class="icon"></image>
<text class="title">账号安全</text>
@ -153,6 +158,11 @@
url: '/pages/common/privacyAgreement/index'
})
},
logOff(){
uni.navigateTo({
url:'/pages/common/user/logOff'
})
},
// 关于我们
aboutUs() {
uni.navigateTo({

View File

@ -0,0 +1,179 @@
<template>
<view class="contentBg maincontent">
<view class="main">
<view class="center">
<image class="img" src="/static/images/6155/DeviceDetail/uploadErr.png" mode="aspectFit"></image>
</view>
<view class="txt" style="margin-top: 30rpx;">
注销账号后账号将永久失效且不可恢复,
</view>
<view class="txt">
并将放弃以下所有权益与服务
</view>
</view>
<view class="ul">
<view class="li">1.账号将无法登陆</view>
<view class="li">2.设备数据全部清除</view>
<view class="li">3.个人资料等内容全部失效</view>
</view>
<view class="footerBtn" @click="showlogOff">
确认注销
</view>
<CustomPopup :show="showPopupFlag" :title="popupTitle" :message="popupMessage"
:icon="ico" :confirm-text="popupConfirmText" :show-cancel="true"
@confirm="onPopupConfirm"
@cancel="onCancel"
:popupBorder="popupBorder" :titleColor="titleColor" :messageColor="messageColor" :confirmBtnBg="confirmBtnBg"
:confirmBtnColor="confirmBtnColor"/>
</view>
</template>
<script>
export default {
data() {
return {
showPopupFlag:false,
popupTitle:'',
popupMessage:'',
ico:'',
popupConfirmText:'',
popupBorder:'',
titleColor:'',
messageColor:'',
confirmBtnBg:'',
confirmBtnColor:'#FFFFFF',
okCallback:null,
cancel:null
}
},
methods: {
onCancel(){
this.showPopupFlag=false;
if(this.cancel){
this.cancel();
}
},
onPopupConfirm(){
this.showPopupFlag=false;
if(this.okCallback){
this.okCallback();
}
},
logOff(){
let task=()=>{
return new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve();
},500)
});
}
let logOut=()=>{
uni.clearStorageSync();
uni.reLaunch({
url:'/pages/common/login/index'
})
}
task().then(res=>{
this.confirm('','您的账号已注销。',logOut,{color:'#AED600',
okTxtColor:'#000000',
ico:'/static/images/common/success.png',
popupBorder:'1px solid rgba(174, 214, 0, 0.3)'},logOut);
});
},
showlogOff(){
this.confirm('','注销后不可恢复,您确认吗?',this.logOff);
},
confirm(title,msg,okCallback,style,cancel){
if(!style){
style={
color:'#E03434',
okTxtColor:'#FFFFFF',
ico:'/static/images/6155/DeviceDetail/warnning.png',
popupBorder:'1px solid rgba(224, 52, 52, 0.3)'
}
}
this.showPopupFlag=true;
this.popupTitle=title;
this.popupMessage=msg;
this.ico=style.ico?style.ico:'';
this.popupConfirmText='确认';
this.popupBorder=style.popupBorder;
this.titleColor=style.color?style.color:'#E03434';
this.messageColor=style.color?style.color:'#E03434';
this.confirmBtnBg=style.color?style.color:'#E03434'
this.confirmBtnColor=style.okTxtColor?style.okTxtColor:'#FFFFFF';
this.okCallback=okCallback;
this.cancel=cancel;
},
}
}
</script>
<style>
.footerBtn{
width:calc(100% - 60rpx);
height: 90rpx;
left: 30rpx;
bottom: 96rpx;
position: fixed;
z-index: 1;
border-radius: 90rpx;
background: rgba(224, 52, 52, 1);
color: rgba(255, 255, 255, 0.87);
font-family: PingFang SC;
font-size: 32rpx;
font-weight: 400;
line-height: 90rpx;
letter-spacing: 0px;
text-align: center;
}
.ul{
width: calc(100% - 120rpx);
height: auto;
border-radius: 8px;
background: #1a1a1a;
color: rgba(255, 255, 255, 0.6);
box-sizing: border-box;
font-family: PingFang SC;
font-size: 28rpx;
font-weight: 400;
line-height: 50rpx;
letter-spacing: 0.14rpx;
text-align: left;
padding: 20rpx;
margin-left: 60rpx;
}
.txt{
text-align: center;
color: #FFFFFF;
font-family: PingFang SC;
font-size: 28rpx;
font-weight: 400;
line-height: 40rpx;
letter-spacing: 0.14rpx;
white-space: nowrap;
}
.img{
width:95rpx;
height: 95rpx;
}
.main{
width: 100%;
height: auto;
box-sizing: border-box;
padding:100rpx 100rpx 40rpx 100rpx ;
margin-bottom: 36rpx;
}
</style>

View File

@ -1,7 +1,127 @@
<template>
<view class="device-page">
<view class="deviceTitle">欢迎你使用我们的产品和服务!本用户协议(以下简称"协议")由你(以下简称"用户")[公司名称](以下简称"我们""本公司")就使用[产品名称]的相关事宜共同订立
欢迎你使用我们的产品和服务!本用户协议(以下简称"协议")由你(以下简称"用户")[公司名称](以下简称"我们""本公司")就使用[产品名称]的相关事宜共同订立</view>
<view class="title marginBottom">应用服务协议</view>
<view class="threeTitle marginBottom">
请仔细阅读以下协议内容使用本应用即表示您同意接受本协议所有条款
</view>
<view class="deviceTitle textLeft">
<view class="threeTitle ">应用名称</view>
<view class="">星汉物联</view>
</view>
<view class="deviceTitle textLeft">
<view class="threeTitle ">公司名称</view>
<view class="">湖北星汉研创科技有限公司</view>
</view>
<view class="deviceTitle textLeft">
<view class="threeTitle ">更新日期</view>
<view class="">2025-09-25</view>
</view>
<view class="deviceTitle marginBottom textLeft">
<view class="threeTitle ">生效日期</view>
<view class="">自用户安装本应用之日起</view>
</view>
<view class="secondTitle">
1.总则
</view>
<view class="threeTitle">1.1 协议确认</view>
<view class="deviceTitle marginBottom">
服务协议以下简称"本协议"是您以下简称"用户"与湖北星汉研创科技有限公司以下简称"我们""公司"之间关于下载安装使用本安卓应用程序以下简称"本应用"所订立的协议</view>
<view class="threeTitle">1.2 同意接受</view>
<view class="deviceTitle marginBottom">请用户仔细阅读本协议特别是免除或限制责任的条款隐私条款等用户安装使用本应用即表示已阅读并同意接受本协议所有条款的约束</view>
<view class="secondTitle">
2.用户权利与义务
</view>
<view class="threeTitle">2.1 合法使用</view>
<view class="deviceTitle marginBottom">用户必须遵守中华人民共和国相关法律法规及国际惯例不得利用本应用进行任何违法或不正当活动</view>
<view class="threeTitle">2.2 信息真实</view>
<view class="deviceTitle marginBottom">用户需保证所提供的注册信息真实准确完整并及时更新因信息不实引起的任何问题由用户自行承担</view>
<view class="threeTitle">2.3 责任承担</view>
<view class="deviceTitle marginBottom">用户应对其账户下发生的一切活动承担法律责任</view>
<view class="secondTitle">
3.服务内容与变更
</view>
<view class="threeTitle">3.1 服务内容</view>
<view class="deviceTitle marginBottom">我们通过本应用向用户提供服务 <view class="red">
该App适配本公司的智能设备核心功能是远程控制设备可通过蓝牙和4G通信给设备发送远程操作指令实现对设备的灯光开关亮度调整探测档位设备发送警报也可以反向接收数据上报的警报信息实时看设备状态满足设备管理与操作需求
</view>
</view>
<view class="threeTitle">3.2 服务变更</view>
<view class="deviceTitle marginBottom">我们有权根据业务需要调整服务内容功能或暂停部分服务并将提前通过应用内通知公告等方式告知用户</view>
<view class="secondTitle">
4.隐私保护
</view>
<view class="threeTitle">4.1 隐私政策</view>
<view class="deviceTitle marginBottom">我们承诺依法保护用户个人信息具体政策详见隐私政策隐私政策为本协议不可分割的一部分</view>
<view class="threeTitle">4.2 信息使用</view>
<view class="deviceTitle marginBottom">在未经用户同意的情况下我们不会向第三方提供用户的个人信息除非
<view>(1)法律法规要求</view>
<view>(2)为保护社会公共利益</view>
<view>(3)为用户提供所要求的服务所必需</view>
</view>
<view class="secondTitle">
5.免责声明
</view>
<view class="threeTitle">5.1 不可抗力</view>
<view class="deviceTitle marginBottom">因不可抗力包括但不限于自然灾害政府行为网络攻击等导致的服务中断或数据丢失我们不承担责任</view>
<view class="threeTitle">5.2 间接损失</view>
<view class="deviceTitle marginBottom">用户因使用本应用而遭受的任何间接损失我们不予赔偿</view>
<view class="threeTitle">5.3 服务保证</view>
<view class="deviceTitle marginBottom">我们不保证服务的及时性安全性和准确性也不对第三方通过本应用发布的内容承担责任</view>
<view class="secondTitle">
6.知识产权
</view>
<view class="threeTitle">6.1 内容保护</view>
<view class="deviceTitle marginBottom">本应用的所有内容包括但不限于文字图像图标音频软件等均受著作权法商标法和其他知识产权法律的保护</view>
<view class="threeTitle">6.2 使用限制</view>
<view class="deviceTitle marginBottom">未经我们明确书面许可用户不得复制修改传播本应用的任何内容</view>
<view class="secondTitle">
7.协议的变更与终止
</view>
<view class="threeTitle">7.1 协议变更</view>
<view class="deviceTitle marginBottom">我们有权根据需要修改本协议修改后的协议将在应用内公布后生效用户继续使用本应用即表示接受修改后的协议</view>
<view class="threeTitle">7.2 协议终止</view>
<view class="deviceTitle marginBottom">用户可随时停止使用本应用如果我们认为用户违反本协议有权暂停或终止向该用户提供服务</view>
<view class="secondTitle">
8.其他
</view>
<view class="threeTitle">8.1 生效时间</view>
<view class="deviceTitle marginBottom">本协议自用户安装本应用之日起生效</view>
<view class="threeTitle">8.2 标题解释</view>
<view class="deviceTitle marginBottom">本协议所有条款的标题仅为阅读方便不影响条款的解释</view>
<view class="threeTitle">8.3 权利放弃</view>
<view class="deviceTitle marginBottom">如果我们未能行使本协议中的任何权利不构成对该权利的放弃</view>
</view>
</template>
@ -16,10 +136,38 @@
min-height: 100vh;
background-color: rgb(18, 18, 18);
padding: 30rpx;
}
.deviceTitle{
color: rgba(255, 255, 255, 0.87);
line-height: 45mnrpx;
font-size: 28rpx;
font-size: 26rpx;
}
.deviceTitle {}
.title {
font-size: 50rpx;
text-align: center
}
.secondTitle {
font-size: 35rpx;
}
.threeTitle {
font-size: 30rpx;
}
.marginBottom {
margin-bottom: 30px;
;
}
.textLeft{
display: flex;
flex-direction: row;
flex-wrap: nowrap;
align-content: center;
align-items: center;
justify-content: flex-start;
}
</style>

View File

@ -36,13 +36,13 @@ class BleHelper {
linkedDevices = uni.getStorageSync(this.StorageKey);
}
if (linkedDevices && linkedDevices.length && linkedDevices.length > 0) {
// console.log("111111", linkedDevices);
console.log("111111", linkedDevices);
linkedDevices = linkedDevices.filter((v) => {
if (v) {
v.Linked = false;
v.notifyState = false;
}
return v ? true : false;
return v.device ? true : false;
});
}
@ -51,12 +51,7 @@ class BleHelper {
setTimeout(() => {
this.OpenBlue().then(() => {
this.linkAllDevices();
});
}, 10);
this.data = {
isOpenBlue: false, //蓝牙模块是否开启
available: false, //蓝牙状态是否可用
@ -64,7 +59,8 @@ class BleHelper {
searchList: [], //已搜索到的设备列表,
isSubscribe: false, //是否开启了订阅
LinkedList: linkedDevices, //已连接的设备列表
platform: systemInfo.uniPlatform
platform: systemInfo.uniPlatform,
Disconnect:[]//主动断开的设备
}
this.cfg = {
onDeviceFound: [], //发现新设备的事件
@ -77,6 +73,14 @@ class BleHelper {
this.addReceiveCallback((receive, f, path, recArr) => {
recei.ReceiveData(receive, f, path, recArr);
}, "BleReceiveData");
setTimeout(() => {
this.OpenBlue().then(() => {
this.linkAllDevices();
});
}, 10);
this.dic = {
errRemarks: [{
key: '10000',
@ -145,7 +149,7 @@ class BleHelper {
let item = this.data.LinkedList[i];
if (deviceId && item.device) {
if (item.device.id == deviceId) {
console.log("找到要删除的设备", item);
console.error("找到要删除的设备", item);
this.data.LinkedList.splice(i, 1);
this.disconnectDevice(item.deviceId);
flag = true;
@ -154,7 +158,7 @@ class BleHelper {
} else {
if (bleId && item.deviceId == bleId) {
console.log("找到要删除的设备1,", item)
console.error("找到要删除的设备1,", item)
this.data.LinkedList.splice(i, 1);
this.disconnectDevice(item.deviceId);
flag = true;
@ -505,8 +509,7 @@ class BleHelper {
console.log("开始订阅各类变化消息");
this.data.isSubscribe = true;
// 保存每个设备的连接状态
let bleDeviceStates = {};
var bytesToHexString = (bytes) => {
@ -515,13 +518,13 @@ class BleHelper {
}
let adapterStateTime=null;
uni.onBluetoothAdapterStateChange((state) => {
clearTimeout(adapterStateTime);
setTimeout(()=>{
if(this.data.discovering === state.discovering && this.data.available===state.available){
console.error("专业给Uniapp填坑,适配器状态错误");
console.error("专业给Uniapp填坑,适配器状态重复回调");
return;
}
clearTimeout(adapterStateTime);
setTimeout(()=>{
console.log('蓝牙模块状态发生变化:' + JSON.stringify(state));
this.data.discovering = state.discovering;
@ -558,10 +561,7 @@ class BleHelper {
return true;
});
// let keys = Object.keys(bleDeviceStates)
// keys.filter(v => {
// bleDeviceStates[v] = false;
// });
this.cfg.stateBreakCallback.forEach(f => {
try {
@ -585,13 +585,16 @@ class BleHelper {
uni.onBLEConnectionStateChange((res) => {
console.log("蓝牙连接状态变化了", res);
// 检查状态是否真的发生了变化
if (bleDeviceStates[res.deviceId] === res.connected) {
console.error('专业给Uniapp填坑,连接状态重复回调');
let ble=this.data.LinkedList.find(dev=>{
return res.deviceId===dev.deviceId;
});
if(ble){
if(ble.Linked===res.connected){
return;
}
}
// 更新状态记录
bleDeviceStates[res.deviceId] = res.connected;
setTimeout(() => {
if (!res.connected) {
@ -608,6 +611,11 @@ class BleHelper {
});
this.updateCache();
if (f && f.device && f.device.id && this.data.available) {
let fdis=this.data.Disconnect.find(dis=>{
return dis===res.deviceId
});//用户主动断开的,不再重连
if(!fdis){
res.device=f.device;
console.log("蓝牙状态可用,尝试5次恢复连接,", f
.deviceId);
this.LinkBlue(res.deviceId, f
@ -616,8 +624,10 @@ class BleHelper {
.notifyCharactId, 5);
}
if (this.cfg.bleDisposeCallback.length >
0) {
}
if (this.cfg.bleDisposeCallback.length >0) {
this.cfg.bleDisposeCallback.forEach(
(c) => {
try {
@ -638,7 +648,7 @@ class BleHelper {
}, 0);
});
console.log("111111111")
uni.onBluetoothDeviceFound((res) => {
//console.log("发现新设备:" + JSON.stringify(res,'name'));
let arr = [];
@ -828,10 +838,12 @@ class BleHelper {
// console.log("有人订阅消息111", )
if (rec.callback) {
try {
// console.log("正在处理订阅消息",rec);
rec.callback(recData, f,
path, this.cfg
.receivDataCallback
);
// console.log("处理订阅消息完毕");
} catch (err) {
console.error(
"订阅消息出现异常",
@ -1500,6 +1512,13 @@ class BleHelper {
}
this.updateCache();
//主动连接某个设备时,从主动断开中删除
this.data.Disconnect.find((c,index)=>{
if(c===deviceId){
this.data.Disconnect.splice(index,1);
return true;
}
})
// console.log("LinkedList=", this.data
// .LinkedList);
@ -1654,6 +1673,7 @@ class BleHelper {
success: (res) => {
console.log("用户主动断开了蓝牙:" + id);
this.subScribe(id, false);
this.data.Disconnect.push(id);
resolve();
},
fail: (ex) => {
@ -1845,7 +1865,7 @@ class BleHelper {
Promise.race([timeOut(ms), promise]).then(resolve).catch((ex) => {
// console.error("ex=", ex);
if (ex.code == -1) {
console.error('专业给Uniapp填坑,发送消息永无回调');
// console.error('专业给Uniapp填坑,发送消息永无回调');
resolve(ex);
} else {
reject(ex);

View File

@ -256,7 +256,7 @@ class BleReceive {
}
Receive_670(receive, f, path, recArr) {
console.log("pagh=", path);
// console.log("pagh=", path);
var todo = (bytes) => {
// console.log("todo",receive);
let receiveData = {};
@ -283,8 +283,8 @@ class BleReceive {
// console.log("todo");
// 解析照明档位
let lightingLevelByte = bytes[2];
let lightingLevelText = lightingLevelByte === 0x6d ? 'hight' : lightingLevelByte === 0x6e ?
'low' : 'close';
let lightingLevelText = lightingLevelByte === 0x6d ? 'qiang' : lightingLevelByte === 0x6e ?
'ruo' : 'close';
// 解析剩余照明时间(第三和第四字节,小端序)
let lightingTime = (bytes[3] << 8) | bytes[4];

169
utils/MqHelper.js Normal file
View File

@ -0,0 +1,169 @@
import MqttClient from '@/utils/mqtt.js';
class MqHelper {
constructor() {
this.instance = null;
this.subTopics=[];
}
timeout(ms) {
if (!ms) {
ms = 200;
}
return new Promise((succ, err) => {
setTimeout(() => {
err({
code: -1,
errMsg: '超时了'
})
}, ms);
});
}
//打开mq连接,topics:要订阅的主题列表格式{topic:'主题',callback:fn}或此格式的数组
init(topics) {
let connect = () => {
return new Promise((resolve, reject) => {
this.instance = new MqttClient();
this.instance.connect((res) => {
if(topics){
console.error("连接成功开始订阅消息",topics);
setTimeout(this.subscribes, 50, topics)
}
resolve();
});
});
}
let p1 = connect();
let p2 = this.timeout(500);
return new Promise((resolve, reject) => {
Promise.race([p1, p2]).then(()=>{
resolve()
}).catch(ex=>{
this.instance=null;
reject(ex);
});
});
}
//订阅消息
subscribes(topics) {
return new Promise((resolve,reject)=>{
if(!this.instance || !topics){
reject();
return;
}
if (!Array.isArray(topics)) {
topics = [topics];
}
for (let i = 0; i < topics.length; i++) {
let item = topics[i];
let f=this.subTopics.find(v=>{
return v.topic===item.topic;
});
if(!f){
this.subTopics.push(item);
}
this.instance.subscribe(item.topic, (payload, receive) => {
try {
console.log("开始处理回调")
item.callback({payload:payload,receive:receive});
console.log("处理回调成功")
} catch (err) {
console.error("订阅消息回调出现异常,",err);
}
});
console.error("订阅消息成功");
}
resolve();
});
}
//取消订阅消息 单个或者数组
unSubscribes(topics){
if(!this.instance || !topics){
return;
}
if (!Array.isArray(topics)) {
topics = [topics];
}
for (let i = 0; i < topics.length; i++) {
let item = topics[i];
this.instance.unsubscribe(item.topic);
this.subTopics.find((v,index)=>{
if(v.topic===item.topic){
this.subTopics.splice(index,1);
return true;
}
return false;
});
}
}
//发送消息,主题 消息内容 是否保留消息
sendData(topic,msg,retained){
return new Promise((resolve,reject)=>{
if(!this.instance || !topic){
reject("MQTT未连接或无主题无法发布消息")
return
}
if(msg===null || msg===undefined){
reject("msg无内容")
return;
}
if(!retained){
retained=false;
}else{
retained=true;
}
try {
let flag = this.instance.publish(topic, msg, retained);
if (flag) {
resolve({
code: 200,
msg: 'MQTT直连发送成功'
});
return;
}
reject("MQTT未连接无法发布消息");
} catch (error) {
reject(error);
}
});
}
//断开连接
disconnect(){
if(!this.instance){
return
}
this.instance.disconnect()
}
}
export default {
getMqTool: function(found, receive) {
let instance = new MqHelper();
return instance;
}
}

View File

@ -281,11 +281,17 @@ class MqttClient {
}
}
publish(topic, message) {
publish(topic, message,retained) {
if (this.client && this.client.isConnected()) {
const mqttMessage = new Paho.Message(message);
mqttMessage.destinationName = topic;
mqttMessage.qos = 1;
console.log("typeof(retained)=",typeof(retained))
if(typeof(retained)==='boolean'){
console.log("retained=",retained)
mqttMessage.retained=retained;
}
this.client.send(mqttMessage);
console.log(`成功发布消息到主题 ${topic}: ${message}`);
return true;