|
|
@@ -93,6 +93,7 @@ import surveyAskPopup from "@/components/popup/surveyAskPopup.vue";
|
|
|
import diagnosisReportPopup from "@/components/popup/diagnosisReportPopup.vue";
|
|
|
import restorePlantingPopup from "@/components/popup/restorePlantingPopup.vue";
|
|
|
import { useI18n } from "@/i18n";
|
|
|
+import { saveSelectedFarm } from "@/utils/selectedFarm";
|
|
|
import wx from "weixin-js-sdk";
|
|
|
|
|
|
|
|
|
@@ -182,12 +183,25 @@ const pendingCount = computed(() => dayTaskList.value.filter((item) => item.stat
|
|
|
const completedCount = computed(() => dayTaskList.value.filter((item) => item.status === "completed").length);
|
|
|
const displayTaskList = computed(() => dayTaskList.value.filter((item) => item.status === activeTab.value));
|
|
|
|
|
|
-/** zone_id / farm_id / crop_type 取当前选中农场,trigger_date 取日历选中日 */
|
|
|
-const resolveQueryParams = () => {
|
|
|
+/** 日历窗口:今天起连续 7 天 */
|
|
|
+function getCalendarDateRange() {
|
|
|
+ const start = new Date();
|
|
|
+ return Array.from({ length: 7 }, (_, i) => {
|
|
|
+ const d = new Date(start);
|
|
|
+ d.setDate(start.getDate() + i);
|
|
|
+ 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}`;
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
+/** zone_id / farm_id / crop_type 取当前选中农场;trigger_date 为窗口内某一天 */
|
|
|
+const resolveQueryParams = (triggerDate = getTodayDate()) => {
|
|
|
const params = {
|
|
|
zone_id: getSelectedZoneId(),
|
|
|
farm_id: getSelectedFarmId(),
|
|
|
- trigger_date: filterDate.value || getTodayDate(),
|
|
|
+ trigger_date: triggerDate,
|
|
|
};
|
|
|
const cropType = getSelectedCropType();
|
|
|
if (cropType) params.crop_type = cropType;
|
|
|
@@ -311,36 +325,77 @@ async function checkFarmCalendarPopup() {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+/** 无选中农场时写入列表首项,保证 zone_fw_task_list 有 farm_id */
|
|
|
+async function ensureSelectedFarm() {
|
|
|
+ if (getSelectedFarmId() != null) return true;
|
|
|
+ const id = getMiniUserId();
|
|
|
+ if (!id) return false;
|
|
|
+ try {
|
|
|
+ const res = await VE_API.questionnaire.getFarms({ id });
|
|
|
+ const list = Array.isArray(res?.data) ? res.data : [];
|
|
|
+ return list[0] ? saveSelectedFarm(list[0]) : false;
|
|
|
+ } catch (e) {
|
|
|
+ console.warn("[work_execute] ensureSelectedFarm failed", e);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
const refreshMapMarkers = () => {
|
|
|
if (!indexMap.kmap) return;
|
|
|
indexMap.initData(getMapMarkerList(), "farmName", "wkt");
|
|
|
};
|
|
|
|
|
|
-/** 地图展示全部日期的待执行农事 */
|
|
|
+/** 与日历一致:展示 7 天窗口内全部待执行农事(列表仍按选中日过滤) */
|
|
|
const getMapMarkerList = () =>
|
|
|
taskList.value.filter((item) => item.status === "pending" && item.wkt);
|
|
|
|
|
|
+/**
|
|
|
+ * 按日历 7 天逐日请求后合并(接口按 trigger_date 返回当日任务)。
|
|
|
+ * 切换日期只本地过滤列表,地图仍用完整 7 天点位。
|
|
|
+ */
|
|
|
const fetchZoneFwTaskList = async () => {
|
|
|
try {
|
|
|
- const params = resolveQueryParams();
|
|
|
- const res = await VE_API.questionnaire.getZoneFwTaskList(params);
|
|
|
- const data = res?.data;
|
|
|
- if (!data) {
|
|
|
- taskList.value = [];
|
|
|
- mapCenterPoint.value = null;
|
|
|
+ const dates = getCalendarDateRange();
|
|
|
+ const settled = await Promise.all(
|
|
|
+ dates.map((triggerDate) =>
|
|
|
+ VE_API.questionnaire
|
|
|
+ .getZoneFwTaskList(resolveQueryParams(triggerDate))
|
|
|
+ .then((res) => ({ triggerDate, data: res?.data || null }))
|
|
|
+ .catch((e) => {
|
|
|
+ console.warn("[work_execute] zone_fw_task_list failed", triggerDate, e);
|
|
|
+ return { triggerDate, data: null };
|
|
|
+ })
|
|
|
+ )
|
|
|
+ );
|
|
|
+ const merged = [];
|
|
|
+ const seen = new Set();
|
|
|
+ let lat = null;
|
|
|
+ let lng = null;
|
|
|
+ for (const { triggerDate, data } of settled) {
|
|
|
+ if (!data) continue;
|
|
|
+ const mapped = mapZoneTaskList(data, triggerDate);
|
|
|
+ if (lat == null && mapped.lat != null) lat = mapped.lat;
|
|
|
+ if (lng == null && mapped.lng != null) lng = mapped.lng;
|
|
|
+ for (const item of mapped.list) {
|
|
|
+ if (seen.has(item.id)) continue;
|
|
|
+ seen.add(item.id);
|
|
|
+ merged.push(item);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ mapCenterPoint.value =
|
|
|
+ lat != null && lng != null ? `POINT(${lng} ${lat})` : null;
|
|
|
+ taskList.value = merged;
|
|
|
+ if (!merged.length) {
|
|
|
calendarRef.value?.selectDateByValue?.(filterDate.value);
|
|
|
calendarRef.value?.setSolarTerm?.([]);
|
|
|
- refreshMapMarkers();
|
|
|
- return;
|
|
|
+ } else {
|
|
|
+ syncCalendar();
|
|
|
}
|
|
|
- const { list, lat, lng } = mapZoneTaskList(data, params.trigger_date);
|
|
|
- mapCenterPoint.value = `POINT(${lng} ${lat})`;
|
|
|
- taskList.value = list;
|
|
|
- syncCalendar();
|
|
|
nextTick(() => refreshMapMarkers());
|
|
|
} catch (e) {
|
|
|
console.error("获取农事任务失败", e);
|
|
|
taskList.value = [];
|
|
|
+ refreshMapMarkers();
|
|
|
}
|
|
|
};
|
|
|
|
|
|
@@ -350,11 +405,11 @@ const handleTabChange = (key) => {
|
|
|
activeTab.value = key;
|
|
|
};
|
|
|
|
|
|
+/** 切日期:只过滤下方列表;地图与日历角标共用完整 7 天数据 */
|
|
|
const handleDateSelect = (date) => {
|
|
|
const next = date ?? getTodayDate();
|
|
|
if (filterDate.value === next) return;
|
|
|
filterDate.value = next;
|
|
|
- fetchZoneFwTaskList();
|
|
|
};
|
|
|
|
|
|
const handleForward = (item) => {
|
|
|
@@ -459,36 +514,43 @@ const initMap = () => {
|
|
|
refreshMapMarkers();
|
|
|
};
|
|
|
|
|
|
+/** keep-alive 下切农场 / 再次进入只走 onActivated,需在此拉列表 */
|
|
|
+const refreshPage = async () => {
|
|
|
+ await ensureSelectedFarm();
|
|
|
+ // 无农场时不打任务列表(弹窗由 checkFarmCalendarPopup 负责)
|
|
|
+ if (getSelectedFarmId() == null) {
|
|
|
+ taskList.value = [];
|
|
|
+ if (!indexMap.kmap) initMap();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ await fetchZoneFwTaskList();
|
|
|
+ if (!indexMap.kmap) {
|
|
|
+ initMap();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (!mapContainer.value || !indexMap.kmap.map) return;
|
|
|
+ const checkAndUpdateSize = () => {
|
|
|
+ const container = mapContainer.value;
|
|
|
+ if (!container) return;
|
|
|
+ const rect = container.getBoundingClientRect();
|
|
|
+ if (rect.width > 0 && rect.height > 0) {
|
|
|
+ indexMap.kmap.map.updateSize();
|
|
|
+ refreshMapMarkers();
|
|
|
+ } else {
|
|
|
+ setTimeout(checkAndUpdateSize, 100);
|
|
|
+ }
|
|
|
+ };
|
|
|
+ setTimeout(checkAndUpdateSize, 200);
|
|
|
+};
|
|
|
+
|
|
|
onMounted(() => {
|
|
|
checkFarmCalendarPopup();
|
|
|
- nextTick(async () => {
|
|
|
- await fetchZoneFwTaskList();
|
|
|
- initMap();
|
|
|
- });
|
|
|
+ nextTick(refreshPage);
|
|
|
});
|
|
|
|
|
|
onActivated(() => {
|
|
|
checkFarmCalendarPopup();
|
|
|
- nextTick(() => {
|
|
|
- if (!indexMap.kmap) {
|
|
|
- initMap();
|
|
|
- return;
|
|
|
- }
|
|
|
- if (mapContainer.value && indexMap.kmap.map) {
|
|
|
- const checkAndUpdateSize = () => {
|
|
|
- const container = mapContainer.value;
|
|
|
- if (!container) return;
|
|
|
- const rect = container.getBoundingClientRect();
|
|
|
- if (rect.width > 0 && rect.height > 0) {
|
|
|
- indexMap.kmap.map.updateSize();
|
|
|
- refreshMapMarkers();
|
|
|
- } else {
|
|
|
- setTimeout(checkAndUpdateSize, 100);
|
|
|
- }
|
|
|
- };
|
|
|
- setTimeout(checkAndUpdateSize, 200);
|
|
|
- }
|
|
|
- });
|
|
|
+ nextTick(refreshPage);
|
|
|
});
|
|
|
onDeactivated(() => {
|
|
|
showFarmCalendarPopup.value = false;
|