Files
hejiu/pages/card/card.vue
T
cg f945ccf4c7 feat(app): 初始化喝酒了么小程序基础架构
- 添加项目配置文件(.editorconfig, .gitignore)
- 创建App.vue主应用文件,包含启动时Mock数据初始化
- 添加index.html和main.js应用入口文件
- 配置manifest.json应用基本信息和权限设置
- 设置pages.json页面路由和全局样式
- 添加uni.promisify.adaptor.js适配器文件
- 创建uni.scss设计令牌系统,定义琥珀夜光主题色彩
- 新增constants.js常量定义,包含酒类分类和品牌数据
2026-07-13 22:15:16 +08:00

292 lines
6.5 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="page-container card-page">
<!-- 顶部导航 -->
<view class="card-nav">
<view class="step-back" @click="goBack">
<text class="step-back-arrow"></text>
</view>
<text class="card-nav-title">你的酒局卡片</text>
</view>
<!-- 照片提示 -->
<view class="photo-hint" v-if="record">
<text class="photo-hint-text">
{{ photoHintText }}
</text>
</view>
<!-- 模板切换 -->
<view class="template-switcher">
<view
v-for="t in templates"
:key="t.id"
class="template-option"
:class="{ 'template-active': currentTemplate === t.id }"
@click="currentTemplate = t.id"
>
<view class="template-swatch" :style="{ background: t.swatch }">
<view class="swatch-dot" v-if="currentTemplate === t.id"></view>
</view>
<text class="template-label">{{ t.name }}</text>
<text class="template-desc">{{ t.desc }}</text>
</view>
</view>
<!-- 卡片预览 -->
<view class="card-preview-area">
<DrinkCard v-if="record" :record="record" :template="currentTemplate" />
</view>
<!-- 操作按钮 -->
<view class="card-actions">
<button class="btn-cta" @click="saveToAlbum">
💾 保存到相册
</button>
<view class="action-row">
<button class="btn-secondary action-btn" @click="shareToFriend">
🔗 分享好友
</button>
<button class="btn-secondary action-btn" @click="goHome">
🏠 返回首页
</button>
</view>
</view>
<!-- 成功提示 -->
<view v-if="showSuccess" class="success-toast">
<text> 已保存到相册</text>
</view>
</view>
</template>
<script>
import DrinkCard from '../../components/DrinkCard.vue'
import { getRecords } from '../../common/mock-data'
export default {
components: { DrinkCard },
data() {
return {
currentTemplate: 'amber',
record: null,
showSuccess: false,
templates: [
{
id: 'amber',
name: '琥珀流光',
desc: '温暖金色调',
swatch: 'linear-gradient(135deg, #1A1308, #0F0B06)'
},
{
id: 'aurora',
name: '暗夜极光',
desc: '冷色氛围感',
swatch: 'linear-gradient(135deg, #0A0E1A, #0E0A1A)'
},
{
id: 'film',
name: '胶片记忆',
desc: '复古胶片风',
swatch: 'linear-gradient(135deg, #141210, #0D0C0A)'
}
]
}
},
computed: {
photoHintText() {
if (!this.record) return ''
const photos = this.record.photos || []
if (photos.length === 0) return '📷 无照片 · 纯文字排版'
if (photos.length === 1) return '📸 单张照片 · 沉浸式全屏'
return `🖼️ ${photos.length}张照片 · 拼贴布局`
}
},
onLoad(options) {
const records = getRecords()
if (options && options.recordId) {
this.record = records.find(r => r.id === options.recordId)
}
if (!this.record) {
this.record = records.find(r => r.mode === 'drank') || this.getFallbackRecord()
}
},
methods: {
getFallbackRecord() {
return {
date: new Date().toISOString().slice(0, 10),
mode: 'drank',
drinks: [{ category: 'beer', brand: '青岛啤酒', product: '经典', amount: 2, unit: 'bottle', degree: 4.3, standardCups: 3.4 }],
food: { category: 'bbq', name: '烤串' },
feeling: 'tipsy',
photos: [],
standardCupsTotal: 3.4
}
},
saveToAlbum() {
this.showSuccess = true
uni.showToast({ title: '已保存到相册', icon: 'success' })
setTimeout(() => { this.showSuccess = false }, 2000)
},
shareToFriend() {
uni.showToast({ title: '点击右上角分享', icon: 'none' })
},
goHome() {
uni.reLaunch({ url: '/pages/index/index' })
},
goBack() {
uni.navigateBack()
}
},
onShareAppMessage() {
return {
title: '今晚的酒局记录 - 喝酒了么',
path: '/pages/index/index'
}
}
}
</script>
<style lang="scss" scoped>
.card-page {
padding: $sp-lg;
padding-bottom: calc(env(safe-area-inset-bottom) + $sp-xl);
display: flex;
flex-direction: column;
min-height: 100vh;
}
/* 导航 */
.card-nav {
display: flex;
align-items: center;
gap: $sp-md;
padding: $sp-md 0 $sp-lg;
}
.step-back {
width: 64rpx;
height: 64rpx;
display: flex;
align-items: center;
justify-content: center;
border-radius: $radius-full;
background: $bg-card;
}
.step-back-arrow {
font-size: $fs-xl;
color: $text-secondary;
font-weight: $fw-bold;
}
.card-nav-title {
font-size: $fs-lg;
font-weight: $fw-bold;
}
/* 照片数量提示 */
.photo-hint {
text-align: center;
margin-bottom: $sp-md;
}
.photo-hint-text {
font-size: $fs-xs;
color: $text-tertiary;
}
/* 模板切换 - 横排卡片选择 */
.template-switcher {
display: flex;
gap: $sp-md;
margin-bottom: $sp-xl;
justify-content: center;
}
.template-option {
display: flex;
flex-direction: column;
align-items: center;
gap: $sp-xs;
padding: $sp-sm $sp-md;
border-radius: $radius-lg;
border: 2rpx solid rgba(255, 255, 255, 0.05);
background: rgba(255, 255, 255, 0.02);
transition: all $duration-fast $ease-out;
flex: 1;
max-width: 220rpx;
&.template-active {
border-color: $amber;
background: rgba(232, 168, 56, 0.05);
}
}
.template-swatch {
width: 64rpx;
height: 80rpx;
border-radius: $radius-md;
border: 2rpx solid rgba(255, 255, 255, 0.1);
position: relative;
display: flex;
align-items: center;
justify-content: center;
}
.swatch-dot {
width: 12rpx;
height: 12rpx;
border-radius: $radius-full;
background: $amber;
}
.template-label {
font-size: $fs-xs;
color: $text-primary;
font-weight: $fw-medium;
}
.template-desc {
font-size: 18rpx;
color: $text-tertiary;
}
/* 卡片预览 */
.card-preview-area {
flex: 1;
display: flex;
align-items: flex-start;
justify-content: center;
margin-bottom: $sp-xl;
width: 100%;
}
/* 操作按钮 */
.card-actions {
padding-bottom: $sp-xl;
}
.action-row {
display: flex;
gap: $sp-md;
margin-top: $sp-md;
}
.action-btn {
flex: 1;
}
.success-toast {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: rgba(0, 0, 0, 0.8);
color: #fff;
padding: $sp-lg $sp-xl;
border-radius: $radius-lg;
font-size: $fs-base;
z-index: 100;
}
</style>