1438 lines
46 KiB
Vue
1438 lines
46 KiB
Vue
<template>
|
||
<view>
|
||
<uni-section title="卷被卷膜控制" titleFontSize="16px" type="line"
|
||
v-if="value!== 1 && !['862538065276939','A','B','C'].includes(value)">
|
||
<template v-slot:right>
|
||
{{ status.deviceTime }}
|
||
</template>
|
||
<!-- 优化:设备卡片循环渲染 -->
|
||
<view class="card-grid">
|
||
<view
|
||
class="control-card"
|
||
v-for="card in deviceCards"
|
||
:key="card.type"
|
||
@click="openTimeModal(card)"
|
||
>
|
||
<view class="card-text">
|
||
<text class="card-main" v-if="dtu_remark[card.type]">{{ dtu_remark[card.type] }}</text>
|
||
<text class="card-main" v-else>{{ card.name }}</text>
|
||
<view class="card-sub-wrapper">
|
||
<text class="card-sub" v-if="showStatusText">{{ show[card.type] || '未知' }}</text>
|
||
<text class="limit-time">
|
||
运行时间:{{
|
||
limitTimes[`${card.type}Limit`] && limitTimes[`${card.type}Limit`] !== '0' ? `${limitTimes[`${card.type}Limit`]} s` : '- -'
|
||
}}
|
||
</text>
|
||
</view>
|
||
</view>
|
||
<view v-if="showFlag" class="card-icon" :class="{ active: status[card.type] === 1 }"
|
||
@click.stop="handleCardClick(1 - status[card.type], card.type, 0)">
|
||
<!-- 加@click.stop防止冒泡触发卡片点击的弹窗事件 -->
|
||
<uni-icons
|
||
:type="status[card.type] === 1 ? 'circle' : 'circle-filled'"
|
||
size="24"
|
||
color="#fff"
|
||
/>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</uni-section>
|
||
<uni-section title="自动化参数配置" titleFontSize="16px" type="line"
|
||
v-if="value!== 1 && !['862538065276939','A','B','C'].includes(value)">
|
||
<template v-slot:right>
|
||
参数设置完成请点击 <button @click="saveAutoTerm" style="margin-right: 10rpx" class="cu-btn bg-cyan shadow">保存</button>
|
||
</template>
|
||
<!--自动化设置-->
|
||
<view class="film-roller">
|
||
<tn-subsection :list="filmRollerList"
|
||
:current="current"
|
||
:bold="true"
|
||
@change="switchTab"
|
||
:height="80"></tn-subsection>
|
||
<swiper class="swiper" :disable-touch="true" :current="current" :acceleration="true"
|
||
@change="change" :style="{ height: swiperHeight + 'rpx' }">
|
||
<swiper-item v-for="(roller, key) in filmRollerList"
|
||
:key="key">
|
||
<view >
|
||
<view class="param-setting">
|
||
<tn-button padding="0 20rpx" :plain="true" margin="10rpx 10rpx" @click="showSelect=true">
|
||
参考温度:{{ termList[current]['config'].refTemp }}
|
||
<uni-icons class="temp-dialog" type="down"/>
|
||
</tn-button>
|
||
<view @click="openParamDialog" class="param-dialog">
|
||
<tn-button padding="0 20rpx" :plain="true" margin="10rpx 10rpx" >
|
||
参数设置弹窗
|
||
</tn-button>
|
||
</view>
|
||
</view>
|
||
<!-- F8F7F8-->
|
||
<view class="term-content">
|
||
|
||
<uni-swipe-action :key="termList[key]['terms'].length">
|
||
<uni-swipe-action-item class="swiper-custom" v-for="(item, index) in termList[key].terms"
|
||
:key="item.id" :index="index" @click="onDeleteItem($event, item.id)" :right-options="options">
|
||
<view class="message">
|
||
<view class="message__left">
|
||
<view class="message__tag">温度控制</view>
|
||
<view class="message__content tn-text-ellipsis">第{{ index+1 }}段</view>
|
||
<!-- <tn-avatar shape="square" size="lg" src="https://resource.tuniaokj.com/images/avatar/xiaomai1.jpg"></tn-avatar>-->
|
||
</view>
|
||
<view class="message__middle" @click="changeTime('startTime',index)">
|
||
<view class="message__name">运行时间开始</view>
|
||
<view class="message__content tn-text-ellipsis">{{ item.startTime }}</view>
|
||
</view>
|
||
<view class="message__middle" @click="changeTime('endTime',index)">
|
||
<view class="message__name">运行时间终止</view>
|
||
<view class="message__content tn-text-ellipsis">{{ item.endTime }}</view>
|
||
</view>
|
||
<!-- <tn-button backgroundColor="#01BEFF" :plain="true" class="message__right" width="150rpx" height="100rpx"-->
|
||
<!-- :fontSize="40" shape="icon" margin="10rpx 10rpx">-->
|
||
<!-- 替换温度按钮 -->
|
||
<view
|
||
class="message__right"
|
||
@click.stop="openSlider('temp', index)"
|
||
>
|
||
<view class="message__name">温度</view>
|
||
<view class="message__content tn-text-ellipsis">{{ formatValueWithUnit(item.temp, '℃') }}</view>
|
||
</view>
|
||
|
||
<!-- 替换风口按钮 -->
|
||
<view
|
||
class="message__right"
|
||
@click.stop="openSlider('vent', index)"
|
||
>
|
||
<view class="message__name">风口</view>
|
||
<view class="message__content tn-text-ellipsis">{{ formatValueWithUnit(item.vent, 'cm') }}</view>
|
||
</view>
|
||
<!-- <view class="message__tag">阶段{{index+1}}</view>-->
|
||
</view>
|
||
</uni-swipe-action-item>
|
||
</uni-swipe-action>
|
||
</view>
|
||
<view class="copy-term" v-if="termList[key]['terms'].length > 0">
|
||
<tn-button @click="copyTerm"
|
||
:shadow="true" width="100%" height="100rpx"
|
||
backgroundColor="#01BEFF" fontColor="#FFFFFF"
|
||
margin="10rpx 0">一键同步卷膜所有配置</tn-button>
|
||
</view>
|
||
<view class="add-term">
|
||
<uni-icons color="var(--cyan)" type="plus" size="40" @click="addTerm"/>
|
||
<text @click="addTerm">添加条件</text>
|
||
</view>
|
||
</view>
|
||
</swiper-item>
|
||
</swiper>
|
||
</view>
|
||
</uni-section>
|
||
<tn-picker mode="time" v-model="selectTime" :params="timeParams" @confirm="confirmTime"></tn-picker>
|
||
<tn-select title="请选择参考温度" :safeAreaInsetBottom="true" :searchShow="false" v-model="showSelect" mode="single" :list="tempList" @confirm="confirmTemp"></tn-select>
|
||
|
||
<uni-popup ref="inputDialog" mode="center">
|
||
<!-- 新增:修改运行时间的弹窗 -->
|
||
<view class="modal-container">
|
||
<view class="modal-title">{{ `【${selectedText} - ${currentCard.name}】设置` }}</view>
|
||
<view class="modal-input-wrap">
|
||
<text class="modal-label">当前时间:</text>
|
||
<text class="modal-current">{{ currentCardTime > 0 ? `${currentCardTime} 秒` : '未设置' }}</text>
|
||
</view>
|
||
<view class="modal-input-wrap">
|
||
<text class="modal-label">修改后时间:</text>
|
||
<input
|
||
class="modal-input"
|
||
type="number"
|
||
v-model.number="newLimitTime"
|
||
/>
|
||
<!-- <uni-number-box v-model="newLimitTime" />-->
|
||
<text class="modal-unit">秒</text>
|
||
</view>
|
||
|
||
<view class="modal-input-wrap">
|
||
<text class="modal-label">别名设置:</text>
|
||
<uni-easyinput style="width: 100px" v-model="remark" placeholder="不填展示默认备注"/>
|
||
</view>
|
||
<view class="modal-btn-wrap">
|
||
<button class="modal-btn cancel" @click="close">取消</button>
|
||
<button class="modal-btn confirm" @click="confirmModifyTime">确定</button>
|
||
</view>
|
||
</view>
|
||
</uni-popup>
|
||
|
||
<uni-popup ref="autoParam" mode="center">
|
||
<!-- 新增:修改运行时间的弹窗 -->
|
||
<view class="modal-container_">
|
||
<view class="modal-title">{{ `【${selectedText} - ${filmRollerList[current]}】风口校准`}}</view>
|
||
|
||
<uni-forms :model="rollerParam" ref="form" :labelWidth="130" >
|
||
<uni-forms-item label="当前卷膜:" prop="refTemp" v-if="false">
|
||
<uni-easyinput type="text" placeholderStyle="font-size: 25rpx;" v-model="rollerParam.imei"
|
||
disabled :inputBorder="false" :clearable="false"/>
|
||
</uni-forms-item>
|
||
<uni-forms-item label="当前卷膜:" prop="refTemp" v-if="false">
|
||
<uni-easyinput type="text" placeholderStyle="font-size: 25rpx;" v-model="rollerParam.roller"
|
||
disabled :inputBorder="false" :clearable="false"/>
|
||
</uni-forms-item>
|
||
<uni-forms-item label="参考温度:" prop="refTemp" v-if="false">
|
||
<uni-easyinput type="text" placeholderStyle="font-size: 25rpx;" v-model="rollerParam.refTemp"
|
||
disabled :inputBorder="false" :clearable="false"/>
|
||
</uni-forms-item>
|
||
<uni-forms-item label="计算风口长度:" prop="autoTotalLen" :labelWidth="124">
|
||
<uni-easyinput type="number" placeholderStyle="font-size: 25rpx;" v-model="rollerParam.autoTotalLen"
|
||
placeholder="风口校准完成自动写入" disabled
|
||
:inputBorder="false" :clearable="false">
|
||
<template #right>
|
||
<view>cm</view>
|
||
</template>
|
||
</uni-easyinput>
|
||
</uni-forms-item>
|
||
<view class="card-grid">
|
||
<view
|
||
class="control-card"
|
||
v-for="card in paramCard"
|
||
:key="card.type">
|
||
<view class="card-text">
|
||
<text class="card-main" >{{ card.name }}</text>
|
||
</view>
|
||
<view class="card-icon" :class="{ active: status[card.type] === 1 }"
|
||
@click.stop="handleCardClick(1 - status[card.type], card.type, 1)">
|
||
<!-- 加@click.stop防止冒泡触发卡片点击的弹窗事件 -->
|
||
<uni-icons
|
||
:type="status[card.type] === 1 ? 'circle' : 'circle-filled'"
|
||
size="24"
|
||
color="#fff"
|
||
/>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<uni-forms-item label="手动设置:" prop="manualTotalLen" :labelWidth="95">
|
||
<uni-easyinput type="number" placeholderStyle="font-size: 25rpx;" v-model="rollerParam.manualTotalLen"
|
||
placeholder="可在此处手动校准风口长度"
|
||
:inputBorder="false" :clearable="false">
|
||
<template #right>
|
||
<view>cm</view>
|
||
</template>
|
||
</uni-easyinput>
|
||
</uni-forms-item>
|
||
<uni-forms-item label="预留风口长度:" prop="reservedLen" :required="true" :labelWidth="135">
|
||
<uni-easyinput type="number" placeholderStyle="font-size: 25rpx;" v-model="rollerParam.reservedLen"
|
||
placeholder="请输入预留风口长度"
|
||
:inputBorder="false" :clearable="false">
|
||
<template #right>
|
||
<view>cm</view>
|
||
</template>
|
||
</uni-easyinput>
|
||
</uni-forms-item>
|
||
</uni-forms>
|
||
<view class="modal-btn-wrap">
|
||
<button class="modal-btn cancel" @click="closeParamDialog">取消</button>
|
||
<button class="modal-btn confirm" @click="setAutoParam">确定</button>
|
||
</view>
|
||
</view>
|
||
</uni-popup>
|
||
|
||
|
||
<uni-popup ref="sliderDialog" mode="center">
|
||
<view class="modal-container">
|
||
<view class="modal-title">{{ `【${selectedText} - 自动化】条件设置` }}</view>
|
||
<!-- 核心修改:给容器加 flex 布局样式 -->
|
||
<view class="modal-slider">
|
||
<text class="slider-label">{{ slider.title }}</text>
|
||
<slider
|
||
:value="slider.value"
|
||
:min="slider.min"
|
||
:max="slider.max"
|
||
show-value
|
||
class="slider-component"
|
||
@change="changeSlider"
|
||
/>
|
||
<text class="slider-unit">{{ slider.unit }}</text>
|
||
</view>
|
||
|
||
<view class="modal-btn-wrap">
|
||
<button class="modal-btn cancel" @click="closeSlider">取消</button>
|
||
<button class="modal-btn confirm" @click="confirmSlider">确定</button>
|
||
</view>
|
||
</view>
|
||
</uni-popup>
|
||
|
||
|
||
<tn-modal
|
||
v-model="showTip"
|
||
title="温馨提示"
|
||
content="卷膜参考温度设置存在重复,请确认是否保存?"
|
||
:button="[
|
||
{
|
||
text: '取消',
|
||
backgroundColor: '#dcdbdb',
|
||
fontColor: '#FFFFFF'
|
||
},
|
||
{
|
||
text: '确定',
|
||
backgroundColor: '#42b3ff',
|
||
fontColor: '#FFFFFF'
|
||
}
|
||
]"
|
||
:showCloseBtn="true"
|
||
:maskCloseable="false"
|
||
@click="showTips"
|
||
/>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
// 优化:抽离魔法值常量
|
||
import UniPopup from "../../../uni_modules/uni-popup/components/uni-popup/uni-popup.vue"; // 引入弹窗组件
|
||
import mqttUtil from '@/utils/mqtt';
|
||
import {addLimit, updateLimit} from "../../../api/system/assets/limit";
|
||
import store from "../../../store";
|
||
import {addRemark, updateRemark} from "../../../api/system/assets/remark";
|
||
import {generateUniqueId} from "../../../utils/agri";
|
||
import UniSection from "../../../components/uni-section/uni-section.vue";
|
||
import UniFormsItem from "../../../uni_modules/uni-forms/components/uni-forms-item/uni-forms-item.vue";
|
||
import { checkTimeConflict } from "../../../utils/agri"
|
||
import {getAgriTerm, saveAgriTerm} from "../../../api/control/autoTerm";
|
||
|
||
export default {
|
||
dicts: ['sys_data_map'],
|
||
name: "manual",
|
||
props: {
|
||
// 尺寸
|
||
value: {
|
||
type: String,
|
||
default: "1"
|
||
},
|
||
// 打开时的背景颜色
|
||
activeColor: {
|
||
type: String,
|
||
default: ''
|
||
},
|
||
dtu_remark: {
|
||
type: Object,
|
||
default() {
|
||
return {}
|
||
}
|
||
},
|
||
status: {
|
||
type: Object,
|
||
default() {
|
||
return {}
|
||
}
|
||
},
|
||
liveData: {
|
||
type: Object,
|
||
default() {
|
||
return {}
|
||
}
|
||
},
|
||
show: {
|
||
type: Object,
|
||
default() {
|
||
return {}
|
||
}
|
||
},
|
||
ventTotalLen: {
|
||
type: Number,
|
||
default: 0
|
||
},
|
||
limitTimes: {
|
||
type: Object,
|
||
default() {
|
||
return {}
|
||
}
|
||
},
|
||
selectedText: {
|
||
type: String,
|
||
default: ""
|
||
},
|
||
agriId: {
|
||
type: String,
|
||
default: null
|
||
},
|
||
},
|
||
watch: {
|
||
value: {
|
||
deep: true, // 监听对象内部属性变化(防止数据是对象时监听不到)
|
||
immediate: true, // 关键:进入组件就执行,不用等数据变化
|
||
handler(newVal) {
|
||
// 确保数据有值后执行方法
|
||
if (newVal) {
|
||
this.imei = this.value
|
||
}
|
||
}
|
||
},
|
||
// 监听 current 变化,切换 tab 时也重新计算高度
|
||
current: {
|
||
handler() {
|
||
this.$nextTick(() => {
|
||
this.getSwiperHeight();
|
||
});
|
||
},
|
||
immediate: true
|
||
},
|
||
ventTotalLen: {
|
||
deep: true, // 监听对象内部属性变化(防止数据是对象时监听不到)
|
||
immediate: true, // 关键:进入组件就执行,不用等数据变化
|
||
handler(newVal) {
|
||
// 确保数据有值后执行方法
|
||
if (newVal) {
|
||
this.rollerParam.autoTotalLen = newVal;
|
||
}
|
||
}
|
||
}
|
||
},
|
||
components: {
|
||
UniFormsItem,
|
||
UniSection,
|
||
UniPopup // 注册弹窗组件
|
||
},
|
||
mounted() {
|
||
this.refresh();
|
||
},
|
||
data() {
|
||
return {
|
||
fontStyle: '',
|
||
deviceCards: [
|
||
{type: 'jbk', name: '卷被开'},
|
||
{type: 'jbg', name: '卷被关'},
|
||
{type: 'jlk', name: '卷帘开'},
|
||
{type: 'jlg', name: '卷帘关'},
|
||
],
|
||
paramCard: [
|
||
{type: '', name: '卷膜开'},
|
||
{type: '', name: '卷膜关'}
|
||
],
|
||
// 优化:语义化变量名(替换原 hide: false)
|
||
showStatusText: false,
|
||
showFlag: true,
|
||
remark: '',
|
||
// 新增:弹窗相关变量
|
||
currentCard: {}, // 当前点击的卡片信息
|
||
currentCardTime: '', // 当前卡片的运行时间
|
||
newLimitTime: 0, // 新的运行时间
|
||
message: {},
|
||
// 优化:声明响应式变量 connected
|
||
connected: false,
|
||
imei: '',
|
||
current: 0,
|
||
filmRollerList:["卷膜1", "卷膜2", "卷膜3"],
|
||
tempList: [
|
||
{
|
||
value: 'temp1',
|
||
label: '温度1'
|
||
},
|
||
{
|
||
value: 'temp2',
|
||
label: '温度2'
|
||
},
|
||
{
|
||
value: 'temp3',
|
||
label: '温度3'
|
||
},
|
||
{
|
||
value: 'temp4',
|
||
label: '温度4'
|
||
}
|
||
],
|
||
showSelect:false,
|
||
demo: {
|
||
config: [
|
||
{
|
||
refTemp: '请选择',
|
||
refTempCode: null,
|
||
autoTotalLen: null,
|
||
manualTotalLen: null,
|
||
reservedLen: null,
|
||
roller:'jm1'
|
||
},
|
||
{
|
||
refTemp: '请选择',
|
||
refTempCode: null,
|
||
autoTotalLen: null,
|
||
manualTotalLen: null,
|
||
reservedLen: null,
|
||
roller:'jm2'
|
||
},
|
||
{
|
||
refTemp: '请选择',
|
||
refTempCode: null,
|
||
autoTotalLen: null,
|
||
manualTotalLen: null,
|
||
reservedLen: null,
|
||
roller:'jm3'
|
||
}
|
||
],
|
||
terms: [
|
||
[/* 卷膜1的条件列表 */],
|
||
[/* 卷膜2的条件列表 */],
|
||
[/* 卷膜3的条件列表 */]
|
||
]
|
||
},
|
||
termList: [
|
||
{
|
||
terms: [],
|
||
config: {
|
||
refTemp: '请选择',
|
||
refTempCode: null,
|
||
autoTotalLen: null,
|
||
manualTotalLen: null,
|
||
reservedLen: null,
|
||
roller:'jm1'
|
||
}
|
||
},
|
||
{
|
||
terms: [],
|
||
config:{
|
||
refTemp: '请选择',
|
||
refTempCode: null,
|
||
autoTotalLen: null,
|
||
manualTotalLen: null,
|
||
reservedLen: null,
|
||
roller:'jm2'
|
||
}
|
||
},
|
||
{
|
||
terms: [],
|
||
config:{
|
||
refTemp: '请选择',
|
||
refTempCode: null,
|
||
autoTotalLen: null,
|
||
manualTotalLen: null,
|
||
reservedLen: null,
|
||
roller:'jm3'
|
||
}
|
||
}
|
||
],
|
||
options: [
|
||
{
|
||
text: '删除',
|
||
icon: 'delete',
|
||
style: {
|
||
backgroundColor: '#E83A30'
|
||
}
|
||
}
|
||
],
|
||
swiperHeight: 720, // 用于动态设置 swiper 高度
|
||
timeParams: {
|
||
year: false,
|
||
month: false,
|
||
day: false,
|
||
hour: true,
|
||
minute: true,
|
||
second: false
|
||
},
|
||
selectTime: false,
|
||
timeTag: null,
|
||
rollerIndex: null,
|
||
defaultTime: null,
|
||
maxTermLength: 5,
|
||
autoParam:false,
|
||
slider: {
|
||
title: '请选择',
|
||
min:0,
|
||
max:100,
|
||
value:0,
|
||
unit:'',
|
||
mode: null
|
||
},
|
||
rollerParam: {
|
||
imei: this.value,
|
||
roller: null,
|
||
refTemp: '请选择',
|
||
autoTotalLen: null,
|
||
manualTotalLen: null,
|
||
reservedLen: null,
|
||
ventTotalLen: null
|
||
},
|
||
showTip:false
|
||
};
|
||
},
|
||
|
||
methods: {
|
||
// 滑动切换卷膜
|
||
change(e) {
|
||
this.current =e.detail.current
|
||
},
|
||
// 切换卷膜
|
||
switchTab(e) {
|
||
this.current=e.index
|
||
},
|
||
// 左上角选择时间
|
||
confirmTemp(event) {
|
||
this.termList[this.current]['config'].refTemp = event[0]['label']
|
||
this.termList[this.current]['config'].refTempCode = event[0]['value']
|
||
},
|
||
// 下拉刷新以及进入组件渲染
|
||
refresh() {
|
||
this.getAgriTerm();
|
||
this.showFlag = !((store.getters && store.getters.name !== 'admin') && this.$auth.hasRole("test"))
|
||
this.$nextTick(() => {
|
||
this.getSwiperHeight(); // 页面初始化时也计算一次
|
||
});
|
||
},
|
||
getAgriTerm() {
|
||
getAgriTerm(this.imei).then(response => {
|
||
if (response.code === 200) {
|
||
this.termList = response.data;
|
||
}
|
||
if (this.termList && this.termList.length>0) {
|
||
return;
|
||
}
|
||
this.termList = [];
|
||
for (const [index,value] of this.filmRollerList.entries()) {
|
||
this.termList.push({
|
||
terms: [],
|
||
config: {
|
||
refTemp: '请选择',
|
||
refTempCode: null,
|
||
autoTotalLen: null,
|
||
manualTotalLen: null,
|
||
reservedLen: null,
|
||
roller: `jm${index+1}`,
|
||
imei: this.value
|
||
}
|
||
})
|
||
}
|
||
}).catch(err => {
|
||
}).finally(() => {
|
||
|
||
});
|
||
},
|
||
// --------------------共同逻辑------------------------------
|
||
// 修改运行时间以及设备备注弹窗
|
||
openTimeModal(card) {
|
||
if ((store.getters && store.getters.name !== 'admin')
|
||
&& this.$auth.hasRole("test")) {
|
||
return;
|
||
}
|
||
this.currentCard = card; // 记录当前卡片信息
|
||
this.currentCardTime = this.limitTimes[`${card.type}Limit`]; // 记录当前时间
|
||
this.newLimitTime = this.currentCardTime; // 默认填充当前时间
|
||
this.remark = this.dtu_remark[card.type] || card.name;
|
||
this.$refs.inputDialog.open()
|
||
},
|
||
// 设备控制
|
||
handleCardClick(status, type, tag) {
|
||
const funcMsg = "该功能用来开启或暂停设备,按钮亮为开启,按钮暗为暂停设备"
|
||
if ((store.getters && store.getters.name !== 'admin')
|
||
&& this.$auth.hasRole("test")) {
|
||
// this.testFunction(`${this.testMsg}\n${funcMsg}`)
|
||
return;
|
||
}
|
||
// 校验
|
||
// 定义类型与提示文案的映射关系,减少重复代码
|
||
const tipMap = {
|
||
'jbk': {opposite: 'jbg', name: '卷被关', op: '卷被开'},
|
||
'jbg': {opposite: 'jbk', name: '卷被开', op: '卷被关'},
|
||
'jlk': {opposite: 'jlg', name: '卷帘关', op: '卷帘开'},
|
||
'jlg': {opposite: 'jlk', name: '卷帘开', op: '卷帘关'},
|
||
'jm1k': {opposite: 'jm1g', name: '卷膜1关', op: '卷膜1开'},
|
||
'jm1g': {opposite: 'jm1k', name: '卷膜1开', op: '卷膜1关'},
|
||
'jm2k': {opposite: 'jm2g', name: '卷膜2关', op: '卷膜2开'},
|
||
'jm2g': {opposite: 'jm2k', name: '卷膜2开', op: '卷膜2关'},
|
||
'jm3k': {opposite: 'jm3g', name: '卷膜3关', op: '卷膜3开'},
|
||
'jm3g': {opposite: 'jm3k', name: '卷膜3开', op: '卷膜3关'}
|
||
};
|
||
|
||
// 先判断类型是否在映射表中,避免无效case
|
||
if (!tipMap[type]) return;
|
||
|
||
const {opposite, name, op} = tipMap[type];
|
||
// 核心校验逻辑(只写一次,无需重复)
|
||
if (status === 1 && this.status[opposite] === 1) {
|
||
this.$modal.msgError(`【${this.selectedText}】${name}在运行状态,不能运行${op}操作!`);
|
||
return;
|
||
}
|
||
|
||
// ========== 修改:从全局工具类获取连接状态 ==========
|
||
this.connected = mqttUtil.getMqttState().isConnected;
|
||
if (!this.connected) {
|
||
this.$modal.msgError("设备连接异常");
|
||
return;
|
||
}
|
||
if (this.value === 1) {
|
||
this.$modal.msgError("设备控制失败!");
|
||
return;
|
||
}
|
||
let content = `确定 ${status === 1 ? "运行" : "暂停"} 【${this.selectedText} - ${op}】设备?`;
|
||
let emitFunction = "publicMsg";
|
||
if (tag === 1) {
|
||
if (type.slice(-1) === 'k' && status === 1) {
|
||
content = `确定 ${status === 1 ? "运行" : "暂停"} 【${this.selectedText} - ${op}】之前已将该卷膜关到最低?`
|
||
}
|
||
emitFunction = "sendSettingMsg";
|
||
}
|
||
uni.showModal({
|
||
title: '操作提示:',
|
||
content: `${content}`,
|
||
cancelText: '取消',
|
||
confirmText: '确定',
|
||
success: (res) => {
|
||
if (res.confirm) {
|
||
// 组装消息
|
||
this.message = JSON.stringify({[`${type}1`]: status})
|
||
|
||
this.$emit(emitFunction, this.message);
|
||
this.$set(this.status, type, status);
|
||
//todo
|
||
// this.testAuto(type);
|
||
|
||
}
|
||
}
|
||
})
|
||
},
|
||
// 修改运行时间以及备注 点击关闭
|
||
close() {
|
||
this.$refs.inputDialog.close()
|
||
},
|
||
// 新增:确认修改运行时间
|
||
// 确认修改运行时间
|
||
confirmModifyTime: function () {
|
||
const funcMsg = "该功能用来设置设备运行时间及设备别名,设备运行时间即开启设备后到达运行时间自行暂停设备;设备别名不填则展示默认设备名称"
|
||
if ((store.getters && store.getters.name !== 'admin')
|
||
&& this.$auth.hasRole("test")) {
|
||
// this.testFunction(`${this.testMsg}\n${funcMsg}`)
|
||
this.$refs?.inputDialog?.close();
|
||
return;
|
||
}
|
||
// 1. 解构赋值:简化频繁的this.xxx调用,提升可读性
|
||
let {
|
||
newLimitTime, currentCardTime, selectedText, currentCard,
|
||
limitTimes, dtu_remark, imei, agriId, remark
|
||
} = this;
|
||
|
||
// 2. 恢复并优化数字校验(如需启用,取消注释即可)
|
||
/*if (!newLimitTime || newLimitTime < 1 || newLimitTime > 60) {
|
||
uni.showToast({ title: '请输入1-60的有效数字', icon: 'none' });
|
||
return;
|
||
}*/
|
||
|
||
// 3. 定义核心判定变量(语义化命名)
|
||
const isLimitTimeModified = newLimitTime !== currentCardTime; // 运行时间是否修改
|
||
remark = remark || currentCard.name;
|
||
const isRemarkModified = (remark !== (dtu_remark[currentCard.type] || currentCard.name)); // 别名是否修改
|
||
|
||
// 4. 无修改则直接返回,避免无效弹窗
|
||
if (!isLimitTimeModified && !isRemarkModified) {
|
||
// 关闭弹窗(无论确认/取消都关闭)
|
||
this.$refs?.inputDialog?.close();
|
||
return;
|
||
}
|
||
|
||
// 5. 简化提示文案拼接(减少嵌套判断)
|
||
let confirmContent = `确定修改${selectedText}-${currentCard.name}:`;
|
||
const tips = [];
|
||
if (isLimitTimeModified) tips.push(`运行时间为:${newLimitTime} 秒`);
|
||
if (isRemarkModified) {
|
||
tips.push(`别名设置为:${remark}`)
|
||
}
|
||
confirmContent += `\n${tips.map((tip, idx) => `${idx + 1}. ${tip}?`).join('\n')}`;
|
||
|
||
// 6. 确认弹窗(async/await处理异步请求)
|
||
uni.showModal({
|
||
title: '温馨提示:',
|
||
content: confirmContent,
|
||
cancelText: '取消',
|
||
confirmText: '确定',
|
||
success: async (res) => {
|
||
// 关闭弹窗(无论确认/取消都关闭)
|
||
this.$refs?.inputDialog?.close();
|
||
|
||
if (!res.confirm) return; // 取消操作则直接返回
|
||
|
||
let isAllSuccess = false; // 统一判定所有请求是否成功
|
||
|
||
try {
|
||
// 7. 处理运行时间修改
|
||
if (isLimitTimeModified) {
|
||
this.$set(limitTimes, `${currentCard.type}Limit`, newLimitTime || 0);
|
||
// 补全必要字段(合并重复逻辑)
|
||
if (!limitTimes.imei) {
|
||
this.$set(limitTimes, 'imei', imei);
|
||
this.$set(limitTimes, 'agriName', selectedText);
|
||
this.$set(limitTimes, 'agriId', agriId);
|
||
}
|
||
// 发起请求并等待结果(async/await确保顺序执行)
|
||
const limitRes = limitTimes.id
|
||
? await updateLimit(limitTimes)
|
||
: await addLimit(limitTimes);
|
||
if (limitRes.code === 200) {
|
||
isAllSuccess = true;
|
||
this.$emit("getAgriLimit")
|
||
}
|
||
}
|
||
|
||
// 8. 处理别名修改
|
||
if (isRemarkModified) {
|
||
this.$set(dtu_remark, currentCard.type, remark);
|
||
// 补全imei字段
|
||
if (!dtu_remark.imei) {
|
||
this.$set(dtu_remark, 'imei', imei);
|
||
}
|
||
// 发起请求并等待结果
|
||
const remarkRes = dtu_remark.id
|
||
? await updateRemark(dtu_remark)
|
||
: await addRemark(dtu_remark);
|
||
if (remarkRes.code === 200) {
|
||
this.$emit("getRemark")
|
||
isAllSuccess = true;
|
||
}
|
||
}
|
||
|
||
// 9. 正确的提示逻辑(修复原本文案反写的问题)
|
||
this.$modal[isAllSuccess ? 'msgSuccess' : 'msgError'](
|
||
isAllSuccess ? '修改成功' : '修改失败'
|
||
);
|
||
} catch (error) {
|
||
// 捕获网络异常/接口报错,避免页面卡死
|
||
console.error('修改失败:', error);
|
||
this.$modal.msgError('修改失败,请重试');
|
||
}
|
||
}
|
||
});
|
||
},
|
||
// --------------------共同逻辑------------------------------
|
||
// 添加条件更新窗口高度
|
||
updateSwiperHeight() {
|
||
if (this.termList[this.current]['terms'].length >= 3) {
|
||
// 加上 param-setting 和 add-term 的高度,以及一些间距
|
||
this.swiperHeight = this.swiperHeight + 160;
|
||
}
|
||
},
|
||
// 获取窗口高度
|
||
getSwiperHeight() {
|
||
this.swiperHeight = 720;
|
||
var length = this.termList[this.current]['terms'].length-2;
|
||
if (length>0) {
|
||
this.swiperHeight = this.swiperHeight + 160*length ;
|
||
}
|
||
},
|
||
// 一键复制卷膜所有配置到其他卷膜
|
||
copyTerm() {
|
||
var temps = this.termList[this.current]['terms'];
|
||
var config = this.termList[this.current]['config'];
|
||
if (temps.length <= 0) return;
|
||
uni.showModal({
|
||
title: '操作提示:',
|
||
content: '确定复制当前卷膜配置到其他卷膜?',
|
||
cancelText: '取消',
|
||
confirmText: '确定',
|
||
success: (res) => {
|
||
if (res.confirm) {
|
||
for (const [index,value] of this.filmRollerList.entries()) {
|
||
if (index === this.current) continue;
|
||
// this.termList[index]['terms'] = [ ...temps ];
|
||
// this.termList[index]['config']= { ...config };
|
||
this.termList[index]['terms'] = JSON.parse(JSON.stringify(temps));
|
||
this.termList[index]['config']= JSON.parse(JSON.stringify(config));
|
||
this.termList[index]['config'].roller = `jm${index+1}`
|
||
}
|
||
}
|
||
}
|
||
})
|
||
},
|
||
// 添加条件方法
|
||
addTerm() {
|
||
var temps = this.termList[this.current]['terms'];
|
||
if (temps.length >= this.maxTermLength) {
|
||
this.$modal.alert(`您设置的条件数量已超过上限!上限为${this.maxTermLength}条,请删除后重试!`,
|
||
"操作提示");
|
||
return;
|
||
}
|
||
const index = this.current + 1
|
||
this.termList[this.current]['terms'].push({
|
||
id: generateUniqueId(),
|
||
startTime: '请选择时间',
|
||
endTime: '请选择时间',
|
||
temp: '选择',
|
||
vent: '选择',
|
||
imei: this.value,
|
||
roller: `jm${index}`
|
||
});
|
||
this.$nextTick(() => {
|
||
this.updateSwiperHeight(); // 数据更新后,在下一个 tick 更新高度
|
||
});
|
||
},
|
||
// 格式化带单位的数值(通用方法,支持温度/风口等所有字段)
|
||
formatValueWithUnit(value, unit) {
|
||
// 容错:如果value是null/undefined,默认显示“选择”
|
||
if (!value || value === '选择') return '选择';
|
||
// 确保value是字符串/数字,避免拼接出错
|
||
return `${value}${unit}`;
|
||
},
|
||
// 删除条件
|
||
onDeleteItem(event, id) {
|
||
// this.rollerIndex = null;
|
||
const currentKey = this.current;
|
||
// 1. 先拿到当前页签的 terms 数组
|
||
const currentTerms = this.termList[currentKey]?.terms || [];
|
||
// 2. 过滤出要保留的项
|
||
const newTerms = currentTerms.filter(item => item.id !== id);
|
||
// 3. 只更新当前页签的 terms,保持 termList 结构不变
|
||
this.$set(this.termList[currentKey], 'terms', newTerms);
|
||
// 4. 更新swiper高度(可选)
|
||
this.$nextTick(() => {
|
||
this.getSwiperHeight();
|
||
uni.$emit('uni-swipe-action-hide');
|
||
});
|
||
},
|
||
// 选择运行时间
|
||
changeTime(timeTag, timeIndex) {
|
||
this.timeTag = timeTag;
|
||
this.rollerIndex = timeIndex;
|
||
this.selectTime = true;
|
||
},
|
||
openParamDialog() {
|
||
var config = this.termList[this.current].config;
|
||
this.rollerParam = JSON.parse(JSON.stringify(config));
|
||
this.paramCard = [
|
||
{type: `${config.roller}k`, name: '卷膜开'},
|
||
{type: `${config.roller}g`, name: '卷膜关'}
|
||
]
|
||
this.$refs.autoParam.open();
|
||
},
|
||
// 卷膜参数设置
|
||
setAutoParam() {
|
||
// 2. 优化校验逻辑
|
||
const isValid = this.rollerParam.manualTotalLen > 0 || this.rollerParam.autoTotalLen > 0;
|
||
if (!isValid) {
|
||
this.$modal.alert(`计算风口总长和手动设置风口长度至少填写一个!`,
|
||
"操作提示");
|
||
return;
|
||
}
|
||
// 300/2.13
|
||
const isValidTotalLen = this.rollerParam.manualTotalLen > 300 || this.rollerParam.autoTotalLen > 300;
|
||
if (isValidTotalLen) {
|
||
this.$modal.alert(`风口长度设置不能大于300cm!`,
|
||
"操作提示");
|
||
return;
|
||
}
|
||
if (!(this.rollerParam.reservedLen && this.rollerParam.reservedLen > 0)) {
|
||
this.$modal.alert(`请填写预留风口!`,
|
||
"操作提示");
|
||
return;
|
||
}
|
||
this.rollerParam.ventTotalLen = this.rollerParam.autoTotalLen;
|
||
if (this.rollerParam.manualTotalLen > 0) {
|
||
this.rollerParam.ventTotalLen = this.rollerParam.manualTotalLen;
|
||
}
|
||
this.termList[this.current]['config'] = {...this.rollerParam}
|
||
this.$refs.autoParam.close();
|
||
},
|
||
closeParamDialog() {
|
||
this.$refs.autoParam.close();
|
||
},
|
||
// 选择时间串口点击确定
|
||
confirmTime(time) {
|
||
this.termList[this.current]['terms'][this.rollerIndex][this.timeTag] = `${time.hour}:${time.minute}`
|
||
},
|
||
/**
|
||
* @param tag 参数
|
||
* @param index 条件
|
||
*/
|
||
openSlider(tag, index) {
|
||
console.info(tag,index)
|
||
var fillerTerm = this.termList[this.current]['terms'][index];
|
||
if (tag === 'temp') {
|
||
this.slider = {
|
||
title: '适宜温度',
|
||
min: 0,
|
||
max: 40,
|
||
unit: '℃',
|
||
value: fillerTerm.temp==='选择'?0:fillerTerm.temp,
|
||
mode: tag
|
||
}
|
||
} else if (tag === 'vent') {
|
||
this.slider = {
|
||
title: '风口大小',
|
||
min: 0,
|
||
max: 100,
|
||
unit: 'cm',
|
||
value: fillerTerm.vent==='选择'?0:fillerTerm.vent,
|
||
mode: tag
|
||
}
|
||
}
|
||
this.rollerIndex = index;
|
||
this.$refs.sliderDialog.open();
|
||
},
|
||
changeSlider(e) {
|
||
this.slider.value = e.detail.value
|
||
},
|
||
closeSlider() {
|
||
this.$refs.sliderDialog.close();
|
||
},
|
||
confirmSlider() {
|
||
const slideMode = this.slider.mode;
|
||
const value = this.slider.value;
|
||
if (slideMode === 'temp') {
|
||
this.termList[this.current]['terms'][this.rollerIndex].temp = value;
|
||
} else if (slideMode === 'vent') {
|
||
this.termList[this.current]['terms'][this.rollerIndex].vent = value;
|
||
}
|
||
this.$refs.sliderDialog.close();
|
||
},
|
||
// 保存自动化条件
|
||
saveAutoTerm() {
|
||
const termMap = this.termList;
|
||
const rollerList = [];
|
||
let showTips = null;
|
||
|
||
const checkRules = [
|
||
{
|
||
tip: '请设置自动化条件后重新保存重试!',
|
||
validate: (rollerParam, term) => rollerParam.refTemp === '请选择' && !(term && term.length > 0)
|
||
},
|
||
{
|
||
tip: '参考温度未设置,请点击相应页签左上角设置后重试!',
|
||
validate: (rollerParam, term) => rollerParam.refTemp === '请选择'
|
||
},
|
||
{
|
||
tip: '计算风口总长和手动设置风口长度至少填写一个!请填写后重试!',
|
||
validate: (rollerParam, term) => !((rollerParam.manualTotalLen && rollerParam.manualTotalLen > 0) ||
|
||
(rollerParam.autoTotalLen && rollerParam.autoTotalLen > 0))
|
||
},
|
||
{
|
||
tip: '风口长度设置不能大于300cm!',
|
||
validate: (rollerParam, term) => (rollerParam.manualTotalLen && rollerParam.manualTotalLen > 300) ||
|
||
(rollerParam.autoTotalLen && rollerParam.autoTotalLen > 300)
|
||
},
|
||
{
|
||
tip: '预留风口长度未设置,请点击相应页签右上角设置后重试!',
|
||
validate: (rollerParam, term) => !(rollerParam.reservedLen && rollerParam.reservedLen > 0)
|
||
},
|
||
{
|
||
tip: '温度控制未设置,请设置后重新尝试!',
|
||
validate: (rollerParam, term) => !(term && term.length > 0)
|
||
},
|
||
{
|
||
tip: '温度控制设置条数超过上限!请调整后重试',
|
||
validate: (rollerParam, term) => term && term.length > 5
|
||
},
|
||
{
|
||
tip: '温度控制运行时间填写不完整,请检查填写后重新尝试!',
|
||
validate: (rollerParam, term) => term.some(item => !(item.startTime && item.startTime!=='请选择时间' &&
|
||
item.endTime && item.endTime !== '请选择时间'))
|
||
},
|
||
{
|
||
tip: '温度控制运行时间起不能大于止,请检查填写后重新尝试!',
|
||
validate: (rollerParam, term) => term.some(item => (item.startTime > item.endTime))
|
||
},
|
||
{
|
||
tip: '温度控制运行时间存在冲突,请检查填写后重新尝试!',
|
||
validate: (rollerParam, term) => {
|
||
// 调用时间冲突判断函数
|
||
const { isConflict } = checkTimeConflict(term);
|
||
return isConflict; // 有冲突 → 返回true(校验失败)
|
||
}
|
||
},
|
||
{
|
||
tip: '温度控制适宜温度填写不完整,请填写后重新尝试!',
|
||
validate: (rollerParam, term) => term.some(item => !(item.temp && item.temp!=='选择'))
|
||
},
|
||
{
|
||
tip: '温度控制风口开合大小填写不完整,请填写后重新尝试!',
|
||
validate: (rollerParam, term) => term.some(item => !(item.vent && item.vent!=='选择'))
|
||
}
|
||
];
|
||
|
||
for (const [_, rule] of checkRules.entries()) {
|
||
for (const [index, item] of this.filmRollerList.entries()) {
|
||
const term = termMap[index]['terms']; // 温度条件
|
||
const rollerParam = termMap[index]['config']; // 参数设置
|
||
const filmRoller = this.filmRollerList[index];
|
||
if (!rollerParam) {
|
||
this.$tn.message.toast('参数设置失败,请下拉刷新后重试!')
|
||
return;
|
||
} else if (rule.validate(rollerParam, term)) {
|
||
rollerList.push(filmRoller);
|
||
showTips = rule.tip;
|
||
}
|
||
}
|
||
if (rollerList.length>0) {
|
||
this.$tn.message.toast(`【${rollerList.join(",")}】${showTips}`);
|
||
return;
|
||
}
|
||
}
|
||
console.info(`要保存的条件:`,termMap)
|
||
const hasDuplicate = this.termList
|
||
.filter(item => item.config.refTempCode) // 过滤空值
|
||
.reduce(({ map, isDup }, item) => {
|
||
const code = item.config.refTempCode;
|
||
if (map.has(code)) isDup = true; // 已有该key,标记为重复
|
||
else map.set(code, true); // 无则存入map
|
||
return { map, isDup };
|
||
}, { map: new Map(), isDup: false })
|
||
.isDup;
|
||
if (hasDuplicate) {
|
||
this.showTip = true;
|
||
} else {
|
||
uni.showModal({
|
||
title: '操作提示:',
|
||
content: '确定保存自动化条件?',
|
||
cancelText: '取消',
|
||
confirmText: '确定',
|
||
success: (res) => {
|
||
if (res.confirm) {
|
||
this.saveAgriTerm();
|
||
}
|
||
}
|
||
})
|
||
}
|
||
},
|
||
saveAgriTerm() {
|
||
saveAgriTerm(this.termList).then(response => {
|
||
if (response.code===200) {
|
||
this.$modal.msgSuccess("自动化条件保存成功!")
|
||
} else {
|
||
this.$modal.msgError("自动化条件保存失败!请重试或联系客服!")
|
||
}
|
||
})
|
||
},
|
||
showTips(event) {
|
||
this.showTip = false;
|
||
if (event.index===1) {
|
||
this.saveAgriTerm();
|
||
}
|
||
}
|
||
}
|
||
|
||
};
|
||
</script>
|
||
<style lang="scss" scoped>
|
||
@import '@/tuniao-ui/index.scss';
|
||
@import "@/colorui/main.css";
|
||
@import "@/colorui/icon.css";
|
||
|
||
|
||
/* 2列栅格布局 */
|
||
.card-grid {
|
||
display: grid;
|
||
grid-template-columns: 1fr 1fr;
|
||
gap: 20rpx;
|
||
padding: 20rpx;
|
||
}
|
||
|
||
/* 卡片样式 */
|
||
.control-card {
|
||
background-color: #fff;
|
||
border-radius: 16rpx;
|
||
padding: 30rpx 20rpx;
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
box-shadow: 0 2rpx 8rpx #bfbec1;
|
||
}
|
||
|
||
/* 卡片文字区域 */
|
||
.card-text {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 8rpx;
|
||
}
|
||
|
||
.card-main {
|
||
font-size: 30rpx;
|
||
color: #333;
|
||
font-weight: 500;
|
||
}
|
||
|
||
.card-sub {
|
||
font-size: 24rpx;
|
||
color: #999;
|
||
}
|
||
|
||
/* 保留原有样式,仅修改/新增以下部分 */
|
||
.card-sub-wrapper {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
width: 100%;
|
||
gap: 10rpx;
|
||
/* 新增:给容器加最小宽度,确保所有卡片一致 */
|
||
min-width: 0;
|
||
}
|
||
|
||
.limit-time {
|
||
font-size: 24rpx;
|
||
color: #999;
|
||
/* 可选:加固定左边距,确保和暂停的间距统一 */
|
||
margin-left: 0rpx;
|
||
}
|
||
|
||
/* 卡片图标容器 */
|
||
.card-icon {
|
||
width: 48rpx;
|
||
height: 48rpx;
|
||
border-radius: 50%;
|
||
background-color: #e5e5e5;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
|
||
/* 激活状态(运行) */
|
||
.card-icon.active {
|
||
background-color: #007aff;
|
||
}
|
||
|
||
.uni-px-5 {
|
||
padding-left: 20rpx;
|
||
padding-right: 20rpx;
|
||
}
|
||
|
||
.uni-pb-5 {
|
||
padding-bottom: 15rpx;
|
||
}
|
||
|
||
.uni-view {
|
||
-webkit-flex: 1;
|
||
flex: 1;
|
||
height: 150rpx;
|
||
-webkit-justify-content: center;
|
||
justify-content: center;
|
||
-webkit-align-items: center;
|
||
align-items: center;
|
||
}
|
||
|
||
/deep/ .uni-section-header__slot-right {
|
||
color: green;
|
||
}
|
||
|
||
/* 新增:弹窗样式 */
|
||
.modal-container, .modal-container_ {
|
||
width: 600rpx;
|
||
background: #fff;
|
||
border-radius: 16rpx;
|
||
padding: 30rpx 20rpx;
|
||
}
|
||
.modal-container_{
|
||
padding: 30rpx 40rpx;
|
||
.uni-forms-item:nth-child(1) {
|
||
margin-bottom: 16rpx;
|
||
}
|
||
.card-grid {
|
||
padding: 20rpx 0;
|
||
gap: 30rpx;
|
||
}
|
||
}
|
||
.modal-title {
|
||
font-size: 30rpx;
|
||
font-weight: 500;
|
||
text-align: center;
|
||
margin-bottom: 40rpx;
|
||
color: #333;
|
||
}
|
||
|
||
.modal-input-wrap {
|
||
display: flex;
|
||
align-items: center;
|
||
margin-bottom: 35rpx;
|
||
font-size: 26rpx;
|
||
margin-left: 20rpx;
|
||
}
|
||
|
||
.modal-label {
|
||
width: 180rpx;
|
||
color: #666;
|
||
}
|
||
|
||
.modal-current {
|
||
margin-left: 14rpx;
|
||
color: #333;
|
||
}
|
||
|
||
.modal-input {
|
||
height: 60rpx;
|
||
border: 1px solid #eee;
|
||
border-radius: 8rpx;
|
||
padding: 0 15rpx;
|
||
font-size: 26rpx;
|
||
width: 80rpx;
|
||
}
|
||
/* 核心样式:让子元素水平排列 */
|
||
.modal-slider {
|
||
display: flex;
|
||
align-items: center; /* 垂直居中对齐 */
|
||
padding: 10rpx 20rpx; /* 增加内边距,避免拥挤 */
|
||
gap: 10rpx; /* 元素之间的间距 */
|
||
}
|
||
|
||
/* 标题样式:固定宽度,避免挤压滑块 */
|
||
.slider-label {
|
||
flex: 0 0 auto; /* 不拉伸、不收缩 */
|
||
font-size: 28rpx;
|
||
white-space: nowrap; /* 防止标题换行 */
|
||
}
|
||
|
||
/* 滑块样式:占满剩余空间 */
|
||
.slider-component {
|
||
flex: 1; /* 自动填充剩余宽度 */
|
||
}
|
||
|
||
/* 单位样式:固定宽度 */
|
||
.slider-unit {
|
||
flex: 0 0 auto;
|
||
font-size: 28rpx;
|
||
margin-left: 5rpx;
|
||
}
|
||
|
||
.modal-btn-wrap {
|
||
display: flex;
|
||
gap: 20rpx;
|
||
margin-top: 40rpx;
|
||
}
|
||
|
||
.modal-btn {
|
||
flex: 1;
|
||
height: 70rpx;
|
||
border-radius: 8rpx;
|
||
font-size: 26rpx;
|
||
}
|
||
|
||
.modal-btn.cancel {
|
||
background: #f5f5f5;
|
||
color: #666;
|
||
}
|
||
|
||
.modal-btn.confirm {
|
||
background: #007aff;
|
||
color: #fff;
|
||
}
|
||
|
||
.icon {
|
||
margin-left: 15rpx
|
||
}
|
||
|
||
/deep/ .is-input-border {
|
||
width: 340rpx;
|
||
}
|
||
|
||
.card {
|
||
border-radius: 20rpx;
|
||
overflow: hidden;
|
||
}
|
||
.film-roller {
|
||
padding: 10rpx 20rpx 20rpx 20rpx;
|
||
}
|
||
.swiper {
|
||
box-sizing: border-box;
|
||
border: 2rpx solid rgb(248, 241, 241);
|
||
border-top: 0;
|
||
border-bottom-left-radius: 10rpx;
|
||
border-bottom-right-radius: 10rpx;
|
||
box-shadow: 8rpx 5rpx 10rpx rgb(233, 231, 239);
|
||
padding-top: 10rpx;
|
||
}
|
||
|
||
.add-term {
|
||
display: flex;
|
||
align-items: center; /* 垂直居中 */
|
||
gap: 4px; /* 图标和文字之间的间距 */
|
||
justify-content: center; /* 内部元素水平居中(可选) */
|
||
//padding: 10px 20px;
|
||
font-size: 40rpx;
|
||
color: #42b3ff;
|
||
margin-top: 50rpx;
|
||
//border: 1px solid var(--cyan);
|
||
//border-radius: 8px;
|
||
//background-color: #fff;
|
||
}
|
||
.copy-term {
|
||
margin: 0 10rpx;
|
||
}
|
||
.param-setting {
|
||
display: flex;
|
||
align-items: center;
|
||
font-size: 28rpx;
|
||
color: #0a0a0a;
|
||
.tn-btn-class {
|
||
border-radius: 15rpx;
|
||
}
|
||
.temp-dialog {
|
||
margin-left: 10rpx;
|
||
}
|
||
.param-dialog {
|
||
margin-left: auto; /* 自动填充左侧空间,将按钮推到最右侧 */
|
||
}
|
||
}
|
||
.term-content {
|
||
margin: 20rpx;
|
||
}
|
||
|
||
|
||
.swiper-custom {
|
||
box-shadow: 8rpx 5rpx 10rpx #D9D9D9 !important;
|
||
//border: 2rpx solid #D9D9D9;
|
||
margin-bottom: 20rpx;
|
||
background: #F8F7F8;
|
||
border-radius: 12rpx;
|
||
}
|
||
.message {
|
||
padding: 10rpx;
|
||
display: flex;
|
||
flex-direction: row;
|
||
align-items: center;
|
||
text-align: center;
|
||
}
|
||
.message__left {
|
||
flex:3;
|
||
.message__tag {
|
||
font-size: 25rpx;
|
||
margin-bottom: 8rpx;
|
||
color: #42b3ff;
|
||
}
|
||
}
|
||
.message__middle {
|
||
flex: 4;
|
||
.message__name {
|
||
margin-bottom: 8rpx;
|
||
}
|
||
}
|
||
|
||
.message__name {
|
||
font-size: 24rpx;
|
||
color: #838383;
|
||
}
|
||
.message__right {
|
||
flex: 2;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
justify-content: center;
|
||
width: 150rpx;
|
||
height: 100rpx;
|
||
margin: 10rpx;
|
||
border-radius: 50rpx;
|
||
background-color: #fff;
|
||
box-shadow: 0 2rpx 4rpx #D9D9D9;
|
||
transition: all 0.2s ease;
|
||
}
|
||
|
||
// 点击反馈效果
|
||
.message__right:active {
|
||
background-color: #f5f5f5;
|
||
transform: scale(0.98);
|
||
}
|
||
//.message__tag {
|
||
// font-size: 24rpx;
|
||
// color: #838383;
|
||
// text-align: center;
|
||
//}
|
||
.message__content {
|
||
font-size: 27rpx;
|
||
color: #020e15;
|
||
}
|
||
/deep/ .uni-slider-handle-wrapper {
|
||
height: 10rpx !important;
|
||
}
|
||
/deep/ .uni-forms-item {
|
||
border-bottom: 1rpx solid #E5E5E5;
|
||
.uni-forms-item__label {
|
||
font-size: 28rpx;
|
||
color: #0a0a0a;
|
||
}
|
||
}
|
||
/deep/.modal-container_ .uni-input-input {
|
||
text-align: right !important;
|
||
font-size: 28rpx;
|
||
}
|
||
</style>
|