设备分享模块页面功能开发

This commit is contained in:
fengerli
2025-07-16 16:43:22 +08:00
parent 9b3be8c7d7
commit bc3bea6df0
9 changed files with 752 additions and 48 deletions

View File

@ -126,6 +126,24 @@
"style": {
"navigationBarTitleText": "地图"
}
},
{
"path": "pages/6170/share/index",
"style": {
"navigationBarTitleText": "分享"
}
},
{
"path": "pages/6170/shareDevices/index",
"style": {
"navigationBarTitleText": "分享设备"
}
},
{
"path": "pages/6170/shareManagement/index",
"style": {
"navigationBarTitleText": "分享管理"
}
}
],
"tabBar": {

View File

@ -1,8 +1,8 @@
<template>
<view>
<!-- 使用自定义导航栏 -->
<custom-navbar :title="navTitle" :showBack="true" color="#FFFFFF" rightIcon="/static/images/path.png"
@right-click="uploadStartup"></custom-navbar>
<custom-navbar :title="navTitle" :showBack="true" color="#FFFFFF" rightIcon="/static/images/shape.png"
@right-click="shareUp"></custom-navbar>
<view class="device-detail-container" :style="{ paddingTop: navBarHeight + 'px' }">
<!-- 设备电量信息 -->
<view class="battery-section">
@ -176,12 +176,12 @@
<!-- 上传开机画面弹框 -->
<view class="agreement-mask" v-if="lightModeB">
<!-- 上传画面弹窗 -->
<view class="agreement-popup">
<view class="agreement-popupB">
<!-- 标题 -->
<view class="popup-title">上传开机画面</view>
<view class="popup-content">
<view class="example-body">
<uni-file-picker limit="1"></uni-file-picker>
<uni-file-picker limit="1" class="custom-file-picker"></uni-file-picker>
<view class="example_title">点击上传图片</view>
</view>
</view>
@ -324,6 +324,12 @@
handleupload() {
this.lightModeB = false
},
// 分享
shareUp(){
uni.navigateTo({
url: '/pages/6170/share/index'
})
},
// 操作说明
operatingInst() {
@ -357,27 +363,42 @@
// 发送人员信息
sendPersonnelInfo() {
if (!this.mqttClient || !this.mqttClient.client.isConnected()) {
uni.showToast({ title: 'MQTT未连接', icon: 'none' });
uni.showToast({
title: 'MQTT未连接',
icon: 'none'
});
return;
}
const topic = `device/command/${this.deviceID}/personnel`;
const message = JSON.stringify(this.personnelInfo);
this.mqttClient.publish(topic, message);
uni.showToast({ title: '人员信息已发送', icon: 'success' });
uni.showToast({
title: '人员信息已发送',
icon: 'success'
});
},
// 发送文本消息
sendTextMessage() {
if (!this.mqttClient || !this.mqttClient.client.isConnected()) {
uni.showToast({ title: 'MQTT未连接', icon: 'none' });
uni.showToast({
title: 'MQTT未连接',
icon: 'none'
});
return;
}
if (!this.messageToSend) {
uni.showToast({ title: '请输入要发送的文字', icon: 'none' });
uni.showToast({
title: '请输入要发送的文字',
icon: 'none'
});
return;
}
const topic = `device/command/${this.deviceID}/message`;
this.mqttClient.publish(topic, this.messageToSend);
uni.showToast({ title: '消息已发送', icon: 'success' });
uni.showToast({
title: '消息已发送',
icon: 'success'
});
}
},
onLoad(options) {
@ -418,7 +439,7 @@
}
</script>
<style>
<style scoped>
.device-detail-container {
padding: 30rpx;
background: #121212;
@ -625,23 +646,13 @@
.example-body {
position: absolute;
left: 50%;
top: 70%;
top: 60%;
width: 100%;
transform: translate(-17%, -100%);
transform: translate(-10%, -100%);
}
.uni-file-picker__container {
width: 200rpx !important;
border: 1px solid rgb(58, 58, 58);
}
:deep .file-picker__box {
width: 40% !important;
}
.example_title {
padding-top: 20rpx;
color: rgba(255, 255, 255, 0.87);
}
@ -776,6 +787,17 @@
bottom: 0rpx;
}
.agreement-popupB {
width: 100%;
height: 40%;
background-color: rgb(42, 42, 42);
border-radius: 60rpx 60rpx 0rpx 0rpx;
padding: 40rpx;
box-sizing: border-box;
position: absolute;
bottom: 0rpx;
}
.agreement-popupC {
width: 80%;
background-color: rgb(42, 42, 42);

View File

@ -0,0 +1,76 @@
<template>
<view class="share">
<!-- 内容区域 -->
<view class="content">
<!-- 分享设备 -->
<view class="section" @click="shareDevice">
<text class="section-title">分享设备</text>
</view>
<!-- 分享管理 -->
<view class="section" @click="shareManagement">
<text class="section-title">分享管理</text>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
}
},
methods: {
// 分享设备
shareDevice(){
uni.navigateTo({
url: '/pages/6170/shareDevices/index'
});
},
// 分享管理
shareManagement(){
uni.navigateTo({
url: '/pages/6170/shareManagement/index'
});
}
}
}
</script>
<style scoped>
.share {
padding: 30rpx;
background: #121212;
min-height: 100vh;
}
.status-bar {
/* 根据实际情况设置状态栏高度 */
width: 100%;
height: 20px;
background-color: #f3f3f3;
}
.title {
font-size: 20px;
margin-top: 10px;
}
.content {
width: 100%;
margin-top: 20px;
}
.section {
margin-bottom: 20px;
padding:50rpx;
border-radius: 16rpx;
background: rgba(26, 26, 26, 1);
text-align: center;
color: rgba(255, 255, 255, 0.87);
width: 100%;
}
</style>

