|
|
@@ -1,7 +1,7 @@
|
|
|
-<template>
|
|
|
+32<template>
|
|
|
<div class="growth-track-page">
|
|
|
<custom-header
|
|
|
- :name="t('agriFile.workName')"
|
|
|
+ :name="pageTitle"
|
|
|
:isGoBack="!isFromShare"
|
|
|
:isClose="isFromShare"
|
|
|
:showClose="false"
|
|
|
@@ -28,7 +28,7 @@
|
|
|
<template v-if="!isAbnormal">
|
|
|
<div class="growth-content">
|
|
|
<div class="growth-content__title">{{ t("agriFile.agriAssessment") }}</div>
|
|
|
- <div class="growth-content__desc">{{ t("agriFile.agriAssessmentDesc") }}</div>
|
|
|
+ <div class="growth-content__desc">{{ assessmentDesc }}</div>
|
|
|
</div>
|
|
|
<div class="interact-card">
|
|
|
<div class="interact-card__head">
|
|
|
@@ -38,23 +38,32 @@
|
|
|
</div>
|
|
|
</div>
|
|
|
<div class="interact-card__qa">
|
|
|
- <div class="interact-card__question">{{ t("agriFile.interactQuestionText") }}</div>
|
|
|
+ <div class="interact-card__question">{{ interactQuestion }}</div>
|
|
|
<div class="interact-card__options">
|
|
|
- <div v-for="item in interactOptions" :key="item.id" class="interact-option"
|
|
|
- :class="{ selected: selectedOptionId === item.id }" @click="selectedOptionId = item.id">
|
|
|
+ <div
|
|
|
+ v-for="item in interactOptions"
|
|
|
+ :key="item.id"
|
|
|
+ class="interact-option"
|
|
|
+ :class="{ selected: selectedOptionId === item.id }"
|
|
|
+ @click="selectedOptionId = item.id"
|
|
|
+ >
|
|
|
<span class="interact-option__text">{{ item.name }}</span>
|
|
|
</div>
|
|
|
</div>
|
|
|
<div class="interact-card__submit" @click="handleSubmit">{{ t("agriFile.submit") }}</div>
|
|
|
</div>
|
|
|
- <div class="interact-card__ref">
|
|
|
+ <!-- <div class="interact-card__ref">
|
|
|
<span class="interact-card__ref-label">{{ t("agriFile.referenceImage") }}</span>
|
|
|
<img class="interact-card__ref-img" src="@/assets/img/agricultural/patrol-guide.png" alt="" />
|
|
|
- </div>
|
|
|
+ </div> -->
|
|
|
</div>
|
|
|
- <div class="guide-card">
|
|
|
+ <div class="guide-card" v-if="interactImg">
|
|
|
<div class="guide-title">{{ t("agriFile.patrolGuide") }}</div>
|
|
|
- <img class="guide-card__img" src="@/assets/img/agricultural/patrol-guide.png" alt="" />
|
|
|
+ <photo-provider :photo-closable="true">
|
|
|
+ <photo-consumer :src="interactImg">
|
|
|
+ <img class="guide-card__img" :src="interactImg" alt="" />
|
|
|
+ </photo-consumer>
|
|
|
+ </photo-provider>
|
|
|
</div>
|
|
|
</template>
|
|
|
<div v-else>
|
|
|
@@ -89,7 +98,7 @@
|
|
|
</template>
|
|
|
|
|
|
<script setup>
|
|
|
-import { computed, nextTick, onActivated, ref } from "vue";
|
|
|
+import { computed, nextTick, onActivated, onMounted, ref } from "vue";
|
|
|
import { useRoute, useRouter } from "vue-router";
|
|
|
import { ElMessage } from "element-plus";
|
|
|
import customHeader from "@/components/customHeader.vue";
|
|
|
@@ -97,12 +106,16 @@ import albumUploadPopup from "../components/albumUploadPopup.vue";
|
|
|
import leaveConfirmPopup from "@/components/popup/leaveConfirmPopup.vue";
|
|
|
import tipPopup from "@/components/popup/tipPopup.vue";
|
|
|
import { useI18n } from "@/i18n";
|
|
|
+import { base_img_url2 } from "@/api/config";
|
|
|
|
|
|
const { t } = useI18n();
|
|
|
const route = useRoute();
|
|
|
const router = useRouter();
|
|
|
|
|
|
+const ENTRY_FARM_DATA_KEY = "ENTRY_FARM_DATA";
|
|
|
+
|
|
|
const isAbnormal = computed(() => route.query.type === "abnormal");
|
|
|
+const pageTitle = computed(() => route.query.pageName || "巡园要点");
|
|
|
|
|
|
function isTruthyFlag(value) {
|
|
|
return value === 1 || value === "1" || value === true || value === "true";
|
|
|
@@ -129,16 +142,16 @@ const isFromShare = computed(() => {
|
|
|
return false;
|
|
|
});
|
|
|
|
|
|
-const theme = computed(() => t("agriFile.interactTheme"));
|
|
|
+const theme = ref("");
|
|
|
const level = computed(() => t("agriFile.riskLevel2"));
|
|
|
-const reason = computed(() => t("agriFile.interactReason"));
|
|
|
-const zoneName = computed(() => t("agriFile.zoneOne"));
|
|
|
-/** 互动选项,后续由接口赋值 */
|
|
|
-const interactOptions = ref([
|
|
|
- { id: 1, name: "选项一" },
|
|
|
- { id: 2, name: "选项二" },
|
|
|
- { id: 3, name: "选项三" },
|
|
|
-]);
|
|
|
+const reason = ref("");
|
|
|
+const zoneName = ref("");
|
|
|
+/** 农情研判描述:interaction_theme */
|
|
|
+const assessmentDesc = ref("");
|
|
|
+/** 互动问题:interaction_problem */
|
|
|
+const interactQuestion = ref("");
|
|
|
+/** 互动选项,由 parse_interact 赋值 */
|
|
|
+const interactOptions = ref([]);
|
|
|
const selectedOptionId = ref(null);
|
|
|
const showUploadPopup = ref(false);
|
|
|
const showSuccessPopup = ref(false);
|
|
|
@@ -151,6 +164,54 @@ const situationList = [
|
|
|
/** 作物档案本地记录(提交互动后写入,农事档案页读取) */
|
|
|
const CROP_ARCHIVE_KEY = "CROP_ARCHIVE_RECORDS";
|
|
|
|
|
|
+function readEntryFarmData() {
|
|
|
+ try {
|
|
|
+ return JSON.parse(localStorage.getItem(ENTRY_FARM_DATA_KEY) || "null");
|
|
|
+ } catch {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+const interactImg = ref("");
|
|
|
+function applyInteractData(data) {
|
|
|
+ if (!data) return;
|
|
|
+ theme.value = data.interaction_title || "";
|
|
|
+ reason.value = data.interaction_theme || "";
|
|
|
+ zoneName.value = data.crop_category_name || "";
|
|
|
+ assessmentDesc.value = data.inspection_guide || "";
|
|
|
+ interactQuestion.value = data.interaction_problem || "";
|
|
|
+ interactImg.value = base_img_url2 + data.interact_pic_url || "";
|
|
|
+ const options = Array.isArray(data.interaction_options) ? data.interaction_options : [];
|
|
|
+ interactOptions.value = options.map((name, index) => ({
|
|
|
+ id: index + 1,
|
|
|
+ name: String(name),
|
|
|
+ }));
|
|
|
+ selectedOptionId.value = null;
|
|
|
+}
|
|
|
+
|
|
|
+/** 长势跟踪:parse_interact */
|
|
|
+async function fetchGrowthInteract() {
|
|
|
+ if (isAbnormal.value) return;
|
|
|
+ const entry = readEntryFarmData();
|
|
|
+ const cropCategoryName = entry?.crop;
|
|
|
+ const phenophaseCode = entry?.cropCode;
|
|
|
+ const riskName = entry?.weatherRisk;
|
|
|
+ if (!cropCategoryName || !phenophaseCode || !riskName) return;
|
|
|
+
|
|
|
+ try {
|
|
|
+ const res = await VE_API.questionnaire.parseInteract({
|
|
|
+ crop_category_name: cropCategoryName,
|
|
|
+ phenophase_code: String(phenophaseCode),
|
|
|
+ risk_name: riskName,
|
|
|
+ });
|
|
|
+ if (res?.code === 200 && res.data) {
|
|
|
+ applyInteractData(res.data);
|
|
|
+ }
|
|
|
+ } catch {
|
|
|
+ // ignore
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
function formatToday() {
|
|
|
const now = new Date();
|
|
|
const y = now.getFullYear();
|
|
|
@@ -182,7 +243,7 @@ const handleSubmit = () => {
|
|
|
saveCropArchiveAnswer({
|
|
|
id: `answer-${Date.now()}`,
|
|
|
date: formatToday(),
|
|
|
- zone_name: t("agriFile.zoneOne"),
|
|
|
+ zone_name: zoneName.value || t("agriFile.zoneOne"),
|
|
|
content: option?.name || "",
|
|
|
optionId: option?.id ?? selectedOptionId.value,
|
|
|
});
|
|
|
@@ -207,10 +268,10 @@ const handleContinueUpload = () => {
|
|
|
const hasAnswered = () => selectedOptionId.value != null;
|
|
|
|
|
|
const handleBack = () => {
|
|
|
- if (!isAbnormal.value && !hasAnswered()) {
|
|
|
- showLeavePopup.value = true;
|
|
|
- return;
|
|
|
- }
|
|
|
+ // if (!isAbnormal.value && !hasAnswered()) {
|
|
|
+ // showLeavePopup.value = true;
|
|
|
+ // return;
|
|
|
+ // }
|
|
|
router.back();
|
|
|
};
|
|
|
|
|
|
@@ -218,7 +279,12 @@ const confirmLeave = () => {
|
|
|
router.back();
|
|
|
};
|
|
|
|
|
|
+onMounted(() => {
|
|
|
+ fetchGrowthInteract();
|
|
|
+});
|
|
|
+
|
|
|
onActivated(() => {
|
|
|
+ if (!isAbnormal.value) fetchGrowthInteract();
|
|
|
if (route.query.showUpload !== "1") return;
|
|
|
nextTick(() => {
|
|
|
showUploadPopup.value = true;
|
|
|
@@ -355,7 +421,7 @@ onActivated(() => {
|
|
|
}
|
|
|
|
|
|
&__qa {
|
|
|
- margin: 10px;
|
|
|
+ margin: 0 10px 10px;
|
|
|
padding: 10px;
|
|
|
border-radius: 8px;
|
|
|
background: rgba(33, 153, 248, 0.1);
|
|
|
@@ -363,7 +429,7 @@ onActivated(() => {
|
|
|
}
|
|
|
|
|
|
&__question {
|
|
|
- font-size: 14px;
|
|
|
+ font-size: 18px;
|
|
|
font-weight: 500;
|
|
|
}
|
|
|
|
|
|
@@ -374,9 +440,10 @@ onActivated(() => {
|
|
|
}
|
|
|
|
|
|
&__submit {
|
|
|
- width: 120px;
|
|
|
- margin: 12px auto 0;
|
|
|
- padding: 8px 0;
|
|
|
+ width: 112px;
|
|
|
+ margin: 10px auto 0;
|
|
|
+ height: 32px;
|
|
|
+ line-height: 32px;
|
|
|
border-radius: 25px;
|
|
|
background: #2199f8;
|
|
|
color: #fff;
|
|
|
@@ -388,9 +455,9 @@ onActivated(() => {
|
|
|
position: relative;
|
|
|
flex: 1;
|
|
|
min-width: 0;
|
|
|
- height: 36px;
|
|
|
- line-height: 36px;
|
|
|
- border-radius: 6px;
|
|
|
+ height: 32px;
|
|
|
+ line-height: 32px;
|
|
|
+ border-radius: 4px;
|
|
|
background: #fff;
|
|
|
border: 1px solid transparent;
|
|
|
text-align: center;
|
|
|
@@ -403,8 +470,8 @@ onActivated(() => {
|
|
|
overflow: hidden;
|
|
|
text-overflow: ellipsis;
|
|
|
white-space: nowrap;
|
|
|
- font-size: 14px;
|
|
|
- color: #666;
|
|
|
+ font-size: 15px;
|
|
|
+ color: #7F7F7F;
|
|
|
}
|
|
|
|
|
|
&.selected {
|