- 新增 server/:Node + Express + SQLite + node-cron 实现登录、纪念日 CRUD 和定时订阅消息推送 - 新增 .gitea/workflows/deploy.yml:推送即触发群晖 Docker 部署,监听 15002 - utils/api.js:自动按 envVersion 切换本地/线上 BASE_URL - app.js 与 add-anniversary.js 移除 wx.cloud 调用,改走自建后端 - cloudfunctions/ 暂保留以便回滚 - 一并提交此前未入库的首页 / 设置页 / 日历 / 万年历等改造 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+93
-37
@@ -1,56 +1,112 @@
|
||||
<!--index.wxml-->
|
||||
<view class="container">
|
||||
<view class="page">
|
||||
|
||||
<!-- 顶部 Header -->
|
||||
<view class="header">
|
||||
<view class="header-top">
|
||||
<view class="header-left">
|
||||
<text class="header-title">生日提醒</text>
|
||||
<text class="header-date">{{todayText}}</text>
|
||||
</view>
|
||||
<view class="header-icon">🎂</view>
|
||||
</view>
|
||||
<view class="stats-row">
|
||||
<view class="stat-item">
|
||||
<text class="stat-num">{{totalCount}}</text>
|
||||
<text class="stat-label">位好友</text>
|
||||
</view>
|
||||
<view class="stat-sep"></view>
|
||||
<view class="stat-item">
|
||||
<text class="stat-num {{upcomingCount > 0 ? 'stat-num-urgent' : ''}}">{{upcomingCount}}</text>
|
||||
<text class="stat-label">即将到来</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 搜索栏 -->
|
||||
<view class="search-bar">
|
||||
<input class="search-input" placeholder="搜索姓名" value="{{searchKeyword}}" bindinput="onSearchInput" />
|
||||
<view class="search-wrap">
|
||||
<view class="search-box">
|
||||
<text class="search-icon">🔍</text>
|
||||
<input
|
||||
class="search-input"
|
||||
placeholder="搜索姓名或昵称"
|
||||
placeholder-class="search-placeholder"
|
||||
value="{{searchKeyword}}"
|
||||
bindinput="onSearchInput"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 筛选栏 -->
|
||||
<view class="filter-bar">
|
||||
<text class="filter-label">筛选:</text>
|
||||
<scroll-view class="filter-scroll" scroll-x>
|
||||
<view class="filter-item {{currentFilter === 'all' ? 'active' : ''}}" bindtap="onFilterTap" data-filter="all">全部</view>
|
||||
<view class="filter-item {{currentFilter === 'birthday' ? 'active' : ''}}" bindtap="onFilterTap" data-filter="birthday">生日</view>
|
||||
<view class="filter-item {{currentFilter === 'anniversary' ? 'active' : ''}}" bindtap="onFilterTap" data-filter="anniversary">纪念日</view>
|
||||
<view class="filter-item {{currentFilter === 'upcoming' ? 'active' : ''}}" bindtap="onFilterTap" data-filter="upcoming">即将到来</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
<scroll-view class="filter-scroll" scroll-x enable-flex>
|
||||
<view class="filter-bar">
|
||||
<view class="filter-tab {{currentFilter === 'all' ? 'tab-active' : ''}}" bindtap="onFilterTap" data-filter="all">全部</view>
|
||||
<view class="filter-tab {{currentFilter === 'birthday' ? 'tab-active' : ''}}" bindtap="onFilterTap" data-filter="birthday">🎂 生日</view>
|
||||
<view class="filter-tab {{currentFilter === 'anniversary' ? 'tab-active' : ''}}" bindtap="onFilterTap" data-filter="anniversary">💍 纪念日</view>
|
||||
<view class="filter-tab {{currentFilter === 'upcoming' ? 'tab-active' : ''}}" bindtap="onFilterTap" data-filter="upcoming">⏰ 即将到来</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
|
||||
<!-- 人员列表 -->
|
||||
<scroll-view class="person-list" scroll-y>
|
||||
<view wx:if="{{persons.length === 0}}" class="empty-state">
|
||||
<text class="icon">📅</text>
|
||||
<text class="text">还没有添加任何人</text>
|
||||
<text class="hint">点击右下角 + 添加第一个</text>
|
||||
<scroll-view class="list" scroll-y>
|
||||
|
||||
<!-- 空状态 -->
|
||||
<view wx:if="{{persons.length === 0}}" class="empty">
|
||||
<text class="empty-icon">🌟</text>
|
||||
<text class="empty-title">还没有添加任何人</text>
|
||||
<text class="empty-hint">点击右下角 + 开始添加</text>
|
||||
</view>
|
||||
|
||||
<view wx:for="{{persons}}" wx:key="id" class="person-card" bindtap="onPersonTap" data-id="{{item.id}}">
|
||||
<view class="person-header">
|
||||
<image class="avatar" src="{{item.avatar || '/images/default-avatar.png'}}" mode="aspectFill" />
|
||||
<view class="person-info">
|
||||
<text class="person-name">{{item.name}}</text>
|
||||
<text wx:if="{{item.nickname}}" class="person-nickname">{{item.nickname}}</text>
|
||||
</view>
|
||||
<view class="person-count">
|
||||
<text wx:if="{{item.anniversaryCount}}" class="count-text">{{item.anniversaryCount}}</text>
|
||||
<text class="count-label">个纪念日</text>
|
||||
<!-- 人员卡片 -->
|
||||
<view
|
||||
wx:for="{{persons}}"
|
||||
wx:key="id"
|
||||
class="card {{item.nextAnniversary && item.nextAnniversary.daysUntil === 0 ? 'card-today' : item.nextAnniversary && item.nextAnniversary.daysUntil <= 7 ? 'card-urgent' : ''}}"
|
||||
bindtap="onPersonTap"
|
||||
data-id="{{item.id}}"
|
||||
>
|
||||
<!-- 左侧头像 -->
|
||||
<view class="avatar-wrap">
|
||||
<image wx:if="{{item.avatar}}" class="avatar-img" src="{{item.avatar}}" mode="aspectFill" />
|
||||
<view wx:else class="avatar-placeholder">
|
||||
<text class="avatar-initial">{{item.name[0]}}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 最近的纪念日 -->
|
||||
<view wx:if="{{item.nextAnniversary}}" class="next-anniversary">
|
||||
<text class="next-label">📌 </text>
|
||||
<text class="next-text">{{item.nextAnniversary.type}}: {{item.nextAnniversary.dateText}}</text>
|
||||
<text wx:if="{{item.nextAnniversary.daysUntil}}" class="days-text {{item.nextAnniversary.daysUntil <= 7 ? 'urgent' : ''}}">
|
||||
{{item.nextAnniversary.daysUntilText}}
|
||||
</text>
|
||||
|
||||
<!-- 右侧内容 -->
|
||||
<view class="card-body">
|
||||
<view class="card-row-top">
|
||||
<view class="name-group">
|
||||
<text class="card-name">{{item.name}}</text>
|
||||
<text wx:if="{{item.nickname}}" class="card-nickname">{{item.nickname}}</text>
|
||||
</view>
|
||||
<view
|
||||
wx:if="{{item.nextAnniversary}}"
|
||||
class="badge {{item.nextAnniversary.daysUntil === 0 ? 'badge-today' : item.nextAnniversary.daysUntil <= 3 ? 'badge-hot' : item.nextAnniversary.daysUntil <= 7 ? 'badge-soon' : item.nextAnniversary.daysUntil <= 30 ? 'badge-month' : 'badge-normal'}}"
|
||||
>
|
||||
<text class="badge-text">{{item.nextAnniversary.daysUntilText}}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view wx:if="{{item.nextAnniversary}}" class="card-row-ann">
|
||||
<text class="ann-icon">
|
||||
{{item.nextAnniversary.type === 'birthday' || item.nextAnniversary.type === 'lunar_birthday' ? '🎂' : item.nextAnniversary.type === 'wedding' ? '💍' : item.nextAnniversary.type === 'engagement' ? '💕' : '📅'}}
|
||||
</text>
|
||||
<text class="ann-info">{{item.nextAnniversary.typeName}} · {{item.nextAnniversary.dateText}}</text>
|
||||
<text wx:if="{{item.anniversaryCount > 1}}" class="ann-more">+{{item.anniversaryCount - 1}}</text>
|
||||
</view>
|
||||
<view wx:else class="card-row-ann no-ann">
|
||||
<text class="ann-info muted">暂无纪念日</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="list-bottom"></view>
|
||||
</scroll-view>
|
||||
|
||||
<!-- 浮动添加按钮 -->
|
||||
<view class="fab" bindtap="onAddTap">
|
||||
<text>+</text>
|
||||
<text class="fab-icon">+</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
|
||||
Reference in New Issue
Block a user