diff --git a/pages/index/discovery.vue b/pages/index/discovery.vue index 31c094b..518242f 100644 --- a/pages/index/discovery.vue +++ b/pages/index/discovery.vue @@ -359,7 +359,7 @@ const userLocation = ref<{ longitude : number; latitude : number } | null>(null) const hospitals = ref([]) const articles = ref([]) - const scrollPaddingBottom = ref(140) + const scrollPaddingBottom = ref(78) const primaryButtonStyle = { background: 'linear-gradient(135deg, #F97316, #FB923C)', @@ -583,7 +583,7 @@ function calcLayout() { const systemInfo = uni.getSystemInfoSync() - scrollPaddingBottom.value = (systemInfo.safeAreaInsets?.bottom || 0) + 150 + scrollPaddingBottom.value = (systemInfo.safeAreaInsets?.bottom || 0) + 78 } async function loadDiscoveryData() { @@ -944,6 +944,11 @@ .tab-card :deep(.tn-tabs) { width: 100%; + align-self: center; + } + + .tab-card :deep(.tn-tabs__container) { + align-items: center; } .tab-card :deep(.tn-tabs__bar-container) { diff --git a/pages/index/index.vue b/pages/index/index.vue index 3cef50e..8da2124 100644 --- a/pages/index/index.vue +++ b/pages/index/index.vue @@ -18,7 +18,7 @@ - + { function calcSafeArea() { const systemInfo = uni.getSystemInfoSync() - // TabBar 高度约 50px,加上安全区底部 - safeAreaBottom.value = (systemInfo.safeAreaInsets?.bottom || 0) + 20 + safeAreaBottom.value = (systemInfo.safeAreaInsets?.bottom || 0) + 78 } function formatDate(dateStr: string) { diff --git a/pages/index/schedules.vue b/pages/index/schedules.vue index ae535e8..5e7b545 100644 --- a/pages/index/schedules.vue +++ b/pages/index/schedules.vue @@ -1,13 +1,1104 @@ - - diff --git a/pages/schedule/edit.vue b/pages/schedule/edit.vue index 9b772f7..4c1e716 100644 --- a/pages/schedule/edit.vue +++ b/pages/schedule/edit.vue @@ -3,7 +3,7 @@ - 添加提醒 + {{ pageTitle }} 为疫苗、驱虫、体检或自定义事项设置提醒。 @@ -38,7 +38,7 @@ - {{ submitting ? '保存中...' : '保存提醒' }} + {{ submitText }} @@ -89,30 +89,45 @@ const submitting = ref(false) const safeBottom = ref(0) const showPetPicker = ref(false) const showDatePicker = ref(false) +const scheduleId = ref('') const primaryButtonStyle = { background: 'linear-gradient(135deg, #F97316, #FB923C)', } const form = reactive({ petId: '', + type: 'custom', title: '', scheduledDate: '', + frequency: 'once', note: '', }) const selectedPetName = computed(() => petList.value.find((pet) => pet._id === form.petId)?.name || '') const canSubmit = computed(() => !!(form.petId && form.title.trim() && form.scheduledDate)) +const pageTitle = computed(() => (scheduleId.value ? '编辑提醒' : '添加提醒')) +const submitText = computed(() => { + if (submitting.value) return '保存中...' + return scheduleId.value ? '更新提醒' : '保存提醒' +}) const todayStr = computed(() => { const d = new Date() return `${d.getFullYear()}/${String(d.getMonth() + 1).padStart(2, '0')}/${String(d.getDate()).padStart(2, '0')} 00:00:00` }) -onLoad(() => { +onLoad((options: any) => { + scheduleId.value = options?.id || '' const sys = uni.getSystemInfoSync() safeBottom.value = sys.safeAreaInsets?.bottom || 0 - loadPets() + uni.setNavigationBarTitle({ title: scheduleId.value ? '编辑提醒' : '添加提醒' }) + loadPageData() }) +async function loadPageData() { + await loadPets() + if (scheduleId.value) await loadScheduleDetail() +} + async function loadPets() { try { const uid = uni.getStorageSync('uid') @@ -127,6 +142,30 @@ async function loadPets() { } } +async function loadScheduleDetail() { + try { + const uid = uni.getStorageSync('uid') + if (!uid || !scheduleId.value) return + const res = await uniCloud.callFunction({ + name: 'scheduleManager', + data: { action: 'detail', uid, scheduleId: scheduleId.value }, + }) + if (res.result?.code !== 0 || !res.result.data) { + throw new Error(res.result?.message || '提醒不存在') + } + const data = res.result.data + form.petId = data.pet_id || '' + form.type = data.type || 'custom' + form.title = data.title || '' + form.scheduledDate = normalizeDateValue(data.scheduledDate) + form.frequency = data.frequency || 'once' + form.note = data.note || '' + } catch (e) { + console.warn('加载提醒详情失败', e) + uni.showToast({ title: '提醒不存在或已删除', icon: 'none' }) + } +} + function selectPet(id: string) { form.petId = id showPetPicker.value = false @@ -137,30 +176,38 @@ async function handleSubmit() { submitting.value = true try { const uid = uni.getStorageSync('uid') - const db = uniCloud.database() - await db.collection('schedules').add({ - user_id: uid, + const payload: any = { + action: scheduleId.value ? 'update' : 'add', + uid, pet_id: form.petId, - type: 'custom', + type: form.type, title: form.title.trim(), scheduledDate: form.scheduledDate, - frequency: 'once', + frequency: form.frequency, interval: 1, - status: 'pending', reminderDays: [7, 3, 1], note: form.note.trim(), - createdAt: Date.now(), - updatedAt: Date.now(), - }) - uni.showToast({ title: '添加成功', icon: 'success' }) + } + if (scheduleId.value) payload.scheduleId = scheduleId.value + const res = await uniCloud.callFunction({ name: 'scheduleManager', data: payload }) + if (res.result?.code !== 0) throw new Error(res.result?.message || '保存失败') + uni.showToast({ title: scheduleId.value ? '更新成功' : '添加成功', icon: 'success' }) setTimeout(() => uni.navigateBack(), 1000) } catch (e) { console.error('保存提醒失败', e) - uni.showToast({ title: '保存失败,请检查云权限', icon: 'none' }) + uni.showToast({ title: '保存失败,请稍后再试', icon: 'none' }) } finally { submitting.value = false } } + +function normalizeDateValue(value: number | string | undefined) { + if (!value) return '' + if (typeof value === 'string') return value + const date = new Date(value) + if (Number.isNaN(date.getTime())) return '' + return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}` +}