2025-05-22 16:24:05 +08:00

560 lines
14 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="device-group-wrap">
<view class="search-wrap">
<div class="left-wrap">
<u-search v-model="queryParams.groupName" shape="square" @search="handleSearch" @custom="handleSearch"
:inputStyle="{ height: '64rpx' }" :placeholder="$tt('group.inputContent')"
:actionText="$tt('timing.search')"
:actionStyle="{ backgroundColor: '#398ade', color: '#fff', padding: '0 12rpx', borderRadius: '6rpx', height: '64rpx', lineHeight: '64rpx' }"></u-search>
</div>
<div class="right-wrap">
<u-button @click="handleAddGrup()" type="success" :text="$tt('common.add')" icon="plus"
:customStyle="{ width: '120rpx', height: '64rpx' }" size="small"></u-button>
</div>
</view>
<view class="card-wrap" v-for="(item, index) in dataList" :key="index" @click="handleEdit(item)">
<u-row gutter="10" customStyle="margin:0;">
<u-col :span="6"
customStyle="background-color:#3fd1ad; padding:40rpx; border-top-left-radius:10rpx; border-bottom-left-radius:10rpx;">
<u--text prefixIcon="grid" iconStyle="color:#fff; font-size:36rpx; margin-right:8rpx;" bold
lines="1" :text="item.groupName" customStyle="color:#fff; font-size: 32rpx;"></u--text>
</u-col>
<u-col :span="6">
<view class="button-group" @click.stop>
<u-button type="success" @click="handleAddDevice(item)" size="small"
customStyle="width:160rpx; height: 70rpx;">{{ $tt('group.add') }}</u-button>
<u-button type="info" @click="showDeviceSelector(item.groupId)" size="small"
customStyle="width:160rpx; height: 70rpx;">区域控制</u-button>
</view>
</u-col>
</u-row>
</view>
<!-- 区域控制弹窗 -->
<u-popup :show="showDevicePopup" mode="center" @close="closeDevicePopup" round="10">
<view class="area-control-popup">
<view class="popup-header">
<text class="popup-title">区域控制</text>
<u-icon name="close" size="20" @click="closeDevicePopup"></u-icon>
</view>
<view class="popup-content">
<!-- 设备类型选择 -->
<u-tabs :list="tabsList" :current="Number(activeMenu)" @click="handleMenuSelect"></u-tabs>
<!-- 安全王配置 -->
<view v-if="activeMenu === 0" class="security-king">
<u-form :model="formData" labelPosition="left">
<u-form-item label="参数上传时间间隔">
<u-input v-model="paramUploadInterval" placeholder="请输入参数上传时间间隔" />
</u-form-item>
<!-- <u-form-item label="接地电阻测试周期">
<u-input v-model="groundResistanceTestInterval" placeholder="请输入接地电阻测试周期" />
</u-form-item> -->
</u-form>
<view class="button-area">
<u-button type="success" @click="submitFormreglin(Security_King)">发送</u-button>
</view>
</view>
<!-- 单灯控配置 -->
<view v-if="activeMenu === 1" class="light-control">
<view class="time-select">
<text class="time-label">时间:</text>
<u-button @click="showTimePicker = true" type="info" size="small">
{{ startTime || '请选择开始时间' }}
</u-button>
</view>
<u-datetime-picker :show="showTimePicker" v-model="startTime" mode="time" @confirm="timeConfirm"
@cancel="timeCancel" :minuteStep="1" format="HH:mm"></u-datetime-picker>
<view class="light-table">
<view class="table-header">
<text style="width: 25%;">阶段</text>
<text style="width: 37.5%;">时长(分钟)</text>
<text style="width: 37.5%;">亮度(%)</text>
</view>
<view class="table-body">
<view class="table-row" v-for="(row, index) in tableData" :key="index">
<text style="width: 25%;">{{ row.segment }}</text>
<view style="width: 37.5%;">
<u-input v-model="row.duration" placeholder="输入时长" type="number" />
</view>
<view style="width: 37.5%;">
<u-input v-model="row.brightness" placeholder="输入亮度" type="number" />
</view>
</view>
</view>
</view>
<view class="button-area">
<u-button type="success" @click="submitlightcontrol(Single_lightcontrol)">发送配置</u-button>
</view>
</view>
</view>
</view>
</u-popup>
<u-empty mode="list" :show="total === 0" marginTop="30"></u-empty>
<u-loadmore :status="status" v-if="total > queryParams.pageSize" marginTop="20"
:nomoreText="$tt('group.nomore')" />
</view>
</template>
<script>
import {
getGroupList
} from '@/apis/modules/group';
import {
listDeviceShort
} from '@/apis/modules/device.js';
export default {
data() {
return {
status: 'nomore', // 加载更多
dataList: [], // 列表数据
total: 0, // 总条数
queryParams: {
pageNum: 1,
pageSize: 10,
userId: 0,
groupName: null,
},
showDevicePopup: false,
selectedDevices: [],
currentGroup: null,
deviceOptions: [
{ deviceName: '安全王' },
{ deviceName: '双灯控' }
],
tabsList: [
{ name: '安全王' },
{ name: '单灯控' }
],
activeMenu: 0,
showTimePicker: false,
startTime: '',
paramUploadInterval: '',
groundResistanceTestInterval: '',
tableData: [
{ segment: '阶段1', duration: '', brightness: '' },
{ segment: '阶段2', duration: '', brightness: '' },
{ segment: '阶段3', duration: '', brightness: '' }
],
Security_King: [],
Single_lightcontrol: [],
formData: {}, // 添加表单数据对象
timeParams: {
hour: true,
minute: true,
second: false
}
};
},
onLoad() {
this.getToken();
if (this.token != '' && this.token != null) {
this.connectMqtt();
}
this.queryParams.userId = this.profile.userId;
this.getList();
},
onShow() {
let operate = getApp().globalData.operate;
if (operate && operate == 'operate') {
this.getList();
// 置空 operate
getApp().globalData.operate = "";
}
},
methods: {
getToken() {
// 本地缓存获取token
this.token = uni.getStorageSync('token');
// vuex存储token
uni.$u.vuex('vuex_token', this.token);
},
// 连接Mqtt消息服务器
async connectMqtt() {
if (this.$mqttTool.client == null) {
await this.$mqttTool.connect(this.vuex_token);
}
this.mqttCallback();
this.getDatas();
},
// 获取列表数据
getList() {
getGroupList(this.queryParams).then(response => {
if (this.queryParams.pageNum == 1) {
this.dataList = response.rows;
} else {
this.dataList = this.dataList.concat(response.rows);
}
this.total = response.total;
uni.stopPullDownRefresh();
});
},
// 搜索
handleSearch(value) {
this.dataList = [];
this.queryParams.pageNum = 1;
this.getList(true);
},
// 新增
handleAddGrup() {
uni.navigateTo({
url: '/pagesB/user/deviceGroup/detail'
});
},
// 编辑
handleEdit(item) {
uni.navigateTo({
url: '/pagesB/user/deviceGroup/detail?groupId=' + item.groupId
});
},
// 选择分组设备
handleAddDevice(item) {
uni.navigateTo({
url: '/pagesB/user/deviceGroup/devices?groupId=' + item.groupId + '&groupUserId=' +
item.userId
});
},
// 下拉刷新
onPullDownRefresh() {
this.dataList = [];
this.queryParams.pageNum = 1;
this.getList(); // Http获取列表
},
// 上拉加载
onReachBottom() {
this.status = 'loading';
this.queryParams.pageNum = this.queryParams.pageNum + 1;
if ((this.queryParams.pageNum - 1) * this.queryParams.pageSize > this.total) {
this.status = 'nomore';
} else {
this.getList();
this.status = 'loading';
}
},
// 显示设备选择弹窗
showDeviceSelector(group) {
this.currentGroup = group;
console.log('当前分组:', JSON.stringify(this.currentGroup));
this.showDevicePopup = true;
// 这里可以添加获取可选设备列表的接口调用
this.getAvailableDevices();
},
// 获取可选设备列表
getAvailableDevices() {
const GroupListqueryParams = {
pageNum: 1,
pageSize: 12,
showChild: true,
groupId: this.currentGroup,
};
listDeviceShort(GroupListqueryParams).then((response) => {
this.deviceList = response.rows;
this.total = response.total;
// 按 productId 分成两个数组
const lightcontrol = this.deviceList.filter(device => device.productId === 138);
const Security = this.deviceList.filter(device => device.productId === 136);
this.Security_King = Security;
this.Single_lightcontrol = lightcontrol;
console.log("安全王设备:", JSON.stringify(this.Security_King));
console.log("单灯控设备:", JSON.stringify(this.Single_lightcontrol));
});
},
// 关闭设备选择弹窗
closeDevicePopup() {
this.showDevicePopup = false;
this.selectedDevices = [];
this.currentGroup = null;
},
// 确认设备选择
confirmDeviceSelection() {
if (this.selectedDevices.length === 0) {
uni.showToast({
title: '请选择设备',
icon: 'none'
});
return;
}
// 这里添加关联设备的逻辑
console.log('选中的设备:', this.selectedDevices);
console.log('当前分组:', this.currentGroup);
// 示例调用关联设备的API
// linkDevicesToGroup({
// groupId: this.currentGroup.groupId,
// deviceIds: this.selectedDevices
// }).then(res => {
// if (res.code === 200) {
// uni.showToast({
// title: '关联成功',
// icon: 'success'
// });
// this.closeDevicePopup();
// this.getList(); // 刷新列表
// }
// });
// 临时显示成功提示
uni.showToast({
title: '关联成功',
icon: 'success'
});
this.closeDevicePopup();
},
// 连接Mqtt消息服务器
async connectMqtt() {
if (this.$mqttTool.client == null) {
await this.$mqttTool.connect(this.vuex_token);
}
},
// 订阅消息
mqttSubscribe(list) {
// 订阅当前页面设备状态和实时监测
let topics = [];
for (let i = 0; i < list.length; i++) {
let topicStatus = '/' + list[i].productId + '/' + list[i].serialNumber + '/status/post';
topics.push(topicStatus);
}
this.$mqttTool.subscribe(topics);
},
// 提交安全王配置
submitFormreglin(devicelist) {
let message = [{
"id": "report_time_min",
"remark": "",
"value": this.paramUploadInterval || "0"
}];
console.log("安全王设置下发数据:", JSON.stringify(message));
this.AreamqttSubscribe(devicelist, JSON.stringify(message));
},
// 提交单灯控配置
submitlightcontrol(devicelist) {
console.log('当前时间值:', this.startTime);
// 默认值
let startHour = '00';
let startMinute = '00';
// 解析时间字符串
if (this.startTime && typeof this.startTime === 'string') {
const timeParts = this.startTime.split(':');
if (timeParts.length === 2) {
startHour = String(timeParts[0]).padStart(2, '0');
startMinute = String(timeParts[1]).padStart(2, '0');
}
}
let message = [
{
"id": "S1_startH",
"remark": "",
"value": startHour
},
{
"id": "S1_startM",
"remark": "",
"value": startMinute
},
{
"id": "S1_seg1M",
"remark": "",
"value": this.tableData[0].duration || "0"
},
{
"id": "S1_seg1B",
"remark": "",
"value": this.tableData[0].brightness || "0"
},
{
"id": "S1_seg2M",
"remark": "",
"value": this.tableData[1].duration || "0"
},
{
"id": "S1_seg2B",
"remark": "",
"value": this.tableData[1].brightness || "0"
},
{
"id": "S1_seg3M",
"remark": "",
"value": this.tableData[2].duration || "0"
},
{
"id": "S1_seg3B",
"remark": "",
"value": this.tableData[2].brightness || "0"
}
];
console.log("单灯控设置下发数据:", JSON.stringify(message));
this.AreamqttSubscribe(devicelist, JSON.stringify(message));
},
// MQTT订阅和发布
AreamqttSubscribe(list, message) {
let topics = [];
for (let i = 0; i < list.length; i++) {
let topicService = '/' + list[i].productId + '/' + list[i].serialNumber + '/function/get';
topics.push(topicService);
this.$mqttTool.subscribe([topicService]);
this.$mqttTool.publish(topicService, message, list[i].serialNumber)
.then((res) => {
console.log(res);
})
.catch((err) => {
console.log(err);
});
}
console.log("Subscribe Topics:", JSON.stringify(topics));
uni.showToast({
title: '指令下发成功',
icon: 'success'
});
},
timeConfirm(e) {
console.log('选择的时间:', e);
// 直接保存时分
this.startTime = {
hour: e, // 直接保存选择的时间值
minute: e
};
this.showTimePicker = false;
},
timeCancel() {
this.showTimePicker = false;
},
handleMenuSelect(item) {
this.activeMenu = Number(item.index);
}
}
};
</script>
<style lang="scss">
page {
background: #eef3f7;
}
.device-group-wrap {
.search-wrap {
padding: 20rpx;
background: #ffffff;
display: flex;
flex-direction: row;
align-items: center;
.left-wrap {
flex: 1;
}
.right-wrap {
margin-left: 20rpx;
}
}
.card-wrap {
box-shadow: 0 2rpx 0 0 rgba(0, 0, 0, 0.1);
border-radius: 10rpx;
margin: 20rpx;
background-color: #ffffff;
min-height: 120rpx;
cursor: pointer;
transition: all 0.3s;
&:active {
opacity: 0.8;
}
.button-group {
display: flex;
gap: 10rpx;
padding: 10rpx;
justify-content: center;
align-items: center;
height: 100%;
}
}
}
.area-control-popup {
width: 90vw;
max-height: 80vh;
background-color: #fff;
border-radius: 20rpx;
.popup-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 30rpx;
border-bottom: 1rpx solid #eee;
.popup-title {
font-size: 32rpx;
font-weight: bold;
}
}
.popup-content {
padding: 20rpx;
.time-select {
display: flex;
align-items: center;
margin: 20rpx 0;
.time-label {
margin-right: 10rpx;
font-size: 28rpx;
}
}
.light-table {
border: 1rpx solid #eee;
border-radius: 10rpx;
margin: 20rpx 0;
.table-header {
display: flex;
background-color: #f5f7fa;
padding: 20rpx;
text-align: center;
}
.table-row {
display: flex;
padding: 20rpx;
border-top: 1rpx solid #eee;
align-items: center;
text-align: center;
}
}
.button-area {
margin-top: 30rpx;
text-align: center;
}
}
}
</style>