1057 lines
27 KiB
Vue
Raw Normal View History

2025-05-22 16:37:43 +08:00
<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>