소스 검색

fix: 对接天气,报价

lxf 2 주 전
부모
커밋
55e7d57b15

+ 5 - 1
src/api/modules/old_mini_map.js

@@ -24,5 +24,9 @@ module.exports = {
     getCtiyList: {
         url: config.base_dev_url + "poi/city",
         type: "get",
-    }
+    },
+    get7d: {
+        url: config.base_dev_url + "lz_weather7d/get7d",
+        type: "get",
+    },
 }

+ 5 - 0
src/api/modules/z_farm_work_pesticide_fertilizer.js

@@ -32,4 +32,9 @@ module.exports = {
         url: url + "_category" + "/firstLevelOptions",
         type: "get",
     },
+    // 删除药肥
+    deleteFertilizer: {
+        url: url + "/delete",
+        type: "get",
+    },
 }

+ 71 - 8
src/components/popup/priceSheetPopup.vue

@@ -143,7 +143,6 @@ const quotationData = ref({});
 const priceData = ref({});
 
 onActivated(() => {
-    console.log('onActivated')
     fetchPriceData()
 })
 
@@ -177,6 +176,8 @@ const processedPrescriptionList = computed(() => {
                     typeName: item.typeName || item.pesticideFertilizerTypeName || '--',
                     defaultName: item.defaultName || item.pesticideFertilizerName || '--',
                     brand: brand,
+                    priceVal: price || null,
+                    pesticideFertilizerId: item.pesticideFertilizerId,
                     price: price ? `${price}元` : '--',
                     unit: unit,
                     muUsage: muUsage,
@@ -221,9 +222,68 @@ function fetchPriceData() {
     });
 }
 
