100 lines
5.2 KiB
Vue
100 lines
5.2 KiB
Vue
<!-- 未来社区 - 社区活动列表 -->
|
|
<template>
|
|
<view class="al-page">
|
|
<view class="fc-nav" :style="{ paddingTop: statusBarTop + 'px' }">
|
|
<view class="fc-nav-bar">
|
|
<view class="fc-back" @tap="goBack"><u-icon name="arrow-left" color="#1a1a1a" size="38"></u-icon></view>
|
|
<text class="fc-nav-title">社区活动</text>
|
|
</view>
|
|
<view class="al-search">
|
|
<u-icon name="search" color="#9098a0" size="28"></u-icon>
|
|
<input class="al-search-input" v-model="keyword" placeholder="搜索活动名称、地点" placeholder-class="al-ph" />
|
|
</view>
|
|
<scroll-view class="al-tabs" scroll-x>
|
|
<text class="al-tab" :class="{ on: activeTab === t.key }" v-for="t in ACTIVITY_TABS" :key="t.key" @tap="activeTab = t.key">{{ t.label }}</text>
|
|
</scroll-view>
|
|
</view>
|
|
|
|
<view class="al-body">
|
|
<view class="al-card" v-for="a in filtered" :key="a.id" @tap="goDetail(a)">
|
|
<view class="al-cover">
|
|
<image v-if="a.image" :src="a.image" class="al-img" mode="aspectFill" />
|
|
<view v-else class="al-img" :style="{ background: sceneBg(a.scene) }"></view>
|
|
<text class="al-badge" :style="statusStyle(a.status)">{{ statusLabel(a.status) }}</text>
|
|
</view>
|
|
<view class="al-info">
|
|
<text class="al-title">{{ a.title }}</text>
|
|
<view class="al-row"><u-icon name="map" color="#9098a0" size="22"></u-icon><text>{{ a.place }}</text></view>
|
|
<view class="al-row"><u-icon name="clock" color="#9098a0" size="22"></u-icon><text>{{ a.time }}</text></view>
|
|
<view class="al-row"><u-icon name="account" color="#9098a0" size="22"></u-icon><text>{{ a.enrolled || a.quota }}</text></view>
|
|
<view class="al-foot">
|
|
<view class="al-row"><u-icon name="map" color="#c2c7ce" size="20"></u-icon><text class="al-dist">{{ a.distance || '社区内' }}</text></view>
|
|
<text class="al-fee">{{ a.fee || '免费' }}</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
<view class="fc-empty" v-if="!filtered.length">暂无相关活动</view>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
import { NavgateTo } from '@/utils'
|
|
import { activities, ACTIVITY_TABS, ACTIVITY_STATUS_META, ACTIVITY_SCENE_BG } from '../data.js'
|
|
|
|
export default {
|
|
data() { return { statusBarTop: 20, ACTIVITY_TABS, activeTab: 'all', keyword: '', activities } },
|
|
onLoad(options) {
|
|
const sys = uni.getSystemInfoSync()
|
|
this.statusBarTop = sys.statusBarHeight || 20
|
|
if (options && options.tab && ACTIVITY_TABS.some(t => t.key === options.tab)) this.activeTab = options.tab
|
|
},
|
|
computed: {
|
|
filtered() {
|
|
const kw = this.keyword.trim()
|
|
return this.activities.filter(a => {
|
|
const okTab = this.activeTab === 'all' || a.status === this.activeTab
|
|
const okKw = !kw || (a.title + a.subtitle + a.place).indexOf(kw) >= 0
|
|
return okTab && okKw
|
|
})
|
|
}
|
|
},
|
|
methods: {
|
|
statusLabel(s) { return (ACTIVITY_STATUS_META[s] || {}).label || '' },
|
|
statusStyle(s) { const m = ACTIVITY_STATUS_META[s] || {}; return { color: m.color, background: m.bg } },
|
|
sceneBg(s) { return ACTIVITY_SCENE_BG[s] || ACTIVITY_SCENE_BG.handicraft },
|
|
goBack() { uni.navigateBack({ delta: 1 }) },
|
|
goDetail(a) { NavgateTo('/packages/futureCommunity/activityDetail/index?id=' + a.id, { isLogin: false }) }
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
page { background: #f5f6f7; }
|
|
.al-page { min-height: 100vh; background: #f5f6f7; }
|
|
.fc-nav { position: sticky; top: 0; z-index: 100; background: #fff; padding: 0 24rpx 12rpx; }
|
|
.fc-nav-bar { position: relative; display: flex; align-items: center; justify-content: center; height: 88rpx; }
|
|
.fc-back { position: absolute; left: 0; top: 0; height: 88rpx; display: flex; align-items: center; }
|
|
.fc-nav-title { font-size: 34rpx; font-weight: 700; color: #1a1a1a; }
|
|
.al-search { display: flex; align-items: center; height: 68rpx; background: #f4f5f7; border-radius: 34rpx; padding: 0 24rpx; }
|
|
.al-search-input { flex: 1; margin-left: 12rpx; font-size: 26rpx; color: #333; }
|
|
.al-ph { color: #9098a0; }
|
|
.al-tabs { white-space: nowrap; padding: 14rpx 0 4rpx; }
|
|
.al-tab { display: inline-block; font-size: 28rpx; color: #6b7078; padding: 8rpx 6rpx; margin-right: 40rpx; }
|
|
.al-tab.on { color: #e9272d; font-weight: 700; }
|
|
|
|
.al-body { padding: 20rpx; }
|
|
.al-card { background: #fff; border-radius: 22rpx; overflow: hidden; margin-bottom: 20rpx; }
|
|
.al-cover { position: relative; width: 100%; height: 300rpx; }
|
|
.al-img { width: 100%; height: 300rpx; display: block; }
|
|
.al-badge { position: absolute; left: 16rpx; top: 16rpx; font-size: 20rpx; padding: 4rpx 14rpx; border-radius: 6rpx; }
|
|
.al-info { padding: 22rpx 24rpx; display: flex; flex-direction: column; }
|
|
.al-title { font-size: 32rpx; font-weight: 700; color: #1a1a1a; }
|
|
.al-row { display: flex; align-items: center; margin-top: 12rpx; font-size: 24rpx; color: #6b7078; }
|
|
.al-row text { margin-left: 8rpx; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
|
|
.al-foot { display: flex; align-items: center; justify-content: space-between; margin-top: 16rpx; }
|
|
.al-dist { color: #9098a0; }
|
|
.al-fee { font-size: 28rpx; color: #e9272d; font-weight: 700; }
|
|
.fc-empty { text-align: center; color: #9aa0a8; font-size: 26rpx; padding: 120rpx 0; }
|
|
</style>
|