Преглед изворни кода

feat(deviceControl): 替换原生滑块为自定义进度滑块并调整参数范围

替换原有u-slider组件为自定义进度条实现,调整各配置项的取值范围:定时时长1-10h、落虫/加热时间1-20min、加热温度75-120℃、高低温保护阈值50-70℃/-30-20℃、数据上传间隔10-60min,优化交互体验
allen пре 1 дан
родитељ
комит
7811617a15
1 измењених фајлова са 192 додато и 6 уклоњено
  1. 192 6
      pages/cbd/deviceControl.vue

+ 192 - 6
pages/cbd/deviceControl.vue

@@ -66,52 +66,172 @@
           </u-radio>
         </u-radio-group>
         <view class="device-detail-viewImage">
-          <text class="device-detail-label">落虫时间(min){{ equipContrlForm.collt }}</text>
+          <text class="device-detail-label">定时时长(h){{ equipContrlForm.tt }}</text>
         </view>
+        <!-- <view class="slider-container">
+          <view class="slider-min-value">0</view>
+          <u-slider v-model="equipContrlForm.tt" class="slider" max="100" min="0" active-color="#0BBC58"></u-slider>
+          <view class="slider-max-value">100</view>
+        </view> -->
         <view class="slider-container">
+          <view class="slider-min-value">1</view>
+          <view
+            class="custom-progress"
+            @touchstart.stop="onSliderTouchStart($event, 'tt', 1, 10)"
+            @touchmove.stop.prevent="onSliderTouchMove($event, 1, 10)"
+            @touchend.stop="onSliderTouchEnd"
+            @tap.stop="onSliderTap($event, 'tt', 1, 10)"
+          >
+            <view class="progress-track">
+              <view class="progress-fill" :style="{ width: getProgressWidth(equipContrlForm.tt, 1, 10) + '%' }"></view>
+              <view class="progress-thumb" :style="{ left: getProgressWidth(equipContrlForm.tt, 1, 10) + '%' }"></view>
+            </view>
+          </view>
+          <view class="slider-max-value">10</view>
+        </view>
+        <view class="device-detail-viewImage">
+          <text class="device-detail-label">落虫时间(min){{ equipContrlForm.collt }}</text>
+        </view>
+        <!-- <view class="slider-container">
           <view class="slider-min-value">0</view>
           <u-slider v-model="equipContrlForm.collt" class="slider" max="100" min="0" active-color="#0BBC58"></u-slider>
           <view class="slider-max-value">100</view>
+        </view> -->
+        <view class="slider-container">
+          <view class="slider-min-value">1</view>
+          <view
+            class="custom-progress"
+            @touchstart.stop="onSliderTouchStart($event, 'collt', 1, 20)"
+            @touchmove.stop.prevent="onSliderTouchMove($event, 1, 20)"
+            @touchend.stop="onSliderTouchEnd"
+            @tap.stop="onSliderTap($event, 'collt', 1, 20)"
+          >
+            <view class="progress-track">
+              <view class="progress-fill" :style="{ width: getProgressWidth(equipContrlForm.collt, 1, 20) + '%' }"></view>
+              <view class="progress-thumb" :style="{ left: getProgressWidth(equipContrlForm.collt, 1, 20) + '%' }"></view>
+            </view>
+          </view>
+          <view class="slider-max-value">20</view>
         </view>
         <view class="device-detail-viewImage">
           <text class="device-detail-label">加热时间(min){{ equipContrlForm.htim }}</text>
         </view>
-        <view class="slider-container">
+        <!-- <view class="slider-container">
           <view class="slider-min-value">0</view>
           <u-slider v-model="equipContrlForm.htim" class="slider" max="100" min="0" active-color="#0BBC58"></u-slider>
           <view class="slider-max-value">100</view>
+        </view> -->
+        <view class="slider-container">
+          <view class="slider-min-value">1</view>
+          <view
+            class="custom-progress"
+            @touchstart.stop="onSliderTouchStart($event, 'htim', 1, 20)"
+            @touchmove.stop.prevent="onSliderTouchMove($event, 1, 20)"
+            @touchend.stop="onSliderTouchEnd"
+            @tap.stop="onSliderTap($event, 'htim', 1, 20)"
+          >
+            <view class="progress-track">
+              <view class="progress-fill" :style="{ width: getProgressWidth(equipContrlForm.htim, 1, 20) + '%' }"></view>
+              <view class="progress-thumb" :style="{ left: getProgressWidth(equipContrlForm.htim, 1, 20) + '%' }"></view>
+            </view>
+          </view>
+          <view class="slider-max-value">20</view>
         </view>
         <view class="device-detail-viewImage">
           <text class="device-detail-label">加热温度(℃){{ equipContrlForm.hst }}</text>
         </view>
-        <view class="slider-container">
+        <!-- <view class="slider-container">
           <view class="slider-min-value">0</view>
           <u-slider v-model="equipContrlForm.hst"  class="slider" max="100" min="0" active-color="#0BBC58"></u-slider>
           <view class="slider-max-value">100</view>
