feat(nsti): add nicotine personality test flow (#36)
* fix: polish logs filter and stats money display * fix: align floating tabs on logs and stats * feat: enhance user profile and achievement features - Add functionality for users to update their profile picture and nickname - Implement achievement theme selection in onboarding - Update API integration for profile updates and achievement themes - Refine UI elements for better user interaction and experience * feat: 梦想清单页与戒烟相关 API - 梦想清单:系统导航栏、浮动添加、图标来自后台预设 - dream-presets API、pages.json 导航样式 Made-with: Cursor * feat(nsti): add nicotine personality test flow
This commit is contained in:
+43
-12
@@ -283,6 +283,12 @@ const weeklyTrendItems = computed(() => {
|
||||
})
|
||||
})
|
||||
|
||||
function safeNumber(value) {
|
||||
if (value === undefined || value === null || value === '') return 0
|
||||
const num = Number(value)
|
||||
return Number.isNaN(num) ? 0 : num
|
||||
}
|
||||
|
||||
function calDotClass(count) {
|
||||
if (count === 0) return 'cal-dot-zero'
|
||||
if (count <= 3) return 'cal-dot-low'
|
||||
@@ -290,10 +296,15 @@ function calDotClass(count) {
|
||||
return 'cal-dot-high'
|
||||
}
|
||||
|
||||
const savedMoneyText = computed(() => {
|
||||
const savedMoneyCent = computed(() => {
|
||||
const money = statsData.value?.money
|
||||
if (!money || !money.available) return '--'
|
||||
return `¥${(money.saved_cent / 100).toFixed(2)}`
|
||||
if (!money || !money.available) return 0
|
||||
return safeNumber(money.saved_cent)
|
||||
})
|
||||
|
||||
const savedMoneyText = computed(() => {
|
||||
if (!moneyAvailable.value) return '--'
|
||||
return `¥${(savedMoneyCent.value / 100).toFixed(2)}`
|
||||
})
|
||||
|
||||
const moneyAvailable = computed(() => !!statsData.value?.money?.available)
|
||||
@@ -301,13 +312,13 @@ const moneyAvailable = computed(() => !!statsData.value?.money?.available)
|
||||
const moneyExpectedTotal = computed(() => {
|
||||
const money = statsData.value?.money
|
||||
if (!money || !money.available) return 0
|
||||
return Number(money.expected_total) || 0
|
||||
return safeNumber(money.expected_total)
|
||||
})
|
||||
|
||||
const moneyActualTotal = computed(() => {
|
||||
const money = statsData.value?.money
|
||||
if (!money || !money.available) return 0
|
||||
return Number(money.actual_total) || 0
|
||||
return safeNumber(money.actual_total)
|
||||
})
|
||||
|
||||
const moneySubtitle = computed(() => {
|
||||
@@ -318,16 +329,17 @@ const moneySubtitle = computed(() => {
|
||||
const moneyTargetCent = computed(() => {
|
||||
const money = statsData.value?.money
|
||||
if (!money || !money.available) return 0
|
||||
const { expected_total, pack_price_cent, cigs_per_pack } = money
|
||||
if (!expected_total || !pack_price_cent || !cigs_per_pack) return 0
|
||||
return Math.round((expected_total / cigs_per_pack) * pack_price_cent)
|
||||
const expectedTotal = safeNumber(money.expected_total)
|
||||
const packPriceCent = safeNumber(money.pack_price_cent)
|
||||
const cigsPerPack = safeNumber(money.cigs_per_pack)
|
||||
if (expectedTotal <= 0 || packPriceCent <= 0 || cigsPerPack <= 0) return 0
|
||||
return Math.round((expectedTotal / cigsPerPack) * packPriceCent)
|
||||
})
|
||||
|
||||
const moneyPercent = computed(() => {
|
||||
const money = statsData.value?.money
|
||||
const target = moneyTargetCent.value
|
||||
if (!money || !money.available || target <= 0) return 0
|
||||
const percent = Math.round((money.saved_cent / target) * 100)
|
||||
if (!moneyAvailable.value || target <= 0) return 0
|
||||
const percent = Math.round((savedMoneyCent.value / target) * 100)
|
||||
return Math.min(Math.max(percent, 0), 100)
|
||||
})
|
||||
|
||||
@@ -486,10 +498,17 @@ onShareAppMessage(() => {
|
||||
|
||||
/* ── Tab 切换 ── */
|
||||
.segment-wrap {
|
||||
padding: 8rpx 0 20rpx;
|
||||
position: relative;
|
||||
height: 148rpx;
|
||||
flex-shrink: 0;
|
||||
z-index: 20;
|
||||
}
|
||||
|
||||
.segment {
|
||||
position: fixed;
|
||||
left: 28rpx;
|
||||
right: 28rpx;
|
||||
z-index: 50;
|
||||
display: flex;
|
||||
background: rgba(255, 255, 255, 0.82);
|
||||
padding: 6rpx;
|
||||
@@ -497,6 +516,18 @@ onShareAppMessage(() => {
|
||||
gap: 6rpx;
|
||||
border: 1.5rpx solid rgba(52, 200, 160, 0.14);
|
||||
box-shadow: 0 4rpx 16rpx rgba(52, 200, 160, 0.07);
|
||||
-webkit-backdrop-filter: blur(12px);
|
||||
backdrop-filter: blur(12px);
|
||||
}
|
||||
|
||||
.segment::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: -12rpx -8rpx -10rpx;
|
||||
border-radius: 34rpx;
|
||||
background: linear-gradient(180deg, rgba(230, 247, 242, 0.96) 0%, rgba(240, 251, 247, 0.88) 72%, rgba(240, 251, 247, 0) 100%);
|
||||
z-index: -1;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.segment-item {
|
||||
|
||||
Reference in New Issue
Block a user