فهرست منبع

feat:长势报告添加文字

wangsisi 3 هفته پیش
والد
کامیت
491b9c17fe

+ 5 - 0
src/api/modules/monitor.js

@@ -90,4 +90,9 @@ module.exports = {
         url: config.base_new_url + "find_farm_record",
         type: "get",
     },
+    //获取农事详情
+    getWorkDetail: {
+        url: config.base_new_url + "find_farm_work",
+        type: "get",
+    },
 };

+ 28 - 34
src/components/pageComponents/ArchivesFarmTimeLine.vue

@@ -30,7 +30,9 @@
                                             <div class="left-date">{{ formatDate(fw.createTime) }}</div>
                                             <div class="text">
                                                 <span class="van-ellipsis">{{ fw.title }}</span>
-                                                <el-icon><ArrowRight /></el-icon>
+                                                <el-icon>
+                                                    <ArrowRight />
+                                                </el-icon>
                                             </div>
                                         </div>
                                         <div class="farm-info" v-if="fw.work_status === 0">
@@ -42,7 +44,9 @@
                                         </div>
                                         <div class="title-text van-ellipsis">{{ fw.title }}</div>
                                     </div>
-                                    <div class="status-right" :style="statusColorObj[fw.work_status]" v-if="fw.work_status !== 3 && fw.work_status !== 5">{{ workStatusObj[fw.work_status] }}</div>
+                                    <div class="status-right" :style="statusColorObj[fw.work_status]"
+                                        v-if="fw.work_status !== 3 && fw.work_status !== 5">{{
+                                        workStatusObj[fw.work_status] }}</div>
                                 </div>
                             </div>
                         </div>
@@ -76,16 +80,6 @@ const props = defineProps({
         type: [String, Number],
         default: null,
     },
-    // 区域ID
-    regionId: {
-        type: [Number, String],
-        default: null,
-    },
-    // 类型ID
-    typeId: {
-        type: [Number, String],
-        default: null,
-    },
 });
 
 const emits = defineEmits(["row-click", "card-click"]);
@@ -93,7 +87,7 @@ const emits = defineEmits(["row-click", "card-click"]);
 const phenologyList = ref([]);
 const timelineContainerRef = ref(null);
 const getTimelineScrollKey = () =>
