修复上线第一版
This commit is contained in:
parent
ad510a1be6
commit
c92f4069a7
@ -1,32 +1,36 @@
|
|||||||
const app = getApp()
|
const app = getApp()
|
||||||
|
|
||||||
|
function staticIcon(path) {
|
||||||
|
return `${app.globalData.staticBaseUrl}/${path.replace(/^\/+/, '')}`
|
||||||
|
}
|
||||||
|
|
||||||
const ACHIEVEMENT_ICON_MAP = {
|
const ACHIEVEMENT_ICON_MAP = {
|
||||||
MASTERED_100: '/assets/icons/achievements/core/100.svg',
|
MASTERED_100: staticIcon('icons/achievements/core/100.svg'),
|
||||||
MASTERED_1000: '/assets/icons/achievements/core/1000.svg',
|
MASTERED_1000: staticIcon('icons/achievements/core/1000.svg'),
|
||||||
MASTERED_3000: '/assets/icons/achievements/core/3000.svg',
|
MASTERED_3000: staticIcon('icons/achievements/core/3000.svg'),
|
||||||
MASTERED_5000: '/assets/icons/achievements/core/5000.svg',
|
MASTERED_5000: staticIcon('icons/achievements/core/5000.svg'),
|
||||||
MASTERED_7000: '/assets/icons/achievements/core/7000.svg',
|
MASTERED_7000: staticIcon('icons/achievements/core/7000.svg'),
|
||||||
MASTERED_10000: '/assets/icons/achievements/core/10000.svg',
|
MASTERED_10000: staticIcon('icons/achievements/core/10000.svg'),
|
||||||
TOTAL_100: '/assets/icons/achievements/core/total-100.svg',
|
TOTAL_100: staticIcon('icons/achievements/core/total-100.svg'),
|
||||||
CHECKIN_7: '/assets/icons/achievements/core/checkin-30.svg',
|
CHECKIN_7: staticIcon('icons/achievements/core/checkin-30.svg'),
|
||||||
CHECKIN_30: '/assets/icons/achievements/core/checkin-30.svg',
|
CHECKIN_30: staticIcon('icons/achievements/core/checkin-30.svg'),
|
||||||
CHECKIN_100: '/assets/icons/achievements/core/streak.svg',
|
CHECKIN_100: staticIcon('icons/achievements/core/streak.svg'),
|
||||||
CHECKIN_180: '/assets/icons/achievements/core/streak.svg',
|
CHECKIN_180: staticIcon('icons/achievements/core/streak.svg'),
|
||||||
CHECKIN_360: '/assets/icons/achievements/core/streak.svg',
|
CHECKIN_360: staticIcon('icons/achievements/core/streak.svg'),
|
||||||
CHECKIN_STREAK_7: '/assets/icons/achievements/core/streak.svg',
|
CHECKIN_STREAK_7: staticIcon('icons/achievements/core/streak.svg'),
|
||||||
CHECKIN_STREAK_30: '/assets/icons/achievements/core/streak.svg',
|
CHECKIN_STREAK_30: staticIcon('icons/achievements/core/streak.svg'),
|
||||||
CHECKIN_STREAK_100: '/assets/icons/achievements/core/streak.svg',
|
CHECKIN_STREAK_100: staticIcon('icons/achievements/core/streak.svg'),
|
||||||
CHECKIN_STREAK_180: '/assets/icons/achievements/core/streak.svg',
|
CHECKIN_STREAK_180: staticIcon('icons/achievements/core/streak.svg'),
|
||||||
CHECKIN_STREAK_360: '/assets/icons/achievements/core/streak.svg',
|
CHECKIN_STREAK_360: staticIcon('icons/achievements/core/streak.svg'),
|
||||||
ACCURACY_80: '/assets/icons/achievements/core/accuracy.svg',
|
ACCURACY_80: staticIcon('icons/achievements/core/accuracy.svg'),
|
||||||
ACCURACY_90: '/assets/icons/achievements/core/accuracy.svg',
|
ACCURACY_90: staticIcon('icons/achievements/core/accuracy.svg'),
|
||||||
DAILY_REVIEW_20: '/assets/icons/achievements/core/review-volume.svg',
|
DAILY_REVIEW_20: staticIcon('icons/achievements/core/review-volume.svg'),
|
||||||
DAILY_REVIEW_50: '/assets/icons/achievements/core/review-volume.svg',
|
DAILY_REVIEW_50: staticIcon('icons/achievements/core/review-volume.svg'),
|
||||||
}
|
}
|
||||||
|
|
||||||
const STATUS_ICON_MAP = {
|
const STATUS_ICON_MAP = {
|
||||||
1: '/assets/icons/achievements/state/achievement-unlocked.svg',
|
1: staticIcon('icons/achievements/state/achievement-unlocked.svg'),
|
||||||
0: '/assets/icons/achievements/state/achievement-locked.svg',
|
0: staticIcon('icons/achievements/state/achievement-locked.svg'),
|
||||||
}
|
}
|
||||||
|
|
||||||
const GROUP_ORDER = {
|
const GROUP_ORDER = {
|
||||||
@ -39,12 +43,12 @@ const GROUP_ORDER = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const GROUP_META = {
|
const GROUP_META = {
|
||||||
mastery: { title: '掌握进阶', subtitle: '从入门到精通', icon: '/assets/icons/achievements/core/mastery-advanced.svg' },
|
mastery: { title: '掌握进阶', subtitle: '从入门到精通', icon: staticIcon('icons/achievements/core/mastery-advanced.svg') },
|
||||||
checkin: { title: '打卡里程', subtitle: '记录坚持的脚步', icon: '/assets/icons/achievements/core/checkin-30.svg' },
|
checkin: { title: '打卡里程', subtitle: '记录坚持的脚步', icon: staticIcon('icons/achievements/core/checkin-30.svg') },
|
||||||
streak: { title: '连续坚持', subtitle: '不断线的努力', icon: '/assets/icons/achievements/core/streak.svg' },
|
streak: { title: '连续坚持', subtitle: '不断线的努力', icon: staticIcon('icons/achievements/core/streak.svg') },
|
||||||
accuracy: { title: '准确率', subtitle: '复习质量提升', icon: '/assets/icons/achievements/core/accuracy.svg' },
|
accuracy: { title: '准确率', subtitle: '复习质量提升', icon: staticIcon('icons/achievements/core/accuracy.svg') },
|
||||||
review: { title: '复习数量', subtitle: '积累复习量', icon: '/assets/icons/achievements/core/review-volume.svg' },
|
review: { title: '复习数量', subtitle: '积累复习量', icon: staticIcon('icons/achievements/core/review-volume.svg') },
|
||||||
other: { title: '其他', subtitle: '更多成就', icon: '/assets/icons/achievements/core/total-100.svg' },
|
other: { title: '其他', subtitle: '更多成就', icon: staticIcon('icons/achievements/core/total-100.svg') },
|
||||||
}
|
}
|
||||||
|
|
||||||
const GROUP_PROGRESS = {
|
const GROUP_PROGRESS = {
|
||||||
|
|||||||
@ -1,45 +0,0 @@
|
|||||||
const app = getApp()
|
|
||||||
|
|
||||||
Page({
|
|
||||||
data: {
|
|
||||||
list: [],
|
|
||||||
loading: false,
|
|
||||||
error: '',
|
|
||||||
},
|
|
||||||
onShow() {
|
|
||||||
this.loadList()
|
|
||||||
},
|
|
||||||
loadList() {
|
|
||||||
if (!app.globalData.openid) {
|
|
||||||
this.setData({ error: '请先登录' })
|
|
||||||
return
|
|
||||||
}
|
|
||||||
this.setData({ loading: true, error: '' })
|
|
||||||
wx.request({
|
|
||||||
url: `${app.globalData.baseUrl}/api/v1/entries`,
|
|
||||||
header: { 'X-OpenID': app.globalData.openid },
|
|
||||||
success: (res) => {
|
|
||||||
const payload = res.data?.data || []
|
|
||||||
this.setData({ list: payload })
|
|
||||||
},
|
|
||||||
fail: () => this.setData({ error: '词库加载失败' }),
|
|
||||||
complete: () => this.setData({ loading: false }),
|
|
||||||
})
|
|
||||||
},
|
|
||||||
goAdd() {
|
|
||||||
wx.navigateTo({ url: '/pages/manage/entry-edit/entry-edit' })
|
|
||||||
},
|
|
||||||
goDetail(e) {
|
|
||||||
const { id } = e.currentTarget.dataset
|
|
||||||
wx.navigateTo({ url: `/pages/manage/entry-detail/entry-detail?id=${id}` })
|
|
||||||
},
|
|
||||||
goBatch() {
|
|
||||||
wx.navigateTo({ url: '/pages/manage/batch-upload/batch-upload' })
|
|
||||||
},
|
|
||||||
goProgress() {
|
|
||||||
wx.navigateTo({ url: '/pages/progress/progress-list/progress-list' })
|
|
||||||
},
|
|
||||||
goSettings() {
|
|
||||||
wx.navigateTo({ url: '/pages/settings/settings' })
|
|
||||||
},
|
|
||||||
})
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
{
|
|
||||||
"usingComponents": {}
|
|
||||||
}
|
|
||||||
@ -1,55 +0,0 @@
|
|||||||
<view class="page">
|
|
||||||
<scroll-view scroll-y class="content">
|
|
||||||
<view class="header">
|
|
||||||
<text class="title">词库管理</text>
|
|
||||||
<text class="subtitle">管理并策划你的个人词汇集合。</text>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- <view class="toolbar">
|
|
||||||
<button class="primary-btn" bindtap="goAdd">新增</button>
|
|
||||||
<button class="secondary-btn" bindtap="goBatch">批量上传</button>
|
|
||||||
<button class="secondary-btn" bindtap="goProgress">进度</button>
|
|
||||||
<button class="secondary-btn" bindtap="goSettings">设置</button>
|
|
||||||
</view> -->
|
|
||||||
|
|
||||||
<view class="search-row">
|
|
||||||
<view class="search-box">
|
|
||||||
<text class="search-icon">🔎</text>
|
|
||||||
<text class="search-placeholder">搜索单词、短语或标签...</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<view wx:if="{{loading}}" class="empty-state">
|
|
||||||
<text class="empty-title">加载中...</text>
|
|
||||||
<text class="empty-subtitle">正在同步词库数据</text>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<view wx:elif="{{error}}" class="error-banner">
|
|
||||||
<text class="error-text">{{error}}</text>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<view wx:elif="{{!list.length}}" class="empty-state">
|
|
||||||
<text class="empty-title">暂无词条</text>
|
|
||||||
<text class="empty-subtitle">点击“新增”或“批量上传”开始构建词库</text>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<view wx:else class="card-grid">
|
|
||||||
<block wx:for="{{list}}" wx:key="id">
|
|
||||||
<view class="word-card {{item.entry_type === 'sentence' ? 'pink' : 'cyan'}}" data-id="{{item.id}}" bindtap="goDetail">
|
|
||||||
<view class="card-top">
|
|
||||||
<view>
|
|
||||||
<text class="word-title">{{item.en_text}}</text>
|
|
||||||
<text class="phonetic">{{item.entry_type === 'sentence' ? '句子' : '单词'}}</text>
|
|
||||||
</view>
|
|
||||||
<view class="status-dot done">{{item.status}}</view>
|
|
||||||
</view>
|
|
||||||
<text class="meaning">{{item.entry_type === 'sentence' ? item.zh_text : item.zh_text}}</text>
|
|
||||||
<text class="example" wx:if="{{item.entry_type === 'word' && item.example_text}}">例句:{{item.example_text}}</text>
|
|
||||||
<text class="example" wx:elif="{{item.entry_type === 'sentence' && item.example_text}}">说明:{{item.example_text}}</text>
|
|
||||||
</view>
|
|
||||||
</block>
|
|
||||||
</view>
|
|
||||||
</scroll-view>
|
|
||||||
|
|
||||||
<view class="fab" bindtap="goAdd">+</view>
|
|
||||||
</view>
|
|
||||||
@ -1 +0,0 @@
|
|||||||
page{background:#0c0e12;color:#f6f6fc}.page{min-height:100vh;background:#0c0e12;box-sizing:border-box}.topbar{display:flex;justify-content:space-between;align-items:center;padding:24rpx 32rpx;background:rgba(12,14,18,.8);backdrop-filter:blur(24px);border-bottom:1rpx solid rgba(255,255,255,.08);box-shadow:0 1rpx 20rpx rgba(0,0,0,.08)}.brand{display:flex;align-items:center;gap:18rpx}.avatar-wrap{width:64rpx;height:64rpx;border-radius:9999rpx;overflow:hidden;border:1rpx solid rgba(255,255,255,.1);flex-shrink:0}.avatar{width:100%;height:100%}.brand-text{font-size:38rpx;font-weight:800;color:#c19cff}.icon-btn{width:72rpx;height:72rpx;border-radius:9999rpx;background:rgba(255,255,255,.06);display:flex;align-items:center;justify-content:center}.content{height:calc(100vh - 120rpx);padding:40rpx 32rpx 32rpx;box-sizing:border-box}.header{margin-bottom:28rpx}.title{display:block;font-size:52rpx;font-weight:800}.subtitle{display:block;margin-top:10rpx;color:#aaabb0;font-size:26rpx}.search-row{display:flex;flex-direction:column;gap:18rpx;margin-bottom:28rpx}.search-box{display:flex;align-items:center;gap:12rpx;padding:22rpx 26rpx;border-radius:9999rpx;background:#000;border:1rpx solid rgba(255,255,255,.1);color:#aaabb0}.search-placeholder{font-size:24rpx}.filters{display:flex;gap:14rpx;overflow-x:auto}.filter-btn{padding:18rpx 22rpx;border-radius:9999rpx;background:#23262c;color:#f6f6fc;font-size:22rpx;white-space:nowrap}.dim{color:#aaabb0;margin:0 4rpx}.card-grid{display:grid;grid-template-columns:1fr;gap:18rpx}.word-card{position:relative;overflow:hidden;padding:28rpx;border-radius:28rpx;background:rgba(29,32,37,.56);backdrop-filter:blur(24rpx);border:1rpx solid rgba(255,255,255,.06);box-shadow:0 20rpx 40rpx rgba(0,0,0,.06)}.cyan{box-shadow:0 20rpx 40rpx rgba(0,229,255,.05)}.purple{box-shadow:0 20rpx 40rpx rgba(127,0,255,.05)}.pink{box-shadow:0 20rpx 40rpx rgba(255,64,129,.05)}.wide{min-height:280rpx}.card-top{display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:18rpx}.word-title{display:block;font-size:38rpx;font-weight:800}.phonetic{display:block;margin-top:8rpx;font-size:22rpx;color:#aaabb0}.status-dot{width:56rpx;height:56rpx;border-radius:9999rpx;display:flex;align-items:center;justify-content:center;background:rgba(255,255,255,.06)}.done{color:#00e5ff}.learn{color:#c19cff}.review{color:#ff4081}.meaning{display:block;font-size:26rpx;color:#f6f6fc;line-height:1.6}.split{display:grid;grid-template-columns:1fr 1fr;gap:18rpx;align-items:start}.example{font-size:22rpx;color:#aaabb0;font-style:italic;border-left:4rpx solid rgba(193,156,255,.3);padding-left:14rpx;line-height:1.6}.progress-block{margin-top:22rpx;padding-top:18rpx;border-top:1rpx solid rgba(255,255,255,.05)}.progress-meta{display:flex;justify-content:space-between;font-size:20rpx;color:#aaabb0;margin-bottom:10rpx}.accent-cyan{color:#00e5ff}.accent-purple{color:#c19cff}.accent-pink{color:#ff4081}.progress-bar{height:10rpx;border-radius:9999rpx;background:#111318;overflow:hidden}.fill{height:100%;border-radius:9999rpx}.cyan-fill{width:95%;background:#00e5ff}.purple-fill{width:60%;background:#c19cff}.pink-fill{width:30%;background:#ff4081}.fab{position:fixed;right:28rpx;bottom:130rpx;width:96rpx;height:96rpx;border-radius:9999rpx;background:linear-gradient(135deg,#c19cff,#00e5ff);display:flex;align-items:center;justify-content:center;color:#fff;font-size:48rpx;box-shadow:0 0 20rpx rgba(193,156,255,.2)}
|
|
||||||
36
me/me.js
36
me/me.js
@ -20,7 +20,7 @@ Page({
|
|||||||
this.setData({ loading: true, error: '' })
|
this.setData({ loading: true, error: '' })
|
||||||
await app.ensureLogin()
|
await app.ensureLogin()
|
||||||
if (!app.globalData.openid) {
|
if (!app.globalData.openid) {
|
||||||
this.setData({ loading: false, error: '登录失败,请重试' })
|
this.setData({ loading: false, error: '????????' })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
wx.request({
|
wx.request({
|
||||||
@ -30,7 +30,7 @@ Page({
|
|||||||
success: (res) => {
|
success: (res) => {
|
||||||
const profile = res.data?.data || {}
|
const profile = res.data?.data || {}
|
||||||
const avatarUrl = profile.avatar_url || wx.getStorageSync(`avatarUrl:${app.globalData.openid}`) || ''
|
const avatarUrl = profile.avatar_url || wx.getStorageSync(`avatarUrl:${app.globalData.openid}`) || ''
|
||||||
const nickname = profile.nickname || '考研搭子'
|
const nickname = profile.nickname || '????'
|
||||||
const normalizedAvatar = avatarUrl.startsWith('http') ? avatarUrl : avatarUrl ? `${app.globalData.baseUrl}${avatarUrl}` : ''
|
const normalizedAvatar = avatarUrl.startsWith('http') ? avatarUrl : avatarUrl ? `${app.globalData.baseUrl}${avatarUrl}` : ''
|
||||||
this.setData({
|
this.setData({
|
||||||
openid: app.globalData.openid,
|
openid: app.globalData.openid,
|
||||||
@ -43,7 +43,7 @@ Page({
|
|||||||
fail: () => {
|
fail: () => {
|
||||||
const storedAvatarUrl = wx.getStorageSync(`avatarUrl:${app.globalData.openid}`) || ''
|
const storedAvatarUrl = wx.getStorageSync(`avatarUrl:${app.globalData.openid}`) || ''
|
||||||
const normalizedAvatar = storedAvatarUrl.startsWith('http') ? storedAvatarUrl : storedAvatarUrl ? `${app.globalData.baseUrl}${storedAvatarUrl}` : ''
|
const normalizedAvatar = storedAvatarUrl.startsWith('http') ? storedAvatarUrl : storedAvatarUrl ? `${app.globalData.baseUrl}${storedAvatarUrl}` : ''
|
||||||
this.setData({ openid: app.globalData.openid, name: '考研搭子', nickname: '考研搭子', avatarUrl: normalizedAvatar, nicknameDraft: '考研搭子' })
|
this.setData({ openid: app.globalData.openid, name: '????', nickname: '????', avatarUrl: normalizedAvatar, nicknameDraft: '????' })
|
||||||
},
|
},
|
||||||
complete: () => {
|
complete: () => {
|
||||||
this.loadAchievements()
|
this.loadAchievements()
|
||||||
@ -52,13 +52,13 @@ Page({
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
openNicknameModal() {
|
openNicknameModal() {
|
||||||
this.setData({ showNicknameModal: true, nicknameDraft: this.data.nickname || this.data.name || '考研搭子' })
|
this.setData({ showNicknameModal: true, nicknameDraft: this.data.nickname || this.data.name || '????' })
|
||||||
},
|
},
|
||||||
onAvatarError() {
|
onAvatarError() {
|
||||||
this.setData({ avatarUrl: '' })
|
this.setData({ avatarUrl: '' })
|
||||||
},
|
},
|
||||||
closeNicknameModal() {
|
closeNicknameModal() {
|
||||||
this.setData({ showNicknameModal: false, nicknameDraft: this.data.nickname || this.data.name || '考研搭子' })
|
this.setData({ showNicknameModal: false, nicknameDraft: this.data.nickname || this.data.name || '????' })
|
||||||
},
|
},
|
||||||
onNicknameInput(e) {
|
onNicknameInput(e) {
|
||||||
this.setData({ nicknameDraft: e.detail.value })
|
this.setData({ nicknameDraft: e.detail.value })
|
||||||
@ -67,7 +67,7 @@ Page({
|
|||||||
if (!app.globalData.openid) return
|
if (!app.globalData.openid) return
|
||||||
const nickname = (this.data.nicknameDraft || '').trim()
|
const nickname = (this.data.nicknameDraft || '').trim()
|
||||||
if (!nickname) {
|
if (!nickname) {
|
||||||
wx.showToast({ title: '昵称不能为空', icon: 'none' })
|
wx.showToast({ title: '??????', icon: 'none' })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
wx.request({
|
wx.request({
|
||||||
@ -79,14 +79,14 @@ Page({
|
|||||||
const profile = res.data?.data || {}
|
const profile = res.data?.data || {}
|
||||||
const nextNickname = profile.nickname || nickname
|
const nextNickname = profile.nickname || nickname
|
||||||
this.setData({ nickname: nextNickname, name: nextNickname, nicknameDraft: nextNickname, showNicknameModal: false })
|
this.setData({ nickname: nextNickname, name: nextNickname, nicknameDraft: nextNickname, showNicknameModal: false })
|
||||||
wx.showToast({ title: '昵称已保存', icon: 'success' })
|
wx.showToast({ title: '?????', icon: 'success' })
|
||||||
},
|
},
|
||||||
fail: () => wx.showToast({ title: '保存失败', icon: 'none' }),
|
fail: () => wx.showToast({ title: '????', icon: 'none' }),
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
chooseAvatar() {
|
chooseAvatar() {
|
||||||
if (!app.globalData.openid) {
|
if (!app.globalData.openid) {
|
||||||
wx.showToast({ title: '请先登录', icon: 'none' })
|
wx.showToast({ title: '????', icon: 'none' })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
wx.chooseImage({
|
wx.chooseImage({
|
||||||
@ -138,30 +138,30 @@ Page({
|
|||||||
data: { openid: app.globalData.openid },
|
data: { openid: app.globalData.openid },
|
||||||
success: (profileRes) => {
|
success: (profileRes) => {
|
||||||
const profile = profileRes.data?.data || {}
|
const profile = profileRes.data?.data || {}
|
||||||
const nextNickname = profile.nickname || '考研搭子'
|
const nextNickname = profile.nickname || '????'
|
||||||
this.setData({ name: nextNickname, avatarUrl: fullUrl })
|
this.setData({ name: nextNickname, avatarUrl: fullUrl })
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
wx.showToast({ title: '头像已上传', icon: 'success' })
|
wx.showToast({ title: '?????', icon: 'success' })
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
wx.showToast({ title: '头像上传失败', icon: 'none' })
|
wx.showToast({ title: '??????', icon: 'none' })
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
fail: () => wx.showToast({ title: '头像上传失败', icon: 'none' }),
|
fail: () => wx.showToast({ title: '??????', icon: 'none' }),
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
fail: () => wx.showToast({ title: '头像处理失败', icon: 'none' }),
|
fail: () => wx.showToast({ title: '??????', icon: 'none' }),
|
||||||
}, this)
|
}, this)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
fail: () => wx.showToast({ title: '头像处理失败', icon: 'none' }),
|
fail: () => wx.showToast({ title: '??????', icon: 'none' }),
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
loadAchievements() {
|
loadAchievements() {
|
||||||
if (!app.globalData.openid) {
|
if (!app.globalData.openid) {
|
||||||
this.setData({ error: '未获取到登录态' })
|
this.setData({ error: '???????' })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
wx.request({
|
wx.request({
|
||||||
@ -172,13 +172,13 @@ Page({
|
|||||||
const badges = Array.isArray(list) ? list.filter((i) => i.is_unlocked).length : 0
|
const badges = Array.isArray(list) ? list.filter((i) => i.is_unlocked).length : 0
|
||||||
this.setData({ badges })
|
this.setData({ badges })
|
||||||
},
|
},
|
||||||
fail: () => this.setData({ error: '成就数据加载失败' }),
|
fail: () => this.setData({ error: '????????' }),
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
goTo(e) {
|
goTo(e) {
|
||||||
const { url } = e.currentTarget.dataset
|
const { url } = e.currentTarget.dataset
|
||||||
if (!app.globalData.openid) {
|
if (!app.globalData.openid) {
|
||||||
wx.showToast({ title: '请先登录', icon: 'none' })
|
wx.showToast({ title: '????', icon: 'none' })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
wx.navigateTo({ url })
|
wx.navigateTo({ url })
|
||||||
|
|||||||
38
me/me.wxml
38
me/me.wxml
@ -1,14 +1,14 @@
|
|||||||
<view class="page">
|
<view class="page">
|
||||||
<scroll-view scroll-y class="content">
|
<scroll-view scroll-y class="content">
|
||||||
<canvas canvas-id="avatar-canvas" class="avatar-canvas"></canvas>
|
<canvas canvas-id="avatar-canvas" class="avatar-canvas"></canvas>
|
||||||
<view wx:if="{{loading}}" class="empty-state">
|
<view wx:if="{{loading}}" class="empty-state">
|
||||||
<text class="empty-title">登录中...</text>
|
<text class="empty-title">加载中...</text>
|
||||||
<text class="empty-subtitle">正在获取你的登录态</text>
|
<text class="empty-subtitle">正在获取个人信息</text>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view wx:elif="{{error}}" class="error-banner">
|
<view wx:elif="{{error}}" class="error-banner">
|
||||||
<text class="error-text">{{error}}</text>
|
<text class="error-text">{{error}}</text>
|
||||||
<button class="secondary-btn error-btn" bindtap="loadProfile">重试登录</button>
|
<button class="secondary-btn error-btn" bindtap="loadProfile">重试</button>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view wx:else class="hero-section">
|
<view wx:else class="hero-section">
|
||||||
@ -16,7 +16,7 @@
|
|||||||
<view class="hero-avatar-border">
|
<view class="hero-avatar-border">
|
||||||
<image class="hero-avatar" src="{{avatarUrl || '/assets/images/default-avatar.png'}}" mode="aspectFill" binderror="onAvatarError" />
|
<image class="hero-avatar" src="{{avatarUrl || '/assets/images/default-avatar.png'}}" mode="aspectFill" binderror="onAvatarError" />
|
||||||
<view class="avatar-mask">
|
<view class="avatar-mask">
|
||||||
<text class="avatar-mask-text">点击更换</text>
|
<text class="avatar-mask-text">更换头像</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@ -24,24 +24,24 @@
|
|||||||
<text class="hero-name" bindtap="openNicknameModal">{{name}}</text>
|
<text class="hero-name" bindtap="openNicknameModal">{{name}}</text>
|
||||||
<view class="hero-badge">
|
<view class="hero-badge">
|
||||||
<view class="pulse-dot"></view>
|
<view class="pulse-dot"></view>
|
||||||
<text class="badge-text">累计学习 {{days}} 天</text>
|
<text class="badge-text">坚持了 {{days}} 天</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view wx:if="{{openid && badges === 0}}" class="empty-state small">
|
<view wx:if="{{openid && badges === 0}}" class="empty-state small">
|
||||||
<text class="empty-title">还没有勋章</text>
|
<text class="empty-title">还没有解锁成就</text>
|
||||||
<text class="empty-subtitle">完成复习和打卡后就会逐渐点亮</text>
|
<text class="empty-subtitle">继续复习和打卡,成就会逐渐点亮</text>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view wx:if="{{openid}}" class="grid-2">
|
<view wx:if="{{openid}}" class="grid-2">
|
||||||
<view class="glass-card accent-tertiary" bindtap="goTo" data-url="/pages/achievements/achievements">
|
<view class="glass-card accent-tertiary" bindtap="goTo" data-url="/package-stats/pages/achievements/achievements">
|
||||||
<view class="card-glow"></view>
|
<view class="card-glow"></view>
|
||||||
<view class="card-icon icon-tertiary">🏅</view>
|
<view class="card-icon icon-tertiary">🏅</view>
|
||||||
<text class="card-title">成就墙</text>
|
<text class="card-title">成就墙</text>
|
||||||
<text class="card-subtitle">已点亮 {{badges}} 枚勋章</text>
|
<text class="card-subtitle">已解锁 {{badges}} 枚勋章</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="glass-card accent-secondary" bindtap="goTo" data-url="/pages/checkin-detail/checkin-detail">
|
<view class="glass-card accent-secondary" bindtap="goTo" data-url="/package-stats/pages/checkin-detail/checkin-detail">
|
||||||
<view class="card-glow"></view>
|
<view class="card-glow"></view>
|
||||||
<view class="card-icon icon-secondary">📅</view>
|
<view class="card-icon icon-secondary">📅</view>
|
||||||
<text class="card-title">打卡详情</text>
|
<text class="card-title">打卡详情</text>
|
||||||
@ -56,27 +56,27 @@
|
|||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="grid-2 management-grid">
|
<view class="grid-2 management-grid">
|
||||||
<view class="small-action" bindtap="goTo" data-url="/pages/vocab-manage/vocab-manage">
|
<view class="small-action" bindtap="goTo" data-url="/package-vocab/pages/vocab-manage/vocab-manage">
|
||||||
<view class="small-icon primary">📚</view>
|
<view class="small-icon primary">📚</view>
|
||||||
<text class="small-text">词库管理</text>
|
<text class="small-text">词库管理</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="small-action" bindtap="goTo" data-url="/pages/entry-edit/entry-edit">
|
<view class="small-action" bindtap="goTo" data-url="/package-vocab/pages/entry-edit/entry-edit">
|
||||||
<view class="small-icon secondary">+</view>
|
<view class="small-icon secondary">+</view>
|
||||||
<text class="small-text">手动新增</text>
|
<text class="small-text">手动新增</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="small-action" bindtap="goTo" data-url="/pages/batch-upload/batch-upload">
|
<view class="small-action" bindtap="goTo" data-url="/package-vocab/pages/batch-upload/batch-upload">
|
||||||
<view class="small-icon tertiary">☁</view>
|
<view class="small-icon tertiary">☁</view>
|
||||||
<text class="small-text">批量上传</text>
|
<text class="small-text">批量上传</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="small-action" bindtap="goTo" data-url="/pages/progress-list/progress-list">
|
<view class="small-action" bindtap="goTo" data-url="/package-stats/pages/progress-list/progress-list">
|
||||||
<view class="small-icon primary-fixed">≡</view>
|
<view class="small-icon primary-fixed">≡</view>
|
||||||
<text class="small-text">进度列表</text>
|
<text class="small-text">进度列表</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="settings-card" bindtap="goTo" data-url="/pages/settings/settings">
|
<view class="settings-card" bindtap="goTo" data-url="/package-stats/pages/settings/settings">
|
||||||
<view class="settings-icon">⚙</view>
|
<view class="settings-icon">⚙</view>
|
||||||
<text class="settings-text">个性化设置</text>
|
<text class="settings-text">设置中心</text>
|
||||||
<view class="chevron">›</view>
|
<view class="chevron">›</view>
|
||||||
</view>
|
</view>
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
@ -97,7 +97,7 @@
|
|||||||
|
|
||||||
<view class="bottom-nav">
|
<view class="bottom-nav">
|
||||||
<view class="nav-item" bindtap="goHome"><text class="nav-icon">⌂</text><text class="nav-label">首页</text></view>
|
<view class="nav-item" bindtap="goHome"><text class="nav-icon">⌂</text><text class="nav-label">首页</text></view>
|
||||||
<view class="nav-item" bindtap="goToReview"><text class="nav-icon">📖</text><text class="nav-label">复习</text></view>
|
<view class="nav-item" bindtap="goToReview"><text class="nav-icon">↻</text><text class="nav-label">复习</text></view>
|
||||||
<view class="nav-item active"><text class="nav-icon">☺</text><text class="nav-label">我的</text></view>
|
<view class="nav-item active"><text class="nav-icon">☺</text><text class="nav-label">我的</text></view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@ -1,45 +0,0 @@
|
|||||||
const app = getApp()
|
|
||||||
|
|
||||||
Page({
|
|
||||||
data: {
|
|
||||||
list: [],
|
|
||||||
loading: false,
|
|
||||||
error: '',
|
|
||||||
},
|
|
||||||
onShow() {
|
|
||||||
this.loadList()
|
|
||||||
},
|
|
||||||
loadList() {
|
|
||||||
if (!app.globalData.openid) {
|
|
||||||
this.setData({ error: '请先登录' })
|
|
||||||
return
|
|
||||||
}
|
|
||||||
this.setData({ loading: true, error: '' })
|
|
||||||
wx.request({
|
|
||||||
url: `${app.globalData.baseUrl}/api/v1/entries`,
|
|
||||||
header: { 'X-OpenID': app.globalData.openid },
|
|
||||||
success: (res) => {
|
|
||||||
const payload = res.data?.data || []
|
|
||||||
this.setData({ list: payload })
|
|
||||||
},
|
|
||||||
fail: () => this.setData({ error: '词库加载失败' }),
|
|
||||||
complete: () => this.setData({ loading: false }),
|
|
||||||
})
|
|
||||||
},
|
|
||||||
goAdd() {
|
|
||||||
wx.navigateTo({ url: '/pages/entry-edit/entry-edit' })
|
|
||||||
},
|
|
||||||
goDetail(e) {
|
|
||||||
const { id } = e.currentTarget.dataset
|
|
||||||
wx.navigateTo({ url: `/pages/entry-detail/entry-detail?id=${id}` })
|
|
||||||
},
|
|
||||||
goBatch() {
|
|
||||||
wx.navigateTo({ url: '/pages/batch-upload/batch-upload' })
|
|
||||||
},
|
|
||||||
goProgress() {
|
|
||||||
wx.navigateTo({ url: '/pages/progress-list/progress-list' })
|
|
||||||
},
|
|
||||||
goSettings() {
|
|
||||||
wx.navigateTo({ url: '/pages/settings/settings' })
|
|
||||||
},
|
|
||||||
})
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
{
|
|
||||||
"usingComponents": {}
|
|
||||||
}
|
|
||||||
@ -1,55 +0,0 @@
|
|||||||
<view class="page">
|
|
||||||
<scroll-view scroll-y class="content">
|
|
||||||
<view class="header">
|
|
||||||
<text class="title">词库管理</text>
|
|
||||||
<text class="subtitle">管理并策划你的个人词汇集合。</text>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- <view class="toolbar">
|
|
||||||
<button class="primary-btn" bindtap="goAdd">新增</button>
|
|
||||||
<button class="secondary-btn" bindtap="goBatch">批量上传</button>
|
|
||||||
<button class="secondary-btn" bindtap="goProgress">进度</button>
|
|
||||||
<button class="secondary-btn" bindtap="goSettings">设置</button>
|
|
||||||
</view> -->
|
|
||||||
|
|
||||||
<view class="search-row">
|
|
||||||
<view class="search-box">
|
|
||||||
<text class="search-icon">🔎</text>
|
|
||||||
<text class="search-placeholder">搜索单词、短语或标签...</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<view wx:if="{{loading}}" class="empty-state">
|
|
||||||
<text class="empty-title">加载中...</text>
|
|
||||||
<text class="empty-subtitle">正在同步词库数据</text>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<view wx:elif="{{error}}" class="error-banner">
|
|
||||||
<text class="error-text">{{error}}</text>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<view wx:elif="{{!list.length}}" class="empty-state">
|
|
||||||
<text class="empty-title">暂无词条</text>
|
|
||||||
<text class="empty-subtitle">点击“新增”或“批量上传”开始构建词库</text>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<view wx:else class="card-grid">
|
|
||||||
<block wx:for="{{list}}" wx:key="id">
|
|
||||||
<view class="word-card {{item.entry_type === 'sentence' ? 'pink' : 'cyan'}}" data-id="{{item.id}}" bindtap="goDetail">
|
|
||||||
<view class="card-top">
|
|
||||||
<view>
|
|
||||||
<text class="word-title">{{item.en_text}}</text>
|
|
||||||
<text class="phonetic">{{item.entry_type === 'sentence' ? '句子' : '单词'}}</text>
|
|
||||||
</view>
|
|
||||||
<view class="status-dot done">{{item.status}}</view>
|
|
||||||
</view>
|
|
||||||
<text class="meaning">{{item.entry_type === 'sentence' ? item.zh_text : item.zh_text}}</text>
|
|
||||||
<text class="example" wx:if="{{item.entry_type === 'word' && item.example_text}}">例句:{{item.example_text}}</text>
|
|
||||||
<text class="example" wx:elif="{{item.entry_type === 'sentence' && item.example_text}}">说明:{{item.example_text}}</text>
|
|
||||||
</view>
|
|
||||||
</block>
|
|
||||||
</view>
|
|
||||||
</scroll-view>
|
|
||||||
|
|
||||||
<view class="fab" bindtap="goAdd">+</view>
|
|
||||||
</view>
|
|
||||||
@ -1 +0,0 @@
|
|||||||
page{background:#0c0e12;color:#f6f6fc}.page{min-height:100vh;background:#0c0e12;box-sizing:border-box}.topbar{display:flex;justify-content:space-between;align-items:center;padding:24rpx 32rpx;background:rgba(12,14,18,.8);backdrop-filter:blur(24px);border-bottom:1rpx solid rgba(255,255,255,.08);box-shadow:0 1rpx 20rpx rgba(0,0,0,.08)}.brand{display:flex;align-items:center;gap:18rpx}.avatar-wrap{width:64rpx;height:64rpx;border-radius:9999rpx;overflow:hidden;border:1rpx solid rgba(255,255,255,.1);flex-shrink:0}.avatar{width:100%;height:100%}.brand-text{font-size:38rpx;font-weight:800;color:#c19cff}.icon-btn{width:72rpx;height:72rpx;border-radius:9999rpx;background:rgba(255,255,255,.06);display:flex;align-items:center;justify-content:center}.content{height:calc(100vh - 120rpx);padding:40rpx 32rpx 32rpx;box-sizing:border-box}.header{margin-bottom:28rpx}.title{display:block;font-size:52rpx;font-weight:800}.subtitle{display:block;margin-top:10rpx;color:#aaabb0;font-size:26rpx}.search-row{display:flex;flex-direction:column;gap:18rpx;margin-bottom:28rpx}.search-box{display:flex;align-items:center;gap:12rpx;padding:22rpx 26rpx;border-radius:9999rpx;background:#000;border:1rpx solid rgba(255,255,255,.1);color:#aaabb0}.search-placeholder{font-size:24rpx}.filters{display:flex;gap:14rpx;overflow-x:auto}.filter-btn{padding:18rpx 22rpx;border-radius:9999rpx;background:#23262c;color:#f6f6fc;font-size:22rpx;white-space:nowrap}.dim{color:#aaabb0;margin:0 4rpx}.card-grid{display:grid;grid-template-columns:1fr;gap:18rpx}.word-card{position:relative;overflow:hidden;padding:28rpx;border-radius:28rpx;background:rgba(29,32,37,.56);backdrop-filter:blur(24rpx);border:1rpx solid rgba(255,255,255,.06);box-shadow:0 20rpx 40rpx rgba(0,0,0,.06)}.cyan{box-shadow:0 20rpx 40rpx rgba(0,229,255,.05)}.purple{box-shadow:0 20rpx 40rpx rgba(127,0,255,.05)}.pink{box-shadow:0 20rpx 40rpx rgba(255,64,129,.05)}.wide{min-height:280rpx}.card-top{display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:18rpx}.word-title{display:block;font-size:38rpx;font-weight:800}.phonetic{display:block;margin-top:8rpx;font-size:22rpx;color:#aaabb0}.status-dot{width:56rpx;height:56rpx;border-radius:9999rpx;display:flex;align-items:center;justify-content:center;background:rgba(255,255,255,.06)}.done{color:#00e5ff}.learn{color:#c19cff}.review{color:#ff4081}.meaning{display:block;font-size:26rpx;color:#f6f6fc;line-height:1.6}.split{display:grid;grid-template-columns:1fr 1fr;gap:18rpx;align-items:start}.example{font-size:22rpx;color:#aaabb0;font-style:italic;border-left:4rpx solid rgba(193,156,255,.3);padding-left:14rpx;line-height:1.6}.progress-block{margin-top:22rpx;padding-top:18rpx;border-top:1rpx solid rgba(255,255,255,.05)}.progress-meta{display:flex;justify-content:space-between;font-size:20rpx;color:#aaabb0;margin-bottom:10rpx}.accent-cyan{color:#00e5ff}.accent-purple{color:#c19cff}.accent-pink{color:#ff4081}.progress-bar{height:10rpx;border-radius:9999rpx;background:#111318;overflow:hidden}.fill{height:100%;border-radius:9999rpx}.cyan-fill{width:95%;background:#00e5ff}.purple-fill{width:60%;background:#c19cff}.pink-fill{width:30%;background:#ff4081}.fab{position:fixed;right:28rpx;bottom:130rpx;width:96rpx;height:96rpx;border-radius:9999rpx;background:linear-gradient(135deg,#c19cff,#00e5ff);display:flex;align-items:center;justify-content:center;color:#fff;font-size:48rpx;box-shadow:0 0 20rpx rgba(193,156,255,.2)}
|
|
||||||
Loading…
Reference in New Issue
Block a user