Files
hejiu/components/AchievementBadge.vue
T
cg 860136bceb feat(theme): 实现日夜主题自动切换功能
- 添加日夜主题CSS变量定义,支持琥珀夜光和暖白琥珀两种风格
- 实现主题切换逻辑,根据时间自动切换白天(light)和夜间(dark)主题
- 在App.vue中集成主题初始化和token恢复功能
- 更新全局样式类应用主题颜色变量,包括卡片、文本、边框等
- 创建主题混入(mixin)供各页面使用,确保主题同步更新
- 实现导航栏和TabBar主题动态切换,提升用户体验
- 添加API服务层封装HaveADrink SDK,统一处理认证和请求
- 优化DrinkCard组件显示饮酒感受信息,丰富打卡记录展示
- 更新项目依赖配置,集成新的API客户端库
2026-07-16 22:47:38 +08:00

100 lines
1.8 KiB
Vue

<template>
<view
class="badge"
:class="{ 'badge-unlocked': achievement.unlocked, 'badge-locked': !achievement.unlocked }"
@click="$emit('click')"
>
<view class="badge-icon-wrap">
<text class="badge-icon">{{ achievement.icon }}</text>
<view v-if="!achievement.unlocked" class="badge-lock">
<text class="badge-lock-icon">🔒</text>
</view>
</view>
<text class="badge-name">{{ achievement.name }}</text>
</view>
</template>
<script>
export default {
props: {
achievement: { type: Object, required: true }
},
emits: ['click']
}
</script>
<style lang="scss" scoped>
.badge {
display: flex;
flex-direction: column;
align-items: center;
gap: $sp-sm;
padding: $sp-lg $sp-sm;
background: $bg-card;
border-radius: $radius-lg;
transition: all $duration-fast $ease-out;
&:active {
transform: scale(0.95);
}
&.badge-unlocked {
.badge-icon-wrap {
box-shadow: 0 0 24rpx rgba(232,168,56,0.3);
border-color: rgba(232,168,56,0.3);
}
.badge-name {
color: $text-primary;
}
}
&.badge-locked {
opacity: 0.5;
.badge-icon {
filter: grayscale(1);
}
}
}
.badge-icon-wrap {
width: 96rpx;
height: 96rpx;
background: $bg-elevated;
border-radius: $radius-full;
display: flex;
align-items: center;
justify-content: center;
border: 3rpx solid var(--border-faint, rgba(255, 255, 255, 0.08));
position: relative;
}
.badge-icon {
font-size: 48rpx;
}
.badge-lock {
position: absolute;
bottom: -4rpx;
right: -4rpx;
width: 36rpx;
height: 36rpx;
background: $bg-base;
border-radius: $radius-full;
display: flex;
align-items: center;
justify-content: center;
}
.badge-lock-icon {
font-size: 20rpx;
}
.badge-name {
font-size: $fs-xs;
color: $text-secondary;
text-align: center;
}
</style>