-    `timelineScrollTop:${props.farmId ?? "none"}:${props.regionId ?? "none"}:${route.path}`;
+    `timelineScrollTop:${props.farmId ?? "none"}:${route.path}`;
 
 const saveTimelineScrollTop = () => {
     if (!timelineContainerRef.value) return;
@@ -131,8 +125,7 @@ const isRequesting = ref(false);
 // 记录上一次请求作用域,避免相同参数重复请求
 const lastRequestedFarmId = ref(null);
 
-const farmWorkPlanScopeKey = () =>
-    JSON.stringify([props.farmId ?? null, props.regionId ?? null]);
+const farmWorkPlanScopeKey = () => JSON.stringify([props.farmId ?? null]);
 
 const resetTimelineData = () => {
     phenologyList.value = [];
@@ -272,11 +265,11 @@ const normalizeFarmWorksPhenologyList = (data) => {
         const startDate =
             !Number.isNaN(minMs) && minMs > 0
                 ? (() => {
-                      const d = new Date(minMs);
-                      const m = `${d.getMonth() + 1}`.padStart(2, "0");
-                      const day = `${d.getDate()}`.padStart(2, "0");
-                      return `${d.getFullYear()}-${m}-${day}`;
-                  })()
+                    const d = new Date(minMs);
+                    const m = `${d.getMonth() + 1}`.padStart(2, "0");
+                    const day = `${d.getDate()}`.padStart(2, "0");
+                    return `${d.getFullYear()}-${m}-${day}`;
+                })()
                 : null;
         return {
             id: stage.id ?? works[0]?.phenology_code ?? `phenology-${idx}`,
@@ -321,11 +314,8 @@ const getFarmWorkPlan = () => {
 
     const params = {
         farm_id: 195,
-        crop_variety:1
+        crop_variety: 1,
     };
-    if (props.typeId != null && props.typeId !== "") {
-        params.crop_variety = props.typeId;
-    }
     VE_API.monitor.getPhenologyList(params)
         .then(({ data, code }) => {
             const ok = code === 200 || code === 0;
@@ -353,12 +343,10 @@ const updateFarmWorkPlan = () => {
 };
 
 watch(
-    () => [props.farmId, props.regionId],
+    () => props.farmId,
     (val, oldVal) => {
         if (!props.farmId) return;
-        const changed =
-            !oldVal ||
-            val.some((item, index) => item !== oldVal[index]);
+        const changed = oldVal == null || val !== oldVal;
         if (changed) {
             lastRequestedFarmId.value = null;
         }
@@ -383,7 +371,6 @@ const handleStatusDetail = (fw) => {
                         farmWorkLibId: '832268348690534411',
                         recordId: "832268363366404096",
                         reproductiveId: 149,
-                        typeId: props.typeId
                     }),
                 }),
             },
@@ -444,8 +431,9 @@ onBeforeRouteLeave(() => {
 </script>
 
 <style scoped lang="scss">
-@mixin arrange-card-status($color, $content-color: null,$border-color: null, $content-bg: null, $text-color: null) {
+@mixin arrange-card-status($color, $content-color: null, $border-color: null, $content-bg: null, $text-color: null) {
     border-color: $color;
+
     @if $content-bg !=null {
         background: $content-bg;
     }
@@ -516,7 +504,7 @@ onBeforeRouteLeave(() => {
             z-index: 10;
             text-align: center;
             display: flex;
-            align-items: center;
+            align-items: baseline;
             justify-content: center;
             writing-mode: vertical-rl;
             text-orientation: upright;
@@ -556,6 +544,10 @@ onBeforeRouteLeave(() => {
                 box-sizing: border-box;
                 writing-mode: vertical-rl;
                 text-orientation: upright;
+                top: 0;
+                bottom: 0;
+                left: 0;
+                position: absolute;
 
 
                 &.phenology-red {
@@ -589,6 +581,7 @@ onBeforeRouteLeave(() => {
                     padding: 8px 15px 8px 10px;
                     writing-mode: horizontal-tb;
                     margin-bottom: 10px;
+
                     .card-content {
                         color: #242424;
                         display: flex;
@@ -635,6 +628,7 @@ onBeforeRouteLeave(() => {
                                 box-sizing: border-box;
                                 border: 0.5px solid rgba(0, 0, 0, 0.4);
                             }
+
                             .farm-info {
                                 font-size: 12px;
                                 color: #626262;
@@ -646,7 +640,7 @@ onBeforeRouteLeave(() => {
                                 justify-content: space-between;
                                 text-align: left;
                                 margin-top: 6px;
-                                
+
                                 .info-right {
                                     background: #FF953D;
                                     border-radius: 2px;
@@ -683,11 +677,11 @@ onBeforeRouteLeave(() => {
                 }
 
                 .arrange-card.status-normal {
-                    @include arrange-card-status(#2199F8, null, #2199F8, null,#000);
+                    @include arrange-card-status(#2199F8, null, #2199F8, null, #000);
                 }
 
                 .arrange-card.status-green-info {
-                    @include arrange-card-status(#4ABF32, #ECFFE8, rgba(74, 191, 50, 0.5),rgba(28, 169, 0, 0.1),rgba(0, 0, 0, 0.4));
+                    @include arrange-card-status(#4ABF32, #ECFFE8, rgba(74, 191, 50, 0.5), rgba(28, 169, 0, 0.1), rgba(0, 0, 0, 0.4));
                 }
 
                 .arrange-card.status-orange {

+ 0 - 1
src/router/globalRoutes.js

@@ -177,7 +177,6 @@ export default [
     {
         path: "/record_details",
         name: "RecordDetails",
-        meta: { keepAlive: true },
         component: () => import("@/views/old_mini/recordDetails/index.vue"),
     },
     // 地图管理

+ 1 - 1
src/views/old_mini/agri_file/fileMap.js

@@ -37,7 +37,7 @@ class FileMap {
             maxZoom: 22,
             source: new VectorSource({}),
             style: function () {
-                return [vectorStyle.getPolygonStyle("#00000040", "#2199F8", 2)];
+                return [vectorStyle.getPolygonStyle("rgba(24, 170, 139, 0.25)", "#18AA8B", 2)];
             },
         });
 

+ 57 - 1
src/views/old_mini/agri_file/index.vue

@@ -22,6 +22,12 @@
         </div>
 
         <div class="file-content" v-show="activeGardenTab === 'current'">
+            <div class="map-legend">
+                <div v-for="item in mapLegendItems" :key="item.label" class="map-legend__item">
+                    <span class="map-legend__dot" :class="item.dotClass"></span>
+                    <span class="map-legend__text">{{ item.label }}</span>
+                </div>
+            </div>
             <div class="map-container" ref="mapContainer"></div>
             <file-float @map-farm-record="onFarmRecordMap"></file-float>
         </div>
@@ -49,6 +55,12 @@ const gardenListRef = ref(null);
 const activeGardenTab = ref("current");
 const activeType = ref("荔枝");
 
+const mapLegendItems = [
+    { label: "管理分区", dotClass: "map-legend__dot--zone" },
+    { label: "长势异常", dotClass: "map-legend__dot--growth" },
+    { label: "病虫害异常", dotClass: "map-legend__dot--pest" },
+];
+
 const fileMap = new FileMap();
 
 const onFarmRecordMap = ({ polygonWkt, records }) => {
@@ -125,10 +137,54 @@ onActivated(() => {
     }
 
     .file-content {
-        // padding-top: 104px;
+        position: relative;
         height: 100%;
         box-sizing: border-box;
 
+        .map-legend {
+            position: absolute;
+            left: 50%;
+            transform: translateX(-50%);
+            z-index: 15;
+            top: 110px;
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            gap: 10px;
+            padding: 3px 10px;
+            background: rgba(255, 255, 255, 0.69);
+            border-radius: 25px;
+        }
+
+        .map-legend__item {
+            display: flex;
+            align-items: center;
+            gap: 5px;
+        }
+
+        .map-legend__dot {
+            width: 12px;
+            height: 12px;
+            border-radius: 50%;
+        }
+
+        .map-legend__dot--zone {
+            background: #1C9E80;
+        }
+
+        .map-legend__dot--growth {
+            background: #FF953D;
+        }
+
+        .map-legend__dot--pest {
+            background: #E03131;
+        }
+
+        .map-legend__text {
+            font-size: 12px;
+            white-space: nowrap;
+        }
+
         .map-container {
             width: 100%;
             height: 100%;

+ 2 - 3
src/views/old_mini/agri_record/index.vue

@@ -36,7 +36,7 @@
                 </div>
             </div>
             <div class="archives-time-line-content">
-                <archives-farm-time-line :farmId="98570" :regionId="235997"></archives-farm-time-line>
+                <archives-farm-time-line :farmId="gardenId"></archives-farm-time-line>
             </div>
         </div>
     </div>
@@ -129,9 +129,8 @@ const changeGarden = ({ id }) => {
 const handleTrendMonitorCardClick = (item) => {
     router.push({
         path: "/record_details",
-        query: { recordId: item.id },
+        query: { workId: item.work_id },
     });
-    console.log(item);
 }
 </script>
 

+ 70 - 12
src/views/old_mini/growth_report/index.vue

@@ -60,8 +60,8 @@
                     </div>
                     </div>
 
-                    <div class="time-tag">{{ workItems?.[0]?.reportDate }}</div>
-                    <div class="report-title">{{ subjectData[activeSubjectIndex]?.speciesName }}长势报告</div>
+                    <div class="time-tag">{{ workItems?.[0]?.reportDate || new Date().toISOString().split('T')[0] }}</div>
+                    <div class="report-title">水稻长势报告</div>
                     <div class="report-info">
                         <div class="info-item">
                             <img class="info-icon" src="@/assets/img/home/farm.png" alt="" />
@@ -116,7 +116,7 @@
                     <div class="box-text">
                         <div class="box-bg">
                             <div class="types-info">
-                                当前 <span class="text-bold">桂味、妃子笑</span> 处于为  新梢萌动<span class="text-link" @click="handleAdjustPopup">(校准物候期)</span>
+                                当前 <span class="text-bold">水稻</span> 处于为  分蘖初期<span class="text-link" @click="handleAdjustPopup">(校准物候期)</span>
                             </div>
                         </div>
                         <div class="warning-part">
@@ -132,9 +132,9 @@
                                 </div>
                             </div>
 
-                            <div class="report-part" v-for="(part, partI) in 3" :key="partI">
-                                <div class="part-title">病虫风险</div>
-                                <div class="part-text">根据问题写一下需要注意的事项有哪些;简单描述农事该怎</div>
+                            <div class="report-part" v-for="(part, partI) in riskList" :key="partI">
+                                <div class="part-title">{{ part.title }}</div>
+                                <div class="part-text">{{ part.description }}</div>
                             </div>
                         </div>
                     </div>
@@ -143,16 +143,33 @@
                 <div class="report-box">
                     <div class="box-title">农事建议</div>
                     <div class="box-text">
-                        <div class="warning-part" v-for="(part, partI) in 3" :key="partI">
+                        <div class="warning-part" v-for="(part, partI) in adviceList" :key="partI">
                             <div class="report-part">
                                 <div class="part-top">
-                                    <div class="part-title">某某农事</div>
+                                    <div class="part-title">{{ part.title }}</div>
                                     <div class="part-link">
                                         <el-icon class="part-link-icon"><Link /></el-icon>
                                         <div class="text-link">查看农事</div>
                                     </div>
                                 </div>
-                                <div class="part-text">描述描述描述描述描述描述描述描述</div>
+                                <div class="part-text">{{ part.description }}</div>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+                <div class="report-box">
+                    <div class="box-title">巡园重点</div>
+                    <div class="box-text">
+                        <div class="warning-part" v-for="(part, partI) in patrolList" :key="partI">
+                            <div class="report-part">
+                                <div class="part-top">
+                                    <div class="part-title">{{ part.title }}</div>
+                                    <div class="part-link">
+                                        <el-icon class="part-link-icon"><Link /></el-icon>
+                                        <div class="text-link">查看互动</div>
+                                    </div>
+                                </div>
+                                <div class="part-text">{{ part.description }}</div>
                             </div>
                         </div>
                     </div>
@@ -248,10 +265,48 @@ const tabBarHeight = computed(() => store.state.home.tabBarHeight);
 const route = useRoute();
 const router = useRouter();
 const loading = ref(false);
-const hasReport = ref(false);
+const hasReport = ref(true);
 const workItems = ref([]);
 const swipeRef = ref(null);
 
+//
+const riskList = ref([
+    {
+        title: '病虫风险',
+        description: '当前分蘖期对病虫害高度敏感,易受害。经过飞鸟智慧大脑计算病虫风险:病虫胁迫指数处于中等水平,存在一定的病虫害发生风险,局部区域可能出现病害流行或虫害爆发,需加强监测预警,及时巡园'
+    },
+    {
+        title: '阴雨寡照风险',
+        description: '经过飞鸟智慧大脑计气象风险:阴雨寡照胁迫指数处于中等水平,存在一定的植株缺素风险,局部区域可能会出现长势异常现象,需加强监测预警,及时巡园'
+    },
+]);
+
+const adviceList = ref([
+    {
+        title: '根外追肥',
+        description: '分蘖前期持续阴雨寡照,需排水增氧、根外追肥促分蘖恢复'
+    },
+    {
+        title: '虫害防治',
+        description: '通过叶面喷施杀虫剂,快速降低刺吸式害虫种群数量,保护心叶和叶鞘正常生长'
+    },
+]);
+
+const patrolList = ref([
+    {
+        title: '进程互动',
+        description: '是否有60%的水稻进入分蘖盛期?'
+    },
+    {
+        title: '长势互动',
+        description: '是否有10%的水稻出现缺素症状?'
+    },
+    {
+        title: '病虫互动',
+        description: '是否有10%的水稻发生病虫害特征?'
+    },
+]);
+//
 const paramsPage = ref({});
 const showBindSuccess = ref(false);
 const startInteractPopupRef = ref(null);
@@ -312,7 +367,8 @@ const changeGarden = async ({ id, name }) => {
     // 初始化品种/大物候期转换
     startInteractPopupRef.value.getPhenologyInitOrConfirmStatus();
     await getSubjectData(id);
-    await getRegions();
+    hasReport.value = true;
+    // await getRegions();
 };
 
 onActivated(() => {
@@ -350,7 +406,8 @@ const userInfoObj = userInfo ? JSON.parse(userInfo) : {};
 
 const handleLockClick = () => {
     if (currentFarmName.value) {
-        router.push("/interaction?subjectId=" + localStorage.getItem("selectedFarmId"));
+        // router.push("/interaction?subjectId=" + localStorage.getItem("selectedFarmId"));
+        router.push(`/create_farm?from=growth_report&isReload=true`);
         return;
     }
     if (userInfoObj?.tel) {
@@ -466,6 +523,7 @@ const getRegions = async () => {
     VE_API.monitor.listRegionsBySubjectId({
         subjectId: paramsPage.value.subjectId,
     }).then(({ data }) => {
+        console.log(data);
         regionsData.value = data || [];
         if (regionsData.value.length > 0) {
             hasReport.value = true;

+ 3 - 10
src/views/old_mini/monitor/index.vue

@@ -56,7 +56,7 @@
             </template>
             <div class="archives-time-line-content">
                 <div class="time-line">
-                    <archives-farm-time-line :farmId="farmIdData" :regionId="regionData" @card-click="handleCardClick"></archives-farm-time-line>
+                    <archives-farm-time-line :farmId="farmIdData" @card-click="handleCardClick"></archives-farm-time-line>
                 </div>
             </div>
         </div>
@@ -73,7 +73,7 @@
 </template>
 
 <script setup>
-import { ref, computed, onActivated, onDeactivated, onMounted } from "vue";
+import { ref, computed, onActivated, onMounted } from "vue";
 import customHeader from "@/components/customHeader.vue";
 import { useStore } from "vuex";
 import wx from "weixin-js-sdk";
@@ -114,14 +114,12 @@ const getVarietyTabs = async (isShowPopup = true) => {
 };
 
 const farmIdData = ref(null);
-const regionData = ref(null);
 const titlePopup = ref("");
 const currentVariety = ref({});
 const handleVarietyClick = (tab, index) => {
     activeVariety.value = index;
-    if(tab.regionId){
+    if (tab.regionId) {
         farmIdData.value = tab.farmId;
-        regionData.value = tab.regionId;
     }
     currentVariety.value = tab;
     if (tab.lastViewTime == null && tab.regionId) {
@@ -216,11 +214,6 @@ const handleLockClick = () => {
 }
 
 
-// 组件卸载时停止语音播放
-onDeactivated(() => {
-    regionData.value = null;
-});
-
 const isExpanded = ref(false);
 const weatherExpanded = (isExpandedValue) => {
     isExpanded.value = isExpandedValue;

+ 26 - 13
src/views/old_mini/recordDetails/index.vue

@@ -3,33 +3,33 @@
         <custom-header name="农事名称"></custom-header>
         <div class="record-content">
             <div class="record-header">
-                <span>物候跟踪记录</span>
-                <div class="question">具体问题具体问题具体问题具体问题具体问题具体</div>
+                <span>{{ workDetail.interaction_type }}</span>
+                <div class="question">{{ workDetail.interaction_issue }}</div>
             </div>
             <div class="record-body">
                 <div class="card-wrap">
                     <div class="card-item">
                         <span class="item-label">农情研判:</span>
-                        <span class="item-value">互动原因互动原因互动原因互动原因互动原因互动原因互动原因互动原因互动原因互动原因互动原因互动原因互动原因互动原因互动原因互动原因</span>
+                        <text-ellipsis class="item-value" expand-text="展开" collapse-text="收起" rows="3" :content="workDetail.crop_condition_analysis" />
                     </div>
                     <div class="card-item">
                         <span class="item-label">巡园要点:</span>
-                        <span class="item-value">巡园要点巡园要点巡园要点巡园要点巡园要点巡园要点巡园要点巡园要点巡园要点巡园要点巡园要点巡园要点</span>
+                        <text-ellipsis class="item-value" expand-text="展开" collapse-text="收起" rows="3" :content="workDetail.inspection_keypoints" />
                     </div>
                     <div class="card-item">
                         <span class="item-label">表型特征:</span>
-                        <span class="item-value">表型特征</span>
+                        <text-ellipsis class="item-value" expand-text="展开" collapse-text="收起" rows="3" :content="workDetail.phenotypic_characteristics" />
                     </div>
                 </div>
-                <div class="tabs-list" v-if="!showMap">
+                <!-- <div class="tabs-list" v-if="!showMap">
                     <div class="item-tab" :class="{ 'item-tab--active': activeTab === index }"
                         v-for="(item, index) in tabsList" :key="index" @click="handleTabClick(index)">{{ item.label }}
                     </div>
-                </div>
+                </div> -->
                 <div class="card-wrap">
                     <div class="border-wrap" v-if="showMap">
                         <div class="question-box">
-                            <span>问题问题问题问题问题问题</span>
+                            <span>{{ workDetail.interaction_issue }}</span>
                             <el-input class="input" v-model="input" size="large" type="number">
                                 <template #suffix>
                                     <span>%</span>
@@ -79,7 +79,7 @@
             <div class="bottom-btn secondary-btn">转发记录</div>
         </div>
 
-        <div class="phenology-tip-banner">
+        <!-- <div class="phenology-tip-banner">
             <div class="banner__left">
                 <div class="banner__title">物候不整齐?</div>
                 <span class="banner__desc">
@@ -91,7 +91,7 @@
             <div class="banner__btn" @click="goPartitionManage">
                 分区管理
             </div>
-        </div>
+        </div> -->
 
         <UploadProgressPopup ref="uploadProgressPopupRef" v-model:show="showUploadProgressPopup"
             :popup-image-upload-loading="popupImageUploadLoading" :init-img-arr="initImgArr"
@@ -112,8 +112,8 @@ import PhenologyTrackTimelineItem from "@/components/pageComponents/PhenologyTra
 import GrowthStageTimeline from "@/components/pageComponents/GrowthStageTimeline.vue";
 import UploadProgressPopup from "@/components/popup/UploadProgressPopup.vue";
 import { ref, onMounted } from 'vue';
-import { useRouter } from 'vue-router';
-import { Uploader } from "vant";
+import { useRouter, useRoute } from 'vue-router';
+import { Uploader,TextEllipsis } from "vant";
 import { ElMessage } from "element-plus";
 import UploadFile from "@/utils/upliadFile";
 import { getFileExt } from "@/utils/util";
@@ -121,7 +121,7 @@ import IndexMap from "./map/index.js";
 import { Plus } from "@element-plus/icons-vue";
 
 const router = useRouter();
-
+const route = useRoute();
 function goPartitionManage() {
     router.push({ name: 'MapManage' });
 }
@@ -258,12 +258,22 @@ const growthStages = ref([
 ]);
 
 onMounted(() => {
+    getWorkDetail();
     if (showMap.value) {
         location.value = "POINT(113.6142086995688 23.585836479509055)";
         indexMap.initMap(location.value, mapContainer.value);
     }
 });
 
+const workDetail = ref({});
+const getWorkDetail = async () => {
+    const res = await VE_API.monitor.getWorkDetail({ id: route.query.workId });
+    if (res.code === 200 && res.data.length) {
+        workDetail.value = res.data[0];
+        console.log(workDetail.value);
+    }
+}
+
 </script>
 
 <style scoped lang="scss">
@@ -335,6 +345,9 @@ onMounted(() => {
                     .item-label {
                         color: rgba(60, 60, 60, 0.5);
                     }
+                    .item-value {
+                        display: inline;
+                    }
                 }
 
                 .card-item+.card-item {