소스 검색

feat:对接互动详情页面接口

wangsisi 1 주 전
부모
커밋
3cf2317310

+ 1 - 1
src/api/modules/monitor.js

@@ -104,5 +104,5 @@ module.exports = {
     farmPhenologyAdjust: {
         url: config.base_new_url + "farm_phenology_adjust",
         type: "post",
-    }
+    },
 };

+ 24 - 0
src/api/modules/record.js

@@ -0,0 +1,24 @@
+const config = require("../config")
+
+module.exports = {
+    //病虫害列表查询
+    abnormalPlan: {
+        url: config.base_new_url + "pest_abnormal_plan",
+        type: "get",
+    },
+    //生长异常列表查询
+    growthAnomalyInfo: {
+        url: config.base_new_url + "get_growth_anomaly_info",
+        type: "get",
+    },
+    //获取分区记录图片
+    farmImages: {
+        url: config.base_new_url + "farm_images",
+        type: "get",
+    },
+    //互动问题记录
+    writeFarmRecord: {
+        url: config.base_new_url + "write_farm_record",
+        type: "post",
+    },
+}

+ 4 - 0
src/i18n/messages.js

@@ -137,6 +137,8 @@ export default {
         recordDetails: recordDetailsZh,
         agriRecord: {
             farmDetail: "农场详情",
+            allFarmWork: "全部农事",
+            traceFarmWork: "溯源农事",
             level2: "二级",
             riskLevel: "{level}级",
             pendingRecord: "待记录",
@@ -307,6 +309,8 @@ export default {
         recordDetails: recordDetailsEn,
         agriRecord: {
             farmDetail: "Farm Details",
+            allFarmWork: "All Farm Work",
+            traceFarmWork: "Traceability",
             level2: "Level 2",
             riskLevel: "Level {level}",
             pendingRecord: "Pending",

+ 18 - 12
src/i18n/recordDetails-messages.js

@@ -46,12 +46,15 @@ export const recordDetailsZh = {
     confirmSuccess: "确认成功",
     pestDisease: "病害",
     pestInsect: "虫害",
-    catFungal: "真菌类",
-    catBorer: "钻蛀类",
-    catVirus: "病毒类",
-    catOther: "其它",
-    catChewing: "啃食类",
-    catMasticate: "咀嚼式",
+    catDiseaseFungal: "真菌型",
+    catDiseaseBacterial: "细菌型",
+    catDiseaseSoilBorne: "土传型",
+    catDiseaseInsectBorne: "虫传型",
+    catDiseaseViral: "病毒型",
+    catInsectPiercing: "刺吸式",
+    catInsectChewing: "咀嚼式",
+    catInsectBoring: "钻蛀式",
+    catInsectUnderground: "地下害虫",
     detDownyMildew: "霜疫霉病",
     detAnthracnose: "炭疽病",
     detBlast: "叶瘟",
@@ -128,12 +131,15 @@ export const recordDetailsEn = {
     confirmSuccess: "Confirmed",
     pestDisease: "Disease",
     pestInsect: "Insect",
-    catFungal: "Fungal",
-    catBorer: "Borer",
-    catVirus: "Viral",
-    catOther: "Other",
-    catChewing: "Chewing",
-    catMasticate: "Chewing type",
+    catDiseaseFungal: "Fungal",
+    catDiseaseBacterial: "Bacterial",
+    catDiseaseSoilBorne: "Soil-borne",
+    catDiseaseInsectBorne: "Insect-borne",
+    catDiseaseViral: "Viral",
+    catInsectPiercing: "Piercing-sucking",
+    catInsectChewing: "Chewing",
+    catInsectBoring: "Boring",
+    catInsectUnderground: "Underground pests",
     detDownyMildew: "Downy mildew",
     detAnthracnose: "Anthracnose",
     detBlast: "Blast",

+ 53 - 7
src/views/old_mini/agri_record/index.vue

@@ -22,17 +22,34 @@
                             <span class="title">{{ item?.first_work?.work_name }}</span>
                             <span class="level-tag" v-if="item?.risk_level">{{ t('agriRecord.riskLevel', { level: item.risk_level }) }}</span>
                         </div>
-                        <div class="status-tag">{{ t('agriRecord.pendingRecord') }}</div>
+                        <div class="status-tag" v-if="item?.status === 0">{{ t('agriRecord.pendingRecord') }}</div>
                     </div>
                     <div class="card-row">
                         <div class="reason-text">{{ item?.first_work?.work_reason_short }}</div>
                         <div class="question-tag">{{ item?.first_work?.interaction_issue }}</div>
                     </div>
-                    <!-- <div class="record-list">
-                        <div class="record-item" v-for="(record, recordIndex) in item.records" :key="recordIndex">
-                            {{ record }}
+                    <div class="record-list">
+                        <div class="record-item" v-for="(record, recordIndex) in item.list" :key="recordIndex">
+                            <span v-if="record?.category_name">({{ record.time }}){{ record.category_name }}</span>
+                            <span v-else>{{ record }}</span>
                         </div>
-                    </div> -->
+                    </div>
+                </div>
+            </div>
+            <div class="farm-work-tabs">
+                <div
+                    class="farm-work-tabs__item"
+                    :class="{ 'farm-work-tabs__item--active': activeFarmWorkTab === 'all' }"
+                    @click="handleFarmWorkTabClick('all')"
+                >
+                    {{ t('agriRecord.allFarmWork') }}
+                </div>
+                <div
+                    class="farm-work-tabs__item"
+                    :class="{ 'farm-work-tabs__item--active': activeFarmWorkTab === 'trace' }"
+                    @click="handleFarmWorkTabClick('trace')"
+                >
+                    {{ t('agriRecord.traceFarmWork') }}
                 </div>
             </div>
             <div class="archives-time-line-content">
@@ -91,19 +108,28 @@ const defaultGardenId = ref(null);
 const selectedGardenId = ref(null);
 const gardenListRef = ref(null);
 const activeGardenTab = ref('current');
+const activeFarmWorkTab = ref('all');
 const trendMonitorMockList = ref([]);
 
+const handleFarmWorkTabClick = (tab) => {
+    activeFarmWorkTab.value = tab;
+};
+
 const changeGardenTab = (tab) => {
     activeGardenTab.value = tab;
 };
 
+const currentPheCode = ref('');
 const getFarmRiskAndTracking = async () => {
     trendMonitorMockList.value = [];
+    const selectedFarmData = JSON.parse(localStorage.getItem("selectedFarmData"));
     const res = await VE_API.monitor.getFarmRiskAndTracking({
         farm_id: gardenId.value,
-        crop_type: JSON.parse(localStorage.getItem("selectedFarmData")).farm_variety,
+        crop_type: selectedFarmData.farm_variety,
+        category_code: selectedFarmData.farm_category
     });
     if (res.code === 200) {
+        currentPheCode.value = res.data?.current_phe_code;
         const growth = res.data?.growth_abnormal_tracking;
         const pest = res.data?.pest_risk_assessment;
         const phenology = res.data?.phenology_tracking;
@@ -201,7 +227,7 @@ const handleTrendMonitorCardClick = (item) => {
     blockArchivesScrollSaveOnce.value = true;
     router.push({
         path: "/record_details",
-        query: { workId: item.work_id, type: item.workType },
+        query: { workId: item?.first_work?.work_id, type: item?.workType, curCode:currentPheCode.value  },
     });
 };
 </script>
@@ -328,6 +354,26 @@ const handleTrendMonitorCardClick = (item) => {
         overflow-y: auto;
         -webkit-overflow-scrolling: touch;
 
+        .farm-work-tabs {
+            display: flex;
+            gap: 8px;
+            margin-top: 10px;
+
+            &__item {
+                flex: 1;
+                padding: 5px 0;
+                border-radius: 2px;
+                text-align: center;
+                background: #EFEFEF;
+                color: #858585;
+
+                &--active {
+                    background: #2199f8;
+                    color: #ffffff;
+                }
+            }
+        }
+
         .archives-time-line-content {
             margin-top: 10px;
             flex: none;

+ 105 - 65
src/views/old_mini/recordDetails/index.vue

@@ -4,7 +4,7 @@
         <div class="record-content">
             <div class="record-header" v-if="recordType === 'growth'">
                 <span>{{ t('agriRecord.growthWorkName') }}</span>
-                <div class="question">{{ t('recordDetails.growthQuestion') }}</div>
+                <div class="question">{{currentGrowthAnomalyDetail?.interact_question }}</div>
             </div>
             <div class="record-header" v-else-if="recordType === 'pest'">
                 <span>{{ t('agriRecord.pestWorkName') }}</span>
@@ -19,22 +19,22 @@
                     <div class="card-item">
                         <span class="item-label">{{ t('recordDetails.scienceLabel') }}</span>
                         <text-ellipsis class="item-value" :expand-text="expandCollapse.expand" :collapse-text="expandCollapse.collapse" rows="3"
-                            :content="t('recordDetails.growthScience')" />
+                            :content="currentGrowthAnomalyDetail?.agri_judgment" />
                     </div>
                     <div class="tabs-list" v-if="!showMap">
-                        <div class="item-tab" :class="{ 'item-tab--active': activeTab1 === index }"
-                            v-for="(item, index) in tabsList1" :key="index" @click="activeTab1 = index">{{ item.label }}
+                        <div class="item-tab" :class="{ 'item-tab--active': activeGrowthAnomalyIndex === index }"
+                            v-for="(item, index) in growthAnomalyTabs" :key="index" @click="handleGrowthAnomalyTabClick(index)">{{ item.label }}
                         </div>
                     </div>
                     <div class="card-item">
                         <span class="item-label">{{ t('recordDetails.phenotypeLabel') }}</span>
                         <text-ellipsis class="item-value" :expand-text="expandCollapse.expand" :collapse-text="expandCollapse.collapse" rows="3"
-                            :content="t('recordDetails.growthPhenotype')" />
+                            :content="currentGrowthAnomalyDetail?.phenotype" />
                     </div>
                     <div class="card-item">
                         <span class="item-label">{{ t('recordDetails.highRiskLabel') }}</span>
                         <text-ellipsis class="item-value" :expand-text="expandCollapse.expand" :collapse-text="expandCollapse.collapse" rows="3"
-                            :content="t('recordDetails.growthHighRisk')" />
+                            :content="currentGrowthAnomalyDetail?.patrol_points" />
                     </div>
                 </div>
                 <div class="card-wrap" v-else-if="recordType === 'pest'">
@@ -51,27 +51,27 @@
                                 @click="handlePestTopClick(i)">{{ label }}</div>
                         </div>
                         <div class="pest-classify-picker__row pest-classify-picker__row--grid4">
-                            <div v-for="(label, i) in pestCategoryLabels" :key="'cat-' + i"
+                            <div v-for="(item, i) in pestCategoryLabels" :key="'cat-' + item.value"
                                 class="pest-classify-picker__chip pest-classify-picker__chip--solid"
                                 :class="{ 'pest-classify-picker__chip--solid-active': pestCategoryIndex === i }"
-                                @click="handlePestCategoryClick(i)">{{ label }}</div>
+                                @click="handlePestCategoryClick(i)">{{ item.label }}</div>
                         </div>
                         <div class="pest-classify-picker__row pest-classify-picker__row--grid4">
-                            <div v-for="(label, i) in pestDetailLabels" :key="'det-' + i"
+                            <div v-for="(item, i) in pestDetailLabels" :key="'det-' + item.value"
                                 class="pest-classify-picker__chip pest-classify-picker__chip--soft"
                                 :class="{ 'pest-classify-picker__chip--soft-active': pestDetailIndex === i }"
-                                @click="handlePestDetailClick(i)">{{ label }}</div>
+                                @click="handlePestDetailClick(i)">{{ item.label }}</div>
                         </div>
                     </div>
                     <div class="card-item">
                         <span class="item-label">{{ t('recordDetails.phenotypeLabel') }}</span>
                         <text-ellipsis class="item-value" :expand-text="expandCollapse.expand" :collapse-text="expandCollapse.collapse" rows="3"
-                            :content="pestText1Content" />
+                            :content="currentPestDetail?.phenotype" />
                     </div>
                     <div class="card-item">
                         <span class="item-label">{{ t('recordDetails.highRiskLabel') }}</span>
                         <text-ellipsis class="item-value" :expand-text="expandCollapse.expand" :collapse-text="expandCollapse.collapse" rows="3"
-                            :content="pestText2Content" />
+                            :content="currentPestDetail?.patrol_points" />
                     </div>
                 </div>
                 <div class="card-wrap" v-else>
@@ -273,66 +273,75 @@ const showMap = ref(false);
 const pestTopIndex = ref(0);
 const pestCategoryIndex = ref(0);
 const pestDetailIndex = ref(0);
-const pestDetailKeys = ref(['detDownyMildew', 'detAnthracnose', 'detBlast', 'detSheathBlight']);
+const pestData = ref([]);
 
 const pestTopLabels = computed(() => [t('recordDetails.pestDisease'), t('recordDetails.pestInsect')]);
 
+const PEST_CATEGORY_DISEASE = [
+    { key: 'catDiseaseFungal', value: 1 },
+    { key: 'catDiseaseBacterial', value: 2 },
+    { key: 'catDiseaseSoilBorne', value: 3 },
+    { key: 'catDiseaseInsectBorne', value: 4 },
+    { key: 'catDiseaseViral', value: 5 },
+];
+
+const PEST_CATEGORY_INSECT = [
+    { key: 'catInsectPiercing', value: 1 },
+    { key: 'catInsectChewing', value: 2 },
+    { key: 'catInsectBoring', value: 3 },
+    { key: 'catInsectUnderground', value: 4 },
+];
+
 const pestCategoryLabels = computed(() => {
-    if (pestTopIndex.value === 0) {
-        return ['catFungal', 'catBorer', 'catVirus', 'catOther'].map((k) => t(`recordDetails.${k}`));
-    }
-    return ['catChewing', 'catMasticate', 'catBorer', 'catOther'].map((k) => t(`recordDetails.${k}`));
+    const list = pestTopIndex.value === 0 ? PEST_CATEGORY_DISEASE : PEST_CATEGORY_INSECT;
+    return list.map(({ key, value }) => ({
+        label: t(`recordDetails.${key}`),
+        value,
+    }));
 });
 
 const pestDetailLabels = computed(() =>
-    pestDetailKeys.value.map((k) => t(`recordDetails.${k}`))
+    pestData.value.map((item) => ({
+        label: item.label ?? item.name ?? '',
+        value: item.value ?? item.fourth_type ?? item.id,
+    }))
 );
 
-const pestText1Content = computed(() => {
-    const top = pestTopIndex.value;
-    const cat = pestCategoryIndex.value;
-    const det = pestDetailIndex.value;
-    if (top === 0) {
-        return det === 0 ? t('recordDetails.pestT1_downy') : t('recordDetails.pestT1_anthracnose');
-    }
-    if (cat === 0) return t('recordDetails.pestT1_stinkbug');
-    if (cat !== 0 && det !== 0) return t('recordDetails.pestT1_stemborer');
-    return t('recordDetails.pestT1_riceborer');
-});
+const currentPestDetail = computed(() => pestData.value[pestDetailIndex.value]);
 
-const pestText2Content = computed(() => {
-    const top = pestTopIndex.value;
-    const cat = pestCategoryIndex.value;
-    const det = pestDetailIndex.value;
-    if (top === 0) {
-        return det === 0 ? t('recordDetails.pestT2_downy') : t('recordDetails.pestT2_anthracnose');
+/** 病虫害列表查询 */
+const getAbnormalPlan = async () => {
+    const category = pestCategoryLabels.value[pestCategoryIndex.value];
+    const params = {
+        crop_type: JSON.parse(localStorage.getItem('selectedFarmData')).farm_variety,
+        phenology_code: route.query.curCode,
+        second_type: pestTopIndex.value === 0 ? 2 : 1,
+        third_type: category?.value ?? 1,
+    };
+    const res = await VE_API.record.abnormalPlan(params);
+    if (res.code === 200 && res.data?.length) {
+        pestData.value = res.data;
+        if (pestDetailIndex.value >= res.data.length) {
+            pestDetailIndex.value = 0;
+        }
+    } else {
+        pestData.value = [];
+        pestDetailIndex.value = 0;
     }
-    if (cat === 0) return t('recordDetails.pestT2_stinkbug');
-    if (cat !== 0 && det !== 0) return t('recordDetails.pestT2_stemborer');
-    return t('recordDetails.pestT2_riceborer');
-});
+};
 
-const handlePestTopClick = (index) => {
+/** 病虫害分类选择 */
+const handlePestTopClick = async (index) => {
     pestTopIndex.value = index;
     pestCategoryIndex.value = 0;
     pestDetailIndex.value = 0;
-    if (index === 0) {
-        pestDetailKeys.value = ['detDownyMildew', 'detAnthracnose', 'detBlast', 'detSheathBlight'];
-    } else {
-        pestDetailKeys.value = ['detStinkBug'];
-    }
+    await getAbnormalPlan();
 };
 
-const handlePestCategoryClick = (index) => {
+const handlePestCategoryClick = async (index) => {
     pestCategoryIndex.value = index;
     pestDetailIndex.value = 0;
-    if (pestTopIndex.value === 1) {
-        pestDetailKeys.value = index === 0 ? ['detStinkBug'] : ['detRiceBorer'];
-    } else if (index !== 0) {
-        pestDetailKeys.value = ['detStemBorer'];
-    } else {
-        pestDetailKeys.value = ['detDownyMildew', 'detAnthracnose', 'detBlast', 'detSheathBlight'];
-    }
+    await getAbnormalPlan();
 };
 
 const handlePestDetailClick = (index) => {
@@ -351,13 +360,19 @@ const tabsList = ref([
     { label: '分区四', value: 3 },
 ]);
 
-const activeTab1 = ref(0);
-const tabsList1 = computed(() => [
-    { label: t('recordDetails.tabFruitBlocked'), value: 0 },
-    { label: t('recordDetails.tabSlowGrowth'), value: 1 },
-    { label: t('recordDetails.tabVigorous'), value: 2 },
-    { label: t('recordDetails.tabWilting'), value: 3 },
-]);
+const activeGrowthAnomalyIndex = ref(0);
+const growthAnomalyData = ref([]);
+const growthAnomalyTabs = computed(() =>
+    growthAnomalyData.value.map((item, index) => ({
+        label: item.name ?? '',
+        value: item.value ?? item.id ?? index,
+    }))
+);
+
+const currentGrowthAnomalyDetail = computed(() => growthAnomalyData.value[activeGrowthAnomalyIndex.value]);
+const handleGrowthAnomalyTabClick = (index) => {
+    activeGrowthAnomalyIndex.value = index;
+};
 
 const currentStatusText = computed(() =>
     t('recordDetails.currentStatus', {
@@ -532,7 +547,15 @@ function syncCurStageFromModel() {
 watch([growthStages, growthStageIndex], syncCurStageFromModel, { immediate: true });
 
 onMounted(() => {
-    getWorkDetail();
+    if (route.query.workId) {
+        getWorkDetail();
+    }
+    if (route.query.type === 'pest') {
+        getAbnormalPlan();
+    }
+    if (route.query.type === 'growth') {
+        getGrowthAnomalyInfo();
+    }
     getFarmRecord()
     getFindPhenologyInfo()
     if (showMap.value) {
@@ -549,6 +572,22 @@ const getWorkDetail = async () => {
     }
 }
 
+// 获取生长异常列表
+const getGrowthAnomalyInfo = async () => {
+    const params = {
+        crop_type: JSON.parse(localStorage.getItem('selectedFarmData')).farm_variety,
+        phenology_code: route.query.curCode,
+    }
+    const res = await VE_API.record.growthAnomalyInfo(params);
+    if (res.code === 200 && res.data?.length) {
+        growthAnomalyData.value = res.data;
+        activeGrowthAnomalyIndex.value = 0;
+    } else {
+        growthAnomalyData.value = [];
+        activeGrowthAnomalyIndex.value = 0;
+    }
+}
+
 const getFarmRecord = async () => {
     // const res = await VE_API.monitor.getFarmRecord();
     const res = {
@@ -720,12 +759,12 @@ const getFindPhenologyInfo = async () => {
                 margin: 10px 0;
                 flex-shrink: 0;
                 display: grid;
-                grid-template-columns: repeat(4, 1fr);
+                grid-template-columns: repeat(auto-fill, minmax(8em, 1fr));
                 gap: 8px;
 
                 .item-tab {
                     box-sizing: border-box;
-                    padding: 4px;
+                    padding: 6px 4px;
                     border-radius: 2px;
                     color: #767676;
                     background: #fff;
@@ -733,8 +772,9 @@ const getFindPhenologyInfo = async () => {
                     align-items: center;
                     justify-content: center;
                     text-align: center;
-                    word-break: break-word;
-                    overflow-wrap: anywhere;
+                    font-size: 13px;
+                    white-space: nowrap;
+                    word-break: keep-all;
                 }
 
                 .item-tab--active {