2 Комити a744225a1a ... 1957959439

Аутор SHA1 Порука Датум
  wangsisi 1957959439 Merge branch 'master' of http://www.sysuimars.cn:3000/feiniao/feiniao-farm-h5 пре 1 недеља
  wangsisi 1b09e9b42f feat:把互动内容从弹窗分离 пре 1 недеља
2 измењених фајлова са 378 додато и 10 уклоњено
  1. 344 0
      src/components/popup/interactPopup.vue
  2. 34 10
      src/views/old_mini/monitor/subPages/plan.vue

+ 344 - 0
src/components/popup/interactPopup.vue

@@ -0,0 +1,344 @@
+<template>
+    <popup
+        class="interact-popup"
+        v-model:show="show"
+        closeable
+        :close-on-click-overlay="false"
+        @closed="handleClosed"
+    >
+        <div class="interact-header">
+            <div class="interact-title">{{ interactTitle }}</div>
+        </div>
+        <div class="interact-form">
+            <div class="form-item">
+                <div class="form-label">
+                    <span class="required">*</span>
+                    请选择互动时间
+                </div>
+                <div class="form-input-wrapper">
+                    <el-date-picker
+                        v-model="interactTime"
+                        size="large"
+                        style="width: 100%"
+                        type="date"
+                        placeholder="请选择日期"
+                        :editable="false"
+                    />
+                </div>
+            </div>
+            <div class="form-item">
+                <div class="form-label">
+                    <span class="required">*</span>
+                    请选择强制触发互动时间
+                </div>
+                <div class="form-input-wrapper">
+                    <el-date-picker
+                        v-model="forceTriggerTime"
+                        size="large"
+                        style="width: 100%"
+                        type="date"
+                        placeholder="请选择日期"
+                        :editable="false"
+                    />
+                </div>
+            </div>
+            <div class="form-item">
+                <div class="form-label">
+                    <span class="required">*</span>
+                    请设置互动问题
+                </div>
+                <el-input
+                    v-model="interactQuestion"
+                    type="textarea"
+                    :rows="4"
+                    placeholder="请设置互动问题"
+                    class="question-textarea"
+                />
+            </div>
+        </div>
+        <div class="interact-buttons">
+            <div class="btn-delete" @click="handleDeleteInteract">删除互动</div>
+            <div class="btn-save" :class="{ disabled: isSaving }" @click="handleSaveInteract">
+                {{ saveButtonText }}
+            </div>
+        </div>
+    </popup>
+</template>
+
+<script setup>
+import { Popup } from "vant";
+import { ref, computed } from "vue";
+import { ElMessage, ElMessageBox } from "element-plus";
+
+// Emits
+const emit = defineEmits(["handleSaveSuccess", "handleDeleteInteract"]);
+
+// 响应式数据
+const show = ref(false);
+const arrangeId = ref(null);
+const isSaving = ref(false);
+const interactTitle = ref("梢期杀虫");
+const interactTime = ref("");
+const forceTriggerTime = ref("");
+const interactQuestion = ref("");
+
+// 计算属性
+const saveButtonText = computed(() => (isSaving.value ? "保存中..." : "保存修改"));
+
+// 工具函数
+const resetInteractData = () => {
+    interactTime.value = "";
+    forceTriggerTime.value = "";
+    interactQuestion.value = "";
+};
+
+// 验证函数
+const validateInteractForm = () => {
+    if (!interactTime.value) {
+        ElMessage.warning("请选择互动时间");
+        return false;
+    }
+    if (!forceTriggerTime.value) {
+        ElMessage.warning("请选择强制触发互动时间");
+        return false;
+    }
+    if (!interactQuestion.value?.trim()) {
+        ElMessage.warning("请设置互动问题");
+        return false;
+    }
+    return true;
+};
+
+// 显示弹窗方法
+const showPopup = ({
+    arrangeIdVal,
+    interactTitleVal,
+    interactTimeVal,
+    forceTriggerTimeVal,
+    interactQuestionVal,
+}) => {
+    // 重置数据
+    resetInteractData();
+
+    // 设置数据
+    arrangeId.value = arrangeIdVal;
+    interactTitle.value = interactTitleVal || "梢期杀虫";
+    interactTime.value = interactTimeVal || "";
+    forceTriggerTime.value = forceTriggerTimeVal || "";
+    interactQuestion.value = interactQuestionVal || "";
+    isSaving.value = false;
+
+    show.value = true;
+};
+
+// 事件处理函数
+const handleDeleteInteract = () => {
+    ElMessageBox.confirm("确定要删除该互动设置吗?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+    })
+        .then(() => {
+            emit("handleDeleteInteract", { arrangeId: arrangeId.value });
+            show.value = false;
+            ElMessage.success("删除成功");
+        })
+        .catch(() => {
+            // 用户取消,不做任何操作
+        });
+};
+
+const handleSaveInteract = () => {
+    if (isSaving.value || !validateInteractForm()) return;
+
+    isSaving.value = true;
+
+    const paramsObj = {
+        arrangeId: arrangeId.value,
+        interactTime: interactTime.value,
+        forceTriggerTime: forceTriggerTime.value,
+        interactQuestion: interactQuestion.value.trim(),
+    };
+
+    // TODO: 调用保存互动设置的API
+    // VE_API.monitor.saveInteractSetting(paramsObj)
+    //     .then((res) => {
+    //         if (res.code === 0) {
+    //             ElMessage.success("保存成功");
+    //             show.value = false;
+    //             emit("handleSaveSuccess", paramsObj);
+    //         } else {
+    //             ElMessage.error(res.message || "保存失败");
+    //         }
+    //     })
+    //     .catch((error) => {
+    //         console.error("保存互动设置失败:", error);
+    //         ElMessage.error("保存失败,请重试");
+    //     })
+    //     .finally(() => {
+    //         isSaving.value = false;
+    //     });
+
+    // 临时模拟保存成功
+    setTimeout(() => {
+        ElMessage.success("保存成功");
+        show.value = false;
+        emit("handleSaveSuccess", paramsObj);
+        isSaving.value = false;
+    }, 500);
+};
+
+const handleClosed = () => {
+    resetInteractData();
+};
+
+// 暴露方法
+defineExpose({
+    showPopup,
+});
+</script>
+
+<style lang="scss" scoped>
+.interact-popup {
+    width: 90%;
+    box-sizing: border-box;
+    background: #ffffff;
+    padding: 0;
+    border-radius: 10px;
+
+    ::v-deep {
+        .van-popup__close-icon {
+            color: #000;
+        }
+    }
+
+    .interact-header {
+        background: linear-gradient(180deg, #d1ebff 0%, #ffffff 100%);
+        padding: 20px 18px;
+        text-align: center;
+        border-radius: 10px 10px 0 0;
+
+        .interact-title {
+            font-size: 18px;
+            font-weight: 600;
+            color: #000;
+        }
+    }
+
+    .interact-form {
+        padding: 0 18px 20px;
+
+        .form-item {
+            margin-bottom: 20px;
+
+            &:last-child {
+                margin-bottom: 0;
+            }
+
+            .form-label {
+                font-size: 14px;
+                color: #000;
+                margin-bottom: 12px;
+                display: flex;
+                align-items: center;
+
+                .required {
+                    color: #ff4d4f;
+                    margin-right: 4px;
+                }
+            }
+
+            .form-input-wrapper {
+                position: relative;
+
+                ::v-deep {
+                    .el-input__inner {
+                        caret-color: transparent;
+                        padding-right: 40px;
+                    }
+
+                    .el-input__suffix {
+                        display: none;
+                    }
+                }
+
+                .time-icon {
+                    position: absolute;
+                    right: 12px;
+                    top: 50%;
+                    transform: translateY(-50%);
+                    color: #909399;
+                    pointer-events: none;
+                    z-index: 1;
+                    font-size: 16px;
+                }
+            }
+
+            .question-textarea {
+                ::v-deep {
+                    .el-textarea__inner {
+                        resize: none;
+                        line-height: 1.5;
+                        min-height: 80px;
+                    }
+                }
+            }
+        }
+    }
+
+    .interact-buttons {
+        display: flex;
+        gap: 12px;
+        padding: 0 18px 20px;
+
+        .btn-delete,
+        .btn-save {
+            flex: 1;
+            padding: 8px;
+            border-radius: 25px;
+            font-size: 16px;
+            text-align: center;
+            cursor: pointer;
+            transition: all 0.3s;
+            user-select: none;
+        }
+
+        .btn-delete {
+            background: #ffffff;
+            border: 1px solid #ff4d4f;
+            color: #ff4d4f;
+
+            &:hover {
+                background: #fff5f5;
+            }
+
+            &:active {
+                opacity: 0.8;
+                transform: scale(0.98);
+            }
+        }
+
+        .btn-save {
+            background: #2199f8;
+            color: #fff;
+            border: none;
+
+            &:hover:not(.disabled) {
+                background: #1a8ae6;
+            }
+
+            &:active:not(.disabled) {
+                opacity: 0.9;
+                transform: scale(0.98);
+            }
+
+            &.disabled {
+                opacity: 0.6;
+                cursor: not-allowed;
+                pointer-events: none;
+            }
+        }
+    }
+}
+</style>
+

+ 34 - 10
src/views/old_mini/monitor/subPages/plan.vue

@@ -89,6 +89,8 @@
     <detail-dialog ref="detailDialogRef" @triggerFarmWork="triggerFarmWork"></detail-dialog>
     <!-- 新增:激活上传弹窗 -->
     <active-upload-popup ref="activeUploadPopupRef" :needExecutor="true" @handleUploadSuccess="getFarmWorkPlan"></active-upload-popup>
+    <!-- 互动设置弹窗 -->
+    <interact-popup ref="interactPopupRef" @handleSaveSuccess="getFarmWorkPlan" @handleDeleteInteract="handleDeleteInteract"></interact-popup>
 </template>
 
 <script setup>
@@ -98,6 +100,7 @@ import { useRouter, useRoute } from "vue-router";
 import detailDialog from "@/components/detailDialog.vue";
 import eventBus from "@/api/eventBus";
 import activeUploadPopup from "@/components/popup/activeUploadPopup.vue";
+import interactPopup from "@/components/popup/interactPopup.vue";
 import { ElMessage } from "element-plus";
 const router = useRouter();
 const route = useRoute();
@@ -228,17 +231,38 @@ const handleRowClick = (item) => {
 };
 
 const activeUploadPopupRef = ref(null);
+const interactPopupRef = ref(null);
+
 const handleEdit = (item) => {
-    eventBus.emit("activeUpload:show", {
-        gardenIdVal: route.query.farmId,
-        problemTitleVal: '请选择 ' + item.farmWorkName + ' 执行截至时间',
-        arrangeIdVal: item.id,
-        modeVal: 'interact', // 设置为互动设置模式
-        interactTitleVal: item.farmWorkName || '梢期杀虫', // 使用农事名称作为标题
-        interactTimeVal: item.interactTime || '', // 如果有已保存的互动时间
-        forceTriggerTimeVal: item.forceTriggerTime || '', // 如果有已保存的强制触发时间
-        interactQuestionVal: item.interactQuestion, // 如果有已保存的互动问题
-    });
+    if (interactPopupRef.value) {
+        interactPopupRef.value.showPopup({
+            arrangeIdVal: item.id,
+            interactTitleVal: item.farmWorkName || '梢期杀虫', // 使用农事名称作为标题
+            interactTimeVal: item.interactTime || '', // 如果有已保存的互动时间
+            forceTriggerTimeVal: item.forceTriggerTime || '', // 如果有已保存的强制触发时间
+            interactQuestionVal: item.interactQuestion, // 如果有已保存的互动问题
+        });
+    }
+};
+
+const handleDeleteInteract = (params) => {
+    // TODO: 调用删除互动设置的API
+    // VE_API.monitor.deleteInteractSetting(params)
+    //     .then((res) => {
+    //         if (res.code === 0) {
+    //             ElMessage.success("删除成功");
+    //             getFarmWorkPlan();
+    //         } else {
+    //             ElMessage.error(res.message || "删除失败");
+    //         }
+    //     })
+    //     .catch((error) => {
+    //         console.error("删除互动设置失败:", error);
+    //         ElMessage.error("删除失败,请重试");
+    //     });
+    
+    // 临时模拟删除成功
+    getFarmWorkPlan();
 };
 
 const detailDialogRef = ref(null);