View File

@ -0,0 +1,348 @@
<template>
<view class="container">
<!-- 设备信息 -->
<view class="device-info" v-for="(item, index) in deviceList" :key="index">
<view class="device-header">
<view class="deviceIMG">
<image :src="item.devicePic" mode="" class="IMG"></image>
</view>
<view class="device-name">
<view>设备:{{item.deviceName}}</view>
<view class="ID">
<view class="ID">ID:{{item.deviceImei}}
</view>
</view>
</view>
</view>
</view>
<!-- 功能权限 -->
<view class="permissions">
<view class="permissions-title">功能权限</view>
<view :checked="allSelected" class="allSelect" @click="toggleAllSelection()">全选</view>
<text class="permissions-title"></text>
<view class="permission-item" v-for="(item, index) in permissions" :key="index"
@click="toggleSelection(index)">
<view class="checkbox" :class="{ checked: item.checked }">
<uni-icons v-if="item.checked" type="checkmarkempty" size="18" color="rgb(0, 0, 0)"></uni-icons>
</view>
<view> {{ item.label }}</view>
</view>
</view>
<!-- 被分享人信息 -->
<view class="recipient-info">
<view class="recipient-title">被分享人信息</view>
<input type="number" placeholder="输入手机号" class="phone-input" :maxlength="11" />
<view class="verification-code">
<input type="number" placeholder="短信验证码" class="code-input" />
<view class="get-code-btn">获取验证码</view>
</view>
</view>
<!-- 分享按钮 -->
<button class="share-btn" @click="shareUp">分享</button>
<!-- 分享弹框 -->
<view class="agreement-mask" v-if="shareShow" @click="closePopup('share')">
<view class="agreement-popup" @click.stop>
<view class="popup-content">
<image src="/static/images/success.png" mode="" class="svg"></image>
<view>
<view class="popup-Title">设备分享成功</view>
</view>
</view>
<!-- 按钮组 -->
<view class="popup-buttons">
<button class="btn agreeBtn" @click="handleBtn">确定</button>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
allSelected: false,
shareShow: false,
permissions: [{
value: "light-mode",
label: "灯光模式",
checked: false
},
{
value: "laser-mode",
label: "激光模式",
checked: false
},
{
value: "startup-image",
label: "开机画面",
checked: false
},
{
value: "person-registration",
label: "人员信息登记",
checked: false
},
{
value: "send-message",
label: "发送信息",
checked: false
},
{
value: "product-info",
label: "产品信息",
checked: false
}
],
deviceList: [{}]
};
},
methods: {
closePopup(){
this.shareShow=false
},
toggleAllSelection() {
this.allSelected = !this.allSelected;
this.permissions.forEach(permission => permission.checked = this.allSelected);
},
toggleSelection(index) {
this.$set(this.permissions[index], 'checked', !this.permissions[index].checked);
this.allSelected = this.permissions.every(permission => permission.checked);
},
shareUp() {
// const selectedPermissions = this.permissions.filter(permission => permission.checked).map(permission =>
// permission.value);
// console.log('Selected Permissions:', selectedPermissions);
this.shareShow=true
},
handleBtn(){
this.shareShow=false
}
}
};
</script>
<style scoped>
.container {
width: 100%;
background: #121212;
min-height: 100vh;
padding: 30rpx;
}
.device-header {
display: flex;
align-items: center;
margin-bottom: 15rpx;
}
.device-name {
font-size: 32rpx;
color: rgba(255, 255, 255, 0.87);
margin-left: 25rpx;
line-height: 50rpx;
white-space: nowrap;
}
.ID {
color: rgba(255, 255, 255, 0.6);
font-size: 26rpx;
display: flex;
justify-content: space-between;
position: relative;
}
.device-info {
font-size: 28rpx;
color: rgba(255, 255, 255, 0.87);
padding-top: 10rpx;
position: relative;
}
.deviceIMG {
width: 100rpx;
height: 100rpx;
border-radius: 16rpx;
position: relative;
background-color: rgba(42, 42, 42, 0.6);
display: flex;
align-items: center;
}
.IMG {
width: 68rpx;
height: 50rpx;
margin-left: 17%;
}
.title {
font-size: 18px;
color: white;
}
.device-info {
width: 100%;
padding: 10px;
border-bottom: 1rpx solid rgba(255, 255, 255, 0.06);
}
.allSelect {
color: rgba(255, 255, 255, 0.87);
float: right;
}
.device-icon {
width: 30px;
height: 30px;
}
.device-id,
.device-serial {
color: white;
}
.permissions {
width: 100%;
margin-top: 20px;
padding: 10px;
border-bottom: 1rpx solid rgba(255, 255, 255, 0.06);
}
.permissions-title {
color: rgba(255, 255, 255, 0.87);
font-size: 30rpx;
/* padding: 30rpx 0rpx; */
}
.checkbox {
width: 40rpx;
height: 40rpx;
border: 2rpx solid rgba(255, 255, 255, 0.5);
margin-right: 20rpx;
border-radius: 4rpx;
display: flex;
align-items: center;
justify-content: center;
}
.checkbox.checked {
background-color: rgb(187, 230, 0);
border-color: rgb(187, 230, 0);
}
.permission-item {
margin-top: 10px;
display: flex;
color: rgba(255, 255, 255, 0.87);
line-height: 60rpx;
align-items: center;
cursor: pointer;
}
.recipient-info {
width: 100%;
margin-top: 20px;
padding: 10px;
border-radius: 5px;
}
.recipient-title {
color: rgba(255, 255, 255, 0.87);
font-size: 30rpx;
}
.phone-input {
width: 100%;
margin-top: 20rpx;
padding: 40rpx 0;
border-bottom: 1rpx solid rgba(255, 255, 255, 0.06);
color: rgba(255, 255, 255, 0.87);
}
.verification-code {
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 1rpx solid rgba(255, 255, 255, 0.06);
padding: 40rpx 0;
color: rgba(255, 255, 255, 0.87);
}
.get-code-btn {
margin-top: 10px;
background-color: transparent;
color: rgba(255, 255, 255, 0.87);
font-size: 30rpx;
white-space: nowrap;
}
.share-btn {
margin-top: 20px;
width: 100%;
padding: 5rpx;
border-radius: 91rpx;
background: rgba(187, 230, 0, 1);
}
/* 遮罩层 */
.agreement-mask {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
justify-content: center;
align-items: center;
z-index: 9999;
}
.popup-Title {
color: rgba(255, 255, 255, 0.86);
text-align: center;
padding: 30rpx 0rpx;
}
.popup-buttons {
display: flex;
text-align: center;
}
/* 弹窗主体 */
.agreement-popup {
width: 60%;
background-color: rgb(42, 42, 42);
border-radius: 40rpx;
padding: 30rpx;
text-align: center;
border: 1px solid rgba(187, 230, 0, 0.3);
}
.svg {
width: 58rpx;
height: 62rpx;
}
/* 通用按钮样式 */
.btn {
height: 60rpx;
line-height: 60rpx;
border-radius: 40rpx;
font-size: 24rpx;
margin: 10rpx auto;
text-align: center;
}
/* 同意按钮 */
.agreeBtn {
background: rgba(187, 230, 0, 1);
color: #232323;
border: none;
width: 170rpx !important;
}
</style>

