2025-05-22 16:37:43 +08:00

1057 lines
27 KiB
Vue
Raw Permalink 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="relay-control">
<!-- 设备状态 -->
<!-- <button type="default" @click="consolebutton()">ceshi </button> -->
<view class="card">
<view class="status-titletop">{{title}}</view>
<view style="padding:20rpx;">
<u--form labelPosition="left" labelWidth="100"
:labelStyle="{ marginRight: '16px', lineHeight: '32px', width: '50px', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis',color: '#000000' }">
<view class="version-wrap">
<u-form-item :label="$tt('status.deviceVersion')">
<u-row>
<u-col span="8">
<u--text :text="'Version' + device.firmwareVersion"></u--text>
</u-col>
</u-row>
</u-form-item>
</view>
</u--form>
</view>
</view>
<!-- 继电器状态显示 -->
<view class="relay-status">
<view class="status-title">继电器状态</view>
<view class="relay-grid">
<view class="relay-item" v-for="(item, index) in relayList" :key="index">
<!-- 可点击的继电器名称 -->
<view class="relay-name" @click="checkOnline(editRelayName, index)">
{{item.remark}}
<u-icon name="edit-pen" size="16" color="#999"></u-icon>
</view>
<view class="relay-state" :class="{'active': item.status === 1}">
{{item.status === 1 ? '开启' : '关闭'}}
</view>
<u-button type="primary" size="mini" @click="checkOnline(toggleRelay, index)"
:disabled="device.status !== 3">
{{item.status === 1 ? '关闭' : '开启'}}
</u-button>
</view>
</view>
</view>
<!-- 时间方案配置 -->
<!-- <view class="time-schedule">
<view class="schedule-title">时间方案配置</view>
<view class="schedule-list">
<view class="schedule-item" v-for="(item, index) in scheduleList" :key="index">
<view class="schedule-info">
<text>时间:{{item.time}}</text>
<text>动作:{{item.action === 1 ? '开启' : '关闭'}}</text>
<text>继电器:{{item.relayIndexes.map(index => index + 1).join(', ')}}</text>
<text>重复日期:{{item.weekdays.map(index => weekdays[index]).join(', ')}}</text>
</view>
<u-button type="error" size="mini" @click="deleteSchedule(index)">删除</u-button>
</view>
</view>
<view class="add-schedule">
<u-button type="primary" @click="showAddSchedule">添加时间方案</u-button>
</view>
</view> -->
<!-- 时间方案配置 -->
<view class="time-schedule">
<view class="schedule-header">
<view class="schedule-title">时间方案配置</view>
<view style="display: flex; justify-content: flex-end;">
<u-button style="width: 180rpx; height: 40rpx;" type="primary" size="mini"
@click="checkOnline(showAddSchedule)" :disabled="device.status !== 3">
添加
</u-button>
</view>
</view>
<view class="empty-tip" v-if="scheduleList.length === 0">
<u-icon name="list" size="50" color="#c0c4cc"></u-icon>
<text>暂无时间方案,点击添加按钮创建</text>
</view>
<view class="schedule-list">
<view class="schedule-card" v-for="(item, index) in scheduleList" :key="index">
<view class="schedule-time">
<u-icon name="clock" size="18" color="#3c9cff"></u-icon>
<text>{{item.time}}</text>
</view>
<view class="schedule-content">
<!-- <view class="schedule-row">
<text class="label">动作</text>
<u-tag :text="item.action === 1 ? '开启' : '关闭'"
:type="item.action === 1 ? 'success' : 'error'" size="mini"></u-tag>
</view> -->
<view class="schedule-row">
<text class="label">继电器</text>
<view class="relay-tags">
<u-tag v-for="relayIndex in item.relayIndexes" :key="relayIndex"
:text="'继电器' + (relayIndex + 1)" type="primary" size="mini"></u-tag>
</view>
</view>
<view class="schedule-row">
<text class="label">重复日期</text>
<view class="weekday-tags">
<u-tag v-for="dayIndex in item.weekdays" :key="dayIndex" :text="weekdays[dayIndex]"
plain size="mini"></u-tag>
</view>
</view>
</view>
<view class="schedule-actions">
<u-button type="error" size="mini" plain @click="checkOnline(deleteSchedule, index)"
:disabled="device.status !== 3">
删除
</u-button>
</view>
</view>
</view>
</view>
<!-- 添加时间方案弹窗 -->
<u-popup :show="showPopup" mode="center">
<view class="popup-content">
<view class="popup-title">添加时间方案</view>
<u--form :model="scheduleForm" ref="uForm">
<u-form-item label="时间">
<u-input v-model="scheduleForm.time" placeholder="请选择时间" @focus="openTimePicker" />
</u-form-item>
<!-- <u-form-item label="动作">
<u-radio-group v-model="scheduleForm.action">
<u-radio :name="1" label="开启"></u-radio>
<u-radio :name="0" label="关闭"></u-radio>
</u-radio-group>
</u-form-item> -->
<u-form-item label="选择继电器">
<u-checkbox-group v-model="scheduleForm.relayIndexes">
<u-checkbox v-for="(item, index) in relayList" :key="index" :name="index" shape="circle"
:label="item.name" class="custom-checkbox">
</u-checkbox>
</u-checkbox-group>
</u-form-item>
<u-form-item label="重复日期">
<u-checkbox-group v-model="scheduleForm.weekdays" class="repeat-weekdays-group">
<u-checkbox v-for="(day, index) in weekdays" :key="index" :name="index" shape="circle"
:label="day" class="custom-checkbox">
{{ day }}
</u-checkbox>
</u-checkbox-group>
</u-form-item>
</u--form>
<view class="popup-buttons">
<u-button @click="showPopup = false">取消</u-button>
<u-button type="primary" @click="addSchedule">确定</u-button>
</view>
</view>
</u-popup>
<!-- 时间选择器 -->
<u-datetime-picker :show="showTimePicker" v-model="tempTime" mode="time" @confirm="timeConfirm"
@cancel="showTimePicker = false" />
<!-- 继电器名称编辑弹窗 -->
<u-popup :show="showRelayEditPopup" mode="center" @close="showRelayEditPopup = false">
<view class="popup-content">
<view class="popup-title">修改继电器名称</view>
<u--form :model="relayEditForm" ref="uForm">
<!-- <u-form-item label="名称">
<u-input v-model="relayEditForm.name" placeholder="请输入继电器名称" />
</u-form-item> -->
<u-form-item label="备注">
<u-input v-model="relayEditForm.remark" placeholder="请输入备注信息" />
</u-form-item>
</u--form>
<view class="popup-buttons">
<u-button @click="showRelayEditPopup = false">取消</u-button>
<u-button type="primary" @click="confirmRelayEdit">确定</u-button>
</view>
</view>
</u-popup>
</view>
</template>
<script>
import {
getLatestFirmware,
relateChannelList,
getOrderControl
} from '@/apis/modules/device.js';
import {
serviceInvoke
} from '@/apis/modules/runtime.js';
import {
getSipStatusInfo,
getLocationWayInfo
} from '@/helpers/common.js'
export default {
name: 'relay-control',
props: {
device: {
type: Object,
default: null,
required: true
}
},
created() {
// 1秒后执行提取继电器列表
setTimeout(() => {
this.extractRelayList();
this.parseScheduleConfig(); // 解析时间方案 、
// this.consolebutton()
}, 1000);
this.updateDeviceStatus(this.device);
this.mqttCallback();
},
onLoad: function(option) {
console.log(JSON.stringify(this.device))
},
data() {
return {
title: '设备离线',
show: false,
firmware: {},
showTimePicker: false,
showPopup: false,
tempTime: '',
weekdays: ['周日', '周一', '周二', '周三', '周四', '周五', '周六'],
bgStyle: '',
shadowUnEnable: false,
scheduleList: [], // 初始化为空数组,等待解析数据
showRelayEditPopup: false,
relayEditForm: {
index: null,
name: '',
remark: ''
},
relayList: [], // 初始化为空数组,等待提取数据
scheduleList: [],
scheduleForm: {
time: '12:00:00',
action: 1,
relayIndexes: [],
weekdays: []
}
}
},
methods: {
// 检查设备是否在线
checkOnline(callback, ...args) {
if (this.device.status !== 3) {
uni.showToast({
title: '设备离线,无法操作',
icon: 'none'
});
return false;
}
if (typeof callback === 'function') {
return callback.apply(this, args);
}
return true;
},
// 编辑继电器名称
editRelayName(index) {
if (!this.checkOnline()) return;
this.relayEditForm = {
index,
name: this.relayList[index].name,
remark: this.relayList[index].remark || ''
};
this.showRelayEditPopup = true;
},
// 确认修改继电器信息
async confirmRelayEdit() {
try {
const {
index,
name,
remark
} = this.relayEditForm;
// 1. 更新本地数据
this.relayList[index].name = name;
this.relayList[index].remark = remark;
// 2. 找到对应的备注物模型
const channel = index + 1; // 继电器通道号(1-4)
const remarkModel = this.device.thingsModels.find(
item => item.id === `remark_ch${channel}`
);
if (remarkModel) {
// 3. 更新物模型值
remarkModel.shadow = remark;
// 4. 通过MQTT发布更新
await this.mqttPublish(this.device, remarkModel);
}
this.showRelayEditPopup = false;
uni.showToast({
title: '修改成功',
icon: 'success'
});
} catch (error) {
console.error(' 修改继电器信息失败:', error);
uni.showToast({
title: '修改失败: ' + error.message,
icon: 'none'
});
}
},
// 解析时间方案配置
parseScheduleConfig() {
try {
// 从 thingsModelValue 中找到 cfg_param
const thingsModelValue = JSON.parse(this.device.thingsModelValue);
const cfgParam = thingsModelValue.find(item => item.id === 'cfg_param');
if (cfgParam && cfgParam.value) {
// 提取 JSON 部分(去掉前面的 "JSON="
const jsonStr = cfgParam.value.startsWith('JSON=') ?
cfgParam.value.substring(5) :
cfgParam.value;
// 解析 JSON
const config = JSON.parse(jsonStr);
// 转换格式为 scheduleList 需要的格式
this.scheduleList = config.shedule.map(item => {
// 将 time_s秒数转换为 HH:mm:ss 格式
const hours = Math.floor(item.time_s / 3600);
const minutes = Math.floor((item.time_s % 3600) / 60);
const seconds = item.time_s % 60;
const time =
`${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
// 将 week 字符串转换为 weekdays 数组
const weekdays = item.week.split('').map((day, index) => day === '1' ? index : null)
.filter(index => index !== null);
// 获取选中的继电器索引
const relayIndexes = [];
if (item.sw1_s === 1) relayIndexes.push(0);
if (item.sw2_s === 1) relayIndexes.push(1);
if (item.sw3_s === 1) relayIndexes.push(2);
if (item.sw4_s === 1) relayIndexes.push(3);
return {
time,
action: relayIndexes.length > 0 ? 1 : 0, // 如果有选中的继电器则为开启
relayIndexes,
weekdays,
originalData: item // 保留原始数据
};
});
console.log(' 解析出的时间方案:', this.scheduleList);
}
} catch (error) {
console.error(' 解析时间方案配置出错:', error);
}
},
// 提取继电器列表
extractRelayList() {
// 从 device.thingsModels 中筛选出所有开关状态属性
const relayItems = this.device.thingsModels.filter(item =>
item.id.startsWith('sw_ch') && item.datatype.type === 'bool'
);
// 转换为继电器列表格式
this.relayList = relayItems.map((item, index) => ({
name: `继电器${index + 1}`,
status: parseInt(item.shadow) || 0, // 确保是数字类型
remark: this.getRelayRemark(index + 1), // 获取对应通道的备注
model: JSON.parse(JSON.stringify(item)) // 深拷贝物模型对象
}));
console.log(' 继电器列表:', JSON.stringify(this.relayList));
},
// 获取继电器备注(从 remark_chX 属性)
getRelayRemark(channel) {
const remarkItem = this.device.thingsModels.find(item =>
item.id === `remark_ch${channel}`
);
return remarkItem ? remarkItem.shadow : '';
},
// mqtt回调
/* Mqtt回调处理 */
mqttCallback() {
this.$mqttTool.client.on('message', (topic, message, buffer) => {
let topics = topic.split('/');
let productId = topics[1];
let deviceNum = topics[2];
message = JSON.parse(message.toString());
// 判断是否是当前设备的消息
if (this.device.serialNumber !== deviceNum) return;
// 处理状态更新
if (topics[3] == 'status') {
console.log(' 接收到【设备状态-运行】主题:', topic);
console.log(' 接收到【设备状态-运行】内容:', JSON.stringify(message));
this.device.status = message.status;
this.device.isShadow = message.isShadow;
this.device.rssi = message.rssi;
this.updateDeviceStatus(this.device);
}
// 处理物模型属性更新
else if (topics[3] == 'property' || topics[3] == 'function' || topic.endsWith('ws/service')) {
console.log(' 接收到【物模型】主题:', topic);
console.log(' 接收到【物模型】内容:', JSON.stringify(message));
// 更新继电器状态
if (Array.isArray(message.message)) {
message.message.forEach(item => {
// 检查是否是继电器状态更新
if (item.id && item.id.startsWith('sw_ch')) {
const channel = parseInt(item.id.replace('sw_ch', ''));
if (!isNaN(channel) && channel >= 1 && channel <= 4) {
const index = channel - 1;
this.relayList[index].status = parseInt(item.value) || 0;
}
}
// 检查是否是继电器备注更新
else if (item.id && item.id.startsWith('remark_ch')) {
const channel = parseInt(item.id.replace('remark_ch', ''));
if (!isNaN(channel) && channel >= 1 && channel <= 4) {
const index = channel - 1;
this.relayList[index].remark = item.value || '';
}
}
});
}
}
});
},
//发送指令
async mqttPublish(device, model) {
const command = {};
command[model.id] = model.shadow;
const params = {
deviceId: device.deviceId,
modelId: model.modelId
}
//判断是否有权限
const response = await getOrderControl(params);
if (response.code != 200) {
uni.$u.toast(response.msg);
return;
}
const data = {
serialNumber: device.serialNumber,
productId: device.productId,
remoteCommand: command,
identifier: model.id,
modelName: model.name,
isShadow: device.status != 3,
type: model.type,
}
serviceInvoke(data).then(response => {
if (response.code === 200) {
uni.showToast({
icon: 'none',
title: this.$tt('status.service')
});
}
})
},
/** 更新设备状态 */
updateDeviceStatus(device) {
if (device.status === 3) {
this.title = this.$tt('status.online');
this.bgStyle =
'background-color:#5ac725;border-top-left-radius:6px;border-top-right-radius:6px;';
this.shadowUnEnable = false;
} else {
if (device.isShadow === 1) {
this.bgStyle =
'background-color:#3c9cff;border-top-left-radius:6px;border-top-right-radius:6px;';
this.title = this.$tt('status.shadow');
this.shadowUnEnable = false;
} else {
this.bgStyle =
'background-color:#909399;border-top-left-radius:6px;border-top-right-radius:6px;';
this.title = this.$tt('status.deviceOffline');
this.shadowUnEnable = true;
}
}
},
consolebutton() {
console.log("按钮打印", JSON.stringify(this.device))
},
// 切换继电器状态
async toggleRelay(index) {
if (!this.checkOnline()) return;
try {
// 1. 更新本地状态
const newStatus = this.relayList[index].status === 1 ? 0 : 1;
this.relayList[index].status = newStatus;
// 2. 找到对应的物模型
const channel = index + 1; // 继电器通道号(1-4)
const switchModel = this.device.thingsModels.find(
item => item.id === `sw_ch${channel}`
);
if (switchModel) {
// 3. 更新物模型值
switchModel.shadow = newStatus.toString();
// 4. 通过MQTT发布更新
await this.mqttPublish(this.device, switchModel);
}
} catch (error) {
console.error(' 切换继电器状态失败:', error);
// 回滚状态
this.relayList[index].status = this.relayList[index].status === 1 ? 0 : 1;
uni.showToast({
title: '操作失败: ' + error.message,
icon: 'none'
});
}
},
showAddSchedule() {
if (!this.checkOnline()) return;
const now = new Date();
const hours = now.getHours().toString().padStart(2, '0');
const minutes = now.getMinutes().toString().padStart(2, '0');
const seconds = now.getSeconds().toString().padStart(2, '0');
this.scheduleForm = {
time: `${hours}:${minutes}:${seconds}`,
action: 1,
relayIndexes: [],
weekdays: []
};
this.showPopup = true;
},
openTimePicker() {
this.showTimePicker = true;
this.tempTime = new Date(); // 打开时初始化临时时间
},
timeConfirm(e) {
const time = new Date(e.value);
const hours = time.getHours().toString().padStart(2, '0');
const minutes = time.getMinutes().toString().padStart(2, '0');
const seconds = time.getSeconds().toString().padStart(2, '0');
this.scheduleForm.time = `${hours}:${minutes}:${seconds}`;
this.showTimePicker = false;
},
async addSchedule() {
try {
// 1. 添加时间方案到本地列表
const newSchedule = {
...this.scheduleForm
};
this.scheduleList.push(newSchedule);
this.showPopup = false;
// 2. 转换为设备需要的格式
const deviceSchedule = this.convertToDeviceSchedule(newSchedule);
// 3. 准备要发送的数据
const scheduleConfig = {
shedule: [...this.scheduleList.map(s => s.originalData || this.convertToDeviceSchedule(s))]
};
// 4. 找到 cfg_param 模型
const cfgParamModel = this.device.thingsModels.find(item => item.id === 'cfg_param');
if (!cfgParamModel) {
throw new Error('找不到定时配置模型');
}
// 5. 更新模型值
cfgParamModel.shadow = `JSON=${JSON.stringify(scheduleConfig)}`;
// 6. 通过 MQTT 发布
await this.mqttPublish(this.device, cfgParamModel);
uni.showToast({
title: '时间方案添加成功',
icon: 'success'
});
} catch (error) {
console.error(' 添加时间方案失败:', error);
uni.showToast({
title: '添加失败: ' + error.message,
icon: 'none'
});
}
},
// 将前端格式转换为设备格式
convertToDeviceSchedule(schedule) {
// 将 HH:mm:ss 转换为秒数
const [hours, minutes, seconds] = schedule.time.split(':').map(Number);
const time_s = hours * 3600 + minutes * 60 + seconds;
// 将星期数组转换为字符串
const weekArr = new Array(7).fill('0');
schedule.weekdays.forEach(day => weekArr[day] = '1');
const week = weekArr.join('');
// 设置继电器状态
const relayStatus = [0, 0, 0, 0]; // 默认全部关闭
schedule.relayIndexes.forEach(index => relayStatus[index] = 1);
return {
time_s,
week,
sw1_s: relayStatus[0],
sw2_s: relayStatus[1],
sw3_s: relayStatus[2],
sw4_s: relayStatus[3]
};
},
async deleteSchedule(index) {
if (!this.checkOnline()) return;
try {
// 1. 从列表中删除
this.scheduleList.splice(index, 1);
// 2. 准备要发送的数据
const scheduleConfig = {
shedule: this.scheduleList.map(s => s.originalData || this.convertToDeviceSchedule(s))
};
// 3. 找到 cfg_param 模型
const cfgParamModel = this.device.thingsModels.find(item => item.id === 'cfg_param');
if (!cfgParamModel) {
throw new Error('找不到定时配置模型');
}
// 4. 更新模型值
cfgParamModel.shadow = `JSON=${JSON.stringify(scheduleConfig)}`;
// 5. 通过 MQTT 发布
await this.mqttPublish(this.device, cfgParamModel);
uni.showToast({
title: '删除成功',
icon: 'success'
});
} catch (error) {
console.error(' 删除时间方案失败:', error);
uni.showToast({
title: '删除失败: ' + error.message,
icon: 'none'
});
}
},
}
}
</script>
<style lang="scss" scoped>
/* 添加禁用状态的样式 */
.u-button[disabled] {
opacity: 0.6;
cursor: not-allowed;
}
.relay-name[disabled] {
opacity: 0.6;
cursor: not-allowed;
}
/* 继电器名称样式 */
.relay-name {
color: #333;
font-weight: 500;
margin-bottom: 10rpx;
display: flex;
align-items: center;
justify-content: center;
gap: 8rpx;
padding: 8rpx;
border-radius: 8rpx;
}
.relay-name:active {
background-color: #f0f0f0;
}
/* 编辑图标样式 */
.u-icon-edit-pen {
opacity: 0.6;
transition: opacity 0.3s;
}
.relay-name:hover .u-icon-edit-pen {
opacity: 1;
}
.empty-tip {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 40rpx 0;
color: #c0c4cc;
font-size: 28rpx;
gap: 20rpx;
}
.card {
box-shadow: 0 1px 0px 0 rgba(0, 0, 0, 0.1);
border-radius: 20rpx;
background-color: #fff;
&:not(:last-child) {
margin-bottom: 20rpx;
}
.status-title {
font-weight: bold;
font-size: 15px;
color: #333333;
line-height: 42rpx;
text-align: left;
font-style: normal;
text-transform: none;
padding: 15rpx 28rpx;
}
.version-wrap {
background-color: #F7F7F7;
border-radius: 10rpx;
padding: 0 42rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 400;
font-size: 24rpx;
color: #000000;
line-height: 42rpx;
text-align: left;
font-style: normal;
}
}
// 重复日期的 u-checkbox-group 布局
::v-deep .repeat-weekdays-group {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 15rpx;
padding: 10rpx 0;
.custom-checkbox {
justify-content: center;
}
}
.relay-control {
padding: 20rpx;
.relay-status,
.time-schedule {
background-color: #fff;
border-radius: 12rpx;
padding: 20rpx;
margin-bottom: 20rpx;
}
.schedule-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20rpx;
}
.schedule-title {
font-size: 32rpx;
font-weight: bold;
color: #333;
}
.schedule-list {
display: flex;
flex-direction: column;
gap: 20rpx;
}
.schedule-card {
background-color: #f9f9f9;
border-radius: 12rpx;
padding: 20rpx;
display: flex;
flex-direction: column;
gap: 15rpx;
position: relative;
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
}
.schedule-time {
display: flex;
align-items: center;
gap: 10rpx;
font-size: 28rpx;
font-weight: bold;
color: #333;
}
.schedule-content {
display: flex;
flex-direction: column;
gap: 12rpx;
padding-left: 28rpx;
/* 对齐图标 */
}
.schedule-row {
display: flex;
align-items: center;
font-size: 26rpx;
}
.label {
color: #666;
min-width: 120rpx;
}
.relay-tags,
.weekday-tags {
display: flex;
flex-wrap: wrap;
gap: 8rpx;
}
.schedule-actions {
display: flex;
justify-content: flex-end;
margin-top: 10rpx;
}
/* 响应式调整 */
@media (min-width: 768px) {
.schedule-card {
flex-direction: row;
align-items: center;
justify-content: space-between;
}
.schedule-content {
flex: 1;
flex-direction: row;
flex-wrap: wrap;
gap: 15rpx 30rpx;
}
.schedule-row {
margin-bottom: 0;
}
.schedule-actions {
margin-top: 0;
}
}
.status-title,
.schedule-title {
font-size: 32rpx;
font-weight: bold;
margin-bottom: 20rpx;
}
.status-titletop {
font-weight: bold;
font-size: 15px;
color: #333333;
line-height: 42rpx;
text-align: left;
font-style: normal;
text-transform: none;
padding: 15rpx 28rpx;
}
.relay-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 20rpx;
}
.relay-item {
background-color: #f5f5f5;
padding: 20rpx;
border-radius: 8rpx;
text-align: center;
.relay-name {
font-size: 28rpx;
margin-bottom: 10rpx;
}
.relay-state {
font-size: 24rpx;
color: #666;
margin-bottom: 10rpx;
&.active {
color: #2979ff;
}
}
}
.schedule-list {
.schedule-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 20rpx;
border-bottom: 1px solid #eee;
.schedule-info {
display: flex;
flex-direction: column;
gap: 10rpx;
}
}
}
.add-schedule {
margin-top: 20rpx;
text-align: center;
}
.popup-content {
background-color: #fff;
padding: 30rpx;
border-radius: 12rpx;
width: 600rpx;
.popup-title {
text-align: center;
font-size: 32rpx;
font-weight: bold;
margin-bottom: 30rpx;
}
.popup-buttons {
display: flex;
justify-content: space-around;
margin-top: 30rpx;
}
// 表单项样式
::v-deep .u-form-item {
margin-bottom: 20rpx;
.u-form-item__body {
padding: 10rpx 0;
}
}
// 继电器选择区域
::v-deep .u-checkbox-group {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 15rpx;
padding: 10rpx 0;
}
// 星期选择区域
// 星期选择区域
::v-deep .u-checkbox-group+.u-checkbox-group {
width: 100%;
display: grid;
grid-template-columns: repeat(4, 1fr);
/* 每行放4个 */
grid-auto-rows: auto;
/* 高度自适应 */
gap: 15rpx;
padding: 10rpx 0;
justify-content: center;
}
// 自定义复选框样式
::v-deep .custom-checkbox {
background-color: #f8f8f8;
padding: 12rpx 8rpx;
border-radius: 6rpx;
text-align: center;
display: flex;
align-items: center;
justify-content: center;
min-height: 50rpx;
border: 1px solid #eee;
margin: 0 auto;
width: 90%;
&:hover {
background-color: #f0f0f0;
}
// 修改文本样式
::v-deep text {
white-space: normal !important;
word-break: break-all;
line-height: 1.2;
font-size: 26rpx;
color: #333;
margin-left: 6rpx;
}
// 调整复选框图标位置
::v-deep .u-checkbox__icon-wrap {
margin: 0;
transform: scale(0.85);
}
}
// 表单容器样式
::v-deep .u-form {
width: 100%;
}
// 表单项样式
::v-deep .u-form-item__body {
padding: 0;
width: 100%;
}
// 动作选择样式
::v-deep .u-radio-group {
display: flex;
gap: 30rpx;
padding: 10rpx 0;
}
}
}
</style>