Files
hejiu/components/DrinkCalendar.vue
T
cg b95243c8f8 docs(api): 更新API接口文档并调整应用配置
- 添加完整的后端接口文档,包含用户、打卡记录、统计等模块
- 修复应用名称从"喝酒了么"统一更正为"喝了么"
- 重构App.vue中的启动逻辑,增加数据迁移和路由守卫功能
- 调整DrinkCalendar组件的UI间距和尺寸参数
- 优化DrinkCard组件的品牌展示文案
- 修改manifest.json中的应用描述和微信小程序配置
- 调整pages.json中的页面路径顺序和tabBar配置
- 更新全局样式文件中的应用名称标识
- 修改mock数据中的用户头像默认值
- 优化卡片导出功能的绘制逻辑和视觉效果
2026-07-14 23:27:23 +08:00

198 lines
4.0 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view class="calendar">
<!-- 月份导航 -->
<view class="cal-header">
<view class="cal-nav" @click="prevMonth">
<text class="cal-nav-arrow"></text>
</view>
<text class="cal-title">{{ year }}{{ month }}</text>
<view class="cal-nav" @click="nextMonth">
<text class="cal-nav-arrow"></text>
</view>
</view>
<!-- 星期头 -->
<view class="cal-weekdays">
<text v-for="day in weekLabels" :key="day" class="cal-weekday">{{ day }}</text>
</view>
<!-- 日期网格 -->
<view class="cal-grid">
<view
v-for="(cell, index) in calendarDays"
:key="index"
class="cal-cell"
:class="{
'cal-cell-empty': !cell.day,
'cal-cell-today': cell.isToday,
'cal-cell-drank': getRecordMode(cell.date) === 'drank',
'cal-cell-abstain': getRecordMode(cell.date) === 'abstain'
}"
@click="cell.day && onSelectDate(cell.date)"
>
<text v-if="cell.day" class="cal-day-num">{{ cell.day }}</text>
<view v-if="getRecordMode(cell.date) === 'drank'" class="cal-dot cal-dot-drank"></view>
<view v-if="getRecordMode(cell.date) === 'abstain'" class="cal-dot cal-dot-abstain"></view>
</view>
</view>
</view>
</template>
<script>
import { getCalendarDays } from '../common/utils'
export default {
props: {
year: Number,
month: Number,
records: {
type: Array,
default: () => []
}
},
data() {
return {
weekLabels: ['一', '二', '三', '四', '五', '六', '日']
}
},
computed: {
calendarDays() {
return getCalendarDays(this.year, this.month)
}
},
methods: {
getRecordMode(date) {
if (!date) return null
const record = this.records.find(r => r.date === date)
return record ? record.mode : null
},
prevMonth() {
let y = this.year
let m = this.month - 1
if (m < 1) { y--; m = 12 }
this.$emit('change-month', { year: y, month: m })
},
nextMonth() {
let y = this.year
let m = this.month + 1
if (m > 12) { y++; m = 1 }
this.$emit('change-month', { year: y, month: m })
},
onSelectDate(date) {
this.$emit('select-date', date)
}
}
}
</script>
<style lang="scss" scoped>
.calendar {
width: 100%;
}
.cal-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: $sp-sm;
}
.cal-nav {
width: 56rpx;
height: 56rpx;
display: flex;
align-items: center;
justify-content: center;
border-radius: $radius-full;
background: $bg-elevated;
}
.cal-nav-arrow {
font-size: $fs-xl;
color: $text-secondary;
font-weight: $fw-bold;
line-height: 1;
}
.cal-title {
font-size: $fs-lg;
font-weight: $fw-bold;
font-family: $font-num;
}
.cal-weekdays {
display: grid;
grid-template-columns: repeat(7, 1fr);
margin-bottom: $sp-xs;
}
.cal-weekday {
text-align: center;
font-size: $fs-xs;
color: $text-tertiary;
padding: 4rpx 0;
}
.cal-grid {
display: grid;
grid-template-columns: repeat(7, 1fr);
gap: 4rpx;
}
.cal-cell {
aspect-ratio: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
border-radius: $radius-sm;
position: relative;
transition: all $duration-fast $ease-out;
&.cal-cell-empty {
background: transparent;
}
&.cal-cell-today {
border: 2rpx solid $amber;
}
&:active:not(.cal-cell-empty) {
transform: scale(0.92);
}
}
.cal-day-num {
font-size: $fs-xs;
font-weight: $fw-medium;
color: $text-primary;
font-family: $font-num;
}
.cal-dot {
width: 8rpx;
height: 8rpx;
border-radius: $radius-full;
margin-top: 4rpx;
&.cal-dot-drank {
background: $amber;
box-shadow: 0 0 12rpx rgba(232, 168, 56, 0.5);
}
&.cal-dot-abstain {
background: $mint;
box-shadow: 0 0 12rpx rgba(94, 198, 160, 0.3);
}
}
/* 饮酒日高亮背景 */
.cal-cell-drank {
background: rgba(232, 168, 56, 0.08);
}
.cal-cell-abstain {
background: rgba(94, 198, 160, 0.06);
}
</style>