wangsisi 6 часов назад
Родитель
Сommit
ddef4951c4

+ 88 - 16
src/components/pageComponents/ArchivesFarmTimeLine.vue

@@ -27,8 +27,8 @@
                                             aIdx === r.farmWorkArrangeList.length - 1 &&
                                             aIdx === r.farmWorkArrangeList.length - 1 &&
                                             rIdx !== r.farmWorkArrangeList.length - 1,
                                             rIdx !== r.farmWorkArrangeList.length - 1,
                                     },
                                     },
-                                    // 右侧农事卡片跟随物候期颜色:未来节气对应的农事卡片置灰
-                                    { 'future-card': !shouldShowBlue(p) },
+                                    // 按单张农事展示日期置灰:晚于今天为 future-card;无日期时回退物候期规则
+                                    { 'future-card': shouldGrayFarmWorkCard(fw, p) },
                                 ]" @click="handleRowClick(fw)">
                                 ]" @click="handleRowClick(fw)">
                                 <div class="card-content">
                                 <div class="card-content">
                                     <div class="card-left"
                                     <div class="card-left"
@@ -47,7 +47,7 @@
                                             </div> -->
                                             </div> -->
                                         </div>
                                         </div>
                                         <div class="title-text van-ellipsis"
                                         <div class="title-text van-ellipsis"
-                                            v-if="shouldShowBlue(p) && fw.sourceType != 4">{{ fw.content }}</div>
+                                            v-if="!shouldGrayFarmWorkCard(fw, p) && fw.sourceType != 4">{{ fw.content }}</div>
                                     </div>
                                     </div>
                                     <div class="card-left agri-record-card" v-else>
                                     <div class="card-left agri-record-card" v-else>
                                         <div class="left-info">
                                         <div class="left-info">
@@ -81,7 +81,7 @@
                         </div>
                         </div>
                         <template v-if="r.name === p.phenologyName">
                         <template v-if="r.name === p.phenologyName">
                             <div class="phenology-name text-blue"
                             <div class="phenology-name text-blue"
-                                :class="{ 'phenology-red': !shouldShowBlue(p), 'phenology-blue': shouldShowBlue(p) }"
+                                :class="{ 'phenology-red': !shouldShowBlueLeft(p, r), 'phenology-blue': shouldShowBlueLeft(p, r) }"
                                 :style="r.phenologyName === getNextPhenologyName(idx, rIdx) ? 'padding: 6px 0;' : ''">
                                 :style="r.phenologyName === getNextPhenologyName(idx, rIdx) ? 'padding: 6px 0;' : ''">
                                 {{ r.name }}
                                 {{ r.name }}
                             </div>
                             </div>
@@ -89,18 +89,18 @@
                         <template v-else>
                         <template v-else>
                             <template v-if="p.phenologyName === getNextPhenologyName(idx, rIdx)">
                             <template v-if="p.phenologyName === getNextPhenologyName(idx, rIdx)">
                                 <div class="phenology-name"
                                 <div class="phenology-name"
-                                    :class="{ 'text-red': !shouldShowBlue(p), 'text-blue': shouldShowBlue(p) }">
+                                    :class="{ 'text-red': !shouldShowBlueLeft(p, r), 'text-blue': shouldShowBlueLeft(p, r) }">
                                     {{ r.name }}
                                     {{ r.name }}
                                 </div>
                                 </div>
                             </template>
                             </template>
                             <template v-else>
                             <template v-else>
                                 <div class="phenology-name"
                                 <div class="phenology-name"
-                                    :class="{ 'text-red': !shouldShowBlue(p), 'text-blue': shouldShowBlue(p) }">
+                                    :class="{ 'text-red': !shouldShowBlueLeft(p, r), 'text-blue': shouldShowBlueLeft(p, r) }">
                                     {{ r.name }}
                                     {{ r.name }}
                                 </div>
                                 </div>
                                 <div class="phenology-name mr" :class="{
                                 <div class="phenology-name mr" :class="{
-                                    'phenology-red': !shouldShowBlue(p),
-                                    'phenology-blue': shouldShowBlue(p),
+                                    'phenology-red': !shouldShowBlueLeft(p, r),
+                                    'phenology-blue': shouldShowBlueLeft(p, r),
                                 }">
                                 }">
                                     {{ p.phenologyName }}
                                     {{ p.phenologyName }}
                                 </div>
                                 </div>
@@ -938,18 +938,76 @@ const flowStatusStr = {
     '5': '已认证',
     '5': '已认证',
 }
 }
 
 
