diff --git a/miniapp/app.js b/miniapp/app.js
index fb65c9f..24fb1f2 100644
--- a/miniapp/app.js
+++ b/miniapp/app.js
@@ -2,7 +2,8 @@ App({
globalData: {
token: '',
user: null,
- apiUrl: 'http://localhost:8080'
+ apiUrl: 'http://localhost:8080',
+ themeMode: 'light',
},
onLaunch() {
const token = wx.getStorageSync('token')
@@ -13,5 +14,47 @@ App({
if (user) this.globalData.user = user
} catch(e) {}
}
- }
+ this.initTheme()
+ },
+ initTheme() {
+ const stored = wx.getStorageSync('inchstep-theme')
+ if (stored === 'light' || stored === 'dark') {
+ this.globalData.themeMode = stored
+ } else {
+ try {
+ const sysInfo = wx.getSystemInfoSync()
+ this.globalData.themeMode = sysInfo.theme === 'dark' ? 'dark' : 'light'
+ } catch(e) {}
+ }
+ this.applyTheme(this.globalData.themeMode)
+ },
+ applyTheme(mode) {
+ this.globalData.themeMode = mode
+ wx.setStorageSync('inchstep-theme', mode)
+ try {
+ wx.setNavigationBarColor({
+ frontColor: mode === 'dark' ? '#ffffff' : '#000000',
+ backgroundColor: mode === 'dark' ? '#1C1C1E' : '#F5F5F7',
+ })
+ wx.setTabBarStyle({
+ backgroundColor: mode === 'dark' ? '#1C1C1E' : '#F5F5F7',
+ borderStyle: mode === 'dark' ? 'black' : 'white',
+ })
+ } catch(e) {}
+ this.notifyPages(mode)
+ },
+ toggleTheme() {
+ const newMode = this.globalData.themeMode === 'light' ? 'dark' : 'light'
+ this.applyTheme(newMode)
+ },
+ notifyPages(mode) {
+ const pages = getCurrentPages()
+ pages.forEach(page => {
+ if (page.setData && typeof page.setThemeData === 'function') {
+ page.setThemeData(mode)
+ } else if (page.setData) {
+ page.setData({ themeMode: mode })
+ }
+ })
+ },
})
diff --git a/miniapp/app.wxss b/miniapp/app.wxss
index 96cf8a0..6e69207 100644
--- a/miniapp/app.wxss
+++ b/miniapp/app.wxss
@@ -1,6 +1,40 @@
-page { font-family: -apple-system, BlinkMacSystemFont, 'PingFang SC', sans-serif; background: #F5F5F7; color: #1D1D1F; }
-.card { background: white; border-radius: 12px; margin: 8px 16px; padding: 16px; box-shadow: 0 1px 3px rgba(0,0,0,0.04); }
-.btn-primary { width: 100%; padding: 14px; background: linear-gradient(135deg, #FF6B35, #FF4D6D); color: white; border: none; border-radius: 10px; font-size: 17px; font-weight: 600; text-align: center; }
-.input-field { width: 100%; padding: 14px 16px; background: #f8f8fa; border: 1px solid #E5E5EA; border-radius: 10px; font-size: 17px; }
+page {
+ font-family: -apple-system, BlinkMacSystemFont, 'PingFang SC', sans-serif;
+ --color-primary: #FF6B35;
+ --color-primary-light: #FF8C5A;
+ --color-primary-gradient: linear-gradient(135deg, #FF6B35, #FF4D6D);
+ --color-accent: #7209B7;
+ --color-bg: #F5F5F7;
+ --color-card: #FFFFFF;
+ --color-text: #1D1D1F;
+ --color-text-secondary: #86868B;
+ --color-border: #E5E5EA;
+ --color-nav-bg: rgba(245,245,247,0.95);
+ --color-success: #34C759;
+ --color-warning: #FF9500;
+ --color-error: #FF3B30;
+ --color-input-bg: #f8f8fa;
+ --color-active-bg: #FFF0EB;
+ --color-divider: #F0F0F0;
+ background: var(--color-bg);
+ color: var(--color-text);
+}
+page[data-theme="dark"] {
+ --color-bg: #1C1C1E;
+ --color-card: #2C2C2E;
+ --color-text: #F5F5F7;
+ --color-text-secondary: #98989D;
+ --color-border: #38383A;
+ --color-nav-bg: rgba(28,28,30,0.95);
+ --color-accent: #BB86FC;
+ --color-error: #FF453A;
+ --color-input-bg: #3A3A3C;
+ --color-active-bg: #3A3A3C;
+ --color-divider: #38383A;
+}
+
+.card { background: var(--color-card); border-radius: 12px; margin: 8px 16px; padding: 16px; box-shadow: 0 1px 3px rgba(0,0,0,0.04); }
+.btn-primary { width: 100%; padding: 14px; background: var(--color-primary-gradient); color: white; border: none; border-radius: 10px; font-size: 17px; font-weight: 600; text-align: center; }
+.input-field { width: 100%; padding: 14px 16px; background: var(--color-input-bg); border: 1px solid var(--color-border); border-radius: 10px; font-size: 17px; }
.page-title { font-size: 28px; font-weight: 600; padding: 20px 16px 8px; }
-.page-subtitle { font-size: 15px; color: #86868B; padding: 0 16px 20px; }
+.page-subtitle { font-size: 15px; color: var(--color-text-secondary); padding: 0 16px 20px; }
\ No newline at end of file
diff --git a/miniapp/components/checkin-card/index.wxss b/miniapp/components/checkin-card/index.wxss
index a75a73a..00ad5ab 100644
--- a/miniapp/components/checkin-card/index.wxss
+++ b/miniapp/components/checkin-card/index.wxss
@@ -1,7 +1,7 @@
.card {
display: flex;
align-items: center;
- background: white;
+ background: var(--color-card);
border-radius: 12px;
margin: 0 12px 8px;
padding: 14px;
@@ -12,7 +12,7 @@
.card-icon {
width: 44px; height: 44px;
border-radius: 12px;
- background: #FFF0EB;
+ background: var(--color-active-bg);
display: flex;
align-items: center;
justify-content: center;
@@ -20,7 +20,7 @@
margin-right: 14px;
}
.card-body { flex: 1; display: flex; flex-direction: column; gap: 2px; }
-.card-name { font-size: 16px; font-weight: 600; }
-.card-meta { font-size: 13px; color: #86868B; }
-.done-badge { font-size: 12px; color: #34C759; font-weight: 600; margin-top: 2px; }
-.card-streak { font-size: 14px; color: #FF6B35; font-weight: 600; }
\ No newline at end of file
+.card-name { font-size: 16px; font-weight: 600; color: var(--color-text); }
+.card-meta { font-size: 13px; color: var(--color-text-secondary); }
+.done-badge { font-size: 12px; color: var(--color-success); font-weight: 600; margin-top: 2px; }
+.card-streak { font-size: 14px; color: var(--color-primary); font-weight: 600; }
\ No newline at end of file
diff --git a/miniapp/components/nav-bar/index.js b/miniapp/components/nav-bar/index.js
index cb723a7..924cbbe 100644
--- a/miniapp/components/nav-bar/index.js
+++ b/miniapp/components/nav-bar/index.js
@@ -1,6 +1,9 @@
+const app = getApp()
+
Component({
properties: {
active: { type: String, value: 'home' },
+ themeMode: { type: String, value: 'light' },
tabs: {
type: Array,
value: [
@@ -10,6 +13,11 @@ Component({
],
},
},
+ lifetimes: {
+ attached() {
+ this.setData({ themeMode: app.globalData.themeMode })
+ },
+ },
methods: {
onSwitch(e) {
this.triggerEvent('switch', { key: e.currentTarget.dataset.key })
diff --git a/miniapp/components/nav-bar/index.wxml b/miniapp/components/nav-bar/index.wxml
index dd650cd..8e4fab2 100644
--- a/miniapp/components/nav-bar/index.wxml
+++ b/miniapp/components/nav-bar/index.wxml
@@ -1,4 +1,4 @@
-
+
{{item.icon}}
{{item.label}}
diff --git a/miniapp/components/nav-bar/index.wxss b/miniapp/components/nav-bar/index.wxss
index fc7c0eb..1701ab5 100644
--- a/miniapp/components/nav-bar/index.wxss
+++ b/miniapp/components/nav-bar/index.wxss
@@ -3,8 +3,8 @@
align-items: center;
justify-content: space-around;
padding: 8px 0 24px;
- border-top: 0.5px solid #E5E5EA;
- background: rgba(245,245,247,0.95);
+ border-top: 0.5px solid var(--color-border);
+ background: var(--color-nav-bg);
position: fixed;
bottom: 0;
left: 0;
@@ -20,5 +20,5 @@
padding: 4px;
}
.nav-icon { font-size: 22px; }
-.nav-label { font-size: 10px; color: #86868B; }
-.nav-label.active { color: #FF6B35; font-weight: 600; }
\ No newline at end of file
+.nav-label { font-size: 10px; color: var(--color-text-secondary); }
+.nav-label.active { color: var(--color-primary); font-weight: 600; }
\ No newline at end of file
diff --git a/miniapp/pages/checkin/create/index.js b/miniapp/pages/checkin/create/index.js
index cb565be..4e280c8 100644
--- a/miniapp/pages/checkin/create/index.js
+++ b/miniapp/pages/checkin/create/index.js
@@ -1,6 +1,10 @@
const api = require('../../../services/api')
+const app = getApp()
Page({
- data: { name: '', category: 'study', cycleType: 'daily', dailyGoal: '', privacy: 2, submitting: false },
+ data: { name: '', category: 'study', cycleType: 'daily', dailyGoal: '', privacy: 2, submitting: false, themeMode: 'light' },
+ onShow() {
+ this.setData({ themeMode: app.globalData.themeMode })
+ },
onNameInput(e) { this.setData({ name: e.detail.value }) },
onGoalInput(e) { this.setData({ dailyGoal: e.detail.value }) },
setCategory(e) { this.setData({ category: e.currentTarget.dataset.cat }) },
diff --git a/miniapp/pages/checkin/create/index.wxml b/miniapp/pages/checkin/create/index.wxml
index eaab741..c3844f7 100644
--- a/miniapp/pages/checkin/create/index.wxml
+++ b/miniapp/pages/checkin/create/index.wxml
@@ -1,4 +1,4 @@
-
+
名称 *
@@ -29,4 +29,4 @@
-
+
diff --git a/miniapp/pages/checkin/create/index.wxss b/miniapp/pages/checkin/create/index.wxss
index 48c87a5..07c1def 100644
--- a/miniapp/pages/checkin/create/index.wxss
+++ b/miniapp/pages/checkin/create/index.wxss
@@ -1,11 +1,11 @@
.form { padding: 16px; }
-.label { font-size: 13px; color: #86868B; margin-bottom: 6px; display: block; }
+.label { font-size: 13px; color: var(--color-text-secondary); margin-bottom: 6px; display: block; }
.category-grid { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 8px; }
-.cat-item { padding: 12px 8px; border-radius: 10px; border: 2px solid #E5E5EA; background: #f8f8fa; text-align: center; font-size: 14px; }
-.cat-item.active { border-color: #FF6B35; background: #FFF0EB; font-weight: 600; }
+.cat-item { padding: 12px 8px; border-radius: 10px; border: 2px solid var(--color-border); background: var(--color-input-bg); text-align: center; font-size: 14px; color: var(--color-text); }
+.cat-item.active { border-color: var(--color-primary); background: var(--color-active-bg); font-weight: 600; }
.cycle-row { display: flex; gap: 8px; }
-.cycle-item { padding: 8px 16px; border-radius: 8px; border: 1.5px solid #E5E5EA; background: #f8f8fa; font-size: 14px; }
-.cycle-item.active { border-color: #FF6B35; background: #FFF0EB; font-weight: 600; }
+.cycle-item { padding: 8px 16px; border-radius: 8px; border: 1.5px solid var(--color-border); background: var(--color-input-bg); font-size: 14px; color: var(--color-text); }
+.cycle-item.active { border-color: var(--color-primary); background: var(--color-active-bg); font-weight: 600; }
.privacy-row { display: flex; gap: 8px; }
-.privacy-item { padding: 8px 16px; border-radius: 8px; border: 1.5px solid #E5E5EA; background: #f8f8fa; font-size: 14px; }
-.privacy-item.active { border-color: #FF6B35; background: #FFF0EB; font-weight: 600; }
+.privacy-item { padding: 8px 16px; border-radius: 8px; border: 1.5px solid var(--color-border); background: var(--color-input-bg); font-size: 14px; color: var(--color-text); }
+.privacy-item.active { border-color: var(--color-primary); background: var(--color-active-bg); font-weight: 600; }
\ No newline at end of file
diff --git a/miniapp/pages/checkin/detail/index.js b/miniapp/pages/checkin/detail/index.js
index 25979da..39b2da3 100644
--- a/miniapp/pages/checkin/detail/index.js
+++ b/miniapp/pages/checkin/detail/index.js
@@ -1,6 +1,10 @@
const api = require('../../../services/api')
+const app = getApp()
Page({
- data: { item: null, streak: 0, records: [], year: 0, month: 0, days: [], loading: true, showActions: false },
+ data: { item: null, streak: 0, records: [], year: 0, month: 0, days: [], loading: true, showActions: false, themeMode: 'light' },
+ onShow() {
+ this.setData({ themeMode: app.globalData.themeMode })
+ },
onLoad(options) {
const now = new Date()
this.setData({ id: options.id, year: now.getFullYear(), month: now.getMonth() + 1 })
diff --git a/miniapp/pages/checkin/detail/index.wxml b/miniapp/pages/checkin/detail/index.wxml
index 0ce2f5b..5ae57a2 100644
--- a/miniapp/pages/checkin/detail/index.wxml
+++ b/miniapp/pages/checkin/detail/index.wxml
@@ -1,5 +1,5 @@
加载中...
-
+
⋯
-
+
diff --git a/miniapp/pages/checkin/detail/index.wxss b/miniapp/pages/checkin/detail/index.wxss
index 262acc9..5334c10 100644
--- a/miniapp/pages/checkin/detail/index.wxss
+++ b/miniapp/pages/checkin/detail/index.wxss
@@ -1,24 +1,24 @@
-.loading { text-align: center; padding: 40px; color: #86868B; }
-.card { background: white; border-radius: 12px; margin: 8px 16px; padding: 16px; box-shadow: 0 1px 3px rgba(0,0,0,0.04); }
+.loading { text-align: center; padding: 40px; color: var(--color-text-secondary); }
+.card { background: var(--color-card); border-radius: 12px; margin: 8px 16px; padding: 16px; box-shadow: 0 1px 3px rgba(0,0,0,0.04); }
.action-btn { position: absolute; right: 16px; top: 12px; font-size: 20px; padding: 4px 8px; z-index: 10; }
-.action-menu { position: absolute; right: 16px; top: 44px; background: white; border-radius: 12px; box-shadow: 0 4px 12px rgba(0,0,0,0.1); z-index: 10; min-width: 120px; }
-.action-item { padding: 12px 16px; font-size: 14px; border-bottom: 0.5px solid #E5E5EA; }
+.action-menu { position: absolute; right: 16px; top: 44px; background: var(--color-card); border-radius: 12px; box-shadow: 0 4px 12px rgba(0,0,0,0.1); z-index: 10; min-width: 120px; }
+.action-item { padding: 12px 16px; font-size: 14px; border-bottom: 0.5px solid var(--color-border); }
.action-item:last-child { border-bottom: none; }
.item-header { display: flex; align-items: center; gap: 12px; }
-.item-icon { width: 52px; height: 52px; border-radius: 14px; background: #FFF0EB; display: flex; align-items: center; justify-content: center; font-size: 26px; }
-.item-name { font-size: 18px; font-weight: 700; display: block; }
-.item-meta { font-size: 13px; color: #86868B; display: block; margin-top: 2px; }
-.item-goal { font-size: 13px; color: #86868B; display: block; margin-top: 2px; }
-.stats-row { display: flex; justify-content: space-around; background: white; border-radius: 12px; margin: 8px 16px; padding: 16px; box-shadow: 0 1px 3px rgba(0,0,0,0.04); }
+.item-icon { width: 52px; height: 52px; border-radius: 14px; background: var(--color-active-bg); display: flex; align-items: center; justify-content: center; font-size: 26px; }
+.item-name { font-size: 18px; font-weight: 700; display: block; color: var(--color-text); }
+.item-meta { font-size: 13px; color: var(--color-text-secondary); display: block; margin-top: 2px; }
+.item-goal { font-size: 13px; color: var(--color-text-secondary); display: block; margin-top: 2px; }
+.stats-row { display: flex; justify-content: space-around; background: var(--color-card); border-radius: 12px; margin: 8px 16px; padding: 16px; box-shadow: 0 1px 3px rgba(0,0,0,0.04); }
.stat { text-align: center; }
-.stat-num { font-size: 28px; font-weight: 700; color: #FF6B35; display: block; }
-.stat-lbl { font-size: 13px; color: #86868B; }
+.stat-num { font-size: 28px; font-weight: 700; color: var(--color-primary); display: block; }
+.stat-lbl { font-size: 13px; color: var(--color-text-secondary); }
.calendar { padding: 16px; }
-.cal-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px; font-size: 16px; font-weight: 600; }
+.cal-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px; font-size: 16px; font-weight: 600; color: var(--color-text); }
.cal-nav { font-size: 18px; padding: 4px 8px; }
.cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 4px; text-align: center; }
-.cal-weekday { font-size: 12px; color: #86868B; padding: 6px 0; }
-.cal-day { padding: 8px 0; font-size: 14px; border-radius: 8px; position: relative; }
+.cal-weekday { font-size: 12px; color: var(--color-text-secondary); padding: 6px 0; }
+.cal-day { padding: 8px 0; font-size: 14px; border-radius: 8px; position: relative; color: var(--color-text); }
.cal-day.checked { font-weight: 600; }
-.cal-day.today { background: #FFF0EB; }
-.cal-dot { width: 6px; height: 6px; border-radius: 3px; background: #34C759; margin: 2px auto 0; }
+.cal-day.today { background: var(--color-active-bg); }
+.cal-dot { width: 6px; height: 6px; border-radius: 3px; background: var(--color-success); margin: 2px auto 0; }
\ No newline at end of file
diff --git a/miniapp/pages/index/index.js b/miniapp/pages/index/index.js
index a4a8309..ea9b667 100644
--- a/miniapp/pages/index/index.js
+++ b/miniapp/pages/index/index.js
@@ -2,10 +2,10 @@ const api = require('../../services/api')
const app = getApp()
Page({
- data: { user: null, items: [], streaks: {}, loading: true },
+ data: { user: null, items: [], streaks: {}, loading: true, themeMode: 'light' },
onShow() {
if (!app.globalData.token) { wx.reLaunch({ url: '/pages/login/index' }); return }
- this.setData({ user: app.globalData.user })
+ this.setData({ user: app.globalData.user, themeMode: app.globalData.themeMode })
this.loadItems()
},
onPullDownRefresh() { this.loadItems().then(() => wx.stopPullDownRefresh()) },
diff --git a/miniapp/pages/index/index.wxml b/miniapp/pages/index/index.wxml
index 0a5e95d..5bdbe00 100644
--- a/miniapp/pages/index/index.wxml
+++ b/miniapp/pages/index/index.wxml
@@ -1,31 +1,32 @@
-