修复复习结果页面的内容

This commit is contained in:
taiyi 2026-04-19 16:39:02 +08:00
parent 7aa02ce831
commit 862b4fbe3b
20 changed files with 484 additions and 60 deletions

View File

@ -42,7 +42,14 @@ Page({
source_type: 'manual',
upload_date: new Date().toISOString().slice(0, 10),
},
success: () => wx.showToast({ title: '保存成功', icon: 'success' }),
success: () => {
wx.showToast({ title: '保存成功', icon: 'success' })
this.setData({
enText: '',
zhText: '',
exampleText: '',
})
},
fail: () => this.setData({ error: '保存失败' }),
complete: () => this.setData({ loading: false }),
})

View File

@ -1 +1,187 @@
page{background:#0c0e12;color:#f6f6fc}.page{min-height:100vh;background:#0c0e12;position:relative;overflow-x:hidden;box-sizing:border-box}.ambient-glow{position:absolute;top:0;left:50%;transform:translateX(-50%);width:80vw;max-width:800px;height:400px;background:radial-gradient(circle,rgba(193,156,255,.08) 0%,rgba(12,14,18,0) 70%);pointer-events:none;z-index:0}.topbar{position:relative;z-index:10;display:flex;align-items:center;justify-content:space-between;padding:24rpx 32rpx}.close-btn{width:72rpx;height:72rpx;border-radius:9999rpx;background:#000;color:#aaabb0;display:flex;align-items:center;justify-content:center;border:1rpx solid rgba(255,255,255,.1)}.spacer{width:72rpx;height:72rpx}.content{position:relative;z-index:10;height:calc(100vh - 120rpx);padding:16rpx 32rpx 48rpx;box-sizing:border-box}.header{margin-bottom:40rpx}.title{display:block;font-size:56rpx;font-weight:800;line-height:1.1}.subtitle{display:block;margin-top:10rpx;color:#aaabb0;font-size:26rpx}.segmented{display:flex;width:fit-content;padding:8rpx;background:#000;border:1rpx solid rgba(255,255,255,.1);border-radius:9999rpx;margin-bottom:40rpx;box-shadow:0 4rpx 20rpx rgba(0,0,0,.2)}.seg{padding:18rpx 32rpx;border-radius:9999rpx;color:#aaabb0;font-size:24rpx}.active{background:#1d2025;color:#c19cff;font-weight:700}.form{display:flex;flex-direction:column;gap:28rpx}.field{display:flex;flex-direction:column}.label{font-size:22rpx;color:#aaabb0;font-weight:700;margin:0 0 12rpx 4rpx}.muted{color:rgba(170,171,176,.5);font-weight:400}.input-shell{border-radius:24rpx;background:#000;border:1rpx solid rgba(255,255,255,.1);box-sizing:border-box}.input{width:100%;padding:24rpx 26rpx;font-size:36rpx;color:#f6f6fc;box-sizing:border-box}.small{font-size:28rpx}.textarea-shell{background:#111318}.textarea{width:100%;min-height:220rpx;padding:24rpx 26rpx;font-size:28rpx;color:#f6f6fc;box-sizing:border-box}.action-bar{display:flex;justify-content:flex-end;gap:18rpx;padding-top:28rpx;margin-top:36rpx;border-top:1rpx solid rgba(255,255,255,.05)}.cancel-btn,.save-btn{border-radius:9999rpx;padding:22rpx 34rpx;font-weight:700}.cancel-btn{background:#000;color:#f6f6fc;border:1rpx solid rgba(255,255,255,.1)}.save-btn{background:linear-gradient(90deg,#c19cff,#9146ff);color:#fff}
page {
background: #0c0e12;
color: #f6f6fc
}
.page {
min-height: 100vh;
background: #0c0e12;
position: relative;
overflow-x: hidden;
box-sizing: border-box
}
.ambient-glow {
position: absolute;
top: 0;
left: 50%;
transform: translateX(-50%);
width: 80vw;
max-width: 800px;
height: 400px;
background: radial-gradient(circle, rgba(193, 156, 255, .08) 0%, rgba(12, 14, 18, 0) 70%);
pointer-events: none;
z-index: 0
}
.topbar {
position: relative;
z-index: 10;
display: flex;
align-items: center;
justify-content: space-between;
padding: 24rpx 32rpx
}
.close-btn {
width: 72rpx;
height: 72rpx;
border-radius: 9999rpx;
background: #000;
color: #aaabb0;
display: flex;
align-items: center;
justify-content: center;
border: 1rpx solid rgba(255, 255, 255, .1)
}
.spacer {
width: 72rpx;
height: 72rpx
}
.content {
position: relative;
z-index: 10;
height: calc(100vh - 120rpx);
padding: 16rpx 32rpx 48rpx;
box-sizing: border-box
}
.header {
margin-bottom: 40rpx
}
.title {
display: block;
font-size: 56rpx;
font-weight: 800;
line-height: 1.1
}
.subtitle {
display: block;
margin-top: 10rpx;
color: #aaabb0;
font-size: 26rpx
}
.segmented {
display: flex;
width: fit-content;
padding: 8rpx;
background: #000;
border: 1rpx solid rgba(255, 255, 255, .1);
border-radius: 9999rpx;
margin-bottom: 40rpx;
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, .2)
}
.seg {
padding: 18rpx 32rpx;
border-radius: 9999rpx;
color: #aaabb0;
font-size: 24rpx
}
.active {
background: #1d2025;
color: #c19cff;
font-weight: 700
}
.form {
display: flex;
flex-direction: column;
gap: 28rpx
}
.field {
display: flex;
flex-direction: column
}
.label {
font-size: 22rpx;
color: #aaabb0;
font-weight: 700;
margin: 0 0 12rpx 4rpx
}
.muted {
color: rgba(170, 171, 176, .5);
font-weight: 400
}
.input-shell {
min-height: 92rpx;
border-radius: 24rpx;
background: #000;
border: 1rpx solid rgba(255, 255, 255, .1);
box-sizing: border-box;
display: flex;
align-items: center
}
.input {
width: 100%;
padding: 28rpx 26rpx;
font-size: 30rpx;
color: #f6f6fc;
box-sizing: border-box
}
.small {
font-size: 28rpx
}
.textarea-shell {
background: #111318
}
.textarea {
width: 100%;
min-height: 220rpx;
padding: 24rpx 26rpx;
font-size: 28rpx;
color: #f6f6fc;
box-sizing: border-box
}
.action-bar {
display: flex;
justify-content: flex-end;
gap: 18rpx;
padding-top: 28rpx;
margin-top: 36rpx;
border-top: 1rpx solid rgba(255, 255, 255, .05)
}
.cancel-btn,
.save-btn {
border-radius: 9999rpx;
padding: 22rpx 34rpx;
font-weight: 700
}
.cancel-btn {
background: #000;
color: #f6f6fc;
border: 1rpx solid rgba(255, 255, 255, .1)
}
.save-btn {
background: linear-gradient(90deg, #c19cff, #9146ff);
color: #fff
}

View File

@ -9,11 +9,16 @@ Page({
onShow() {
this.loadStats()
},
loadStats() {
async loadStats() {
this.setData({ loading: true, error: '' })
await app.ensureLogin()
if (!app.globalData.openid) {
this.setData({ error: '登录失败,请稍后重试', loading: false })
return
}
wx.request({
url: `${app.globalData.baseUrl}/api/v1/home/stats`,
header: { 'X-OpenID': app.globalData.openid || '' },
header: { 'X-OpenID': app.globalData.openid },
success: (res) => {
const payload = res.data?.data
if (payload) this.setData({ stats: payload })

View File

@ -1,4 +1,4 @@
page { background:#0c0e12; color:#f6f6fc; }
.page { min-height:100vh; background: radial-gradient(circle at top, rgba(193,156,255,0.15), transparent 30%), #0c0e12; box-sizing:border-box; }
.topbar { position:sticky; top:0; z-index:20; display:flex; justify-content:space-between; align-items:center; padding:24rpx 32rpx; background:rgba(255,255,255,.8); backdrop-filter:blur(24px); border-bottom:1rpx solid rgba(255,255,255,.2); box-shadow:0 1rpx 20rpx rgba(0,0,0,.08); }
.brand,.streak-left{display:flex;align-items:center;gap:20rpx}.avatar-wrap{width:80rpx;height:80rpx;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:40rpx;font-weight:900;background:linear-gradient(90deg,#6366f1,#22d3ee);-webkit-background-clip:text;color:transparent}.icon-btn{color:#6366f1;width:72rpx;height:72rpx;border-radius:9999rpx;display:flex;align-items:center;justify-content:center;background:rgba(255,255,255,.4)}.content{height:calc(100vh - 120rpx);padding:40rpx 32rpx 140rpx;box-sizing:border-box}.greeting{display:flex;flex-direction:column;gap:8rpx;margin-bottom:32rpx}.title{display:block;font-size:56rpx;font-weight:800;color:#fff}.subtitle{display:block;font-size:30rpx;color:#aaabb0}.grid-layout{display:grid;grid-template-columns:1fr;gap:24rpx}.hero-card{position:relative;overflow:hidden;min-height:280rpx;padding:32rpx;border-radius:24rpx;background:rgba(29,32,37,.6);backdrop-filter:blur(24px);border:1rpx solid rgba(255,255,255,.1);box-shadow:0 20rpx 40rpx rgba(0,0,0,.4)}.hero-overlay{position:absolute;inset:0;background:linear-gradient(135deg,rgba(193,156,255,.05),rgba(0,227,253,.05));z-index:0}.hero-row,.hero-grid{position:relative;z-index:1}.hero-row{display:flex;justify-content:space-between;align-items:flex-start}.hero-number{display:block;font-size:72rpx;font-weight:800;color:#fff;line-height:1}.hero-icon{width:96rpx;height:96rpx;border-radius:9999rpx;background:rgba(255,255,255,.08);display:flex;align-items:center;justify-content:center;font-size:44rpx;border:1rpx solid rgba(255,255,255,.05)}.label{display:block;margin-top:8rpx;font-size:24rpx;color:#aaabb0}.hero-grid{display:grid;grid-template-columns:1fr 1fr;gap:18rpx;margin-top:44rpx}.metric-card{padding:24rpx;border-radius:20rpx;background:rgba(0,0,0,.15);border:1rpx solid rgba(255,255,255,.05)}.metric-value{display:block;font-size:44rpx;font-weight:800;color:#fff}.metric-value.accent{color:#00e3fd}.small{font-size:20rpx}.stack{display:flex;flex-direction:column;gap:24rpx}.streak-card{padding:28rpx;border-radius:24rpx;background:#111318;border:1rpx solid rgba(255,255,255,.1);box-shadow:0 20rpx 40rpx rgba(0,0,0,.4)}.streak-head{display:flex;justify-content:space-between;align-items:center}.fire{width:80rpx;height:80rpx;border-radius:9999rpx;background:#171a1f;display:flex;align-items:center;justify-content:center;border:1rpx solid rgba(255,255,255,.05)}.streak-title{font-size:30rpx;font-weight:700;color:#fff}.streak-goal{font-size:24rpx;color:#00e3fd;font-weight:500}.progress-bar{height:12rpx;background:#23262c;border-radius:9999rpx;overflow:hidden;margin-top:18rpx}.progress-fill{width:71%;height:100%;background:linear-gradient(90deg,#c19cff,#00e3fd);position:relative}.progress-fill::after{content:'';position:absolute;inset:0;background:rgba(255,255,255,.2)}.week-row{display:flex;justify-content:space-between;margin-top:10rpx;font-size:22rpx;color:#aaabb0}.day.active{color:#00e3fd;font-weight:700}.actions{display:flex;flex-direction:column;gap:18rpx;margin-top:4rpx}.primary-btn,.secondary-btn{width:100%;padding:26rpx 0;border-radius:9999rpx;font-size:32rpx;font-weight:800}.primary-btn{background:linear-gradient(90deg,#c19cff,#9146ff);color:#fff;box-shadow:0 0 20rpx rgba(193,156,255,.3)}.secondary-btn{background:#23262c;color:#fff;border:1rpx solid rgba(255,255,255,.08)}.bottom-nav{position:fixed;left:0;right:0;bottom:0;z-index:30;display:flex;justify-content:space-around;align-items:center;padding:20rpx 24rpx 40rpx;background:rgba(255,255,255,.7);backdrop-filter:blur(24px);border-top-left-radius:32rpx;border-top-right-radius:32rpx;box-shadow:0 -10rpx 40rpx rgba(0,0,0,.1)}.nav-item{display:flex;flex-direction:column;align-items:center;color:#aaabb0}.nav-item.active{color:#00e3fd;transform:translateY(-6rpx)}.nav-icon{width:56rpx;height:56rpx;border-radius:9999rpx;background:rgba(255,255,255,.05);display:flex;align-items:center;justify-content:center;font-size:26rpx}.nav-label{font-size:20rpx}
.brand,.streak-left{display:flex;align-items:center;gap:20rpx}.avatar-wrap{width:80rpx;height:80rpx;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:40rpx;font-weight:900;background:linear-gradient(90deg,#6366f1,#22d3ee);-webkit-background-clip:text;color:transparent}.icon-btn{color:#6366f1;width:72rpx;height:72rpx;border-radius:9999rpx;display:flex;align-items:center;justify-content:center;background:rgba(255,255,255,.4)}.content{height:calc(100vh - 120rpx);padding:40rpx 32rpx 160rpx;box-sizing:border-box}.greeting{display:flex;flex-direction:column;gap:8rpx;margin-bottom:32rpx}.title{display:block;font-size:56rpx;font-weight:800;color:#fff}.subtitle{display:block;font-size:30rpx;color:#aaabb0}.grid-layout{display:grid;grid-template-columns:1fr;gap:24rpx}.hero-card{position:relative;overflow:hidden;min-height:280rpx;padding:32rpx;border-radius:24rpx;background:rgba(29,32,37,.6);backdrop-filter:blur(24rpx);border:1rpx solid rgba(255,255,255,.1);box-shadow:0 20rpx 40rpx rgba(0,0,0,.4)}.hero-overlay{position:absolute;inset:0;background:linear-gradient(135deg,rgba(193,156,255,.05),rgba(0,227,253,.05));z-index:0}.hero-row,.hero-grid{position:relative;z-index:1}.hero-row{display:flex;justify-content:space-between;align-items:flex-start}.hero-number{display:block;font-size:72rpx;font-weight:800;color:#fff;line-height:1}.hero-icon{width:96rpx;height:96rpx;border-radius:9999rpx;background:rgba(255,255,255,.08);display:flex;align-items:center;justify-content:center;font-size:44rpx;border:1rpx solid rgba(255,255,255,.05)}.label{display:block;margin-top:8rpx;font-size:24rpx;color:#aaabb0}.hero-grid{display:grid;grid-template-columns:1fr 1fr;gap:18rpx;margin-top:44rpx}.metric-card{padding:24rpx;border-radius:20rpx;background:rgba(0,0,0,.15);border:1rpx solid rgba(255,255,255,.05)}.metric-value{display:block;font-size:44rpx;font-weight:800;color:#fff}.metric-value.accent{color:#00e3fd}.small{font-size:20rpx}.stack{display:flex;flex-direction:column;gap:24rpx}.streak-card{padding:28rpx;border-radius:24rpx;background:#111318;border:1rpx solid rgba(255,255,255,.1);box-shadow:0 20rpx 40rpx rgba(0,0,0,.4)}.streak-head{display:flex;justify-content:space-between;align-items:center}.fire{width:80rpx;height:80rpx;border-radius:9999rpx;background:#171a1f;display:flex;align-items:center;justify-content:center;border:1rpx solid rgba(255,255,255,.05)}.streak-title{font-size:30rpx;font-weight:700;color:#fff}.streak-goal{font-size:24rpx;color:#00e3fd;font-weight:500}.progress-bar{height:12rpx;background:#23262c;border-radius:9999rpx;overflow:hidden;margin-top:18rpx}.progress-fill{width:71%;height:100%;background:linear-gradient(90deg,#c19cff,#00e3fd);position:relative}.progress-fill::after{content:'';position:absolute;inset:0;background:rgba(255,255,255,.2)}.week-row{display:flex;justify-content:space-between;margin-top:10rpx;font-size:22rpx;color:#aaabb0}.day.active{color:#00e3fd;font-weight:700}.actions{display:flex;flex-direction:column;gap:18rpx;margin-top:4rpx}.primary-btn,.secondary-btn{width:100%;padding:26rpx 0;border-radius:9999rpx;font-size:32rpx;font-weight:800}.primary-btn{background:linear-gradient(90deg,#c19cff,#9146ff);color:#fff;box-shadow:0 0 20rpx rgba(193,156,255,.3)}.secondary-btn{background:#23262c;color:#fff;border:1rpx solid rgba(255,255,255,.08)}.bottom-nav{position:fixed;left:0;right:0;bottom:0;z-index:30;display:flex;justify-content:space-around;align-items:center;padding:20rpx 24rpx 40rpx;background:rgba(12,14,18,.7);backdrop-filter:blur(32rpx);border-top-left-radius:32rpx;border-top-right-radius:32rpx;box-shadow:0 -10rpx 40rpx rgba(0,0,0,.4);border-top:1rpx solid rgba(255,255,255,.08)}.nav-item{display:flex;flex-direction:column;align-items:center;color:#6b7280;opacity:.8}.nav-item.active{color:#66dff3;transform:translateY(-6rpx);filter:drop-shadow(0 0 10rpx rgba(34,211,238,.8))}.nav-icon{width:56rpx;height:56rpx;border-radius:9999rpx;background:rgba(255,255,255,.04);display:flex;align-items:center;justify-content:center;font-size:26rpx}.nav-label{font-size:20rpx;font-weight:600;letter-spacing:.08em;text-transform:uppercase}

View File

@ -48,6 +48,10 @@ Page({
wx.navigateTo({ url })
},
goHome() {
wx.switchTab({ url: '/pages/index/index' })
wx.reLaunch({ url: '/pages/index/index' })
},
goToReview() {
wx.navigateTo({ url: '/pages/review-config/review-config' })
},
goToMe() {},
})

View File

@ -76,4 +76,10 @@
<view class="chevron"></view>
</view>
</scroll-view>
<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="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>
</view>

File diff suppressed because one or more lines are too long

View File

@ -1,8 +1,16 @@
<view class="page">
<view class="bg-orb bg-orb-right"></view>
<view class="bg-orb bg-orb-left"></view>
<scroll-view scroll-y class="content">
<view class="header">
<text class="title">进度列表</text>
<text class="subtitle">查看每个词条的掌握程度。</text>
<text class="title">复习档案</text>
<text class="subtitle">您的词汇神经元网络正在构建中。</text>
</view>
<view class="tabs">
<view class="tab tab-active">待复习</view>
<view class="tab">已掌握</view>
</view>
<view wx:if="{{loading}}" class="empty-state">
@ -15,36 +23,54 @@
</view>
<view wx:else>
<view class="section-title">待复习</view>
<view class="list" wx:if="{{reviewList.length}}">
<view class="grid">
<block wx:for="{{reviewList}}" wx:key="id">
<view class="row">
<view class="card card-pink">
<view class="card-glow card-glow-pink"></view>
<view class="card-head">
<view>
<text class="word">{{item.en_text}}</text>
<text class="desc">{{item.zh_text}}</text>
<text class="word word-large">{{item.en_text}}</text>
<text class="desc desc-spaced">{{item.zh_text}}</text>
</view>
<text class="percent pink">{{item.mastery_score}}%</text>
</view>
</block>
</view>
<view wx:else class="empty-state small">
<text class="empty-title">暂无待复习内容</text>
<view class="badge badge-pink">🔥</view>
</view>
<view class="section-title">已掌握</view>
<view class="list" wx:if="{{masteredList.length}}">
<block wx:for="{{masteredList}}" wx:key="id">
<view class="row">
<view>
<text class="word">{{item.en_text}}</text>
<text class="desc">{{item.zh_text}}</text>
<view class="progress-meta">
<text class="progress-label">神经元连接强度</text>
<text class="progress-value progress-pink">{{item.mastery_score}}%</text>
</view>
<text class="percent cyan">{{item.mastery_score}}%</text>
<view class="progress-track">
<view class="progress-fill progress-fill-pink" style="width: {{item.mastery_score}}%;"></view>
</view>
<view class="action-btn">移至已掌握</view>
</view>
</block>
<block wx:for="{{masteredList}}" wx:key="id">
<view class="card card-cyan">
<view class="card-glow card-glow-cyan"></view>
<view class="card-head">
<view>
<text class="word word-large">{{item.en_text}}</text>
<text class="desc desc-spaced">{{item.zh_text}}</text>
</view>
<view class="badge badge-cyan">✓</view>
</view>
<view class="progress-meta">
<text class="progress-label">神经元连接强度</text>
<text class="progress-value progress-cyan">{{item.mastery_score}}%</text>
</view>
<view class="progress-track">
<view class="progress-fill progress-fill-cyan" style="width: {{item.mastery_score}}%;"></view>
</view>
<view class="action-btn">移至已掌握</view>
</view>
</block>
</view>
<view wx:else class="empty-state small">
<text class="empty-title">暂无已掌握内容</text>
<view wx:if="{{!reviewList.length && !masteredList.length}}" class="empty-state small">
<text class="empty-title">暂无进度内容</text>
</view>
</view>
</scroll-view>

View File

@ -1 +1 @@
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;box-sizing:border-box}.header{margin-bottom:24rpx}.title{display:block;font-size:52rpx;font-weight:800}.subtitle{display:block;margin-top:10rpx;color:#aaabb0;font-size:24rpx}.list{background:rgba(29,32,37,.56);border:1rpx solid rgba(255,255,255,.08);border-radius:28rpx;overflow:hidden}.row{display:flex;justify-content:space-between;align-items:center;padding:24rpx 22rpx;border-bottom:1rpx solid rgba(255,255,255,.06)}.row:last-child{border-bottom:none}.word{display:block;font-size:30rpx;font-weight:700}.desc{display:block;margin-top:6rpx;color:#aaabb0;font-size:22rpx}.percent{font-size:32rpx;font-weight:800}.cyan{color:#00e5ff}.purple{color:#c19cff}.pink{color:#ff4081}
page{background:#0c0e12;color:#f6f6fc}.page{min-height:100vh;background:#0c0e12;box-sizing:border-box;position:relative;overflow:hidden}.bg-orb{position:absolute;border-radius:9999rpx;filter:blur(120rpx);pointer-events:none;z-index:0}.bg-orb-right{width:40vw;height:40vw;top:-10vw;right:-10vw;background:rgba(193,156,255,.08)}.bg-orb-left{width:50vw;height:50vw;left:-15vw;bottom:-15vw;background:rgba(0,227,253,.06)}.content{height:100vh;padding:40rpx 32rpx;box-sizing:border-box;position:relative;z-index:1}.header{margin-bottom:28rpx}.title{display:block;font-size:56rpx;line-height:1.1;font-weight:800;letter-spacing:-1rpx}.subtitle{display:block;margin-top:10rpx;color:#aaabb0;font-size:24rpx;line-height:1.5}.tabs{display:flex;gap:16rpx;padding:6rpx;border:1rpx solid rgba(255,255,255,.05);background:rgba(23,26,31,.7);border-radius:9999rpx;width:max-content;box-shadow:0 8rpx 30rpx rgba(0,0,0,.12);margin-bottom:34rpx}.tab{padding:18rpx 34rpx;border-radius:9999rpx;color:#aaabb0;font-size:24rpx;font-weight:600}.tab-active{background:#1d2025;color:#c19cff;box-shadow:0 0 24rpx rgba(193,156,255,.22)}.grid{display:flex;flex-direction:column;gap:24rpx}.card{position:relative;overflow:hidden;padding:30rpx;background:rgba(29,32,37,.56);border:1rpx solid rgba(255,255,255,.08);border-radius:32rpx;box-shadow:0 16rpx 60rpx rgba(0,0,0,.12)}.card-glow{position:absolute;right:-40rpx;top:-40rpx;width:180rpx;height:180rpx;border-radius:9999rpx;filter:blur(30rpx);opacity:.35}.card-glow-pink{background:rgba(255,108,149,.5)}.card-glow-cyan{background:rgba(0,227,253,.45)}.card-head{display:flex;justify-content:space-between;align-items:flex-start;gap:20rpx;margin-bottom:18rpx}.word{display:block;font-weight:800;line-height:1.1}.word-large{font-size:48rpx;letter-spacing:-1rpx}.desc{display:block;color:#aaabb0;font-size:22rpx}.desc-spaced{margin-top:10rpx}.badge{width:80rpx;height:80rpx;border-radius:9999rpx;display:flex;align-items:center;justify-content:center;background:rgba(255,255,255,.04);border:1rpx solid rgba(255,255,255,.05);flex-shrink:0;font-size:28rpx}.badge-pink{color:#ff6c95}.badge-cyan{color:#00e3fd}.progress-meta{display:flex;justify-content:space-between;align-items:flex-end;margin-bottom:14rpx}.progress-label{font-size:20rpx;color:#aaabb0;letter-spacing:1rpx}.progress-value{font-size:28rpx;font-weight:800}.progress-pink{color:#ff6c95}.progress-cyan{color:#00e3fd}.progress-track{width:100%;height:8rpx;background:#23262c;border-radius:9999rpx;overflow:hidden;box-shadow:inset 0 0 0 1rpx rgba(255,255,255,.03);margin-bottom:20rpx}.progress-fill{height:100%;border-radius:9999rpx}.progress-fill-pink{background:linear-gradient(90deg,#ff769b,#ff6c95);box-shadow:0 0 20rpx rgba(255,108,149,.5)}.progress-fill-cyan{background:linear-gradient(90deg,#c19cff,#00e3fd);box-shadow:0 0 20rpx rgba(0,227,253,.45)}.action-btn{width:100%;padding:22rpx 0;border-radius:9999rpx;background:#1d2025;border:1rpx solid rgba(255,255,255,.05);color:#aaabb0;font-size:24rpx;font-weight:600;text-align:center}.empty-state{padding:60rpx 20rpx;text-align:center;color:#aaabb0}.empty-state.small{padding:40rpx 20rpx}.empty-title{display:block;font-size:28rpx;font-weight:700;color:#f6f6fc}.empty-subtitle{display:block;margin-top:10rpx;font-size:22rpx;color:#aaabb0}.error-banner{padding:24rpx 28rpx;border-radius:20rpx;background:rgba(167,1,56,.2);border:1rpx solid rgba(255,110,132,.35)}.error-text{color:#ffb2b9;font-size:24rpx}.cyan{color:#00e5ff}.purple{color:#c19cff}.pink{color:#ff4081}

View File

@ -92,4 +92,11 @@ Page({
complete: () => this.setData({ loading: false }),
})
},
goHome() {
wx.reLaunch({ url: '/pages/index/index' })
},
goToReview() {},
goToMe() {
wx.navigateTo({ url: '/pages/me/me' })
},
})

View File

@ -36,4 +36,10 @@
<button class="start-btn" bindtap="startReview">开始复习</button>
</scroll-view>
<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 active"><text class="nav-icon">📖</text><text class="nav-label">复习</text></view>
<view class="nav-item" bindtap="goToMe"><text class="nav-icon">☺</text><text class="nav-label">我的</text></view>
</view>
</view>

View File

@ -1,5 +1,26 @@
page { background:#0c0e12; color:#f6f6fc; }
.page { min-height:100vh; background:#0c0e12; }
.topbar { position:sticky; top:0; z-index:10; 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); }
.brand{display:flex;align-items:center;gap:20rpx}.avatar-wrap{width:80rpx;height:80rpx;border-radius:9999rpx;overflow:hidden;flex-shrink:0}.avatar{width:100%;height:100%}.brand-text{font-size:40rpx;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}
.config-content{height:calc(100vh - 120rpx);padding:32rpx;box-sizing:border-box}.heading{margin:16rpx 0 24rpx}.title{display:block;font-size:52rpx;font-weight:800}.subtitle{display:block;margin-top:10rpx;font-size:28rpx;color:#aaabb0;line-height:1.6}.config-card{margin-top:24rpx;padding:28rpx;border-radius:28rpx;background:rgba(29,32,37,.65);border:1rpx solid rgba(255,255,255,.08)}.section-title{display:block;font-size:32rpx;font-weight:700;margin-bottom:20rpx}.chip-row{display:flex;flex-wrap:wrap;gap:16rpx}.chip{padding:18rpx 28rpx;border-radius:9999rpx;background:#23262c;color:#aaabb0}.chip.active{background:#c19cff;color:#000}.two-grid{display:grid;grid-template-columns:1fr 1fr;gap:18rpx}.option-box,.mode-item{padding:24rpx;border-radius:24rpx;background:#111318;border:1rpx solid rgba(255,255,255,.08);text-align:center;color:#aaabb0;min-height:96rpx;display:flex;align-items:center;justify-content:center}.option-box.active,.mode-item.active{color:#c19cff;border-color:#c19cff}.mode-list{display:flex;flex-direction:column;gap:18rpx}.switch-row,.range-row{display:flex;justify-content:space-between;align-items:center;padding:12rpx 0}.switch{padding:6rpx 16rpx;border-radius:9999rpx;background:#23262c;color:#aaabb0}.switch.on{background:#c19cff;color:#000}.accent{color:#c19cff;font-weight:700}.range-bar{height:12rpx;border-radius:9999rpx;background:#23262c;overflow:hidden}.range-fill{width:30%;height:100%;background:linear-gradient(90deg,#c19cff,#00e3fd)}.start-btn{margin:32rpx 0 48rpx;padding:28rpx 0;border-radius:9999rpx;background:linear-gradient(90deg,#c19cff,#9146ff);color:#fff;font-size:34rpx;font-weight:800;box-shadow:0 0 20rpx rgba(193,156,255,.28)}
.page { min-height:100vh; background:#0c0e12; box-sizing:border-box; }
.content { height:calc(100vh - 120rpx); padding:32rpx; box-sizing:border-box; }
.config-content { padding-bottom:180rpx; }
.heading { margin:16rpx 0 24rpx; }
.title { display:block; font-size:52rpx; font-weight:800; }
.subtitle { display:block; margin-top:10rpx; font-size:28rpx; color:#aaabb0; line-height:1.6; }
.config-card { margin-top:24rpx; padding:28rpx; border-radius:28rpx; background:rgba(29,32,37,.65); border:1rpx solid rgba(255,255,255,.08); }
.section-title { display:block; font-size:32rpx; font-weight:700; margin-bottom:20rpx; }
.chip-row { display:flex; flex-wrap:wrap; gap:16rpx; }
.chip { padding:18rpx 28rpx; border-radius:9999rpx; background:#23262c; color:#aaabb0; }
.chip.active { background:#c19cff; color:#000; }
.two-grid { display:grid; grid-template-columns:1fr 1fr; gap:18rpx; }
.option-box, .mode-item { padding:24rpx; border-radius:24rpx; background:#111318; border:1rpx solid rgba(255,255,255,.08); text-align:center; color:#aaabb0; min-height:96rpx; display:flex; align-items:center; justify-content:center; }
.option-box.active, .mode-item.active { color:#c19cff; border-color:#c19cff; }
.mode-list { display:flex; flex-direction:column; gap:18rpx; }
.switch-row, .range-row { display:flex; justify-content:space-between; align-items:center; padding:12rpx 0; }
.switch { padding:6rpx 16rpx; border-radius:9999rpx; background:#23262c; color:#aaabb0; }
.switch.on { background:#c19cff; color:#000; }
.accent { color:#c19cff; font-weight:700; }
.start-btn { margin:32rpx 0 48rpx; padding:28rpx 0; border-radius:9999rpx; background:linear-gradient(90deg,#c19cff,#9146ff); color:#fff; font-size:34rpx; font-weight:800; box-shadow:0 0 20rpx rgba(193,156,255,.28); }
.bottom-nav { position:fixed; left:0; right:0; bottom:0; z-index:50; display:flex; justify-content:space-around; align-items:center; padding:20rpx 24rpx 40rpx; background:rgba(12,14,18,.7); backdrop-filter:blur(32rpx); border-top:1rpx solid rgba(255,255,255,.08); border-radius:32rpx 32rpx 0 0; box-shadow:0 -10rpx 40rpx rgba(0,0,0,.4); }
.nav-item { display:flex; flex-direction:column; align-items:center; gap:6rpx; color:#aaabb0; }
.nav-item.active { color:#00e3fd; transform:translateY(-6rpx); }
.nav-icon { width:56rpx; height:56rpx; border-radius:9999rpx; background:rgba(255,255,255,.05); display:flex; align-items:center; justify-content:center; }
.nav-label { font-size:20rpx; }

View File

@ -7,6 +7,8 @@ Page({
total: 0,
mastered: 0,
reviewNeeded: 0,
improved: 0,
regressed: 0,
loading: false,
error: '',
},
@ -15,7 +17,8 @@ Page({
},
loadResult() {
const sessionId = app.globalData.reviewSessionMeta?.id
if (!sessionId) {
const fallbackSession = app.globalData.reviewSession
if (!sessionId && !fallbackSession?.completed) {
this.setData({ error: '暂无复习结果' })
return
}
@ -24,7 +27,20 @@ Page({
url: `${app.globalData.baseUrl}/api/v1/review-result?session_id=${sessionId}`,
header: { 'X-OpenID': app.globalData.openid || '' },
success: (res) => {
this.setData(res.data?.data || {})
const data = res.data?.data || {}
const total = Number(data.total || 0)
const correct = Number(data.correct || 0)
const wrong = Number(data.wrong || Math.max(0, total - correct))
const accuracy = total ? Math.round((correct / total) * 100) : 0
this.setData({
total,
accuracy,
mastered: Number(data.mastered ?? correct),
reviewNeeded: Number(data.review_needed ?? wrong),
improved: Number(data.improved ?? 0),
regressed: Number(data.regressed ?? 0),
timeUsed: data.time_used || '--:--',
})
},
fail: () => this.setData({ error: '结果加载失败' }),
complete: () => this.setData({ loading: false }),

View File

@ -50,6 +50,14 @@
<text class="break-num pink">{{reviewNeeded}}</text>
<text class="break-label">需加强</text>
</view>
<view class="break-item">
<text class="break-num green">{{improved}}</text>
<text class="break-label">进步题目</text>
</view>
<view class="break-item">
<text class="break-num amber">{{regressed}}</text>
<text class="break-label">退步题目</text>
</view>
</view>
</view>

View File

@ -1,5 +1,15 @@
const app = getApp()
const getReviewSettings = () => {
const settings = app.globalData.userSettings || {}
return {
autoNextQuestion: Number(settings.auto_next_question || 0) === 1,
showAnswerAfterSubmit: Number(settings.show_answer_after_submit || 0) === 1,
blankCount: Number(settings.blank_count || 2),
blankDifficulty: settings.blank_difficulty || 'normal',
}
}
Page({
data: {
progress: 0,
@ -9,16 +19,40 @@ Page({
meaning: '',
answer: '',
feedback: '',
revealAnswer: '',
feedbackType: '',
showFeedback: false,
completed: false,
masterHint: false,
questions: [],
loading: false,
error: '',
settings: getReviewSettings(),
},
submitting: false,
judged: false,
onLoad() {
this.loadSettingsAndQuestions()
},
loadSettingsAndQuestions() {
if (!app.globalData.openid) {
this.setData({ error: '请先登录' })
return
}
wx.request({
url: `${app.globalData.baseUrl}/api/v1/settings`,
header: { 'X-OpenID': app.globalData.openid },
success: (res) => {
app.globalData.userSettings = res.data?.data || {}
this.setData({ settings: getReviewSettings() })
this.loadQuestions()
},
fail: () => {
this.setData({ error: '设置加载失败' })
this.loadQuestions()
},
})
},
loadQuestions() {
const session = app.globalData.reviewSessionMeta
if (!session) {
@ -30,8 +64,24 @@ Page({
url: `${app.globalData.baseUrl}/api/v1/review/questions?session_id=${session.id}`,
header: { 'X-OpenID': app.globalData.openid || '' },
success: (res) => {
const questions = res.data?.data || []
app.globalData.reviewSession = { deck: questions, currentIndex: 0, correctCount: 0, wrongCount: 0, completed: false, currentAnswer: '' }
const questions = (res.data?.data || []).map((item) => {
if (item.question_mode === 'C') {
return {
...item,
blank_prompt: item.blank_prompt || item.prompt,
}
}
return item
})
app.globalData.reviewSession = {
deck: questions,
currentIndex: 0,
correctCount: 0,
wrongCount: 0,
completed: false,
currentAnswer: '',
startedAt: Date.now(),
}
this.setData({ questions })
this.syncSession()
},
@ -47,10 +97,12 @@ Page({
progress: Math.round((session.currentIndex / total) * 100),
current: session.currentIndex + 1,
total,
word: current?.prompt || '',
meaning: current?.answer_hint || '',
word: current?.question_mode === 'C' ? (current?.blank_prompt || current?.prompt || '') : (current?.prompt || ''),
meaning: current?.question_mode === 'C' ? (current?.answer_hint || '') : '',
answer: session.currentAnswer || '',
feedback: '',
revealAnswer: '',
feedbackType: '',
showFeedback: false,
completed: session.completed,
masterHint: false,
@ -59,12 +111,20 @@ Page({
onAnswerInput(e) {
const answer = e.detail.value
app.globalData.reviewSession.currentAnswer = answer
this.setData({ answer })
this.setData({ answer, showFeedback: false, revealAnswer: '', feedback: '', feedbackType: '', judged: false })
},
checkAnswer() {
submitAnswer(showExplanation = false) {
const session = app.globalData.reviewSession
const current = session.deck[session.currentIndex]
if (!current) return
if (!current || this.submitting || this.judged) return
const answer = (this.data.answer || '').trim()
if (!answer) {
wx.showToast({ title: '请先输入答案', icon: 'none' })
return
}
this.submitting = true
wx.request({
url: `${app.globalData.baseUrl}/api/v1/review/submit`,
method: 'POST',
@ -73,24 +133,43 @@ Page({
session_id: app.globalData.reviewSessionMeta.id,
entry_id: current.entry_id,
question_mode: current.question_mode,
user_answer: this.data.answer,
user_answer: answer,
},
success: (res) => {
const result = res.data?.data || {}
session.correctCount += result.is_correct ? 1 : 0
session.wrongCount += result.is_correct ? 0 : 1
this.judged = true
const shouldShowAnswer = showExplanation || this.data.settings.showAnswerAfterSubmit
this.setData({
feedback: result.is_correct ? '回答正确' : `正确答案:${result.correct_answer}`,
feedback: result.is_correct ? '回答正确' : '回答错误',
feedbackType: result.is_correct ? 'correct' : 'wrong',
revealAnswer: shouldShowAnswer ? `正确答案:${result.correct_answer}` : '',
showFeedback: true,
})
if (this.data.settings.autoNextQuestion) {
setTimeout(() => this.nextQuestion(), shouldShowAnswer ? 1200 : 0)
}
},
complete: () => {
this.submitting = false
},
})
},
checkAnswer() {
this.submitAnswer(true)
},
nextQuestion() {
const session = app.globalData.reviewSession
if (!session.deck.length) return
if (!this.judged) {
wx.showToast({ title: '请先提交答案', icon: 'none' })
return
}
this.judged = false
if (session.currentIndex >= session.deck.length - 1) {
session.completed = true
session.endedAt = Date.now()
wx.request({
url: `${app.globalData.baseUrl}/api/v1/review/finish?session_id=${app.globalData.reviewSessionMeta.id}`,
method: 'POST',

View File

@ -16,7 +16,7 @@
<view wx:else class="glass-card question-card ghost-border">
<view class="ambient-glow"></view>
<view class="mode-tag">{{questions[current-1].question_mode || 'C'}}</view>
<view class="meaning-wrap">
<view class="meaning-wrap" wx:if="{{meaning}}">
<text class="meaning">{{meaning}}</text>
</view>
@ -30,7 +30,10 @@
<view class="input-shell">
<input class="answer" value="{{answer}}" placeholder="输入答案..." bindinput="onAnswerInput" />
</view>
<view wx:if="{{showFeedback}}" class="feedback">{{feedback}}</view>
<view wx:if="{{showFeedback}}" class="feedback-box {{feedbackType}}">
<text class="feedback">{{feedback}}</text>
<text wx:if="{{revealAnswer}}" class="reveal-answer">{{revealAnswer}}</text>
</view>
</view>
<view wx:if="{{questions.length}}" class="actions-cluster">

View File

@ -1,14 +1,31 @@
const app = getApp()
const difficultyOptions = [
{ label: '简单', value: 'easy' },
{ label: '普通', value: 'normal' },
{ label: '困难', value: 'hard' },
]
Page({
data: {
settings: null,
loading: false,
error: '',
difficultyOptions,
difficultyIndex: 1,
difficultyLabel: '普通',
},
onShow() {
this.loadSettings()
},
syncDerivedState(settings) {
const difficultyIndex = Math.max(0, difficultyOptions.findIndex((item) => item.value === settings.blank_difficulty))
this.setData({
settings,
difficultyIndex: difficultyIndex >= 0 ? difficultyIndex : 1,
difficultyLabel: difficultyOptions[difficultyIndex >= 0 ? difficultyIndex : 1].label,
})
},
loadSettings() {
if (!app.globalData.openid) {
this.setData({ error: '请先登录' })
@ -19,12 +36,39 @@ Page({
url: `${app.globalData.baseUrl}/api/v1/settings`,
header: { 'X-OpenID': app.globalData.openid },
success: (res) => {
this.setData({ settings: res.data?.data || null })
this.syncDerivedState(res.data?.data || null)
},
fail: () => this.setData({ error: '设置加载失败' }),
complete: () => this.setData({ loading: false }),
})
},
onBlankCountInput(e) {
const value = Number(e.detail.value || 0)
this.setData({
settings: {
...this.data.settings,
blank_count: Number.isFinite(value) ? value : 0,
},
})
},
onDifficultyChange(e) {
const index = Number(e.detail.value)
const option = difficultyOptions[index] || difficultyOptions[1]
this.setData({
difficultyIndex: index,
difficultyLabel: option.label,
settings: {
...this.data.settings,
blank_difficulty: option.value,
},
})
},
toggleSetting(e) {
const key = e.currentTarget.dataset.key
const settings = { ...this.data.settings }
settings[key] = settings[key] ? 0 : 1
this.setData({ settings })
},
save() {
if (!app.globalData.openid) {
wx.showToast({ title: '请先登录', icon: 'none' })

View File

@ -22,11 +22,17 @@
<view class="panel">
<view class="row">
<view><text class="label">挖空数量</text><text class="desc">题型 C 中每题挖空的词数</text></view>
<view class="value-group"><text class="value">{{settings.blank_count}}</text></view>
<view class="value-group">
<input class="setting-input" type="number" value="{{settings.blank_count}}" bindinput="onBlankCountInput" />
</view>
</view>
<view class="row">
<view><text class="label">挖空难度</text><text class="desc">影响挖空比例与保留字母</text></view>
<view class="value-group"><text class="value accent">{{settings.blank_difficulty}}</text></view>
<view class="value-group">
<picker mode="selector" range="{{difficultyOptions}}" range-key="label" value="{{difficultyIndex}}" bindchange="onDifficultyChange">
<view class="picker-value accent">{{difficultyLabel}}</view>
</picker>
</view>
</view>
</view>
</view>
@ -37,11 +43,11 @@
<text class="section-title">交互设置</text>
</view>
<view class="panel">
<view class="row">
<view class="row" bindtap="toggleSetting" data-key="auto_next_question">
<view><text class="label">自动进入下一词</text><text class="desc">答题后自动跳转,保持心流状态</text></view>
<view class="toggle {{settings.auto_next_question ? 'on' : ''}}">{{settings.auto_next_question ? 'ON' : 'OFF'}}</view>
</view>
<view class="row">
<view class="row" bindtap="toggleSetting" data-key="show_answer_after_submit">
<view><text class="label">提交后显示答案</text><text class="desc">答题后直接显示正确答案</text></view>
<view class="toggle {{settings.show_answer_after_submit ? 'on' : ''}}">{{settings.show_answer_after_submit ? 'ON' : 'OFF'}}</view>
</view>

View File

@ -1 +1 @@
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)}.topbar-left,.topbar-right{display:flex;align-items:center;gap:18rpx}.back-btn{width:72rpx;height:72rpx;border-radius:9999rpx;background:#000;color:#aaabb0;display:flex;align-items:center;justify-content:center;border:1rpx solid rgba(255,255,255,.1)}.brand-text{font-size:38rpx;font-weight:800;color:#c19cff}.topbar-icon{font-size:30rpx;color:#aaabb0}.avatar-shell{width:64rpx;height:64rpx;border-radius:9999rpx;overflow:hidden;border:1rpx solid rgba(255,255,255,.1)}.avatar-img{width:100%;height:100%}.content{height:calc(100vh - 120rpx);padding:40rpx 32rpx 32rpx;box-sizing:border-box}.header{margin-bottom:32rpx}.title{display:block;font-size:56rpx;font-weight:800;line-height:1.1}.subtitle{display:block;margin-top:10rpx;color:#aaabb0;font-size:26rpx}.section-block{margin-top:28rpx}.section-head{display:flex;align-items:center;gap:14rpx;margin-bottom:18rpx}.section-ico{width:76rpx;height:76rpx;border-radius:9999rpx;background:rgba(255,255,255,.06);display:flex;align-items:center;justify-content:center;font-size:30rpx}.section-title{font-size:32rpx;font-weight:800}.panel{position:relative;padding:8rpx;border-radius:24rpx;background:rgba(17,19,24,.9);border:1rpx solid rgba(255,255,255,.1);box-shadow:0 20rpx 40rpx rgba(0,0,0,.08)}.row{display:flex;justify-content:space-between;align-items:center;padding:24rpx 20rpx;border-radius:18rpx;background:#1d2025;position:relative;overflow:hidden}.row + .row{margin-top:8rpx}.row:before{content:'';position:absolute;inset:0;border:1rpx solid rgba(255,255,255,.05);border-radius:18rpx;pointer-events:none}.label{display:block;font-size:28rpx;font-weight:600;color:#fff;margin-bottom:6rpx}.desc{display:block;font-size:22rpx;color:#aaabb0}.value-group{display:flex;align-items:center;gap:16rpx}.value{font-size:28rpx;font-weight:800;color:#c19cff}.accent{color:#00e5ff}.edit{font-size:28rpx;color:#aaabb0}.toggle{padding:10rpx 18rpx;border-radius:9999rpx;background:#23262c;color:#aaabb0;font-weight:700}.toggle.on{background:#c19cff;color:#000;box-shadow:0 0 10rpx rgba(193,156,255,.5)}.save-wrap{margin-top:34rpx}.save-btn{width:100%;border-radius:9999rpx;padding:28rpx 0;background:linear-gradient(90deg,#c19cff,#9146ff);color:#fff;font-size:32rpx;font-weight:800;box-shadow:0 0 20rpx rgba(193,156,255,.3)}
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)}.topbar-left,.topbar-right{display:flex;align-items:center;gap:18rpx}.back-btn{width:72rpx;height:72rpx;border-radius:9999rpx;background:#000;color:#aaabb0;display:flex;align-items:center;justify-content:center;border:1rpx solid rgba(255,255,255,.1)}.brand-text{font-size:38rpx;font-weight:800;color:#c19cff}.topbar-icon{font-size:30rpx;color:#aaabb0}.avatar-shell{width:64rpx;height:64rpx;border-radius:9999rpx;overflow:hidden;border:1rpx solid rgba(255,255,255,.1)}.avatar-img{width:100%;height:100%}.content{height:calc(100vh - 120rpx);padding:40rpx 32rpx 32rpx;box-sizing:border-box}.header{margin-bottom:32rpx}.title{display:block;font-size:56rpx;font-weight:800;line-height:1.1}.subtitle{display:block;margin-top:10rpx;color:#aaabb0;font-size:26rpx}.section-block{margin-top:28rpx}.section-head{display:flex;align-items:center;gap:14rpx;margin-bottom:18rpx}.section-ico{width:76rpx;height:76rpx;border-radius:9999rpx;background:rgba(255,255,255,.06);display:flex;align-items:center;justify-content:center;font-size:30rpx}.section-title{font-size:32rpx;font-weight:800}.panel{position:relative;padding:8rpx;border-radius:24rpx;background:rgba(17,19,24,.9);border:1rpx solid rgba(255,255,255,.1);box-shadow:0 20rpx 40rpx rgba(0,0,0,.08)}.row{display:flex;justify-content:space-between;align-items:center;padding:24rpx 20rpx;border-radius:18rpx;background:#1d2025;position:relative;overflow:hidden}.row + .row{margin-top:8rpx}.row:before{content:'';position:absolute;inset:0;border:1rpx solid rgba(255,255,255,.05);border-radius:18rpx;pointer-events:none}.label{display:block;font-size:28rpx;font-weight:600;color:#fff;margin-bottom:6rpx}.desc{display:block;font-size:22rpx;color:#aaabb0}.value-group{display:flex;align-items:center;gap:16rpx}.value{font-size:28rpx;font-weight:800;color:#c19cff}.accent{color:#00e5ff}.edit{font-size:28rpx;color:#aaabb0}.setting-input{min-width:140rpx;text-align:right;font-size:28rpx;font-weight:800;color:#c19cff}.picker-value{min-width:140rpx;text-align:right;font-size:28rpx;font-weight:800}.toggle{padding:10rpx 18rpx;border-radius:9999rpx;background:#23262c;color:#aaabb0;font-weight:700}.toggle.on{background:#c19cff;color:#000;box-shadow:0 0 10rpx rgba(193,156,255,.5)}.save-wrap{margin-top:34rpx}.save-btn{width:100%;border-radius:9999rpx;padding:28rpx 0;background:linear-gradient(90deg,#c19cff,#9146ff);color:#fff;font-size:32rpx;font-weight:800;box-shadow:0 0 20rpx rgba(193,156,255,.3)}

View File

@ -5,12 +5,12 @@
<text class="subtitle">管理并策划你的个人词汇集合。</text>
</view>
<view class="toolbar">
<!-- <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> -->
<view class="search-row">
<view class="search-box">