-// 判断物候期是否应该显示蓝色(已过或当前节气的物候期)
-const shouldShowBlue = (phenology) => {
-    // 农事记录页兼容:只要该物候期下存在待认证农事,左侧生育期/物候期均高亮为蓝色
-    if (props.pageType === "agri_record") {
-        const hasPendingAuth = (Array.isArray(phenology?.reproductiveList) ? phenology.reproductiveList : []).some((reproductive) =>
-            (Array.isArray(reproductive?.farmWorkArrangeList) ? reproductive.farmWorkArrangeList : []).some((fw) => Number(fw?.flowStatus) === 3)
-        );
-        if (hasPendingAuth) {
+// 右侧农事卡片展示用日期(与模板 left-date 一致:规划 createTime、记录 recommendDate)
+const getFarmWorkTimelineDateMs = (fw) => {
+    const primary = props.pageType === "agri_plan" ? fw?.createTime : fw?.recommendDate ?? fw?.createTime;
+    let ms = safeParseDate(primary);
+    if (Number.isNaN(ms) || ms <= 0) {
+        ms = safeParseDate(props.pageType === "agri_plan" ? fw?.recommendDate : fw?.createTime);
+    }
+    return ms;
+};
+
+const isFarmWorkDateOnOrBeforeToday = (ms) => {
+    if (Number.isNaN(ms) || ms <= 0) return false;
+    const today = new Date();
+    today.setHours(0, 0, 0, 0);
+    const d = new Date(ms);
+    d.setHours(0, 0, 0, 0);
+    return d.getTime() <= today.getTime();
+};
+
+// 单张卡片:有有效展示日期且晚于今天 → 未来农事,右侧应置灰(与 left-date 同一套字段)
+const isFarmWorkTimelineStrictlyFuture = (fw) => {
+    const ms = getFarmWorkTimelineDateMs(fw);
+    if (Number.isNaN(ms) || ms <= 0) return false;
+    return !isFarmWorkDateOnOrBeforeToday(ms);
+};
+
+// 右侧 arrange-card:未来日期置灰;解析不到日期时回退物候期节气/待认证规则(与旧版整段逻辑一致)
+// 无农事展示日期时的置灰回退:仅用节气/物候期 + 待认证(不含「任一行农事≤今天」),避免右侧卡片被外层标题连带误判
+const isPhenologyActiveWithoutFarmWorkDates = (phenology) =>
+    agriRecordHasPendingAuthInPhenology(phenology) || shouldShowBlueBase(phenology);
+
+const shouldGrayFarmWorkCard = (fw, phenology) => {
+    if (isFarmWorkTimelineStrictlyFuture(fw)) return true;
+    const ms = getFarmWorkTimelineDateMs(fw);
+    if (!Number.isNaN(ms) && ms > 0) {
+        return false;
+    }
+    return !isPhenologyActiveWithoutFarmWorkDates(phenology);
+};
+
+// 某一生育期行下是否存在「农事时间 ≤ 今天」的卡片(与右侧 left-date 字段一致)
+const reproductiveHasFarmWorkOnOrBeforeToday = (reproductive) => {
+    const fws = Array.isArray(reproductive?.farmWorkArrangeList) ? reproductive.farmWorkArrangeList : [];
+    for (const fw of fws) {
+        if (isFarmWorkDateOnOrBeforeToday(getFarmWorkTimelineDateMs(fw))) {
             return true;
             return true;
         }
         }
     }
     }
+    return false;
+};
+
+// 物候期内是否至少有一行生育期因「农事≤今天」而高亮(用于最外层物候期标题与内层对齐)
+const phenologyHasFarmWorkOnOrBeforeToday = (phenology) => {
+    const reproductives = Array.isArray(phenology?.reproductiveList) ? phenology.reproductiveList : [];
+    return reproductives.some((r) => reproductiveHasFarmWorkOnOrBeforeToday(r));
+};
 
 
+// 仅农事记录页(agri_record):该物候期内存在待认证农事时,左侧最外层物候期与各生育期/物候期文案均高亮为蓝;农事规划(agri_plan)不生效
+const agriRecordHasPendingAuthInPhenology = (phenology) => {
+    if (props.pageType !== "agri_record") return false;
+    return (Array.isArray(phenology?.reproductiveList) ? phenology.reproductiveList : []).some((reproductive) =>
+        (Array.isArray(reproductive?.farmWorkArrangeList) ? reproductive.farmWorkArrangeList : []).some((fw) => {
+            const s = fw?.flowStatus;
+            return s === 3 || s === "3";
+        })
+    );
+};
+
+// 物候期底色/节气规则(不含「农事卡片日期」「待认证」扩展)
+const shouldShowBlueBase = (phenology) => {
     // 优先使用物候期真实日期判断:未来日期不应显示蓝色
     // 优先使用物候期真实日期判断:未来日期不应显示蓝色
     const phenologyTimeMs =
     const phenologyTimeMs =
         Number(phenology?.startTimeMs) ||
         Number(phenology?.startTimeMs) ||
@@ -999,6 +1057,20 @@ const shouldShowBlue = (phenology) => {
     return phenologyTermProgress < nextTermProgress;
     return phenologyTermProgress < nextTermProgress;
 };
 };
 
 
+// 最外层物候期标题:与内层生育期对齐——任一生育行因农事≤今天变蓝;农事记录下有待认证则整段标题也蓝;否则按节气规则(右侧卡片仍按单卡日期置灰)
+const shouldShowBlue = (phenology) => {
+    if (phenologyHasFarmWorkOnOrBeforeToday(phenology)) return true;
+    if (agriRecordHasPendingAuthInPhenology(phenology)) return true;
+    return shouldShowBlueBase(phenology);
+};
+
+// 左侧生育期/物候期文案:农事记录下物候期内有待认证则该段内所有生育期/物候期名称均蓝;否则本行农事≤今天或节气规则
+const shouldShowBlueLeft = (phenology, reproductive) => {
+    if (agriRecordHasPendingAuthInPhenology(phenology)) return true;
+    if (reproductiveHasFarmWorkOnOrBeforeToday(reproductive)) return true;
+    return shouldShowBlueBase(phenology);
+};
+
 defineExpose({
 defineExpose({
     updateFarmWorkPlan,
     updateFarmWorkPlan,
 });
 });

+ 22 - 2
src/components/weatherInfo.vue

@@ -69,6 +69,7 @@
             :showEditBtn="false"
             :showEditBtn="false"
             :showBtn="true"
             :showBtn="true"
             :farmId="farmId"
             :farmId="farmId"
+            @success="onFarmBasicInfoSaved"
         ></farm-info-popup>
         ></farm-info-popup>
     </div>
     </div>
 
 
@@ -194,13 +195,14 @@ function selectFarmFromList(data) {
     const savedFarmId = localStorage.getItem('selectedFarmId');
     const savedFarmId = localStorage.getItem('selectedFarmId');
     const savedFarmName = localStorage.getItem('selectedFarmName');
     const savedFarmName = localStorage.getItem('selectedFarmName');
     if (savedFarmId && savedFarmName) {
     if (savedFarmId && savedFarmName) {
-        // 检查保存的农场是否还在当前列表中
+        // 检查保存的农场是否还在当前列表中(名称以接口列表为准,避免改名后仍显示 localStorage 旧值)
         const savedFarm = data.find(farm => farm.id == savedFarmId);
         const savedFarm = data.find(farm => farm.id == savedFarmId);
         if (savedFarm) {
         if (savedFarm) {
-            farmName.value = savedFarmName;
+            farmName.value = savedFarm.name;
             farmId.value = Number(savedFarmId);
             farmId.value = Number(savedFarmId);
             isDefaultFarm.value = savedFarm.defaultOption || false;
             isDefaultFarm.value = savedFarm.defaultOption || false;
             localStorage.setItem('selectedFarmPoint', savedFarm.wkt);
             localStorage.setItem('selectedFarmPoint', savedFarm.wkt);
+            localStorage.setItem('selectedFarmName', savedFarm.name);
         } else {
         } else {
             // 如果保存的农场不在列表中,按优先级选择
             // 如果保存的农场不在列表中,按优先级选择
             selectDefaultFarm(data);
             selectDefaultFarm(data);
@@ -298,6 +300,24 @@ function getLocationName() {
 }
 }
 
 
 const myFarmInfoRef = ref(null);
 const myFarmInfoRef = ref(null);
+
+/** 弹窗内修改农场名称等成功后,同步头部展示与下拉列表、本地缓存 */
+function onFarmBasicInfoSaved(payload) {
+    if (!payload?.id || payload.name == null) {
+        return;
+    }
+    const savedId = Number(payload.id);
+    const idx = farmList.value.findIndex((f) => f.id == savedId);
+    if (idx !== -1) {
+        farmList.value[idx] = { ...farmList.value[idx], name: payload.name };
+    }
+    if (farmId.value == savedId) {
+        farmName.value = payload.name;
+        localStorage.setItem('selectedFarmName', payload.name);
+        emit('changeGarden', { id: farmId.value, name: farmName.value });
+    }
+}
+
 const handleFarmInfo = () => {
 const handleFarmInfo = () => {
     // myFarmInfoRef.value.handleShow();
     // myFarmInfoRef.value.handleShow();
     router.push(`/farm_info?subjectId=${farmId.value}`);
     router.push(`/farm_info?subjectId=${farmId.value}`);

+ 4 - 1
src/views/old_mini/home/components/farmInfoPopup.vue

@@ -163,7 +163,10 @@ const handleEdit = async () => {
         if (res.code === 0) {
         if (res.code === 0) {
             ElMessage.success('修改成功');
             ElMessage.success('修改成功');
             show.value = false;
             show.value = false;
-            emit('success');
+            emit('success', {
+                id: props.farmId,
+                name: farmInfo.value.subjectName,
+            });
         }
         }
     });
     });
     // setTimeout(() => {
     // setTimeout(() => {

+ 50 - 19
src/views/old_mini/home/subPages/prescriptionPage.vue

@@ -261,7 +261,9 @@ const basicForm = ref({
 });
 });
 
 
 const basicFarmFormData = ref({});
 const basicFarmFormData = ref({});
-const getBasicFarmFormData = () => {
+/** @param {{ machineryMerge?: { name: string, quantity?: string, unit?: string } }} [options] */
+const getBasicFarmFormData = (options = {}) => {
+    const machineryMerge = options.machineryMerge;
     loadingPage.value = true;
     loadingPage.value = true;
     VE_API.basic_farm.fetchBasicFarmFormData({subjectId: route.query?.subjectId}).then(({ data }) => {
     VE_API.basic_farm.fetchBasicFarmFormData({subjectId: route.query?.subjectId}).then(({ data }) => {
         basicFarmFormData.value = data;
         basicFarmFormData.value = data;
@@ -297,6 +299,22 @@ const getBasicFarmFormData = () => {
         
         
         // 4. irrigationMethods, improvementAreas, machinery 的 selected 状态已经在 data 中设置好了
         // 4. irrigationMethods, improvementAreas, machinery 的 selected 状态已经在 data 中设置好了
         // 这些数据会直接显示在页面上,因为页面是通过 basicFarmFormData 来渲染的
         // 这些数据会直接显示在页面上,因为页面是通过 basicFarmFormData 来渲染的
+
+        // 新增「其它设备」时接口只存名称,刷新后把弹窗里填写的数量写回对应自定义项
+        if (machineryMerge && Array.isArray(basicFarmFormData.value.machinery)) {
+            const nameKey = (machineryMerge.name || "").trim();
+            const row = basicFarmFormData.value.machinery.find(
+                (m) => m.custom && String(m.name || "").trim() === nameKey
+            );
+            if (row) {
+                row.selected = true;
+                const q = (machineryMerge.quantity || "").trim();
+                row.quantity = q || null;
+                if (machineryMerge.unit) {
+                    row.unit = machineryMerge.unit;
+                }
+            }
+        }
     }).finally(() => {
     }).finally(() => {
         loadingPage.value = false;
         loadingPage.value = false;
     });
     });
@@ -379,19 +397,22 @@ function handleMachinerySelect(type, index, item) {
 
 
 function handleConfirm() {
 function handleConfirm() {
     if (addTypeKey.value === 'machinery') {
     if (addTypeKey.value === 'machinery') {
-        if (!popupInputNum.value.trim()) {
-            return;
-        }
         if (isMachineSelf.value && !isEditPopup.value) {
         if (isMachineSelf.value && !isEditPopup.value) {
-            
-            saveCustomOption(popupInputVal.value);
+            if (!popupInputVal.value.trim()) {
+                return;
+            }
+            const nameTrim = popupInputVal.value.trim();
+            saveCustomOption(nameTrim, {
+                quantity: popupInputNum.value.trim(),
+                unit: machineryUnit.value || undefined,
+            });
         } else {
         } else {
             const option = basicFarmFormData.value[addTypeKey.value][currentEditIndex.value]
             const option = basicFarmFormData.value[addTypeKey.value][currentEditIndex.value]
             option.name = popupInputVal.value;
             option.name = popupInputVal.value;
-            option.quantity = popupInputNum.value;
+            const qtyTrim = (popupInputNum.value || "").trim();
+            option.quantity = qtyTrim || null;
             option.selected = true;
             option.selected = true;
             // 更新名称
             // 更新名称
-            console.log('更新名称', basicFarmFormData.value[addTypeKey.value][currentEditIndex.value]);
             if (option.custom) {
             if (option.custom) {
                 // updateCustomOption(popupInputVal.value, option.id || option.code);
                 // updateCustomOption(popupInputVal.value, option.id || option.code);
                 updateCustomOption(popupInputVal.value, basicFarmFormData.value[addTypeKey.value][currentEditIndex.value].id);
                 updateCustomOption(popupInputVal.value, basicFarmFormData.value[addTypeKey.value][currentEditIndex.value].id);
@@ -424,17 +445,27 @@ const configTypeObj = {
     irrigationMethods: 'IRRIGATION',
     irrigationMethods: 'IRRIGATION',
     machinery: 'MACHINERY',
     machinery: 'MACHINERY',
 }
 }
-function saveCustomOption(name) {
-    VE_API.basic_farm.addCustomOption({ configType: configTypeObj[addTypeKey.value], name: name }).then(({ data }) => {
-        console.log(data);
+/** @param {{ quantity?: string, unit?: string }} [machineryMeta] 仅新增自定义农机时传入,用于刷新表单后合并数量 */
+function saveCustomOption(name, machineryMeta) {
+    const cfgKey = addTypeKey.value;
+    VE_API.basic_farm.addCustomOption({ configType: configTypeObj[cfgKey], name: name }).then(({ data }) => {
         ElMessage.success('保存成功');
         ElMessage.success('保存成功');
-        basicFarmFormData.value[addTypeKey.value].push({ id: data.id, name: popupInputVal.value, code: popupInputVal.value, selected: true, custom: true, quantity: popupInputNum.value });
+        if (cfgKey === "machinery" && machineryMeta) {
+            getBasicFarmFormData({
+                machineryMerge: {
+                    name,
+                    quantity: machineryMeta.quantity,
+                    unit: machineryMeta.unit,
+                },
+            });
+        } else {
+            getBasicFarmFormData();
+        }
     });
     });
 }
 }
 
 
 function updateCustomOption(name, id) {
 function updateCustomOption(name, id) {
     VE_API.basic_farm.updateCustomOption({ id, configType: configTypeObj[addTypeKey.value], name: name }).then(({ data }) => {
     VE_API.basic_farm.updateCustomOption({ id, configType: configTypeObj[addTypeKey.value], name: name }).then(({ data }) => {
-        console.log(data);
         ElMessage.success('保存成功');
         ElMessage.success('保存成功');
     });
     });
 }
 }
@@ -480,7 +511,7 @@ function handleSubmit() {
         .map(item => item.code || item.id);
         .map(item => item.code || item.id);
     // 收集农机设备(包含 code 和 quantity)
     // 收集农机设备(包含 code 和 quantity)
     const machineryWithQuantity = (basicFarmFormData.value.machinery || [])
     const machineryWithQuantity = (basicFarmFormData.value.machinery || [])
-        .filter(item => item.selected && item.quantity)
+        .filter(item => item.selected)
         .map(item => ({
         .map(item => ({
             code: item.code || item.id,
             code: item.code || item.id,
             quantity: Number(item.quantity) || 0
             quantity: Number(item.quantity) || 0
@@ -531,11 +562,11 @@ function validateForm() {
         return false;
         return false;
     }
     }
 
 
-    // 校验农机设备
-    const machineryWithQuantity = (basicFarmFormData.value.machinery || [])
-        .filter(item => item.selected && item.quantity);
-    if (machineryWithQuantity.length === 0) {
-        ElMessage.warning('请选择您的农机设备并填写数量');
+    // 校验农机设备(仅要求有选中项,数量选填)
+    const machinerySelected = (basicFarmFormData.value.machinery || [])
+        .filter(item => item.selected);
+    if (machinerySelected.length === 0) {
+        ElMessage.warning('请选择您的农机设备');
         return false;
         return false;
     }
     }
 
 

+ 3 - 0
src/views/old_mini/interactionList/index.vue

@@ -789,6 +789,9 @@ const oldUser = ref(false);
 const miniData = ref({});
 const miniData = ref({});
 // 页面从勾画页返回时,如果组件被 keep-alive 缓存,则会触发 onActivated,在此再做一次回显
 // 页面从勾画页返回时,如果组件被 keep-alive 缓存,则会触发 onActivated,在此再做一次回显
 onActivated(() => {
 onActivated(() => {
+    // 重新进入页面时清空提交/上传中状态,避免上次未完成请求导致按钮一直卡在「提交中」「上传中」
+    itemSubmittingMap.value = {};
+    confirmUploadLoading.value = false;
     if(route.query.miniJson) {
     if(route.query.miniJson) {
         const data = JSON.parse(route.query.miniJson);
         const data = JSON.parse(route.query.miniJson);
         miniData.value = JSON.parse(data.paramsPage);
         miniData.value = JSON.parse(data.paramsPage);