Sprinkler-app/page_user/dingshi.vue
2025-09-22 15:24:01 +08:00

995 lines
25 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>
<u-navbar :is-back="true" title='定时管理' title-color="#000" :border-bottom="false" :background="bgc" id="navbar">
</u-navbar>
<image class="bj" src="https://api.ccttiot.com/smartmeter/img/static/urqUoIyCCEBykZ2oG8eO" mode=""></image>
<!-- 加载提示 -->
<u-loading-page :loading="isLoading" loading-text="数据同步中..."></u-loading-page>
<view class="" v-if="pre == 'WATER'">
<view class="list" v-if="list.length > 0 || list != null">
<view class="list_val" v-for="(values, key, index) in list" :key="key">
<view class="lt" @click="btnitem(key,index,values)">
<view class="one">{{ formattedTime(values[0], values[1]) }}</view>
<view class="two">P{{ index + 1 }} <text></text> {{ formatTime(values[2]) }}</view>
<view class="two">{{ formatInterval(values[4]) }}</view>
</view>
<view class="rt">
<u-switch v-model="values[3]" @change="btnchange(key,index,values)" active-color="#48893B"
inactive-color="#BDBCBC"></u-switch>
</view>
</view>
</view>
<!-- 设置浇水时间弹窗 -->
<view class="jiaoshui" v-if="timeflag">
<view class="top">
设置浇水
</view>
<view class="jssc">
请设置浇水时间
</view>
<view class="shifen" @click="btnshowone">
<text>{{hour}}时</text> <text>{{minutekq}}分</text>
</view>
<view class="jssc">
浇水时长
</view>
<view class="shifen" @click="btnshowtwo">
<text>{{minute}}分</text> <text>{{second}}秒</text>
</view>
<view class="jiange">
<text>每几天浇一次</text>
<view class="number-input">
<text class="btn-minus" @click="changeDays(-1)">-</text>
<text class="days">{{jgtian || 1}}</text>
<text class="btn-plus" @click="changeDays(1)">+</text>
</view>
</view>
<view class="anniu">
<view class="qx" @click="btnqx">
取消
</view>
<view class="qd" @click="btnqd">
确定
</view>
</view>
</view>
<view class="mask" v-if="timeflag"></view>
<!-- 定时时间 -->
<u-picker v-model="show" mode="time" :params="paramss" :defaultTime="defaultTime" @confirm="confirm"></u-picker>
<!-- 定时时长 -->
<u-picker v-model="shows" mode="time" :params="params" :defaultTime="defaultTimeLength" @confirm="confirms"></u-picker>
<view class="mask" style="z-index: 9999;" v-if="kgflag"></view>
</view>
<view class="choushuiben" v-else>
<view class="tit">
浇水设置
</view>
<view class="name" @click="showtime = true">
<text>启动时间:</text>
<view class="">
{{shi == '' ? '' : shi + ':' + fen}} <u-icon name="arrow-right" color="#7C7C7C" size="28"></u-icon>
</view>
</view>
<view class="name">
<text>工作时长:</text>
<view class="">
<input type="number" v-model="miao" @input="handleMiaoInput" @blur="handleMiaoBlur"/>
</view>
</view>
<view class="name" style="border: 0;">
<text>间隔时间:</text>
<view class="">
<input type="number" v-model="tian"/>
</view>
</view>
</view>
<view class="baocun" v-if="pre != 'WATER'" @click="btnbc">
保存
</view>
<u-picker v-model="showtime" mode="time" :params="paramstime" :default-time="00" @confirm='confirmtime'></u-picker>
<view class="" v-if="pre == 'WATER'" style="width: 100%;padding-top: 80rpx;text-align: center;color: #000;font-size: 36rpx;">
没有更多定时浇水啦...
</view>
</view>
</template>
<script>
var xBlufi = require("@/components/blufi/xBlufi.js")
export default {
data() {
return {
showtime: false,
paramstime: {
year: false,
month: false,
day: false,
hour: true,
minute: true,
second: false
},
bgc: {
backgroundColor: "#fff",
},
active: 1,
flag: false,
checked: false,
timeflag: false,
show: false,
params: {
year: false,
month: false,
day: false,
hour: false,
minute: true,
second: true,
},
shows: false,
paramss: {
year: false,
month: false,
day: false,
hour: true,
minute: true,
second: false,
},
minute: '--',
second: '--',
hour: '--',
minutekq: '--',
list: {},
checkedStatus: {},
deviceindex: '',
devicemiao: '',
deviceflag: '',
devicehour: '',
deviceminute: '',
kgflag: false,
xctime: '',
csbobj:{},
pre:'',
shi:'',
fen:'',
miao:'',
tian: '',
isLoading: false, // 加载状态
retryCount: 0, // 重试次数
maxRetries: 3, // 最大重试次数
lastOperation: null, // 最后一次操作
// 添加默认时间设置
defaultTime:'',
defaultTimeLength: '',
jgtian: '',
shebid:'',
zaixianobj:{}
}
},
// 分享到好友(会话)
onShareAppMessage: function() {
return {
title: '绿小能',
path: '/pages/index/index'
}
},
// 分享到朋友圈
onShareTimeline: function() {
return {
title: '绿小能',
query: '',
path: '/pages/index/index'
}
},
onLoad(option) {
this.pre = option.pre
if(option.shebid){
this.shebid = option.shebid
this.getxq()
}else{
xBlufi.listenDeviceMsgEvent(true, this.funListenDeviceMsgEvent)
xBlufi.notifySendCustomData({
customData: "11get"
})
if (option.list.length > 0) { //判断有无数据 有数据直接拿 无数据则发送命令获取数据
if (option.pre == 'WATER') {
this.list = JSON.parse(option.list)
for (let key in this.list) {
if (this.list.hasOwnProperty(key)) {
// 获取当前数组
let arr = this.list[key];
// 只转换开关状态values[3])为布尔值
arr[3] = arr[3] === 1;
}
}
console.log(this.list,'listlistlist')
} else {
this.csbobj = JSON.parse(option.list)
console.log(this.csbobj,'chobjchobj');
this.shi = this.csbobj.hour
this.fen = this.csbobj.minute
this.miao = this.csbobj.second
this.tian = this.csbobj.day
}
} else {
xBlufi.notifySendCustomData({
customData: "11get"
})
}
}
},
onShow() {
},
methods: {
// 请求浇花器数据
getxq(){
this.$u.get(`/app/getDeviceInfo/${this.shebid}`).then(res => {
if (res.code == 200) {
if(this.pre != 'WATER'){
this.shi = res.data.gatewayReturnParams.h.value
this.fen = res.data.gatewayReturnParams.m.value < 10 ? '0' + res.data.gatewayReturnParams.m.value : res.data.gatewayReturnParams.m.value
this.miao = res.data.gatewayReturnParams.t.value
this.tian = res.data.gatewayReturnParams.d.value
} else {
// 单阀 WATER从后台字段 h1/m1/s1/o1...(以及可选 d1..d6) 组装展示结构
const params = res.data.gatewayReturnParams
const mapped = this.buildListFromBackend(params)
// u-switch 需要布尔值,已在构建阶段转换
this.list = mapped
}
}
})
},
// 后台 -> 定时列表结构(与蓝牙解析一致)
buildListFromBackend(params){
const result = {}
for(let i = 1; i <= 6; i++){
const h = Number(params?.[`h${i}`]?.value)
const m = Number(params?.[`m${i}`]?.value)
const s = Number(params?.[`s${i}`]?.value)
const o = Number(params?.[`o${i}`]?.value)
const d = Number(params?.[`d${i}`]?.value)
const hour = isNaN(h) ? 0 : h
const minute = isNaN(m) ? 0 : m
const second = isNaN(s) ? 0 : s
const onoff = !isNaN(o) && o === 1
const interval = isNaN(d) || d <= 0 ? 1 : d
result[`p_set${i}`] = [hour, minute, second, onoff, interval]
}
return result
},
// 选择启动时间
confirmtime(e){
console.log(e);
this.shi = e.hour
this.fen = e.minute
},
// 点击选择浇水时间
btnshowone(){
this.defaultTime = (this.hour.length < 10 ? '0' + this.hour : this.hour) + ':' + (this.minutekq.length < 10 ? '0' + this.minutekq : this.minutekq)
this.show = true
},
// 点击选择浇水时长
btnshowtwo(){
console.log(this.defaultTimeLength,this.minute,this.second,'111');
this.defaultTimeLength = '00' + ':' + this.minute + ':' + this.second
console.log(this.defaultTimeLength,this.minute,this.second,'222');
this.shows = true
},
// 显示加载
showLoading() {
this.isLoading = true;
},
// 格式化间隔天数显示
formatInterval(days) {
return days <= 1 ? '每天浇一次' : '每' + days + '天浇一次';
},
// 隐藏加载
hideLoading() {
this.isLoading = false;
setTimeout(() => {
this.isLoading = false;
}, 500);
},
// 重试机制
async retryOperation() {
if (this.retryCount < this.maxRetries) {
this.retryCount++;
await this.delay(1000);
if (this.lastOperation) {
this.lastOperation();
}
} else {
this.hideLoading();
uni.showToast({
title: '操作失败,请重试',
icon: 'none'
});
this.retryCount = 0;
}
},
// 延时函数
delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
},
// 点击开关是否开启
async btnchange(key, index, values) {
uni.showLoading({
title: '操作中...'
})
try {
this.showLoading()
// 保持 UI 不变,等待请求成功后再更新
this.deviceindex = index
this.devicehour = values[0] || 0
this.deviceminute = values[1] || 0
this.devicemiao = values[2] || 0
const prevSwitch = !!values[3]
const nextSwitch = !prevSwitch
const intervalDays = parseInt(this.jgtian) || 1
const flag = nextSwitch ? 1 : 0
const cucun = '11p_set' + (Number(this.deviceindex) + 1)+ ':' + this.devicehour + ',' + this.deviceminute + ',' + this.devicemiao + ',' + flag + ',' + intervalDays + ';'
if(this.shebid == ''){
this.lastOperation = () => {
xBlufi.notifySendCustomData({
customData: cucun
})
}
this.lastOperation()
await this.delay(1000)
xBlufi.notifySendCustomData({
customData: "11get"
})
// BLE 下不立即改 UI等待设备返回数据刷新
setTimeout(() => {
uni.hideLoading()
this.hideLoading()
}, 1000)
}else{
let parameters = {
date:cucun
}
let data = {
deviceId:this.shebid,
instructionKey:'date',
parameters:parameters
}
this.$u.post(`/app/sendCommandByGateway`,data).then(res => {
if (res.code == 200) {
// 网关成功:仅本地更新开关状态
const keyName = `p_set${Number(this.deviceindex) + 1}`
if (this.list[keyName]) {
this.$set(this.list[keyName], 3, nextSwitch)
}
uni.showToast({
title: '设置成功',
icon: 'success',
duration:2000
})
// 不再请求新数据
}else{
// 失败则保持原状态
values[3] = prevSwitch
uni.showToast({
title: res.msg,
icon: 'none',
duration:2000
})
}
})
}
} catch (error) {
console.error('btnchange error:', error)
this.retryOperation()
}
},
// 点击设置定时时间
btnitem(key, index, values) {
// 从 key 中提取索引号,例如从 'p_set1' 提取 '1'
const indexMatch = key.match(/p_set(\d+)/)
this.deviceindex = indexMatch ? indexMatch[1] : index
this.timeflag = true
this.hour = values[0]
this.minutekq = values[1]
const totalSeconds = values[2]
const minutes = Math.floor(totalSeconds / 60)
const seconds = totalSeconds % 60
const formattedMinutes = minutes < 10 ? '0' + minutes : minutes.toString()
const formattedSeconds = seconds < 10 ? '0' + seconds : seconds.toString()
this.minute = formattedMinutes
this.second = formattedSeconds
// 添加间隔天数的处理,确保为数字
this.jgtian = parseInt(values[4]) || 0
// 设置设备相关值
this.devicehour = values[0]
this.deviceminute = values[1]
this.devicemiao = values[2]
if (this.list.hasOwnProperty(key)) {
const array = this.list[key]
// 只转换开关状态为布尔值
this.deviceflag = array[3] ? 1 : 0
}
},
formattedTime(minutes, seconds) {
// 将数字转换为字符串并补零
const formattedMinutes = String(minutes).padStart(2, '0')
const formattedSeconds = String(seconds).padStart(2, '0')
// 返回格式化后的时间字符串
return `${formattedMinutes}:${formattedSeconds}`
},
formatTime(seconds) {
const minutes = Math.floor(seconds / 60)
const remainingSeconds = seconds % 60
return `${minutes}分${remainingSeconds < 10 ? '0' : ''}${remainingSeconds}秒`
},
// 取消选择设置定时时间
btnqx() {
this.timeflag = false
this.hour = '--'
this.minutekq = '--'
this.minute = '--'
this.second = '--'
},
// 确定选择设置定时时间
async btnqd() {
try {
this.showLoading()
this.timeflag = false
this.hour = '--'
this.minutekq = '--'
this.minute = '--'
this.second = '--'
// 确保间隔天数为数字
const intervalDays = parseInt(this.jgtian) || 0;
let cucun = '11p_set' + this.deviceindex + ':' + this.devicehour + ',' + this.deviceminute + ',' + this.devicemiao + ',' + 1 + ',' + intervalDays + ';'
if(this.shebid == ''){
this.lastOperation = () => {
xBlufi.notifySendCustomData({
customData: cucun
})
}
this.lastOperation()
await this.delay(1000)
xBlufi.notifySendCustomData({
customData: "11get"
})
// BLE 下设置后计时刷新由设备推送完成
this.hideLoading()
}else{
let parameters = {
date:cucun
}
let data = {
deviceId:this.shebid,
instructionKey:'date',
parameters:parameters
}
this.$u.post(`/app/sendCommandByGateway`,data).then(res => {
if (res.code == 200) {
uni.showToast({
title: '设置成功',
icon: 'success',
duration:2000
})
// 网关成功:本地立即更新列表,避免再次请求
const key = `p_set${this.deviceindex}`
if (!this.list[key]) {
this.$set(this.list, key, [0,0,0,false,1])
}
// 更新为本次设置的值(使用 $set 保证响应式)
this.$set(this.list[key], 0, Number(this.devicehour) || 0)
this.$set(this.list[key], 1, Number(this.deviceminute) || 0)
this.$set(this.list[key], 2, Number(this.devicemiao) || 0)
this.$set(this.list[key], 3, true)
this.$set(this.list[key], 4, Number(intervalDays) || 1)
}else{
uni.showToast({
title: res.msg,
icon: 'none',
duration:2000
})
}
})
}
} catch (error) {
console.error('btnqd error:', error)
this.retryOperation()
}
},
// 保存抽水泵设置
async btnbc() {
try {
if(this.shi >= 24){
uni.showToast({
title: '最大值为23时',
icon: 'none',
duration:2000
})
return
} else if(this.fen >= 60){
uni.showToast({
title: '最大值为59分钟',
icon: 'none',
duration:2000
})
return
}
// 限制工作时长不能超过9999秒
if(this.miao > 9999){
uni.showToast({
title: '工作时长最大值为9999秒',
icon: 'none',
duration:2000
})
this.miao = 9999
}
this.showLoading();
this.timeflag = false;
if(this.tian > 99){
uni.showToast({
title: '间隔最大时间为99天',
icon: 'none',
duration:2000
})
}
let tian = this.tian > 99 ? 99 : this.tian
let cucun = '11pset' + ',' + this.shi + ',' + this.fen + ',' + this.miao + ',' + tian + '@'
if(this.shebid == ''){
this.lastOperation = () => {
xBlufi.notifySendCustomData({
customData: cucun
})
};
this.lastOperation()
await this.delay(1000)
xBlufi.notifySendCustomData({
customData: "11get"
})
uni.showToast({
title: '保存成功',
icon: 'success',
duration: 2000
})
this.hideLoading()
}else{
let parameters = {
date:cucun
}
let data = {
deviceId:this.shebid,
instructionKey:'date',
parameters:parameters
}
this.$u.post(`/app/sendCommandByGateway`,data).then(res => {
if (res.code == 200) {
uni.showToast({
title: '保存成功',
icon: 'success',
duration:2000
})
}else{
uni.showToast({
title: res.msg,
icon: 'none',
duration:2000
})
}
})
}
} catch (error) {
console.error('btnbc error:', error)
this.retryOperation()
}
},
// 定时浇水时间
confirm(e) {
this.hour = e.hour || '00'
this.minutekq = e.minute || '00'
this.devicehour = e.hour || '00'
this.deviceminute = e.minute || '00'
},
// 定时浇水时长
confirms(e) {
this.minute = e.minute || '00'
this.second = e.second || '00'
this.devicemiao = (Number(this.minute) * 60 + Number(this.second)) || 0
console.log(this.devicemiao)
},
funListenDeviceMsgEvent: function(options) {
switch (options.type) {
case xBlufi.XBLUFI_TYPE.TYPE_STATUS_CONNECTED:
if (!options.result) {
uni.showToast({
title: '蓝牙连接异常',
icon: 'none'
});
}
break;
case xBlufi.XBLUFI_TYPE.TYPE_RECIEVE_CUSTON_DATA:
try {
console.log("收到设备发来的自定义数据结果:", options.data);
const inputString = options.data.slice(0, -1) + ";";
if (this.pre == 'WATER') {
const pairs = inputString.split(';');
const pSetObjects = {};
pairs.forEach(pair => {
if (!pair) return;
const [key, value] = pair.split(':');
if (key && key.startsWith('p_set') && value) {
try {
const numbers = value.split(',').map(num => {
const parsed = parseInt(num);
return isNaN(parsed) ? 0 : parsed;
});
// 只转换开关状态为布尔值
numbers[3] = numbers[3] === 1;
pSetObjects[key] = numbers;
} catch (e) {
console.error('数据解析错误:', e);
}
}
});
if (Object.keys(pSetObjects).length > 0) {
this.list = pSetObjects;
}
} else {
const input = options.data.slice(0, -1) + ";"
// 去除末尾的分号并分割字符串
const parts = input.replace(";", "").split(":")
// 获取时间部分并分割
const timeParts = parts[1].split(",")
// 解析为对象
console.log(timeParts,'timePartstimePartstimeParts');
this.csbobj = {
hour: parseInt(timeParts[0]), // 小时
minute: parseInt(timeParts[1]), // 分钟
second: parseInt(timeParts[2]), // 秒
day: parseInt(timeParts[3]) // 天数
}
console.log(this.csbobj);
this.shi = this.csbobj.hour < 10 ? '0' + this.csbobj.hour : this.csbobj.hour
this.fen = this.csbobj.minute < 10 ? '0' + this.csbobj.minute : this.csbobj.minute
this.miao = this.csbobj.second
this.tian = this.csbobj.day
}
this.hideLoading();
} catch (error) {
console.error('数据处理错误:', error);
this.retryOperation();
}
break
}
},
// 处理工作时长输入
handleMiaoInput(e) {
// 在uni-app中直接使用e.detail.value获取输入值
let value = e.detail.value || e.target.value || '';
console.log('输入值:', value); // 调试用
// 转换为数字
let numValue = parseInt(value) || 0;
console.log('转换后数值:', numValue); // 调试用
// 限制最大值为9999
if (numValue > 9999) {
numValue = 9999;
uni.showToast({
title: '工作时长最大值为9999秒',
icon: 'none',
duration: 2000
});
}
// 更新数据
this.miao = numValue;
console.log('最终miao值:', this.miao); // 调试用
},
// 处理工作时长失去焦点时的验证
handleMiaoBlur(e) {
// 再次验证并限制
if (this.miao > 9999) {
this.miao = 9999;
uni.showToast({
title: '工作时长最大值为9999秒',
icon: 'none',
duration: 2000
});
}
},
// 改变天数
changeDays(change) {
let newValue = (parseInt(this.jgtian) || 1) + change;
// 确保天数不小于1
this.jgtian = Math.max(1, newValue);
},
}
}
</script>
<style lang="less">
::v-deep .u-title {
margin-bottom: 22rpx;
}
::v-deep .uicon-nav-back {
margin-bottom: 22rpx;
}
.baocun{
margin: auto;
width: 680rpx;
height: 94rpx;
background: #48893B;
border-radius: 14rpx 14rpx 14rpx 14rpx;
margin-top: 50rpx;
text-align: center;
line-height: 100rpx;
border-radius: 20rpx;
color: #fff;
font-size: 32rpx;
}
.choushuiben{
width: 680rpx;
height: 426rpx;
background: #FFFFFF;
box-shadow: 0rpx 10rpx 64rpx 0rpx rgba(0,0,0,0.08);
border-radius: 20rpx;
padding: 36rpx 34rpx;
box-sizing: border-box;
.tit{
font-weight: 600;
font-size: 36rpx;
color: #3D3D3D;
}
.name{
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 34rpx;
border-bottom: 1px solid #D8D8D8;
padding-bottom: 34rpx;
box-sizing: border-box;
view{
display: flex;
}
text{
font-size: 32rpx;
color: #3D3D3D;
}
input{
width: 100rpx;
}
}
}
.jiaoshui {
position: fixed;
top: 366rpx;
left: 50%;
transform: translateX(-50%);
width: 678rpx;
max-height: 1200rpx;
padding-bottom: 30rpx;
box-sizing: border-box;
background: #FFFFFF;
border-radius: 24rpx 24rpx 24rpx 24rpx;
z-index: 99;
.top {
margin-top: 42rpx;
width: 100%;
text-align: center;
font-size: 44rpx;
color: #3D3D3D;
font-weight: 600;
}
.ts {
margin-top: 30rpx;
width: 100%;
text-align: center;
font-size: 32rpx;
color: #808080;
font-weight: 600;
}
.shifen {
width: 512rpx;
height: 128rpx;
background: #F0F0F0;
border-radius: 16rpx 16rpx 16rpx 16rpx;
margin: auto;
margin-top: 30rpx;
display: flex;
justify-content: space-between;
line-height: 128rpx;
padding: 0 102rpx;
box-sizing: border-box;
text {
font-size: 44rpx;
color: #3D3D3D;
font-weight: 600;
}
}
.jssc {
font-size: 32rpx;
color: #808080;
font-weight: 600;
margin-top: 58rpx;
margin-left: 96rpx;
}
.jiange {
width: 512rpx;
margin: 30rpx auto 0;
display: flex;
align-items: center;
justify-content: space-between;
text {
font-size: 32rpx;
color: #808080;
font-weight: 600;
}
.number-input {
display: flex;
align-items: center;
background: #F0F0F0;
border-radius: 16rpx;
padding: 0 20rpx;
height: 80rpx;
.btn-minus, .btn-plus {
width: 60rpx;
height: 60rpx;
line-height: 60rpx;
text-align: center;
font-size: 40rpx;
color: #48893B;
font-weight: bold;
background: #fff;
border-radius: 8rpx;
}
.days {
margin: 0 30rpx;
min-width: 60rpx;
text-align: center;
font-size: 32rpx;
color: #3D3D3D;
}
}
}
.anniu {
display: flex;
justify-content: space-between;
margin-top: 58rpx;
padding: 0 44rpx;
box-sizing: border-box;
.qx {
width: 278rpx;
height: 80rpx;
border-radius: 10rpx 10rpx 10rpx 10rpx;
border: 2rpx solid #7FAD76;
font-size: 36rpx;
color: #7FAD76;
font-weight: 600;
line-height: 80rpx;
text-align: center;
}
.qd {
width: 278rpx;
height: 80rpx;
background: #7FAD76;
border-radius: 10rpx 10rpx 10rpx 10rpx;
font-size: 36rpx;
color: #fff;
font-weight: 600;
line-height: 80rpx;
text-align: center;
}
}
}
.mask {
width: 100%;
height: 100vh;
background-color: #000;
opacity: .6;
position: fixed;
top: 0;
left: 0;
z-index: 98;
}
.list {
.list_val {
width: 678rpx;
height: 248rpx;
background: #FFFFFF;
box-shadow: 0rpx 10rpx 64rpx 0rpx rgba(0, 0, 0, 0.08);
border-radius: 20rpx;
padding-top: 16rpx;
padding-left: 42rpx;
padding-right: 42rpx;
box-sizing: border-box;
display: flex;
justify-content: space-between;
margin-top: 30rpx;
.lt {
width: 100%;
.one {
font-size: 72rpx;
color: #50565A;
font-weight: 600;
}
.two {
font-size: 32rpx;
color: #50565A;
margin-top: 12rpx;
text {
display: inline-block;
width: 1rpx;
height: 28rpx;
background: #3D3D3D;
margin-left: 26rpx;
margin-right: 26rpx;
}
}
}
.rt {
padding-top: 70rpx;
box-sizing: border-box;
}
}
}
page {
width: 100%;
padding: 20rpx 30rpx;
box-sizing: border-box;
background-color: #fff;
}
.bj {
width: 100%;
height: 100vh;
position: fixed;
top: 0;
left: 0;
z-index: -1;
}
</style>