-const handleShare = () => {
-    if (!priceData.value?.id || !priceData.value?.itemsList || priceData.value?.itemsList?.length === 0) {
-        ElMessage.warning('请补全报价数据')
+// 检查 itemsList 是否都有价格
+function checkItemsListHasPrice() {
+    if (!priceData.value?.itemsList || !Array.isArray(priceData.value.itemsList) || priceData.value.itemsList.length === 0) {
+        return false;
+    }
+    // 检查所有项是否都有 price 且 price 大于 0
+    return priceData.value.itemsList.every(item => item.price != null && item.price !== '' && item.price !== 0);
+}
+
+async function checkOrder() {
+    // 如果没有 id,需要检查 itemsList 是否都有价格
+    if (!checkItemsListHasPrice()) {
+        return false; // 没有价格,返回 false
+    }
+    if (!priceData.value?.id) {
+        // 如果 itemsList 都有价格,调用接口创建报价
+        const pesticideFertilizerQuoteList = processedPrescriptionList.value.map(item => {
+            return {
+                pesticideFertilizerId: item.pesticideFertilizerId,
+                price: item.priceVal,
+                brand: item.brand,
+            }
+        });
+        
+        const payload = {
+            farmWorkRecordId: quotationData.value?.id,
+            pesticideFertilizerQuoteList,
+            servicePrice: priceData.value.farmWorkServiceCost,
+            executionMethod: priceData.value.executionMethod,
+        };
+        
+        try {
+            const { code } = await VE_API.z_farm_work_record.acceptFarmWorkRecord(payload);
+            if (code === 0) {
+                // 创建成功后,重新获取价格数据
+                await fetchPriceData();
+                return true; // 创建成功,返回 true
+            } else {
+                return false; // 创建失败,返回 false
+            }
+        } catch (error) {
+            return false; // 接口调用失败,返回 false
+        }
+    }
+    
+    // 如果有 id,检查 itemsList 是否都有价格
+    if (!checkItemsListHasPrice()) {
+        return false; // 没有价格,返回 false
+    }
+    
+    // 有 id 且都有价格,返回 true
+    return true;
+}
+
+const handleShare = async () => {
+    // 检查订单状态,如果返回 false 说明数据不完整
+    const canProceed = await checkOrder();
+    if (!canProceed) {
+        ElMessage.warning('请补全报价数据');
+        setTimeout(() => {
+            handleEdit();
+        }, 1000);
         return;
     }
     const userId = quotationData.value.farmMiniUserId;
@@ -243,9 +303,11 @@ const handleShare = () => {
     }   
 };
 
-const handleWechat = () => {
-    if (!priceData.value?.id || !priceData.value?.itemsList || priceData.value?.itemsList?.length === 0) {
-        ElMessage.warning('请补全报价数据')
+const handleWechat = async () => {
+    // 检查订单状态,如果返回 false 说明数据不完整
+    const canProceed = await checkOrder();
+    if (!canProceed) {
+        ElMessage.warning('请补全报价数据');
         return;
     }
     // router.push({
@@ -319,7 +381,7 @@ const handleSaveImage = async () => {
             scroller.style.height = prev.scrollerHeight;
         }
     } catch (e) {
-        console.error('保存图片失败', e);
+        // 保存图片失败
     }
 };
 
@@ -702,6 +764,7 @@ defineExpose({
     font-size: 14px;
     width: fit-content;
     cursor: pointer;
+    font-weight: 500;
 }
 
 // 底部操作按钮

+ 153 - 256
src/components/weatherChart.vue

@@ -6,246 +6,132 @@
 import { onMounted, ref, watch } from "vue";
 import * as echarts from "echarts";
 
-// const props = defineProps({
-//     list: {
-//         type: Array,
-//         default: () => [],
-//         required: true,
-//     },
-// });
-
-let demoData = [
-    {
-        sourceof: null,
-        create_by: null,
-        update_by: null,
-        remark: null,
-        sys_dept_code: null,
-        createTime: null,
-        updateTime: null,
-        rq: "08/28",
-        weatherZgwd: 30,
-        weatherZdwd: 18,
-        weatherTqDay: "晴",
-        weatherTqNight: "晴",
-        weatherImgDay: "https://d.scggqx.com/forecast/img/小雨.png",
-        weatherImgNight: "https://d.scggqx.com/forecast/img/小雨.png",
-        windDirectDay: "南风",
-        windDirectNight: "南风",
-        windPowerDay: "微风",
-        windPowerNight: "微风",
-        week: "星期三",
-    },
-    {
-        sourceof: null,
-        create_by: null,
-        update_by: null,
-        remark: null,
-        sys_dept_code: null,
-        createTime: null,
-        updateTime: null,
-        rq: "08/29",
-        weatherZgwd: 31,
-        weatherZdwd: 19,
-        weatherTqDay: "晴",
-        weatherTqNight: "晴",
-        weatherImgDay: "https://d.scggqx.com/forecast/img/小雨.png",
-        weatherImgNight: "https://d.scggqx.com/forecast/img/小雨.png",
-        windDirectDay: "南风",
-        windDirectNight: "南风",
-        windPowerDay: "微风",
-        windPowerNight: "微风",
-        week: "星期四",
-    },
-    {
-        sourceof: null,
-        create_by: null,
-        update_by: null,
-        remark: null,
-        sys_dept_code: null,
-        createTime: null,
-        updateTime: null,
-        rq: "08/30",
-        weatherZgwd: 30,
-        weatherZdwd: 19,
-        weatherTqDay: "晴",
-        weatherTqNight: "多云",
-        weatherImgDay: "https://d.scggqx.com/forecast/img/小雨.png",
-        weatherImgNight: "https://d.scggqx.com/forecast/img/小雨.png",
-        windDirectDay: "西南风",
-        windDirectNight: "北风",
-        windPowerDay: "微风",
-        windPowerNight: "微风",
-        week: "星期五",
-    },
-    {
-        sourceof: null,
-        create_by: null,
-        update_by: null,
-        remark: null,
-        sys_dept_code: null,
-        createTime: null,
-        updateTime: null,
-        rq: "08/31",
-        weatherZgwd: 30,
-        weatherZdwd: 21,
-        weatherTqDay: "多云",
-        weatherTqNight: "雷阵雨",
-        weatherImgDay: "https://d.scggqx.com/forecast/img/小雨.png",
-        weatherImgNight: "https://d.scggqx.com/forecast/img/小雨.png",
-        windDirectDay: "北风",
-        windDirectNight: "南风",
-        windPowerDay: "3~4级",
-        windPowerNight: "3~4级",
-        week: "星期六",
-    },
-    {
-        sourceof: null,
-        create_by: null,
-        update_by: null,
-        remark: null,
-        sys_dept_code: null,
-        createTime: null,
-        updateTime: null,
-        rq: "09/01",
-        weatherZgwd: 25,
-        weatherZdwd: 16,
-        weatherTqDay: "雷阵雨",
-        weatherTqNight: "多云",
-        weatherImgDay: "https://d.scggqx.com/forecast/img/多云.png",
-        weatherImgNight: "https://d.scggqx.com/forecast/img/多云.png",
-        windDirectDay: "北风",
-        windDirectNight: "北风",
-        windPowerDay: "3~4级",
-        windPowerNight: "3~4级",
-        week: "星期日",
-    },
-    {
-        sourceof: null,
-        create_by: null,
-        update_by: null,
-        remark: null,
-        sys_dept_code: null,
-        createTime: null,
-        updateTime: null,
-        rq: "09/02",
-        weatherZgwd: 26,
-        weatherZdwd: 15,
-        weatherTqDay: "晴",
-        weatherTqNight: "晴",
-        weatherImgDay: "https://d.scggqx.com/forecast/img/阴.png",
-        weatherImgNight: "https://d.scggqx.com/forecast/img/阴.png",
-        windDirectDay: "北风",
-        windDirectNight: "北风",
-        windPowerDay: "3~4级",
-        windPowerNight: "微风",
-        week: "星期一",
-    },
-    {
-        sourceof: null,
-        create_by: null,
-        update_by: null,
-        remark: null,
-        sys_dept_code: null,
-        createTime: null,
-        updateTime: null,
-        rq: "09/03",
-        weatherZgwd: 27,
-        weatherZdwd: 18,
-        weatherTqDay: "多云",
-        weatherTqNight: "阴",
-        weatherImgDay: "https://d.scggqx.com/forecast/img/小雨.png",
-        weatherImgNight: "https://d.scggqx.com/forecast/img/小雨.png",
-        windDirectDay: "无持续风向",
-        windDirectNight: "无持续风向",
-        windPowerDay: "微风",
-        windPowerNight: "微风",
-        week: "星期二",
-    },
-    {
-        sourceof: null,
-        create_by: null,
-        update_by: null,
-        remark: null,
-        sys_dept_code: null,
-        createTime: null,
-        updateTime: null,
-        rq: "09/04",
-        weatherZgwd: 27,
-        weatherZdwd: 18,
-        weatherTqDay: "多云",
-        weatherTqNight: "阴",
-        weatherImgDay: "https://d.scggqx.com/forecast/img/小雨.png",
-        weatherImgNight: "https://d.scggqx.com/forecast/img/小雨.png",
-        windDirectDay: "无持续风向",
-        windDirectNight: "无持续风向",
-        windPowerDay: "微风",
-        windPowerNight: "微风",
-        week: "星期二",
+const props = defineProps({
+    weatherData: {
+        type: Object,
+        default: null,
     },
-];
-
-let weekday = [];
-let datelist = [];
-let weatherDaylist = [];
-let weatherNightlist = [];
-let weatherImgDaylist = [];
-let weatherImgNightlist = [];
-let windDirectlist = [];
-let windPowerlist = [];
-let weatherZgwdlist = [];
-let weatherZdwdlist = [];
+});
 
-let weatherImgDaylistRich = {};
-let weatherImgNightlistRich = {};
+// 将接口数据转换为图表需要的格式
+function formatWeatherData(weatherData) {
+    if (!weatherData || !weatherData.daily || !Array.isArray(weatherData.daily)) {
+        return [];
+    }
+    
+    const weekDays = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
+    
+    return weatherData.daily.map((item) => {
+        // 格式化日期:从 "2025-11-14" 转换为 "11/14"
+        const date = new Date(item.fxDate);
+        const month = String(date.getMonth() + 1).padStart(2, '0');
+        const day = String(date.getDate()).padStart(2, '0');
+        const rq = `${month}/${day}`;
+        
+        // 获取星期几
+        const weekDay = weekDays[date.getDay()];
+        
+        // 根据 iconDay 和 iconNight 生成图片URL(这里需要根据实际API返回的icon值来映射)
+        // 暂时使用默认图片,后续可以根据icon值映射到具体图片
+        const getWeatherImg = (icon) => {
+            // 可以根据icon值返回对应的图片URL
+            // 例如:icon "100" -> 晴, "101" -> 多云, "104" -> 阴等
+            // return `https://d.scggqx.com/forecast/img/${icon}.png`;
+            return `https://birdseye-img.sysuimars.com/weather/${icon}.svg`;
+        };
+        
+        return {
+            rq: rq,
+            weatherZgwd: item.tempMax,
+            weatherZdwd: item.tempMin,
+            weatherTqDay: item.textDay,
+            weatherTqNight: item.textNight,
+            weatherImgDay: getWeatherImg(item.iconDay),
+            weatherImgNight: getWeatherImg(item.iconNight),
+            windDirectDay: item.windDirDay,
+            windDirectNight: item.windDirNight,
+            windPowerDay: item.windScaleDay,
+            windPowerNight: item.windScaleNight,
+            week: weekDay,
+        };
+    });
+}
 
-let maxWD = 30;
-let minWD = 0;
+// 处理天气数据
+function processWeatherData(data) {
+    let weekday = [];
+    let datelist = [];
+    let weatherDaylist = [];
+    let weatherNightlist = [];
+    let weatherImgDaylist = [];
+    let weatherImgNightlist = [];
+    let windDirectlist = [];
+    let windPowerlist = [];
+    let weatherZgwdlist = [];
+    let weatherZdwdlist = [];
 
-demoData.forEach((item) => {
-    weekday.push(item.week);
-    datelist.push(item.rq);
-    weatherDaylist.push(item.weatherTqDay);
-    weatherNightlist.push(item.weatherTqNight);
-    weatherImgDaylist.push(item.weatherImgDay);
-    weatherImgNightlist.push(item.weatherImgNight);
-    windDirectlist.push(item.windDirectDay);
-    windPowerlist.push(item.windPowerDay);
-    weatherZgwdlist.push(item.weatherZgwd);
-    weatherZdwdlist.push(item.weatherZdwd);
-});
-maxWD = Math.max(...weatherZgwdlist) + 30;
-minWD = Math.min(...weatherZdwdlist) - 30;
-let weatherImgDaylistStyle = weatherImgDaylist.map((item) => {
-    let dateUrl = item;
-    return {
-        backgroundColor: {
-            image: dateUrl,
-        },
-        height: 20,
-        width: 20,
-    };
-});
-let weatherImgNightlistStyle = weatherImgNightlist.map((item) => {
-    let dateUrl = item;
+    data.forEach((item) => {
+        weekday.push(item.week);
+        datelist.push(item.rq);
+        weatherDaylist.push(item.weatherTqDay);
+        weatherNightlist.push(item.weatherTqNight);
+        weatherImgDaylist.push(item.weatherImgDay);
+        weatherImgNightlist.push(item.weatherImgNight);
+        windDirectlist.push(item.windDirectDay);
+        windPowerlist.push(item.windPowerDay);
+        weatherZgwdlist.push(item.weatherZgwd);
+        weatherZdwdlist.push(item.weatherZdwd);
+    });
+    
+    const maxWD = weatherZgwdlist.length > 0 ? Math.max(...weatherZgwdlist) + 30 : 60;
+    const minWD = weatherZdwdlist.length > 0 ? Math.min(...weatherZdwdlist) - 30 : 0;
+    
     return {
-        backgroundColor: {
-            image: dateUrl,
-        },
-        height: 20,
-        width: 20,
+        weekday,
+        datelist,
+        weatherDaylist,
+        weatherNightlist,
+        weatherImgDaylist,
+        weatherImgNightlist,
+        windDirectlist,
+        windPowerlist,
+        weatherZgwdlist,
+        weatherZdwdlist,
+        maxWD,
+        minWD
     };
-});
-weatherImgDaylistStyle.forEach((i, index) => {
-    weatherImgDaylistRich[index] = i;
-});
-weatherImgNightlistStyle.forEach((i, index) => {
-    weatherImgNightlistRich[index] = i;
-});
+}
+// 生成天气图片样式
+function generateWeatherImgRich(weatherImgList) {
+    const weatherImgListStyle = weatherImgList.map((item) => {
+        return {
+            backgroundColor: {
+                image: item,
+            },
+            height: 20,
+            width: 20,
+        };
+    });
+    
+    const rich = {};
+    weatherImgListStyle.forEach((i, index) => {
+        rich[index] = i;
+    });
+    return rich;
+}
 
 const myChart = ref(null);
 const chartDom = ref(null);
-const options = {
+
+// 初始化默认数据(用于首次渲染)
+const defaultData = formatWeatherData(null);
+const defaultProcessed = processWeatherData(defaultData.length > 0 ? defaultData : []);
+const defaultWeatherImgDaylistRich = generateWeatherImgRich(defaultProcessed.weatherImgDaylist);
+const defaultWeatherImgNightlistRich = generateWeatherImgRich(defaultProcessed.weatherImgNightlist);
+
+// 生成图表配置
+function generateOptions(processedData, weatherImgDaylistRich, weatherImgNightlistRich) {
+    return {
     grid: {
         top: "-100px",
         right: "20px",
@@ -278,7 +164,7 @@ const options = {
                     },
                 },
             },
-            data: weekday,
+            data: processedData.weekday,
         },
         {
             type: "category",
@@ -302,7 +188,7 @@ const options = {
                     },
                 },
             },
-            data: datelist,
+            data: processedData.datelist,
             axisPointer: {
                 show: false,
             },
@@ -328,7 +214,7 @@ const options = {
                     },
                 },
             },
-            data: weatherDaylist,
+            data: processedData.weatherDaylist,
             axisPointer: {
                 show: false,
             },
@@ -350,7 +236,7 @@ const options = {
                 formatter: ["{{value}|}"].join("\n"),
                 rich: weatherImgDaylistRich,
             },
-            data: ["0", "1", "2", "3", "4", "5", "6","7"],
+            data: processedData.weatherImgDaylist.map((_, index) => String(index)),
             axisPointer: {
                 show: false,
             },
@@ -376,7 +262,7 @@ const options = {
                     },
                 },
             },
-            data: weatherZgwdlist,
+            data: processedData.weatherZgwdlist,
             axisPointer: {
                 show: false,
             },
@@ -402,7 +288,7 @@ const options = {
                     },
                 },
             },
