lxf před 1 týdnem
rodič
revize
35ec65bf23

binární
src/assets/img/home/today.png


+ 299 - 0
src/views/old_mini/task_condition/components/calendar.vue

@@ -0,0 +1,299 @@
+<template>
+    <div class="calendar">
+        <div class="header-wrap">
+            <div class="header-l">
+                <el-icon class="icon" color="#999999" size="11" @click="prevPeriod"><ArrowLeftBold /></el-icon>
+                <span class="header-text"
+                    >{{ dateRange.start }} <span class="center-line">-</span> {{ dateRange.end }}</span
+                >
+                <el-icon class="icon" color="#999999" size="11" @click="nextPeriod"><ArrowRightBold /></el-icon>
+            </div>
+            <!-- <div class="header-r">
+                <span class="line"></span>
+                高温预警
+            </div> -->
+        </div>
+        <div class="days">
+            <div
+                class="days-item"
+                v-for="(day, index) in calendarDays"
+                :key="index"
+                :class="[{ activeDay: activeDay === day.date, today: day.isToday && !day.solarTerm }]"
+                @click="selectDate(day.date, day)"
+            >
+                <div class="day-box">
+                    <span class="days-week">{{ day.isToday ? "今天" : `周${day.dayOfWeek}` }}</span>
+                    <span class="days-one">{{ day.day }}</span>
+                </div>
+                <div v-if="day.solarTerm" class="solar-term">{{ day.solarTerm }}</div>
+                <div v-if="day.typeName" class="type-num">{{ day.typeName.farmWorkName.length }}</div>
+                <!-- <div v-if="day.isHeatWarning" class="heat-warning"></div>
+                <div v-if="day.typeName" class="type-name">
+                    <div class="type-text">{{ day.typeName.farmWorkName }}</div>
+                </div> -->
+            </div>
+        </div>
+    </div>
+</template>
+
+<script setup>
+import { ref, computed, onDeactivated, onMounted } from "vue";
+// const props = defineProps({
+//     calendarWorkList: {
+//         type: Array,
+//         required: true,
+//     },
+// });
+
+const today = new Date();
+// const startDate = ref(getAlignedStartDate(today));
+const startDate = ref(new Date(today));
+console.log('startDate', startDate);
+// 定义星期几的名称
+const weekdays = ["周一", "周二", "周三", "周四", "周五", "周六", "周日"];
+const weekdaysShort = ["一", "二", "三", "四", "五", "六", "日"];
+
+const days = computed(() => {
+    return Array.from({ length: 7 }, (_, i) => {
+        const date = new Date(startDate.value);
+        date.setDate(startDate.value.getDate() + i);
+        return date;
+    });
+});
+
+const calendarDays = computed(() => {
+    const daysList = [];
+    for (let i = 0; i < days.value.length; i++) {
+        const date = days.value[i];
+        const dayOfWeek = date.getDay(); // 0是周日,1是周一,...,6是周六
+        // 调整显示:周一显示为"一",周二显示为"二",...,周日显示为"日"
+        const displayDayOfWeek = dayOfWeek === 0 ? "日" : weekdaysShort[dayOfWeek - 1];
+
+        daysList.push({
+            day: date.getDate(),
+            date: formatDate(date),
+            isToday: formatDate(date) === formatDate(today),
+            dayOfWeek: displayDayOfWeek,
+            // 模拟数据 - 在实际应用中可以从props中获取
+            solarTerm: i === 3 ? "白露" : null,
+            isHeatWarning: i === 5,
+            typeName:
+                i === 2
+                    ? { farmWorkType: 2, farmWorkName: "播种" }
+                    : i === 4
+                    ? { farmWorkType: 1, farmWorkName: "施肥" }
+                    : i === 6
+                    ? { farmWorkType: 3, farmWorkName: "收割" }
+                    : null,
+        });
+    }
+    return daysList;
+});
+
+const dateRange = computed(() => {
+    let start = calendarDays.value[0].date;
+    start = start.replace(/-/g, ".");
+    let end = calendarDays.value[6].date;
+    end = end.replace(/^\d{4}-(\d{2})-(\d{2})$/, "$1.$2");
+    return { start, end };
+});
+
+function getAlignedStartDate(referenceDate) {
+    const start = new Date(referenceDate);
+    const dayOfWeek = start.getDay();
+    start.setDate(start.getDate() - dayOfWeek + (dayOfWeek === 0 ? -13 : 1)); // 对齐至周一,确保21天周期合理
+    return start;
+}
+
+function formatDate(date) {
+    // String(currentMonth.value).padStart(2, "0")
+    return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, "0")}-${String(date.getDate()).padStart(
+        2,
+        "0"
+    )}`;
+}
+
+function prevPeriod() {
+    startDate.value.setDate(startDate.value.getDate() - 7);
+    startDate.value = new Date(startDate.value);
+}
+
+function nextPeriod() {
+    startDate.value.setDate(startDate.value.getDate() + 7);
+    startDate.value = new Date(startDate.value);
+}
+
+const activeDay = ref(null);
+const selectDate = (date, day) => {
+    activeDay.value = date;
+    selectedDate.value = `${date} (${day.dayOfWeek})`;
+};
+
+// 初始化时选择今天
+onMounted(() => {
+    selectDate(formatDate(today), {
+        day: today.getDate(),
+        dayOfWeek: weekdaysShort[today.getDay() === 0 ? 6 : today.getDay() - 1],
+    });
+});
+
+function closeDialog() {
+    activeDay.value = null;
+}
+const selectedDate = ref(null);
+</script>
+
+<style lang="scss" scoped>
+.calendar {
+    width: 100%;
+    text-align: center;
+    box-sizing: border-box;
+    .header-wrap {
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+        margin-bottom: 10px;
+        .header-l {
+            display: flex;
+            align-items: center;
+            justify-content: space-between;
+            width: 100%;
+            .header-text {
+                color: #000;
+                font-size: 16px;
+                font-weight: bold;
+                .center-line {
+                    position: relative;
+                    top: -3px;
+                }
+            }
+            .icon {
+                width: 20px;
+                height: 20px;
+                background: #F2F3F5;
+                border-radius: 50%;
+                text-align: center;
+                line-height: 20px;
+                margin-left: 6px;
+            }
+        }
+        .header-r {
+            background: rgba(252, 138, 44, 0.12);
+            padding: 6px 10px;
+            border-radius: 28px;
+            color: #fc8a2c;
+            display: inline-flex;
+            align-items: center;
+            font-size: 10px;
+            .line {
+                width: 12px;
+                height: 1px;
+                margin-right: 5px;
+                background: #fc8a2c;
+            }
+        }
+    }
+}
+
+.weekdays {
+    display: grid;
+    grid-template-columns: repeat(7, 1fr);
+    font-size: 12px;
+}
+.days {
+    display: grid;
+    grid-template-columns: repeat(7, 1fr);
+    // gap: 5px;
+    font-size: 12px;
+    .days-item + .days-item {
+        margin-left: 6px;
+    }
+    .days-item {
+        cursor: pointer;
+        position: relative;
+        &.today {
+            .day-box {
+                color: #2199f8;
+            }
+        }
+
+        &.activeDay {
+            .day-box {
+                color: #fff;
+                background: linear-gradient(136deg, #9fd5ff, #2199f8);
+            }
+        }
+        .day-box {
+            background: #ffffff;
+            color: #000;
+            border-radius: 8px;
+            padding: 7px 0;
+            position: relative;
+            .days-week {
+                font-size: 12px;
+            }
+        }
+        .solar-term {
+            padding-top: 3px;
+            color: #8D8D8D;
+            font-size: 12px;
+        }
+        .type-num {
+            position: absolute;
+            top: -5px;
+            right: -5px;
+            color: #fff;
+            font-size: 10px;
+            background: #2199F8;
+            width: 12px;
+            height: 12px;
+            border-radius: 50%;
+        }
+        .days-one {
+            text-align: center;
+            display: block;
+            margin: 0 auto;
+            font-size: 14px;
+            line-height: 16px;
+            font-weight: bold;
+            padding-top: 2px;
+            // width: 32px;
+            // height: 32px;
+            // line-height: 32px;
+            // border-radius: 50%;
+        }
+        .type-name {
+            font-size: 10px;
+            position: relative;
+            top: -4px;
+            border-radius: 12px;
+            position: relative;
+            background: #fff;
+            padding-top: 2px;
+            .type-text {
+                border-radius: 12px;
+                padding: 2px;
+            }
+        }
+    }
+}
+.today {
+    position: relative;
+    &::after {
+        content: "";
+        position: absolute;
+        left: 0;
+        right: 0;
+        bottom: 0;
+        margin: 0 auto;
+        width: 10px;
+        height: 10px;
+        background: url("@/assets/img/home/today.png") no-repeat center center / 100% 100%;
+    }
+    &.no-type {
+        &::after {
+            bottom: 14px;
+        }
+    }
+}
+</style>

+ 5 - 3
src/views/old_mini/task_condition/components/task.vue

@@ -2,7 +2,9 @@
     <div class="task-page" :style="{ height: `calc(100vh - ${tabBarHeight}px - 50px)` }">
         <div class="task-top">
             <div class="map-container" ref="mapContainer"></div>
-            <div class="calendar-wrap">calendar</div>
+            <div class="calendar-wrap">
+                <calendar></calendar>
+            </div>
         </div>
         <div class="task-list">
             <div class="list-filter">
@@ -60,6 +62,7 @@ import { computed, nextTick, onMounted, ref } from "vue";
 import { useStore } from "vuex";
 import IndexMap from "../../farm_manage/map/index";
 import taskItem from "@/components/taskItem.vue";
+import calendar from "./calendar.vue"
 
 const store = useStore();
 const indexMap = new IndexMap();
@@ -142,8 +145,7 @@ function handleActiveFilter(i) {
     }
 
     .calendar-wrap {
-        padding: 10px 0;
-        height: 130px;
+        padding: 10px 0 4px 0;
     }
 
     .task-top {