Pārlūkot izejas kodu

feat: 优化害虫分析图表样式并增强设备数据展示功能

refactor(deviceData): 重构图表组件使用echarts替代u-charts

feat(photoImage): 添加年份选择和时间范围筛选功能

fix(detail): 修复设备数据初始化逻辑并添加历史数据获取

style(pestEchart): 调整图表分割线样式为虚线

feat(devicePhoto): 实现害虫分类展示和图片详情查看功能
allen 13 stundas atpakaļ
vecāks
revīzija
0366974d6d

+ 175 - 106
pages/cbd/components/deviceData.vue

@@ -79,20 +79,13 @@
             {{ tab.name }}
           </view>
         </view>
-        <view class="chart-dropdown">
+        <!-- <view class="chart-dropdown">
           <text class="iconfont dropdown-icon">&#xe606;</text>
-        </view>
+        </view> -->
       </view>
       <view class="chart-content">
         <view class="chart-canvas-container">
-          <canvas
-            canvas-id="tempChart"
-            id="tempChart"
-            class="chart-canvas"
-            @touchstart="chartTouchStart"
-            @touchmove="chartTouchMove"
-            @touchend="chartTouchEnd"
-          />
+          <div id="tempChart" class="chart-canvas"></div>
         </view>
       </view>
     </view>
@@ -116,7 +109,7 @@
                 class="fixed-row"
                 :class="{ even: index % 2 === 0 }"
               >
-                <text class="body-cell fixed">{{ item.time }}</text>
+                <text class="body-cell fixed">{{ formatTime(item.addtime) }}</text>
               </view>
             </view>
           </view>
@@ -125,10 +118,16 @@
             <view class="scrollable-header">
               <text class="header-cell">环境温度(°C)</text>
               <text class="header-cell">环境湿度(%)</text>
-              <text class="header-cell">环境湿度(%)</text>
-              <text class="header-cell">环境湿度(%)</text>
-              <text class="header-cell">环境湿度(%)</text>
-              <text class="header-cell">环境湿度(%)</text>
+              <text class="header-cell">加热仓温度(°C)</text>
+              <text class="header-cell">雨控状态</text>
+              <text class="header-cell">温控状态</text>
+              <text class="header-cell">光控状态</text>
+              <text class="header-cell">灯管状态</text>
+              <text class="header-cell">信号强度</text>
+              <text class="header-cell">电流(mA)</text>
+              <text class="header-cell">电压(V)</text>
+              <text class="header-cell">经度</text>
+              <text class="header-cell">纬度</text>
             </view>
             <view class="scrollable-body">
               <view
@@ -137,13 +136,18 @@
                 class="scrollable-row"
                 :class="{ even: index % 2 === 0 }"
               >
-                <text class="body-cell">{{ item.temp }}</text>
-                <text class="body-cell">{{ item.humidity }}</text>
-                <text class="body-cell">{{ item.humidity }}</text>
-                <text class="body-cell">{{ item.humidity }}</text>
-                <text class="body-cell">{{ item.humidity }}</text>
-                <text class="body-cell">{{ item.humidity }}</text>
-                <text class="body-cell">{{ item.humidity }}</text>
+                <text class="body-cell">{{ item.at }}</text>
+                <text class="body-cell">{{ item.ah }}</text>
+                <text class="body-cell">{{ item.hrt }}</text>
+                <text class="body-cell">{{ item.rps }}</text>
+                <text class="body-cell">{{ item.tps }}</text>
+                <text class="body-cell">{{ item.lps }}</text>
+                <text class="body-cell">{{ item.blbs }}</text>
+                <text class="body-cell">{{ item.csq }}</text>
+                <text class="body-cell">{{ item.current }}</text>
+                <text class="body-cell">{{ item.vbat }}</text>
+                <text class="body-cell">{{ item.lng }}</text>
+                <text class="body-cell">{{ item.lat }}</text>
               </view>
             </view>
           </view>
@@ -159,7 +163,7 @@
 </template>
 
 <script>
-import uCharts from '@/components/js_sdk/u-charts/u-charts/u-charts.js';
+import * as echarts from 'echarts';
 import setting from '../assets/setting.png';
 import edit from '../assets/edit.png';
 import sim from '../assets/sim.png';
