Selaa lähdekoodia

fix: 对接农资和农户农事操作

lxf 23 tuntia sitten
vanhempi
commit
a7bdd25ae7

+ 4 - 0
src/api/modules/z_farm_work_record_cost.js

@@ -6,4 +6,8 @@ module.exports = {
         url: url + "/listByOrderId",
         type: "get",
     },
+    selectQuote: {
+        url: url + "/selectQuote",
+        type: "post",
+    },
 }

+ 21 - 5
src/components/popup/priceSheetPopup.vue

@@ -1,5 +1,5 @@
 <template>
-    <popup class="price-sheet-popup" v-model:show="showPopup" :close-on-click-overlay="false">
+    <popup class="price-sheet-popup" v-model:show="showPopup">
         <div class="price-sheet-content">
             <div class="price-sheet-content-inner">
                 <!-- 顶部标题区域 -->
@@ -94,21 +94,21 @@
             </div>
 
             <!-- 底部操作按钮 -->
-            <div class="bottom-actions">
+            <div class="bottom-actions" @click.stop="showPopup = false">
                 <div class="action-buttons">
-                    <div class="action-btn blue-btn">
+                    <div class="action-btn blue-btn" @click.stop="handleShare">
                         <div class="icon-circle">
                             <img src="@/assets/img/home/bird.png" alt="" />
                         </div>
                         <span class="btn-label">飞鸟用户</span>
                     </div>
-                    <div class="action-btn green-btn">
+                    <div class="action-btn green-btn" @click.stop="handleWechat">
                         <div class="icon-circle">
                             <img src="@/assets/img/home/wechat.png" alt="" />
                         </div>
                         <span class="btn-label">微信</span>
                     </div>
-                    <div class="action-btn orange-btn">
+                    <div class="action-btn orange-btn" @click.stop="handleSaveImage">
                         <div class="icon-circle">
                             <el-icon :size="24"><Download /></el-icon>
                         </div>
@@ -201,6 +201,22 @@ function fetchPriceData() {
     });
 }
 
