|
@@ -45,6 +45,7 @@
|
|
|
:weather-stress="weatherStress"
|
|
:weather-stress="weatherStress"
|
|
|
:weather-risk-explain="weatherRiskExplain"
|
|
:weather-risk-explain="weatherRiskExplain"
|
|
|
:weather-stress-explain="weatherStressExplain"
|
|
:weather-stress-explain="weatherStressExplain"
|
|
|
|
|
+ :report-generating="reportGenerating"
|
|
|
@switch-category="handleSwitchCategory"
|
|
@switch-category="handleSwitchCategory"
|
|
|
@view-detail="handleViewDetail"
|
|
@view-detail="handleViewDetail"
|
|
|
@patrol-tip="handlePatrolTip"
|
|
@patrol-tip="handlePatrolTip"
|
|
@@ -64,7 +65,7 @@
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
|
<script setup>
|
|
<script setup>
|
|
|
-import { computed, nextTick, onActivated, onMounted, ref } from "vue";
|
|
|
|
|
|
|
+import { computed, nextTick, onActivated, onBeforeUnmount, onDeactivated, onMounted, ref } from "vue";
|
|
|
import { useRoute, useRouter } from "vue-router";
|
|
import { useRoute, useRouter } from "vue-router";
|
|
|
import { useStore } from "vuex";
|
|
import { useStore } from "vuex";
|
|
|
import { Close, LocationFilled } from "@element-plus/icons-vue";
|
|
import { Close, LocationFilled } from "@element-plus/icons-vue";
|
|
@@ -131,6 +132,8 @@ const weatherStress = ref(entryFarmData?.weatherStress || "某某胁迫");
|
|
|
const weatherRiskExplain = ref("");
|
|
const weatherRiskExplain = ref("");
|
|
|
/** 当下胁迫正文:stress_report.explain_simple */
|
|
/** 当下胁迫正文:stress_report.explain_simple */
|
|
|
const weatherStressExplain = ref("");
|
|
const weatherStressExplain = ref("");
|
|
|
|
|
+/** stress_report 为空时,气象报告生成中 */
|
|
|
|
|
+const reportGenerating = ref(false);
|
|
|
const activeMenuKey = ref("hot-drought-2");
|
|
const activeMenuKey = ref("hot-drought-2");
|
|
|
const panelHeight = ref(280);
|
|
const panelHeight = ref(280);
|
|
|
const inviteBottom = computed(() => panelHeight.value);
|
|
const inviteBottom = computed(() => panelHeight.value);
|
|
@@ -139,6 +142,9 @@ const invitePopupRef = ref(null);
|
|
|
const showInteractCard = ref(false);
|
|
const showInteractCard = ref(false);
|
|
|
const interactQuestionText = ref("");
|
|
const interactQuestionText = ref("");
|
|
|
|
|
|
|
|
|
|
+const CHECK_REPORT_INTERVAL_MS = 3000;
|
|
|
|
|
+let checkWeatherReportTimer = null;
|
|
|
|
|
+
|
|
|
function resolveUserTel() {
|
|
function resolveUserTel() {
|
|
|
const entry = readEntryFarmData();
|
|
const entry = readEntryFarmData();
|
|
|
if (entry?.phone) return String(entry.phone).trim();
|
|
if (entry?.phone) return String(entry.phone).trim();
|
|
@@ -150,9 +156,55 @@ function resolveUserTel() {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+function stopCheckWeatherReport() {
|
|
|
|
|
+ if (checkWeatherReportTimer) {
|
|
|
|
|
+ clearTimeout(checkWeatherReportTimer);
|
|
|
|
|
+ checkWeatherReportTimer = null;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/** stress 为空时轮询 check_stress_report,status=1 后再拉 risk */
|
|
|
|
|
+async function pollWeatherReportGenerated() {
|
|
|
|
|
+ const tel = resolveUserTel();
|
|
|
|
|
+ if (!tel) {
|
|
|
|
|
+ reportGenerating.value = false;
|
|
|
|
|
+ stopCheckWeatherReport();
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ try {
|
|
|
|
|
+ const raw = await VE_API.questionnaire.checkWeatherReportGenerated({ tel });
|
|
|
|
|
+ const res = Array.isArray(raw) ? raw[0] : raw;
|
|
|
|
|
+ const status = Number(res?.data?.status);
|
|
|
|
|
+ if (status === 0) {
|
|
|
|
|
+ reportGenerating.value = true;
|
|
|
|
|
+ stopCheckWeatherReport();
|
|
|
|
|
+ checkWeatherReportTimer = setTimeout(pollWeatherReportGenerated, CHECK_REPORT_INTERVAL_MS);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (status === 1) {
|
|
|
|
|
+ stopCheckWeatherReport();
|
|
|
|
|
+ reportGenerating.value = false;
|
|
|
|
|
+ await fetchRiskReport();
|
|
|
|
|
+ // 生成完成后补拉胁迫正文(避免仍显示空)
|
|
|
|
|
+ await fetchStressReportAfterReady(tel);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ reportGenerating.value = false;
|
|
|
|
|
+ stopCheckWeatherReport();
|
|
|
|
|
+ } catch {
|
|
|
|
|
+ reportGenerating.value = false;
|
|
|
|
|
+ stopCheckWeatherReport();
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+function startCheckWeatherReport() {
|
|
|
|
|
+ reportGenerating.value = true;
|
|
|
|
|
+ stopCheckWeatherReport();
|
|
|
|
|
+ pollWeatherReportGenerated();
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
/** 未来预警卡片:risk_report → explain_simple */
|
|
/** 未来预警卡片:risk_report → explain_simple */
|
|
|
async function fetchRiskReport() {
|
|
async function fetchRiskReport() {
|
|
|
- // TODO: 接口有正式数据后改回 resolveUserTel()
|
|
|
|
|
const tel = resolveUserTel();
|
|
const tel = resolveUserTel();
|
|
|
if (!tel) {
|
|
if (!tel) {
|
|
|
weatherRiskExplain.value = "";
|
|
weatherRiskExplain.value = "";
|
|
@@ -174,12 +226,13 @@ async function fetchRiskReport() {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-/** 当下胁迫卡片:stress_report → explain_simple */
|
|
|
|
|
|
|
+/** 当下胁迫卡片:stress_report → explain_simple;空数组则轮询是否生成中 */
|
|
|
async function fetchStressReport() {
|
|
async function fetchStressReport() {
|
|
|
- // TODO: 接口有正式数据后改回 resolveUserTel()
|
|
|
|
|
const tel = resolveUserTel();
|
|
const tel = resolveUserTel();
|
|
|
if (!tel) {
|
|
if (!tel) {
|
|
|
weatherStressExplain.value = "";
|
|
weatherStressExplain.value = "";
|
|
|
|
|
+ reportGenerating.value = false;
|
|
|
|
|
+ stopCheckWeatherReport();
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
try {
|
|
try {
|
|
@@ -190,6 +243,32 @@ async function fetchStressReport() {
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
const data = res.data;
|
|
const data = res.data;
|
|
|
|
|
+ // 报告尚未落库:空数组 → 查生成状态
|
|
|
|
|
+ if (Array.isArray(data) && data.length === 0) {
|
|
|
|
|
+ weatherStressExplain.value = "";
|
|
|
|
|
+ startCheckWeatherReport();
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ stopCheckWeatherReport();
|
|
|
|
|
+ reportGenerating.value = false;
|
|
|
|
|
+ const item = Array.isArray(data) ? data[0] : data;
|
|
|
|
|
+ weatherStressExplain.value =
|
|
|
|
|
+ item?.explain_simple || item?.interact_explain || "";
|
|
|
|
|
+ } catch {
|
|
|
|
|
+ weatherStressExplain.value = "";
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/** 生成完成后只取正文,不再触发轮询 */
|
|
|
|
|
+async function fetchStressReportAfterReady(tel) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const raw = await VE_API.questionnaire.stressReport({ tel });
|
|
|
|
|
+ const res = Array.isArray(raw) ? raw[0] : raw;
|
|
|
|
|
+ if (Number(res?.code) !== 200 || !res.data) {
|
|
|
|
|
+ weatherStressExplain.value = "";
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ const data = res.data;
|
|
|
const item = Array.isArray(data) ? data[0] : data;
|
|
const item = Array.isArray(data) ? data[0] : data;
|
|
|
weatherStressExplain.value =
|
|
weatherStressExplain.value =
|
|
|
item?.explain_simple || item?.interact_explain || "";
|
|
item?.explain_simple || item?.interact_explain || "";
|
|
@@ -456,8 +535,6 @@ onMounted(() => {
|
|
|
initMap();
|
|
initMap();
|
|
|
tryOpenInviteEntryPopup();
|
|
tryOpenInviteEntryPopup();
|
|
|
fetchAbnormalContent();
|
|
fetchAbnormalContent();
|
|
|
- fetchRiskReport();
|
|
|
|
|
- fetchStressReport();
|
|
|
|
|
});
|
|
});
|
|
|
onActivated(() => {
|
|
onActivated(() => {
|
|
|
syncEntryFarmData();
|
|
syncEntryFarmData();
|
|
@@ -469,6 +546,12 @@ onActivated(() => {
|
|
|
fetchRiskReport();
|
|
fetchRiskReport();
|
|
|
fetchStressReport();
|
|
fetchStressReport();
|
|
|
});
|
|
});
|
|
|
|
|
+onDeactivated(() => {
|
|
|
|
|
+ stopCheckWeatherReport();
|
|
|
|
|
+});
|
|
|
|
|
+onBeforeUnmount(() => {
|
|
|
|
|
+ stopCheckWeatherReport();
|
|
|
|
|
+});
|
|
|
</script>
|
|
</script>
|
|
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
<style lang="scss" scoped>
|