View File

@ -0,0 +1,197 @@
<template>
<view class="share">
<view class="device-title">已分享用户</view>
<view class="device-info" v-for="(item, index) in deviceList" :key="index">
<view class="device-header">
<view class="deviceIMG">
<image :src="item.devicePic" mode="" class="IMG"></image>
</view>
<view class="device-name">
<view>{{item.deviceName}}rr32r23r23</view>
<view class="ID">
<view class="ID">ID:{{item.deviceImei}}ererer
</view>
</view>
</view>
<view class="device-delete" @click="handleDelete">
<text class="delete">移除</text>
</view>
</view>
</view>
<!-- 删除弹框 -->
<view class="agreement-mask" v-if="deleteShow" @click="closePopup('delete')">
<view class="agreement-popup" @click.stop>
<view class="popup-content">
<image src="/static/images/dell.png" mode="" class="svg"></image>
<uni-icon class="trash"></uni-icon>
<view>
<view class="popup-Title">确定移除该用户</view>
</view>
</view>
<!-- 按钮组 -->
<view class="popup-buttons">
<button class="btn agreeBtn" @click="handleBtn">确定</button>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
deviceList: [{}],
deleteShow:false
}
},
methods: {
// 删除
handleDelete() {
this.deleteShow=true
},
handleBtn(){
this.deleteShow=false
}
}
}
</script>
<style scoped>
.share {
padding: 30rpx;
background: #121212;
min-height: 100vh;
}
.device-title {
color: rgba(255, 255, 255, 0.87);
padding: 30rpx 0;
}
.device-info {
font-size: 28rpx;
color: rgba(255, 255, 255, 0.87);
padding-top: 10rpx;
position: relative;
}
.device-header {
display: flex;
align-items: center;
margin-bottom: 15rpx;
}
.device-name {
font-size: 32rpx;
color: rgba(255, 255, 255, 0.87);
margin-left: 25rpx;
line-height: 50rpx;
white-space: nowrap;
}
.ID {
color: rgba(255, 255, 255, 0.6);
font-size: 26rpx;
}
.deviceIMG {
width: 100rpx;
height: 100rpx;
border-radius: 16rpx;
position: relative;
background-color: rgba(42, 42, 42, 0.6);
display: flex;
align-items: center;
}
.device-delete {
text-align: end;
width: 50%;
}
.delete {
border-radius: 32px;
background: rgba(255, 200, 78, 0.06);
display: inline-block;
width: 152rpx;
height: 60rpx;
text-align: center;
line-height: 60rpx;
color: rgba(255, 200, 78, 1);
cursor: pointer;
}
.IMG {
width: 68rpx;
height: 50rpx;
margin-left: 17%;
}
.title {
font-size: 18px;
color: white;
}
.device-info {
width: 100%;
padding: 10px;
background: rgba(26, 26, 26, 1);
border-radius: 16rpx;
}
/* 遮罩层 */
.agreement-mask {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
justify-content: center;
align-items: center;
z-index: 9999;
}
.popup-Title {
color: rgba(255, 255, 255, 0.86);
text-align: center;
padding: 30rpx 0rpx;
}
.popup-buttons {
display: flex;
text-align: center;
}
/* 弹窗主体 */
.agreement-popup {
width: 60%;
background-color: rgb(42, 42, 42);
border-radius: 40rpx;
padding: 30rpx;
text-align: center;
border: 1px solid rgba(255, 200, 78, 0.3);
}
.svg {
width: 58rpx;
height: 62rpx;
}
/* 通用按钮样式 */
.btn {
height: 60rpx;
line-height: 60rpx;
border-radius: 40rpx;
font-size: 24rpx;
margin: 10rpx auto;
text-align: center;
}
/* 同意按钮 */
.agreeBtn {
background: #FFC84E;
color: #232323;
border: none;
width: 170rpx !important;
}
</style>

