修改页面
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
Component({
|
||||
properties: {
|
||||
item: { type: Object, value: {} },
|
||||
done: { type: Boolean, value: false },
|
||||
streak: { type: Number, value: undefined },
|
||||
categoryLabel: { type: String, value: '' },
|
||||
cycleLabel: { type: String, value: '' },
|
||||
},
|
||||
methods: {
|
||||
onTap() {
|
||||
this.triggerEvent('tap', { id: this.data.item.id })
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"component": true,
|
||||
"usingComponents": {}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
<view class="card {{status}}" data-id="{{item.id}}" bindtap="onTap">
|
||||
<view class="card-icon">{{item.icon || '📋'}}</view>
|
||||
<view class="card-body">
|
||||
<text class="card-name">{{item.name}}</text>
|
||||
<text class="card-meta">{{categoryLabel}} · {{cycleLabel}}</text>
|
||||
<text wx:if="{{done}}" class="done-badge">✓ 已打卡</text>
|
||||
</view>
|
||||
<view class="card-streak" wx:if="{{streak !== undefined}}">
|
||||
<text>🔥 {{streak}}天</text>
|
||||
</view>
|
||||
</view>
|
||||
@@ -0,0 +1,26 @@
|
||||
.card {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background: white;
|
||||
border-radius: 12px;
|
||||
margin: 0 12px 8px;
|
||||
padding: 14px;
|
||||
box-shadow: 0 1px 3px rgba(0,0,0,0.04);
|
||||
}
|
||||
.card.paused { opacity: 0.6; }
|
||||
.card.archived { opacity: 0.4; }
|
||||
.card-icon {
|
||||
width: 44px; height: 44px;
|
||||
border-radius: 12px;
|
||||
background: #FFF0EB;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 22px;
|
||||
margin-right: 14px;
|
||||
}
|
||||
.card-body { flex: 1; display: flex; flex-direction: column; gap: 2px; }
|
||||
.card-name { font-size: 16px; font-weight: 600; }
|
||||
.card-meta { font-size: 13px; color: #86868B; }
|
||||
.done-badge { font-size: 12px; color: #34C759; font-weight: 600; margin-top: 2px; }
|
||||
.card-streak { font-size: 14px; color: #FF6B35; font-weight: 600; }
|
||||
@@ -0,0 +1,18 @@
|
||||
Component({
|
||||
properties: {
|
||||
active: { type: String, value: 'home' },
|
||||
tabs: {
|
||||
type: Array,
|
||||
value: [
|
||||
{ key: 'home', label: '打卡', icon: '📋' },
|
||||
{ key: 'feed', label: '广场', icon: '🌊' },
|
||||
{ key: 'profile', label: '我的', icon: '👤' },
|
||||
],
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
onSwitch(e) {
|
||||
this.triggerEvent('switch', { key: e.currentTarget.dataset.key })
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"component": true,
|
||||
"usingComponents": {}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
<view class="nav-bar">
|
||||
<view wx:for="{{tabs}}" wx:key="key" class="nav-item" data-key="{{item.key}}" bindtap="onSwitch">
|
||||
<text class="nav-icon">{{item.icon}}</text>
|
||||
<text class="nav-label {{active===item.key?'active':''}}">{{item.label}}</text>
|
||||
</view>
|
||||
</view>
|
||||
@@ -0,0 +1,24 @@
|
||||
.nav-bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-around;
|
||||
padding: 8px 0 24px;
|
||||
border-top: 0.5px solid #E5E5EA;
|
||||
background: rgba(245,245,247,0.95);
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 100;
|
||||
}
|
||||
.nav-item {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 2px;
|
||||
padding: 4px;
|
||||
}
|
||||
.nav-icon { font-size: 22px; }
|
||||
.nav-label { font-size: 10px; color: #86868B; }
|
||||
.nav-label.active { color: #FF6B35; font-weight: 600; }
|
||||
@@ -0,0 +1,93 @@
|
||||
/**
|
||||
* 格式化日期为 YYYY-MM-DD
|
||||
*/
|
||||
function formatDate(date) {
|
||||
const d = date ? new Date(date) : new Date()
|
||||
const y = d.getFullYear()
|
||||
const m = String(d.getMonth() + 1).padStart(2, '0')
|
||||
const day = String(d.getDate()).padStart(2, '0')
|
||||
return `${y}-${m}-${day}`
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化日期为 YYYY-MM
|
||||
*/
|
||||
function formatMonth(date) {
|
||||
const d = date ? new Date(date) : new Date()
|
||||
return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}`
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取相对时间描述(几分钟前、几小时前、几天前)
|
||||
*/
|
||||
function timeAgo(dateStr) {
|
||||
if (!dateStr) return ''
|
||||
const now = Date.now()
|
||||
const t = new Date(dateStr).getTime()
|
||||
const diff = Math.floor((now - t) / 1000)
|
||||
if (diff < 60) return '刚刚'
|
||||
if (diff < 3600) return Math.floor(diff / 60) + '分钟前'
|
||||
if (diff < 86400) return Math.floor(diff / 3600) + '小时前'
|
||||
if (diff < 2592000) return Math.floor(diff / 86400) + '天前'
|
||||
return formatDate(dateStr)
|
||||
}
|
||||
|
||||
/**
|
||||
* 打卡分类中文标签
|
||||
*/
|
||||
const CATEGORY_LABEL = {
|
||||
study: '学习成长',
|
||||
health: '健康生活',
|
||||
habit: '习惯自律',
|
||||
hobby: '兴趣爱好',
|
||||
goal: '目标任务',
|
||||
}
|
||||
|
||||
const CYCLE_LABEL = {
|
||||
daily: '每日',
|
||||
weekly: '每周',
|
||||
every_other_day: '隔日',
|
||||
custom: '自定义',
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取分类中文名
|
||||
*/
|
||||
function getCategoryLabel(cat) {
|
||||
return CATEGORY_LABEL[cat] || cat
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取周期中文名
|
||||
*/
|
||||
function getCycleLabel(cycle) {
|
||||
return CYCLE_LABEL[cycle] || cycle
|
||||
}
|
||||
|
||||
/**
|
||||
* 隐私级别中文名
|
||||
*/
|
||||
function getPrivacyLabel(level) {
|
||||
const map = { 1: '公开', 2: '仅好友可见', 3: '仅自己可见' }
|
||||
return map[level] || '未知'
|
||||
}
|
||||
|
||||
/**
|
||||
* 积分显示(带 + 号)
|
||||
*/
|
||||
function formatPoints(p) {
|
||||
if (p === undefined || p === null) return '--'
|
||||
return p > 0 ? '+' + p : String(p)
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
formatDate,
|
||||
formatMonth,
|
||||
timeAgo,
|
||||
getCategoryLabel,
|
||||
getCycleLabel,
|
||||
getPrivacyLabel,
|
||||
formatPoints,
|
||||
CATEGORY_LABEL,
|
||||
CYCLE_LABEL,
|
||||
}
|
||||
Reference in New Issue
Block a user