修复日程提醒功能

This commit is contained in:
2026-07-20 11:41:39 +08:00
parent 7ab6958538
commit f00ba9f9cc
19 changed files with 1735 additions and 1725 deletions
+18 -87
View File
@@ -15,29 +15,14 @@
<view class="field content-field">
<text class="field-label">内容</text>
<view class="editor-wrap">
<editor
id="noteEditor"
class="note-editor"
:placeholder="'记录你的想法...'"
:value="form.content"
@ready="onEditorReady"
@input="onEditorInput"
@focus="editorFocused = true"
@blur="editorFocused = false"
/>
<view class="editor-toolbar">
<view
v-for="btn in toolbarBtns"
:key="btn.name"
class="toolbar-btn"
:class="{ active: btn.active }"
@tap="execCommand(btn)"
>
<text>{{ btn.label }}</text>
</view>
</view>
</view>
<editor
id="noteEditor"
class="note-editor"
:placeholder="'记录你的想法...'"
:value="form.content"
@ready="onEditorReady"
@input="onEditorInput"
/>
</view>
<view class="switch-row" @tap="form.pinned = !form.pinned">
@@ -71,7 +56,6 @@ import { formatDate } from '@/utils/date.js'
const noteId = ref('')
const saving = ref(false)
const editorCtx = ref(null)
const editorFocused = ref(false)
const form = reactive({
title: '',
content: '',
@@ -81,28 +65,6 @@ const meta = reactive({
updatedAt: 0
})
const toolbarBtns = reactive([
{ name: 'bold', label: 'B', active: false, value: 'bold' },
{ name: 'italic', label: 'I', active: false, value: 'italic' },
{ name: 'underline', label: 'U', active: false, value: 'underline' },
{ name: 'strike', label: 'S', active: false, value: 'strikeThrough' },
{ name: 'header', label: 'H', active: false, value: 'header' },
{ name: 'list', label: '•', active: false, value: 'insertUnorderedList' },
{ name: 'indent', label: '→', active: false, value: 'indent' },
{ name: 'outdent', label: '←', active: false, value: 'outdent' },
{ name: 'divider', label: '—', active: false, value: 'insertHorizontalRule' },
])
onLoad(async (query) => {
if (query?.id) {
noteId.value = query.id
uni.setNavigationBarTitle({ title: '编辑笔记' })
await loadNote(query.id)
} else {
uni.setNavigationBarTitle({ title: '新建笔记' })
}
})
function onEditorReady() {
uni.createSelectorQuery().select('#noteEditor').context((res) => {
if (res && res.context) {
@@ -118,14 +80,15 @@ function onEditorInput(e) {
form.content = e.detail.html || ''
}
function execCommand(btn) {
if (!editorCtx.value) return
if (btn.name === 'header') {
editorCtx.value.format('header', 'H2')
onLoad(async (query) => {
if (query?.id) {
noteId.value = query.id
uni.setNavigationBarTitle({ title: '编辑笔记' })
await loadNote(query.id)
} else {
editorCtx.value.format(btn.value)
uni.setNavigationBarTitle({ title: '新建笔记' })
}
}
})
async function loadNote(id) {
try {
@@ -246,17 +209,9 @@ function onDelete() {
flex: 1;
display: flex;
flex-direction: column;
padding-bottom: 0;
padding: 24rpx 28rpx 0 28rpx;
overflow: hidden;
}
.editor-wrap {
background: $color-bg-page;
border-radius: $radius-md;
overflow: hidden;
flex: 1;
display: flex;
flex-direction: column;
border-top: 1rpx solid $color-divider;
}
.note-editor {
@@ -268,32 +223,8 @@ function onDelete() {
color: $color-text;
box-sizing: border-box;
overflow-y: auto;
}
.editor-toolbar {
display: flex;
flex-wrap: wrap;
gap: 8rpx;
padding: 16rpx 20rpx;
border-top: 1rpx solid $color-divider;
background: $color-card;
}
.toolbar-btn {
padding: 10rpx 20rpx;
border-radius: $radius-sm;
font-size: 24rpx;
color: $color-text-secondary;
background: $color-bg-page;
&.active {
color: $color-primary;
background: $color-primary-bg;
}
&:active {
opacity: 0.7;
}
border-radius: $radius-md;
}
.placeholder {
+95 -3
View File
@@ -65,6 +65,38 @@
</view>
</picker>
</view>
<view class="field">
<text class="field-label">重复提醒间隔分钟</text>
<view class="number-input">
<button class="number-btn" @tap="form.repeatIntervalMinutes = Math.max(0, form.repeatIntervalMinutes - 1)" :disabled="isCompleted"></button>
<input
v-model.number="form.repeatIntervalMinutes"
type="number"
class="number-field"
:disabled="isCompleted"
@blur="form.repeatIntervalMinutes = Math.max(0, Math.min(1440, form.repeatIntervalMinutes))"
/>
<button class="number-btn" @tap="form.repeatIntervalMinutes = Math.min(1440, form.repeatIntervalMinutes + 1)" :disabled="isCompleted">+</button>
</view>
<text class="form-tip">0表示不重复仅发送一次</text>
</view>
<view class="field">
<text class="field-label">最多提醒次数</text>
<view class="number-input">
<button class="number-btn" @tap="form.maxSendCount = Math.max(1, form.maxSendCount - 1)" :disabled="isCompleted"></button>
<input
v-model.number="form.maxSendCount"
type="number"
class="number-field"
:disabled="isCompleted"
@blur="form.maxSendCount = Math.max(1, Math.min(100, form.maxSendCount))"
/>
<button class="number-btn" @tap="form.maxSendCount = Math.min(100, form.maxSendCount + 1)" :disabled="isCompleted">+</button>
</view>
<text class="form-tip">最多发送的提醒次数</text>
</view>
</view>
<view v-if="!isCompleted" class="footer">
@@ -99,7 +131,9 @@ const form = reactive({
date: '',
time: '',
remindChannels: ['app'],
remindMinutes: 15
remindMinutes: 0,
repeatIntervalMinutes: 0,
maxSendCount: 1
})
const remindIndex = computed(() => {
@@ -134,7 +168,9 @@ async function loadSchedule(id) {
form.date = formatDate(d)
form.time = `${pad(d.getHours())}:${pad(d.getMinutes())}`
form.remindChannels = [...(item.remindChannels || [])]
form.remindMinutes = item.remindMinutes ?? 15
form.remindMinutes = item.remindMinutes ?? 0
form.repeatIntervalMinutes = item.repeatIntervalMinutes ?? 0
form.maxSendCount = item.maxSendCount ?? 1
isCompleted.value = !!item.completed
} catch (e) {
uni.showToast({ title: '加载失败', icon: 'none' })
@@ -200,7 +236,9 @@ async function saveData(datetime) {
content: form.content,
datetime,
remindChannels: [...form.remindChannels],
remindMinutes: form.remindMinutes
remindMinutes: form.remindMinutes,
repeatIntervalMinutes: form.repeatIntervalMinutes,
maxSendCount: form.maxSendCount
}
try {
if (scheduleId.value) {
@@ -334,6 +372,60 @@ async function saveData(datetime) {
}
}
.number-input {
display: flex;
align-items: center;
gap: 12rpx;
margin-bottom: 12rpx;
}
.number-btn {
width: 60rpx;
height: 60rpx;
border-radius: $radius-md;
background: $color-bg-page;
border: 1rpx solid $color-divider;
display: flex;
align-items: center;
justify-content: center;
font-size: 28rpx;
color: $color-text;
flex-shrink: 0;
&:active:not(:disabled) {
background: $color-primary-bg;
color: $color-primary;
}
&:disabled {
opacity: 0.5;
cursor: not-allowed;
}
}
.number-field {
flex: 1;
height: 60rpx;
padding: 0 16rpx;
background: $color-bg-page;
border: 1rpx solid $color-divider;
border-radius: $radius-md;
font-size: 28rpx;
color: $color-text;
text-align: center;
&:disabled {
opacity: 0.5;
}
}
.form-tip {
display: block;
font-size: 22rpx;
color: $color-text-muted;
margin-top: 8rpx;
}
.footer {
position: fixed;
left: 0;