+const handleShare = () => {
+    console.log("handleShare");
+};
+
+const handleWechat = () => {
+    console.log("handleWechat");
+    router.push({
+        path: "/completed_work",
+        query: { id: quotationData.value.id, farmWorkOrderId: quotationData.value.orderId },
+    });
+};
+
+const handleSaveImage = () => {
+    console.log("handleSaveImage");
+};
+
 const handleEdit = () => {
     // 编辑报价逻辑
     // 可以触发编辑事件或打开编辑页面

+ 2 - 0
src/router/globalRoutes.js

@@ -110,6 +110,7 @@ export default [
     {
         path: "/completed_work",
         name: "CompletedWork",
+        meta: { keepAlive: true },
         component: () => import("@/views/old_mini/modify_work/completedWork.vue"),
     },
     // 我的档案
@@ -204,6 +205,7 @@ export default [
     {
         path: "/price_detail",
         name: "PriceDetail",
+        meta: { keepAlive: true },
         component: () => import("@/views/old_mini/price_detail/index.vue"),
     },
     // 报价维护

+ 6 - 47
src/views/old_mini/agri_work/components/priceTable.vue

@@ -11,7 +11,7 @@
             </div>
             <div
                 class="new-table-wrap"
-                v-for="(prescriptionItem, prescriptionI) in prescriptioData.prescriptionList"
+                v-for="(prescriptionItem, prescriptionI) in prescriptionData"
                 :key="prescriptionI"
             >
                 <div
@@ -38,52 +38,11 @@
 </template>
 
 <script setup>
-import { ref } from "vue";
-
-const prescriptioData = ref({
-    prescriptionList: [
-        {
-            name: "营养",
-            pesticideFertilizerList: [
-                {
-                    key: 1,
-                    typeName: "营养",
-                    defaultName: "乙烯利",
-                    brand: "国光",
-                    price: "5元/ml",
-                    dosage: "300ml",
-                    total: "500",
-                    muUsage: "50",
-                    muUsage2: "500",
-                    ratio: "400",
-                    ratio2: "400",
-                    unit: "ml",
-                    remark: "这是是用药注意事项的备注,这是是用药注意事项的备注",
-                },
-            ],
-        },
-        {
-            name: "生长",
-            pesticideFertilizerList: [
-                {
-                    key: 1,
-                    typeName: "生长",
-                    defaultName: "矿源黄腐酸钾",
-                    brand: "国光",
-                    price: "5元/ml",
-                    dosage: "300ml",
-                    total: "500",
-                    muUsage: "50",
-                    muUsage2: "500",
-                    ratio: "400",
-                    ratio2: "400",
-                    unit: "ml",
-                    remark: "这是是用药注意事项的备注,这是是用药注意事项的备注",
-                },
-            ],
-        },
-    ],
-    usageMode: "叶面施",
+const props = defineProps({
+    prescriptionData: {
+        type: Array,
+        default: () => []
+    }
 });
 </script>
 

+ 13 - 4
src/views/old_mini/farm_manage/components/demandHall.vue

@@ -66,7 +66,7 @@
                                         <div class="btn second">
                                             转发给客户
                                         </div>
-                                        <div class="btn primary" @click="toPage(item)">
+                                        <div class="btn primary" @click="showPriceSheetPopup(item)">
                                             生成报价单
                                         </div>
                                     </div>
@@ -80,6 +80,8 @@
             </div>
         </floating-panel>
     </div>
+    <!-- 服务报价单 -->
+    <price-sheet-popup ref="priceSheetPopupRef"></price-sheet-popup>
 </template>
 
 <script setup>
@@ -89,6 +91,7 @@ import { useStore } from "vuex";
 import IndexMap from "../map/index";
 import taskItem from "@/components/taskItem.vue";
 import { Search } from "@element-plus/icons-vue";
+import priceSheetPopup from "@/components/popup/priceSheetPopup.vue";
 import { useRouter } from "vue-router";
 const props = defineProps({
     isCapital: {
@@ -175,9 +178,15 @@ const handleHeightChange = ({ height }) => {
     }
 };
 
-function toPage() {
-    console.log('topage');
-}
+
+const priceSheetPopupRef = ref(null);
+const showPriceSheetPopup = (item) => {
+    VE_API.z_farm_work_record.getDetail({ id: item.id }).then(({ data }) => {
+        const res = data[0];
+        priceSheetPopupRef.value.handleShowPopup(res);
+    });
+};
+
 
 </script>
 

+ 11 - 8
src/views/old_mini/farm_manage/map/index.js

@@ -414,14 +414,17 @@ class IndexMap {
     //   "serviceRegion": "广州市从化区荔枝博览园",
     //   "cost": null,
     // }]
-    for (let item of taskList) {
-      item.mapInfo = item.executeDate?.replace(/^\d{4}-(\d{2})-(\d{2})$/, '$1.$2') + '  ' + item.farmWorkName
-      this.gardenPointLayer.source.addFeature(newPoint(item, "point", "myGarden"))
-    }
-    this.kmap.getView().fit(this.gardenPointLayer.source.getExtent(), { padding: [20, 2, 20, 2] });
-    const finalZoom = this.kmap.getView().getZoom();
-    if (finalZoom > 18) {
-      this.kmap.getView().setZoom(18);
+    this.gardenPointLayer.source.clear();
+    if (taskList.length > 0) {  // 如果任务列表不为空,则添加任务点
+      for (let item of taskList) {
+        item.mapInfo = item.executeDate?.replace(/^\d{4}-(\d{2})-(\d{2})$/, '$1.$2') + '  ' + item.farmWorkName
+          this.gardenPointLayer.source.addFeature(newPoint(item, "point", "myGarden"))
+        }
+        this.kmap.getView().fit(this.gardenPointLayer.source.getExtent(), { padding: [20, 2, 20, 2] });
+        const finalZoom = this.kmap.getView().getZoom();
+        if (finalZoom > 18) {
+          this.kmap.getView().setZoom(18);
+        }
     }
   }
 }

+ 98 - 22
src/views/old_mini/modify_work/completedWork.vue

@@ -29,8 +29,8 @@
                     <div class="status-r" v-if="curRole == 2">{{ status === 0 ? "提醒执行" : "提醒复核" }}</div>
                 </template>
             </div>
-            <div class="work-wrap" v-if="detailData?.orderStatus === 4 || detailData?.orderStatus === 5">
-                <div class="box-wrap executor-info" v-if="query.status === 'warning' || curRole == 1 || curRole == 2">
+            <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">
                     <!-- <div class="executor-title">执行人</div> -->
                     <div class="executor-content">
                         <div class="executor-info mt-0">
@@ -42,7 +42,7 @@
                             </div>
                             <div class="executor-details">
                                 <div class="org-name">
-                                    <span class="name">河南农资农服组织</span>
+                                    <span class="name">{{ quotationData.agriculturalStoreName || '--' }}</span>
                                     <span class="rating">5.0分</span>
                                 </div>
                                 <div class="service-info">
@@ -56,23 +56,23 @@
                         <div class="farm-info">
                             <div class="info-title-wrap">
                                 <div class="sub-title">肥药费用</div>
-                                <div class="info-more">1582<span class="unit-text">元</span></div>
+                                <div class="info-more">{{ quotationData.pesticideFertilizerCost || '--' }}<span class="unit-text">元</span></div>
                             </div>
                             <div class="info-content-wrap">
-                                <price-table>
+                                <price-table :prescriptionData="quotationData.prescriptionList">
                                     <template #bottomContent>
                                         <div class="price-bottom">
                                             <div class="info-title-wrap">
                                                 <div class="sub-title">服务费用</div>
-                                                <div class="info-more">1582<span class="unit-text">元</span></div>
+                                                <div class="info-more">{{ quotationData.farmWorkServiceCost || '--' }}<span class="unit-text">元</span></div>
                                             </div>
                                             <div class="price-info">
-                                                <div class="info-l">执行方式<span class="main-text">无人机</span></div>
-                                                <div class="info-c">亩单价<span class="main-text">500元/亩</span></div>
-                                                <div class="info-r">亩数<span class="main-text">10亩</span></div>
+                                                <div class="info-l">执行方式<span class="main-text">{{ quotationData.executionMethodName || '--' }}</span></div>
+                                                <div class="info-c">亩单价<span class="main-text">{{ quotationData.farmWorkServiceCost ? (quotationData.farmWorkServiceCost + '元/亩') : '--' }}</span></div>
+                                                <div class="info-r">亩数<span class="main-text">{{ quotationData.area ? (quotationData.area + '亩') : '--' }}</span></div>
                                             </div>
                                             <div class="price-total">
-                                                报价合计:<span class="main-val">1258</span>元
+                                                报价合计:<span class="main-val">{{ quotationData.totalCost || '--' }}</span>元
                                             </div>
                                         </div>
                                     </template>
@@ -233,15 +233,16 @@
             </div>
             <div
                 class="fixed-btn-wrap"
-                :class="{ center: currentStep == 0 || (detailData?.flowStatus == 3 && curRole == 0) || (detailData?.flowStatus == 4 && curRole == 2) || (detailData?.flowStatus == 2 && curRole == 0)}"
+                :class="{ center: currentStep == 0 || (detailData?.flowStatus == 3 && curRole == 0) || (detailData?.flowStatus == 4 && curRole == 2) || (detailData?.flowStatus == 2 && curRole == 0) || (detailData?.flowStatus == 4 && curRole == 0)}"
                 v-if="query.status !== 'warning'"
             >
-                <div class="fixed-btn expert" v-if="currentStep == 0">提醒农事确认</div>
-                <div class="fixed-btn expert excute" v-if="detailData?.flowStatus == 3 && curRole == 0">确认对方执行</div>
+                <!-- <div class="fixed-btn expert">提醒农事确认</div> -->
+                <div class="fixed-btn expert excute" v-if="detailData?.flowStatus == 2 && query?.farmWorkOrderId && curRole == 0" @click="handleConfirmExecute">确认对方执行</div>
                 <div class="fixed-btn expert" v-if="detailData?.flowStatus == 5 && curRole == 0">确认对方完成</div>
+                <div class="fixed-btn expert" v-if="detailData?.flowStatus == 4 && curRole == 0">提醒对方执行</div>
                 <div class="fixed-btn expert" v-if="currentStep == 2 && curRole == 2">请求确认</div>
                 <div class="fixed-btn orange" v-if="detailData?.flowStatus == 1 && curRole == 0" @click="handleDemand">发起需求</div>
-                <div class="fixed-btn orange" v-if="detailData?.flowStatus == 2 && curRole == 0" @click="cancelDemand">取消发起</div>
+                <div class="fixed-btn orange" v-if="detailData?.flowStatus == 2 && !(query?.farmWorkOrderId) && curRole == 0" @click="cancelDemand">取消发起</div>
                 <div class="fixed-btn" v-if="detailData?.flowStatus == 1 && curRole == 0" @click="handleOk">我已完成</div>
             </div>
 
@@ -269,7 +270,7 @@
         </template>
         <template v-else>
             <img class="farm-check-icon" src="@/assets/img/home/right.png" alt="">
-            <div class="create-farm-text success-text">需求已发送成功</div>
+            <div class="create-farm-text success-text">{{ successText }}</div>
         </template>
         <div class="create-farm-btn" @click="handlePopupBtn">{{ taskPopupType === 'warning' ? '确认' : '我知道了' }}</div>
     </popup>
@@ -286,6 +287,7 @@ import { useRouter, useRoute } from "vue-router";
 import farmSteps from "@/components/farmSteps.vue";
 import priceTable from "../agri_work/components/priceTable.vue";
 import priceSheetPopup from "@/components/popup/priceSheetPopup.vue";
+import { ElMessage } from "element-plus";
 
 const router = useRouter();
 const store = useStore();
@@ -313,11 +315,13 @@ const handleOk = () => {
     }
 };
 
+const successText = ref('');
 const handleDemand = () => {
     // router.push("/share_page");
     VE_API.z_farm_work_record.updateFlowStatus({ id: query.id, targetFlowStatus: 2 }).then((res) => {
         if (res.code === 0) {
             taskPopupType.value = 'success';
+            successText.value = '需求已发送成功';
             showTaskPopup.value = true;
         }
     })
@@ -351,13 +355,85 @@ const showPriceSheetPopup = () => {
     priceSheetPopupRef.value.handleShowPopup(detailData.value);
 };
 
+const handleConfirmExecute = () => {
+    VE_API.z_farm_work_record_cost.selectQuote({ farmWorkRecordId: query.id, agriculturalId: quotationData.value.agriculturalId }).then((res) => {
+    if (res.code === 0) {
+        taskPopupType.value = 'success';
+        successText.value = '农事已锁单成功';
+        showTaskPopup.value = true;
+    }
+})
+};
 // 地图
 // const areaRef = ref(null);
 // let newFarmMap = new NewFarmMap();
-onMounted(() => {
+const quotationData = ref({});
+onMounted(async () => {
     const id = query.id;
     if (id) {
-        getDetail(id);
+        await getDetail(id);
+    }
+    if (query.farmWorkOrderId || detailData.value?.flowStatus === 4) {
+        const farmWorkOrderId = query.farmWorkOrderId || detailData.value.orderId;
+        const { data } = await VE_API.z_farm_work_record_cost.listByOrderId({ farmWorkOrderId });
+        if (data && data.length > 0) {
+            const priceDataObj = data[0];
+            
+            // 合并外层字段
+            quotationData.value = {
+                ...detailData.value,
+                ...priceDataObj,
+                agriculturalId: priceDataObj.agriculturalId,
+            };
+            console.log("quotationData.value", quotationData.value);
+            
+            // 根据 itemsList 的 pesticideFertilizerId 匹配并赋值品牌和价格
+            if (priceDataObj.itemsList && Array.isArray(priceDataObj.itemsList) && detailData.value.prescriptionList) {
+                // 创建价格映射表
+                const priceMap = new Map();
+                priceDataObj.itemsList.forEach(item => {
+                    priceMap.set(String(item.pesticideFertilizerId), {
+                        brand: item.brand || '',
+                        price: item.price || 0,
+                        totalPrice: item.totalPrice || null
+                    });
+                });
+                
+                // 遍历处方列表,赋值品牌和价格,并计算格式化字段供 price-table 使用
+                quotationData.value.prescriptionList = detailData.value.prescriptionList.map(prescription => {
+                    return {
+                        ...prescription,
+                        pesticideFertilizerList: prescription.pesticideFertilizerList.map(pesticide => {
+                            const pesticideId = String(pesticide.pesticideFertilizerId || '');
+                            const priceInfo = priceMap.get(pesticideId);
+                            
+                            if (priceInfo) {
+                                const price = priceInfo.price || 0;
+                                const muUsage = pesticide.muUsage || 0;
+                                const unit = pesticide.unit || '';
+                                const area = detailData.value.area || 0;
+                                
+                                // 计算总价:优先使用 totalPrice,否则计算 price * muUsage * area
+                                const total = priceInfo.totalPrice !== null && priceInfo.totalPrice !== undefined 
+                                    ? priceInfo.totalPrice 
+                                    : (price * muUsage * area);
+                                
+                                return {
+                                    ...pesticide,
+                                    brand: priceInfo.brand || '--',
+                                    totalPrice: priceInfo.totalPrice,
+                                    // 格式化字段供 price-table 组件使用
+                                    price: price > 0 ? `${price}元/${unit}` : '--', // 格式化单价显示
+                                    dosage: muUsage > 0 ? `${muUsage}${unit}` : '--', // 格式化用量显示
+                                    total: total > 0 ? total.toFixed(2) : '--' // 格式化总价显示
+                                };
+                            }
+                            return pesticide;
+                        })
+                    };
+                });
+            }
+        }
     }
     // const point = store.state.home.miniUserLocationPoint;
     // if (areaRef.value) {
@@ -371,12 +447,12 @@ onMounted(() => {
 });
 
 const detailData = ref({});
-const getDetail = (id) => {
-    VE_API.z_farm_work_record.getDetail({ id }).then(({ data }) => {
-        const res = data[0];
-        detailData.value = res;
+const getDetail = async (id) => {
+    const { data } = await VE_API.z_farm_work_record.getDetail({ id });
+    if (data && data.length > 0) {
+        detailData.value = data[0];
         currentStep.value = getCurrentStep(detailData.value.flowStatus);
-    });
+    }
 };
 
 function getCurrentStep(flowStatus) {

+ 9 - 6
src/views/old_mini/price_detail/index.vue

@@ -87,7 +87,7 @@
                             <div class="item-val">
                                 <el-select
                                     class="select-item"
-                                    v-model="modeVal"
+                                    v-model="executionMethod"
                                     placeholder="执行方式"
                                     style="width: 132px"
                                 >
@@ -146,7 +146,7 @@ const detailData = ref(JSON.parse(query.data));
 const priceData = ref({});
 
 const servicePricePerMu = ref(0);
-const modeVal = ref(null);
+const executionMethod = ref(null);
 const modeList = ref([
     {name: "无人机", value: 1},
     {name: "人工", value: 2},
@@ -154,12 +154,12 @@ const modeList = ref([
 
 // 初始化数据
 onMounted(() => {
-    console.log("query", query);
     executeDate.value = detailData.value.executeDate;
     priceData.value = JSON.parse(query?.priceData || '{}');
     
     // 从 priceData 中匹配价格和品牌到对应的药肥
     if (priceData.value.itemsList && detailData.value.prescriptionList) {
+        // executionMethod.value = priceData.value.executionMethod;
         detailData.value.prescriptionList.forEach(prescription => {
             if (prescription.pesticideFertilizerList) {
                 prescription.pesticideFertilizerList.forEach(pesticide => {
@@ -221,7 +221,7 @@ const getTotalCost = () => {
 }
 
 const confirmPrice = () => {
-    if (!modeVal.value) {
+    if (!executionMethod.value) {
         ElMessage.error("请选择执行方式");
         return;
     }
@@ -241,7 +241,7 @@ const confirmPrice = () => {
         farmWorkRecordId: detailData.value?.id,
         pesticideFertilizerQuoteList,
         servicePrice: servicePricePerMu.value,
-        executionMethod: modeVal.value,
+        executionMethod: executionMethod.value,
     };
     console.log('confirmPrice payload =>', payload);
     VE_API.z_farm_work_record.acceptFarmWorkRecord(payload).then(({ data }) => {
@@ -276,7 +276,10 @@ const confirmPrice = () => {
                 text-align: center;
             }
             .el-select__placeholder {
-                color: rgba(33, 153, 248, 0.6);
+                color: #2199f8;
+                &.is-transparent {
+                    color: rgba(33, 153, 248, 0.6);
+                }
                 text-align: center;
             }
             .el-input__prefix {

+ 12 - 2
src/views/old_mini/task_condition/components/task.vue

@@ -206,6 +206,8 @@ function getSimpleList() {
         } else {
             taskList.value = [];
             taskCounts.value[activeIndex.value] = 0;
+            indexMap.initData(taskList.value)
+            calendarRef.value && calendarRef.value.setSolarTerm(taskList.value)
             noData.value = true;
         }
     }).catch((error) => {
@@ -226,8 +228,16 @@ function toPage(item) {
         uploadExecuteRef.value.showPopup();
     } else {
         // 下发农事请求
-        taskPopupType.value = 'success';
-        showTaskPopup.value = true;
+        const data = {
+            id: item.id,
+        };
+        VE_API.z_farm_work_record.issueFarmWorkRecord(data).then((res) => {
+            if (res.code === 0) {
+                taskPopupType.value = 'success';
+                showTaskPopup.value = true;
+                getSimpleList()
+            }
+        })
         // router.push("/service_agri");
     }
 }