Quellcode durchsuchen

feat: 生成成果报告,高度自适应

lxf vor 4 Tagen
Ursprung
Commit
ba0bc168fb

BIN
src/assets/img/home/book.png


BIN
src/assets/img/home/report_bg.png


BIN
src/assets/img/home/title-bg.png


+ 8 - 2
src/components/album_compoents/albumCarouselItem.vue

@@ -3,7 +3,7 @@
         <!-- 图片列表 -->
         <div class="carousel-wrapper" :style="carouselStyle">
             <photo-provider v-if="images" :photo-closable="true" @visibleChange="handleVisibleChange">
-                <photo-consumer
+                <!-- <photo-consumer
                     class="carousel-img"
                     v-for="(photo, index) in images"
                     :key="photo.id"
@@ -14,7 +14,12 @@
                         :src="base_img_url2 + (photo.cloudFilename ? photo.cloudFilename : photo)"
                         alt=""
                     />
-                </photo-consumer>
+                </photo-consumer> -->
+                <template  v-for="(photo, index) in images"
+                   :key="photo.id">
+                    <album-draw-box :isShowNum="0" :farmId="766" :photo="photo" :current="currentIndex" :index="index" :length="images.length"
+                    ></album-draw-box>
+                    </template>
             </photo-provider>
         </div>
         <div class="label-text">{{ labelText }}</div>
@@ -31,6 +36,7 @@
 
 <script setup>
 import { toRefs, ref, computed, onMounted, onUnmounted } from "vue";