+        </view> -->
+        <view class="slider-container">
+          <view class="slider-min-value">75</view>
+          <view
+            class="custom-progress"
+            @touchstart.stop="onSliderTouchStart($event, 'hst', 75, 120)"
+            @touchmove.stop.prevent="onSliderTouchMove($event, 75, 120)"
+            @touchend.stop="onSliderTouchEnd"
+            @tap.stop="onSliderTap($event, 'hst', 75, 120)"
+          >
+            <view class="progress-track">
+              <view class="progress-fill" :style="{ width: getProgressWidth(equipContrlForm.hst, 75, 120) + '%' }"></view>
+              <view class="progress-thumb" :style="{ left: getProgressWidth(equipContrlForm.hst, 75, 120) + '%' }"></view>
+            </view>
+          </view>
+          <view class="slider-max-value">120</view>
         </view>
         <view class="device-detail-viewImage">
           <text class="device-detail-label">高温保护阀值(℃){{ equipContrlForm.tph }}</text>
         </view>
-        <view class="slider-container">
+        <!-- <view class="slider-container">
           <view class="slider-min-value">0</view>
           <u-slider v-model="equipContrlForm.tph" class="slider" max="100" min="0" active-color="#0BBC58"></u-slider>
           <view class="slider-max-value">100</view>
+        </view> -->
+        <view class="slider-container">
+          <view class="slider-min-value">50</view>
+          <view
+            class="custom-progress"
+            @touchstart.stop="onSliderTouchStart($event, 'tph', 50, 70)"
+            @touchmove.stop.prevent="onSliderTouchMove($event, 50, 70)"
+            @touchend.stop="onSliderTouchEnd"
+            @tap.stop="onSliderTap($event, 'tph', 50, 70)"
+          >
+            <view class="progress-track">
+              <view class="progress-fill" :style="{ width: getProgressWidth(equipContrlForm.tph, 50, 70) + '%' }"></view>
+              <view class="progress-thumb" :style="{ left: getProgressWidth(equipContrlForm.tph, 50, 70) + '%' }"></view>
+            </view>
+          </view>
+          <view class="slider-max-value">70</view>
         </view>
         <view class="device-detail-viewImage">
           <text class="device-detail-label">低温保护阀值(℃){{ equipContrlForm.tpl }}</text>
         </view>
-        <view class="slider-container">
+        <!-- <view class="slider-container">
           <view class="slider-min-value">0</view>
           <u-slider v-model="equipContrlForm.tpl" class="slider" max="100" min="0" active-color="#0BBC58"></u-slider>
           <view class="slider-max-value">100</view>
+        </view> -->
+        <view class="slider-container">
+          <view class="slider-min-value">-30</view>
+          <view
+            class="custom-progress"
+            @touchstart.stop="onSliderTouchStart($event, 'tpl', -30, 20)"
+            @touchmove.stop.prevent="onSliderTouchMove($event, -30, 20)"
+            @touchend.stop="onSliderTouchEnd"
+            @tap.stop="onSliderTap($event, 'tpl', -30, 20)"
+          >
+            <view class="progress-track">
+              <view class="progress-fill" :style="{ width: getProgressWidth(equipContrlForm.tpl, -30, 20) + '%' }"></view>
+              <view class="progress-thumb" :style="{ left: getProgressWidth(equipContrlForm.tpl, -30, 20) + '%' }"></view>
+            </view>
+          </view>
+          <view class="slider-max-value">20</view>
         </view>
         <view class="device-detail-viewImage">
           <text class="device-detail-label">数据上传间隔(min){{ equipContrlForm.datt }}</text>
         </view>
-        <view class="slider-container">
+        <!-- <view class="slider-container">
           <view class="slider-min-value">0</view>
           <u-slider v-model="equipContrlForm.datt" class="slider" max="100" min="0" active-color="#0BBC58"></u-slider>
           <view class="slider-max-value">100</view>
+        </view> -->
+        <view class="slider-container">
+          <view class="slider-min-value">10</view>
+          <view
+            class="custom-progress"
+            @touchstart.stop="onSliderTouchStart($event, 'datt', 10, 60)"
+            @touchmove.stop.prevent="onSliderTouchMove($event, 10, 60)"
+            @touchend.stop="onSliderTouchEnd"
+            @tap.stop="onSliderTap($event, 'datt', 10, 60)"
+          >
+            <view class="progress-track">
+              <view class="progress-fill" :style="{ width: getProgressWidth(equipContrlForm.datt, 10, 60) + '%' }"></view>
+              <view class="progress-thumb" :style="{ left: getProgressWidth(equipContrlForm.datt, 10, 60) + '%' }"></view>
+            </view>
+          </view>
+          <view class="slider-max-value">60</view>
         </view>
       </view>
     </view>
@@ -166,6 +286,41 @@ export default {
     })
   },
   methods: {
+    getProgressWidth(value, min, max) {
+      if (max === min) return 0
+      return ((value - min) / (max - min)) * 100
+    },
+    onSliderTouchStart(e, field, min, max) {
+      this.sliderField = field
+      this.sliderMin = min
+      this.sliderMax = max
+      const query = uni.createSelectorQuery().in(this)
+      query.select('.custom-progress').boundingClientRect(rect => {
+        this.sliderRect = rect
+      }).exec()
+      this.updateSliderValue(e.touches[0].clientX, field, min, max)
+    },
+    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) 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)
+    },
     handleBack() {
       uni.navigateBack({
         delta: 1
@@ -400,6 +555,37 @@ export default {
       top: -50rpx;
     }
   }
+  .custom-progress{
+    width: 600rpx;
+    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;
+    }
+  }
   .device-detail-btn-footer{
     position: fixed;
     bottom: 0;