From fb036fd65f4303d39375443cbb9169c805846853 Mon Sep 17 00:00:00 2001 From: yuming Date: Tue, 2 Jun 2026 12:54:20 +0800 Subject: [PATCH] =?UTF-8?q?=E8=AE=BE=E7=BD=AE=E9=A1=B5=E6=94=B9=E9=80=A0?= =?UTF-8?q?=EF=BC=9A=E3=80=8C=E8=AE=BE=E7=BD=AE=E3=80=8D=E2=86=92=E3=80=8C?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E3=80=8D=EF=BC=8C=E5=81=9A=E6=88=90=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E4=B8=AD=E5=BF=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - tabBar 文字 ⚙️ 设置 → 💾 数据 - Header 收敛成 标题 + 一行统计 + 上次备份时间 - 删除「关于」「温馨提示」整块装饰内容 - 「数据管理」拆成「备份」+「危险操作」两组 - 导出成功后写入 lastBackupAt,进页面格式化展示 - 图标背景从冷色统一为纸感暖色 - 底部加版本号 v2.1.3 小字 Co-Authored-By: Claude Opus 4.7 (1M context) --- app.json | 2 +- pages/settings/settings.js | 62 ++++++++++---------- pages/settings/settings.wxml | 94 ++++++++---------------------- pages/settings/settings.wxss | 109 ++++++++++------------------------- 4 files changed, 85 insertions(+), 182 deletions(-) diff --git a/app.json b/app.json index 5bc5eef..17ee946 100644 --- a/app.json +++ b/app.json @@ -30,7 +30,7 @@ }, { "pagePath": "pages/settings/settings", - "text": "⚙️ 设置" + "text": "💾 数据" } ] }, diff --git a/pages/settings/settings.js b/pages/settings/settings.js index b7a581d..2398e24 100644 --- a/pages/settings/settings.js +++ b/pages/settings/settings.js @@ -1,50 +1,56 @@ // settings.js const storage = require('../../utils/storage') +const LAST_BACKUP_KEY = 'lastBackupAt' + +function formatRelativeTime(ts) { + if (!ts) return '从未备份' + const diff = Date.now() - ts + if (diff < 60 * 1000) return '刚刚' + if (diff < 60 * 60 * 1000) return Math.floor(diff / 60000) + ' 分钟前' + if (diff < 24 * 60 * 60 * 1000) return Math.floor(diff / 3600000) + ' 小时前' + if (diff < 30 * 24 * 60 * 60 * 1000) return Math.floor(diff / 86400000) + ' 天前' + const d = new Date(ts) + return (d.getMonth() + 1) + '月' + d.getDate() + '日' +} + Page({ data: { - dataCount: { - persons: 0, - anniversaries: 0 - } + personsCount: 0, + anniversariesCount: 0, + lastBackupText: '从未备份', + version: 'v2.1.3' }, onLoad() { - this.loadDataCount() + this.loadSummary() }, onShow() { - this.loadDataCount() + this.loadSummary() }, - /** - * 加载数据统计 - */ - loadDataCount() { + loadSummary() { const persons = storage.getPersons() const anniversaries = storage.getAnniversaries() - + const lastBackupAt = wx.getStorageSync(LAST_BACKUP_KEY) || 0 + this.setData({ - dataCount: { - persons: persons.length, - anniversaries: anniversaries.length - } + personsCount: persons.length, + anniversariesCount: anniversaries.length, + lastBackupText: formatRelativeTime(lastBackupAt) }) }, - /** - * 导出数据 - */ onExportData() { const data = storage.exportData() - - // 转换为JSON字符串 const jsonStr = JSON.stringify(data, null, 2) - - // 在小程序中,可以通过提示用户复制 + wx.setClipboardData({ data: jsonStr, success: () => { + wx.setStorageSync(LAST_BACKUP_KEY, Date.now()) + this.loadSummary() wx.showToast({ title: '数据已复制到剪贴板', icon: 'success' @@ -53,9 +59,6 @@ Page({ }) }, - /** - * 导入数据 - */ onImportData() { wx.showModal({ title: '导入数据', @@ -64,7 +67,6 @@ Page({ cancelText: '取消', success: (res) => { if (res.confirm) { - // 读取剪贴板 wx.getClipboardData({ success: (res) => { try { @@ -87,25 +89,20 @@ Page({ }) }, - /** - * 清空所有数据 - */ onClearData() { wx.showModal({ title: '确认清空', content: '确定要清空所有数据吗?此操作不可恢复!', confirmText: '确认清空', - confirmColor: '#ff5722', + confirmColor: '#C8412F', success: (res) => { if (res.confirm) { const success = storage.clearAllData() - if (success) { wx.showToast({ title: '已清空', icon: 'success' }) - setTimeout(() => { wx.reLaunch({ url: '/pages/index/index' @@ -117,4 +114,3 @@ Page({ }) } }) - diff --git a/pages/settings/settings.wxml b/pages/settings/settings.wxml index d1c3d1b..11679ea 100644 --- a/pages/settings/settings.wxml +++ b/pages/settings/settings.wxml @@ -5,37 +5,29 @@ - 设置 - 数据管理与关于 + 数据 + {{personsCount}} 位好友 · {{anniversariesCount}} 个纪念日 - ⚙️ + 💾 - - - - {{dataCount.persons}} - 位好友 - - - - {{dataCount.anniversaries}} - 个纪念日 - + + 上次备份 + {{lastBackupText}} - - + + - + 📤 - 导出数据 - 复制 JSON 到剪贴板 + 导出到剪贴板 + 复制 JSON,粘贴到备忘录或邮件保存 @@ -43,74 +35,34 @@ - + 📥 - 导入数据 - 从剪贴板读取并导入 + 从剪贴板恢复 + 读取剪贴板内容并覆盖本地数据 + - - + + + - - 🗑️ + + 🗑 清空所有数据 - 此操作不可恢复,请谨慎 + 此操作不可恢复,请先导出备份 - - - - - - 📱 - - - 版本号 - - v1.0.0 - - - - - - - 👨‍💻 - - - 开发作者 - - 生日提醒团队 - - - - - - - 💡 - 温馨提示 - - - · - 建议定期导出数据备份 - - - · - 农历转换使用寿星万年历算法(1900–2100) - - - · - 开启提醒需授权订阅消息 - + + {{version}} diff --git a/pages/settings/settings.wxss b/pages/settings/settings.wxss index 5b78e5b..a03aaab 100644 --- a/pages/settings/settings.wxss +++ b/pages/settings/settings.wxss @@ -1,5 +1,6 @@ /* settings.wxss - * 视觉方向:纸感编辑风(A 方案,与首页/日历一致) + * 视觉方向:纸感编辑风(A 方案,与全局一致) + * 定位:数据中心(备份 + 危险操作 + 版本号) */ page { @@ -23,7 +24,7 @@ page { display: flex; align-items: flex-start; justify-content: space-between; - margin-bottom: 28rpx; + margin-bottom: 20rpx; } .header-left { @@ -50,36 +51,24 @@ page { opacity: 0.85; } -.stats-row { +.header-meta { display: flex; - gap: 64rpx; - padding-top: 12rpx; + align-items: baseline; + gap: 12rpx; + padding-top: 20rpx; border-top: 1rpx solid #E8E2D5; - padding-top: 24rpx; - margin-top: 4rpx; } -.stat-item { - display: flex; - flex-direction: column; - gap: 4rpx; +.meta-label { + font-size: 22rpx; + color: #A9A096; + letter-spacing: 1rpx; } -.stat-num { - font-size: 44rpx; - font-weight: 600; - color: #1F1D2B; - line-height: 1; - letter-spacing: -1rpx; -} - -.stat-label { +.meta-value { font-size: 24rpx; - color: #8A8278; -} - -.stat-sep { - display: none; + color: #1F1D2B; + font-weight: 500; } /* ───── Body ───── */ @@ -98,6 +87,10 @@ page { text-transform: uppercase; } +.section-label.danger-label { + color: #C8412F; +} + /* ───── Card group ───── */ .card-group { background: #FFFFFF; @@ -123,6 +116,7 @@ page { width: 64rpx; height: 64rpx; border-radius: 14rpx; + background: #F2EEE5; display: flex; align-items: center; justify-content: center; @@ -130,6 +124,10 @@ page { margin-right: 20rpx; } +.row-icon-wrap.danger-icon-wrap { + background: #FFF1EA; +} + .row-icon { font-size: 32rpx; } @@ -139,6 +137,7 @@ page { display: flex; flex-direction: column; gap: 4rpx; + min-width: 0; } .row-title { @@ -170,66 +169,22 @@ page { color: #E29F92; } -.row-value { - font-size: 26rpx; - color: #8A8278; -} - .row-divider { height: 1rpx; background: #E8E2D5; margin-left: 112rpx; } -/* ───── Tips card ───── */ -/* 删原 border-left 6rpx 紫色条(禁项),改全边线 + 浅暖底标识 */ -.tips-card { - background: #FFF8EE; - border: 1rpx solid #EFD9B5; - border-radius: 14rpx; - margin: 12rpx 24rpx 0; - padding: 24rpx 28rpx 28rpx; +/* ───── Footer ───── */ +.footer { + text-align: center; + padding: 48rpx 0 16rpx; } -.tips-title { - display: flex; - align-items: center; - gap: 12rpx; - margin-bottom: 16rpx; -} - -.tips-icon { - font-size: 30rpx; -} - -.tips-heading { - font-size: 26rpx; - font-weight: 600; - color: #1F1D2B; -} - -.tips-item { - display: flex; - align-items: flex-start; - gap: 12rpx; - margin-bottom: 10rpx; -} - -.tips-item:last-child { - margin-bottom: 0; -} - -.tips-dot { - font-size: 26rpx; - color: #B36A1F; - line-height: 1.8; - flex-shrink: 0; -} - -.tips-text { - font-size: 24rpx; - color: #5A5247; - line-height: 1.7; +.footer-version { + font-size: 22rpx; + color: #C8C2B4; + letter-spacing: 2rpx; } /* ───── Bottom padding ───── */