71 lines
2.3 KiB
Vue
71 lines
2.3 KiB
Vue
<template>
|
|
<view class="mailbox-group">
|
|
<view class="group-header" @tap="onToggleHeader">
|
|
<text class="chevron">{{ collapsed ? '▸' : '▾' }}</text>
|
|
<text class="group-label">{{ label }}</text>
|
|
<text v-if="unreadCount > 0" class="group-badge">{{ unreadCount }}</text>
|
|
</view>
|
|
<view v-if="!collapsed" class="group-list">
|
|
<view
|
|
v-for="n in items" :key="n.id"
|
|
class="group-item"
|
|
@tap="onSelectItem(n)"
|
|
@longpress="onLongPressItem(n)"
|
|
>
|
|
<text class="dot" v-if="!n.is_read">●</text>
|
|
<text class="dot dot-read" v-else>○</text>
|
|
<text class="item-title">{{ n.title }}</text>
|
|
<text class="item-time">{{ formatTime(n.created_at) }}</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script setup>
|
|
const props = defineProps({
|
|
groupKey: String,
|
|
label: String,
|
|
collapsed: Boolean,
|
|
items: { type: Array, default: () => [] },
|
|
unreadCount: { type: Number, default: 0 },
|
|
})
|
|
const emit = defineEmits(['toggle', 'select', 'long-press'])
|
|
|
|
function onToggleHeader() { emit('toggle') }
|
|
function onSelectItem(n) { emit('select', n) }
|
|
function onLongPressItem(n) { emit('long-press', n) }
|
|
function formatTime(ms) {
|
|
if (!ms) return ''
|
|
const d = new Date(ms)
|
|
const pad = n => (n < 10 ? '0' + n : '' + n)
|
|
return `${d.getFullYear()}-${pad(d.getMonth()+1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}`
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.mailbox-group {
|
|
background: #fff;
|
|
border-radius: 16rpx;
|
|
margin-bottom: 16rpx;
|
|
.group-header {
|
|
display: flex; align-items: center; padding: 24rpx;
|
|
border-bottom: 1rpx solid #f5f5f5;
|
|
.chevron { font-size: 28rpx; color: #999; margin-right: 12rpx; width: 30rpx; }
|
|
.group-label { font-size: 28rpx; font-weight: 600; flex: 1; }
|
|
.group-badge {
|
|
background: #f5222d; color: #fff; border-radius: 16rpx;
|
|
padding: 4rpx 12rpx; font-size: 22rpx;
|
|
}
|
|
}
|
|
.group-item {
|
|
display: flex; align-items: center; padding: 20rpx 24rpx;
|
|
border-bottom: 1rpx solid #fafafa;
|
|
&:last-child { border-bottom: 0; }
|
|
.dot { color: #f5222d; font-size: 24rpx; margin-right: 12rpx; width: 24rpx; }
|
|
.dot-read { color: #ccc; }
|
|
.item-title { font-size: 26rpx; flex: 1; }
|
|
.item-time { font-size: 22rpx; color: #999; }
|
|
}
|
|
}
|
|
</style>
|