Selaa lähdekoodia

feat:添加过期农事详情状态和触发农事弹窗

wangsisi 1 viikko sitten
vanhempi
commit
785c0b6044

+ 6 - 1
src/components/detailDialog.vue

@@ -107,8 +107,13 @@ const sampleId = route.query.sampleId
 const farmId = route.query.farmId;
 
 const triggerClick = () => {
+    console.log('triggerClick called, emitting activeUpload:show', { farmId: dialogData.value.farmId, farmWorkName: dialogData.value.farmWorkName })
     winDialogVisible.value = false;
-    noShow.value = true;
+    // 打开同级的激活上传弹窗
+    eventBus.emit("activeUpload:show", { 
+        gardenIdVal: dialogData.value.farmId,
+        problemTitleVal: dialogData.value.farmWorkName
+    });
 }
 
 const dialogData = ref({

+ 175 - 0
src/components/popup/activeUploadPopup.vue

@@ -0,0 +1,175 @@
+<template>
+    <popup
+        class="active-upload-popup"
+        v-model:show="show"
+        closeable
+        :close-on-click-overlay="false"
+        @closed="handleClosed"
+    >
+        <div class="header">
+            <div class="title">
+                <span class="required">*</span>
+                {{ problemTitle }}
+            </div>
+            <div class="date-input">
+                <el-time-select
+                    size="large"
+                    v-model="uploadDate"
+                    start="08:30"
+                    step="00:15"
+                    end="18:30"
+                    placeholder="请选择时间"
+                />
+            </div>
+        </div>
+        <div class="tips-text">上传照片,专家诊断更准确哦~</div>
+        <upload :textShow="true" class="upload-wrap"></upload>
+        <div class="btn" @click="handleUpload">确认</div>
+    </popup>
+
+    <!-- 上传成功提示弹窗 -->
+    <popup class="success-popup" v-model:show="successShow" :close-on-click-overlay="false">
+        <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="btn" @click="successShow = false">我知道了</div>
+        </div>
+    </popup>
+</template>
+
+<script setup>
+import { Popup } from "vant";
+import { onMounted, onUnmounted, ref } from "vue";
+import upload from "@/components/upload";
+import eventBus from "@/api/eventBus";
+import { ElMessage } from "element-plus";
+
+const show = ref(false);
+const gardenId = ref(null);
+const images = ref([]);
+const uploadDate = ref("");
+const problemTitle = ref("请选择问题");
+const successShow = ref(false);
+
+onMounted(() => {
+    eventBus.off("upload:changeArr", uploadChange);
+    eventBus.on("upload:changeArr", uploadChange);
+    eventBus.on("activeUpload:show", handleShow);
+});
+
+function uploadChange(arr) {
+    images.value = arr;
+}
+
+function formatDate(date) {
+    let year = date.getFullYear();
+    let month = String(date.getMonth() + 1).padStart(2, "0");
+    let day = String(date.getDate()).padStart(2, "0");
+    return `${year}-${month}-${day}`;
+}
+
+function handleShow({ gardenIdVal, problemTitleVal }) {
+    console.log("activeUpload:show event received", { gardenIdVal, problemTitleVal });
+    images.value = [];
+    gardenId.value = gardenIdVal;
+    problemTitle.value = problemTitleVal || "请选择问题";
+    uploadDate.value = formatDate(new Date());
+    show.value = true;
+}
+
+const handleUpload = () => {
+    if (images.value.length === 0) return ElMessage.warning("请上传图片");
+    const params = {
+        gardenId: gardenId.value,
+        images: images.value,
+        uploadDate: uploadDate.value,
+    };
+    // 提交成功后的反馈弹窗(示例直接展示)
+    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");
+    //     }
+    // });
+};
+
+function handleClosed() {
+    eventBus.emit("upload:reset");
+}
+
+onUnmounted(() => {
+    eventBus.off("activeUpload:show", handleShow);
+    eventBus.off("upload:changeArr", uploadChange);
+    show.value = false;
+});
+</script>
+
+<style lang="scss" scoped>
+.active-upload-popup {
+    width: 90%;
+    box-sizing: border-box;
+    padding: 24px 18px 20px;
+    background: linear-gradient(0deg, #ffffff 70%, #d1ebff 100%);
+    border-radius: 10px;
+    ::v-deep {
+        .van-popup__close-icon {
+            color: #000;
+        }
+    }
+    .header {
+        .title {
+            font-size: 16px;
+            font-weight: 500;
+            display: flex;
+            align-items: center;
+            .required {
+                color: #ff4d4f;
+                margin-right: 4px;
+            }
+        }
+        .date-input {
+            margin: 12px 0;
+        }
+    }
+    .tips-text {
+        font-weight: 500;
+    }
+    .upload-wrap {
+        margin: 12px 0 24px;
+    }
+}
+
+.btn {
+    padding: 8px;
+    background: #2199f8;
+    border-radius: 25px;
+    color: #fff;
+    font-size: 16px;
+    text-align: center;
+}
+
+.success-popup {
+    width: 300px;
+    border-radius: 14px;
+    padding: 28px 15px 20px;
+    box-sizing: border-box;
+    .success-wrap {
+        text-align: center;
+    }
+    .success-icon {
+        width: 68px;
+        height: 68px;
+    }
+    .success-title {
+        font-size: 24px;
+        margin-top: 12px;
+    }
+    .success-sub {
+        margin: 8px 0 32px;
+    }
+}
+</style>

+ 113 - 12
src/views/old_mini/modify_work/completedWork.vue

@@ -2,13 +2,14 @@
     <div class="completed-work">
         <custom-header name="农事详情"></custom-header>
         <div class="work-content" :class="{'hasBottom': curRole == 0}">
-            <div class="step-wrap">
+            <div class="step-wrap" v-show="query.status !== 'warning'">
                 <farm-steps :currentStep="currentStep" />
             </div>
-            <div class="content-status" v-if="currentStep !== 0">
+            <div class="content-status" :class="{'warning': query.status === 'warning'}" v-if="currentStep !== 0 || query.status === 'warning'">
                 <div class="status-l" v-if="status === 0">
-                    <div class="stauts-text">待执行</div>
-                    <div class="stauts-sub-text">距离预计执行时间还差 <span class="time-text">3</span> 天</div>
+                    <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>
+                    <div class="stauts-sub-text" v-else>该农事触发但未执行</div>
                 </div>
                 <div class="status-l" v-if="status === 1">
                     <div class="stauts-text">
@@ -16,10 +17,35 @@
                         该农事已完成
                     </div>
                 </div>
-                <div class="status-r" v-if="curRole == 0">{{ status === 0 ? "设置提醒" : "去评价" }}</div>
-                <div class="status-r" v-if="curRole == 1">{{ status === 0 ? "提醒执行" : "提醒复核" }}</div>
+                <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>
+                </template>
+            </div>
+            <div class="work-wrap">
+                <div class="box-wrap executor-info">
+                    <div class="executor-title">执行人</div>
+                    <div class="executor-content">
+                        <div class="executor-avatar">
+                            <img src="https://birdseye-img-ali-cdn.sysuimars.com/16926861-1e20-4cbd-8bf2-90208db5a2d0/806080da-1a30-4b5b-b64b-b22e722c6cb6/DJI_202509010800_001_806080da-1a30-4b5b-b64b-b22e722c6cb6/DJI_20250901080536_0045_V_code-ws0fsmge97gh.jpeg" alt="执行人" />
+                        </div>
+                        <div class="executor-details">
+                            <div class="org-name">
+                                <span class="name">河南农资农服组织</span>
+                                <span class="rating">5.0分</span>
+                            </div>
+                            <div class="service-info">
+                                <div class="service-item">服务品种: <span>荔枝、龙眼</span></div>
+                                <div class="service-item">服务设备: <span>无人机、水肥一体机、水肥一体机水肥</span></div>
+                            </div>
+                            <div class="contact-buttons">
+                                <button class="contact-btn">电话联系</button>
+                                <button class="contact-btn">在线联系</button>
+                            </div>
+                        </div>
+                    </div>
+                </div>
             </div>
-
             <div class="work-wrap">
                 <div class="box-wrap farm-info">
                     <div class="info-title">
@@ -147,7 +173,7 @@
                     </div>
                 </div>
             </div>
-            <div class="fixed-btn-wrap" :class="{'center': currentStep == 0}" v-if="curRole === 0">
+            <div class="fixed-btn-wrap" :class="{'center': currentStep == 0}" v-if="curRole === 0 && query.status !== 'warning'">
                 <div class="fixed-btn expert" v-if="currentStep == 0">提醒专家确认</div>
                 <div class="fixed-btn orange" v-if="currentStep == 1" @click="handleDemand">发起需求</div>
                 <div class="fixed-btn" v-if="currentStep == 1" @click="handleOk">{{ status === 0 ? "我已完成" : "立即复核" }}</div>
@@ -164,16 +190,16 @@ import { onMounted, ref } from "vue";
 import NewFarmMap from "./newFarmMap";
 import { useStore } from "vuex";
 import offerPopup from "@/components/popup/offerPopup.vue";
-import { useRouter } from "vue-router";
+import { useRouter, useRoute } from "vue-router";
 import farmSteps from "@/components/farmSteps.vue";
 
 const router = useRouter();
 const store = useStore();
-
+const query = useRoute().query;
 // 角色
 // const curRole = store.state.app.curRole
-const currentStep = ref(1);
-const curRole = 1
+const currentStep = ref(0);
+const curRole = 0
 
 // 0:执行, 1: 复核
 const status = ref(0);
@@ -489,6 +515,14 @@ const changeRegion = (e) => {
                     color: #ffff;
                 }
             }
+            &.warning {
+                &::after {
+                    background: #FF953D;
+                }
+                .stauts-sub-text {
+                    color: #fff;
+                }
+            }
             .status-r {
                 height: 32px;
                 line-height: 32px;
@@ -504,6 +538,73 @@ const changeRegion = (e) => {
             padding: 10px 0;
             position: relative;
         }
+        .executor-info {
+            margin-top: 14px;
+            .executor-title {
+                font-size: 18px;
+                font-weight: bold;
+                color: #000;
+                margin-bottom: 12px;
+            }
+            .executor-content {
+                display: flex;
+                align-items: flex-start;
+                gap: 12px;
+                .executor-avatar {
+                    flex-shrink: 0;
+                    img {
+                        width: 60px;
+                        height: 60px;
+                        border-radius: 8px;
+                        object-fit: cover;
+                    }
+                }
+                .executor-details {
+                    flex: 1;
+                    .org-name {
+                        display: flex;
+                        align-items: center;
+                        gap: 8px;
+                        margin-bottom: 3px;
+                        .name {
+                            font-size: 16px;
+                            font-weight: bold;
+                            color: #000;
+                        }
+                        .rating {
+                            font-size: 16px;
+                            color: #FF953D;
+                            font-weight: bold;
+                        }
+                    }
+                    .service-info {
+                        margin-bottom: 12px;
+                        .service-item {
+                            font-size: 12px;
+                            color: #B6B6B6;
+                            line-height: 1.3;
+                            margin-bottom: 2px;
+                            span{
+                                color: #666666;
+                            }
+                        }
+                    }
+                    .contact-buttons {
+                        display: flex;
+                        justify-content: flex-end;
+                        gap: 8px;
+                        .contact-btn {
+                            width: 88px;
+                            height: 32px;
+                            border-radius: 20px;
+                            color: rgba(0, 0, 0, 0.5);
+                            background: #fff;
+                            border: 1px solid rgba(0, 0, 0, 0.1);
+                        }
+                    }
+                }
+            }
+        }
         .farm-info {
             color: rgba(0, 0, 0, 0.6);
             font-size: 14px;

+ 8 - 4
src/views/old_mini/monitor/subPages/plan.vue

@@ -68,6 +68,8 @@
     </div>
     <!-- 农事信息弹窗 -->
     <detail-dialog ref="detailDialogRef"></detail-dialog>
+    <!-- 新增:激活上传弹窗 -->
+    <active-upload-popup></active-upload-popup>
 </template>
 
 <script setup>
@@ -75,6 +77,7 @@ import { reactive, ref } from "vue";
 import customHeader from "@/components/customHeader.vue";
 import { useRouter } from "vue-router";
 import detailDialog from "@/components/detailDialog.vue";
+import activeUploadPopup from "@/components/popup/activeUploadPopup.vue";
 const router = useRouter();
 
 // 状态列表数据
@@ -162,7 +165,7 @@ const timelineRows = reactive([
     },
     {
         items: [
-        { type: "term", status: "active" },
+            { type: "term", status: "active" },
             { type: "task", status: "warning", icon: { type: "warning", text: "✓" } },
             { type: "term", status: "active" },
             { type: "task", status: "complete", icon: { type: "complete", text: "!" } },
@@ -196,15 +199,16 @@ const handleRowClick = (item) => {
                 id: item.id,
             },
         });
-    }else if(item.status === "normal"){//services_agri
+    }else if(item.type !== "term"){
+        detailDialogRef.value.showDialog();
+    }else if (item.status === "warning" || item.status === "normal"){
         router.push({
             path: "/completed_work",
             query: {
                 id: item.id,
+                status: item.status,
             },
         });
-    }else if(item.status === "default"){
-        detailDialogRef.value.showDialog();
     }
 };
 </script>

+ 1 - 1
src/views/old_mini/plan/index.vue

@@ -3,7 +3,7 @@
         <custom-header name="农事方案"></custom-header>
         <div class="plan-title">
             <div class="tabs">
-                <div class="tab" :class="{ active: activeTab === 'left' }" @click="setActiveTab('left')">专家方</div>
+                <div class="tab" :class="{ active: activeTab === 'left' }" @click="setActiveTab('left')">专家方</div>
                 <div class="tab" :class="{ active: activeTab === 'right' }" @click="setActiveTab('right')">
                     我的方案
                     <span class="badge-dot">2</span>