chore: initialize frontend miniapp repository

This commit is contained in:
lyf
2026-06-09 21:08:45 +08:00
commit a90f63cef0
107 changed files with 60454 additions and 0 deletions

235
src/pages/hall/detail.vue Normal file
View File

@@ -0,0 +1,235 @@
<template>
<view class="detail-page">
<scroll-view class="content" scroll-y>
<!-- 展厅封面 -->
<view class="hall-hero">
<image class="hero-image" :src="hall.image" mode="aspectFill" />
<view class="hall-badge">
<text class="badge-text">{{ hall.floor }}</text>
</view>
</view>
<!-- 展厅信息 -->
<view class="hall-info">
<text class="hall-title">{{ hall.name }}</text>
<text class="hall-description">{{ hall.description }}</text>
<view class="stats-row">
<view class="stat-item">
<text class="stat-value">{{ hall.exhibitCount }}</text>
<text class="stat-label">展品数量</text>
</view>
<view class="stat-item">
<text class="stat-value">{{ hall.area }}</text>
<text class="stat-label">展厅面积</text>
</view>
</view>
<!-- 展品列表 -->
<view class="exhibits-section">
<text class="section-title">展厅展品</text>
<view class="exhibits-grid">
<ExhibitCard
v-for="exhibit in exhibits"
:key="exhibit.id"
:exhibit="exhibit"
@click="handleExhibitClick"
/>
</view>
</view>
</view>
</scroll-view>
<!-- 底部操作栏 -->
<view class="action-bar">
<view class="action-btn primary" @tap="handleNavigate">
<text class="btn-text">导航到展厅</text>
</view>
</view>
</view>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
import ExhibitCard from '@/components/content/ExhibitCard.vue'
const hall = ref({
id: '1',
name: '1号展厅',
floor: '1F',
description: '文艺复兴时期艺术作品展厅,展示了欧洲文艺复兴时期最具代表性的绘画和雕塑作品。',
image: '/static/hall-placeholder.jpg',
exhibitCount: 25,
area: '500㎡'
})
const exhibits = ref([
{ id: '1', name: '蒙娜丽莎', artist: '达芬奇', hasAudio: true },
{ id: '2', name: '最后的晚餐', artist: '达芬奇', hasAudio: true }
])
onLoad((options: any) => {
if (options.id) {
console.log('加载展厅:', options.id)
}
})
const handleExhibitClick = (exhibit: any) => {
uni.navigateTo({
url: `/pages/exhibit/detail?id=${exhibit.id}`
})
}
const handleNavigate = () => {
console.log('导航到展厅')
uni.navigateBack()
}
</script>
<style scoped lang="scss">
.detail-page {
width: 100%;
height: 100vh;
overflow-x: hidden;
background-color: var(--museum-bg-light);
display: flex;
flex-direction: column;
}
.content {
flex: 1;
width: 100%;
box-sizing: border-box;
overflow-y: auto;
}
.hall-hero {
position: relative;
width: 100%;
height: 240px;
background-color: var(--museum-bg-map);
}
.hero-image {
width: 100%;
height: 100%;
}
.hall-badge {
position: absolute;
top: 16px;
right: 16px;
background-color: rgba(0, 0, 0, 0.6);
backdrop-filter: var(--blur-medium);
padding: 6px 12px;
border-radius: 16px;
}
.badge-text {
font-size: 14px;
color: var(--museum-bg-surface);
font-weight: 500;
}
.hall-info {
padding: 24px 16px;
box-sizing: border-box;
background-color: var(--museum-bg-surface);
}
.hall-title {
font-size: 24px;
font-weight: 700;
color: var(--museum-text-primary);
margin-bottom: 12px;
display: block;
}
.hall-description {
font-size: 14px;
line-height: 1.6;
color: var(--museum-text-secondary);
margin-bottom: 24px;
display: block;
}
.stats-row {
display: flex;
gap: 24px;
padding: 16px;
box-sizing: border-box;
background-color: var(--museum-bg-light);
border-radius: var(--radius-card);
margin-bottom: 24px;
}
.stat-item {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
gap: 4px;
}
.stat-value {
font-size: 24px;
font-weight: 700;
color: var(--museum-text-primary);
}
.stat-label {
font-size: 12px;
color: var(--museum-text-disabled);
}
.exhibits-section {
margin-top: 24px;
}
.section-title {
font-size: 18px;
font-weight: 600;
color: var(--museum-text-primary);
margin-bottom: 16px;
display: block;
}
.exhibits-grid {
display: grid;
grid-template-columns: 1fr;
gap: 12px;
}
.action-bar {
background-color: var(--museum-bg-surface);
border-top: 1px solid var(--museum-border-light);
padding: 12px 16px;
padding-bottom: calc(12px + env(safe-area-inset-bottom));
box-sizing: border-box;
}
.action-btn {
width: 100%;
padding: 14px;
box-sizing: border-box;
border-radius: var(--radius-button);
text-align: center;
cursor: pointer;
transition: all 0.3s;
}
.action-btn.primary {
background-color: var(--museum-accent);
}
.action-btn:active {
opacity: 0.8;
}
.btn-text {
font-size: 16px;
font-weight: 500;
color: var(--museum-text-primary);
}
</style>