Prechádzať zdrojové kódy

feat:添加农事档案和农事列表弹窗

wangsisi 4 dní pred
rodič
commit
4f5048e32d

+ 145 - 0
src/components/popup/farmCalendarPopup.vue

@@ -0,0 +1,145 @@
+<template>
+    <popup
+        v-model:show="showValue"
+        round
+        teleport="body"
+        class="farm-calendar-popup"
+        :close-on-click-overlay="true"
+    >
+        <div class="farm-calendar-popup__title">{{ t("agriFile.completeFarmInfo") }}</div>
+        <div class="farm-calendar-popup__subtitle">
+            {{ t("agriFile.getImmediately") }}
+            <span>{{ t("workExecute.exclusiveFarmCalendar") }}</span>
+        </div>
+        <div class="farm-calendar-popup__days">
+            <div
+                v-for="(day, index) in weekDays"
+                :key="day"
+                class="farm-calendar-popup__day"
+                :class="{ 'is-active': activeDay === index }"
+                @click="activeDay = index"
+            >
+                {{ t(day) }}
+            </div>
+        </div>
+        <div class="farm-calendar-popup__image">
+            <img v-if="currentImage" :src="currentImage" alt="" />
+            <slot v-else name="image" :day="activeDay"></slot>
+        </div>
+        <div class="farm-calendar-popup__btn" @click="handleOpen">{{ t("agriFile.goEnable") }}</div>
+    </popup>
+</template>
+
+<script setup>
+import { computed, ref } from "vue";
+import { Popup } from "vant";
+import { useI18n } from "@/i18n";
+
+const { t } = useI18n();
+
+const props = defineProps({
+    show: {
+        type: Boolean,
+        default: false,
+    },
+    images: {
+        type: Array,
+        default: () => [],
+    },
+});
+
+const emit = defineEmits(["update:show", "confirm"]);
+
+const showValue = computed({
+    get: () => props.show,
+    set: (val) => emit("update:show", val),
+});
+
+const weekDays = ["week.1", "week.2", "week.3", "week.4", "week.5"];
+const activeDay = ref(1);
+
+const currentImage = computed(() => props.images[activeDay.value] || "");
+
+const handleOpen = () => {
+    emit("confirm");
+    showValue.value = false;
+};
+</script>
+
+<style scoped lang="scss">
+.farm-calendar-popup {
+    width: 82%;
+    padding: 20px 10px;
+    text-align: center;
+    background: linear-gradient(360deg, #FFFFFF 1.28%, #D7EEFF 55.76%, #FFFFFF 98.67%);
+
+    &__title,
+    &__subtitle {
+        font-size: 24px;
+        font-family: "pangmenzhengdao";
+        line-height: 28px;
+    }
+
+    &__subtitle {
+        span {
+            color: #2199f8;
+        }
+    }
+
+    &__days {
+        display: flex;
+        justify-content: space-between;
+        gap: 12px;
+        margin-top: 14px;
+    }
+
+    &__day {
+        position: relative;
+        flex: 1;
+        border-radius: 4px 4px 0 0;
+        background: #fff;
+        padding: 4px 0;
+
+        &.is-active {
+            background: linear-gradient(149.44deg, #9FD5FF 2.43%, #2199F8 91.84%);
+            color: #fff;
+            border-radius: 4px;
+
+            &::after {
+                content: "";
+                position: absolute;
+                left: 50%;
+                bottom: -6px;
+                transform: translateX(-50%);
+                border-left: 6px solid transparent;
+                border-right: 6px solid transparent;
+                border-top: 6px solid #2199f8;
+            }
+        }
+    }
+
+    &__image {
+        width: 100%;
+        height: 142px;
+        margin: 12px 0 14px;
+        border-radius: 5px;
+        background: #f2f4f7;
+
+        img {
+            display: block;
+            width: 100%;
+            height: 100%;
+        }
+    }
+
+    &__btn {
+        width: 162px;
+        margin: auto;
+        padding: 8px 0;
+        border-radius: 25px;
+        background: #2199f8;
+        color: #fff;
+        font-size: 16px;
+    }
+}
+</style>

+ 94 - 0
src/components/popup/leaveConfirmPopup.vue

@@ -0,0 +1,94 @@
+<template>
+    <popup
+        v-model:show="showValue"
+        round
+        teleport="body"
+        class="leave-confirm-popup"
+        :close-on-click-overlay="true"
+    >
+        <img class="leave-confirm-popup__icon" src="@/assets/img/agricultural/notice.png" alt="" />
+        <div class="leave-confirm-popup__title">{{ t("agriFile.confirmLeaveTitle") }}</div>
+        <div class="leave-confirm-popup__desc">
+            <div>{{ t("agriFile.confirmLeaveDesc1") }}</div>
+            <div>{{ t("agriFile.confirmLeaveDesc2") }}</div>
+        </div>
+        <div class="leave-confirm-popup__btn" @click="handleContinue">{{ t("agriFile.continueRecord") }}</div>
+        <div class="leave-confirm-popup__leave" @click="handleLeave">{{ t("agriFile.confirmLeave") }}</div>
+    </popup>
+</template>
+
+<script setup>
+import { computed } from "vue";
+import { Popup } from "vant";
+import { useI18n } from "@/i18n";
+
+const { t } = useI18n();
+
+const props = defineProps({
+    show: {
+        type: Boolean,
+        default: false,
+    },
+});
+
+const emit = defineEmits(["update:show", "confirm", "cancel"]);
+
+const showValue = computed({
+    get: () => props.show,
+    set: (val) => emit("update:show", val),
+});
+
+const handleContinue = () => {
+    emit("cancel");
+    showValue.value = false;
+};
+
+const handleLeave = () => {
+    emit("confirm");
+    showValue.value = false;
+};
+</script>
+
+<style scoped lang="scss">
+.leave-confirm-popup {
+    width: 78%;
+    padding: 72px 20px 22px;
+    text-align: center;
+    overflow: visible;
+    background: linear-gradient(360deg, #FFFFFF 0%, #D3EBFF 100%);
+
+    &__icon {
+        position: absolute;
+        top: -32px;
+        left: 50%;
+        display: block;
+        width: 102px;
+        height: 102px;
+        transform: translateX(-50%);
+    }
+
+    &__title {
+        font-size: 26px;
+        color: #010101;
+        font-family: "pangmenzhengdao";
+    }
+
+    &__desc {
+        margin-top: 8px;
+        color: #1F1F1F;
+    }
+
+    &__btn {
+        margin: 20px auto 10px;
+        padding: 8px;
+        border-radius: 25px;
+        background: linear-gradient(180deg, #96D1FF 0%, #2199F8 100%);
+        color: #fff;
+        font-size: 16px;
+    }
+
+    &__leave {
+        color: #AEAEAE;
+    }
+}
+</style>

+ 12 - 0
src/i18n/messages.js

@@ -177,6 +177,11 @@ export default {
             reportGenerated: "已生成",
             clickToView: "点击查看",
             viewInDiagnosisHint: "还可在 农事档案-诊断报告 中查看",
+            confirmLeaveTitle: "确认要离开?",
+            confirmLeaveDesc1: "长势巡园比例还没录入,确定要走吗?",
+            confirmLeaveDesc2: "少了这一步,估产数据就不准了哦~",
+            continueRecord: "继续记录",
+            confirmLeave: "确认离开",
             agriAlbum: "农情相册",
             diagnosisReport: "诊断报告",
             reportUpdate: "更新",
@@ -321,6 +326,7 @@ export default {
             forward: "转发",
             viewDetail: "查看详情",
             forwardTip: "转发功能即将开放",
+            exclusiveFarmCalendar: "专属农事日历",
             redispatch: "重新派发",
             remindAccept: "提醒接受",
             modifyInfo: "修改信息",
@@ -571,6 +577,11 @@ export default {
             reportGenerated: "Generated",
             clickToView: "View now",
             viewInDiagnosisHint: "Also available in Crop Archives - Diagnosis report",
+            confirmLeaveTitle: "Leave this page?",
+            confirmLeaveDesc1: "Growth patrol ratio is not entered yet. Leave anyway?",
+            confirmLeaveDesc2: "Without this step, yield estimates will be less accurate~",
+            continueRecord: "Keep recording",
+            confirmLeave: "Leave",
             agriAlbum: "Agri album",
             diagnosisReport: "Diagnosis report",
             reportUpdate: "Update",
@@ -715,6 +726,7 @@ export default {
             forward: "Forward",
             viewDetail: "View details",
             forwardTip: "Forward feature coming soon",
+            exclusiveFarmCalendar: "exclusive farm calendar",
             redispatch: "Redispatch",
             remindAccept: "Remind to accept",
             modifyInfo: "Edit info",

+ 21 - 1
src/views/old_mini/agri_file/pages/growthTrack.vue

@@ -1,6 +1,6 @@
 <template>
     <div class="growth-track-page">
-        <custom-header :name="t('agriFile.workName')" />
+        <custom-header :name="t('agriFile.workName')" :isGoBack="true" @goback="handleBack" />
         <div class="growth-track-body">
             <div class="growth-hero">
                 <div class="growth-hero__top">
@@ -79,6 +79,10 @@
             <span>{{ t("agriFile.uploadPhoto") }}</span>
         </div>
         <album-upload-popup v-model:show="showUploadPopup" />
+        <leave-confirm-popup
+            v-model:show="showLeavePopup"
+            @confirm="confirmLeave"
+        />
     </div>
 </template>
 
@@ -89,6 +93,7 @@ import { Icon } from 'vant';
 import { ElMessage } from "element-plus";
 import customHeader from "@/components/customHeader.vue";
 import albumUploadPopup from "../components/albumUploadPopup.vue";
+import leaveConfirmPopup from "@/components/popup/leaveConfirmPopup.vue";
 import { useI18n } from "@/i18n";
 
 const { t } = useI18n();
@@ -102,6 +107,7 @@ const reason = computed(() => t("agriFile.interactReason"));
 const zoneName = computed(() => t("agriFile.zoneOne"));
 const ratio = ref("");
 const showUploadPopup = ref(false);
+const showLeavePopup = ref(false);
 const situationList = [
     { nameKey: "agriFile.growthAbnormal" },
     { nameKey: "agriFile.rootAbnormal" },
@@ -122,6 +128,20 @@ const handleUploadClick = () => {
     }
     showUploadPopup.value = true;
 };
+
+const hasRatio = () => ratio.value !== "" && ratio.value != null;
+
+const handleBack = () => {
+    // if (!isAbnormal.value && !hasRatio()) {
+    //     showLeavePopup.value = true;
+    //     return;
+    // }
+    router.back();
+};
+
+const confirmLeave = () => {
+    router.back();
+};
 </script>
 
 <style lang="scss" scoped>

+ 7 - 0
src/views/old_mini/work_execute/index.vue

@@ -45,6 +45,7 @@
                 <div v-if="!taskList.length" class="empty-tip">{{ t("workExecute.noData") }}</div>
             </div>
         </div>
+        <farm-calendar-popup v-model:show="showFarmCalendarPopup" @confirm="goCompleteFarmInfo" />
     </div>
 </template>
 
@@ -56,6 +57,7 @@ import { ElMessage } from "element-plus";
 import IndexMap from "./index";
 import customCalendar from "./components/calendar.vue";
 import farmHeader from "@/components/farmHeader.vue";
+import farmCalendarPopup from "@/components/popup/farmCalendarPopup.vue";
 import { useI18n } from "@/i18n";
 
 const { t } = useI18n();
@@ -64,6 +66,7 @@ const router = useRouter();
 const indexMap = new IndexMap();
 const mapContainer = ref(null);
 const calendarRef = ref(null);
+const showFarmCalendarPopup = ref(false);
 const tabBarHeight = computed(() => store.state.home.tabBarHeight);
 
 const formatDateYMD = (date = new Date()) =>
@@ -137,6 +140,10 @@ const handleViewDetail = (item) => {
     });
 };
 
+const goCompleteFarmInfo = () => {
+    router.push("/entry_information");
+};
+
 const mapPoint = ref(null);
 
 const getMapMarkerList = () => taskList.value.filter((item) => item.wkt);