wizhi更新

This commit is contained in:
hero920103 committed 2026-11-03 09:00:29 +08:00
1 parent d4e89788c5
commit 0c6efc4160
16 files changed
+11810 -811

No files matched your search

+249 -20
View File
@@ -14,20 +14,52 @@
</view>
</view>
<!-- 周历条 -->
<view class="week-card">
<view
v-for="d in weekDays"
:key="d.key"
class="week-item"
@tap="pickWeekDay(d)"
>
<text class="week-name">{{ d.name }}</text>
<!-- 月历(可下拉展开) -->
<view class="cal-card">
<view class="cal-header">
<view class="cal-nav" @tap="switchMonth(-1)">
<FaIcon name="chevron-left" color="#94a3b8" :size="13" />
</view>
<text class="cal-title">{{ monthLabel }}</text>
<view class="cal-nav" @tap="switchMonth(1)">
<FaIcon name="chevron-right" color="#94a3b8" :size="13" />
</view>
<view class="cal-toggle" @tap="monthOpen = !monthOpen">
<text class="cal-toggle-text">{{ monthOpen ? '收起' : '展开月历' }}</text>
<FaIcon :name="monthOpen ? 'chevron-up' : 'chevron-down'" color="#2563eb" :size="12" />
</view>
</view>
<!-- 周历条 -->
<view class="week-strip">
<view
class="week-date"
:class="{ today: d.isToday, selected: d.key === selectedKey }"
>{{ d.day }}</view>
<view class="week-dot" :class="{ show: d.count > 0 }" />
v-for="d in weekDays"
:key="d.key"
class="week-item"
@tap="pickWeekDay(d)"
>
<text class="week-name">{{ d.name }}</text>
<view
class="week-date"
:class="{ today: d.isToday, selected: d.key === selectedKey }"
>{{ d.day }}</view>
<view class="week-dot" :class="{ show: d.count > 0 }" />
</view>
</view>
<!-- 月历展开 -->
<view v-if="monthOpen" class="month-grid">
<text v-for="n in WEEK_LABELS" :key="'w' + n" class="month-weekname">周{{ n }}</text>
<view
v-for="cell in monthCells"
:key="cell.key"
class="month-day"
:class="{ muted: !cell.inMonth, today: cell.isToday, selected: cell.selected }"
@tap="pickMonthDay(cell)"
>
<view class="month-day-num"><text>{{ cell.day }}</text></view>
<view class="week-dot" :class="{ show: cell.count > 0 }" />
</view>
</view>
</view>
@@ -48,7 +80,7 @@
:text="range === 'week' ? '本周暂无日程提醒' : '当天暂无日程提醒'"
/>
<view v-else class="rem-list">
<view v-for="item in shownItems" :key="item.id" class="rem-card" @tap="openDetail(item.id)">
<view v-for="item in shownItems" :key="item.id" class="rem-card" @tap="openEdit(item.id)">
<view class="rem-time">
<text class="rem-day">{{ shortDayLabel(item.datetime) }}</text>
<text class="rem-clock">{{ timeText(item.datetime) }}</text>
@@ -68,11 +100,18 @@
</view>
<view class="bottom-space" />
<!-- 新增按钮 -->
<view class="fab" @tap="openCreate">
<FaIcon name="plus" color="#ffffff" :size="20" />
<text class="fab-text">新增</text>
</view>
</view>
</template>
<script setup>
import { ref, computed, onMounted } from 'vue'
import { onShow } from '@dcloudio/uni-app'
import { fetchSchedules, getRemindChannelLabel, getRemindMinutesLabel } from '@/api/schedule.js'
import { pad, startOfDay, isToday } from '@/utils/date.js'
import { isLoggedIn } from '@/utils/auth.js'
@@ -99,6 +138,52 @@ function startOfWeek(base = new Date()) {
const weekStart = computed(() => startOfWeek(selectedDate.value))
const selectedKey = computed(() => dateKey(selectedDate.value))
/* ---------- 月历(可下拉展开) ---------- */
const monthOpen = ref(false)
const viewYear = ref(new Date().getFullYear())
const viewMonth = ref(new Date().getMonth()) // 0-based
const monthLabel = computed(() => `${viewYear.value}年${viewMonth.value + 1}月`)
function switchMonth(step) {
let y = viewYear.value
let m = viewMonth.value + step
if (m < 0) {
m = 11
y -= 1
} else if (m > 11) {
m = 0
y += 1
}
viewYear.value = y
viewMonth.value = m
}
/** 月历格子:从包含 1 号的那周周一起,固定 6 行 × 7 列 */
const monthCells = computed(() => {
const first = new Date(viewYear.value, viewMonth.value, 1)
const offset = (first.getDay() + 6) % 7
const start = new Date(viewYear.value, viewMonth.value, 1 - offset)
return Array.from({ length: 42 }, (_, i) => {
const d = new Date(start.getFullYear(), start.getMonth(), start.getDate() + i)
const key = dateKey(d)
return {
key,
date: d,
day: d.getDate(),
inMonth: d.getMonth() === viewMonth.value && d.getFullYear() === viewYear.value,
isToday: isToday(d),
selected: key === selectedKey.value,
count: (reminderMap.value[key] || []).length
}
})
})
function pickMonthDay(cell) {
selectedDate.value = startOfDay(cell.date)
range.value = 'day'
}
/** 只保留已设置提醒渠道的日程 */
const reminders = computed(() =>
schedules.value.filter((item) => item.remindChannels && item.remindChannels.length > 0)
@@ -176,16 +261,24 @@ function remindLine(item) {
function pickWeekDay(d) {
selectedDate.value = startOfDay(d.date)
viewYear.value = d.date.getFullYear()
viewMonth.value = d.date.getMonth()
range.value = 'day'
}
function showToday() {
selectedDate.value = startOfDay(new Date())
viewYear.value = selectedDate.value.getFullYear()
viewMonth.value = selectedDate.value.getMonth()
range.value = 'day'
}
function openDetail(id) {
uni.navigateTo({ url: `/pages/tools/schedule/detail?id=${id}` })
function openEdit(id) {
uni.navigateTo({ url: `/pages/tools/schedule/reminder-edit?id=${id}` })
}
function openCreate() {
uni.navigateTo({ url: '/pages/tools/schedule/reminder-edit' })
}
onMounted(() => {
@@ -196,6 +289,12 @@ onMounted(() => {
loadReminders()
})
// 新增/编辑返回后刷新列表
onShow(() => {
if (!isLoggedIn()) return
if (schedules.value.length || !loading.value) loadReminders()
})
async function loadReminders() {
loading.value = true
try {
@@ -271,16 +370,66 @@ async function loadReminders() {
justify-content: center;
}
/* ---------- 周历条 ---------- */
.week-card {
display: flex;
/* ---------- 月历(可下拉展开) ---------- */
.cal-card {
margin-top: 20rpx;
padding: 20rpx 8rpx 16rpx;
padding: 12rpx 8rpx 16rpx;
background: $color-card;
border-radius: $radius-lg;
box-shadow: $shadow-card;
}
.cal-header {
position: relative;
display: flex;
align-items: center;
justify-content: center;
gap: 20rpx;
padding: 8rpx 16rpx 12rpx;
}
.cal-nav {
display: flex;
align-items: center;
padding: 8rpx 12rpx;
&:active {
opacity: 0.6;
}
}
.cal-title {
min-width: 170rpx;
text-align: center;
font-size: 28rpx;
font-weight: 600;
color: $color-text;
}
.cal-toggle {
position: absolute;
right: 8rpx;
display: flex;
align-items: center;
gap: 6rpx;
padding: 8rpx 12rpx;
&:active {
opacity: 0.6;
}
}
.cal-toggle-text {
font-size: 24rpx;
color: $color-primary;
}
/* ---------- 周历条 ---------- */
.week-strip {
display: flex;
padding: 8rpx 8rpx 4rpx;
}
.week-item {
flex: 1;
display: flex;
@@ -327,6 +476,62 @@ async function loadReminders() {
}
}
/* ---------- 月历网格 ---------- */
.month-grid {
display: flex;
flex-wrap: wrap;
margin-top: 8rpx;
padding: 8rpx 8rpx 0;
border-top: 1rpx solid $color-divider;
}
.month-weekname {
width: calc(100% / 7);
text-align: center;
font-size: 22rpx;
color: $color-text-muted;
padding: 10rpx 0;
}
.month-day {
width: calc(100% / 7);
display: flex;
flex-direction: column;
align-items: center;
gap: 4rpx;
padding: 8rpx 0;
}
.month-day-num {
width: 52rpx;
height: 52rpx;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 26rpx;
color: $color-text;
}
.month-day.today .month-day-num {
color: $color-primary;
font-weight: 600;
}
.month-day.selected .month-day-num {
background: $color-primary;
color: #ffffff;
font-weight: 600;
}
.month-day.muted .month-day-num {
color: #c4cbd6;
}
.month-day:active {
opacity: 0.6;
}
/* ---------- 我的日程 ---------- */
.section-head {
display: flex;
@@ -438,4 +643,28 @@ async function loadReminders() {
.bottom-space {
height: 60rpx;
}
/* ---------- 新增按钮 ---------- */
.fab {
position: fixed;
right: 32rpx;
bottom: calc(48rpx + env(safe-area-inset-bottom));
display: flex;
align-items: center;
gap: 10rpx;
padding: 22rpx 36rpx;
border-radius: 44rpx;
background: $color-primary;
box-shadow: 0 12rpx 28rpx rgba(37, 99, 235, 0.36);
&:active {
opacity: 0.88;
}
}
.fab-text {
font-size: 28rpx;
color: #ffffff;
font-weight: 600;
}
</style>