@@ -175,7 +179,15 @@ export default {
     deviceStatic:{
       type:Object,
       default:()=>({}),
-    }
+    },
+    polylineList:{
+      type:Array,
+      default:()=>[],
+    },
+    deviceHistoryList:{
+      type:Array,
+      default:()=>[],
+    },
   },
   data() {
     return {
@@ -183,38 +195,43 @@ export default {
       edit,
       sim,
       chartTabs: [
-        { name: '温度', id: 'temp' },
-        { name: '湿度', id: 'humidity' },
-        { name: '加热仓温度', id: 'heatingTemp' },
-        { name: '雨量累计', id: 'rainfall' }
+        { name: '温度', id: 'new_tem' },
+        { name: '湿度', id: 'new_hum' },
+        { name: '加热仓温度', id: 'others' },
       ],
+      xData:[],
+      yData:[],
       activeChartTab: 0,
-      chartData: {
-        categories: ['05-29/00:00', '05-29/00:00', '05-29/00:00', '05-29/00:00', '05-29/00:00', '05-29/00:00'],
-        series: [
-          {
-            name: '大气温度',
-            data: [2, 4, 6, 8, 10, 8]
-          }
-        ]
-      },
-      cWidth: 320,
-      cHeight: 180,
-      historyData: [
-        { time: '2025-12-28 08:00', temp: '25', humidity: '70' },
-        { time: '2025-12-28 07:00', temp: '24', humidity: '68' },
-        { time: '2025-12-28 06:00', temp: '23', humidity: '65' },
-        { time: '2025-12-28 05:00', temp: '22', humidity: '63' },
-        { time: '2025-12-28 04:00', temp: '21', humidity: '60' },
-        { time: '2025-12-28 03:00', temp: '20', humidity: '58' },
-        { time: '2025-12-28 02:00', temp: '19', humidity: '55' }
-      ],
+      historyData: [],
       currentPage: 1,
       totalPages: 6
     };
   },
-  mounted() {
-    this.initChart();
+  watch:{
+    polylineList:{
+      handler(newVal, oldVal){
+        if(newVal.length > 0){
+          this.xData = newVal.map(item => this.formatDate(new Date(item.addtime)));
+          this.yData = newVal.map(item => Number(item.new_tem) || 0);
+          this.initChart();
+        }
+      },
+      deep:true,
+      immediate:true,
+    },
+    deviceHistoryList:{
+      handler(newVal, oldVal){
+        console.log(newVal,'newValnewVal')
+        this.historyData = []
+        if(newVal.length > 0){
+          newVal.forEach(item=>{
+            this.historyData.push(item.d_h_t)
+          })
+        }
+      },
+      deep:true,
+      immediate:true,
+    }
   },
   methods: {
     openSettings(){
@@ -226,8 +243,6 @@ export default {
       });
     },
     initChart() {
-      this.cWidth = uni.upx2px(640);
-      this.cHeight = uni.upx2px(360);
       this.$nextTick(() => {
         this.drawChart();
       });
@@ -238,82 +253,136 @@ export default {
       const year = date.getFullYear();
       const month = String(date.getMonth() + 1).padStart(2, '0');
       const day = String(date.getDate()).padStart(2, '0');
+      return `${year}-${month}-${day}`;
+    },
+    formatTime(dateString) {
+      const date = new Date(dateString*1000);
+      const year = date.getFullYear();
+      const month = String(date.getMonth() + 1).padStart(2, '0');
+      const day = String(date.getDate()).padStart(2, '0');
       const hour = String(date.getHours()).padStart(2, '0');
       const minute = String(date.getMinutes()).padStart(2, '0');
       const second = String(date.getSeconds()).padStart(2, '0');
       return `${year}-${month}-${day} ${hour}:${minute}:${second}`;
     },
     drawChart() {
-      const ctx = uni.createCanvasContext('tempChart', this);
-
-      chartInstance = new uCharts({
-        type: 'area',
-        context: ctx,
-        width: this.cWidth,
-        height: this.cHeight,
-        categories: this.chartData.categories,
-        series: this.chartData.series,
-        animation: true,
-        background: '#FFFFFF',
-        color: ['#0BBC58'],
-        padding: [20, 10, 10, 0],
-        dataLabel: false,
-        dataPointShape: true,
-        enableScroll: false,
+      // 销毁已有的图表实例
+      if (chartInstance) {
+        chartInstance.dispose();
+      }
+      
+      // 初始化图表
+      const chartDom = document.getElementById('tempChart');
+      if (!chartDom) return;
+      
+      chartInstance = echarts.init(chartDom);
+      
+      const option = {
+        backgroundColor: '#FFFFFF',
+        tooltip: {
+          trigger: 'axis'
+        },
         legend: {
           show: false
         },
+        grid: {
+          left: '3%',
+          right: '4%',
+          bottom: '3%',
+          top: '8%',
+          containLabel: true
+        },
         xAxis: {
-          disableGrid: true,
-          boundaryGap: 'center',
-          fontSize: 10,
-          fontColor: '#999999',
-          scrollShow: false
+          type: 'category',
+          boundaryGap: false,
+          data: this.xData,
+          axisLine: {
+            lineStyle: {
+              color: '#CCCCCC'
+            }
+          },
+          axisLabel: {
+            fontSize: 10,
+            color: '#999999'
+          },
+          splitLine: {
+            show: false
+          }
         },
         yAxis: {
-          gridType: 'dash',
+          type: 'value',
           splitNumber: 4,
-          min: 0,
-          max: 12,
-          fontSize: 10,
-          fontColor: '#999999'
+          axisLine: {
+            show: true,
+            lineStyle: {
+              color: '#CCCCCC'
+            }
+          },
+          axisLabel: {
+            fontSize: 10,
+            color: '#999999'
+          },
+          splitLine: {
+            show: true,
+            lineStyle: {
+              color: '#E5E5E5',
+              type: 'dashed'
+            }
+          }
         },
-        extra: {
-          area: {
-            type: 'curve',
-            width: 2,
-            addLine: true,
-            gradient: true,
-            activeType: 'hollow',
-            linearType: 'custom',
-            shadowColor: 'rgba(11, 188, 88, 0.3)',
-            tension: 0.4
+        series: [
+          {
+            name: this.chartTabs[this.activeChartTab].name,
+            type: 'line',
+            smooth: true,
+            data: this.yData,
+            lineStyle: {
+              color: '#0BBC58',
+              width: 2
+            },
+            itemStyle: {
+              color: '#0BBC58',
+              borderColor: '#0BBC58',
+              borderWidth: 2
+            },
+            symbol: 'circle',
+            symbolSize: 6,
+            areaStyle: {
+              color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+                {
+                  offset: 0,
+                  color: 'rgba(11, 188, 88, 0.3)'
+                },
+                {
+                  offset: 1,
+                  color: 'rgba(11, 188, 88, 0)'
+                }
+              ])
+            }
           }
-        }
+        ]
+      };
+      
+      chartInstance.setOption(option);
+      
+      // 监听窗口大小变化,调整图表大小
+      window.addEventListener('resize', () => {
+        chartInstance.resize();
       });
     },
     switchChartTab(index) {
       this.activeChartTab = index;
       // 根据不同标签切换数据
+      if (this.chartTabs[index].id === 'new_tem') {
+        this.yData = this.polylineList.map(item => Number(item.new_tem) || 0);
+      } else if (this.chartTabs[index].id === 'new_hum') {
+        this.yData = this.polylineList.map(item => Number(item.new_hum) || 0);
+      } else if (this.chartTabs[index].id === 'others') {
+        this.yData = this.polylineList.map(item => Number(item.others) || 0);
+      }
       this.$nextTick(() => {
         this.drawChart();
       });
-    },
-    chartTouchStart(e) {
-      if (chartInstance) {
-        chartInstance.scrollStart(e);
-      }
-    },
-    chartTouchMove(e) {
-      if (chartInstance) {
-        chartInstance.scroll(e);
-      }
-    },
-    chartTouchEnd(e) {
-      if (chartInstance) {
-        chartInstance.scrollEnd(e);
-        chartInstance.showToolTip(e);
-      }
     }
   }
 };
@@ -712,7 +781,7 @@ export default {
             }
 
             .body-cell {
-              min-width: 120rpx;
+              min-width: 140rpx;
               font-size: 24rpx;
               font-family: 'Source Han Sans CN VF', sans-serif;
               font-weight: 400;

+ 5 - 1
pages/cbd/components/pestEchart.vue

@@ -228,7 +228,11 @@ export default {
             formatter: (value) => Math.floor(value)
           },
           splitLine: {
-            show: false
+            show: true,
+            lineStyle: {
+              color: '#E5E5E5',
+              type: 'dashed'
+            }
           }
         },
         series: [

+ 10 - 2
pages/cbd/components/photoImage.vue

@@ -11,7 +11,7 @@
         <text class="tab-text">{{ pest.pest_name }}({{ pest.pest_num }})</text>
       </view>
     </view>
-    <view class="photo-image__content">
+    <view class="photo-image__content" v-if="images.length">
       <view class="photo-image__grid">
         <view class="photo-image__item" v-for="(item, index) in images" :key="index" @click="handleClick(item)">
           <view class="photo-image__item-img-container">
@@ -41,6 +41,14 @@ export default {
       type: Array,
       default: () => []
     },
+    id:{
+      type: String,
+      default: ''
+    },
+    currentYear:{
+      type: String,
+      default: ''
+    },
   },
   data() {
     return {
@@ -74,7 +82,7 @@ export default {
     },
     handleClick(item) {
       uni.navigateTo({
-        url: '/pages/cbd/devicePhoto?devicePhoto=' + item
+        url: '/pages/cbd/devicePhoto?device_id=' + item?.device_id + '&img_id=' + item?.ids + '&id=' + this.id + '&currentYear=' + this.currentYear
       })
     }
   },

+ 72 - 28
pages/cbd/detail.vue

@@ -48,15 +48,38 @@
         </view>
       </view>
       <view v-if="activeTab === 'pestAnalysis'" class="tab-content">
-        <PestDiscern :total="total" :pest_order="pest_order"/>
-        <PestEchart :pest_order="pest_order" @getInfo="getInfo" :endDate="endDate" :d_id="deviceInfo.d_id" :day="day" :pest="pest"/>
-        <PestArchive :pest_info="pestInfo"/>
+        <PestDiscern
+          :total="total"
+          :pest_order="pest_order"
+        />
+        <PestEchart
+          :pest_order="pest_order"
+          @getInfo="getInfo" 
+          :endDate="endDate"
+          :d_id="deviceInfo.d_id"
+          :day="day"
+          :pest="pest"
+        />
+        <PestArchive
+          :pest_info="pestInfo"
+        />
       </view>
       <view v-if="activeTab === 'viewImage'">
-        <photoImage :images="imageList" :pestList="pestList" @changeTab="changeTab"/>
+        <photoImage
+          :images="imageList"
+          :pestList="pestList"
+          @changeTab="changeTab"
+          :currentYear="currentYear"
+          :id="deviceInfo.id"
+        />
       </view>
       <view v-if="activeTab === 'deviceData'">
-        <DeviceData :deviceStatic="deviceStatic" :deviceInfo="deviceInfo"/>
+        <DeviceData
+          :deviceStatic="deviceStatic"
+          :deviceInfo="deviceInfo"
+          :polylineList="polylineList"
+          :deviceHistoryList="deviceHistoryList"
+        />
       </view>
     </view>
 		<u-calendar v-model="show" :mode="mode" @change="handleChange" :max-date="maxDate" :min-date="minDate"></u-calendar>
@@ -109,6 +132,8 @@ export default {
       page_size:24,
       pestList:[],
       pest_names:'',
+      polylineList:[],
+      deviceHistoryList:[],
       deviceStatic:{}
     }
   },
@@ -144,14 +169,7 @@ export default {
         this.maxDate = this.formatDate(new Date(this.currentYear, 11, 31));
         this.minDate = this.formatDate(new Date(this.currentYear, 0, 1));
       }
-      if(this.activeTab === 'pestAnalysis'){
-        this.getPestAnalysis();
-      }else if(this.activeTab === 'viewImage'){
-        this.initPest();
-        this.initImageList();
-      }else if(this.activeTab === 'deviceData'){
-        this.getDeviceData();
-      }
+      this.initAction();
       this.showPicker = false;
     },
     getInfo(info){
@@ -167,14 +185,7 @@ export default {
     handleChange(e){
       this.startDate = e.startDate;
       this.endDate = e.endDate;
-      if(this.activeTab === 'pestAnalysis'){
-        this.getPestAnalysis();
-      }else if(this.activeTab === 'viewImage'){
-        this.initPest();
-        this.initImageList();
-      }else if(this.activeTab === 'deviceData'){
-        this.getDeviceData();
-      }
+      this.initAction();
     },
     showCalendar(){
       this.show = true;
@@ -184,18 +195,22 @@ export default {
         delta: 1
       });
     },
-    handleTabClick(tab) {
-      this.activeTab = tab;
-      if(tab === 'pestAnalysis'){
+    initAction(){
+      if(this.activeTab === 'pestAnalysis'){
         this.getPestAnalysis();
-      }else if(tab === 'viewImage'){
+      }else if(this.activeTab === 'viewImage'){
         this.initPest();
         this.initImageList();
-      }else if(tab === 'deviceData'){
+      }else if(this.activeTab === 'deviceData'){
         this.getDeviceData();
+        this.getPolylineData();
+        this.getDeviceHistoryData();
       }
     },
-    //api/api_gateway?method=forecast.worm_lamp.device_status_data
+    handleTabClick(tab) {
+      this.activeTab = tab;
+      this.initAction();
+    },
     async getDeviceData(){
       const res = await this.$myRequest({
         url: '/api/api_gateway?method=forecast.worm_lamp.device_status_data',
@@ -239,7 +254,36 @@ export default {
       });
       const data = res?.data || [];
       this.pestList = data
-      console.log(res,'resresres')
+    },
+    async getPolylineData(){
+      const res = await this.$myRequest({
+        url: '/api/api_gateway?method=forecast.worm_lamp.device_polyline_data',
+        method: 'POST',
+        data: {
+          device_type_id: this.deviceInfo.type_id,
+          d_id: this.deviceInfo.d_id,
+          start_time: new Date(this.startDate).getTime()/1000,// 转成毫秒
+          end_time: new Date(this.endDate).getTime()/1000,// 转成毫秒
+        },
+      });
+      const data = res || [];
+      this.polylineList = data
+    },
+    async getDeviceHistoryData(){
+      const res = await this.$myRequest({
+        url: '/api/api_gateway?method=forecast.worm_lamp.device_history_data',
+        method: 'POST',
+        data: {
+          device_type_id: this.deviceInfo.type_id,
+          device_id: this.deviceInfo.id,
+          start_time: new Date(this.startDate).getTime()/1000,
+          end_time: new Date(this.endDate).getTime()/1000,
+          page: this.page,
+          page_size: this.page_size,
+        },
+      });
+      const data = res?.data || [];
+      this.deviceHistoryList = data
     },
     async getPestAnalysis(){
       const res = await this.$myRequest({

+ 227 - 82
pages/cbd/devicePhoto.vue

@@ -12,24 +12,31 @@
     </view>
 
     <!-- 日期选择器 -->
-    <view class="date-picker">
-      <view class="date-input">
-        <text class="date-label">开始日期</text>
-      </view>
-      <view class="date-separator">-</view>
-      <view class="date-input">
-        <text class="date-label">结束日期</text>
-      </view>
-      <u-icon name="calendar" class="calendar"></u-icon>
+     <view class="date-container">
+        <view class="select-year">
+          <view class="select-year-item" @click="showPicker = true">
+            {{ currentYear }}
+            <u-icon name="arrow-down" size="18" class="arrow-down"></u-icon>
+          </view>
+        </view>
+        <view class="date-picker" @click="show = true">
+          <view class="date-input">
+            <text class="date-label">{{ time_begin || '-' }}</text>
+          </view>
+          <view class="date-separator">-</view>
+          <view class="date-input">
+            <text class="date-label">{{ time_end || '-' }}</text>
+          </view>
+          <u-icon name="calendar" class="calendar"></u-icon>
+        </view>
     </view>
-
     <!-- 主图片区域 -->
     <view class="main-photo">
       <image 
-        src="https://trae-api-cn.mchost.guru/api/ide/v1/text_to_image?prompt=insects%20on%20a%20white%20surface%20with%20markers&image_size=portrait_4_3" 
+        :src="currentImg.addr" 
         class="main-photo-image"
       />
-      <view class="photo-timestamp">2025-12-28 08:00:00</view>
+      <view class="photo-timestamp">{{ formatDate(currentImg.addtime) }}</view>
     </view>
 
     <!-- 缩略图预览 -->
@@ -39,11 +46,11 @@
           class="thumbnail-item" 
           v-for="(item, index) in thumbnails" 
           :key="index"
-          :class="{ active: index === currentThumbnail }"
-          @click="selectThumbnail(index)"
+          :class="{ active: img_id == item.ids }"
+          @click="selectThumbnail(item)"
         >
           <image 
-            :src="item.src" 
+            :src="item.addr" 
             class="thumbnail-image"
           />
         </view>
@@ -55,50 +62,22 @@
       <view class="result-title">当前图片识别结果</view>
       
       <!-- 一类害虫 -->
-      <view class="pest-category">
+      <view class="pest-category" v-for="(pest,index) in pestList" :key="index">
         <view class="category-header">
-          <text class="category-title">一类害虫</text>
+          <text class="category-title">{{ pest[0] }}</text>
           <text class="category-count">数量</text>
         </view>
-        <view class="pest-item" v-for="(pest, index) in category1Pests" :key="index">
+        <view class="pest-item" v-for="(p, i) in pest[1]" :key="i">
           <view class="pest-info">
-            <view class="pest-color" :style="{ backgroundColor: pest.color }"></view>
-            <text class="pest-name">{{ pest.name }}</text>
+            <view class="pest-color" :style="{ backgroundColor: getRandomColor() }"></view>
+            <text class="pest-name">{{ p.pest_name }}</text>
           </view>
-          <text class="pest-count">{{ pest.count }}</text>
-        </view>
-      </view>
-
-      <!-- 二类害虫 -->
-      <view class="pest-category">
-        <view class="category-header">
-          <text class="category-title">二类害虫</text>
-          <text class="category-count">数量</text>
-        </view>
-        <view class="pest-item" v-for="(pest, index) in category2Pests" :key="index">
-          <view class="pest-info">
-            <view class="pest-color" :style="{ backgroundColor: pest.color }"></view>
-            <text class="pest-name">{{ pest.name }}</text>
-          </view>
-          <text class="pest-count">{{ pest.count }}</text>
-        </view>
-      </view>
-
-      <!-- 三类害虫 -->
-      <view class="pest-category">
-        <view class="category-header">
-          <text class="category-title">三类害虫</text>
-          <text class="category-count">数量</text>
-        </view>
-        <view class="pest-item" v-for="(pest, index) in category3Pests" :key="index">
-          <view class="pest-info">
-            <view class="pest-color" :style="{ backgroundColor: pest.color }"></view>
-            <text class="pest-name">{{ pest.name }}</text>
-          </view>
-          <text class="pest-count">{{ pest.count }}</text>
+          <text class="pest-count">{{ p.pest_num }}</text>
         </view>
       </view>
     </view>
+		<u-calendar v-model="show" :mode="mode" @change="handleChange" :max-date="maxDate" :min-date="minDate"></u-calendar>
+		<u-picker v-model="showPicker" mode="selector" :range="selectorRange" range-key="id" :default-selector="[0]" @confirm="confirmHandler"></u-picker>
   </view>
 </template>
 
@@ -106,45 +85,185 @@
 export default {
   data() {
     return {
+      show: false,
+      mode: 'range',
+      maxDate: this.formatTime(new Date()),
+      minDate: this.formatTime(new Date(new Date().getFullYear(), 0, 1)),
+      showPicker: false,
+      selectorRange: [],
       title: '查看图片',
       currentThumbnail: 2,
-      thumbnails: [
-        { src: "https://trae-api-cn.mchost.guru/api/ide/v1/text_to_image?prompt=insects%20on%20white%20surface&image_size=square" },
-        { src: "https://trae-api-cn.mchost.guru/api/ide/v1/text_to_image?prompt=insects%20on%20white%20surface&image_size=square" },
-        { src: "https://trae-api-cn.mchost.guru/api/ide/v1/text_to_image?prompt=insects%20on%20white%20surface&image_size=square" },
-        { src: "https://trae-api-cn.mchost.guru/api/ide/v1/text_to_image?prompt=insects%20on%20white%20surface&image_size=square" },
-        { src: "https://trae-api-cn.mchost.guru/api/ide/v1/text_to_image?prompt=insects%20on%20white%20surface&image_size=square" },
-        { src: "https://trae-api-cn.mchost.guru/api/ide/v1/text_to_image?prompt=insects%20on%20white%20surface&image_size=square" },
-        { src: "https://trae-api-cn.mchost.guru/api/ide/v1/text_to_image?prompt=insects%20on%20white%20surface&image_size=square" },
-        { src: "https://trae-api-cn.mchost.guru/api/ide/v1/text_to_image?prompt=insects%20on%20white%20surface&image_size=square" },
-        { src: "https://trae-api-cn.mchost.guru/api/ide/v1/text_to_image?prompt=insects%20on%20white%20surface&image_size=square" },
-        { src: "https://trae-api-cn.mchost.guru/api/ide/v1/text_to_image?prompt=insects%20on%20white%20surface&image_size=square" },
-        { src: "https://trae-api-cn.mchost.guru/api/ide/v1/text_to_image?prompt=insects%20on%20white%20surface&image_size=square" },
-        { src: "https://trae-api-cn.mchost.guru/api/ide/v1/text_to_image?prompt=insects%20on%20white%20surface&image_size=square" }
+      pestYype:{},
+      device_id: '',
+      time_begin: this.formatTime(new Date(new Date().getFullYear(), 0, 1)),
+      time_end: this.formatTime(new Date()),
+      img_id: '',
+      pest_list:[],
+      pestList:[],
+      colors:[
+        '#FF5951',
+        '#66EDED',
+        '#E67B3E',
+        '#6DE28B',
+        '#FFC97A',
+        '#E7EB4B',
+        '#1561F3',
+        '#FA73F5',
+        '#159AFF',
+        '#FA73F5'
       ],
-      category1Pests: [
-        { name: '蚜虫', color: '#FF9933', count: 3 },
-        { name: '松墨天牛', color: '#FF3333', count: 3 },
-        { name: '夜蛾', color: '#3366FF', count: 3 }
-      ],
-      category2Pests: [
-        { name: '蚜虫', color: '#FF9933', count: 3 },
-        { name: '松墨天牛', color: '#FF3333', count: 3 },
-        { name: '夜蛾', color: '#3366FF', count: 3 }
-      ],
-      category3Pests: [
-        { name: '蚜虫', color: '#FF9933', count: 3 },
-        { name: '松墨天牛', color: '#FF3333', count: 3 },
-        { name: '夜蛾', color: '#3366FF', count: 3 }
-      ]
+      currentYear:'',
+      pest_list_arr:[],
+      thumbnails: [],
+      currentImg:{},
     };
   },
+  onLoad(options) {
+    const {id,img_id,currentYear} = options
+    this.device_id = id
+    this.img_id = img_id
+    this.currentYear = currentYear
+    this.time_begin = this.currentYear + '-01-01'
+    this.time_end = this.currentYear + '-12-31'
+    this.maxDate = this.formatTime(new Date())
+    this.minDate = this.formatTime(new Date(new Date().getFullYear(), 0, 1))
+    this.selectorRange = [];
+    const nowYear = new Date().getFullYear();
+    for(let i = 0;i<50;i++){
+      const item = {
+        label: nowYear - i,
+        id: nowYear - i
+      }
+      this.selectorRange.push(item);
+    }
+    this.getPestLevelMap();
+    this.getPestList();
+    this.getDevicePhotoDetails();
+  },
   methods: {
+    confirmHandler(e){
+      this.currentYear = this.selectorRange[e].id;
+      if(this.currentYear == new Date().getFullYear()){
+        this.time_begin = this.formatTime(new Date(new Date().getFullYear(), 0, 1));
+        this.time_end = this.formatTime(new Date());
+        this.maxDate = this.formatTime(new Date());
+        this.minDate = this.formatTime(new Date(new Date().getFullYear(), 0, 1));
+      }else{
+        this.time_begin = this.formatTime(new Date(this.currentYear, 0, 1));
+        this.time_end = this.formatTime(new Date(this.currentYear, 11, 31));
+        this.maxDate = this.formatTime(new Date(this.currentYear, 11, 31));
+        this.minDate = this.formatTime(new Date(this.currentYear, 0, 1));
+      }
+      this.showPicker = false;
+    },
+    handleChange(e){
+      console.log(e,'e')
+      this.time_begin = e.startDate;
+      this.time_begin = e.endDate;
+      this.getPestList()
+    },
+    getRandomColor(){
+      return this.colors[Math.floor(Math.random() * this.colors.length)]
+    },
+     getLevelDisplayName(level) {
+      const levelMap = {
+        '-1': '其他害虫',
+        1: '一类害虫',
+        2: '二类害虫',
+        3: '三类害虫',
+        4: '四类害虫',
+        5: '五类害虫'
+      };
+      return levelMap[String(level)] || `${level}`;
+    },
+    async getPestList() {
+      const res = await this.$myRequest({
+        url: '/api/api_gateway?method=forecast.new_cbd.photo_list',
+        method: 'POST',
+        data: {
+          identify_model:'B',
+          cmd:'cbd',
+          time_begin: this.time_begin + ' 00:00:00',
+          time_end: this.time_end + ' 23:59:59',
+          identify_model:'B',
+          device_id: this.device_id,
+        },
+      });
+      this.thumbnails = res?.data || [];
+      console.log(this.thumbnails,'resres2222res')
+    },
+    formatTime(dateString) {
+      const date = new Date(dateString);
+      const year = date.getFullYear();
+      const month = String(date.getMonth() + 1).padStart(2, '0');
+      const day = String(date.getDate()).padStart(2, '0');
+      return `${year}-${month}-${day}`;
+    },
+    async getPestLevelMap() {
+      const res = await this.$myRequest({
+        url: '/api/api_gateway?method=forecast.new_cbd.pest_level_map',
+        method: 'POST',
+      });
+      const pestYype = {}
+      for(let key in res){
+        pestYype[this.getLevelDisplayName(key)] = res[key]
+      }
+      this.pestYype = pestYype
+    },
+    formatDate(dateString) {
+      const date = new Date(dateString*1000);
+      const year = date.getFullYear();
+      const month = String(date.getMonth() + 1).padStart(2, '0');
+      const day = String(date.getDate()).padStart(2, '0');
+      const hour = String(date.getHours()).padStart(2, '0');
+      const minute = String(date.getMinutes()).padStart(2, '0');
+      const second = String(date.getSeconds()).padStart(2, '0');
+      return `${year}-${month}-${day} ${hour}:${minute}:${second}`;
+    },
+    async getDevicePhotoDetails() {
+      const res = await this.$myRequest({
+        url: '/api/api_gateway?method=forecast.forecast_system.device_photo_details',
+        method: 'POST',
+        data: {
+          identify_model:'B',
+          cmd:'cbd',
+          img_id: this.img_id,
+        },
+      });
+      this.currentImg = res;
+      const pest_list = res.pest_list
+      const pestArr = new Map()
+      for(let key in this.pestYype){
+        for(let j in this.pestYype[key]){
+          const pestName = this.pestYype[key][j]
+          pest_list.forEach(item => {
+            if(item.pest_name == pestName){
+              if(pestArr.has(item.level)){
+                pestArr.get(key).push(item)
+              }else{
+                pestArr.set(key, [item])
+              }
+            }
+          })
+        }
+      }
+      const pestList = []
+      for(let key of pestArr){
+        pestList.push(key)
+      }
+      this.pestList = pestList
+    },
+    handleBack() {
+      uni.navigateBack({
+        delta: 1
+      });
+    },
     goBack() {
       uni.navigateBack();
     },
-    selectThumbnail(index) {
-      this.currentThumbnail = index;
+    selectThumbnail(item) {
+      this.img_id = item.ids;
+      this.getDevicePhotoDetails();
     }
   }
 };
@@ -209,7 +328,33 @@ export default {
       }
     }
   }
-
+  .date-container{
+    padding: 0 20rpx;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    .select-year{
+      width: 150rpx;
+      height: 80rpx;
+      display: flex;
+      align-items: center;
+      justify-content: space-around;
+      color: #656565;
+      font-size: 26rpx;
+      line-height: 80rpx;
+      text-align: center;
+      border-radius: 48rpx;
+      background-color: #FFFFFF;
+      margin-right: 10rpx;
+      padding: 0 26rpx;
+      .select-year-item{
+        width: 100%;
+        display: flex;
+        align-items: center;
+        justify-content: space-around;
+      }
+    }
+  }
   /* 日期选择器 */
   .date-picker {
     display: flex;