feat(app): 初始化喝酒了么小程序基础架构

- 添加项目配置文件(.editorconfig, .gitignore)
- 创建App.vue主应用文件,包含启动时Mock数据初始化
- 添加index.html和main.js应用入口文件
- 配置manifest.json应用基本信息和权限设置
- 设置pages.json页面路由和全局样式
- 添加uni.promisify.adaptor.js适配器文件
- 创建uni.scss设计令牌系统,定义琥珀夜光主题色彩
- 新增constants.js常量定义,包含酒类分类和品牌数据
This commit is contained in:
cg
2026-07-13 22:15:16 +08:00
parent 35af888097
commit f945ccf4c7
34 changed files with 6447 additions and 0 deletions
+197
View File
@@ -0,0 +1,197 @@
<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-lg;
}
.cal-nav {
width: 64rpx;
height: 64rpx;
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-sm;
}
.cal-weekday {
text-align: center;
font-size: $fs-xs;
color: $text-tertiary;
padding: $sp-xs 0;
}
.cal-grid {
display: grid;
grid-template-columns: repeat(7, 1fr);
gap: $sp-xs;
}
.cal-cell {
aspect-ratio: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
border-radius: $radius-md;
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-sm;
font-weight: $fw-medium;
color: $text-primary;
font-family: $font-num;
}
.cal-dot {
width: 10rpx;
height: 10rpx;
border-radius: $radius-full;
margin-top: $sp-xs;
&.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>