-            data: weatherZgwdlist,
+            data: processedData.weatherZdwdlist,
             axisPointer: {
                 show: false,
             },
@@ -415,14 +301,14 @@ const options = {
         axisLabel: {
             formatter: "{value}" + "℃",
         },
-        max: maxWD,
-        min: minWD,
+        max: processedData.maxWD,
+        min: processedData.minWD,
     },
     series: [
         {
             name: "最高温度",
             type: "line",
-            data: weatherZgwdlist,
+            data: processedData.weatherZgwdlist,
             symbol: "circle",
             symbolSize: 3,
             showSymbol: true,
@@ -445,7 +331,7 @@ const options = {
         {
             name: "最低温度",
             type: "line",
-            data: weatherZdwdlist,
+            data: processedData.weatherZdwdlist,
             symbol: "circle",
             symbolSize: 3,
             showSymbol: true,
@@ -467,29 +353,40 @@ const options = {
             silent: false,
         },
     ],
-};
+    };
+}
+
+const options = ref(generateOptions(defaultProcessed, defaultWeatherImgDaylistRich, defaultWeatherImgNightlistRich));
 
 onMounted(() => {
-    setTimeout(()=>{
+    setTimeout(() => {
         initChart();
-    },200)
+    }, 200);
 });
 
-
-// watch(
-//     () => props.list,
-//     (newValue, oldValue) => {
-//         // if(newValue){
-//         //     options.xAxis[0].data = newValue.map(item => item[1] + item[2])
-//         //     options.series[0].data = newValue.map(item => Math.floor(item[3]))
-//         // }
-//         myChart.value.setOption(options);
-//     }
-// );
+// 监听 weatherData 变化,更新图表
+watch(
+    () => props.weatherData,
+    (newValue) => {
+        if (newValue && newValue.daily) {
+            const formattedData = formatWeatherData(newValue);
+            const processedData = processWeatherData(formattedData);
+            const weatherImgDaylistRich = generateWeatherImgRich(processedData.weatherImgDaylist);
+            const weatherImgNightlistRich = generateWeatherImgRich(processedData.weatherImgNightlist);
+            
+            options.value = generateOptions(processedData, weatherImgDaylistRich, weatherImgNightlistRich);
+            
+            if (myChart.value) {
+                myChart.value.setOption(options.value);
+            }
+        }
+    },
+    { deep: true }
+);
 
 const initChart = () => {
     myChart.value = echarts.init(chartDom.value);
-    myChart.value.setOption(options);
+    myChart.value.setOption(options.value);
 };
 
 