+import AlbumDrawBox from "./albumDrawBox.vue";
 import { base_img_url2 } from "@/api/config";
 import "./cacheImg.js";
 const props = defineProps({

+ 41 - 28
src/components/album_compoents/albumDrawBox.vue

@@ -3,13 +3,18 @@
       class="carousel-item"
       :src="watermark || base_img_url2 + (photo.resFilename ? photo.resFilename : photo.filename) + resize"
   >
-    <img v-if="Math.abs(current - index) < 3" crossorigin="anonymous" @load="drawWatermark($event)" loading="lazy" :src="watermark || (base_img_url2 + (photo.resFilename ? photo.resFilename : photo.filename) + resize)"
-         style="width: 100%;height:25vh;object-fit: cover;" />
-    <canvas  ref="canvasRef" style="position: absolute;"></canvas>
-    <div class="tag-text" v-if="photo.growText && showTagBox" >
-      <span v-html="photo.growText"></span>
-      <button class="close-button" @click="hideTagBox">✖</button>
-    </div>
+    <img
+      v-if="Math.abs(current - index) < 3"
+      crossorigin="anonymous"
+      @load="drawWatermark($event)"
+      loading="lazy"
+      :src="watermark || (base_img_url2 + (photo.resFilename ? photo.resFilename : photo.filename) + resize)"
+      style="width: 100%; height: auto; display: block;"
+    />
+    <canvas
+      ref="canvasRef"
+      style="position: absolute; left: 0; top: 0; width: 100%; height: 100%; pointer-events: none;"
+    ></canvas>
     <div class="tag-box right" v-if="isShowNum" :class="{'leftTop': 'leftTop'}">{{ index+1 }}/{{ length }}</div>
 <!--    <div class="center-mark">mark</div>-->
   </photo-consumer>
@@ -75,20 +80,28 @@ let data = {year:props.photo.uploadDate.substring(0,4),
 
 async function drawWatermark(event) {
   img = event.target
-  await loadImage(props.photo.baseMap,"base_map_"+props.photo.treeId)
-  data.baseMap = imageCache.get("base_map_"+props.photo.treeId)
-  if(!watermark.value){
-    let param = {farmId:props.farmId, date: props.photo.uploadDate}
-    let weather = null
-    VE_API.weather7d.findSuitabilityByPoint(param).then((res)=>{
-      if(res.code === 0){
-        weather = res.data
-        drawWatermark2(img,weather)
-      }else{
-        drawWatermark2(img,null)
-      }
-    })
-  }
+  const weather = {
+  "tempMax": 17,
+  "tempMin": 10,
+  "tempSuitability": "适宜",
+  "humiditySuitability": "适宜",
+  "vindexSuitability": "寡照"
+}
+  drawWatermark2(img,null)
+  // await loadImage(props.photo.baseMap,"base_map_"+props.photo.treeId)
+  // data.baseMap = imageCache.get("base_map_"+props.photo.treeId)
+  // if(!watermark.value){
+  //   let param = {farmId:props.farmId, date: props.photo.uploadDate}
+  //   let weather = null
+  //   VE_API.weather7d.findSuitabilityByPoint(param).then((res)=>{
+  //     if(res.code === 0){
+  //       weather = res.data
+  //       drawWatermark2(img,weather)
+  //     }else{
+  //       drawWatermark2(img,null)
+  //     }
+  //   })
+  // }
 }
 
 function drawWatermark2(img,weather) {
@@ -127,13 +140,13 @@ const drawBottom = (imgWidth, imgHeight, weather) => {
   ctx.fillStyle = "white"; // 文本颜色为白色
   // 绘制温度
   let startXPercent = 1;
-  drawImageInRect(ctx, bottomRect, data.tempImg, startXPercent, 5+10, 5, 30)
+  // drawImageInRect(ctx, bottomRect, data.tempImg, startXPercent, 5+10, 5, 30)
   drawTextInRect(ctx, bottomRect,`${data.temp}`,startXPercent + 4, 28+10, 20)
   // 绘制湿度
-  drawImageInRect(ctx, bottomRect, data.shiduImg, startXPercent+26, 7 + 10, 4, 30)
+  // drawImageInRect(ctx, bottomRect, data.shiduImg, startXPercent+26, 7 + 10, 4, 30)
   drawTextInRect(ctx, bottomRect,`${data.shidu}`,startXPercent + 31, 28 + 10, 20)
   // 绘制辐射
-  drawImageInRect(ctx, bottomRect, data.fusheImg, startXPercent+26 + 18, 7 + 10, 5, 30)
+  // drawImageInRect(ctx, bottomRect, data.fusheImg, startXPercent+26 + 18, 7 + 10, 5, 30)
   drawTextInRect(ctx, bottomRect,`${data.fushe}`,startXPercent+31 + 18, 28 + 10, 20)
   //绘制日期信息
   ctx.fillStyle = "#FFFFFF";
@@ -142,10 +155,10 @@ const drawBottom = (imgWidth, imgHeight, weather) => {
   ctx.fillStyle = "#FFFFFF90";
   drawTextInRect(ctx, bottomRect,`${data.treeCode}_S3_SCS3-3_D0P0G1`,startXPercent +13, 75, 18)
 
-  if(data.baseMap){
-    drawBorderImageInRect(ctx, imgRect, data.baseMap, 2/3*100, 2/3*100,
-        1/3*100, 1/3*100, 5, 5)
-  }
+  // if(data.baseMap){
+  //   drawBorderImageInRect(ctx, imgRect, data.baseMap, 2/3*100, 2/3*100,
+  //       1/3*100, 1/3*100, 5, 5)
+  // }
 }
 
 

+ 1 - 0
src/components/album_compoents/cacheImg.js

@@ -2,6 +2,7 @@
 const imageCache = new Map();
 
 function loadImage(url, key) {
+    console.log('loadImage',url,key)
     if (!url) {
         return Promise.reject('图片地址不能为空');
     }

+ 6 - 0
src/router/globalRoutes.js

@@ -366,4 +366,10 @@ export default [
         name: "RemindCustomer",
         component: () => import("@/views/old_mini/task_condition/components/remindCustomer.vue"),
     },
+    // 成果报告
+    {
+        path: "/achievement_report",
+        name: "AchievementReport",
+        component: () => import("@/views/old_mini/achievement_report/index.vue"),
+    },
 ];

+ 240 - 0
src/views/old_mini/achievement_report/index.vue

@@ -0,0 +1,240 @@
+<template>
+    <div class="achievement-report-page">
+        <custom-header name="生成成果报告"></custom-header>
+        <div class="report-content">
+            <div class="report-header">
+                <img class="header-book" src="@/assets/img/home/book.png" alt="">
+                <div class="time-tag">2025.12.15</div>
+                <div class="report-title">成果报告</div>
+                <div class="report-info">
+                    <div class="info-item">
+                        <img class="info-icon" src="@/assets/img/home/nz.png" alt="">
+                        <span class="info-text">执行组织:大荔农资组织</span>
+                    </div>
+                    <div class="info-item">
+                        <img class="info-icon" src="@/assets/img/home/nz.png" alt="">
+                        <span class="info-text">服务农场:荔博园</span>
+                    </div>
+                </div>
+            </div>
+
+            <div class="report-box">
+                <div class="report-box-item" v-for="(item, index) in reportBoxList" :key="index">
+                    <div class="item-content">{{ item.content }}</div>
+                    <div class="item-title">{{ item.title }}</div>
+                </div>
+            </div>
+
+            <div class="report-box">
+                <div class="box-title">精准施治,智慧护航</div>
+                <div class="box-text">
+                    我们凭借时机精准的判断与定制化方案的核心能力,结合***高效产品与专业设备,病虫害防治率95% ,落果减少30%
+                </div>
+            </div>
+
+            <div class="report-excute" v-for="(item, index) in executeViewImage" :key="index">
+                <album-carousel
+                    :key="index"
+                    labelText="执行照片"
+                    :images="[item]"
+                ></album-carousel>
+            </div>
+            <div class="report-excute">
+                <!-- <album-carousel
+                    :key="2"
+                    labelText="执行照片"
+                    :images="executeViewImage2"
+                ></album-carousel> -->
+            </div>
+        </div>
+    </div>
+</template>
+
+<script setup>
+import CustomHeader from "@/components/customHeader.vue";
+import AlbumCarousel from "@/components/album_compoents/albumCarousel";
+import { ref } from "vue";
+
+const reportBoxList = ref([
+    {
+        title: "作业农事",
+        content: "梢期杀虫",
+    },
+    {
+        title: "作业面积",
+        content: "200亩",
+    },
+    {
+        title: "作业周期",
+        content: "2天",
+    },
+    {
+        title: "使用设备",
+        content: "无人机NI-7",
+    },
+]);
+
+const executeViewImage = ref([
+    {
+  "address": "",
+  "angle": "",
+  "baseMap": "https://birdseye-img.sysuimars.com/birdseye-look-mini/base_map/v2/111594.jpg",
+  "blueZoneId": null,
+  "district": "东莞市",
+//   "filename": "birdseye-look-mini/91429/1763371316207.jpg",
+  "filename": "birdseye-look-mini/91429/1763461501781.png",
+//   "filename": "3f27e127-6497-4175-8efb-ba18d703852b/b1f6d99e-826d-4468-a6dd-83f9e7a12ea3/DJI_202512131000_001_b1f6d99e-826d-4468-a6dd-83f9e7a12ea3/DJI_20251213100724_0070_V_code-ws0fsmghvf91.jpeg",
+  "fosterCode": "LCGW-DGJH-GLY0253",
+  "gardenId": null,
+  "gardenName": "莞荔园",
+  "growText": "当前进入冬梢。\n\n\n\n    暂无病虫害\n\n    暂无生长异常\n",
+  "id": "787625848910909520",
+  "localPath": "",
+  "localResPath": "",
+  "location": "POINT (113.746646 22.970229)",
+  "miniUserId": null,
+  "miniUserName": "",
+  "modelId": null,
+  "phenologyId": "18",
+  "pingzhong": "",
+  "planId": null,
+  "regionId": null,
+  "regionName": "2区",
+  "resFilename": "",
+  "shotCode": "",
+  "source": "dji",
+  "sourceCode": null,
+  "status": null,
+  "sysId": null,
+  "treeCode": "莞荔园_M2_064",
+  "treeGeoHash": "ws0fsmgq9uhp",
+  "treeId": 111594,
+  "uploadDate": "2025-12-13",
+  "watermarkMsg": "",
+  "watermarkUrl": "",
+  "watermarks": [],
+  "weather": null,
+  "workspaceId": ""
+}
+]);
+
+const executeViewImage2 = ref(["birdseye-look-mini/91754/1763373487891.png"]);
+</script>
+
+<style lang="scss" scoped>
+.achievement-report-page {
+    width: 100%;
+    height: 100vh;
+    background: linear-gradient(195.35deg, #d4e4ff 16.34%, rgba(93, 189, 255, 0) 50.3%),
+        linear-gradient(156.64deg, rgba(255, 255, 255, 0.16) 27.7%, rgba(255, 255, 255, 0) 72.82%);
+
+    .report-content {
+        background: url("@/assets/img/home/report_bg.png") no-repeat center center;
+        background-size: 100% auto;
+        background-position: top center;
+        height: calc(100% - 40px);
+        overflow: auto;
+        padding: 24px 16px 16px;
+        box-sizing: border-box;
+        .report-header {
+            position: relative;
+            .header-book {
+                position: absolute;
+                right: 0;
+                top: 0;
+                width: 160px;
+                height: 160px;
+            }
+            .time-tag {
+                background: linear-gradient(137.86deg, #9FD5FF 5.87%, #2199F8 82.98%);
+                border-radius: 5px 0 5px 0;
+                height: 23px;
+                line-height: 23px;
+                font-size: 13px;
+                font-weight: 500;
+                color: #fff;
+                padding: 0 9px;
+                width: fit-content;
+            }
+            .report-title {
+                font-family: "PangMenZhengDao";
+                font-size: 34px;
+                line-height: 38px;
+                color: #000000;
+            }
+            .report-info {
+                padding: 10px 0 16px 0;
+                .info-item {
+                    width: fit-content;
+                    display: flex;
+                    height: 33px;
+                    align-items: center;
+                    padding: 0 6px 0 3px;
+                    background: linear-gradient(90deg, rgba(255, 255, 255, 0.58) 0%, rgba(255, 255, 255, 0.0696) 100%);
+                    border-radius: 20px;
+                    border: 0.5px solid rgba(33, 153, 248, 0.35);
+                    gap: 3px;
+                    .info-icon {
+                        width: 26px;
+                        height: 26px;
+                        object-fit: cover;
+                        border-radius: 50%;
+                    }
+                    .info-text {
+                        font-size: 14px;
+                        color: #2199F8;
+                    }
+                }
+                .info-item + .info-item {
+                    margin-top: 5px;
+                }
+            }
+        }
+
+        .report-box {
+            display: flex;
+            align-items: center;
+            padding: 8px;
+            background: linear-gradient(0deg, #FFFFFF 86.32%, #2199F8 136.87%);
+            border: 1px solid #FFFFFF;
+            border-radius: 8px;
+            gap: 5px;
+            position: relative;
+            .report-box-item {
+                flex: 1;
+                padding: 10px 2px;
+                background: rgba(33, 153, 248, 0.1);
+                border-radius: 8px;
+                .item-content {
+                    color: #2199F8;
+                    font-size: 14px;
+                    text-align: center;
+                }
+                .item-title {
+                    color: #000000;
+                    font-size: 10px;
+                    text-align: center;
+                    padding-top: 5px;
+                }
+            }
+
+            .box-title {
+                position: absolute;
+                top: -8px;
+                left: 0;
+                height: 32px;
+                line-height: 26px;
+                padding: 0 10px;
+                color: #FFFFFF;
+                background: url("@/assets/img/home/title-bg.png") no-repeat center center /100% 100%;
+            }
+            .box-text {
+                padding: 22px 0 12px 0;
+            }
+        }
+        .report-box + .report-box {
+            margin-top: 20px;
+        }
+    }
+}
+</style>