diff --git a/achievements/achievements.js b/achievements/achievements.js
index d4c63a4..93e7845 100644
--- a/achievements/achievements.js
+++ b/achievements/achievements.js
@@ -137,7 +137,7 @@ Page({
this.setData({ loading: true, error: '' })
wx.request({
url: `${app.globalData.baseUrl}/api/v1/achievements`,
- header: { 'X-OpenID': app.globalData.openid || '' },
+ header: { 'X-Auth-Token': app.globalData.authToken || '' },
success: (res) => {
const list = this.decorateList(res.data?.data || [])
const sections = this.buildSections(list)
@@ -156,7 +156,7 @@ Page({
wx.request({
url: `${app.globalData.baseUrl}/api/v1/achievements/refresh`,
method: 'POST',
- header: { 'X-OpenID': app.globalData.openid || '' },
+ header: { 'X-Auth-Token': app.globalData.authToken || '' },
success: (res) => {
const payload = res.data?.data || {}
const list = this.decorateList(payload.achievements || [])
diff --git a/batch-upload/batch-upload.js b/batch-upload/batch-upload.js
index 9702b18..c24c3d0 100644
--- a/batch-upload/batch-upload.js
+++ b/batch-upload/batch-upload.js
@@ -36,7 +36,7 @@ Page({
url: `${app.globalData.baseUrl}/api/v1/entries/upload-file`,
filePath: file.path,
name: 'file',
- header: { 'X-OpenID': app.globalData.openid || '' },
+ header: { 'X-Auth-Token': app.globalData.authToken || '' },
success: (uploadRes) => {
try {
const payload = JSON.parse(uploadRes.data)
diff --git a/checkin-detail/checkin-detail.js b/checkin-detail/checkin-detail.js
index 64fefe5..ebf6e22 100644
--- a/checkin-detail/checkin-detail.js
+++ b/checkin-detail/checkin-detail.js
@@ -13,7 +13,7 @@ Page({
this.setData({ loading: true, error: '' })
wx.request({
url: `${app.globalData.baseUrl}/api/v1/checkin/stats`,
- header: { 'X-OpenID': app.globalData.openid || '' },
+ header: { 'X-Auth-Token': app.globalData.authToken || '' },
success: (res) => this.setData({ stats: res.data?.data || null }),
fail: () => this.setData({ error: '打卡数据加载失败' }),
complete: () => this.setData({ loading: false }),
diff --git a/entry-detail/entry-detail.js b/entry-detail/entry-detail.js
index 704d528..550b214 100644
--- a/entry-detail/entry-detail.js
+++ b/entry-detail/entry-detail.js
@@ -11,7 +11,7 @@ Page({
this.loadEntry()
},
loadEntry() {
- if (!app.globalData.openid) {
+ if (!app.globalData.authToken) {
this.setData({ error: '请先登录' })
return
}
@@ -22,7 +22,7 @@ Page({
this.setData({ loading: true, error: '' })
wx.request({
url: `${app.globalData.baseUrl}/api/v1/entries/${this.entryId}`,
- header: { 'X-OpenID': app.globalData.openid },
+ header: { 'X-Auth-Token': app.globalData.authToken },
success: (res) => {
const entry = res.data?.data || null
this.setData({ entry, error: entry ? '' : '未找到词条' })
@@ -45,7 +45,7 @@ Page({
wx.request({
url: `${app.globalData.baseUrl}/api/v1/entries/${this.data.entry.id}`,
method: 'DELETE',
- header: { 'X-OpenID': app.globalData.openid },
+ header: { 'X-Auth-Token': app.globalData.authToken },
success: () => {
wx.showToast({ title: '已删除', icon: 'success' })
const pages = getCurrentPages()
diff --git a/entry-edit/entry-edit.js b/entry-edit/entry-edit.js
index 6b9f5d5..a0331f1 100644
--- a/entry-edit/entry-edit.js
+++ b/entry-edit/entry-edit.js
@@ -17,14 +17,14 @@ Page({
if (entryId) this.loadEntry(entryId)
},
loadEntry(entryId) {
- if (!app.globalData.openid) {
+ if (!app.globalData.authToken) {
this.setData({ error: '请先登录' })
return
}
this.setData({ loading: true, error: '' })
wx.request({
url: `${app.globalData.baseUrl}/api/v1/entries/${entryId}`,
- header: { 'X-OpenID': app.globalData.openid },
+ header: { 'X-Auth-Token': app.globalData.authToken },
success: (res) => {
const entry = res.data?.data
if (!entry) {
@@ -71,7 +71,7 @@ Page({
wx.navigateBack()
},
save() {
- if (!app.globalData.openid) {
+ if (!app.globalData.authToken) {
wx.showToast({ title: '请先登录', icon: 'none' })
return
}
@@ -83,7 +83,7 @@ Page({
wx.request({
url,
method,
- header: { 'Content-Type': 'application/json', 'X-OpenID': app.globalData.openid },
+ header: { 'Content-Type': 'application/json', 'X-Auth-Token': app.globalData.authToken },
data: this.data.isEditMode
? {
entry_type: this.data.entryType,
diff --git a/index/index.js b/index/index.js
index 8cae738..9bc753d 100644
--- a/index/index.js
+++ b/index/index.js
@@ -12,13 +12,13 @@ Page({
async loadStats() {
this.setData({ loading: true, error: '' })
await app.ensureLogin()
- if (!app.globalData.openid) {
+ if (!app.globalData.authToken) {
this.setData({ error: '登录失败,请稍后重试', loading: false })
return
}
wx.request({
url: `${app.globalData.baseUrl}/api/v1/home/stats`,
- header: { 'X-OpenID': app.globalData.openid },
+ header: { 'X-Auth-Token': app.globalData.authToken },
success: (res) => {
const payload = res.data?.data
if (payload) this.setData({ stats: payload })
diff --git a/manage/batch-upload/batch-upload.js b/manage/batch-upload/batch-upload.js
index 9702b18..c24c3d0 100644
--- a/manage/batch-upload/batch-upload.js
+++ b/manage/batch-upload/batch-upload.js
@@ -36,7 +36,7 @@ Page({
url: `${app.globalData.baseUrl}/api/v1/entries/upload-file`,
filePath: file.path,
name: 'file',
- header: { 'X-OpenID': app.globalData.openid || '' },
+ header: { 'X-Auth-Token': app.globalData.authToken || '' },
success: (uploadRes) => {
try {
const payload = JSON.parse(uploadRes.data)
diff --git a/manage/entry-detail/entry-detail.js b/manage/entry-detail/entry-detail.js
index 942cb41..97c2901 100644
--- a/manage/entry-detail/entry-detail.js
+++ b/manage/entry-detail/entry-detail.js
@@ -11,7 +11,7 @@ Page({
this.loadEntry()
},
loadEntry() {
- if (!app.globalData.openid) {
+ if (!app.globalData.authToken) {
this.setData({ error: '????' })
return
}
@@ -22,7 +22,7 @@ Page({
this.setData({ loading: true, error: '' })
wx.request({
url: `${app.globalData.baseUrl}/api/v1/entries/${this.entryId}`,
- header: { 'X-OpenID': app.globalData.openid },
+ header: { 'X-Auth-Token': app.globalData.authToken },
success: (res) => {
const entry = res.data?.data || null
this.setData({ entry, error: entry ? '' : '?????' })
@@ -45,7 +45,7 @@ Page({
wx.request({
url: `${app.globalData.baseUrl}/api/v1/entries/${this.data.entry.id}`,
method: 'DELETE',
- header: { 'X-OpenID': app.globalData.openid },
+ header: { 'X-Auth-Token': app.globalData.authToken },
success: () => {
wx.showToast({ title: '???', icon: 'success' })
const pages = getCurrentPages()
diff --git a/manage/entry-edit/entry-edit.js b/manage/entry-edit/entry-edit.js
index 6b9f5d5..a0331f1 100644
--- a/manage/entry-edit/entry-edit.js
+++ b/manage/entry-edit/entry-edit.js
@@ -17,14 +17,14 @@ Page({
if (entryId) this.loadEntry(entryId)
},
loadEntry(entryId) {
- if (!app.globalData.openid) {
+ if (!app.globalData.authToken) {
this.setData({ error: '请先登录' })
return
}
this.setData({ loading: true, error: '' })
wx.request({
url: `${app.globalData.baseUrl}/api/v1/entries/${entryId}`,
- header: { 'X-OpenID': app.globalData.openid },
+ header: { 'X-Auth-Token': app.globalData.authToken },
success: (res) => {
const entry = res.data?.data
if (!entry) {
@@ -71,7 +71,7 @@ Page({
wx.navigateBack()
},
save() {
- if (!app.globalData.openid) {
+ if (!app.globalData.authToken) {
wx.showToast({ title: '请先登录', icon: 'none' })
return
}
@@ -83,7 +83,7 @@ Page({
wx.request({
url,
method,
- header: { 'Content-Type': 'application/json', 'X-OpenID': app.globalData.openid },
+ header: { 'Content-Type': 'application/json', 'X-Auth-Token': app.globalData.authToken },
data: this.data.isEditMode
? {
entry_type: this.data.entryType,
diff --git a/me/file_content_needed.py b/me/file_content_needed.py
new file mode 100644
index 0000000..d3109e1
--- /dev/null
+++ b/me/file_content_needed.py
@@ -0,0 +1,20 @@
+from sqlalchemy import BigInteger, Column, DateTime, String, func
+from sqlalchemy.orm import relationship
+
+from app.db.session import Base
+
+
+class User(Base):
+ __tablename__ = "users"
+
+ id = Column(BigInteger, primary_key=True, autoincrement=True)
+ openid = Column(String(64), nullable=False, unique=True, index=True)
+ username = Column(String(64), nullable=True, unique=True, index=True)
+ password = Column(String(128), nullable=True)
+ login_type = Column(String(20), nullable=False, default="wechat")
+ nickname = Column(String(100), nullable=True)
+ avatar_url = Column(String(255), nullable=True)
+ created_at = Column(DateTime, nullable=False, server_default=func.now())
+ updated_at = Column(DateTime, nullable=False, server_default=func.now(), onupdate=func.now())
+
+ entries = relationship("Entry", back_populates="user")
diff --git a/me/me.js b/me/me.js
index 565ea0c..770a089 100644
--- a/me/me.js
+++ b/me/me.js
@@ -7,10 +7,10 @@ function normalizeAvatarUrl(avatarUrl, baseUrl) {
function requestFailHint(errMsg) {
const m = String(errMsg || '').toLowerCase()
- if (m.includes('domain') || m.includes('合法域名')) return '域名未在公众平台配置,或未开启 HTTPS'
- if (m.includes('ssl') || m.includes('certificate')) return 'HTTPS 证书异常,请检查服务器证书'
+ if (m.includes('domain')) return '域名未配置或未开启 HTTPS'
+ if (m.includes('ssl') || m.includes('certificate')) return 'HTTPS 证书异常,请检查服务端配置'
if (m.includes('timeout') || m.includes('timed out')) return '连接超时,请稍后重试'
- return '网络异常,请检查网络后重试'
+ return '网络异常,请稍后重试'
}
const DEFAULT_AVATAR = 'data:image/svg+xml;utf8,' + encodeURIComponent(`
@@ -32,91 +32,148 @@ Page({
data: {
name: '',
nickname: '',
+ username: '',
days: 0,
badges: 0,
- openid: '',
avatarUrl: '',
defaultAvatarUrl: DEFAULT_AVATAR,
loading: false,
error: '',
showNicknameModal: false,
nicknameDraft: '',
+ authMode: 'login',
+ authForm: {
+ username: '',
+ password: '',
+ nickname: '',
+ },
},
onShow() {
this.loadProfile()
},
- async loadProfile() {
- const openid = app.globalData.openid || wx.getStorageSync('openid') || ''
- if (!openid) {
- this.setData({
- loading: false,
- openid: '',
- name: '未登录',
- nickname: '未登录',
- avatarUrl: '',
- nicknameDraft: '',
- badges: 0,
- days: 0,
- error: '',
- })
+ isLoggedIn() {
+ return !!app.globalData.authToken
+ },
+ onAuthModeChange(e) {
+ this.setData({ authMode: e.currentTarget.dataset.mode || 'login', error: '' })
+ },
+ onAuthInput(e) {
+ const { field } = e.currentTarget.dataset
+ const value = e.detail.value || ''
+ this.setData({ [`authForm.${field}`]: value })
+ },
+ submitAuth() {
+ const baseUrl = app.getApiBaseUrl ? app.getApiBaseUrl() : app.globalData.baseUrl
+ const mode = this.data.authMode
+ const username = (this.data.authForm.username || '').trim()
+ const password = (this.data.authForm.password || '').trim()
+ const nickname = (this.data.authForm.nickname || '').trim()
+
+ if (!username || !password) {
+ wx.showToast({ title: '请输入账号和密码', icon: 'none' })
return
}
+
+ if (mode === 'register' && !nickname) {
+ wx.showToast({ title: '请输入昵称', icon: 'none' })
+ return
+ }
+
this.setData({ loading: true, error: '' })
- app.globalData.openid = openid
- const baseUrl = app.getApiBaseUrl ? app.getApiBaseUrl() : app.globalData.baseUrl
- let profileErrMsg = ''
wx.request({
- url: `${baseUrl}/api/v1/auth/profile?openid=${encodeURIComponent(openid)}`,
- method: 'GET',
+ url: `${baseUrl}/api/v1/auth/${mode === 'register' ? 'register' : 'login'}`,
+ method: 'POST',
+ header: { 'Content-Type': 'application/json' },
+ data: mode === 'register' ? { username, password, nickname } : { username, password },
success: (res) => {
- const body = res.data || {}
- const ok = res.statusCode >= 200 && res.statusCode < 300 && body.code === 0 && body.data
- if (!ok) {
- profileErrMsg = '个人信息加载失败,请稍后重试'
- const storedAvatarUrl = wx.getStorageSync(`avatarUrl:${openid}`) || ''
- const normalizedAvatar = normalizeAvatarUrl(storedAvatarUrl, baseUrl)
- this.setData({
- openid,
- name: '考研战士',
- nickname: '考研战士',
- avatarUrl: normalizedAvatar,
- nicknameDraft: '考研战士',
- error: profileErrMsg,
- })
+ const payload = res.data?.data || null
+ if (res.statusCode < 200 || res.statusCode >= 300 || !payload?.auth_token) {
+ const message = res.data?.detail || res.data?.message || `${mode === 'register' ? '注册' : '登录'}失败`
+ this.setData({ error: message })
+ wx.showToast({ title: message, icon: 'none' })
return
}
- const profile = body.data
- const avatarUrl = wx.getStorageSync(`avatarUrl:${openid}`) || profile.avatar_url || ''
- const nickname = profile.nickname || '考研战士'
- const normalizedAvatar = normalizeAvatarUrl(avatarUrl, baseUrl)
- profileErrMsg = ''
+
+ app.setLoginSession(payload)
this.setData({
- openid,
- name: nickname,
- nickname,
- avatarUrl: normalizedAvatar,
- nicknameDraft: nickname,
- days: Number(profile.days || 0),
+ authForm: { username: '', password: '', nickname: '' },
+ username: payload.username || '',
+ })
+ wx.showToast({ title: mode === 'register' ? '注册成功' : '登录成功', icon: 'success' })
+ this.loadProfile()
+ },
+ fail: (err) => {
+ const message = requestFailHint(err.errMsg)
+ this.setData({ error: message })
+ wx.showToast({ title: message, icon: 'none' })
+ },
+ complete: () => this.setData({ loading: false }),
+ })
+ },
+ loadProfile() {
+ const token = app.ensureLogin()
+ Promise.resolve(token).then((authToken) => {
+ if (!authToken) {
+ this.setData({
+ loading: false,
+ name: '未登录',
+ nickname: '未登录',
+ username: '',
+ avatarUrl: '',
+ nicknameDraft: '',
+ badges: 0,
+ days: 0,
error: '',
})
- },
- fail: () => {
- profileErrMsg = '个人信息加载失败,请稍后重试'
- const storedAvatarUrl = wx.getStorageSync(`avatarUrl:${openid}`) || ''
- const normalizedAvatar = normalizeAvatarUrl(storedAvatarUrl, baseUrl)
- this.setData({
- openid,
- name: '考研战士',
- nickname: '考研战士',
- avatarUrl: normalizedAvatar,
- nicknameDraft: '考研战士',
- error: profileErrMsg,
- })
- },
- complete: () => {
- this.loadAchievements(profileErrMsg)
- this.setData({ loading: false })
- },
+ return
+ }
+
+ this.setData({ loading: true, error: '' })
+ const baseUrl = app.getApiBaseUrl ? app.getApiBaseUrl() : app.globalData.baseUrl
+ wx.request({
+ url: `${baseUrl}/api/v1/auth/profile`,
+ method: 'GET',
+ header: app.getAuthHeader(),
+ success: (res) => {
+ const body = res.data || {}
+ const profile = body.data
+ const ok = res.statusCode >= 200 && res.statusCode < 300 && body.code === 0 && profile
+ if (!ok) {
+ const message = body.detail || body.message || '个人信息加载失败'
+ this.setData({ error: message })
+ return
+ }
+
+ const identity = profile.username || app.globalData.currentUser?.username || ''
+ const avatarUrl = wx.getStorageSync(`avatarUrl:${identity}`) || profile.avatar_url || ''
+ const normalizedAvatar = normalizeAvatarUrl(avatarUrl, baseUrl)
+ const nickname = profile.nickname || identity || '考研战士'
+
+ app.globalData.currentUser = {
+ ...(app.globalData.currentUser || {}),
+ id: profile.id,
+ username: profile.username || '',
+ nickname,
+ loginType: profile.login_type || 'account',
+ }
+ wx.setStorageSync('currentUser', app.globalData.currentUser)
+
+ this.setData({
+ name: nickname,
+ nickname,
+ username: profile.username || '',
+ avatarUrl: normalizedAvatar,
+ nicknameDraft: nickname,
+ days: Number(profile.days || 0),
+ error: '',
+ })
+ this.loadAchievements()
+ },
+ fail: (err) => {
+ this.setData({ error: requestFailHint(err.errMsg) })
+ },
+ complete: () => this.setData({ loading: false }),
+ })
})
},
openNicknameModal() {
@@ -132,7 +189,7 @@ Page({
this.setData({ nicknameDraft: e.detail.value })
},
saveNickname() {
- if (!app.globalData.openid) return
+ if (!this.isLoggedIn()) return
const nickname = (this.data.nicknameDraft || '').trim()
if (!nickname) {
wx.showToast({ title: '请输入昵称', icon: 'none' })
@@ -141,11 +198,14 @@ Page({
wx.request({
url: `${app.getApiBaseUrl ? app.getApiBaseUrl() : app.globalData.baseUrl}/api/v1/auth/profile`,
method: 'PUT',
- header: { 'Content-Type': 'application/json' },
- data: { openid: app.globalData.openid, nickname },
+ header: app.getAuthHeader({ 'Content-Type': 'application/json' }),
+ data: { nickname },
success: (res) => {
const profile = res.data?.data || {}
const nextNickname = profile.nickname || nickname
+ const currentUser = { ...(app.globalData.currentUser || {}), nickname: nextNickname }
+ app.globalData.currentUser = currentUser
+ wx.setStorageSync('currentUser', currentUser)
this.setData({ nickname: nextNickname, name: nextNickname, nicknameDraft: nextNickname, showNicknameModal: false })
wx.showToast({ title: '保存成功', icon: 'success' })
},
@@ -154,7 +214,7 @@ Page({
},
onChooseAvatar(e) {
const tempPath = e.detail?.avatarUrl || ''
- if (!app.globalData.openid) {
+ if (!this.isLoggedIn()) {
wx.showToast({ title: '请先登录', icon: 'none' })
return
}
@@ -164,24 +224,22 @@ Page({
}
const baseUrl = app.getApiBaseUrl ? app.getApiBaseUrl() : app.globalData.baseUrl
wx.uploadFile({
- url: `${baseUrl}/api/v1/auth/avatar?openid=${encodeURIComponent(app.globalData.openid)}`,
+ url: `${baseUrl}/api/v1/auth/avatar`,
filePath: tempPath,
name: 'file',
+ header: app.getAuthHeader(),
success: (uploadRes) => {
try {
const payload = JSON.parse(uploadRes.data || '{}')
- const ok =
- uploadRes.statusCode >= 200 &&
- uploadRes.statusCode < 300 &&
- payload.code === 0 &&
- payload.data
+ const ok = uploadRes.statusCode >= 200 && uploadRes.statusCode < 300 && payload.code === 0 && payload.data
if (!ok) {
wx.showToast({ title: payload.message || '头像上传失败', icon: 'none' })
return
}
const rel = payload.data.avatar_url || ''
const full = normalizeAvatarUrl(rel, baseUrl)
- wx.setStorageSync(`avatarUrl:${app.globalData.openid}`, full)
+ const key = this.data.username || app.globalData.currentUser?.username || ''
+ if (key) wx.setStorageSync(`avatarUrl:${key}`, full)
this.setData({ avatarUrl: full })
wx.showToast({ title: '头像已更新', icon: 'success' })
} catch {
@@ -191,77 +249,46 @@ Page({
fail: (err) => wx.showToast({ title: requestFailHint(err.errMsg), icon: 'none' }),
})
},
- loadAchievements(profileErrMsg) {
- if (!app.globalData.openid) {
- this.setData({ error: '登录状态已失效,请重新进入页面' })
- return
- }
+ loadAchievements() {
+ if (!this.isLoggedIn()) return
const baseUrl = app.getApiBaseUrl ? app.getApiBaseUrl() : app.globalData.baseUrl
- const achFail = '成就数据加载失败,请稍后重试'
wx.request({
url: `${baseUrl}/api/v1/achievements`,
- header: { 'X-OpenID': app.globalData.openid },
+ header: app.getAuthHeader(),
success: (res) => {
const body = res.data || {}
const ok = res.statusCode >= 200 && res.statusCode < 300 && body.code === 0 && Array.isArray(body.data)
- if (!ok) {
- this.setData({ error: profileErrMsg ? `${profileErrMsg};${achFail}` : achFail })
- return
- }
- const list = body.data
- const badges = list.filter((i) => i.is_unlocked).length
- this.setData({ badges, error: profileErrMsg || '' })
- },
- fail: (err) => {
- const netHint = requestFailHint(err.errMsg)
- const line = profileErrMsg ? `${profileErrMsg};${achFail}` : achFail
- this.setData({ error: `${line}(${netHint})` })
+ if (!ok) return
+ const badges = body.data.filter((i) => i.is_unlocked).length
+ this.setData({ badges })
},
})
},
- manualLogin() {
- wx.login({
- success: (res) => {
- const code = res.code || ''
- console.log('[login] wx.login success', res)
- console.log('[login] code', code)
- if (!code) {
- wx.showToast({ title: '登录失败,请重试', icon: 'none' })
- return
- }
- wx.request({
- url: `${app.getApiBaseUrl ? app.getApiBaseUrl() : app.globalData.baseUrl}/api/v1/auth/wx-login`,
- method: 'POST',
- header: { 'Content-Type': 'application/json' },
- data: { code },
- success: (loginRes) => {
- console.log('[login] wx-login success', loginRes)
- const payload = loginRes.data?.data || {}
- if (loginRes.statusCode >= 200 && loginRes.statusCode < 300 && loginRes.data?.code === 0 && payload.openid) {
- app.globalData.openid = payload.openid
- wx.setStorageSync('openid', payload.openid)
- wx.showToast({ title: '登录成功', icon: 'success' })
- this.loadProfile()
- return
- }
- console.log('[login] wx-login invalid response', loginRes.data)
- wx.showToast({ title: '登录接口异常,请稍后重试', icon: 'none' })
- },
- fail: (err) => {
- console.log('[login] wx-login fail', err)
- wx.showToast({ title: requestFailHint(err.errMsg), icon: 'none' })
- },
+ logout() {
+ if (!this.isLoggedIn()) return
+ wx.request({
+ url: `${app.getApiBaseUrl ? app.getApiBaseUrl() : app.globalData.baseUrl}/api/v1/auth/logout`,
+ method: 'POST',
+ header: app.getAuthHeader(),
+ complete: () => {
+ app.clearLoginSession()
+ this.setData({
+ name: '未登录',
+ nickname: '未登录',
+ username: '',
+ avatarUrl: '',
+ nicknameDraft: '',
+ badges: 0,
+ days: 0,
+ error: '',
})
- },
- fail: (err) => {
- console.log('[login] wx.login fail', err)
- wx.showToast({ title: '登录失败,请重试', icon: 'none' })
+ wx.showToast({ title: '已退出登录', icon: 'success' })
},
})
},
goTo(e) {
const { url } = e.currentTarget.dataset
- if (!app.globalData.openid) {
+ if (!this.isLoggedIn()) {
wx.showToast({ title: '请先登录', icon: 'none' })
return
}
diff --git a/me/me.wxml b/me/me.wxml
index 54209fc..69cce1a 100644
--- a/me/me.wxml
+++ b/me/me.wxml
@@ -6,10 +6,19 @@
正在获取个人信息
-
- 还未登录
- 请点击下方按钮手动登录后继续使用
-
+
+ 账号登录
+ 使用账号密码登录,或先注册一个新账号
+
+ 登录
+ 注册
+
+
+
+
+
+
+
@@ -35,12 +44,12 @@
-
+
还没有解锁成就
继续复习和打卡,成就会逐渐点亮
-
+
🏅
@@ -85,6 +94,8 @@
设置中心
›
+
+
@@ -106,4 +117,4 @@
↻复习
☺我的
-
\ No newline at end of file
+
diff --git a/me/me.wxss b/me/me.wxss
index ed2acd7..ae884d9 100644
--- a/me/me.wxss
+++ b/me/me.wxss
@@ -79,6 +79,62 @@ page {
min-width: 200rpx
}
+.auth-switch {
+ display: flex;
+ gap: 20rpx;
+ margin: 32rpx 0 24rpx
+}
+
+.auth-chip {
+ min-width: 160rpx;
+ padding: 18rpx 0;
+ border-radius: 9999rpx;
+ background: rgba(255, 255, 255, .05);
+ border: 1rpx solid rgba(255, 255, 255, .08);
+ font-size: 24rpx;
+ font-weight: 700;
+ color: #aaabb0
+}
+
+.auth-chip.active {
+ color: #0c0e12;
+ background: linear-gradient(135deg, #00e3fd, #c19cff)
+}
+
+.auth-card {
+ width: 100%;
+ padding: 28rpx;
+ border-radius: 28rpx;
+ border: 1rpx solid rgba(255, 255, 255, .08);
+ background: rgba(23, 26, 31, .72);
+ box-sizing: border-box
+}
+
+.auth-input {
+ width: 100%;
+ height: 84rpx;
+ margin-bottom: 18rpx;
+ padding: 0 24rpx;
+ border-radius: 18rpx;
+ border: 1rpx solid rgba(255, 255, 255, .08);
+ background: #111318;
+ color: #f6f6fc;
+ font-size: 26rpx;
+ box-sizing: border-box
+}
+
+.auth-submit {
+ margin-top: 12rpx;
+ border: none;
+ border-radius: 20rpx;
+ height: 84rpx;
+ line-height: 84rpx;
+ background: linear-gradient(135deg, #c19cff, #9146ff);
+ color: #fff;
+ font-size: 28rpx;
+ font-weight: 700
+}
+
.hero-section {
display: flex;
align-items: center;
@@ -381,6 +437,16 @@ page {
box-shadow: 0 10rpx 30rpx rgba(0, 0, 0, .1)
}
+.logout-btn {
+ margin-top: 28rpx;
+ border: 1rpx solid rgba(255, 110, 132, .35);
+ border-radius: 24rpx;
+ background: rgba(255, 110, 132, .08);
+ color: #ff6e84;
+ font-size: 26rpx;
+ font-weight: 700
+}
+
.settings-icon {
width: 96rpx;
height: 96rpx;
@@ -542,4 +608,4 @@ page {
.nav-label {
font-size: 20rpx
-}
\ No newline at end of file
+}
diff --git a/progress-list/progress-list.js b/progress-list/progress-list.js
index 2158244..688fafe 100644
--- a/progress-list/progress-list.js
+++ b/progress-list/progress-list.js
@@ -31,7 +31,7 @@ Page({
this.setData({ loading: true, error: '' })
wx.request({
url: `${app.globalData.baseUrl}/api/v1/progress/review`,
- header: { 'X-OpenID': app.globalData.openid || '' },
+ header: { 'X-Auth-Token': app.globalData.authToken || '' },
success: (res) => {
const reviewList = res.data?.data || []
const grouped = groupByType(reviewList)
@@ -41,7 +41,7 @@ Page({
})
wx.request({
url: `${app.globalData.baseUrl}/api/v1/progress/mastered`,
- header: { 'X-OpenID': app.globalData.openid || '' },
+ header: { 'X-Auth-Token': app.globalData.authToken || '' },
success: (res) => {
const masteredList = res.data?.data || []
const grouped = groupByType(masteredList)
diff --git a/progress/achievements/achievements.js b/progress/achievements/achievements.js
index 02174a0..d30e5de 100644
--- a/progress/achievements/achievements.js
+++ b/progress/achievements/achievements.js
@@ -142,7 +142,7 @@ Page({
this.setData({ loading: true, error: '' })
wx.request({
url: `${app.globalData.baseUrl}/api/v1/achievements`,
- header: { 'X-OpenID': app.globalData.openid || '' },
+ header: { 'X-Auth-Token': app.globalData.authToken || '' },
success: (res) => {
const list = this.decorateList(res.data?.data || [])
const sections = this.buildSections(list)
@@ -161,7 +161,7 @@ Page({
wx.request({
url: `${app.globalData.baseUrl}/api/v1/achievements/refresh`,
method: 'POST',
- header: { 'X-OpenID': app.globalData.openid || '' },
+ header: { 'X-Auth-Token': app.globalData.authToken || '' },
success: (res) => {
const payload = res.data?.data || {}
const list = this.decorateList(payload.achievements || [])
diff --git a/progress/checkin-detail/checkin-detail.js b/progress/checkin-detail/checkin-detail.js
index 64fefe5..ebf6e22 100644
--- a/progress/checkin-detail/checkin-detail.js
+++ b/progress/checkin-detail/checkin-detail.js
@@ -13,7 +13,7 @@ Page({
this.setData({ loading: true, error: '' })
wx.request({
url: `${app.globalData.baseUrl}/api/v1/checkin/stats`,
- header: { 'X-OpenID': app.globalData.openid || '' },
+ header: { 'X-Auth-Token': app.globalData.authToken || '' },
success: (res) => this.setData({ stats: res.data?.data || null }),
fail: () => this.setData({ error: '打卡数据加载失败' }),
complete: () => this.setData({ loading: false }),
diff --git a/progress/progress-list/progress-list.js b/progress/progress-list/progress-list.js
index 2158244..688fafe 100644
--- a/progress/progress-list/progress-list.js
+++ b/progress/progress-list/progress-list.js
@@ -31,7 +31,7 @@ Page({
this.setData({ loading: true, error: '' })
wx.request({
url: `${app.globalData.baseUrl}/api/v1/progress/review`,
- header: { 'X-OpenID': app.globalData.openid || '' },
+ header: { 'X-Auth-Token': app.globalData.authToken || '' },
success: (res) => {
const reviewList = res.data?.data || []
const grouped = groupByType(reviewList)
@@ -41,7 +41,7 @@ Page({
})
wx.request({
url: `${app.globalData.baseUrl}/api/v1/progress/mastered`,
- header: { 'X-OpenID': app.globalData.openid || '' },
+ header: { 'X-Auth-Token': app.globalData.authToken || '' },
success: (res) => {
const masteredList = res.data?.data || []
const grouped = groupByType(masteredList)
diff --git a/review-config/review-config.js b/review-config/review-config.js
index be521bf..d4f3454 100644
--- a/review-config/review-config.js
+++ b/review-config/review-config.js
@@ -69,15 +69,15 @@ Page({
const question_mode = questionModeMap[this.data.activeMode]
const scope_config = {}
this.setData({ loading: true, error: '' })
- app.ensureLogin().then((openid) => {
- if (!openid) {
+ app.ensureLogin().then((authToken) => {
+ if (!authToken) {
this.setData({ loading: false, error: '请先登录后再开始复习' })
return
}
wx.request({
url: `${app.globalData.baseUrl}/api/v1/review/generate`,
method: 'POST',
- header: { 'Content-Type': 'application/json', 'X-OpenID': openid },
+ header: { 'Content-Type': 'application/json', 'X-Auth-Token': authToken },
data: {
scope_type,
scope_config,
diff --git a/review-result/review-result.js b/review-result/review-result.js
index d72a6a6..1d55ba0 100644
--- a/review-result/review-result.js
+++ b/review-result/review-result.js
@@ -30,7 +30,7 @@ Page({
this.setData({ loading: true, error: '' })
wx.request({
url: `${app.globalData.baseUrl}/api/v1/review-result?session_id=${sessionId}`,
- header: { 'X-OpenID': app.globalData.openid || '' },
+ header: { 'X-Auth-Token': app.globalData.authToken || '' },
success: (res) => {
const data = res.data?.data || {}
const total = Number(data.total || 0)
diff --git a/review-session/review-session.js b/review-session/review-session.js
index d250558..e5aed33 100644
--- a/review-session/review-session.js
+++ b/review-session/review-session.js
@@ -46,13 +46,13 @@ Page({
this.loadSettingsAndQuestions()
},
loadSettingsAndQuestions() {
- if (!app.globalData.openid) {
+ if (!app.globalData.authToken) {
this.setData({ error: '请先登录' })
return
}
wx.request({
url: `${app.globalData.baseUrl}/api/v1/settings`,
- header: { 'X-OpenID': app.globalData.openid },
+ header: { 'X-Auth-Token': app.globalData.authToken },
success: (res) => {
app.globalData.userSettings = res.data?.data || {}
this.setData({ settings: getReviewSettings() })
@@ -128,7 +128,7 @@ Page({
this.setData({ loading: true, error: '' })
wx.request({
url: `${app.globalData.baseUrl}/api/v1/review/questions?session_id=${session.id}`,
- header: { 'X-OpenID': app.globalData.openid || '' },
+ header: { 'X-Auth-Token': app.globalData.authToken || '' },
success: (res) => {
if (res.statusCode < 200 || res.statusCode >= 300) {
const message = res.data?.detail || res.data?.message || '题目加载失败'
@@ -339,7 +339,7 @@ Page({
wx.request({
url: `${app.globalData.baseUrl}/api/v1/review/submit`,
method: 'POST',
- header: { 'Content-Type': 'application/json', 'X-OpenID': app.globalData.openid || '' },
+ header: { 'Content-Type': 'application/json', 'X-Auth-Token': app.globalData.authToken || '' },
data: payload,
success: (res) => {
const result = res.data?.data || {}
@@ -422,7 +422,7 @@ Page({
wx.request({
url: `${app.globalData.baseUrl}/api/v1/review/finish?session_id=${app.globalData.reviewSessionMeta.id}`,
method: 'POST',
- header: { 'X-OpenID': app.globalData.openid || '' },
+ header: { 'X-Auth-Token': app.globalData.authToken || '' },
success: () => wx.navigateTo({ url: '/pages/review-result/review-result' }),
fail: () => {
wx.showToast({ title: '提交结果失败,已本地完成', icon: 'none' })
diff --git a/review/review-config/review-config.js b/review/review-config/review-config.js
index cd1a5e0..3c84c06 100644
--- a/review/review-config/review-config.js
+++ b/review/review-config/review-config.js
@@ -69,15 +69,15 @@ Page({
const question_mode = questionModeMap[this.data.activeMode]
const scope_config = {}
this.setData({ loading: true, error: '' })
- app.ensureLogin().then((openid) => {
- if (!openid) {
+ app.ensureLogin().then((authToken) => {
+ if (!authToken) {
this.setData({ loading: false, error: '??????????' })
return
}
wx.request({
url: `${app.globalData.baseUrl}/api/v1/review/generate`,
method: 'POST',
- header: { 'Content-Type': 'application/json', 'X-OpenID': openid },
+ header: { 'Content-Type': 'application/json', 'X-Auth-Token': authToken },
data: {
scope_type,
scope_config,
diff --git a/review/review-result/review-result.js b/review/review-result/review-result.js
index 205f3b4..30abd3b 100644
--- a/review/review-result/review-result.js
+++ b/review/review-result/review-result.js
@@ -30,7 +30,7 @@ Page({
this.setData({ loading: true, error: '' })
wx.request({
url: `${app.globalData.baseUrl}/api/v1/review-result?session_id=${sessionId}`,
- header: { 'X-OpenID': app.globalData.openid || '' },
+ header: { 'X-Auth-Token': app.globalData.authToken || '' },
success: (res) => {
const data = res.data?.data || {}
const total = Number(data.total || 0)
diff --git a/review/review-session/review-session.js b/review/review-session/review-session.js
index 8dfef90..9710229 100644
--- a/review/review-session/review-session.js
+++ b/review/review-session/review-session.js
@@ -46,13 +46,13 @@ Page({
this.loadSettingsAndQuestions()
},
loadSettingsAndQuestions() {
- if (!app.globalData.openid) {
+ if (!app.globalData.authToken) {
this.setData({ error: '????' })
return
}
wx.request({
url: `${app.globalData.baseUrl}/api/v1/settings`,
- header: { 'X-OpenID': app.globalData.openid },
+ header: { 'X-Auth-Token': app.globalData.authToken },
success: (res) => {
app.globalData.userSettings = res.data?.data || {}
this.setData({ settings: getReviewSettings() })
@@ -128,7 +128,7 @@ Page({
this.setData({ loading: true, error: '' })
wx.request({
url: `${app.globalData.baseUrl}/api/v1/review/questions?session_id=${session.id}`,
- header: { 'X-OpenID': app.globalData.openid || '' },
+ header: { 'X-Auth-Token': app.globalData.authToken || '' },
success: (res) => {
if (res.statusCode < 200 || res.statusCode >= 300) {
const message = res.data?.detail || res.data?.message || '??????'
@@ -339,7 +339,7 @@ Page({
wx.request({
url: `${app.globalData.baseUrl}/api/v1/review/submit`,
method: 'POST',
- header: { 'Content-Type': 'application/json', 'X-OpenID': app.globalData.openid || '' },
+ header: { 'Content-Type': 'application/json', 'X-Auth-Token': app.globalData.authToken || '' },
data: payload,
success: (res) => {
const result = res.data?.data || {}
@@ -422,7 +422,7 @@ Page({
wx.request({
url: `${app.globalData.baseUrl}/api/v1/review/finish?session_id=${app.globalData.reviewSessionMeta.id}`,
method: 'POST',
- header: { 'X-OpenID': app.globalData.openid || '' },
+ header: { 'X-Auth-Token': app.globalData.authToken || '' },
success: () => wx.navigateTo({ url: '/pages/review/review-result/review-result' }),
fail: () => {
wx.showToast({ title: '????????????', icon: 'none' })
diff --git a/settings/settings.js b/settings/settings.js
index 8bd73ba..bd7de0d 100644
--- a/settings/settings.js
+++ b/settings/settings.js
@@ -38,14 +38,14 @@ Page({
})
},
loadSettings() {
- if (!app.globalData.openid) {
+ if (!app.globalData.authToken) {
this.setData({ error: '请先登录' })
return
}
this.setData({ loading: true, error: '' })
wx.request({
url: `${app.globalData.baseUrl}/api/v1/settings`,
- header: { 'X-OpenID': app.globalData.openid },
+ header: { 'X-Auth-Token': app.globalData.authToken },
success: (res) => {
this.syncDerivedState(res.data?.data || null)
},
@@ -93,7 +93,7 @@ Page({
this.setData({ settings })
},
save() {
- if (!app.globalData.openid) {
+ if (!app.globalData.authToken) {
wx.showToast({ title: '请先登录', icon: 'none' })
return
}
@@ -101,7 +101,7 @@ Page({
wx.request({
url: `${app.globalData.baseUrl}/api/v1/settings`,
method: 'PUT',
- header: { 'Content-Type': 'application/json', 'X-OpenID': app.globalData.openid },
+ header: { 'Content-Type': 'application/json', 'X-Auth-Token': app.globalData.authToken },
data: settings,
success: () => wx.showToast({ title: '已保存', icon: 'success' }),
fail: () => wx.showToast({ title: '保存失败', icon: 'none' }),