Prechádzať zdrojové kódy

feat:对接农事服务过往总数和对接农户的农情互动功能

wangsisi 16 hodín pred
rodič
commit
54ec3c0333

+ 4 - 2
src/App.vue

@@ -130,7 +130,7 @@ import { Tabbar, TabbarItem } from "vant";
 import { nextTick, watch, onMounted, ref } from "vue";
 import { useRoute, useRouter } from "vue-router";
 import { useStore } from "vuex";
-// import {NH,NF,NZ,EXPERT} from "@/common/user_role";
+import {NH,NZ,EXPERT} from "@/common/user_role";
 const store = useStore();
 const route = useRoute();
 const router = useRouter();
@@ -138,11 +138,12 @@ const router = useRouter();
 // 首页loading加载完才显示底部导航栏
 const showTab = ref(false);
 // 0: 农户, 1: 专家, 2:农资农服
-const curRole = ref(localStorage.getItem("SET_USER_CUR_ROLE"));
+const curRole = ref(0);
 
 let tabBarHeight = 0;
 onMounted(() => {
     setTimeout(() => {
+        curRole.value = store.state.app.curRole;
         if (route.meta.showTabbar) {
             showTab.value = true;
         }
@@ -172,6 +173,7 @@ watch(
                 localStorage.setItem("tabBarHeight", tabBarHeight);
                 store.commit("home/SET_TAB_BAR_HEIGHT", tabBarHeight);
             }
+            curRole.value = store.state.app.curRole
         });
     },
     { immediate: false }

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

@@ -25,5 +25,10 @@ module.exports = {
     getFutureFarmWorkList: {
         url: config.base_dev_url + "container_farm_work_arrange/futureFarmWorkList/{page}/{limit}",
         type: "get",
+    },
+    //统计农场的过往农事服务成本
+    getFarmPastServiceCost: {
+        url: config.base_dev_url + "z_farm_work_record_cost/statistics",
+        type: "get",
     }
 }

BIN
src/assets/img/home/example-4.png


+ 11 - 0
src/common/user_role.js

@@ -0,0 +1,11 @@
+// 定义用户角色枚举
+const UserRole = {
+    NH: 0,//"农户"
+    // NF: 1,//"农服"
+    NZ: 2,//"农资"
+    EXPERT: 3,//"专家"
+};
+
+export const NH = UserRole.NH;
+export const NZ = UserRole.NZ;
+export const EXPERT = UserRole.EXPERT;

+ 4 - 3
src/components/detailDialog.vue

@@ -69,7 +69,7 @@
             </div>
 
             <div class="bottom-btn">
-                <div class="btn-item secondary-btn" @click="toPage">转发</div>
+                <div class="btn-item secondary-btn" @click="toPage">{{ btnText }}</div>
                 <div class="btn-item primary-btn" @click="triggerClick">触发农事</div>
             </div>
         </div>
@@ -110,7 +110,7 @@ const props = defineProps({
 
 const winDialogVisible = ref(false);
 const noShow = ref(false);
-
+const btnText = ref('');
 const route = useRoute();
 const router = useRouter();
 const sampleId = route.query.sampleId;
@@ -132,7 +132,8 @@ const triggerClick = () => {
 };
 
 const dialogData = ref({})
-const showDialog = (id) => {
+const showDialog = (id,btnTextVal = '转发') => {
+    btnText.value = btnTextVal;
     if (id) {
         VE_API.farm
             .getFarmWorkLib({ id })

+ 25 - 9
src/components/popup/activeUploadPopup.vue

@@ -15,8 +15,11 @@
                 <el-date-picker v-model="uploadDate" size="large" style="width: 100%" type="date" placeholder="请选择日期" />
             </div>
         </div>
-        <div class="tips-text">上传照片,专家诊断更准确哦~</div>
-        <upload :textShow="true" class="upload-wrap"></upload>
+        <div class="tips-text">上传照片,诊断更准确哦~</div>
+        <upload :textShow="true" class="upload-wrap" exampleImg placeholderImg>
+            <img class="example" src="@/assets/img/home/example-4.png" alt="" />
+            <img class="example" src="@/assets/img/home/plus.png" alt="">
+        </upload>
         <div class="btn" @click="handleUpload">确认</div>
     </popup>
 
@@ -25,7 +28,7 @@
         <div class="success-wrap">
             <img class="success-icon" src="@/assets/img/home/right.png" alt="" />
             <div class="success-title">好的,感谢您的配合</div>
-            <div class="success-sub">请您耐心等待专家确认农事</div>
+            <div class="success-sub">请您耐心等待农事确认</div>
             <div class="btn" @click="successShow = false">我知道了</div>
         </div>
     </popup>
@@ -44,7 +47,6 @@ const images = ref([]);
 const uploadDate = ref("");
 const problemTitle = ref("请选择问题");
 const successShow = ref(false);
-
 onMounted(() => {
     eventBus.off("upload:changeArr", uploadChange);
     eventBus.on("upload:changeArr", uploadChange);
@@ -63,19 +65,22 @@ function formatDate(date) {
     return `${year}-${month}-${day}`;
 }
 
-function handleShow({ gardenIdVal, problemTitleVal }) {
-    console.log("activeUpload:show event received", { gardenIdVal, problemTitleVal });
+const type = ref(null);
+function handleShow({ gardenIdVal, problemTitleVal,typeVal }) {
     images.value = [];
     gardenId.value = gardenIdVal;
     problemTitle.value = problemTitleVal || "请选择问题";
     uploadDate.value = formatDate(new Date());
     show.value = true;
+    type.value = typeVal;
 }
 
 function handleSuccess() {
     successShow.value = true;
 }
 
+const emit = defineEmits(['handleUploadSuccess']);
+
 const handleUpload = () => {
     if (images.value.length === 0) return ElMessage.warning("请上传图片");
     const params = {
@@ -84,13 +89,17 @@ const handleUpload = () => {
         uploadDate: uploadDate.value,
     };
     // 提交成功后的反馈弹窗(示例直接展示)
-    show.value = false;
-    successShow.value = true;
+    if(type.value === 'question'){
+        show.value = false;
+        emit("handleUploadSuccess",params);
+    }else{
+        show.value = false;
+        successShow.value = true;
+    }
     // VE_API.ali.uploadImg(params).then((res) => {
     //     if (res.success) {
     //         show.value = false;
     //         successShow.value = true;
-    //         eventBus.emit("confirm:callback");
     //     }
     // });
 };
@@ -140,6 +149,13 @@ onUnmounted(() => {
     .upload-wrap {
         margin: 12px 0 24px;
     }
+    .example {
+        width: 80px;
+        height: 80px;
+    }
+    .example + .example {
+        margin-left: 12px;
+    }
 }
 
 .btn {

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

@@ -22,7 +22,7 @@
                     <field v-model="farmInfo.fzr" readonly label="联系人" />
                     <field v-model="farmInfo.tel" readonly label="联系电话" />
                     <field class="address-field" v-model="farmInfo.address" readonly label="农场位置" />
-                    <checkbox class="checkbox" icon-size="16px" shape="square" v-model="farmInfo.defaultOption">是否勾选为默认农场</checkbox>
+                    <checkbox v-if="!showBtn" class="checkbox" icon-size="16px" shape="square" v-model="farmInfo.defaultOption">是否勾选为默认农场</checkbox>
                 </cell-group>
             </div>
             <div class="popup-footer" v-if="!showBtn">

+ 44 - 29
src/views/old_mini/home/components/problemReminder.vue

@@ -44,9 +44,9 @@
         <div class="no-popup-btn" @click="noShow = false">我知道了</div>
     </Popup>
     <!-- 农事信息弹窗 -->
-    <detail-dialog ref="detailDialogRef"></detail-dialog>
+    <detail-dialog ref="detailDialogRef" :show-success-only="true"></detail-dialog>
     <!-- 新增:激活上传弹窗 -->
-    <active-upload-popup></active-upload-popup>
+    <active-upload-popup @handleUploadSuccess="handleUploadSuccess"></active-upload-popup>
 </template>
 <script setup>
 import { Popup } from "vant";
@@ -56,12 +56,13 @@ import activeUploadPopup from "@/components/popup/activeUploadPopup.vue";
 import detailDialog from "@/components/detailDialog.vue";
 import eventBus from "@/api/eventBus";
 import { useRouter } from "vue-router";
+import { sassTrue } from "sass";
 const router = useRouter();
 
 const show = ref(false);
 const noShow = ref(false);
 const dropdownGardenItem = ref({
-    organId: 766,
+    organId: 93490,
     periodId: 1,
     wktVal: "wktVal",
     address: "address",
@@ -87,7 +88,7 @@ const questPopupData = ref({});
 const bottomAnswerOptions = ref([]);
 const fetchQuestPopup = () => {
     VE_API.home
-        .fetchQuestPopup({ farmId: 766 })
+        .fetchQuestPopup({ farmId: 93490 })
         .then(({ data }) => {
             if (Array.isArray(data) && data.length > 0) {
                 show.value = true;
@@ -137,40 +138,54 @@ function isYesOption(opt) {
     return yesKeywords.some((k) => label.toLowerCase().includes(k.toLowerCase()));
 }
 
+const optValue = ref(null);
 function onBottomOptionClick(opt) {
+    show.value = false;
+    optValue.value = opt.value;
+    if (opt.value == 1) {
+        eventBus.emit("activeUpload:show", {
+            gardenIdVal: 93490,
+            problemTitleVal: "请选择您出现白点的时间",
+            typeVal: "question",
+        });
+    } else {
+        saveQuestPopup();
+    }
+}
+
+function saveQuestPopup() {
     const agriDate = getTodayStr();
-    VE_API.home
-        .saveQuestPopup({
-            farmId: 766,
-            phenologyId: questPopupData.value.phenologyId,
-            indicatorId: questPopupData.value.indicatorId,
-            answerValue: opt.value,
-            agriDate: agriDate,
-        })
-        .then((res) => {
-            if (res.code === 0) {
-                if (opt.value == 1) {
-                    show.value = false;
-                    // 打开同级的激活上传弹窗
-                    eventBus.emit("activeUpload:show", {
-                        gardenIdVal: 766,
-                        problemTitleVal: '请选择您出现白点的时间',
-                    });
-                } else {
-                    show.value = false;
-                    noShow.value = true;
-                }
+    const params = {
+        farmId: 93490,
+        phenologyId: questPopupData.value.phenologyId,
+        indicatorId: questPopupData.value.indicatorId,
+        answerValue: optValue.value,
+        agriDate: agriDate,
+    };
+    params.imagePaths = images.value;
+    VE_API.home.saveQuestPopup(params).then((res) => {
+        if (res.code === 0) {
+            show.value = false;
+            if (optValue.value != 1) {
+                noShow.value = true;
             }
-        });
+        }
+    });
 }
 
 function getTodayStr() {
     const d = new Date();
     const y = d.getFullYear();
-    const m = String(d.getMonth() + 1).padStart(2, '0');
-    const day = String(d.getDate()).padStart(2, '0');
+    const m = String(d.getMonth() + 1).padStart(2, "0");
+    const day = String(d.getDate()).padStart(2, "0");
     return `${y}-${m}-${day}`;
 }
+const images = ref([]);
+function handleUploadSuccess(params) {
+    images.value = params.images;
+    saveQuestPopup();
+    detailDialogRef.value.showDialog("708734452137725952", "咨询专家");
+}
 </script>
 <style lang="scss" scoped>
 .problem-reminder-popup {
@@ -221,7 +236,7 @@ function getTodayStr() {
                 margin: 12px 0;
                 width: 100%;
                 height: 140px;
-                img{
+                img {
                     width: 100%;
                     height: 100%;
                     border-radius: 6px;

+ 3 - 3
src/views/old_mini/home/index.vue

@@ -72,18 +72,18 @@ const farmPopupType = ref("create");
 const monitorCards = ref({
     left: {
         title: "农场监测",
-        content: "实时监测农场环境和作物生长情况",
+        content: "实时监测农场状态",
         route: "/monitor",
     },
     right: [
         {
             title: "病虫识别",
-            content: "智能识别病虫害,提供防治建议",
+            content: "精准识别病虫",
             route: "/pest",
         },
         {
             title: "专家咨询",
-            content: "专业农技专家在线解答疑问",
+            content: "专家多年经验指导",
             route: "/chat_frame",
         },
     ],

+ 67 - 43
src/views/old_mini/user/farmDetails.vue

@@ -21,29 +21,36 @@
                         <template #right>
                             <span @click="handleDetail('farm_list')">查看详情</span>
                         </template>
-                        <div class="question-header">
-                            <img class="question-icon" src="@/assets/img/home/ask-icon.png" alt="" />
-                            <div class="question-title">{{ farmWorkData.quest }}</div>
-                        </div>
-                        <template v-if="isImg">
-                            <div class="answer-content">
-                                答:{{ farmWorkData.agriDate }} {{ farmWorkData.answerLabel }}出现{{
-                                    farmWorkData.indicatorName
-                                }}
+                        <template v-if="farmWorkData.quest">
+                            <div class="question-header">
+                                <img class="question-icon" src="@/assets/img/home/ask-icon.png" alt="" />
+                                <div class="question-title">{{ farmWorkData.quest }}</div>
                             </div>
-                            <div class="answer-img">
-                                <img src="https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png" alt="" />
-                                <img src="https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png" alt="" />
-                                <img src="https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png" alt="" />
+                            <template v-if="farmWorkData.images.length">
+                                <div class="answer-content">
+                                    答:{{ farmWorkData.agriDate }} {{ farmWorkData.answerLabel }}出现{{
+                                        farmWorkData.indicatorName
+                                    }}
+                                </div>
+                                <div class="answer-img">
+                                    <img v-for="image in farmWorkData.images" :key="image" :src="config.base_img_url2 + image.cloudFilename" alt="" />
+                                </div>
+                            </template>
+                            <div v-else class="answer-btn">
+                                <div class="answer-btn-item">转发给客户</div>
+                                <div class="answer-btn-item-group">
+                                    <div class="answer-btn-item">否</div>
+                                    <div class="answer-btn-item primary">是</div>
+                                </div>
                             </div>
                         </template>
-                        <div v-else class="answer-btn">
-                            <div class="answer-btn-item">转发给客户</div>
-                            <div class="answer-btn-item-group">
-                                <div class="answer-btn-item">否</div>
-                                <div class="answer-btn-item primary">是</div>
-                            </div>
-                        </div>
+                        <empty
+                            v-else
+                            image="https://fastly.jsdelivr.net/npm/@vant/assets/custom-empty-image.png"
+                            image-size="80"
+                            description="暂无数据"
+                            class="empty-state"
+                        />
                     </common-box>
                 </tab>
                 <tab title="农事服务" class="tab-item">
@@ -70,6 +77,13 @@
                                 class="recipe-item"
                             />
                         </div>
+                        <empty
+                            v-if="detailList.length === 0"
+                            image="https://fastly.jsdelivr.net/npm/@vant/assets/custom-empty-image.png"
+                            image-size="80"
+                            description="暂无数据"
+                            class="empty-state"
+                        />
                     </common-box>
                 </tab>
                 <tab title="农场报告" class="tab-item">
@@ -87,8 +101,14 @@
                         <template #right>
                             <span @click="handleDetail('agricultural_plan')">查看更多</span>
                         </template>
-                        <record-item :record-item-data="detailList[0]" title-mode="default" class="recipe-item" />
-                        <!-- <plan-list :farm-id="93301" :container-id="route.query.containerId || 2" class="plan-list-wrapper" /> -->
+                        <record-item v-if="detailList.length > 0" :record-item-data="detailList[0]" title-mode="default" class="recipe-item" />
+                        <empty
+                            v-else
+                            image="https://fastly.jsdelivr.net/npm/@vant/assets/custom-empty-image.png"
+                            image-size="80"
+                            description="暂无数据"
+                            class="empty-state"
+                        />
                     </common-box>
                 </tab>
             </tabs>
@@ -103,18 +123,17 @@
 </template>
 
 <script setup>
-import { ref, onMounted } from "vue";
+import { ref, onMounted} from "vue";
 import { useRoute, useRouter } from "vue-router";
-import { Tab, Tabs } from "vant";
+import { Tab, Tabs, Empty } from "vant";
 import customHeader from "@/components/customHeader.vue";
 import FarmInfoCard from "@/components/pageComponents/FarmInfoCard.vue";
 import tabList from "@/components/pageComponents/TabList.vue";
 import commonBox from "@/components/pageComponents/CommonBox.vue";
 import StatsBox from "@/components/pageComponents/StatsBox.vue";
 import recordItem from "@/components/recordItem.vue";
-import PlanList from "@/components/pageComponents/PlanList.vue";
 import farmInfoPopup from "../home/components/farmInfoPopup.vue";
-
+import config from "@/api/config";
 const router = useRouter();
 const route = useRoute();
 const activeTab = ref(0);
@@ -127,13 +146,8 @@ const handleFarmInfo = () => {
 };
 
 const handleFarmServiceTabChange = (index) => {
-    console.log("切换到标签页:", index, farmServiceTabs[index]);
     if (index === 0) {
-        serviceStatsData.value = [
-            { value: "1258", unit: "元", desc: "总收益" },
-            { value: "1258", unit: "元", desc: "投入成本" },
-            { value: "118", unit: "次", desc: "服务次数" },
-        ];
+        getFarmPastServiceCost();
         getDetailList();
     } else {
         getFutureFarmWorkList();
@@ -144,13 +158,7 @@ const handleFarmServiceTabChange = (index) => {
     }
 };
 
-const serviceStatsData = ref([
-    { value: "1258", unit: "元", desc: "总收益" },
-    { value: "1258", unit: "元", desc: "投入成本" },
-    { value: "118", unit: "次", desc: "服务次数" },
-]);
-
-const isImg = ref(true);
+const serviceStatsData = ref([]);
 
 onMounted(() => {
     farmIdVal.value = route.query.farmId;
@@ -162,7 +170,9 @@ onMounted(() => {
     getFarmDetail();
     getFarmWorkList();
     getDetailList();
+    getFarmPastServiceCost();
 });
+
 const farmIdVal = ref(null);
 const farmDetail = ref({});
 const paramsPage = ref({});
@@ -184,10 +194,8 @@ const getFarmWorkList = () => {
 const detailList = ref([]);
 const getDetailList = () => {
     const params = {
-        farmId: 766,
-        flowStatus: 0,
-        limit: 1,
-        page: 1,
+        ...paramsPage.value,
+        flowStatus: '4,5',
     };
     VE_API.user.getDetailList(params).then(({ data }) => {
         detailList.value = data || [];
@@ -199,6 +207,15 @@ const getFutureFarmWorkList = () => {
     });
 };
 
+const getFarmPastServiceCost = () => {
+    VE_API.user.getFarmPastServiceCost({ farmId: farmIdVal.value }).then(({ data }) => {
+        serviceStatsData.value = [
+            { value: data.totalCost, unit: "元", desc: "总收益" },
+            { value: data.totalCost, unit: "元", desc: "投入成本" },
+            { value: data.serviceCount, unit: "次", desc: "服务次数" },
+        ];
+    });
+};
 const handleDetail = (path) => {
     router.push(`/${path}?farmId=${farmIdVal.value}`);
 };
@@ -266,8 +283,10 @@ const handleDetail = (path) => {
             gap: 5px;
             img {
                 flex: 1;
+                max-width: 105px;
                 height: 105px;
                 border-radius: 5px;
+                object-fit: cover;
             }
         }
         .content-section {
@@ -312,6 +331,11 @@ const handleDetail = (path) => {
                 color: #ffffff;
             }
         }
+        .empty-state {
+            ::v-deep .van-empty {
+                padding: 40px 0;
+            }
+        }
     }
 }
 </style>

+ 5 - 4
src/views/old_mini/user/subPages/farmList.vue

@@ -7,14 +7,12 @@
                     <img class="question-icon" src="@/assets/img/home/ask-icon.png" alt="" />
                     <div class="question-title">{{ item.quest }}</div>
                 </div>
-                <template v-if="true">
+                <template v-if="item.images.length">
                     <div class="answer-content">
                         答:{{ item.agriDate }} {{ item.answerLabel }}出现{{ item.indicatorName }}
                     </div>
                     <div class="answer-img" >
-                        <img src="https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png" alt="" />
-                        <img src="https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png" alt="" />
-                        <img src="https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png" alt="" />
+                        <img v-for="image in item.images" :key="image" :src="config.base_img_url2 + image.cloudFilename" alt="" />
                     </div>
                 </template>
                 <div v-else class="answer-btn">
@@ -33,6 +31,7 @@
 import { ref, onMounted } from "vue";
 import customHeader from "@/components/customHeader.vue";
 import { useRoute } from "vue-router";
+import config from "@/api/config";
 
 const route = useRoute();
 onMounted(() => {
@@ -89,8 +88,10 @@ const getFarmWorkList = () => {
                 gap: 5px;
                 img {
                     flex: 1;
+                    max-width: 105px;
                     height: 105px;
                     border-radius: 5px;
+                    object-fit: cover;
                 }
             }
             .answer-btn {

+ 25 - 12
src/views/old_mini/user/subPages/serviceList.vue

@@ -22,6 +22,12 @@
                     :title-right-dot-text="farmServiceActiveTab === 1 ? '2区' : ''"
                     class="recipe-item"
                 />
+                <empty
+                    v-show="detailList.length === 0"
+                    image="https://fastly.jsdelivr.net/npm/@vant/assets/custom-empty-image.png"
+                    image-size="80"
+                    description="暂无数据"
+                />
             </div>
         </div>
     </div>
@@ -32,6 +38,7 @@ import customHeader from "@/components/customHeader.vue";
 import tabList from "@/components/pageComponents/TabList.vue";
 import StatsBox from "@/components/pageComponents/StatsBox.vue";
 import recordItem from "@/components/recordItem.vue";
+import { Empty } from "vant";
 import { useRoute } from "vue-router";
 import { ref, onMounted } from "vue";
 
@@ -40,23 +47,16 @@ const farmIdVal = ref(null);
 onMounted(() => {
     farmIdVal.value = route.query.farmId;
     getDetailList();
+    getFarmPastServiceCost();
 });
 
 const farmServiceTabs = ["过往服务", "未来服务"];
 const farmServiceActiveTab = ref(0);
-const serviceStatsData = ref([
-    { value: "1258", unit: "元", desc: "总收益" },
-    { value: "1258", unit: "元", desc: "投入成本" },
-    { value: "118", unit: "次", desc: "服务次数" },
-]);
+const serviceStatsData = ref([]);
 
 const handleFarmServiceTabChange = (index) => {
     if (index === 0) {
-        serviceStatsData.value = [
-            { value: "1258", unit: "元", desc: "总收益" },
-            { value: "1258", unit: "元", desc: "投入成本" },
-            { value: "118", unit: "次", desc: "服务次数" },
-        ];
+        getFarmPastServiceCost();
         getDetailList();
     } else {
         getFutureFarmWorkList();
@@ -71,8 +71,8 @@ const paramsLimit = ref(99);
 const detailList = ref([]);
 const getDetailList = () => {
     const params = {
-        farmId: 766,
-        flowStatus: 0,
+        farmId: farmIdVal.value,
+        flowStatus: '4,5',
         limit: paramsLimit.value,
         page: paramsPage.value,
     };
@@ -90,6 +90,16 @@ const getFutureFarmWorkList = () => {
         detailList.value = data || [];
     });
 };
+
+const getFarmPastServiceCost = () => {
+    VE_API.user.getFarmPastServiceCost({ farmId: farmIdVal.value }).then(({ data }) => {
+        serviceStatsData.value = [
+            { value: data.totalCost, unit: "元", desc: "总收益" },
+            { value: data.totalCost, unit: "元", desc: "投入成本" },
+            { value: data.serviceCount, unit: "次", desc: "服务次数" },
+        ];
+    });
+};
 </script>
 
 <style scoped lang="scss">
@@ -107,6 +117,9 @@ const getFutureFarmWorkList = () => {
                 border: 1px solid rgba(0, 0, 0, 0.1);
                 margin: 12px 0 0 0;
             }
+            ::v-deep .van-empty {
+                padding: 40px 0;
+            }
         }
     }
 }