|
@@ -3,6 +3,7 @@
|
|
|
v-model:show="visible"
|
|
v-model:show="visible"
|
|
|
round
|
|
round
|
|
|
teleport="body"
|
|
teleport="body"
|
|
|
|
|
+ :z-index="20000"
|
|
|
class="restore-planting-popup"
|
|
class="restore-planting-popup"
|
|
|
:close-on-click-overlay="true"
|
|
:close-on-click-overlay="true"
|
|
|
>
|
|
>
|
|
@@ -33,10 +34,6 @@
|
|
|
|
|
|
|
|
<div class="restore-planting-popup__photo">
|
|
<div class="restore-planting-popup__photo">
|
|
|
<img :src="sampleImage" alt="" />
|
|
<img :src="sampleImage" alt="" />
|
|
|
- <!-- <div class="restore-planting-popup__bbox">
|
|
|
|
|
- <span>{{ stageTag }}</span>
|
|
|
|
|
- </div>
|
|
|
|
|
- <div class="restore-planting-popup__detect">{{ detectText }}</div> -->
|
|
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
<el-date-picker
|
|
<el-date-picker
|
|
@@ -48,6 +45,8 @@
|
|
|
:placeholder="t('agriFile.selectTime')"
|
|
:placeholder="t('agriFile.selectTime')"
|
|
|
:editable="false"
|
|
:editable="false"
|
|
|
:clearable="false"
|
|
:clearable="false"
|
|
|
|
|
+ teleported
|
|
|
|
|
+ popper-class="restore-planting-date-popper"
|
|
|
style="width: 100%"
|
|
style="width: 100%"
|
|
|
/>
|
|
/>
|
|
|
</div>
|
|
</div>
|
|
@@ -65,9 +64,13 @@
|
|
|
|
|
|
|
|
<div class="restore-planting-popup__photo restore-planting-popup__photo--guide">
|
|
<div class="restore-planting-popup__photo restore-planting-popup__photo--guide">
|
|
|
<img :src="phenologyImage" alt="" />
|
|
<img :src="phenologyImage" alt="" />
|
|
|
- <div class="restore-planting-popup__guide-btn" @click="handleViewGuide">
|
|
|
|
|
- {{ t("agriFile.viewPatrolGuide") }}
|
|
|
|
|
- </div>
|
|
|
|
|
|
|
+ <photo-provider :photo-closable="true">
|
|
|
|
|
+ <photo-consumer :src="patrolGuideImage" :intro="patrolGuideImage">
|
|
|
|
|
+ <div class="restore-planting-popup__guide-btn">
|
|
|
|
|
+ {{ t("agriFile.viewPatrolGuide") }}
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </photo-consumer>
|
|
|
|
|
+ </photo-provider>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
<div class="restore-planting-popup__options">
|
|
<div class="restore-planting-popup__options">
|
|
@@ -76,7 +79,7 @@
|
|
|
:key="item.value"
|
|
:key="item.value"
|
|
|
class="restore-planting-popup__option"
|
|
class="restore-planting-popup__option"
|
|
|
:class="{ active: phenologyAnswer === item.value }"
|
|
:class="{ active: phenologyAnswer === item.value }"
|
|
|
- @click="phenologyAnswer = item.value"
|
|
|
|
|
|
|
+ @click="handlePhenologySelect(item.value)"
|
|
|
>
|
|
>
|
|
|
<span>{{ item.label }}</span>
|
|
<span>{{ item.label }}</span>
|
|
|
<span v-if="phenologyAnswer === item.value" class="restore-planting-popup__option-check">
|
|
<span v-if="phenologyAnswer === item.value" class="restore-planting-popup__option-check">
|
|
@@ -87,11 +90,12 @@
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
<div class="restore-planting-popup__actions">
|
|
<div class="restore-planting-popup__actions">
|
|
|
- <div class="restore-planting-popup__btn restore-planting-popup__btn--ghost" @click="handleChangeQuestion">
|
|
|
|
|
- {{ t("agriFile.changeQuestion") }}
|
|
|
|
|
- </div>
|
|
|
|
|
- <div class="restore-planting-popup__btn restore-planting-popup__btn--primary" @click="handleConfirm">
|
|
|
|
|
- {{ questionType === 'time' ? t("agriFile.confirmNow") : t("agriFile.submitInfo") }}
|
|
|
|
|
|
|
+ <div
|
|
|
|
|
+ class="restore-planting-popup__btn restore-planting-popup__btn--primary"
|
|
|
|
|
+ :class="{ disabled: submitting }"
|
|
|
|
|
+ @click="handleConfirm"
|
|
|
|
|
+ >
|
|
|
|
|
+ {{ questionType === "time" ? t("agriFile.confirmNow") : t("agriFile.submitInfo") }}
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
@@ -102,69 +106,314 @@
|
|
|
import { computed, onMounted, ref } from "vue";
|
|
import { computed, onMounted, ref } from "vue";
|
|
|
import { Popup } from "vant";
|
|
import { Popup } from "vant";
|
|
|
import { Check } from "@element-plus/icons-vue";
|
|
import { Check } from "@element-plus/icons-vue";
|
|
|
|
|
+import { ElMessage } from "element-plus";
|
|
|
import { useI18n } from "@/i18n";
|
|
import { useI18n } from "@/i18n";
|
|
|
|
|
+import { base_img_url2 } from "@/api/config";
|
|
|
|
|
|
|
|
const { t } = useI18n();
|
|
const { t } = useI18n();
|
|
|
|
|
|
|
|
-/** 弹窗显隐由组件内接口控制,默认不展示 */
|
|
|
|
|
|
|
+// ---------------------------------------------------------------------------
|
|
|
|
|
+// Props
|
|
|
|
|
+// ---------------------------------------------------------------------------
|
|
|
|
|
+const props = defineProps({
|
|
|
|
|
+ /** 分区 id,初始互动接口必填 */
|
|
|
|
|
+ zoneId: { type: [Number, String], default: 42 },
|
|
|
|
|
+});
|
|
|
|
|
+
|
|
|
|
|
+// ---------------------------------------------------------------------------
|
|
|
|
|
+// 常量
|
|
|
|
|
+// ---------------------------------------------------------------------------
|
|
|
|
|
+const PHENOLOGY_PREFIX = "您的农场是否进入到 ";
|
|
|
|
|
+const DEFAULT_SAMPLE_IMAGE = require("@/assets/img/agricultural/baidian.png");
|
|
|
|
|
+const DEFAULT_PHENOLOGY_IMAGE = require("@/assets/img/common/sd-1.jpg");
|
|
|
|
|
+/** 巡园向导预览图 */
|
|
|
|
|
+const PATROL_GUIDE_IMAGE_PATH =
|
|
|
|
|
+ "e84a8f1b-9842-434c-951f-068ff6963f31/6c8b7135-95b7-4c04-82ef-a2daeb674d0c/DJI_202608190758_001_6c8b7135-95b7-4c04-82ef-a2daeb674d0c/DJI_20260819080818_0085_V_code-ws0fsmg8zg8u.jpeg";
|
|
|
|
|
+const patrolGuideImage = base_img_url2 + PATROL_GUIDE_IMAGE_PATH;
|
|
|
|
|
+
|
|
|
|
|
+// ---------------------------------------------------------------------------
|
|
|
|
|
+// 页面状态
|
|
|
|
|
+// ---------------------------------------------------------------------------
|
|
|
|
|
+/** 弹窗显隐由接口数据控制,默认不展示 */
|
|
|
const visible = ref(false);
|
|
const visible = ref(false);
|
|
|
const questionType = ref("time"); // time | phenology
|
|
const questionType = ref("time"); // time | phenology
|
|
|
const selectedDate = ref("");
|
|
const selectedDate = ref("");
|
|
|
-const phenologyAnswer = ref("reached");
|
|
|
|
|
-
|
|
|
|
|
-/** 问题内容:后续由接口赋值 */
|
|
|
|
|
-const questionText = ref("还记得农场的 “来梢” 的时间吗?");
|
|
|
|
|
-const highlightWord = ref("来梢");
|
|
|
|
|
-const hintText = ref("时间误差 5-7 天无需担心,系统将结合作物生长模拟模型自动校准");
|
|
|
|
|
-const sampleImage = ref(require("@/assets/img/agricultural/baidian.png"));
|
|
|
|
|
-const stageTag = ref("白点");
|
|
|
|
|
-const detectText = ref("生育期检测:当前检测到白点期");
|
|
|
|
|
-const phenologyQuestion = ref("您的农场是否进入到 某某物候期 ?");
|
|
|
|
|
-const phenologyHighlight = ref("某某物候期");
|
|
|
|
|
-const phenologyImage = ref(require("@/assets/img/common/sd-1.jpg"));
|
|
|
|
|
-
|
|
|
|
|
|
|
+const phenologyAnswer = ref("");
|
|
|
|
|
+const submitting = ref(false);
|
|
|
|
|
+
|
|
|
|
|
+const hasDateInteract = ref(false);
|
|
|
|
|
+const hasOptionsInteract = ref(false);
|
|
|
|
|
+/** date_interact 原始数据,提交时可能用到 */
|
|
|
|
|
+const dateInteractData = ref(null);
|
|
|
|
|
+/** options_interact.interact 映射表,key 为 start_with 同类序号 */
|
|
|
|
|
+const interactMap = ref({});
|
|
|
|
|
+/** 当前展示的物候期序号(对应 interact 的 key) */
|
|
|
|
|
+const currentInteractKey = ref("");
|
|
|
|
|
+/** 用户确认「已到达」后写入,提交接口使用 */
|
|
|
|
|
+const selectedPeriodCode = ref("");
|
|
|
|
|
+
|
|
|
|
|
+const questionText = ref("");
|
|
|
|
|
+const highlightWord = ref("");
|
|
|
|
|
+const hintText = ref("");
|
|
|
|
|
+const sampleImage = ref(DEFAULT_SAMPLE_IMAGE);
|
|
|
|
|
+const phenologyQuestion = ref("");
|
|
|
|
|
+const phenologyHighlight = ref("");
|
|
|
|
|
+const phenologyImage = ref(DEFAULT_PHENOLOGY_IMAGE);
|
|
|
|
|
+
|
|
|
|
|
+// ---------------------------------------------------------------------------
|
|
|
|
|
+// 计算属性
|
|
|
|
|
+// ---------------------------------------------------------------------------
|
|
|
const phenologyOptions = computed(() => [
|
|
const phenologyOptions = computed(() => [
|
|
|
{ value: "not_reached", label: t("agriFile.notReached") },
|
|
{ value: "not_reached", label: t("agriFile.notReached") },
|
|
|
{ value: "reached", label: t("agriFile.reached") },
|
|
{ value: "reached", label: t("agriFile.reached") },
|
|
|
{ value: "passed", label: t("agriFile.passed") },
|
|
{ value: "passed", label: t("agriFile.passed") },
|
|
|
]);
|
|
]);
|
|
|
|
|
|
|
|
|
|
+const interactKeys = computed(() =>
|
|
|
|
|
+ Object.keys(interactMap.value).sort((a, b) => Number(a) - Number(b))
|
|
|
|
|
+);
|
|
|
|
|
+
|
|
|
|
|
+// ---------------------------------------------------------------------------
|
|
|
|
|
+// 工具函数
|
|
|
|
|
+// ---------------------------------------------------------------------------
|
|
|
|
|
+/** 当天日期 YYYY-MM-DD */
|
|
|
|
|
+const formatToday = () => {
|
|
|
|
|
+ const d = new Date();
|
|
|
|
|
+ const y = d.getFullYear();
|
|
|
|
|
+ const m = String(d.getMonth() + 1).padStart(2, "0");
|
|
|
|
|
+ const day = String(d.getDate()).padStart(2, "0");
|
|
|
|
|
+ return `${y}-${m}-${day}`;
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+/** 日期选择器 YYYY.MM.DD → 接口 YYYY-MM-DD */
|
|
|
|
|
+const toApiDate = (value) => (value ? String(value).replace(/\./g, "-") : "");
|
|
|
|
|
+
|
|
|
|
|
+/** 拼接 CDN 图片地址 */
|
|
|
|
|
+const resolveImageUrl = (path) => {
|
|
|
|
|
+ if (!path) return "";
|
|
|
|
|
+ if (/^https?:\/\//i.test(path)) return path;
|
|
|
|
|
+ return base_img_url2 + String(path).replace(/^\//, "");
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+/** 从 interact_theme 引号中提取高亮词,如「来梢」 */
|
|
|
|
|
+const extractHighlightWord = (text) => {
|
|
|
|
|
+ if (!text) return "";
|
|
|
|
|
+ const match = String(text).match(/[“"「]([^”"」]+)[”"」]/);
|
|
|
|
|
+ return match ? match[1] : "";
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+/** Message 需高于弹窗 z-index: 20000 */
|
|
|
|
|
+const showMessage = (message, type = "warning") => {
|
|
|
|
|
+ ElMessage({
|
|
|
|
|
+ message,
|
|
|
|
|
+ type,
|
|
|
|
|
+ customClass: "restore-planting-message",
|
|
|
|
|
+ zIndex: 40000,
|
|
|
|
|
+ });
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+const showWarning = (message) => showMessage(message, "warning");
|
|
|
|
|
+
|
|
|
const resetForm = () => {
|
|
const resetForm = () => {
|
|
|
- questionType.value = "time";
|
|
|
|
|
|
|
+ questionType.value = hasDateInteract.value ? "time" : "phenology";
|
|
|
selectedDate.value = "";
|
|
selectedDate.value = "";
|
|
|
- phenologyAnswer.value = "reached";
|
|
|
|
|
|
|
+ phenologyAnswer.value = "";
|
|
|
|
|
+ selectedPeriodCode.value = "";
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// ---------------------------------------------------------------------------
|
|
|
|
|
+// 业务逻辑:填充问题 / 物候期切换
|
|
|
|
|
+// ---------------------------------------------------------------------------
|
|
|
|
|
+const applyDateInteract = (data) => {
|
|
|
|
|
+ dateInteractData.value = data;
|
|
|
|
|
+ questionText.value = data.interact_theme || "";
|
|
|
|
|
+ highlightWord.value = extractHighlightWord(data.interact_theme);
|
|
|
|
|
+ hintText.value = data.interact_reason || "";
|
|
|
|
|
+ sampleImage.value = resolveImageUrl(data.guide_url) || DEFAULT_SAMPLE_IMAGE;
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+/** 按 interact key 刷新问题二文案与配图 */
|
|
|
|
|
+const applyPhenologyByKey = (key) => {
|
|
|
|
|
+ const item = interactMap.value[key];
|
|
|
|
|
+ if (!item) return;
|
|
|
|
|
+ currentInteractKey.value = String(key);
|
|
|
|
|
+ const name = item.period_name || "";
|
|
|
|
|
+ phenologyHighlight.value = name;
|
|
|
|
|
+ phenologyQuestion.value = `${PHENOLOGY_PREFIX}${name} ?`;
|
|
|
|
|
+ phenologyImage.value = resolveImageUrl(item.url) || DEFAULT_PHENOLOGY_IMAGE;
|
|
|
|
|
+ selectedPeriodCode.value = "";
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+/** 暂未到达 → 前一个;已过 → 后一个 */
|
|
|
|
|
+const movePhenology = (direction) => {
|
|
|
|
|
+ const keys = interactKeys.value;
|
|
|
|
|
+ const idx = keys.indexOf(String(currentInteractKey.value));
|
|
|
|
|
+ if (idx < 0) return false;
|
|
|
|
|
+ const nextIdx = direction === "prev" ? idx - 1 : idx + 1;
|
|
|
|
|
+ if (nextIdx < 0 || nextIdx >= keys.length) {
|
|
|
|
|
+ showWarning(direction === "prev" ? "已是最早物候期" : "已是最晚物候期");
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ applyPhenologyByKey(keys[nextIdx]);
|
|
|
|
|
+ phenologyAnswer.value = "";
|
|
|
|
|
+ return true;
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+const applyQuestionData = (data) => {
|
|
|
|
|
+ hasDateInteract.value = !!data?.date_interact;
|
|
|
|
|
+ hasOptionsInteract.value = !!data?.options_interact?.interact;
|
|
|
|
|
+
|
|
|
|
|
+ if (hasDateInteract.value) {
|
|
|
|
|
+ applyDateInteract(data.date_interact);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (hasOptionsInteract.value) {
|
|
|
|
|
+ interactMap.value = data.options_interact.interact || {};
|
|
|
|
|
+ const startKey = String(data.options_interact.start_with ?? interactKeys.value[0] ?? "");
|
|
|
|
|
+ applyPhenologyByKey(startKey);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 有时间题优先展示;仅物候题则直接进入问题二
|
|
|
|
|
+ questionType.value = hasDateInteract.value ? "time" : "phenology";
|
|
|
|
|
+ visible.value = hasDateInteract.value || hasOptionsInteract.value;
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
/** 请求接口判断是否展示,并填充问题内容 */
|
|
/** 请求接口判断是否展示,并填充问题内容 */
|
|
|
const checkShouldShow = async () => {
|
|
const checkShouldShow = async () => {
|
|
|
try {
|
|
try {
|
|
|
- // TODO: 对接恢复种植服务弹窗展示接口
|
|
|
|
|
- // const res = await xxxApi();
|
|
|
|
|
- // visible.value = !!res?.needShow;
|
|
|
|
|
- // if (res?.needShow) applyQuestionData(res);
|
|
|
|
|
- visible.value = false;
|
|
|
|
|
|
|
+ const res = await VE_API.questionnaire.getInitialInteraction({
|
|
|
|
|
+ zone_id: props.zoneId,
|
|
|
|
|
+ date: formatToday(),
|
|
|
|
|
+ // date: '2025-07-10',
|
|
|
|
|
+ });
|
|
|
|
|
+ if (res?.code === 200 && res.data) {
|
|
|
|
|
+ applyQuestionData(res.data);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ visible.value = false;
|
|
|
|
|
+ }
|
|
|
} catch (e) {
|
|
} catch (e) {
|
|
|
visible.value = false;
|
|
visible.value = false;
|
|
|
}
|
|
}
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
+// ---------------------------------------------------------------------------
|
|
|
|
|
+// 事件处理 / 生命周期
|
|
|
|
|
+// ---------------------------------------------------------------------------
|
|
|
onMounted(() => {
|
|
onMounted(() => {
|
|
|
checkShouldShow();
|
|
checkShouldShow();
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
-const handleChangeQuestion = () => {
|
|
|
|
|
- questionType.value = questionType.value === "time" ? "phenology" : "time";
|
|
|
|
|
|
|
+/**
|
|
|
|
|
+ * 暂未到达 / 已过:立刻切到相邻物候期;
|
|
|
|
|
+ * 已到达:选中并记下当前 period_code,供提交使用
|
|
|
|
|
+ */
|
|
|
|
|
+const handlePhenologySelect = (value) => {
|
|
|
|
|
+ if (value === "not_reached") {
|
|
|
|
|
+ movePhenology("prev");
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (value === "passed") {
|
|
|
|
|
+ movePhenology("next");
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ phenologyAnswer.value = "reached";
|
|
|
|
|
+ const current = interactMap.value[currentInteractKey.value];
|
|
|
|
|
+ selectedPeriodCode.value = current?.period_code || "";
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * 组装保存感知结果载荷
|
|
|
|
|
+ * @param {'time'|'phenology'} type 问题一不含 period_code;问题二不含 interact_code
|
|
|
|
|
+ */
|
|
|
|
|
+const buildSubmitPayload = (type = "time") => {
|
|
|
|
|
+ const payload = {
|
|
|
|
|
+ zone_id: Number(props.zoneId) || props.zoneId,
|
|
|
|
|
+ date: toApiDate(selectedDate.value) || formatToday(),
|
|
|
|
|
+ };
|
|
|
|
|
+ if (type === "time") {
|
|
|
|
|
+ payload.interact_code = dateInteractData.value?.interact_code || "";
|
|
|
|
|
+ } else {
|
|
|
|
|
+ payload.period_code = selectedPeriodCode.value || "";
|
|
|
|
|
+ }
|
|
|
|
|
+ return payload;
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+/** 从 axios 错误中取出可读信息 */
|
|
|
|
|
+const getRequestErrorMessage = (err) => {
|
|
|
|
|
+ const data = err?.response?.data;
|
|
|
|
|
+ if (typeof data === "string" && data) return data;
|
|
|
|
|
+ if (data?.msg) return data.msg;
|
|
|
|
|
+ if (data?.message) return data.message;
|
|
|
|
|
+ if (err?.message) return err.message;
|
|
|
|
|
+ return "提交失败,请稍后再试";
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
-const handleViewGuide = () => {
|
|
|
|
|
- // TODO: 跳转巡园向导
|
|
|
|
|
|
|
+/**
|
|
|
|
|
+ * 调用保存感知结果接口
|
|
|
|
|
+ * @param {'time'|'phenology'} type
|
|
|
|
|
+ * @param {{ closeOnSuccess?: boolean }} options closeOnSuccess=false 时成功后不关弹窗(用于继续答问题二)
|
|
|
|
|
+ */
|
|
|
|
|
+const submitInteractResult = async (type = "time", { closeOnSuccess = true } = {}) => {
|
|
|
|
|
+ if (submitting.value) return false;
|
|
|
|
|
+ submitting.value = true;
|
|
|
|
|
+ try {
|
|
|
|
|
+ const res = await VE_API.questionnaire.saveInteractResult(buildSubmitPayload(type));
|
|
|
|
|
+ if (res?.code === 200) {
|
|
|
|
|
+ if (closeOnSuccess) {
|
|
|
|
|
+ showMessage(res.msg || "提交成功", "success");
|
|
|
|
|
+ visible.value = false;
|
|
|
|
|
+ resetForm();
|
|
|
|
|
+ }
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+ showMessage(res?.msg || "提交失败,请稍后再试", "error");
|
|
|
|
|
+ return false;
|
|
|
|
|
+ } catch (err) {
|
|
|
|
|
+ showMessage(getRequestErrorMessage(err), "error");
|
|
|
|
|
+ return false;
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ submitting.value = false;
|
|
|
|
|
+ }
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
const handleConfirm = async () => {
|
|
const handleConfirm = async () => {
|
|
|
- // TODO: 对接提交接口
|
|
|
|
|
- visible.value = false;
|
|
|
|
|
- resetForm();
|
|
|
|
|
|
|
+ if (submitting.value) return;
|
|
|
|
|
+
|
|
|
|
|
+ // 问题一:立即确认 → 提交(不含 period_code)
|
|
|
|
|
+ if (questionType.value === "time") {
|
|
|
|
|
+ if (!selectedDate.value) {
|
|
|
|
|
+ showWarning(t("agriFile.selectTime"));
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ const ok = await submitInteractResult("time", {
|
|
|
|
|
+ // 还有问题二则提交成功后继续展示,不关弹窗
|
|
|
|
|
+ closeOnSuccess: !hasOptionsInteract.value,
|
|
|
|
|
+ });
|
|
|
|
|
+ if (ok && hasOptionsInteract.value) {
|
|
|
|
|
+ questionType.value = "phenology";
|
|
|
|
|
+ }
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 问题二:需已选择「已到达」并写入 period_code;提交不含 interact_code
|
|
|
|
|
+ if (phenologyAnswer.value !== "reached" || !selectedPeriodCode.value) {
|
|
|
|
|
+ const current = interactMap.value[currentInteractKey.value];
|
|
|
|
|
+ if (phenologyAnswer.value === "reached" && current?.period_code) {
|
|
|
|
|
+ selectedPeriodCode.value = current.period_code;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ showWarning("请确认当前物候期是否已到达");
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ await submitInteractResult("phenology");
|
|
|
};
|
|
};
|
|
|
|
|
+
|
|
|
|
|
+defineExpose({
|
|
|
|
|
+ checkShouldShow,
|
|
|
|
|
+ buildSubmitPayload,
|
|
|
|
|
+ selectedPeriodCode,
|
|
|
|
|
+});
|
|
|
</script>
|
|
</script>
|
|
|
|
|
|
|
|
<style scoped lang="scss">
|
|
<style scoped lang="scss">
|
|
@@ -174,15 +423,11 @@ const handleConfirm = async () => {
|
|
|
box-sizing: border-box;
|
|
box-sizing: border-box;
|
|
|
background: linear-gradient(180deg, #d7ecff 0%, #ffffff 28%);
|
|
background: linear-gradient(180deg, #d7ecff 0%, #ffffff 28%);
|
|
|
overflow: visible;
|
|
overflow: visible;
|
|
|
-
|
|
|
|
|
|
|
|
|
|
&__header {
|
|
&__header {
|
|
|
- // position: relative;
|
|
|
|
|
display: flex;
|
|
display: flex;
|
|
|
align-items: flex-start;
|
|
align-items: flex-start;
|
|
|
justify-content: space-between;
|
|
justify-content: space-between;
|
|
|
- // padding-right: 72px;
|
|
|
|
|
- // min-height: 64px;
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
&__title {
|
|
&__title {
|
|
@@ -219,7 +464,7 @@ const handleConfirm = async () => {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
&__question {
|
|
&__question {
|
|
|
- font-size: 16px;
|
|
|
|
|
|
|
+ font-size: 15px;
|
|
|
line-height: 24px;
|
|
line-height: 24px;
|
|
|
color: #252525;
|
|
color: #252525;
|
|
|
font-weight: 500;
|
|
font-weight: 500;
|
|
@@ -233,7 +478,7 @@ const handleConfirm = async () => {
|
|
|
margin-top: 4px;
|
|
margin-top: 4px;
|
|
|
font-size: 12px;
|
|
font-size: 12px;
|
|
|
line-height: 16px;
|
|
line-height: 16px;
|
|
|
- color: #9E9E9E;
|
|
|
|
|
|
|
+ color: #9e9e9e;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
&__photo {
|
|
&__photo {
|
|
@@ -255,43 +500,6 @@ const handleConfirm = async () => {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- &__bbox {
|
|
|
|
|
- position: absolute;
|
|
|
|
|
- top: 36%;
|
|
|
|
|
- left: 50%;
|
|
|
|
|
- width: 72px;
|
|
|
|
|
- height: 72px;
|
|
|
|
|
- transform: translate(-50%, -50%);
|
|
|
|
|
- border: 2px solid #2199f8;
|
|
|
|
|
- box-sizing: border-box;
|
|
|
|
|
- pointer-events: none;
|
|
|
|
|
-
|
|
|
|
|
- span {
|
|
|
|
|
- position: absolute;
|
|
|
|
|
- top: -18px;
|
|
|
|
|
- left: 50%;
|
|
|
|
|
- transform: translateX(-50%);
|
|
|
|
|
- padding: 0 4px;
|
|
|
|
|
- font-size: 12px;
|
|
|
|
|
- line-height: 16px;
|
|
|
|
|
- color: #2199f8;
|
|
|
|
|
- white-space: nowrap;
|
|
|
|
|
- background: rgba(255, 255, 255, 0.85);
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- &__detect {
|
|
|
|
|
- position: absolute;
|
|
|
|
|
- left: 0;
|
|
|
|
|
- right: 0;
|
|
|
|
|
- bottom: 0;
|
|
|
|
|
- padding: 8px 10px;
|
|
|
|
|
- background: rgba(0, 0, 0, 0.55);
|
|
|
|
|
- color: #fff;
|
|
|
|
|
- font-size: 12px;
|
|
|
|
|
- line-height: 18px;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
&__guide-btn {
|
|
&__guide-btn {
|
|
|
position: absolute;
|
|
position: absolute;
|
|
|
top: 8px;
|
|
top: 8px;
|
|
@@ -374,8 +582,7 @@ const handleConfirm = async () => {
|
|
|
margin-top: 12px;
|
|
margin-top: 12px;
|
|
|
display: flex;
|
|
display: flex;
|
|
|
align-items: center;
|
|
align-items: center;
|
|
|
- justify-content: space-between;
|
|
|
|
|
- gap: 12px;
|
|
|
|
|
|
|
+ justify-content: center;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
&__btn {
|
|
&__btn {
|
|
@@ -390,15 +597,31 @@ const handleConfirm = async () => {
|
|
|
font-weight: 500;
|
|
font-weight: 500;
|
|
|
box-sizing: border-box;
|
|
box-sizing: border-box;
|
|
|
|
|
|
|
|
- &--ghost {
|
|
|
|
|
- background: rgba(236, 236, 236, 0.5);
|
|
|
|
|
- color: rgba(0, 0, 0, 0.6);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
&--primary {
|
|
&--primary {
|
|
|
- background: linear-gradient(180deg, #76C3FF 0%, #2199F8 100%);
|
|
|
|
|
|
|
+ // flex: 1;
|
|
|
|
|
+ background: linear-gradient(180deg, #76c3ff 0%, #2199f8 100%);
|
|
|
color: #fff;
|
|
color: #fff;
|
|
|
|
|
+
|
|
|
|
|
+ &.disabled {
|
|
|
|
|
+ opacity: 0.6;
|
|
|
|
|
+ pointer-events: none;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
</style>
|
|
</style>
|
|
|
|
|
+
|
|
|
|
|
+<!-- 日期面板 / 图片预览 / Message teleport 到 body,需高于弹窗 z-index: 20000 -->
|
|
|
|
|
+<style lang="scss">
|
|
|
|
|
+.restore-planting-date-popper {
|
|
|
|
|
+ z-index: 30000 !important;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.PhotoSlider__Wrapper {
|
|
|
|
|
+ z-index: 30001 !important;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.el-message.restore-planting-message {
|
|
|
|
|
+ z-index: 40000 !important;
|
|
|
|
|
+}
|
|
|
|
|
+</style>
|