future #14

Merged
袁涛 merged 3 commits from future into main 2025-11-03 11:44:22 +08:00
3 changed files with 2786 additions and 2341 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -1,440 +1,518 @@
<template> <template>
<ion-page> <ion-page>
<div class="container"> <div class="container">
<!-- 头部编辑模式 --> <!-- 头部编辑模式 -->
<Header v-if="isEditorFocus" :onBack="handleCancel" :onAction="handleAction" actionIcon="edit" /> <Header v-if="isEditorFocus" :onBack="handleCancel" :onAction="handleAction" actionIcon="edit" />
<!-- 头部预览模式 --> <!-- 头部预览模式 -->
<Header v-else ref="headerRef" :onBack="handleCancel" :onAction="handleAction" actionIcon="preview" /> <Header v-else ref="headerRef" :onBack="handleCancel" :onAction="handleAction" actionIcon="preview" />
<section> <section>
<!-- 顶部信息栏 --> <!-- 顶部信息栏 -->
<div class="header-info"> <div ref="headerInfoRef" class="header-info">
<span class="edit-time">{{ formattedTime }}</span> <span class="edit-time">{{ formattedTime }}</span>
<span>|</span> <span>|</span>
<span class="word-count">{{ wordCount }}</span> <span class="word-count">{{ wordCount }}</span>
</div> </div>
<!-- 富文本编辑器 --> <!-- 富文本编辑器 -->
<div class="editor-container"> <div class="note-container" :style="{ height: noteContainerHeight }">
<RichTextEditor ref="editorRef" :modelValue="content" @update:modelValue="handleContentChange" @focus="handleEditorFocus" @blur="handleEditorBlur" class="rich-text-editor" /> <RichTextEditor ref="editorRef" :modelValue="content" @update:modelValue="handleContentChange" @focus="handleEditorFocus" @blur="handleEditorBlur" class="rich-text-editor" />
</div> </div>
</section> </section>
</div> </div>
</ion-page> </ion-page>
</template> </template>
<script setup> <script setup>
import { ref, computed, onMounted, nextTick, watch, onBeforeUnmount } from 'vue' import { ref, computed, onMounted, nextTick, watch, onBeforeUnmount } from 'vue'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
import { useAppStore } from '../stores/useAppStore' import { useAppStore } from '../stores/useAppStore'
import Header from '../components/Header.vue' import Header from '../components/Header.vue'
import RichTextEditor from '../components/RichTextEditor.vue' import RichTextEditor from '../components/RichTextEditor.vue'
import { formatNoteEditorDate } from '../utils/dateUtils' import { formatNoteEditorDate } from '../utils/dateUtils'
import { IonPage } from '@ionic/vue' import { IonPage } from '@ionic/vue'
const props = defineProps({ const props = defineProps({
id: { id: {
type: String, type: String,
default: null, default: null,
}, },
}) })
// 为了保持向后兼容性我们也支持noteId属性 // 为了保持向后兼容性我们也支持noteId属性
// 通过计算属性确保无论使用id还是noteId都能正确获取便签ID // 通过计算属性确保无论使用id还是noteId都能正确获取便签ID
const noteId = computed(() => props.id || props.noteId) const noteId = computed(() => props.id || props.noteId)
const store = useAppStore() const store = useAppStore()
const router = useRouter() const router = useRouter()
const editorRef = ref(null) const editorRef = ref(null)
const headerRef = ref(null) const headerRef = ref(null)
// 是否聚焦编辑器 const headerInfoRef = ref(null)
const isEditorFocus = ref(false) // 是否聚焦编辑器
const isEditorFocus = ref(false)
// 设置便签内容的函数
// 用于在编辑器中加载指定便签的内容 // 计算.note-container的高度
const setNoteContent = async noteId => { const noteContainerHeight = ref('100vh')
// 确保store数据已加载如果便签列表为空则先加载数据
if (store.notes.length === 0) { // 设置便签内容的函数
await store.loadData() // 用于在编辑器中加载指定便签的内容
} const setNoteContent = async noteId => {
// 确保store数据已加载如果便签列表为空则先加载数据
// 从store中查找指定ID的便签 if (store.notes.length === 0) {
const note = store.notes.find(n => n.id === noteId) await store.loadData()
}
// 确保编辑器已经初始化完成
await nextTick() // 从store中查找指定ID的便签
const note = store.notes.find(n => n.id === noteId)
if (note) {
// 无论editorRef是否可用都先设置content的值作为备份 // 确保编辑器已经初始化完成
content.value = note.content || '' await nextTick()
// 如果editorRef可用直接设置编辑器内容
if (editorRef.value) { if (note) {
editorRef.value.setContent(note.content || '') // 无论editorRef是否可用都先设置content的值作为备份
} content.value = note.content || ''
} // 如果editorRef可用直接设置编辑器内容
} if (editorRef.value) {
editorRef.value.setContent(note.content || '')
// 加载初始数据 }
onMounted(async () => { }
await store.loadData() }
// 如果是编辑现有便签,在组件挂载后设置内容 // 加载初始数据
if (noteId.value) { onMounted(async () => {
await setNoteContent(noteId.value) await store.loadData()
}
}) // 如果是编辑现有便签,在组件挂载后设置内容
if (noteId.value) {
// 监听noteId变化确保在编辑器准备好后设置内容 await setNoteContent(noteId.value)
watch( }
noteId,
async newNoteId => { // 等待DOM更新后计算.note-container的高度
if (newNoteId) { calculateNoteContainerHeight()
await setNoteContent(newNoteId) })
}
}, // 监听noteId变化确保在编辑器准备好后设置内容
{ immediate: true } watch(
) noteId,
async newNoteId => {
// 监听store变化确保在store加载后设置内容 if (newNoteId) {
watch( await setNoteContent(newNoteId)
() => store.notes, // 重新计算.note-container的高度
async newNotes => { calculateNoteContainerHeight()
if (noteId.value && newNotes.length > 0) { }
await setNoteContent(noteId.value) },
} { immediate: true }
}, )
{ immediate: true }
) // 监听store变化确保在store加载后设置内容
watch(
// 检查是否正在编辑现有便签 () => store.notes,
// 如果noteId存在则表示是编辑模式否则是新建模式 async newNotes => {
const isEditing = !!noteId.value if (noteId.value && newNotes.length > 0) {
const existingNote = isEditing ? store.notes.find(n => n.id === noteId.value) : null await setNoteContent(noteId.value)
// 重新计算.note-container的高度
// 初始化内容状态,如果是编辑现有便签则使用便签内容,否则为空字符串 calculateNoteContainerHeight()
const content = ref(existingNote?.content || '') }
},
// 当组件挂载时,确保编辑器初始化为空内容(针对新建便签) { immediate: true }
onMounted(() => { )
if (!isEditing && editorRef.value) {
console.log('Initializing editor for new note') // 检查是否正在编辑现有便签
editorRef.value.setContent('') // 如果noteId存在则表示是编辑模式否则是新建模式
} const isEditing = !!noteId.value
}) const existingNote = isEditing ? store.notes.find(n => n.id === noteId.value) : null
// 监听store变化确保在store加载后设置内容 // 初始化内容状态,如果是编辑现有便签则使用便签内容,否则为空字符串
watch( const content = ref(existingNote?.content || '')
() => store.notes,
async newNotes => { // 当组件挂载时,确保编辑器初始化为空内容(针对新建便签)
if (noteId.value && newNotes.length > 0) { onMounted(() => {
await setNoteContent(noteId.value) if (!isEditing && editorRef.value) {
} console.log('Initializing editor for new note')
}, editorRef.value.setContent('')
{ immediate: true } }
) })
const showAlert = ref(false)
// 监听store变化确保在store加载后设置内容
// 防抖函数 watch(
// 用于避免函数在短时间内被频繁调用,提高性能 () => store.notes,
const debounce = (func, delay) => { async newNotes => {
let timeoutId if (noteId.value && newNotes.length > 0) {
return function (...args) { await setNoteContent(noteId.value)
clearTimeout(timeoutId) // 重新计算.note-container的高度
timeoutId = setTimeout(() => func.apply(this, args), delay) calculateNoteContainerHeight()
} }
} },
{ immediate: true }
// 防抖处理内容变化 )
// 延迟300ms更新内容避免用户输入时频繁触发更新 const showAlert = ref(false)
const debouncedHandleContentChange = debounce(newContent => {
content.value = newContent // 防抖函数
}, 300) // 用于避免函数在短时间内被频繁调用,提高性能
const debounce = (func, delay) => {
// 监听编辑器内容变化 let timeoutId
// 当编辑器内容发生变化时调用此函数 return function (...args) {
const handleContentChange = newContent => { clearTimeout(timeoutId)
debouncedHandleContentChange(newContent) timeoutId = setTimeout(() => func.apply(this, args), delay)
} }
}
// 计算属性 - 格式化时间显示
// 如果是编辑现有便签则显示便签的更新时间,否则显示当前时间 // 防抖处理内容变化
const formattedTime = computed(() => { // 延迟300ms更新内容避免用户输入时频繁触发更新
if (existingNote?.updatedAt) { const debouncedHandleContentChange = debounce(newContent => {
return formatNoteEditorDate(existingNote.updatedAt) content.value = newContent
} }, 300)
return formatNoteEditorDate(new Date())
}) // 监听编辑器内容变化
// 当编辑器内容发生变化时调用此函数
// 计算属性 - 计算字数 const handleContentChange = newContent => {
// 移除HTML标签后计算纯文本字数 debouncedHandleContentChange(newContent)
const wordCount = computed(() => { }
// 使用正则表达式移除HTML标签只保留纯文本内容
const textContent = content.value.replace(/<[^>]*>/g, '') // 计算属性 - 格式化时间显示
return textContent.length || 0 // 如果是编辑现有便签则显示便签的更新时间,否则显示当前时间
}) const formattedTime = computed(() => {
if (existingNote?.updatedAt) {
// 处理保存 return formatNoteEditorDate(existingNote.updatedAt)
const handleSave = async () => { }
try { return formatNoteEditorDate(new Date())
// 获取编辑器中的实际内容 })
const editorContent = editorRef.value ? editorRef.value.getContent() : content.value
// 计算属性 - 计算字数
// 检查内容是否为空 // 移除HTML标签后计算纯文本字数
if (isContentEmpty(editorContent)) { const wordCount = computed(() => {
// 如果是编辑模式且内容为空,则删除便签 // 使用正则表达式移除HTML标签只保留纯文本内容
if (isEditing && existingNote) { const textContent = content.value.replace(/<[^>]*>/g, '')
await store.deleteNote(noteId.value) return textContent.length || 0
console.log('空便签已删除') })
// 删除后返回便签列表页面
router.push('/notes') // 处理保存
return const handleSave = async () => {
} try {
} else if (isEditing && existingNote) { // 获取编辑器中的实际内容
// 更新现有便签 const editorContent = editorRef.value ? editorRef.value.getContent() : content.value
await store.updateNote(noteId.value, {
content: editorContent, // 检查内容是否为空
}) if (isContentEmpty(editorContent)) {
console.log('便签已保存') // 如果是编辑模式且内容为空,则删除便签
} else { if (isEditing && existingNote) {
// 创建新便签 await store.deleteNote(noteId.value)
await store.addNote({ console.log('空便签已删除')
content: editorContent, // 删除后返回便签列表页面
isStarred: false, router.push('/notes')
}) return
console.log('新便签已创建') }
} } else if (isEditing && existingNote) {
// 更新现有便签
// 保存后切换到预览模式(失去编辑器焦点) await store.updateNote(noteId.value, {
isEditorFocus.value = false content: editorContent,
} catch (error) { })
// In a full implementation, show an alert or toast console.log('便签已保存')
console.log('Save error: Failed to save note. Please try again.') } else {
} // 创建新便签
} await store.addNote({
content: editorContent,
// 检查内容是否为空(无实质性内容) isStarred: false,
const isContentEmpty = content => { })
if (!content) return true console.log('新便签已创建')
}
// 检查是否包含图片元素
const hasImages = /<img[^>]*>|<div[^>]*class="[^"]*editor-image[^"]*"[^>]*>/.test(content) // 保存后切换到预览模式(失去编辑器焦点)
if (hasImages) return false isEditorFocus.value = false
} catch (error) {
// 移除HTML标签和空白字符后检查是否为空 // In a full implementation, show an alert or toast
const plainText = content.replace(/<[^>]*>/g, '').trim() console.log('Save error: Failed to save note. Please try again.')
if (plainText === '') return true }
}
// 检查是否只有空的HTML元素
const strippedContent = content // 检查内容是否为空(无实质性内容)
.replace(/\s+/g, '') const isContentEmpty = content => {
.replace(/<br>/g, '') if (!content) return true
.replace(/<br\/>/g, '')
if (strippedContent === '<p></p>' || strippedContent === '<div></div>' || strippedContent === '') return true // 检查是否包含图片元素
const hasImages = /<img[^>]*>|<div[^>]*class="[^"]*editor-image[^"]*"[^>]*>/.test(content)
return false if (hasImages) return false
}
// 移除HTML标签和空白字符后检查是否为空
// 自动保存便签(仅在非主动保存操作时调用) const plainText = content.replace(/<[^>]*>/g, '').trim()
const autoSaveNote = async () => { if (plainText === '') return true
try {
// 获取编辑器中的实际内容 // 检查是否只有空的HTML元素
const editorContent = editorRef.value ? editorRef.value.getContent() : content.value const strippedContent = content
.replace(/\s+/g, '')
if (isEditing && existingNote) { .replace(/<br>/g, '')
// 检查内容是否为空,如果为空则删除便签 .replace(/<br\/>/g, '')
if (isContentEmpty(editorContent)) { if (strippedContent === '<p></p>' || strippedContent === '<div></div>' || strippedContent === '') return true
// 删除便签
await store.deleteNote(noteId.value) return false
console.log('空便签已自动删除') }
} else if (editorContent !== (existingNote?.content || '')) {
// 更新现有便签(仅当内容有变化时 // 自动保存便签(仅在非主动保存操作时调用
await store.updateNote(noteId.value, { const autoSaveNote = async () => {
content: editorContent, try {
}) // 获取编辑器中的实际内容
console.log('便签已自动保存') const editorContent = editorRef.value ? editorRef.value.getContent() : content.value
}
} else if (!isContentEmpty(editorContent)) { if (isEditing && existingNote) {
// 创建新便签(仅当有内容时) // 检查内容是否为空,如果为空则删除便签
// 检查是否已经存在相同内容的便签以避免重复创建 if (isContentEmpty(editorContent)) {
const existingNotes = store.notes.filter(n => n.content === editorContent && !n.isDeleted) // 删除便签
if (existingNotes.length === 0) { await store.deleteNote(noteId.value)
await store.addNote({ console.log('空便签已自动删除')
content: editorContent, } else if (editorContent !== (existingNote?.content || '')) {
isStarred: false, // 更新现有便签(仅当内容有变化时)
}) await store.updateNote(noteId.value, {
console.log('新便签已自动保存') content: editorContent,
} })
} console.log('便签已自动保存')
} catch (error) { }
console.error('自动保存失败:', error) } else if (!isContentEmpty(editorContent)) {
} // 创建新便签(仅当有内容时)
} // 检查是否已经存在相同内容的便签以避免重复创建
const existingNotes = store.notes.filter(n => n.content === editorContent && !n.isDeleted)
// 处理取消 if (existingNotes.length === 0) {
const handleCancel = async () => { await store.addNote({
// 自动保存便签 content: editorContent,
await autoSaveNote() isStarred: false,
})
// 直接导航回便签列表页面,因为已经处理了保存或删除逻辑 console.log('新便签已自动保存')
router.push('/notes') }
} }
} catch (error) {
// 处理创建(用于新建便签) console.error('自动保存失败:', error)
const handleCreate = async () => { }
try { }
// 获取编辑器中的实际内容
const editorContent = editorRef.value ? editorRef.value.getContent() : content.value // 处理取消
const handleCancel = async () => {
// 只有当有内容时才创建新便签 // 自动保存便签
if (!isContentEmpty(editorContent)) { await autoSaveNote()
await store.addNote({
content: editorContent, // 直接导航回便签列表页面,因为已经处理了保存或删除逻辑
isStarred: false, router.push('/notes')
}) }
console.log('新便签已创建')
} // 处理创建(用于新建便签)
const handleCreate = async () => {
// 创建后切换到预览模式(失去编辑器焦点) try {
isEditorFocus.value = false // 获取编辑器中的实际内容
} catch (error) { const editorContent = editorRef.value ? editorRef.value.getContent() : content.value
// In a full implementation, show an alert or toast
console.log('Create error: Failed to create note. Please try again.') // 只有当有内容时才创建新便签
} if (!isContentEmpty(editorContent)) {
} await store.addNote({
content: editorContent,
// 处理Header组件的操作按钮点击事件 isStarred: false,
const handleAction = actionType => { })
if (actionType === 'save') { console.log('新便签已创建')
handleSave() }
} else if (actionType === 'create') {
handleCreate() // 创建后切换到预览模式(失去编辑器焦点)
} else if (actionType === 'insertImage') { isEditorFocus.value = false
// 插入图片功能 } catch (error) {
if (editorRef.value) { // In a full implementation, show an alert or toast
// 通过editorRef调用RichTextEditor组件的方法来插入图片 console.log('Create error: Failed to create note. Please try again.')
editorRef.value.insertImage() }
} }
} else if (actionType === 'delete') {
// 删除便签 // 处理Header组件的操作按钮点击事件
handleDelete() const handleAction = actionType => {
} else if (actionType === 'share') { if (actionType === 'save') {
// 分享便签 handleSave()
handleShare() } else if (actionType === 'create') {
} handleCreate()
} } else if (actionType === 'insertImage') {
// 插入图片功能
const setShowAlert = value => { if (editorRef.value) {
showAlert.value = value // 通过editorRef调用RichTextEditor组件的方法来插入图片
} editorRef.value.insertImage()
}
// 处理编辑器获得焦点 } else if (actionType === 'delete') {
const handleEditorFocus = () => { // 删除便签
isEditorFocus.value = true handleDelete()
} } else if (actionType === 'share') {
// 分享便签
// 处理编辑器失去焦点 handleShare()
const handleEditorBlur = () => { }
isEditorFocus.value = false }
}
const setShowAlert = value => {
// 处理删除便签 showAlert.value = value
const handleDelete = async () => { }
if (isEditing && existingNote) {
// 播放删除按钮动画 // 处理编辑器获得焦点
if (headerRef.value && headerRef.value.playDeleteAnimation) { const handleEditorFocus = () => {
headerRef.value.playDeleteAnimation() isEditorFocus.value = true
} // 重新计算.note-container的高度
nextTick(() => {
// 等待动画播放完成后再执行删除操作 calculateNoteContainerHeight()
// 15帧 * 50ms = 750ms再加上一些缓冲时间 })
setTimeout(async () => { }
try {
// 删除便签 // 处理编辑器失去焦点
await store.deleteNote(noteId.value) const handleEditorBlur = () => {
console.log('便签已删除') isEditorFocus.value = false
// 返回便签列表页面 // 重新计算.note-container的高度
router.push('/notes') nextTick(() => {
} catch (error) { calculateNoteContainerHeight()
console.error('删除便签失败:', error) })
} }
}, 800) // 等待约800ms让动画播放完成
} // 处理删除便签
} const handleDelete = async () => {
if (isEditing && existingNote) {
// 处理分享便签 // 播放删除按钮动画
const handleShare = () => { if (headerRef.value && headerRef.value.playDeleteAnimation) {
// 获取编辑器中的实际内容 headerRef.value.playDeleteAnimation()
const editorContent = editorRef.value ? editorRef.value.getContent() : content.value }
// 移除HTML标签获取纯文本内容用于分享 // 等待动画播放完成后再执行删除操作
const plainText = editorContent.replace(/<[^>]*>/g, '').trim() // 15帧 * 50ms = 750ms再加上一些缓冲时间
setTimeout(async () => {
if (plainText) { try {
// 在实际应用中,这里会调用设备的分享功能 // 删除便签
// 为了演示我们使用Web Share API如果支持 await store.deleteNote(noteId.value)
if (navigator.share) { console.log('便签已删除')
navigator // 返回便签列表页面
.share({ router.push('/notes')
title: '分享便签', } catch (error) {
text: plainText, console.error('删除便签失败:', error)
}) }
.catch(error => { }, 800) // 等待约800ms让动画播放完成
console.log('分享取消或失败:', error) }
}) }
} else {
// 如果不支持Web Share API可以复制到剪贴板 // 处理分享便签
navigator.clipboard const handleShare = () => {
.writeText(plainText) // 获取编辑器中的实际内容
.then(() => { const editorContent = editorRef.value ? editorRef.value.getContent() : content.value
console.log('内容已复制到剪贴板')
// 在实际应用中,这里会显示一个提示消息 // 移除HTML标签获取纯文本内容用于分享
}) const plainText = editorContent.replace(/<[^>]*>/g, '').trim()
.catch(error => {
console.error('复制失败:', error) if (plainText) {
}) // 在实际应用中,这里会调用设备的分享功能
} // 为了演示我们使用Web Share API如果支持
} if (navigator.share) {
} navigator
.share({
// 在组件卸载前自动保存或删除 title: '分享便签',
onBeforeUnmount(async () => { text: plainText,
await autoSaveNote() })
}) .catch(error => {
</script> console.log('分享取消或失败:', error)
})
<style lang="less" scoped> } else {
.container { // 如果不支持Web Share API可以复制到剪贴板
display: flex; navigator.clipboard
flex-direction: column; .writeText(plainText)
height: 100vh; .then(() => {
background-color: var(--background); console.log('内容已复制到剪贴板')
section { // 在实际应用中,这里会显示一个提示消息
width: 100%; })
height: 100%; .catch(error => {
} console.error('复制失败:', error)
} })
}
.editor-container { }
flex: 1; }
min-height: 100%;
overflow-y: auto; // 计算.note-container的高度
background-color: var(--background-card); const calculateNoteContainerHeight = () => {
&.disabled { nextTick(() => {
pointer-events: none; let headerHeight = 0
} let headerInfoHeight = 0
}
// 获取Header组件的高度
.rich-text-editor { if (headerRef.value?.$el) {
min-height: 100%; headerHeight = headerRef.value.$el.offsetHeight || 0
} } else {
// 如果headerRef不可用尝试查找Header组件的DOM元素
.header-info { const headerElement = document.querySelector('.component')
display: flex; headerHeight = headerElement ? headerElement.offsetHeight : 100 // 默认高度
justify-content: flex-start; }
gap: 0.625rem;
padding: 1rem 1rem 0.7rem 1rem; // 获取.header-info的高度
background-color: var(--background-card); if (headerInfoRef.value) {
border-bottom: 1px solid var(--border); headerInfoHeight = headerInfoRef.value.offsetHeight || 0
font-size: 0.7rem; } else {
color: var(--text-tertiary); // 如果headerInfoRef不可用获取.header-info的默认高度
} const headerInfoElement = document.querySelector('.header-info')
</style> headerInfoHeight = headerInfoElement ? headerInfoElement.offsetHeight : 40 // 默认高度
}
// 计算剩余高度 (屏幕高度 - Header高度 - HeaderInfo高度)
const totalHeaderHeight = headerHeight + headerInfoHeight
const screenHeight = window.innerHeight
const newHeight = screenHeight - totalHeaderHeight
// 设置.note-container的高度
noteContainerHeight.value = `${newHeight}px`
})
}
// 在组件挂载后和内容变化时重新计算高度
onMounted(() => {
// 等待DOM更新后再计算高度
nextTick(() => {
calculateNoteContainerHeight()
})
// 监听窗口大小变化事件
window.addEventListener('resize', calculateNoteContainerHeight)
})
// 监听编辑器焦点变化,重新计算高度
watch(isEditorFocus, () => {
nextTick(() => {
calculateNoteContainerHeight()
})
})
// 监听内容变化重新计算高度当内容变化可能导致header-info高度变化时
watch(content, () => {
nextTick(() => {
calculateNoteContainerHeight()
})
})
// 在组件卸载前自动保存或删除
onBeforeUnmount(async () => {
await autoSaveNote()
// 移除窗口大小变化事件监听器
window.removeEventListener('resize', calculateNoteContainerHeight)
})
</script>
<style lang="less" scoped>
.container {
display: flex;
flex-direction: column;
height: 100vh;
background-color: var(--background);
section {
width: 100%;
height: 100%;
}
}
.note-container {
flex: 1;
overflow-y: scroll;
background-color: var(--background);
}
.rich-text-editor {
min-height: 100%;
}
.header-info {
display: flex;
justify-content: flex-start;
gap: 0.625rem;
padding: 1rem 1rem 0.7rem 1rem;
background-color: var(--background-card);
border-bottom: 1px solid var(--border);
font-size: 0.7rem;
color: var(--text-tertiary);
}
</style>

View File

@@ -101,23 +101,7 @@ export const useAppStore = defineStore('app', {
// Mock folders - 使用固定的日期值 // Mock folders - 使用固定的日期值
// 预设的文件夹示例数据 // 预设的文件夹示例数据
const mockFolders = [ const mockFolders = []
{
id: 'folder1',
name: '工作',
createdAt: '2025-10-12T10:00:00.000Z',
},
{
id: 'folder2',
name: '个人',
createdAt: '2025-10-12T10:00:00.000Z',
},
{
id: 'folder3',
name: '学习',
createdAt: '2025-10-12T10:00:00.000Z',
},
]
// Mock settings // Mock settings
// 预设的设置示例数据 // 预设的设置示例数据