Files
APP/pages/6155/BJQ6155.vue
2026-02-04 09:08:59 +08:00

2321 lines
56 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<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" :class="{'visibilityHidden':Status.apiType!=item.apiType}" @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>
</view>
<view class="rightTxt">
<view class="row">
<image class="img" src="/static/images/6155/DeviceDetail/battry.png" mode="aspectFit"></image>
<view class="txt">
<view class="bigTxt">{{formData.battary}}%</view>
<view class="smallTxt">电量</view>
</view>
</view>
<view class="row">
<image class="img" src="/static/images/6155/DeviceDetail/time.png" mode="aspectFit"></image>
<view class="txt">
<view class="bigTxt">{{formData.xuhang}}</view>
<view class="smallTxt">续航时间</view>
</view>
</view>
</view>
</view>
<view class="eqinfo">
<view class="item">
<text class="lbl">设备名称</text>
<text class="value">{{device.deviceName}}</text>
</view>
<view class="item">
<text class="lbl">Mac地址</text>
<text class="value">{{device.deviceMac}}</text>
</view>
<view class="item">
<text class="lbl">设备状态</text>
<text class="value">{{formData.statu}}</text>
</view>
<view class="item">
<text class="lbl">蓝牙名称</text>
<text class="value">{{device.bluetoothName}}</text>
</view>
<view class="item">
<text class="lbl">蓝牙状态</text>
<text class="value" :class="formData.bleStatu?'green':'red'">{{formData.bleStatu?'已连接':'未连接'}}</text>
</view>
</view>
<view class="lamp">
<view class="title">
<text>灯光亮度</text>
<text>{{formData.liangDu}}%</text>
</view>
<view class="slider-container">
<slider min="1" max="100" step="1" :disabled="false" :value="formData.liangDu" activeColor="#bbe600"
backgroundColor="#00000000" block-size="20" block-color="#ffffffde" @change="sliderChange"
@changing="sliderChange" class="custom-slider" />
</view>
</view>
<view class="lampMode">
<view class="mode fleft" v-on:click.stop="ModeSetting('main')">
<view class="leftImg">
<image class="img" src="/static/images/6155/DeviceDetail/mainLamp.png" mode="aspectFit"></image>
</view>
<view class="rightTxt">
<text class="bigTxt">主灯模式</text>
<text class="smallTxt">{{getMode('main')}}</text>
</view>
</view>
<view class="mode marginLeft fleft" v-on:click.stop="ModeSetting('fu')">
<view class="leftImg">
<image class="img" src="/static/images/6155/DeviceDetail/fuLamp.png" mode="aspectFit"></image>
</view>
<view class="rightTxt">
<text class="bigTxt">辅灯模式</text>
<text class="smallTxt">{{getMode('fu')}}</text>
</view>
</view>
<view class="mode fleft" v-on:click.stop="UploadOpenImg()">
<view class="leftImg">
<image class="img" src="/static/images/6155/DeviceDetail/open.png" mode="aspectFit"></image>
</view>
<view class="rightTxt">
<text class="bigTxt">开机画面</text>
<text class="smallTxt">上传</text>
</view>
</view>
<view class="mode marginLeft fleft" v-on:click.stop="UploadOpenVideo()">
<view class="leftImg">
<image class="img" src="/static/images/common/video.png" mode="aspectFit"></image>
</view>
<view class="rightTxt">
<text class="bigTxt">开机视频</text>
<text class="smallTxt">上传</text>
</view>
</view>
<view class="clear"></view>
</view>
<view class="usrinfo">
<view>
<text class="usrtitle fleft">人员信息登记</text>
<view class="btnSend fright" v-on:click.stop="sendUsr">发送</view>
<view class="clear"></view>
<TextToHexV1 class="TextToHex" ref="textToHex" :txts="formData.textLines" :bgColor="'#FFFFFF'"
:color="'#000000'" :fontSize="16" />
</view>
<view class="item">
<text class="lbl">单位</text>
<input class="value" v-model.trim="formData.textLines[0]" placeholder="请输入单位"
placeholder-class="usrplace" />
</view>
<view class="item">
<text class="lbl">部门</text>
<input class="value" v-model.trim="formData.textLines[1]" placeholder="请输入姓名"
placeholder-class="usrplace" />
</view>
<view class="item">
<text class="lbl">姓名</text>
<input class="value" v-model.trim="formData.textLines[2]" placeholder="请输入职位"
placeholder-class="usrplace" />
</view>
</view>
<view class="proinfo lamp">
<text class="title">产品信息</text>
<view class="itemcontent">
<view class="item" @click="proParam()">
<image class="img" src="/static/images/6155/DeviceDetail/param.png" mode="aspectFit"></image>
<text class="txt">产品参数</text>
</view>
<view class="item" @click="handRemark()">
<image class="img" src="/static/images/6155/DeviceDetail/remark.png" mode="aspectFit"></image>
<text class="txt">操作说明</text>
</view>
<view class="item" @click="handVideo()">
<image class="img" src="/static/images/6155/DeviceDetail/video.png" mode="aspectFit"></image>
<text class="txt">操作视频</text>
</view>
</view>
</view>
<!-- 弹窗通知 -->
<MessagePopup :visible="Status.Pop.showPop" :type="Status.Pop.popType" :bgColor="Status.Pop.bgColor"
:borderColor="Status.Pop.borderColor" :textColor="Status.Pop.textColor"
:buttonBgColor="Status.Pop.buttonBgColor" :buttonTextColor="Status.Pop.buttonTextColor"
:iconUrl="Status.Pop.iconUrl" :message="Status.Pop.message" :buttonText="Status.Pop.buttonText"
@buttonClick="HidePop" @closePop="closePop" :visiblePrompt="Status.Pop.visiblePrompt"
:promptTitle="Status.Pop.promptTitle" v-model="Status.Pop.modelValue" />
<!-- 下方菜单 -->
<BottomSlideMenuPlus :config="Status.BottomMenu" @close="closeMenu" @itemClick="handleItemClick"
@btnClick="btnClick">
<view class="addIco">
<view class="icoContent center" v-on:click.stop="checkImgUpload()">
<image mode="aspectFit" class="img" src="/static/images/6155/DeviceDetail/add.png"></image>
</view>
</view>
</BottomSlideMenuPlus>
<global-loading ref="loading" />
</view>
</template>
<script>
import TextToHexV1 from '@/components/TextToHex/TextToHexV1.vue';
import bleTool from '@/utils/BleHelper.js';
import usrApi from '@/api/670/HBY670.js'
import Common from '@/utils/Common.js';
import {
showLoading,
hideLoading,
updateLoading
} from '@/utils/loading.js'
import BleReceive from '@/utils/BleReceive';
import {
baseURL
} from '@/utils/request.js';
var pagePath = "/pages/6155/BJQ6155";
var ble = null;
var these = null;
var BrighInteval = null;
var recei = null;
export default {
components: {
TextToHexV1
},
data() {
return {
Status: {
apiType: '',
navbar: {
icons: [{
src: '/static/images/common/shape.png',
callback: this.gotoShare,
apiType:'listA'
}],
title: 'BJQ6155'
},
lightMode: {
},
pageHide: false,
Pop: {
showPop: false, //是否显示弹窗
popType: 'custom',
textColor: '#ffffffde',
bgColor: '#383934bd',
borderColor: '#BBE600',
buttonBgColor: '#BBE600',
buttonTextColor: '#232323DE',
iconUrl: '',
message: '您确定要这样做吗?',
buttonText: '确定',
clickEvt: '',
visiblePrompt: false,
promptTitle: '设备名称',
modelValue: '',
visibleClose: false,
okCallback: null
},
BottomMenu: {
show: false,
showHeader: true,
menuItems: [],
activeIndex: -1,
bgColor: '#2a2a2a',
itemBgColor: '#3a3a3a',
textColor: '#ffffffde',
textAlign: 'flex-start',
title: '主灯模式',
showDivider: false,
dividerColor: '#00000000',
dividerThickness: '0rpx',
dividerMargin: '10rpx',
itemHeight: '80rpx',
type: '',
showBtn: true,
btnBgColor: "#bbe600",
btnText: "确定",
btnTextColor: "#232323de",
showMask: true,
maskBgColor: '#00000066',
showClose: false
}
},
formData: {
img: '/static/images/common/HBY6155.png',
battary: '',
xuhang: '',
deviceName: '',
RSSI: '',
statu: '正常',
liangDu: '100',
id: '',
deviceId: '',
textLines: ['', '', ''],
mode: '',
light: null,
bleStatu: ''
},
inteval: 80,
device: {
id: "",
deviceName: "",
deviceImei: "",
deviceMac: "",
communicationMode: 0,
devicePic: "",
typeName: "",
bluetoothName: null,
deviceStatus: null,
bindingTime: "",
onlineStatus: 0,
battery: "0",
latitude: null,
longitude: null,
alarmStatus: null,
detailPageUrl: "/pages/6155/deviceDetail",
showConfirm: false
},
videoHexArray: [],
rgb565Data: [],
permissions: [],
dic: {
menuItems: [{
text: '强光',
icon: '/static/images/6155/DeviceDetail/qiang.png',
math: 100,
type: 'main'
},
{
text: '弱光',
icon: '/static/images/6155/DeviceDetail/ruo.png',
math: 50,
type: 'main'
},
{
text: '爆闪',
icon: '/static/images/6155/DeviceDetail/shan.png',
math: 30,
type: 'main'
},
{
text: '关闭',
icon: '/static/images/6155/DeviceDetail/close.png',
math: 0,
type: 'main'
},
{
text: '泛光',
icon: '/static/images/6155/DeviceDetail/fan.png',
math: 100,
type: 'fu'
},
{
text: '强+泛光',
icon: '/static/images/6155/DeviceDetail/fan.png',
math: 70,
type: 'fu'
}
]
}
}
},
onUnload() {
ble.removeAllCallback(pagePath);
},
onLoad: function() {
these = this;
recei = BleReceive.getBleReceive();
ble = bleTool.getBleTool();
ble.addReceiveCallback(these.bleValueNotify, pagePath);
ble.addStateBreakCallback(these.bleStateBreak, pagePath);
ble.addStateRecoveryCallback(these.bleStateRecovry, pagePath);
ble.addDisposeCallback(these.deviceDispose, pagePath);
ble.addRecoveryCallback(these.deviceRecovry, pagePath);
let eventChannel = this.getOpenerEventChannel();
eventChannel.on('detailData', function(data) {
let device = data.data;
these.device = device;
these.Status.apiType = data.apiType;
these.Status.navbar.title=device.deviceName;
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(',');
}
}
});
}
let f = ble.data.LinkedList.find((v) => {
if (v.macAddress == device.deviceMac) {
console.log("找到设备了", v);
these.formData.deviceId = v.deviceId;
return true;
}
return false;
});
if (!f) {
these.getDetail();
these.showBleUnConnect();
return;
}
let form = f.formData;
if (form) {
let keys = Object.keys(form);
for (var i = keys.length; i >= 0; i--) {
let key = keys[i];
these.formData[key] = form[key];
}
}
these.formData.blename = f.name ? f.name : "Unname";
these.formData.deviceName = device.deviceName;
these.formData.id = device.id;
these.formData.deviceId = f.deviceId;
these.formData.bleStatu = false;
ble.LinkBlue(f.deviceId, f.writeServiceId, f.wirteCharactId, f.notifyCharactId).then(res => {
these.formData.bleStatu = true;
});
these.setBleFormData();
these.getDetail();
});
},
onHide: function() {
this.Status.pageHide = true;
},
onShow() {
this.Status.pageHide = false;
},
onBackPress(e) {
ble.removeReceiveCallback();
},
computed: {
cModeItems: function() {
}
},
methods: {
handleRightClick(item, s) {
if (item && item.callback) {
item.callback(item, s);
} else {
uni.showModal({
content: '敬请期待'
})
}
},
navigatorBack() {
uni.navigateBack();
},
gotoShare(item, s) {
uni.navigateTo({
url: '/pages/common/share/index',
events: {
ack: function(data) {}
},
success: (res) => {
let json = {
persissonType: '6155'
};
Object.assign(json, this.device);
res.eventChannel.emit('share', {
data: json
});
}
})
},
getMode(type) {
let txt = "关闭";
switch (this.formData.light) {
case 0:
if (type == 'fu' && this.formData.mode == 'fu') {
txt = '泛光';
} else if (type == 'main' && this.formData.mode == 'main') {
txt = "强光";
}
break;
case 1:
if (type == 'fu' && this.formData.mode == 'fu') {
txt = '强+泛光';
} else if (type == 'main' && this.formData.mode == 'main') {
txt = "弱光";
}
break;
case 2:
if (type == 'main' && this.formData.mode == 'main') {
txt = "爆闪";
}
break;
case 3:
if (type == 'main' && this.formData.mode == 'main') {
txt = "关闭";
}
break;
default:
txt = "关闭";
break;
}
return txt;
},
calcTotalPackets(frames) {
if (!Array.isArray(frames) || frames.length === 0) {
return 0;
}
return frames.reduce((frameSum, frame) => {
if (!Array.isArray(frame)) {
return frameSum;
}
const packSum = frame.reduce((packAcc, pack) => {
if (!Array.isArray(pack)) {
return packAcc;
}
return packAcc + pack.length;
}, 0);
return frameSum + packSum;
}, 0);
},
deviceRecovry(res) {
if (this.Status.pageHide) {
return;
}
if (res.deviceId == these.formData.deviceId) {
this.formData.bleStatu = true;
setTimeout(() => {
hideLoading(these, 1000);
});
uni.showToast({
icon: 'success',
title: '蓝牙连接成功'
});
}
},
deviceDispose(res) {
if (this.Status.pageHide) {
return;
}
if (res.deviceId == these.formData.deviceId) {
this.formData.bleStatu = false;
setTimeout(() => {
hideLoading(these, 1000);
});
uni.showToast({
icon: 'fail',
title: '蓝牙连接已断开'
});
}
},
bleStateBreak() {
if (this.Status.pageHide) {
return;
}
//蓝牙适配器不可用
this.formData.bleStatu = false;
uni.showToast({
icon: 'fail',
title: '蓝牙已不可用'
})
hideLoading(this);
},
bleStateRecovry() {
console.log("蓝牙可用");
if (this.Status.pageHide) {
return;
}
console.log("蓝牙可用");
//蓝牙适配器再次可用,尝试恢复连接
showLoading(this, {
text: "蓝牙恢复可用,正在连接设备"
});
ble.LinkBlue(these.formData.deviceId).then(() => {
these.formData.bleStatu = true;
updateLoading(these, {
text: '连接成功'
});
}).catch(ex => {
updateLoading(these, {
text: ex.msg
})
}).finally(() => {
setTimeout(() => {
hideLoading(these);
}, 1000);
});
},
previewImg(img) {
if (!img) {
return;
}
uni.previewImage({
urls: [img]
})
},
getDevice: function() {
// console.log("LinkedList=", ble.data.LinkedList);
// console.log("formData=", these.formData);
let f = ble.data.LinkedList.find((v) => {
return v.macAddress == these.device.deviceMac;
});
return f;
},
bleValueNotify: function(receive, device, path, recArr) {
if (receive.deviceId !== this.formData.deviceId) {
return;
}
if (this.Status.pageHide) {
return;
}
let json = recei.ReceiveData(receive, device, path, recArr);
if (!json) {
return;
}
console.log("收到原始数据:", receive);
console.log("解析设备数据:", json);
let keys = Object.keys(json);
keys.forEach((key) => {
if (key in these.formData) {
// 确保响应式更新
// console.log(`更新字段 ${key}: ${these.formData[key]} -> ${json[key]}`);
these.$set(these.formData, key, json[key]);
} else {
console.log(`字段 ${key} 不在 formData 中,跳过更新`);
}
});
// 强制触发视图更新,确保电量显示同步
these.$forceUpdate();
// console.log("更新后的电量:", these.formData.battary);
if (this.formData.battary <= 20) {
this.showPop({
message: "设备电量低",
iconUrl: "/static/images/6155/DeviceDetail/uploadErr.png",
borderColor: "#e034344d",
buttonBgColor: "#E03434",
});
}
},
proParam: function() {
uni.navigateTo({
url: '/pages/common/productDes/index?id=' + this.device.id,
success(ev) {
}
});
},
handRemark: function() {
uni.navigateTo({
url: '/pages/common/operatingInstruct/index?id=' + this.device.id,
success(ev) {
}
});
},
handVideo: function() {
uni.navigateTo({
url: '/pages/common/operationVideo/index?id=' + this.device.id,
success(ev) {
}
});
},
showBleUnConnect() {
this.showPop({
message: "蓝牙未连接过该设备,请使用蓝牙重新添加该设备",
iconUrl: "/static/images/6155/DeviceDetail/uploadErr.png",
borderColor: "#e034344d",
buttonBgColor: "#E03434",
buttonText: '去连接',
buttonTextColor: '#232323de',
okCallback: function() {
// console.log("1111");
uni.navigateTo({
url: "/pages/common/addBLE/addEquip",
events: {
BindOver: function(data) {
console.log(data)
these.formData.bleStatu = true;
}
},
success: function(res) {
// 通过eventChannel向被打开页面传送数据
res.eventChannel.emit('detailData', {
data: these.device
})
},
fail(ex) {
console.log("跳转失败", ex);
}
})
}
});
},
checkImgUpload: function() {
let f = these.getDevice();
if (!f) {
these.showBleUnConnect();
return;
}
// 分包发送图片数据
var sendImagePackets = function(ReSendNo) {
return new Promise((resolve, reject) => {
// 总数据包数
let totalPackets = 52;
let currentPacket = 1;
if (ReSendNo) {
totalPackets = ReSendNo;
currentPacket = ReSendNo;
}
if (f) {
// 发送单个数据包
const sendNextPacket = () => {
if (currentPacket > totalPackets) {
hideLoading(these);
these.Status.BottomMenu.show = false;
these.showPop({
showPop: true,
message: "上传成功",
iconUrl: "/static/images/common/success.png",
});
ble.sendString(f.deviceId, "transmit complete", f.writeServiceId, f
.wirteCharactId);
these.rgb565Data = null;
resolve();
return;
}
// 计算当前包的数据
let packetSize = 250;
// if (currentPacket <= 51) {
// packetSize = 250; // 前51个包每个500字节
// } else {
// packetSize = 50; // 最后一个包100字节
// }
// 创建数据包
const startIndex = (currentPacket - 1) * packetSize;
const endIndex = Math.min(startIndex + packetSize, these.rgb565Data
.length);
if (startIndex > endIndex) {
return;
}
const packetData = these.rgb565Data.slice(startIndex,
endIndex);
// 构建数据包
const bufferSize = 505; // 5 + packetData.length * 2; // 头部5字节 + 数据部分
const buffer = new ArrayBuffer(bufferSize);
const dataView = new DataView(buffer);
// 填充头部
dataView.setUint8(0, 0x55); // 帧头
dataView.setUint8(1, 0x02); // 帧类型:开机画面
dataView.setUint8(2, '0x' + currentPacket.toString(16).padStart(2,
'0')); // 包序号
if (packetData.length == 250) {
dataView.setUint8(3, 0x01);
dataView.setUint8(4, 0xF4);
} else {
dataView.setUint8(3, 0x00);
dataView.setUint8(4, 0x64);
}
// 填充数据每个RGB565值占2字节
for (let i = 0; i < packetData.length; i++) {
dataView.setUint16(5 + i * 2, packetData[i], false); // 大端字节序
}
if (currentPacket > 51) { //第52包补FF
for (var i = 105; i < bufferSize; i++) {
dataView.setUint8(i, 0xFF);
}
}
//发送数据包
ble.sendData(f.deviceId, buffer, f.writeServiceId, f.wirteCharactId,
10)
.then(() => {
updateLoading(these, {
text: "正在发送:" + currentPacket + "/" +
totalPackets
})
currentPacket++;
setTimeout(sendNextPacket, these.inteval);
}).catch(err => {
console.log("发送数据包失败了" + JSON.stringify(err));
if (err.code == '10007') {
setTimeout(sendNextPacket, these.inteval);
return;
}
these.Status.BottomMenu.show = false;
these.showPop({
message: err.msg,
iconUrl: "/static/images/6155/DeviceDetail/uploadErr.png",
borderColor: "#e034344d",
buttonBgColor: "#E03434",
});
hideLoading(these);
these.rgb565Data = null;
reject(err);
});
}
if (ReSendNo) {
sendNextPacket(ReSendNo);
return;
}
// 开始牵手
ble.sendString(f.deviceId, "picture transmit start", f.writeServiceId,
f.wirteCharactId).then(() => {
setTimeout(sendNextPacket, 120);
}).catch((err) => {
console.log("握手没有成功");
these.showPop({
message: err.msg,
iconUrl: "/static/images/6155/DeviceDetail/uploadErr.png",
borderColor: "#e034344d",
buttonBgColor: "#E03434",
});
hideLoading(these);
reject(err);
});
}
});
}
uni.chooseImage({
count: 1,
sizeType: ['original', 'compressed'],
sourceType: ['album'],
success: function(res) {
uni.navigateTo({
url: "/pages/6155/ImgCrop",
events: {
ImgCutOver: function(data) {
showLoading(these, {
text: "正在发送0/52"
});
console.log("data=", data);
these.Status.BottomMenu.show = false;
these.rgb565Data = ble.convertToRGB565(data.piexls);
setTimeout(function() {
sendImagePackets().catch(() => {
});
}, 0)
}
},
success(ev) {
ev.eventChannel.emit('checkImg', {
data: res.tempFiles[0].path
})
},
fail(ex) {
console.log("跳转页面失败" + JSON.stringify(ex));
}
});
}
});
},
UploadOpenVideo: function() { //开机动画
if (!this.permissions.includes('3') && this.Status.apiType !== 'listA') {
this.showPop({
message: '无操作权限',
iconUrl: "/static/images/6155/DeviceDetail/uploadErr.png",
borderColor: "#e034344d",
buttonBgColor: "#E03434",
okCallback: null,
buttonText: "确定"
})
return;
}
let f = these.getDevice();
if (!f) {
these.showBleUnConnect();
return;
}
let timeDelayCloseLoading = () => {
setTimeout(() => {
hideLoading(these);
}, 1500);
}
let sendVideoPackets = (ReSendNo) => {
console.log("开始发送分片数据");
return new Promise((resolve, reject) => {
if (f) {
// 总数据包数
var totalPackets = 1536; //36;
let currentPacket = 1;
console.log("发送数据准备中,总共" + totalPackets);
if (ReSendNo) {
totalPackets = ReSendNo;
currentPacket = ReSendNo;
}
this.totalPackets = totalPackets;
// 发送单个数据包
const sendNextVideoPacket = () => {
// console.log("准备发送一段数据");
if (currentPacket > totalPackets) {
if (!ReSendNo) {
setTimeout(() => {
ble.sendString(f.deviceId, "transmit complete", f
.writeServiceId, f.wirteCharactId, 20)
.then(
() => {
console.log("全部发送完毕")
}).catch((ex) => {
console.log("出现异常", ex);
});
}, 500);
}
these.Status.BottomMenu.show = false;
hideLoading(these);
these.showPop({
showPop: true,
message: "上传成功",
iconUrl: "/static/images/common/success.png"
});
these.videoHexArray = null;
resolve();
return;
}
// 计算当前包的数据
let packetSize = 500;
// 创建数据包
const startIndex = (currentPacket - 1) * packetSize;
const endIndex = Math.min(startIndex + packetSize, these.videoHexArray
.length);
if (startIndex > endIndex) {
resolve();
return;
}
////console.log("111111");
const packetData = these.videoHexArray.slice(startIndex, endIndex);
// 构建数据包
////console.log("packetData.length"+packetData.length);
const bufferSize = 504; // 头部5字节 + 数据部分
const buffer = new ArrayBuffer(bufferSize);
const dataView = new DataView(buffer);
let sortNo = currentPacket.toString(16).padStart(4, '0');
// 填充头部
dataView.setUint8(0, 0x55); // 帧头
dataView.setUint8(1, 0x04); // 帧类型:开机画面
dataView.setUint8(2, '0x' + sortNo.substring(0, 2)); // 包序号
dataView.setUint8(3, '0x' + sortNo.substring(2, 4)); // 包序号
// dataView.setUint8(4, 0x01);
// dataView.setUint8(5, 0xF4);
for (let i = 0; i < packetData.length; i++) {
dataView.setUint8(4 + i, '0x' + packetData[i]);
}
let inteval = 40;
ble.sendData(f.deviceId, buffer, f.writeServiceId, f
.wirteCharactId, 10).then(() => {
updateLoading(these, {
text: "正在发送:" + currentPacket + "/" +
totalPackets
})
currentPacket++;
// console.log("发送一段成功,发送下一段");
setTimeout(sendNextVideoPacket, inteval);
}).catch(err => {
console.log("发送失败了", err);
if (err.code == '10007') { //遇到这个错误自动重新发送
console.log(err.errMsg + ",发送失败了,正在补偿:" +
currentPacket);
setTimeout(sendNextVideoPacket, inteval);
} else {
these.Status.BottomMenu.show = false;
hideLoading(these);
these.showPop({
showPop: true,
message: err.msg + ",发送失败了",
borderColor: "#e034344d",
buttonBgColor: "#E03434",
buttonText: "确定",
iconUrl: "/static/images/6155/DeviceDetail/uploadErr.png"
});
reject(err);
these.videoHexArray = null;
return;
}
});
};
sendNextVideoPacket();
} else {
console.log("Fail.......")
}
});
}
var sendVideo = (videoPath) => {
let uploadVideo = () => {
these.videoHexArray = [];
console.log("开始处理,正在上传");
showLoading(these, {
text: "上传中"
});
let p1 = new Promise((resolve, reject) => {
ble.sendString(f.deviceId, "video transmit start", f
.writeServiceId, f.wirteCharactId).then(res => {
setTimeout(() => {
console.log("握手成功了");
resolve(true);
}, 2200)
}).catch(ex => {
reject(ex);
});
});
let p2 = new Promise((succ, err) => {
const token = uni.getStorageSync('token');
const clientid = uni.getStorageSync('clientID');
if (!token) {
err({
code: 401,
msg: "请先登陆后再试"
});
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",
filePath: videoPath,
name: 'file',
header: {
"Method": "POST",
"Content-Type": "multipart/form-data",
"Authorization": 'Bearer ' + token,
"clientid": clientid
},
timeout: 600000,
fail: (ex) => {
console.log("上传视频失败" + JSON.stringify(ex));
err(ex);
},
success: (res) => {
console.log("上传完成,向蓝牙设备发送");
succ(res);
}
});
});
Promise.all([p1, p2]).then((arr) => {
if (arr[0].status == 'rejected') {
these.showPop({
message: "设备准备未就绪",
iconUrl: "/static/images/6155/DeviceDetail/uploadErr.png",
borderColor: "#e034344d",
buttonBgColor: "#E03434",
});
return;
}
let res = arr[1];
// console.log("11111111111111111111111",res);
res = JSON.parse(res.data);
// console.log("22222222222222222222");
if (res.data) {
these.videoHexArray = res.data;
updateLoading(these, {
text: "正在发送:0/1536"
});
these.Status.BottomMenu.show = false;
shotVideoClick(res.data);
} else {
console.log("服务器未返回正确的数据");
these.showPop({
message: "与服务器连接出现异常,请检查网络设置",
iconUrl: "/static/images/6155/DeviceDetail/uploadErr.png",
borderColor: "#e034344d",
buttonBgColor: "#E03434",
});
}
}).catch((ex) => {
console.log("出现异常,", ex)
hideLoading(these);
these.showPop({
message: "出现异常," + ex.msg,
iconUrl: "/static/images/6155/DeviceDetail/uploadErr.png",
borderColor: "#e034344d",
buttonBgColor: "#E03434",
});
})
}
let f = these.getDevice();
let shotVideoClick = () => {
console.log("正在开始发送");
sendVideoPackets().then(() => {
console.log("发送完成");
}).catch((ex1) => {
//console.log("出现了异常", ex1)
}).finally(() => {
hideLoading(these);
});
}
uploadVideo();
}
uni.chooseVideo({
sourceType: ['album'],
compressed: false, // 关闭视频压缩,确保上传原始文件
success: function(res) {
console.log("res=", res);
let path = res.tempFilePath;
// iOS可能返回浮点数需要转换为整数进行比较
let width = Math.round(res.width);
let height = Math.round(res.height);
let duration = res.duration;
// 获取平台信息
const systemInfo = uni.getSystemInfoSync();
const platform = systemInfo.platform;
const isIOS = platform === 'ios';
console.log("平台:", platform, "uni.chooseVideo返回 - 宽度:", width, "高度:", height,
"时长:", duration);
// iOS特殊处理如果返回的是80*40很可能是160*80的一半iOS的bug
if (isIOS && width === 80 && height === 40) {
console.log("检测到iOS特殊情况返回80*40实际应该是160*80进行修正");
width = 160;
height = 80;
}
// 检查分辨率是否符合要求
let checkResolution = (w, h) => {
// 使用容差比较允许1像素的误差
return Math.abs(w - 160) <= 1 && Math.abs(h - 80) <= 1;
};
let err = [];
if (duration < 2) {
err.push("视频时长至少2秒");
}
if (!checkResolution(width, height)) {
err.push("视频宽高必须是160*80当前分辨率" + width + "*" + height);
}
if (err.length > 0) {
err = err.join(";");
these.showPop({
message: err,
iconUrl: "/static/images/6155/DeviceDetail/uploadErr.png",
borderColor: "#e034344d",
buttonBgColor: "#E03434",
});
return;
}
showLoading(these, {
text: '正在上传'
});
setTimeout(() => {
sendVideo(path);
}, 0);
}
});
},
UploadOpenImg: function() {
if (!this.permissions.includes('3') && this.Status.apiType !== 'listA') {
this.showPop({
message: '无操作权限',
iconUrl: "/static/images/6155/DeviceDetail/uploadErr.png",
borderColor: "#e034344d",
buttonBgColor: "#E03434",
okCallback: null,
buttonText: "确定"
})
return;
}
//上传开机画面
this.Status.BottomMenu.menuItems = [];
this.Status.BottomMenu.title = "上传开机画面";
this.Status.BottomMenu.type = "checkImg";
this.Status.BottomMenu.show = true;
},
ModeSetting: function(type) {
this.Status.lightMode = type;
let title = '';
let items = this.dic.menuItems.filter((v => {
return v.type == type;
}));
switch (type) {
case "main":
title = '主灯模式';
break;
case "fu":
title = '辅灯模式';
break;
}
this.Status.BottomMenu.menuItems = items;
this.Status.BottomMenu.title = title;
this.Status.BottomMenu.type = type;
this.Status.BottomMenu.show = true;
if (this.formData.mode != type) {
this.Status.BottomMenu.activeIndex = null;
} else {
this.Status.BottomMenu.activeIndex = this.formData.light;
}
},
showMenu(flag) {
this.Status.BottomMenu.show = true;
},
closeMenu() {
this.Status.BottomMenu.show = false;
},
btnClick(item, index) {
if (!this.permissions.includes('1') && this.Status.apiType !== 'listA') {
this.showPop({
message: '无操作权限',
iconUrl: "/static/images/6155/DeviceDetail/uploadErr.png",
borderColor: "#e034344d",
buttonBgColor: "#E03434",
okCallback: null,
buttonText: "确定"
})
return;
}
if (parseInt(this.Status.BottomMenu.activeIndex) === NaN) {
uni.showToast('请选择模式');
return;
}
//发送指令给设备
switch (this.Status.BottomMenu.type) {
case "main":
this.setMode(this.Status.BottomMenu.activeIndex, this.Status.BottomMenu.type);
break;
case "fu":
this.setMode(this.Status.BottomMenu.activeIndex, this.Status.BottomMenu.type);
break;
}
this.closeMenu();
},
setMode(mode, type) {
let dataValue = 0;
console.log("mode=", mode);
switch (mode) {
case 0:
if (type == 'main') {
dataValue = 0x6D;
} else if (type == 'fu') {
dataValue = 0x71;
}
break;
case 1:
if (type == 'main') {
dataValue = 0x6E;
} else if (type == 'fu') {
dataValue = 0x72; //强泛光
}
break;
case 2:
dataValue = 0x70;
break;
case 3:
dataValue = 0x6F;
break;
}
console.log("dataValue=", dataValue)
// 构建数据包
var buffer = new ArrayBuffer(6);
var dataView = new DataView(buffer);
dataView.setUint8(0, 0x55); // 帧头
dataView.setUint8(1, 0x00); // 帧类型
dataView.setUint8(2, 0x01); // 数据
dataView.setUint8(3, 0x00); // 数据
dataView.setUint8(4, 0x01); // 数据
dataView.setUint8(5, dataValue); // 数据
let f = this.getDevice();
// 发送数据
if (!f) {
these.showBleUnConnect();
return;
}
showLoading(these, {
text: "请稍候..."
});
ble.sendData(f.deviceId, buffer, f.writeServiceId, f.wirteCharactId, 30).then(() => {
this.formData.light = mode;
this.formData.mode = type
this.formData.liangDu = 100;
this.setBleFormData();
}).catch((ex) => {
these.showPop({
message: "发送失败," + ex.msg,
iconUrl: "/static/images/6155/DeviceDetail/uploadErr.png",
borderColor: "#e034344d",
buttonBgColor: "#E03434",
});
}).finally(() => {
hideLoading(these);
});
},
handleItemClick(item, index) {
// switch (this.Status.BottomMenu.type) {
// case "main":
// break;
// case "fu":
// break;
// }
this.Status.BottomMenu.activeIndex = index;
},
setBleFormData() {
ble.data.LinkedList.find((v) => {
if (v.deviceId == these.formData.deviceId) {
v.formData = these.formData;
return true;
}
return false;
});
uni.setStorage({
key: ble.StorageKey,
data: ble.data.LinkedList
})
},
closePop: function() {
this.Status.Pop.showPop = false;
if (this.Status.Pop.cancelCallback) {
this.Status.Pop.cancelCallback();
}
},
HidePop: function() {
// console.log("1111");
if (this.Status.Pop.clickEvt == 'SendUsr') {
}
if (this.Status.Pop.okCallback) {
this.Status.Pop.okCallback();
}
this.Status.Pop.showPop = false;
},
showPop: function(option) {
hideLoading(this);
let def = {
showPop: true, //是否显示弹窗
popType: 'custom',
bgColor: '#383934bd',
borderColor: '#BBE600',
textColor: '#ffffffde',
buttonBgColor: '#BBE600',
buttonTextColor: '#232323DE',
iconUrl: '',
message: '',
buttonText: '确定',
clickEvt: '',
visiblePrompt: false,
promptTitle: '',
modelValue: '',
visibleClose: false,
okCallback: null,
showSlot: false,
buttonCancelText: '',
showCancel: false,
}
let keys = Object.keys(def);
for (let i = 0; i < keys.length; i++) {
let key = keys[i];
if (key in option) {
continue;
}
this.Status.Pop[key] = def[key];
}
if (option) {
keys = Object.keys(option);
for (let i = 0; i < keys.length; i++) {
let key = keys[i];
this.Status.Pop[key] = option[key];
}
}
if (!option.borderColor) {
option.borderColor = '#BBE600';
option.buttonBgColor = '#BBE600';
}
these.Status.Pop.showPop = true;
},
sendUsr() {
if (!this.permissions.includes('4') && this.Status.apiType !== 'listA') {
this.showPop({
message: '无操作权限',
iconUrl: "/static/images/6155/DeviceDetail/uploadErr.png",
borderColor: "#e034344d",
buttonBgColor: "#E03434",
okCallback: null,
buttonText: "确定"
})
return;
}
let f = this.getDevice();
if (!f) {
these.showBleUnConnect()
return;
}
let toByteValue = (value) => {
if (typeof value === 'number') {
return value;
}
if (typeof value === 'string') {
if (value.startsWith('0x') || value.startsWith('0X')) {
return parseInt(value, 16);
}
return parseInt(`0x${value}`, 16);
}
return 0;
}
let err = false;
this.formData.textLines.find((txt) => {
if (txt.length === 0 || txt.length > 7) {
console.log("txt=", txt);
err = true;
return true;
}
return false;
})
if (err) {
this.showPop({
message: "单位、部门、姓名必须填写且最多7字",
iconUrl: "/static/images/6155/DeviceDetail/uploadErr.png",
borderColor: "#e034344d",
buttonBgColor: "#E03434",
});
return;
}
showLoading(these, {
text: "请稍候..."
});
//握手
let holdHand = () => {
return new Promise((resolve, reject) => {
updateLoading(these, {
text: '设备准备中...'
})
let hexs = 'word transmit start';
ble.sendString(f.deviceId, hexs, f.writeServiceId, f.wirteCharactId, 10).then(res => {
setTimeout(() => {
resolve(res)
}, 2200);
}).catch(ex => {
reject(ex)
});
});
}
//画图
let drawText = () => {
return new Promise((resolve, reject) => {
this.$refs.textToHex.drawAndGetPixels().then(allPixels => {
if (!allPixels) {
reject("文本初始化失败");
return;
}
resolve(allPixels);
}).catch(compEx => {
reject(compEx);
});
});
}
//发送3个分包的数据
let task = (allPixels) => {
try {
let combinedData = [];
for (let i = 0; i < 3; i++) {
let linePixels = (allPixels[i] || []).flat(Infinity).map(item =>
typeof item === 'string' ? toByteValue(item) : item
);
for (var j = linePixels.length; j < 256; j++) {
linePixels.push(0x00);
}
linePixels = [0xFA, 0x06, 0x03, i + 1].concat(linePixels);
linePixels.push(0xFF)
combinedData.push(linePixels);
}
combinedData.push([0x74, 0x72, 0x61, 0x6E, 0x73, 0x6D, 0x69, 0x74, 0x20, 0x63, 0x6F, 0x6D,
0x70, 0x6C, 0x65, 0x74, 0x65
]);
let curr = 1;
let len = combinedData.length;
console.log(combinedData);
showLoading(these, {
text: '正在发送' + (curr - 1) + '/' + len
});
//分包发送
let sendPacket = () => {
if (combinedData.length === curr - 1) {
these.setBleFormData();
these.showPop({
message: "发送成功",
iconUrl: "/static/images/common/success.png",
borderColor: '#BBE600',
buttonBgColor: '#BBE600'
});
let json = {
deviceId: these.device.id,
name: these.formData.textLines[1],
position: these.formData.textLines[0],
unitName: these.formData.textLines[2],
code: ""
};
usrApi.sendUsr(json);
hideLoading(these);
return;
}
let array = combinedData[curr - 1];
ble.sendHexs(f.deviceId, array, f.writeServiceId, f.wirteCharactId, 10).then(
res => {
updateLoading(these, {
text: '正在发送' + curr + '/' + len
});
curr++;
setTimeout(sendPacket, 150);
}).catch(err => {
if (err.code == '10007') {
setTimeout(sendPacket, 150);
} else {
console.log("err:", err);
hideLoading(these);
these.showPop({
message: "发送失败: " + (err.msg || err.message),
iconUrl: "/static/images/6155/DeviceDetail/uploadErr.png",
borderColor: "#e034344d",
buttonBgColor: "#E03434",
});
}
});
}
setTimeout(sendPacket, 0);
// 5. 发送成功处理
} catch (ex) {
hideLoading(these);
this.showPop({
message: "发送失败: " + (ex.msg || ex.message),
iconUrl: "/static/images/6155/DeviceDetail/uploadErr.png",
borderColor: "#e034344d",
buttonBgColor: "#E03434",
});
}
}
setTimeout(() => {
Promise.allSettled([holdHand(), drawText()]).then(results => {
if (results[0].status == 'rejected') {
updateLoading(these, {
text: results[0].reason
});
setTimeout(() => {
hideLoading(these)
}, 500);
return;
}
if (results[1].status == 'rejected') {
updateLoading(these, {
text: results[1].reason
})
setTimeout(() => {
hideLoading(these)
}, 500);
return;
}
task(results[1].value);
})
}, 0);
},
getDetail() {
var these = this;
usrApi.getDetail(this.device.id).then(res => {
if (res && res.code == 200) {
res = res.data;
let personnelInfo = res.personnelInfo;
if (personnelInfo) {
these.formData.textLines[2] = personnelInfo.unitName;
these.formData.textLines[1] = personnelInfo.name;
these.formData.textLines[0] = personnelInfo.position;
}
}
});
},
ack: function() {
let eventChannel = this.getOpenerEventChannel();
eventChannel.emit('ack', {
data: '我已收到了您的消息,谢谢。'
});
},
sliderChange: function(evt) {
if (!this.permissions.includes('1') && this.Status.apiType !== 'listA') {
this.showPop({
message: '无操作权限',
iconUrl: "/static/images/6155/DeviceDetail/uploadErr.png",
borderColor: "#e034344d",
buttonBgColor: "#E03434",
okCallback: null,
buttonText: "确定"
})
return;
}
let f = this.getDevice();
if (!f) {
these.showBleUnConnect()
return;
}
this.formData.liangDu = evt.detail.value;
clearTimeout(BrighInteval)
//给蓝牙设备发送信号更新亮度
BrighInteval = setTimeout(() => {
this.sendBrightness();
}, 100);
},
sendBrightness: function() {
try {
let liangDu = this.formData.liangDu
let fs = this.dic.menuItems.filter((v => {
return v.type == this.formData.mode;
}));
if (fs.length > 0) {
if (this.formData.light < fs.length) {
let f = fs[this.formData.light];
liangDu = Math.floor(liangDu / 100 * f.math);
console.error("当前模式", this.formData.mode);
console.error("当前灯光", this.formData.light);
console.error("当前亮度", liangDu);
}
}
const buffer = new ArrayBuffer(6);
const dataView = new DataView(buffer);
dataView.setUint8(0, 0x55); // 帧头
dataView.setUint8(1, 0x07); // 帧类型:亮度调节
dataView.setUint8(2, 0x01); // 包序号
dataView.setUint8(3, 0x00); // 包序号
dataView.setUint8(4, 0x01); // 数据长度
dataView.setUint8(5, liangDu); // 数据长度
let f = this.getDevice();
if (f) {
// 发送数据
ble.sendData(f.deviceId, buffer, f.writeServiceId, f.wirteCharactId, 30).then(res => {
this.setBleFormData();
}).catch(err => {
});
}
} catch (ex) {
console.error("出现错误", ex);
}
}
}
}
</script>
<style>
.content {
box-sizing: border-box;
width: 100%;
min-height: 100vh;
height: auto;
}
.contentBg {
background-color: #121212;
color: #ffffffde;
}
.fleft {
float: left;
}
.fright {
float: right;
}
.clear {
clear: both;
}
.displayNone {
display: none !important;
}
.p100 {
width: 100%;
height: 100%;
}
.center {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
align-content: center;
justify-content: center;
align-items: center;
}
.centerLeft {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
align-content: center;
justify-content: flex-start;
align-items: center;
}
.content {
padding: 30rpx;
box-sizing: border-box;
}
.eq {
width: 100%;
height: 250rpx;
border-radius: 8px;
background: rgba(26, 26, 26, 1);
box-sizing: border-box;
padding: 24rpx 28rpx;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
align-content: center;
justify-content: center;
align-items: center;
margin-bottom: 24rpx;
}
.eq .leftImg {
box-sizing: border-box;
padding: 36rpx;
border-radius: 16rpx;
background: rgba(42, 42, 42, 0.5);
}
.eq .leftImg,
.eq .rightTxt {
width: 50%;
height: 100%;
}
.eq .rightTxt {
display: flex;
flex-direction: column;
flex-wrap: nowrap;
align-content: flex-start;
justify-content: space-evenly;
align-items: flex-start;
}
.eq .leftImg .img {
width: 100%;
height: 100%;
}
.eq .rightTxt .img {
width: 52rpx;
height: 52rpx;
}
.eq .rightTxt .row {
width: 100%;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
align-content: center;
justify-content: flex-start;
align-items: center;
box-sizing: border-box;
padding-left: 50rpx;
}
.eq .rightTxt .row .txt {
padding-left: 20rpx;
}
.eq .bigTxt {
color: rgba(255, 255, 255, 0.87);
font-family: "PingFang SC";
font-size: 28rpx;
font-weight: 400;
}
.eq .smallTxt {
color: rgba(255, 255, 255, 0.6);
font-family: "PingFang SC";
font-size: 24rpx;
font-weight: 400;
}
.eqinfo {
border-radius: 16rpx;
background: rgba(26, 26, 26, 1);
box-sizing: border-box;
padding: 14rpx 0rpx;
}
.eqinfo .item {
width: 100%;
height: 60rpx;
line-height: 60rpx;
padding: 0rpx 28rpx;
box-sizing: border-box;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
align-content: center;
justify-content: space-between;
align-items: center;
}
.eqinfo .lbl {
color: rgba(255, 255, 255, 0.87);
font-family: "PingFang SC";
font-size: 28rpx;
font-weight: 400;
letter-spacing: 0.07px;
text-align: left;
}
.eqinfo .value {
color: rgba(255, 255, 255, 0.6);
font-family: "PingFang SC";
font-size: 28rpx;
font-weight: 400;
letter-spacing: 0.07px;
text-align: left;
}
.lamp {
margin-top: 24rpx;
}
.lamp .title {
width: 100%;
height: 60rpx;
line-height: 60rpx;
padding: 0rpx 28rpx;
box-sizing: border-box;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
align-content: center;
justify-content: space-between;
align-items: center;
font-size: 28rpx;
}
.lampMode {
padding: 30rpx 0rpx;
width: 100%;
box-sizing: border-box;
}
.lampMode .mode {
width: calc(calc(100% - 34rpx) / 2);
border-radius: 8px;
margin-top: 20rpx;
background: rgba(26, 26, 26, 1);
display: flex;
flex-direction: row;
flex-wrap: nowrap;
align-content: center;
align-items: center;
justify-content: flex-start;
padding: 30rpx;
box-sizing: border-box;
}
.mode.marginLeft {
margin-left: 34rpx !important;
}
.mode .leftImg .img {
width: 70rpx;
height: 70rpx;
}
.mode .rightTxt {
display: flex;
flex-direction: column;
flex-wrap: nowrap;
align-content: flex-start;
justify-content: center;
align-items: flex-start;
padding-left: 20rpx;
}
.mode .bigTxt {
color: rgba(255, 255, 255, 0.87);
font-family: "PingFang SC";
font-size: 28rpx;
font-weight: 400;
letter-spacing: 0.07px;
}
.mode .smallTxt {
color: rgba(255, 255, 255, 0.6);
font-family: "PingFang SC";
font-size: 24rpx;
font-weight: 400;
letter-spacing: 0.07px;
}
.usrinfo {
border-radius: 8px;
width: 100%;
box-sizing: border-box;
padding: 24rpx 28rpx;
background: rgba(26, 26, 26, 1);
}
.usrtitle {
color: rgba(255, 255, 255, 0.87);
font-family: "PingFang SC";
font-size: 28rpx;
font-weight: 400;
height: 40rpx;
line-height: 40rpx;
letter-spacing: 0.07px;
}
.usrinfo .btnSend {
line-height: 65rpx;
border-radius: 8px;
width: 120rpx;
height: 65rpx;
color: rgba(35, 35, 35, 0.87);
font-family: "PingFang SC";
font-size: 20rpx;
font-weight: 400;
letter-spacing: 0.07px;
text-align: center;
background-color: #BBE600;
}
.usrinfo .item {
border-radius: 8px;
width: 100%;
box-sizing: border-box;
line-height: 90rpx;
height: 90rpx;
background: rgba(42, 42, 42, 1);
margin-top: 24rpx;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
align-content: center;
justify-content: flex-start;
align-items: center;
}
.usrinfo .lbl {
width: 120rpx;
height: 100%;
padding-left: 24rpx;
box-sizing: border-box;
text-align: right;
color: rgba(255, 255, 255, 0.87);
font-family: "PingFang SC";
font-size: 28rpx;
font-weight: 400;
letter-spacing: 0.07px;
}
.usrinfo .value {
width: calc(100% - 120rpx);
height: 100%;
}
.usrinfo .value .uni-input-input {
color: rgba(255, 255, 255, 0.87);
font-family: "PingFang SC";
font-size: 28rpx;
font-weight: 400;
letter-spacing: 0.07px;
text-align: left;
}
.usrplace {
color: rgba(255, 255, 255, 0.4);
font-family: "PingFang SC";
font-size: 28rpx;
font-weight: 400;
letter-spacing: 0.07px;
text-align: left;
}
.proinfo .itemcontent {
display: flex;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
align-content: center;
justify-content: space-evenly;
}
.proinfo .item {
width: 180rpx;
height: 180rpx;
box-sizing: border-box;
padding: 40rpx;
border-radius: 16rpx;
background: rgba(26, 26, 26, 1);
display: flex;
flex-direction: column;
flex-wrap: nowrap;
align-content: center;
justify-content: center;
align-items: center;
}
.proinfo .item .img {
width: 50rpx;
height: 50rpx;
}
.proinfo .item .txt {
color: rgba(255, 255, 255, 0.6);
font-family: "PingFang SC";
font-size: 24rpx;
font-weight: 400;
margin-top: 20rpx;
letter-spacing: 0.07px;
text-align: left;
}
.slider-container {
padding: 0px;
}
.addIco {
width: 100%;
height: 360rpx;
display: flex;
flex-wrap: nowrap;
flex-direction: row;
align-content: center;
justify-content: center;
align-items: center;
}
.icoContent {
width: 240rpx;
height: 240rpx;
border-radius: 8rpx;
background: rgba(58, 58, 58, 1);
}
.icoContent .img {
width: 70rpx;
height: 70rpx;
}
.TextToHex {
position: fixed;
top: -99999rpx;
left: -99999rpx;
visibility: hidden;
}
.navbarRight {
width: 40px;
height: 100%;
}
.navbarRight .imgContent {
width: 36rpx;
height: 36rpx;
position: relative;
}
.navbarRight .imgContent:first-child {
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;
}
.uninavebartext {
width: 100%;
font-size: 32rpx;
}
</style>