+ 74 - 7
src/components/weatherInfo.vue

@@ -4,7 +4,7 @@
             <div class="header-left">
                 <div class="address flex-center" v-if="!isGarden">
                     <el-icon class="address-icon"><Location /></el-icon>
-                    <span class="address-text">广州市番禺区</span>
+                    <span class="address-text">{{ locationName || '--' }}</span>
                 </div>
                 <div class="address-select flex-center" v-else>
                     <el-dropdown class="select-garden" trigger="click" popper-class="select-garden-popper">
@@ -30,9 +30,9 @@
                     <div class="add-garden" @click="handleAddGarden">新增农场</div>
                 </div>
                 <div class="temperature flex-center">
-                    <div class="temperature-number">26</div>
+                    <div class="temperature-number">{{ currentWeather.temp || '--' }}</div>
                     <div class="temperature-text">
-                        <span>晴天</span>
+                        <span>{{ currentWeather.text || '--' }}</span>
                         <div class="temperature-text-time">
                             <span>{{ currentDateText }}</span>
                             <span v-show="!isExpanded" class="temperature-text-more" @click="toggleExpand">
@@ -42,22 +42,30 @@
                     </div>
                 </div>
             </div>
-            <img class="header-right" src="@/assets/img/home/rain.png" alt="" />
+            <div class="weather-icon" v-if="currentWeather.iconDay">
+                <i :class="'qi-'+currentWeather.iconDay + '-fill'"></i>
+            </div>
+            <!-- <div class="weather-icon" v-else>
+                <img :src="`https://birdseye-img.sysuimars.com/weather/${currentWeather.iconDay}.svg`" alt="" />
+            </div> -->
         </div>
         <div class="weather-chart-container">
             <div class="weather-chart-title">
                 <span>未来七天天气</span>
                 <div class="weather-chart-title-more" @click="toggleExpand">收起</div>
             </div>
