| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451 |
- <template>
- <view class="control-container">
- <custom-card>
- <block slot="backText">{{ title }}</block>
- </custom-card>
- <view class="control-content" v-if="leftList.length > 0">
- <view class="control-list-left">
- <view
- class="control-list-left-item"
- v-for="(item, index) in leftList"
- :key="index"
- @click="controlClick(index)"
- :class="{ 'control-list-left-item-active': index === activeIndex }"
- >
- {{ item.title }}
- </view>
- </view>
- <view class="control-list-right">
- <view class="action-container" v-if="deviceList.length > 0">
- <view class="action-button" @click="openAll">一键开启</view>
- <view class="action-button action-button-plain" @click="closeAll">一键关闭</view>
- </view>
- <view
- v-for="(item, index) in deviceList"
- class="control-list-right-item"
- :key="index"
- >
- <view style="display: flex; align-items: center;" v-if="item.sfType != '10'">
- <view class="control-list-right-item-icon">
- <image
- :src="solenoidValve"
- class="solenoid-valve"
- />
- </view>
- <view class="control-list-right-item-title">{{
- item.device_name
- }}</view>
- <view class="control-list-right-item-action">
- <u-switch
- :value="item.device_status == 1 ? true : false"
- activeColor="#0BBC58"
- size="40"
- inactiveColor="rgb(230, 230, 230)"
- ></u-switch>
- </view>
- </view>
- </view>
- <u-empty v-if="deviceList.length === 0" text="暂无数据"></u-empty>
- </view>
- </view>
- <u-empty v-else text="暂无数据"></u-empty>
- <u-popup v-model="showPopup" mode="bottom">
- <u-form :model="form" label-width="160rpx" :label-style="{marginLeft:'20rpx'}">
- <u-form-item label="开启状态">
- <u-radio-group v-model="value">
- <u-radio
- @change="radioChange"
- v-for="(item, index) in radioList" :key="index"
- :name="item.value"
- active-color="#0BBC58"
- >
- {{item.name}}
- </u-radio>
- </u-radio-group>
- </u-form-item>
- <u-form-item label="开阀时间" v-if="value == 1">
- <view @click="show1 = true" class="hour">{{hour}} 小时</view>
- </u-form-item>
- <u-form-item label="开度数值">
- <view class="slider-row" style="display:flex;align-items:center;"><view class="slider-container">
- <view class="slider-min-value">10</view>
- <view
- class="custom-progress"
- @touchstart.stop="onSliderTouchStart($event, 'openingValue', 10, 100)"
- @touchmove="onSliderTouchMove($event, 10, 100)"
- @touchend.stop="onSliderTouchEnd"
- >
- <view class="progress-track">
- <view class="progress-fill" :style="{ width: getProgressWidth(equipContrlForm.openingValue, 10, 100) + '%' }"></view>
- <view class="progress-thumb" :style="{ left: getProgressWidth(equipContrlForm.openingValue, 10, 100) + '%' }"></view>
- </view>
- </view>
- <view class="slider-max-value">100</view>
- </view>
- <text style="margin-left: 20rpx">{{equipContrlForm.openingValue}}</text></view>
- </u-form-item>
- <u-button type="success" style="width: 94%;margin-left: 3%;margin-bottom: 40rpx" @click="submit">提交</u-button>
- </u-form>
- </u-popup>
- <u-modal v-model="show2" :title="'提示'" :content="content" @confirm="confirmHandle" @cancel="show2 = false"></u-modal>
- <u-select v-model="show1" :list="hours" @confirm="changeHour"></u-select>
- <u-popup v-model="show4" mode="center" width="80%" :mask-close-able="false">
- <view class="progress-container">
- <u-line-progress :percent="percentage" style="width: 90%;"></u-line-progress>
- </view>
- </u-popup>
- </view>
- </template>
- <script>
- import solenoidValve from './assets/solenoidValve.png';
- export default {
- name: 'control',
- data() {
- return {
- show1: false,
- show2: false,
- show4: false,
- percentage: 0,
- activeIndex: 0,
- showPopup: false,
- content:'确定一键关闭所有阀门吗?',
- value: 0,
- sliderField: '',
- sliderMin: 0,
- hours: [],
- sliderMax: 0,
- sliderRect: {},
- hour: 1,
- minute: 0,
- form: {},
- radioList:[{
- name:'常开',
- value:0
- },
- {
- name:'定时',
- value:1
- }],
- equipContrlForm: {
- openingValue: 60,
- },
- solenoidValve,
- title: '分组控制',
- leftList: [],
- deviceList: [],
- timer: null,
- };
- },
- methods: {
- changeHour(e){
- this.hour = e[0].value
- },
- setPercentage(msg){
- this.timer = setInterval(() => {
- this.percentage += 1;
- if(this.percentage >= 100){
- this.percentage = 100;
- uni.showToast({
- title: msg,
- icon: 'none',
- });
- clearInterval(this.timer);
- this.show4 = false;
- this.percentage = 0;
- this.getdeviceSfStatus();
- }
- }, 125);
- },
- getHours(){
- for(let i = 0; i < 24; i++){
- this.hours.push({
- label: i + ' 时',
- value: i,
- })
- }
- },
- async confirmHandle(){
- const data = {
- group_id: this.leftList[this.activeIndex].id,
- control_type:'close',
- };
- const res = await this.$myRequest({
- url: '/api/api_gateway?method=irrigation_system.valvecontrol.control_huapu_valve_group',
- method: 'post',
- data
- });
- if(res.code == 0){
- this.show4 = true;
- this.setPercentage(res.msg);
- }
- this.showPopup = false;
- this.show2 = false;
- },
- async submit(){
- const data = {
- group_id: this.leftList[this.activeIndex].id,
- control_type:'open',
- valve_delayed: this.value == 0 ? 0 : this.hour * 60 + this.minute,
- var_value: this.equipContrlForm.openingValue,
- };
- const res = await this.$myRequest({
- url: '/api/api_gateway?method=irrigation_system.valvecontrol.control_huapu_valve_group',
- method: 'post',
- data
- });
- if(res.code == 0){
- this.show4 = true;
- this.setPercentage(res.msg);
- }
- this.showPopup = false;
- this.show2 = false;
- },
- getProgressWidth(value, min, max) {
- if (max === min) return 0
- return ((value - min) / (max - min)) * 100
- },
- getModel(value){
- return value == 0 ? false : true
- },
- controlClick(index) {
- this.activeIndex = index;
- this.deviceList = this.leftList[this.activeIndex]?.device_list || [];
- },
- onSliderTouchStart(e, field, min, max) {
- const clientX = e.touches[0].clientX
- this.sliderField = field
- this.sliderMin = min
- this.sliderMax = max
- const query = uni.createSelectorQuery().in(this)
- query.selectAll('.custom-progress').boundingClientRect(rects => {
- const list = Array.isArray(rects) ? rects : []
- this.sliderRect = list.find(r => r && r.width > 0) || list[0] || null
- this.updateSliderValue(clientX, field, min, max)
- }).exec()
- },
- onSliderTouchMove(e, min, max) {
- if (!this.sliderField || !this.sliderRect) return
- this.updateSliderValue(e.touches[0].clientX, this.sliderField, min, max)
- },
- onSliderTouchEnd() {
- this.sliderField = ''
- },
- onSliderTap(e, field, min, max) {
- const query = uni.createSelectorQuery().in(this)
- query.select('.custom-progress').boundingClientRect(rect => {
- this.sliderRect = rect
- this.updateSliderValue(e.detail.x + rect.left, field, min, max)
- }).exec()
- },
- updateSliderValue(clientX, field, min, max) {
- if (!this.sliderRect || !this.sliderRect.width) return
- let ratio = (clientX - this.sliderRect.left) / this.sliderRect.width
- ratio = Math.max(0, Math.min(1, ratio))
- const value = Math.round(min + ratio * (max - min))
- this.$set(this.equipContrlForm, field, value)
- },
- openAll(){
- this.showPopup = true;
- },
- closeAll(){
- this.show2 = true;
- },
- initData(res){
- this.deviceList = [];
- this.leftList = [];
- res?.forEach((item) => {
- this.leftList.push(item);
- });
- },
- async getdeviceSfStatus() {
- this.activeIndex = 0;
- const res = await this.$myRequest({
- url: '/api/api_gateway?method=irrigation_system.valvecontrol.get_huapu_valve_group_list',
- method: 'post',
- });
- this.initData(res?.data || []);
- },
- },
- onLoad() {
- this.getHours();
- this.getdeviceSfStatus();
- },
- };
- </script>
- <style scoped lang="scss">
- uni-page-body {
- position: relative;
- height: 100%;
- }
- .progress-container{
- display: flex;
- justify-content: center;
- align-items: center;
- height:100%;
- }
- .hour,.minute{
- font-size: 28rpx;
- color: #999999;
- border-radius: 8rpx;
- border: 2rpx solid #aaa;
- padding: 4rpx 8rpx;
- margin-right: 8rpx;
- height: 40rpx;
- display: flex;
- align-items: center;
- justify-content: center;
- width: 160rpx;
- }
- .control-container {
- background: linear-gradient(180deg, #ffffff00 0%, #fff 23.64%, #fff 100%),
- linear-gradient(102deg, #bfeadd 6.77%, #b8f1e7 40.15%, #b9eef5 84.02%);
- height: 100%;
- width: 100%;
- overflow-x: hidden;
- overflow-y: hidden;
- .control-content {
- display: flex;
- width: 100%;
- height: calc(100% - 102rpx);
- overflow-x: hidden;
- overflow-y: auto;
- padding: 8px 0;
- border-radius: 8px 8px 0 0;
- background: #fff;
- .control-list-left {
- width: 250rpx;
- position: fixed;
- height: calc(100% - 90rpx);
- overflow-x: hidden;
- overflow-y: auto;
- .control-list-left-item {
- width: 240rpx;
- height: 96rpx;
- line-height: 96rpx;
- background: #f5f7fa;
- padding-left: 24rpx;
- color: #364d46;
- font-family: 'Source Han Sans CN VF';
- font-size: 32rpx;
- font-weight: 400;
- position: relative;
- //超出隐藏
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
- }
- .control-list-left-item-active {
- background: #0bbc581a;
- color:#0BBC58;
- font-family: "Source Han Sans CN VF";
- font-size: 32rpx;
- font-weight: 700;
- }
- }
- .control-list-right {
- width: calc(100% - 250rpx);
- margin: 0 32rpx;
- margin-left: 280rpx;
- .action-container {
- display: flex;
- justify-content: center;
- align-items: center;
- margin-bottom: 22rpx;
- gap: 22rpx;
- .action-button{
- flex:1;
- height: 80rpx;
- line-height: 80rpx;
- text-align: center;
- border-radius: 8rpx;
- background: #0bbc58;
- color:#ffffff;
- font-family: "Source Han Sans CN VF";
- font-size: 28rpx;
- font-weight: 600;
- }
- .action-button-plain{
- background: #ffffff;
- border:2rpx solid #0bbc58;
- color:#0bbc58;
- }
- }
- .control-list-right-item {
- height: 96rpx;
- display: flex;
- padding: 0rpx 16rpx;
- align-items: center;
- border-radius: 8rpx;
- background: #f5f7fa;
- margin-bottom: 22rpx;
- position: relative;
- .control-list-right-item-icon {
- display: flex;
- align-items: center;
- .solenoid-valve {
- width: 40rpx;
- height: 40rpx;
- }
- }
- .control-list-right-item-title {
- margin-left: 8rpx;
- }
- .control-list-right-item-action {
- position: absolute;
- right: 16rpx;
- }
- }
- }
- }
-
- .slider-container{
- position: relative;
- margin-top: 10rpx;
- .slider-min-value{
- position: absolute;
- left: 0;
- top: -60rpx;
- }
- .slider{
- width: 600rpx;
- }
- .slider-max-value{
- position: absolute;
- right: 0;
- top: -60rpx;
- }
- }
- .custom-progress{
- width: 500rpx;
- padding: 0;
- .progress-track{
- position: relative;
- height: 12rpx;
- background-color: #ebedf0;
- border-radius: 6rpx;
- }
- .progress-fill{
- position: absolute;
- left: 0;
- top: 0;
- height: 100%;
- background-color: #0BBC58;
- border-radius: 6rpx;
- transition: width 0.2s;
- }
- .progress-thumb{
- position: absolute;
- top: 50%;
- width: 28rpx;
- height: 28rpx;
- margin-left: -14rpx;
- margin-top: -14rpx;
- border-radius: 50%;
- background-color: #fff;
- box-shadow: 0 1px 4px rgba(0,0,0,0.3);
- transition: left 0.2s;
- }
- }
- }
- </style>
|