View File

@ -530,7 +530,7 @@
.ID {
color: rgba(255, 255, 255, 0.6);
font-size: 24rpx;
font-size: 26rpx;
display: flex;
justify-content: space-between;
position: relative;

View File

@ -15,18 +15,20 @@
</view>
<view class="device-name">
<view>设备:{{item.deviceName}}</view>
<view class="ID">ID:{{ item.deviceImei }}</view>
<view class="ID">
<view class="ID" v-if="item.communicationMode==0">ID:{{item.deviceImei}}
</view>
<view class="ID" v-else>ID:{{item.deviceMac}}</view>
<!-- <view class="onlines" v-if="item.communicationMode==0">在线</view> -->
<view class="unlines" v-if="item.communicationMode==0">离线</view>
<view>电量90%</view>
</view>
</view>
</view>
<view class="" v-if="item.communicationMode==1">
<view class="device-status online">已连接</view>
<view class="device-status unline">未连接</view>
</view>
<view class="device-info">
<text class="onlines">在线</text>
<text class="line"></text>
<text>电量90</text>
</view>
</view>
</view>
<view style="padding:20rpx;">
@ -69,7 +71,7 @@
this.loading = true;
let data = {
pageNum: 1,
pageSize: 50,
pageSize: 20,
deviceType: deviceType
}
deviceInfo(data).then((res) => {
@ -107,24 +109,30 @@
min-height: 100vh;
background-color: rgb(18, 18, 18);
}
.header {
padding: 30rpx;
text-align: center;
}
.title {
font-size: 36rpx;
color: rgba(255, 255, 255, 0.87);
}
.device-list {
flex: 1;
padding: 0 20rpx;
margin-top: 20rpx;
}
.device-card {
position: relative;
display: flex;
align-items: center;
width: 94%;
width: 95%;
}
.checkbox {
width: 40rpx;
height: 40rpx;
@ -135,10 +143,12 @@
align-items: center;
justify-content: center;
}
.checkbox.checked {
background-color: rgb(187, 230, 0);
border-color: rgb(187, 230, 0);
}
.device-content {
background-color: rgb(26, 26, 26);
border-radius: 16rpx;
@ -147,23 +157,32 @@
/* display: flex; */
align-items: center;
padding: 20rpx;
width: 93%;
width: 95%;
}
.device-header {
display: flex;
align-items: center;
margin-bottom: 15rpx;
}
.device-name {
font-size: 32rpx;
color: rgba(255, 255, 255, 0.87);
margin-left: 24rpx;
margin-left: 12rpx;
line-height: 50rpx;
width: 83%;
white-space: nowrap;
}
.ID {
color: rgba(255, 255, 255, 0.6);
font-size: 26rpx;
display: flex;
justify-content: space-between;
position: relative;
}
.device-status {
width: 122rpx;
height: 52rpx;
@ -180,15 +199,18 @@
.online {
color: rgb(187, 230, 0);
}
.unline {
color: rgba(255, 255, 255, 0.4);
}
.device-info {
display: flex;
justify-content: space-evenly;
font-size: 28rpx;
font-size: 26rpx;
color: rgba(255, 255, 255, 0.87);
padding-top: 10rpx;
position: relative;
}
.deviceIMG {
@ -207,6 +229,10 @@
margin-left: 17%;
}
.onlines {
position: relative;
}
.onlines::before {
content: '';
position: absolute;
@ -214,8 +240,23 @@
height: 15rpx;
background: rgb(0, 171, 103);
border-radius: 50%;
left: 98rpx;
bottom: 32rpx
top: 20rpx;
left: -20rpx
}
.unlines {
position: relative;
}
.unlines::before {
content: '';
position: absolute;
width: 15rpx;
height: 15rpx;
background: rgba(255, 255, 255, 0.4);
border-radius: 50%;
top: 20rpx;
left: -20rpx
}
.line {
@ -242,9 +283,11 @@
border-radius: 16rpx;
background: rgb(26, 26, 26);
}
.textarea {
color: rgba(255, 255, 255, 0.8);
}
.login-btn {
margin-top: 30rpx;
background-color: rgb(187, 230, 0);

BIN
static/images/shape.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 278 B

BIN
static/images/success.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 510 B