OfficeSystem/pages/event/reminder-time-select/index.vue
2025-11-07 11:40:13 +08:00

327 lines
6.9 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="reminder-time-select-page">
<!-- 自定义导航栏 -->
<view class="custom-navbar">
<view class="navbar-content">
<text class="nav-btn" @click="handleCancel"></text>
<text class="nav-title">日程提醒</text>
<text class="nav-btn" style="opacity: 0; min-width: 44px;"></text>
</view>
</view>
<!-- 时间选项列表 -->
<scroll-view class="content-scroll" scroll-y>
<view class="time-options">
<view
v-for="option in timeOptions"
:key="option.value"
class="time-option"
:class="{ active: selectedValue === option.value && !isCustom }"
@click="selectTime(option.value)"
>
<text class="time-label">{{ option.label }}</text>
<text v-if="selectedValue === option.value && !isCustom" class="check">✓</text>
</view>
<!-- 自定义时间 -->
<view
class="time-option custom-option"
:class="{ active: isCustom }"
@click="openCustomTime"
>
<text class="time-label">自定义时间</text>
<text class="arrow"></text>
</view>
</view>
</scroll-view>
<!-- 自定义时间弹窗 -->
<view v-if="showCustomModal" class="modal-mask" @click="showCustomModal = false">
<view class="modal-content" @click.stop>
<view class="modal-title">自定义时间</view>
<view class="custom-time-content">
<view class="custom-input-group">
<text class="input-label">提前时间(分钟)</text>
<input
v-model="customMinutes"
type="number"
class="custom-input"
placeholder="请输入分钟数"
/>
</view>
<view class="custom-input-group">
<text class="input-label">显示文本</text>
<input
v-model="customText"
class="custom-input"
placeholder="例如开始前2小时"
/>
</view>
</view>
<view class="modal-buttons">
<button class="modal-btn" @click="showCustomModal = false">取消</button>
<button class="modal-btn primary" @click="confirmCustomTime">确定</button>
</view>
</view>
</view>
</view>
</template>
<script setup>
import { ref } from 'vue';
import { onLoad } from '@dcloudio/uni-app';
// 时间选项
const timeOptions = [
{ label: '开始时', value: 0 },
{ label: '开始前5分钟', value: 5 },
{ label: '开始前15分钟', value: 15 },
{ label: '开始前30分钟', value: 30 },
{ label: '开始前1小时', value: 60 },
{ label: '开始前2小时', value: 120 },
{ label: '开始前1天', value: 1440 },
{ label: '开始前2天', value: 2880 },
{ label: '开始前3天', value: 4320 }
];
const selectedValue = ref(15);
const isCustom = ref(false);
const showCustomModal = ref(false);
const customMinutes = ref('');
const customText = ref('');
const action = ref('add'); // add 或 edit
const reminderIndex = ref(0);
// 选择时间
const selectTime = (value) => {
selectedValue.value = value;
isCustom.value = false;
// 立即保存并返回
saveAndReturn();
};
// 打开自定义时间
const openCustomTime = () => {
showCustomModal.value = true;
// 如果已经是自定义,填充现有值(从 onLoad 中已设置)
};
// 确认自定义时间
const confirmCustomTime = () => {
if (!customMinutes.value || !customText.value.trim()) {
uni.showToast({
title: '请填写完整信息',
icon: 'none'
});
return;
}
isCustom.value = true;
selectedValue.value = parseInt(customMinutes.value);
showCustomModal.value = false;
// 保存并返回
saveAndReturn();
};
// 保存并返回
const saveAndReturn = () => {
const reminder = {
type: isCustom.value ? 'custom' : 'preset',
minutes: selectedValue.value
};
if (isCustom.value) {
reminder.customText = customText.value;
reminder.customMinutes = parseInt(customMinutes.value);
}
// 通过存储传递数据
uni.setStorageSync('updatedReminder', {
action: action.value,
index: reminderIndex.value,
reminder: reminder
});
uni.navigateBack();
};
// 取消
const handleCancel = () => {
uni.navigateBack();
};
// 页面加载
onLoad((options) => {
action.value = options.action || 'add';
reminderIndex.value = parseInt(options.index || 0);
if (options.type === 'custom') {
isCustom.value = true;
customMinutes.value = options.customMinutes || '';
customText.value = options.customText || '';
selectedValue.value = parseInt(options.customMinutes || 0);
} else {
selectedValue.value = parseInt(options.minutes || 15);
isCustom.value = false;
}
});
</script>
<style lang="scss" scoped>
.reminder-time-select-page {
min-height: 100vh;
background: #fff;
}
.custom-navbar {
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 1000;
background: #fff;
border-bottom: 1px solid #e5e5e5;
padding-top: var(--status-bar-height, 0);
}
.navbar-content {
height: 44px;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 16px;
}
.nav-btn {
font-size: 20px;
color: #333;
padding: 8px;
min-width: 44px;
}
.nav-title {
font-size: 17px;
font-weight: 600;
color: #333;
}
.content-scroll {
margin-top: calc(var(--status-bar-height, 0) + 45px);
height: calc(100vh - var(--status-bar-height, 0) - 45px);
}
.time-options {
padding: 0;
}
.time-option {
display: flex;
align-items: center;
justify-content: space-between;
padding: 16px;
border-bottom: 1px solid #f5f5f5;
}
.time-option.active {
color: #2885ff;
}
.time-label {
font-size: 16px;
color: #333;
}
.time-option.active .time-label {
color: #2885ff;
}
.check {
color: #2885ff;
font-size: 18px;
font-weight: 600;
}
.arrow {
font-size: 20px;
color: #ccc;
}
.custom-option.active .arrow {
color: #2885ff;
}
/* 弹窗样式 */
.modal-mask {
position: fixed;
left: 0;
top: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.5);
display: flex;
align-items: center;
justify-content: center;
z-index: 2000;
}
.modal-content {
background: #fff;
border-radius: 12px;
padding: 24px;
width: 80%;
max-width: 500px;
}
.modal-title {
font-size: 18px;
font-weight: 600;
margin-bottom: 20px;
text-align: center;
}
.custom-time-content {
margin-bottom: 20px;
}
.custom-input-group {
margin-bottom: 16px;
}
.input-label {
display: block;
font-size: 14px;
color: #666;
margin-bottom: 8px;
}
.custom-input {
width: 100%;
padding: 12px;
border: 1px solid #e5e5e5;
border-radius: 8px;
font-size: 16px;
}
.modal-buttons {
display: flex;
justify-content: flex-end;
gap: 16px;
margin-top: 20px;
}
.modal-btn {
padding: 10px 24px;
border: none;
background: #f5f5f5;
border-radius: 8px;
font-size: 16px;
color: #333;
}
.modal-btn.primary {
background: #2885ff;
color: #fff;
}
</style>