You've already forked SmartisanNote.Remake
优化 时间显示格式调整
This commit is contained in:
31
IFLOW.md
31
IFLOW.md
@@ -15,6 +15,7 @@
|
|||||||
* **样式预处理器**: Less
|
* **样式预处理器**: Less
|
||||||
* **代码语言**: JavaScript (ES6+)
|
* **代码语言**: JavaScript (ES6+)
|
||||||
* **UI 组件库**: Ionic Framework
|
* **UI 组件库**: Ionic Framework
|
||||||
|
* **日期处理**: moment.js
|
||||||
|
|
||||||
## 项目结构
|
## 项目结构
|
||||||
|
|
||||||
@@ -31,6 +32,7 @@
|
|||||||
│ ├── stores/ # Pinia 状态管理 stores
|
│ ├── stores/ # Pinia 状态管理 stores
|
||||||
│ │ └── useAppStore.js # 全局状态管理 store
|
│ │ └── useAppStore.js # 全局状态管理 store
|
||||||
│ ├── utils/ # 工具函数
|
│ ├── utils/ # 工具函数
|
||||||
|
│ │ ├── dateUtils.js # 日期处理工具,基于 moment.js
|
||||||
│ │ └── storage.js # localStorage 封装,负责数据的读写
|
│ │ └── storage.js # localStorage 封装,负责数据的读写
|
||||||
│ ├── App.vue # 根组件
|
│ ├── App.vue # 根组件
|
||||||
│ └── main.js # 应用入口,初始化路由、Pinia 和挂载
|
│ └── main.js # 应用入口,初始化路由、Pinia 和挂载
|
||||||
@@ -48,8 +50,8 @@
|
|||||||
* 基于 Vite,支持热更新。
|
* 基于 Vite,支持热更新。
|
||||||
* **构建生产版本**: `npm run build`
|
* **构建生产版本**: `npm run build`
|
||||||
* 使用 Vite 构建,并同步到 Capacitor 项目 (`npx cap sync`)。
|
* 使用 Vite 构建,并同步到 Capacitor 项目 (`npx cap sync`)。
|
||||||
* **构建PWA版本**: `npm run build:pwa`
|
* **构建所有版本**: `npm run build:all`
|
||||||
* 构建PWA版本的应用
|
* 构建标准版本和 PWA 版本
|
||||||
* **部署PWA版本**: `npm run deploy:pwa`
|
* **部署PWA版本**: `npm run deploy:pwa`
|
||||||
* 构建并部署PWA版本到FTP服务器
|
* 构建并部署PWA版本到FTP服务器
|
||||||
* **在 Android 设备上运行**: `npm run android`
|
* **在 Android 设备上运行**: `npm run android`
|
||||||
@@ -77,6 +79,11 @@
|
|||||||
* **云同步**: 支持云同步设置(待实现)
|
* **云同步**: 支持云同步设置(待实现)
|
||||||
* **深色模式**: 支持深色模式切换(待完善)
|
* **深色模式**: 支持深色模式切换(待完善)
|
||||||
|
|
||||||
|
### 日期时间处理
|
||||||
|
* **智能格式化**: 根据时间范围自动格式化日期显示
|
||||||
|
* **多场景适配**: 不同页面使用不同的日期格式化规则
|
||||||
|
* **本地化支持**: 支持中文日期格式显示
|
||||||
|
|
||||||
## 代码规范与开发约定
|
## 代码规范与开发约定
|
||||||
|
|
||||||
* **状态管理**: 使用 Pinia 进行全局状态管理,通过 `useAppStore` composable 函数访问状态。
|
* **状态管理**: 使用 Pinia 进行全局状态管理,通过 `useAppStore` composable 函数访问状态。
|
||||||
@@ -85,6 +92,7 @@
|
|||||||
* **UI 风格**: 颜色方案严格遵循 `index.html` 中定义的 CSS 变量,以保持锤子便签的视觉风格。
|
* **UI 风格**: 颜色方案严格遵循 `index.html` 中定义的 CSS 变量,以保持锤子便签的视觉风格。
|
||||||
* **组件组织**: 页面组件 (`pages/`) 和可复用组件 (`components/`) 分离,结构清晰。
|
* **组件组织**: 页面组件 (`pages/`) 和可复用组件 (`components/`) 分离,结构清晰。
|
||||||
* **代码风格**: 采用标准的 Vue 3 Composition API 写法,使用 ES6 模块系统 (`import`/`export`)。
|
* **代码风格**: 采用标准的 Vue 3 Composition API 写法,使用 ES6 模块系统 (`import`/`export`)。
|
||||||
|
* **日期处理**: 使用 moment.js 进行日期处理,通过 `src/utils/dateUtils.js` 统一管理日期格式化逻辑。
|
||||||
|
|
||||||
## 样式
|
## 样式
|
||||||
|
|
||||||
@@ -124,6 +132,7 @@
|
|||||||
* **滑动交互**: 支持右滑显示删除按钮,带有阻尼效果
|
* **滑动交互**: 支持右滑显示删除按钮,带有阻尼效果
|
||||||
* **状态切换**: 支持星标和置顶状态的切换
|
* **状态切换**: 支持星标和置顶状态的切换
|
||||||
* **视觉反馈**: 滑动时便签夹会切换状态,提供直观的交互反馈
|
* **视觉反馈**: 滑动时便签夹会切换状态,提供直观的交互反馈
|
||||||
|
* **日期显示**: 显示格式化后的便签更新时间
|
||||||
|
|
||||||
### RichTextEditor 组件
|
### RichTextEditor 组件
|
||||||
* **富文本编辑**: 支持多种文本格式(加粗、居中、待办事项、列表、标题、引用)
|
* **富文本编辑**: 支持多种文本格式(加粗、居中、待办事项、列表、标题、引用)
|
||||||
@@ -140,12 +149,23 @@
|
|||||||
* **文件夹管理**: 支持文件夹的展开和切换
|
* **文件夹管理**: 支持文件夹的展开和切换
|
||||||
* **搜索功能**: 提供便签搜索功能
|
* **搜索功能**: 提供便签搜索功能
|
||||||
* **交互反馈**: 显示便签总数和置顶便签数量
|
* **交互反馈**: 显示便签总数和置顶便签数量
|
||||||
|
* **智能日期显示**: 根据时间范围显示不同的日期格式
|
||||||
|
* 今天:显示为 "今天 下午 4:00"
|
||||||
|
* 昨天:显示为 "昨天 下午 4:00"
|
||||||
|
* 超过两天但小于一周:显示为 "星期一 10/8 上午 3:00"
|
||||||
|
* 超过一周但小于一年:显示为 "10天前 9/20 下午 2:00"
|
||||||
|
* 超过一年:显示为 "635天前 2024/8/10 上午 9:00"
|
||||||
|
|
||||||
### NoteEditorPage
|
### NoteEditorPage
|
||||||
* **编辑模式**: 支持新建和编辑便签
|
* **编辑模式**: 支持新建和编辑便签
|
||||||
* **富文本编辑**: 集成RichTextEditor组件,支持丰富的文本格式
|
* **富文本编辑**: 集成RichTextEditor组件,支持丰富的文本格式
|
||||||
* **图片插入**: 支持通过工具栏插入图片
|
* **图片插入**: 支持通过工具栏插入图片
|
||||||
* **状态管理**: 根据路由参数判断是新建还是编辑模式
|
* **状态管理**: 根据路由参数判断是新建还是编辑模式
|
||||||
|
* **智能日期显示**: 根据时间范围显示不同的日期格式
|
||||||
|
* 今天:显示为 "今天 下午 4:00"
|
||||||
|
* 昨天:显示为 "昨天 下午 4:00"
|
||||||
|
* 超过两天但小于一个月:显示为 "10/8 上午 3:00"
|
||||||
|
* 超过一个月:显示为 "2024/8/10 上午 9:00"
|
||||||
|
|
||||||
## 状态管理 (Pinia)
|
## 状态管理 (Pinia)
|
||||||
|
|
||||||
@@ -170,6 +190,7 @@
|
|||||||
* **自动加载**: 当检测到无数据时自动加载预设的 mock 数据
|
* **自动加载**: 当检测到无数据时自动加载预设的 mock 数据
|
||||||
* **手动加载**: 可通过 URL 参数 `?mock=true` 强制加载 mock 数据
|
* **手动加载**: 可通过 URL 参数 `?mock=true` 强制加载 mock 数据
|
||||||
* **丰富内容**: 包含多种类型的便签、文件夹和设置示例
|
* **丰富内容**: 包含多种类型的便签、文件夹和设置示例
|
||||||
|
* **固定日期**: 使用固定的日期值确保数据一致性
|
||||||
|
|
||||||
### 增强的便签功能
|
### 增强的便签功能
|
||||||
* **置顶支持**: 便签可以置顶显示在列表顶部
|
* **置顶支持**: 便签可以置顶显示在列表顶部
|
||||||
@@ -179,3 +200,9 @@
|
|||||||
### PWA 支持
|
### PWA 支持
|
||||||
* **离线使用**: 支持构建PWA版本,可离线使用
|
* **离线使用**: 支持构建PWA版本,可离线使用
|
||||||
* **自动部署**: 支持一键构建并部署到FTP服务器
|
* **自动部署**: 支持一键构建并部署到FTP服务器
|
||||||
|
|
||||||
|
### 智能日期处理
|
||||||
|
* **统一管理**: 通过 `dateUtils.js` 统一管理所有日期处理逻辑
|
||||||
|
* **多格式支持**: 支持多种日期格式化方式以适应不同场景
|
||||||
|
* **本地化显示**: 支持中文友好的日期时间显示
|
||||||
|
* **场景适配**: 不同页面使用最适合的日期格式化规则
|
||||||
10
package-lock.json
generated
10
package-lock.json
generated
@@ -17,6 +17,7 @@
|
|||||||
"@vue/compiler-sfc": "^3.5.22",
|
"@vue/compiler-sfc": "^3.5.22",
|
||||||
"basic-ftp": "^5.0.5",
|
"basic-ftp": "^5.0.5",
|
||||||
"ionicons": "^7.4.0",
|
"ionicons": "^7.4.0",
|
||||||
|
"moment": "^2.30.1",
|
||||||
"pinia": "^3.0.3",
|
"pinia": "^3.0.3",
|
||||||
"vue": "^3.5.22",
|
"vue": "^3.5.22",
|
||||||
"vue-router": "^4.5.1"
|
"vue-router": "^4.5.1"
|
||||||
@@ -8868,6 +8869,15 @@
|
|||||||
"integrity": "sha512-23g5BFj4zdQL/b6tor7Ji+QY4pEfNH784BMslY9Qb0UnJWRAt+lQGLYmRaM0KDBwIG23ffEBELhZDP2rhi9f/Q==",
|
"integrity": "sha512-23g5BFj4zdQL/b6tor7Ji+QY4pEfNH784BMslY9Qb0UnJWRAt+lQGLYmRaM0KDBwIG23ffEBELhZDP2rhi9f/Q==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/moment": {
|
||||||
|
"version": "2.30.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz",
|
||||||
|
"integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/mrmime": {
|
"node_modules/mrmime": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz",
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
"@vue/compiler-sfc": "^3.5.22",
|
"@vue/compiler-sfc": "^3.5.22",
|
||||||
"basic-ftp": "^5.0.5",
|
"basic-ftp": "^5.0.5",
|
||||||
"ionicons": "^7.4.0",
|
"ionicons": "^7.4.0",
|
||||||
|
"moment": "^2.30.1",
|
||||||
"pinia": "^3.0.3",
|
"pinia": "^3.0.3",
|
||||||
"vue": "^3.5.22",
|
"vue": "^3.5.22",
|
||||||
"vue-router": "^4.5.1"
|
"vue-router": "^4.5.1"
|
||||||
|
|||||||
@@ -30,6 +30,7 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { computed, ref } from 'vue'
|
import { computed, ref } from 'vue'
|
||||||
|
import { formatDateTime } from '../utils/dateUtils'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
content: {
|
content: {
|
||||||
@@ -77,7 +78,7 @@ const isSliding = ref(false)
|
|||||||
const isSlided = ref(false) // 是否已经滑动到阈值
|
const isSlided = ref(false) // 是否已经滑动到阈值
|
||||||
|
|
||||||
const formattedDate = computed(() => {
|
const formattedDate = computed(() => {
|
||||||
// 简单的日期格式化,实际项目中可能需要更复杂的处理
|
// 直接返回已经格式化的日期字符串
|
||||||
return props.date
|
return props.date
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ import { ref, computed, onMounted, nextTick, watch } from 'vue'
|
|||||||
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'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
id: {
|
id: {
|
||||||
@@ -158,23 +159,10 @@ const handleContentChange = (newContent) => {
|
|||||||
|
|
||||||
// 计算属性
|
// 计算属性
|
||||||
const formattedTime = computed(() => {
|
const formattedTime = computed(() => {
|
||||||
const now = new Date()
|
if (existingNote?.updatedAt) {
|
||||||
const date = existingNote?.updatedAt ? new Date(existingNote.updatedAt) : now
|
return formatNoteEditorDate(existingNote.updatedAt)
|
||||||
|
|
||||||
// 如果是今天
|
|
||||||
if (date.toDateString() === now.toDateString()) {
|
|
||||||
return `今天 ${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}`
|
|
||||||
}
|
}
|
||||||
|
return formatNoteEditorDate(new Date())
|
||||||
// 如果是昨天
|
|
||||||
const yesterday = new Date(now)
|
|
||||||
yesterday.setDate(yesterday.getDate() - 1)
|
|
||||||
if (date.toDateString() === yesterday.toDateString()) {
|
|
||||||
return `昨天 ${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}`
|
|
||||||
}
|
|
||||||
|
|
||||||
// 其他情况显示月日
|
|
||||||
return `${date.getMonth() + 1}月${date.getDate()}日`
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const wordCount = computed(() => {
|
const wordCount = computed(() => {
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ import NoteItem from '../components/NoteItem.vue'
|
|||||||
import Header from '../components/Header.vue'
|
import Header from '../components/Header.vue'
|
||||||
import FolderManage from '../components/FolderManage.vue'
|
import FolderManage from '../components/FolderManage.vue'
|
||||||
import SearchBar from '../components/SearchBar.vue'
|
import SearchBar from '../components/SearchBar.vue'
|
||||||
|
import { formatNoteListDate } from '../utils/dateUtils'
|
||||||
|
|
||||||
const store = useAppStore()
|
const store = useAppStore()
|
||||||
|
|
||||||
@@ -318,31 +319,7 @@ const debouncedHandleSearch = debounceSearch((query) => {
|
|||||||
|
|
||||||
// 改进的日期格式化函数
|
// 改进的日期格式化函数
|
||||||
const formatDate = dateString => {
|
const formatDate = dateString => {
|
||||||
const date = new Date(dateString)
|
return formatNoteListDate(dateString)
|
||||||
const now = new Date()
|
|
||||||
|
|
||||||
// 计算日期差
|
|
||||||
const diffTime = now - date
|
|
||||||
const diffDays = Math.floor(diffTime / (1000 * 60 * 60 * 24))
|
|
||||||
|
|
||||||
// 今天的便签显示时间
|
|
||||||
if (diffDays === 0) {
|
|
||||||
return `${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}`
|
|
||||||
}
|
|
||||||
|
|
||||||
// 昨天的便签显示"昨天"
|
|
||||||
if (diffDays === 1) {
|
|
||||||
return '昨天'
|
|
||||||
}
|
|
||||||
|
|
||||||
// 一周内的便签显示星期几
|
|
||||||
if (diffDays < 7) {
|
|
||||||
const weekdays = ['周日', '周一', '周二', '周三', '周四', '周五', '周六']
|
|
||||||
return weekdays[date.getDay()]
|
|
||||||
}
|
|
||||||
|
|
||||||
// 超过一周的便签显示月日
|
|
||||||
return `${date.getMonth() + 1}/${date.getDate()}`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const setCurrentFolder = folder => {
|
const setCurrentFolder = folder => {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { defineStore } from 'pinia'
|
import { defineStore } from 'pinia'
|
||||||
import * as storage from '../utils/storage'
|
import * as storage from '../utils/storage'
|
||||||
|
import { getCurrentDateTime, getPastDate } from '../utils/dateUtils'
|
||||||
|
|
||||||
export const useAppStore = defineStore('app', {
|
export const useAppStore = defineStore('app', {
|
||||||
state: () => ({
|
state: () => ({
|
||||||
@@ -41,14 +42,21 @@ export const useAppStore = defineStore('app', {
|
|||||||
|
|
||||||
// 加载mock数据
|
// 加载mock数据
|
||||||
async loadMockData() {
|
async loadMockData() {
|
||||||
// Mock notes
|
// Mock notes - 使用固定的日期值以避免每次运行时变化
|
||||||
|
const fixedCurrentDate = '2025-10-12T10:00:00.000Z';
|
||||||
|
const fixedYesterday = '2025-10-11T10:00:00.000Z';
|
||||||
|
const fixedTwoDaysAgo = '2025-10-10T10:00:00.000Z';
|
||||||
|
const fixedThreeDaysAgo = '2025-10-09T10:00:00.000Z';
|
||||||
|
const fixedFourDaysAgo = '2025-10-08T10:00:00.000Z';
|
||||||
|
const fixedFiveDaysAgo = '2025-10-07T10:00:00.000Z';
|
||||||
|
|
||||||
const mockNotes = [
|
const mockNotes = [
|
||||||
{
|
{
|
||||||
id: '1',
|
id: '1',
|
||||||
title: '欢迎使用锤子便签',
|
title: '欢迎使用锤子便签',
|
||||||
content: '这是一个功能强大的便签应用,您可以在这里记录您的想法、待办事项等。',
|
content: '这是一个功能强大的便签应用,您可以在这里记录您的想法、待办事项等。',
|
||||||
createdAt: new Date().toISOString(),
|
createdAt: fixedCurrentDate,
|
||||||
updatedAt: new Date().toISOString(),
|
updatedAt: fixedCurrentDate,
|
||||||
folderId: null,
|
folderId: null,
|
||||||
isStarred: true,
|
isStarred: true,
|
||||||
isTop: true,
|
isTop: true,
|
||||||
@@ -60,8 +68,8 @@ export const useAppStore = defineStore('app', {
|
|||||||
id: '2',
|
id: '2',
|
||||||
title: '待办事项',
|
title: '待办事项',
|
||||||
content: '1. 完成项目报告\n2. 购买 groceries\n3. 预约医生\n4. 给朋友打电话',
|
content: '1. 完成项目报告\n2. 购买 groceries\n3. 预约医生\n4. 给朋友打电话',
|
||||||
createdAt: new Date(Date.now() - 86400000).toISOString(), // 昨天
|
createdAt: fixedYesterday,
|
||||||
updatedAt: new Date(Date.now() - 86400000).toISOString(),
|
updatedAt: fixedYesterday,
|
||||||
folderId: null,
|
folderId: null,
|
||||||
isStarred: true,
|
isStarred: true,
|
||||||
isTop: false,
|
isTop: false,
|
||||||
@@ -73,8 +81,8 @@ export const useAppStore = defineStore('app', {
|
|||||||
id: '3',
|
id: '3',
|
||||||
title: '购物清单',
|
title: '购物清单',
|
||||||
content: '苹果\n牛奶\n面包\n鸡蛋\n西红柿\n咖啡',
|
content: '苹果\n牛奶\n面包\n鸡蛋\n西红柿\n咖啡',
|
||||||
createdAt: new Date(Date.now() - 172800000).toISOString(), // 前天
|
createdAt: fixedTwoDaysAgo,
|
||||||
updatedAt: new Date(Date.now() - 172800000).toISOString(),
|
updatedAt: fixedTwoDaysAgo,
|
||||||
folderId: null,
|
folderId: null,
|
||||||
isStarred: false,
|
isStarred: false,
|
||||||
isTop: false,
|
isTop: false,
|
||||||
@@ -86,8 +94,8 @@ export const useAppStore = defineStore('app', {
|
|||||||
id: '4',
|
id: '4',
|
||||||
title: '项目想法',
|
title: '项目想法',
|
||||||
content: '1. 实现云同步功能\n2. 添加深色模式\n3. 支持Markdown语法\n4. 添加标签功能',
|
content: '1. 实现云同步功能\n2. 添加深色模式\n3. 支持Markdown语法\n4. 添加标签功能',
|
||||||
createdAt: new Date(Date.now() - 259200000).toISOString(), // 3天前
|
createdAt: fixedThreeDaysAgo,
|
||||||
updatedAt: new Date(Date.now() - 259200000).toISOString(),
|
updatedAt: fixedThreeDaysAgo,
|
||||||
folderId: null,
|
folderId: null,
|
||||||
isStarred: false,
|
isStarred: false,
|
||||||
isTop: false,
|
isTop: false,
|
||||||
@@ -99,8 +107,8 @@ export const useAppStore = defineStore('app', {
|
|||||||
id: '5',
|
id: '5',
|
||||||
title: '读书笔记',
|
title: '读书笔记',
|
||||||
content: '《Vue.js实战》\n- 组件化思想是Vue的核心\n- 理解响应式原理很重要\n- Pinia是Vue 3的推荐状态管理库',
|
content: '《Vue.js实战》\n- 组件化思想是Vue的核心\n- 理解响应式原理很重要\n- Pinia是Vue 3的推荐状态管理库',
|
||||||
createdAt: new Date(Date.now() - 345600000).toISOString(), // 4天前
|
createdAt: fixedFourDaysAgo,
|
||||||
updatedAt: new Date(Date.now() - 345600000).toISOString(),
|
updatedAt: fixedFourDaysAgo,
|
||||||
folderId: null,
|
folderId: null,
|
||||||
isStarred: false,
|
isStarred: false,
|
||||||
isTop: false,
|
isTop: false,
|
||||||
@@ -112,33 +120,33 @@ export const useAppStore = defineStore('app', {
|
|||||||
id: '6',
|
id: '6',
|
||||||
title: '已删除的便签',
|
title: '已删除的便签',
|
||||||
content: '这是一条已删除的便签示例,应该只在回收站中显示。',
|
content: '这是一条已删除的便签示例,应该只在回收站中显示。',
|
||||||
createdAt: new Date(Date.now() - 432000000).toISOString(), // 5天前
|
createdAt: fixedFiveDaysAgo,
|
||||||
updatedAt: new Date(Date.now() - 432000000).toISOString(),
|
updatedAt: fixedFiveDaysAgo,
|
||||||
folderId: null,
|
folderId: null,
|
||||||
isStarred: false,
|
isStarred: false,
|
||||||
isTop: false,
|
isTop: false,
|
||||||
hasImage: false,
|
hasImage: false,
|
||||||
isDeleted: true,
|
isDeleted: true,
|
||||||
deletedAt: new Date(Date.now() - 86400000).toISOString(), // 1天前删除
|
deletedAt: fixedYesterday,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
// Mock folders
|
// Mock folders - 使用固定的日期值
|
||||||
const mockFolders = [
|
const mockFolders = [
|
||||||
{
|
{
|
||||||
id: 'folder1',
|
id: 'folder1',
|
||||||
name: '工作',
|
name: '工作',
|
||||||
createdAt: new Date().toISOString(),
|
createdAt: '2025-10-12T10:00:00.000Z',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'folder2',
|
id: 'folder2',
|
||||||
name: '个人',
|
name: '个人',
|
||||||
createdAt: new Date().toISOString(),
|
createdAt: '2025-10-12T10:00:00.000Z',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'folder3',
|
id: 'folder3',
|
||||||
name: '学习',
|
name: '学习',
|
||||||
createdAt: new Date().toISOString(),
|
createdAt: '2025-10-12T10:00:00.000Z',
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -229,7 +237,7 @@ export const useAppStore = defineStore('app', {
|
|||||||
// 将便签移至回收站
|
// 将便签移至回收站
|
||||||
async moveToTrash(id) {
|
async moveToTrash(id) {
|
||||||
try {
|
try {
|
||||||
const updatedNote = await storage.updateNote(id, { isDeleted: true, deletedAt: new Date().toISOString() })
|
const updatedNote = await storage.updateNote(id, { isDeleted: true, deletedAt: getCurrentDateTime() })
|
||||||
if (updatedNote) {
|
if (updatedNote) {
|
||||||
const index = this.notes.findIndex(note => note.id === id)
|
const index = this.notes.findIndex(note => note.id === id)
|
||||||
if (index !== -1) {
|
if (index !== -1) {
|
||||||
|
|||||||
124
src/utils/dateUtils.js
Normal file
124
src/utils/dateUtils.js
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
import moment from 'moment'
|
||||||
|
|
||||||
|
// 设置中文语言包
|
||||||
|
import 'moment/locale/zh-cn'
|
||||||
|
moment.locale('zh-cn')
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 格式化日期时间
|
||||||
|
* @param {string|Date} date - 日期对象或日期字符串
|
||||||
|
* @param {string} format - 格式化字符串,默认为 'YYYY-MM-DD HH:mm'
|
||||||
|
* @returns {string} 格式化后的日期时间字符串
|
||||||
|
*/
|
||||||
|
export const formatDateTime = (date, format = 'YYYY-MM-DD HH:mm') => {
|
||||||
|
return moment(date).format(format)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 格式化相对时间(如:5分钟前,2小时前等)
|
||||||
|
* @param {string|Date} date - 日期对象或日期字符串
|
||||||
|
* @returns {string} 相对时间字符串
|
||||||
|
*/
|
||||||
|
export const formatRelativeTime = (date) => {
|
||||||
|
return moment(date).fromNow()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 格式化便签列表时间
|
||||||
|
* @param {string|Date} date - 日期对象或日期字符串
|
||||||
|
* @returns {string} 格式化后的日期时间字符串
|
||||||
|
*/
|
||||||
|
export const formatNoteListDate = (date) => {
|
||||||
|
const momentDate = moment(date)
|
||||||
|
const now = moment()
|
||||||
|
const diffDays = now.diff(momentDate, 'days')
|
||||||
|
|
||||||
|
// 今天
|
||||||
|
if (diffDays === 0) {
|
||||||
|
return momentDate.format('[今天] A h:mm').replace('AM', '上午').replace('PM', '下午')
|
||||||
|
}
|
||||||
|
|
||||||
|
// 昨天
|
||||||
|
if (diffDays === 1) {
|
||||||
|
return momentDate.format('[昨天] A h:mm').replace('AM', '上午').replace('PM', '下午')
|
||||||
|
}
|
||||||
|
|
||||||
|
// 超过两天但小于一周
|
||||||
|
if (diffDays > 1 && diffDays < 7) {
|
||||||
|
const weekdays = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六']
|
||||||
|
return momentDate.format(`[${weekdays[momentDate.day()]}] M/D A h:mm`).replace('AM', '上午').replace('PM', '下午')
|
||||||
|
}
|
||||||
|
|
||||||
|
// 超过一周但小于一年
|
||||||
|
if (diffDays >= 7 && diffDays < 365) {
|
||||||
|
return momentDate.format(`[${diffDays}天前] M/D A h:mm`).replace('AM', '上午').replace('PM', '下午')
|
||||||
|
}
|
||||||
|
|
||||||
|
// 超过一年
|
||||||
|
return momentDate.format(`[${diffDays}天前] YYYY/M/D A h:mm`).replace('AM', '上午').replace('PM', '下午')
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 格式化便签编辑页时间
|
||||||
|
* @param {string|Date} date - 日期对象或日期字符串
|
||||||
|
* @returns {string} 格式化后的日期时间字符串
|
||||||
|
*/
|
||||||
|
export const formatNoteEditorDate = (date) => {
|
||||||
|
const momentDate = moment(date)
|
||||||
|
const now = moment()
|
||||||
|
const diffDays = now.diff(momentDate, 'days')
|
||||||
|
|
||||||
|
// 今天
|
||||||
|
if (diffDays === 0) {
|
||||||
|
return momentDate.format('[今天] A h:mm').replace('AM', '上午').replace('PM', '下午')
|
||||||
|
}
|
||||||
|
|
||||||
|
// 昨天
|
||||||
|
if (diffDays === 1) {
|
||||||
|
return momentDate.format('[昨天] A h:mm').replace('AM', '上午').replace('PM', '下午')
|
||||||
|
}
|
||||||
|
|
||||||
|
// 超过两天但小于一个月
|
||||||
|
if (diffDays > 1 && diffDays < 30) {
|
||||||
|
return momentDate.format('M/D A h:mm').replace('AM', '上午').replace('PM', '下午')
|
||||||
|
}
|
||||||
|
|
||||||
|
// 超过一个月
|
||||||
|
return momentDate.format('YYYY/M/D A h:mm').replace('AM', '上午').replace('PM', '下午')
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取过去的日期
|
||||||
|
* @param {number} amount - 数量
|
||||||
|
* @param {string} unit - 单位(days, weeks, months, years等)
|
||||||
|
* @returns {string} ISO格式的日期字符串
|
||||||
|
*/
|
||||||
|
export const getPastDate = (amount, unit) => {
|
||||||
|
return moment().subtract(amount, unit).toISOString()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取当前日期时间
|
||||||
|
* @returns {string} ISO格式的日期字符串
|
||||||
|
*/
|
||||||
|
export const getCurrentDateTime = () => {
|
||||||
|
return moment().toISOString()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取时间戳
|
||||||
|
* @returns {number} 时间戳
|
||||||
|
*/
|
||||||
|
export const getTimestamp = () => {
|
||||||
|
return moment().valueOf()
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
formatDateTime,
|
||||||
|
formatRelativeTime,
|
||||||
|
formatNoteListDate,
|
||||||
|
formatNoteEditorDate,
|
||||||
|
getPastDate,
|
||||||
|
getCurrentDateTime,
|
||||||
|
getTimestamp
|
||||||
|
}
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import { getCurrentDateTime, getTimestamp } from './dateUtils'
|
||||||
|
|
||||||
// Storage keys
|
// Storage keys
|
||||||
const NOTES_KEY = 'notes';
|
const NOTES_KEY = 'notes';
|
||||||
const FOLDERS_KEY = 'folders';
|
const FOLDERS_KEY = 'folders';
|
||||||
@@ -25,9 +27,9 @@ export const saveNotes = async (notes) => {
|
|||||||
export const addNote = async (note) => {
|
export const addNote = async (note) => {
|
||||||
const newNote = {
|
const newNote = {
|
||||||
...note,
|
...note,
|
||||||
id: Date.now().toString(),
|
id: getTimestamp().toString(),
|
||||||
createdAt: new Date().toISOString(),
|
createdAt: getCurrentDateTime(),
|
||||||
updatedAt: new Date().toISOString(),
|
updatedAt: getCurrentDateTime(),
|
||||||
isStarred: note.isStarred || false,
|
isStarred: note.isStarred || false,
|
||||||
isTop: note.isTop || false,
|
isTop: note.isTop || false,
|
||||||
hasImage: note.hasImage || false,
|
hasImage: note.hasImage || false,
|
||||||
@@ -51,7 +53,7 @@ export const updateNote = async (id, updates) => {
|
|||||||
const updatedNote = {
|
const updatedNote = {
|
||||||
...notes[index],
|
...notes[index],
|
||||||
...updates,
|
...updates,
|
||||||
updatedAt: new Date().toISOString(),
|
updatedAt: getCurrentDateTime(),
|
||||||
};
|
};
|
||||||
|
|
||||||
notes[index] = updatedNote;
|
notes[index] = updatedNote;
|
||||||
@@ -92,8 +94,8 @@ export const saveFolders = async (folders) => {
|
|||||||
export const addFolder = async (folder) => {
|
export const addFolder = async (folder) => {
|
||||||
const newFolder = {
|
const newFolder = {
|
||||||
...folder,
|
...folder,
|
||||||
id: Date.now().toString(),
|
id: getTimestamp().toString(),
|
||||||
createdAt: new Date().toISOString(),
|
createdAt: getCurrentDateTime(),
|
||||||
};
|
};
|
||||||
|
|
||||||
const folders = await getFolders();
|
const folders = await getFolders();
|
||||||
|
|||||||
Reference in New Issue
Block a user