-            <weather-chart class="weather-chart"></weather-chart>
+            <weather-chart class="weather-chart" :weather-data="weatherData"></weather-chart>
         </div>
     </div>
 </template>
 
 <script setup>
-import { ref, onActivated, computed, watch } from "vue";
+import { ref, onActivated, computed, watch, onMounted } from "vue";
 import weatherChart from "./weatherChart.vue";
 import { useRouter } from "vue-router";
+import { useStore } from "vuex";
+const store = useStore();
+
 const props = defineProps({
     isGarden: {
         type: Boolean,
@@ -215,19 +223,72 @@ function selectDefaultFarm(data) {
     localStorage.setItem('selectedFarmName', farmName.value);
 }
 
+onMounted(() => {
+    getLocationName();
+    getWeatherData();
+})
+
 onActivated(() => {
     getFarmList();
+    getWeatherData();
 });
 
 // 暴露刷新方法供父组件调用
 defineExpose({
-    refreshFarmList: getFarmList
+    refreshFarmList: getFarmList,
+    toggleExpand
 });
 
+const locationName = ref("");
+const weatherData = ref(null);
+const currentWeather = ref({ temp: "--", text: "--", iconDay: "" });
+const MAP_KEY = "CZLBZ-LJICQ-R4A5J-BN62X-YXCRJ-GNBUT";
+function getLocationName() {
+    const location = store.state.home.miniUserLocation;
+    // 将 location 从"经度,纬度"格式转换为"纬度,经度"格式
+    let formattedLocation = location;
+    if (typeof location === 'string' && location.includes(',')) {
+        const [lng, lat] = location.split(',');
+        formattedLocation = `${lat},${lng}`;
+    }
+    const params = {
+            key: MAP_KEY,
+            location: formattedLocation,
+        };
+        VE_API.old_mini_map.location(params).then(({ result }) => {
+            // locationVal.value = result.formatted_addresses.recommend;
+            locationName.value = result.address_component
+                ? result.address_component.city + result.address_component.district
+                : result.address + "";
+        });
+}
+
 const handleAddGarden = () => {
     router.push(`/create_farm?isReload=true&from=monitor`)
 }
 
+// 获取天气数据
+function getWeatherData() {
+    const point = store.state.home.miniUserLocationPoint;
+    if (!point) {
+        return;
+    }
+    VE_API.old_mini_map.get7d({ point }).then(({ data }) => {
+        if (data && data.daily && data.daily.length > 0) {
+            weatherData.value = data;
+            // 设置当前天气(第一天的数据)
+            const today = data.daily[0];
+            currentWeather.value = {
+                temp: today.tempMax || today.tempMin || 26,
+                text: today.textDay || "晴天",
+                iconDay: today.iconDay
+            };
+        }
+    }).catch(() => {
+        // 获取天气数据失败,使用默认值
+    });
+}
+
 // 获取当前日期和星期
 const currentDateText = computed(() => {
     const now = new Date();
@@ -351,6 +412,12 @@ const currentDateText = computed(() => {
             width: 84px;
             height: 73px;
         }
+        .weather-icon {
+            i {
+                font-size: 50px;
+                color: #a7cffb;
+            }
+        }
     }
     .weather-chart-container {
         width: 100%;

+ 10 - 2
src/views/old_mini/home/index.vue

@@ -2,9 +2,9 @@
     <div class="home-index" :style="{ height: `calc(100vh - ${tabBarHeight}px)` }">
         <img class="banner" src="@/assets/img/home/banner.png" alt="" />
         <!-- 天气遮罩 -->
-        <div class="weather-mask" v-show="isExpanded"></div>
+        <div class="weather-mask" v-show="isExpanded" @click="handleMaskClick"></div>
         <!-- 天气 -->
-        <weather-info class="weather-info" @weatherExpanded="weatherExpanded" :isGarden="false" @changeGarden="changeGarden"></weather-info>
+        <weather-info ref="weatherInfoRef" class="weather-info" @weatherExpanded="weatherExpanded" :isGarden="false" @changeGarden="changeGarden"></weather-info>
         <div class="farm-monitor-container" :class="{ 'container-role': curRole == 2 }">
             <div class="farm-monitor-left" @click="handleCardClick(monitorCards.left)">
                 <div class="title">
@@ -173,9 +173,17 @@ onActivated(() => {
 });
 
 const isExpanded = ref(false);
+const weatherInfoRef = ref(null);
 const weatherExpanded = (isExpandedValue) => {
     isExpanded.value = isExpandedValue;
 };
+
+// 点击遮罩时收起天气
+const handleMaskClick = () => {
+    if (weatherInfoRef.value && weatherInfoRef.value.toggleExpand) {
+        weatherInfoRef.value.toggleExpand();
+    }
+};
 </script>
 
 <style scoped lang="scss">

+ 35 - 6
src/views/old_mini/modify_work/completedWork.vue

@@ -12,10 +12,18 @@
             >
                 <div class="status-l" v-if="status === 0">
                     <div class="stauts-text">{{ query.status === "warning" ? "已过期" : "待完成" }}</div>
-                    <div class="stauts-sub-text" v-if="query.status !== 'warning'">
-                        距离预计执行时间还差 <span class="time-text">3</span> 天
+                    <div class="stauts-sub-text" v-if="query.status !== 'warning' && detailData?.executeDate">
+                        <template v-if="daysDiff > 0">
+                            距离预计执行时间还差 <span class="time-text">{{ daysDiff }}</span> 天
+                        </template>
+                        <template v-else-if="daysDiff < 0">
+                            距离预计执行时间已经过去了 <span class="time-text">{{ Math.abs(daysDiff) }}</span> 天
+                        </template>
+                        <template v-else>
+                            预计执行时间为今天
+                        </template>
                     </div>
-                    <div class="stauts-sub-text" v-else>该农事触发但未执行</div>
+                    <div class="stauts-sub-text" v-else-if="query.status === 'warning'">该农事触发但未执行</div>
                 </div>
                 <div class="status-l" v-if="status === 1">
                     <div class="stauts-text">
@@ -23,11 +31,11 @@
                         该农事已完成
                     </div>
                 </div>
-                <template v-if="query.status !== 'warning'">
+                <!-- <template v-if="query.status !== 'warning'">
                     <div class="status-r" v-if="curRole == 0">{{ status === 0 ? "设置提醒" : "去评价" }}</div>
                     <div class="status-r" v-if="curRole == 1">{{ status === 0 ? "提醒执行" : "提醒复核" }}</div>
                     <div class="status-r" v-if="curRole == 2">{{ status === 0 ? "提醒执行" : "提醒复核" }}</div>
-                </template>
+                </template> -->
             </div>
             <div class="work-wrap" v-if="query?.farmWorkOrderId || detailData?.flowStatus === 4">
                 <div class="box-wrap executor-info" v-if="query.status === 'warning' || curRole == 0 || curRole == 2">
@@ -438,7 +446,7 @@ const handleOk = () => {
     if (status.value === 0) {
         showPopup.value = !showPopup.value;
     } else {
-        console.log("立即复核");
+        // 立即复核
     }
 };
 
@@ -735,6 +743,27 @@ const getTriggerImg = async (id) => {
     triggerImg.value = data || [];
 };
 const detailData = ref({});
+
+// 计算距离执行时间的天数差
+const daysDiff = computed(() => {
+    if (!detailData.value?.executeDate) {
+        return 0;
+    }
+    
+    const executeDate = new Date(detailData.value.executeDate);
+    const today = new Date();
+    
+    // 将时间设置为 00:00:00,只比较日期
+    executeDate.setHours(0, 0, 0, 0);
+    today.setHours(0, 0, 0, 0);
+    
+    // 计算天数差(毫秒转天数)
+    const diffTime = executeDate.getTime() - today.getTime();
+    const diffDays = Math.floor(diffTime / (1000 * 60 * 60 * 24));
+    
+    return diffDays;
+});
+
 const getDetail = async (id) => {
     const { data } = await VE_API.z_farm_work_record.getDetail({ id });
     if (data && data.length > 0) {

+ 27 - 22
src/views/old_mini/offer_price/component/editPrice.vue

@@ -54,31 +54,31 @@
                 </el-form-item>
 
                 <el-form-item label="药肥成本" prop="cost" required class="input-unit">
-                    <el-input v-model.number="form.cost" placeholder="请输入">
+                    <el-input v-model="form.cost" type="number" step="0.01" placeholder="请输入">
                         <template #append>元/{{ form.unit }}</template>
                     </el-input>
                 </el-form-item>
 
                 <el-form-item label="药肥报价" prop="price" required class="input-unit">
-                    <el-input v-model.number="form.price" placeholder="请输入">
+                    <el-input v-model="form.price" type="number" step="0.01" placeholder="请输入">
                         <template #append>元/{{ form.unit }}</template>
                     </el-input>
                 </el-form-item>
 
                 <el-form-item label="药肥库存" prop="stock" required class="input-unit">
-                    <el-input v-model.number="form.stock" placeholder="请输入">
+                    <el-input v-model="form.stock" type="number" step="0.01" placeholder="请输入">
                         <template #append>{{ form.unit }}</template>
                     </el-input>
                 </el-form-item>
 
                 <el-form-item label="单位兑水" class="input-unit">
                     <div class="water-row">
-                        <el-input v-model.number="form.waterMin" placeholder="请输入兑水量">
-                            <template #append>kg</template>
+                        <el-input v-model="form.waterMin" type="number" step="0.01" placeholder="请输入兑水量">
+                            <template #append>{{ form.unit }}</template>
                         </el-input>
                         <span>-</span>
-                        <el-input v-model.number="form.waterMax" placeholder="请输入兑水量">
-                            <template #append>kg</template>
+                        <el-input v-model="form.waterMax" type="number" step="0.01" placeholder="请输入兑水量">
+                            <template #append>{{ form.unit }}</template>
                         </el-input>
                     </div>
                 </el-form-item>
@@ -139,7 +139,14 @@ const openDelete = () => {
         cancelButtonText: "取消",
         type: "warning",
     })
-        .then(() => {})
+        .then(() => {
+            VE_API.z_farm_work_pesticide_fertilizer.deleteFertilizer({ agriculturalStoreId: detailData.value.agriculturalStoreId, pesticideFertilizerId: detailData.value.id }).then((res) => {
+                if (res.code === 0) {
+                    ElMessage.success("删除成功");
+                    router.back();
+                }
+            });
+        })
         .catch(() => {});
 };
 
@@ -211,7 +218,6 @@ onMounted(() => {
 });
 
 const specieList = ref([]);
-
 function getSpecieList() {
     VE_API.farm.fetchSpecieList().then(({ data }) => {
         specieList.value = data;
@@ -247,7 +253,6 @@ function fetchTypeOptions() {
             if (res.code === 0) {
                 // 清理空的 children 属性
                 typeOptions.value = cleanEmptyChildren(res.data || []);
-                console.log("typeOptions.value", typeOptions.value);
             }
         });
     }
@@ -265,8 +270,8 @@ function fetchPesticideOptions() {
                 pesticideOptions.value = res.data || [];
             }
         })
-        .catch((error) => {
-            console.error("获取药肥选项失败:", error);
+        .catch(() => {
+            // 获取药肥选项失败
         });
 }
 
@@ -338,6 +343,7 @@ watch(
 );
 
 // 获取详情数据
+const detailData = ref({});
 const getDetail = () => {
     const id = route.query.id;
     if (!id || isAdd.value) {
@@ -348,6 +354,7 @@ const getDetail = () => {
         .fertilizerDetail({ id })
         .then(({ data }) => {
             if (data) {
+                detailData.value = data;
                 // 赋值表单数据
                 form.id = data.id || "";
                 form.brand = data.brand || "";
@@ -369,11 +376,11 @@ const getDetail = () => {
                 form.waterMax = data.unitWaterAmountMax || null;
                 // 适用品种
                 if (data.speciesList && Array.isArray(data.speciesList) && data.speciesList.length > 0) {
-                    form.speciesIds = data.speciesList;
+                    form.speciesIds = data.speciesList.map(item => item.id);
                 } else {
                     form.speciesIds = [];
                 }
-                
+                console.log("form.speciesIds", form.speciesIds, data.speciesList);
                 // 设置级联选择器的默认值(watch 会自动处理)
                 if (form.typeId && typeOptions.value.length > 0) {
                     setCascaderDefaultValue(form.typeId);
@@ -519,7 +526,6 @@ const handleSave = async () => {
     // const speciesIds = Array.isArray(form.crops) 
     //     ? form.crops.join(",") 
     //     : (form.crops || "");
-    console.log("form.speciesIds", form.speciesIds);
     // 构建请求参数
     const params = {
         pesticideFertilizer: {
@@ -531,17 +537,17 @@ const handleSave = async () => {
             defaultName: selectedPesticide.name || "",
             unit: unit,
             // price: selectedPesticide.price || form.price || null,
-            unitWaterAmount: form.waterMin || null,
-            unitWaterAmountMax: form.waterMax || null,
+            unitWaterAmount: form.waterMin ? Number(form.waterMin) : null,
+            unitWaterAmountMax: form.waterMax ? Number(form.waterMax) : null,
             speciesIds: form.speciesIds,
             usageModeList: usageModeList,
             categoryLevel1Name: categoryNames.categoryLevel1Name,
             categoryLevel2Name: categoryNames.categoryLevel2Name,
             categoryLevel3Name: categoryNames.categoryLevel3Name,
         },
-        price: form.price,
-        cost: form.cost,
-        stock: form.stock,
+        price: form.price ? Number(form.price) : null,
+        cost: form.cost ? Number(form.cost) : null,
+        stock: form.stock ? Number(form.stock) : null,
         remark: selectedPesticide.remark || "",
         brand: form.brand,
     };
@@ -559,8 +565,7 @@ const handleSave = async () => {
                 ElMessage.error(res.message || "保存失败");
             }
         })
-        .catch((error) => {
-            console.error("保存失败:", error);
+        .catch(() => {
             ElMessage.error("保存失败,请重试");
         });
 };

+ 33 - 0
src/views/old_mini/price_detail/index.vue

@@ -35,6 +35,7 @@
                                     v-model="executionMethod"
                                     placeholder="执行方式"
                                     style="width: 132px"
+                                    @change="handleExecutionMethodChange"
                                 >
                                     <el-option
                                         v-for="(item, index) in modeList"
@@ -272,6 +273,30 @@ const confirmPrice = () => {
         ElMessage.error("请选择执行方式");
         return;
     }
+    
+    // 检查服务费用是否有价格
+    if (!servicePricePerMu.value || servicePricePerMu.value <= 0) {
+        ElMessage.error("请填写服务费用");
+        return;
+    }
+    
+    // 检查是否所有药肥都有价格
+    if (detailData.value?.prescriptionList) {
+        const emptyPriceItems = [];
+        detailData.value.prescriptionList.forEach(prescription => {
+            (prescription.pesticideFertilizerList || []).forEach(pesticide => {
+                if (!pesticide.price || pesticide.price <= 0) {
+                    emptyPriceItems.push(pesticide.pesticideFertilizerName || '药肥');
+                }
+            });
+        });
+        
+        if (emptyPriceItems.length > 0) {
+            ElMessage.error(`请填写${emptyPriceItems[0]}的价格`);
+            return;
+        }
+    }
+    
     const pesticideFertilizerQuoteList = [];
     if (detailData.value?.prescriptionList) {
         detailData.value.prescriptionList.forEach(prescription => {
@@ -302,6 +327,14 @@ const confirmPrice = () => {
         }
     })
 }
+
+const handleExecutionMethodChange = (val) => {
+    if (val == 1) {
+        servicePricePerMu.value = priceData.value.uavServicePrice
+    } else {
+        servicePricePerMu.value = priceData.value.manualServicePrice
+    }
+}
 </script>
 
 <style lang="scss" scoped>