feat: redesign discovery and messages tabs
This commit is contained in:
@@ -18,6 +18,8 @@ Component({
|
||||
this.triggerEvent('tap', {
|
||||
conversationId: this.data.conversation.conversationId,
|
||||
targetUserId: this.data.conversation.targetUserId,
|
||||
canSendMessage: this.data.conversation.canSendMessage,
|
||||
relationStatus: this.data.conversation.relationStatus,
|
||||
});
|
||||
},
|
||||
},
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
.ui-conv {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
align-items: center;
|
||||
background: var(--color-bg-card);
|
||||
padding: var(--spacing-3) var(--spacing-page-x);
|
||||
padding: 18rpx 20rpx;
|
||||
border-bottom: 1rpx solid var(--color-divider);
|
||||
}
|
||||
.ui-conv--disabled {
|
||||
@@ -19,13 +19,13 @@
|
||||
align-items: baseline;
|
||||
}
|
||||
.ui-conv__name {
|
||||
font-size: var(--font-size-lg);
|
||||
font-weight: var(--font-weight-medium);
|
||||
color: var(--color-text-primary);
|
||||
color: #222746;
|
||||
font-size: 26rpx;
|
||||
font-weight: 650;
|
||||
}
|
||||
.ui-conv__time {
|
||||
font-size: var(--font-size-xs);
|
||||
color: var(--color-text-tertiary);
|
||||
color: #8b90a5;
|
||||
font-size: 19rpx;
|
||||
flex-shrink: 0;
|
||||
margin-left: var(--spacing-2);
|
||||
}
|
||||
@@ -38,8 +38,8 @@
|
||||
.ui-conv__last {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
font-size: var(--font-size-sm);
|
||||
color: var(--color-text-tertiary);
|
||||
color: #7a8097;
|
||||
font-size: 21rpx;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<view class="ui-user-card" bindtap="onTap">
|
||||
<view wx:if="{{selectable}}" class="ui-user-card__select" catchtap="onToggleSelect">
|
||||
<view class="ui-user-card__checkbox {{selected ? 'ui-user-card__checkbox--checked' : ''}}"></view>
|
||||
<checkbox class="ui-user-card__checkbox" checked="{{selected}}" color="#FF5C82" />
|
||||
</view>
|
||||
<ui-avatar
|
||||
src="{{user.avatarUrl}}"
|
||||
src="{{user.avatarUrl || '/assets/brand/default-avatar.png'}}"
|
||||
size="lg"
|
||||
verified="{{user.verified}}"
|
||||
reviewed="{{user.reviewed}}"
|
||||
@@ -14,6 +14,7 @@
|
||||
<view class="ui-user-card__name-row">
|
||||
<text class="ui-user-card__name">{{user.displayName}}</text>
|
||||
<text class="ui-user-card__age">{{user.age}}岁</text>
|
||||
<text wx:if="{{user.online}}" class="ui-user-card__online">在线</text>
|
||||
</view>
|
||||
<view class="ui-user-card__meta">
|
||||
<text wx:if="{{user.heightCm}}">{{user.heightCm}}cm · </text>
|
||||
@@ -23,6 +24,9 @@
|
||||
<view wx:if="{{user.occupationCode}}" class="ui-user-card__meta">
|
||||
{{user.occupationCode}}
|
||||
</view>
|
||||
<view wx:if="{{user.recommendationReasons && user.recommendationReasons.length}}" class="ui-user-card__tags">
|
||||
<text wx:for="{{user.recommendationReasons}}" wx:key="*this" class="ui-user-card__tag">{{item}}</text>
|
||||
</view>
|
||||
<view wx:if="{{user.maritalStatus || user.hasChildren !== undefined}}" class="ui-user-card__meta">
|
||||
<text wx:if="{{user.maritalStatus}}">{{user.maritalStatus}}</text>
|
||||
<text wx:if="{{user.hasChildren}}"> · 有孩</text>
|
||||
|
||||
@@ -2,40 +2,20 @@
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background: var(--color-bg-card);
|
||||
padding: var(--spacing-3) var(--spacing-page-x);
|
||||
border-bottom: 1rpx solid var(--color-divider);
|
||||
min-height: 148rpx;
|
||||
padding: 14rpx 18rpx;
|
||||
border-bottom: 1rpx solid #F0F1F6;
|
||||
}
|
||||
.ui-user-card__select {
|
||||
margin-right: var(--spacing-3);
|
||||
}
|
||||
.ui-user-card__checkbox {
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
border-radius: 50%;
|
||||
border: 2rpx solid var(--color-text-disabled);
|
||||
position: relative;
|
||||
background: var(--color-bg-card);
|
||||
transition: all var(--motion-fast) var(--ease-standard);
|
||||
}
|
||||
.ui-user-card__checkbox--checked {
|
||||
background: var(--color-primary);
|
||||
border-color: var(--color-primary);
|
||||
}
|
||||
.ui-user-card__checkbox--checked::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 12rpx;
|
||||
top: 6rpx;
|
||||
width: 10rpx;
|
||||
height: 18rpx;
|
||||
border: solid #FFFFFF;
|
||||
border-width: 0 3rpx 3rpx 0;
|
||||
transform: rotate(45deg);
|
||||
transform: scale(.82);
|
||||
}
|
||||
.ui-user-card__body {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
margin-left: var(--spacing-3);
|
||||
margin-left: 16rpx;
|
||||
}
|
||||
.ui-user-card__name-row {
|
||||
display: flex;
|
||||
@@ -43,22 +23,28 @@
|
||||
margin-bottom: var(--spacing-1);
|
||||
}
|
||||
.ui-user-card__name {
|
||||
font-size: var(--font-size-lg);
|
||||
font-weight: var(--font-weight-semibold);
|
||||
color: var(--color-text-primary);
|
||||
font-size: 26rpx;
|
||||
font-weight: 700;
|
||||
color: #222746;
|
||||
margin-right: var(--spacing-2);
|
||||
}
|
||||
.ui-user-card__age {
|
||||
font-size: var(--font-size-sm);
|
||||
color: var(--color-text-tertiary);
|
||||
font-size: 21rpx;
|
||||
color: #596079;
|
||||
}
|
||||
.ui-user-card__online {
|
||||
margin-left: auto;
|
||||
color: #39A987;
|
||||
font-size: 18rpx;
|
||||
}
|
||||
.ui-user-card__meta {
|
||||
font-size: var(--font-size-sm);
|
||||
color: var(--color-text-secondary);
|
||||
line-height: var(--line-height-normal);
|
||||
font-size: 20rpx;
|
||||
color: #767C94;
|
||||
line-height: 1.4;
|
||||
margin-top: 4rpx;
|
||||
}
|
||||
.ui-user-card__actions {
|
||||
flex-shrink: 0;
|
||||
margin-left: var(--spacing-2);
|
||||
}
|
||||
.ui-user-card__tags{display:flex;gap:7rpx;margin-top:8rpx;overflow:hidden}.ui-user-card__tag{flex:none;padding:4rpx 9rpx;border-radius:12rpx;background:#F3EEFF;color:#7860AE;font-size:17rpx;white-space:nowrap}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
{
|
||||
"navigationBarTitleText": "找对象",
|
||||
"navigationStyle": "custom",
|
||||
"enablePullDownRefresh": true,
|
||||
"backgroundColor": "#F7F8FA",
|
||||
"backgroundColor": "#1D205F",
|
||||
"backgroundTextStyle": "dark",
|
||||
"usingComponents": {
|
||||
"ui-user-card": "/components/user-card/index",
|
||||
|
||||
@@ -1,131 +1,24 @@
|
||||
<!-- 找对象页 U19-U20(重构:ui-user-card + matchStore + recommendationService.discover) -->
|
||||
<view class="page app-page reference-page">
|
||||
<!-- 搜索栏 -->
|
||||
<view class="search-bar">
|
||||
<view class="search-input">
|
||||
<text class="search-icon">搜索</text>
|
||||
<input
|
||||
class="search-field"
|
||||
placeholder="搜索符合条件的对象"
|
||||
placeholder-class="search-placeholder"
|
||||
value="{{keywordInput}}"
|
||||
bindinput="onKeywordInput"
|
||||
confirm-type="search"
|
||||
bindconfirm="onSearch"
|
||||
/>
|
||||
</view>
|
||||
<view class="filter-btn {{showFilter ? 'active' : ''}} {{hasActiveFilter ? 'has-filter' : ''}}" bindtap="toggleFilter">
|
||||
<text>筛选</text>
|
||||
<view wx:if="{{hasActiveFilter}}" class="filter-dot"></view>
|
||||
<view class="discover-hero">
|
||||
<view class="discover-nav"><text class="nav-title">找对象</text><view class="nav-search" bindtap="toggleFilter"><image src="/assets/icons/ui/search.png" mode="aspectFit" /></view></view>
|
||||
<view class="search-bar">
|
||||
<view class="search-input"><text class="search-label">搜索</text><input class="search-field" placeholder="姓名、职业或地区" placeholder-class="search-placeholder" value="{{keywordInput}}" bindinput="onKeywordInput" confirm-type="search" bindconfirm="onSearch" /></view>
|
||||
</view>
|
||||
<scroll-view scroll-x class="filter-scroll discover-filter-chips"><view class="filter-chips"><view class="filter-chip active" bindtap="onResetFilter">推荐</view><view class="filter-chip {{tempRegion === '丹阳' ? 'active' : ''}}" bindtap="onRegionTap" data-val="丹阳">丹阳本地</view><view class="filter-chip" bindtap="toggleFilter">附近</view><view class="filter-chip {{hasActiveFilter ? 'active' : ''}}" bindtap="toggleFilter">年龄</view><view class="filter-chip" bindtap="toggleFilter">学历</view><view class="filter-chip" bindtap="toggleFilter">更多筛选</view></view></scroll-view>
|
||||
</view>
|
||||
|
||||
<!-- 筛选面板 -->
|
||||
<view wx:if="{{showFilter}}" class="filter-panel">
|
||||
<view class="filter-section">
|
||||
<text class="filter-label">年龄范围</text>
|
||||
<view class="range-row">
|
||||
<text class="range-value">{{tempAgeMin}} 岁</text>
|
||||
<slider
|
||||
class="range-slider"
|
||||
min="{{18}}"
|
||||
max="{{60}}"
|
||||
value="{{tempAgeMin}}"
|
||||
activeColor="{{'#E96B6B'}}"
|
||||
backgroundColor="{{'#F0F0F0'}}"
|
||||
block-size="{{20}}"
|
||||
bindchange="onMinAgeChange"
|
||||
/>
|
||||
<text class="range-value">{{tempAgeMax}} 岁</text>
|
||||
</view>
|
||||
<slider
|
||||
class="range-slider"
|
||||
min="{{18}}"
|
||||
max="{{60}}"
|
||||
value="{{tempAgeMax}}"
|
||||
activeColor="{{'#E96B6B'}}"
|
||||
backgroundColor="{{'#F0F0F0'}}"
|
||||
block-size="{{20}}"
|
||||
bindchange="onMaxAgeChange"
|
||||
/>
|
||||
</view>
|
||||
|
||||
<view class="filter-section">
|
||||
<text class="filter-label">地区</text>
|
||||
<view class="tag-group">
|
||||
<view
|
||||
wx:for="{{regions}}"
|
||||
wx:key="*this"
|
||||
class="tag {{tempRegion === item ? 'selected' : ''}}"
|
||||
bindtap="onRegionTap"
|
||||
data-val="{{item}}"
|
||||
>{{item}}</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="filter-actions">
|
||||
<ui-button variant="ghost" size="md" block bind:tap="onResetFilter">重置</ui-button>
|
||||
<ui-button variant="primary" size="md" block bind:tap="onApplyFilter">应用筛选</ui-button>
|
||||
</view>
|
||||
<view class="filter-section"><view class="filter-heading"><text class="filter-label">年龄范围</text><text class="filter-value">{{tempAgeMin}}–{{tempAgeMax}} 岁</text></view><slider class="range-slider" min="18" max="60" value="{{tempAgeMin}}" activeColor="#FF4F91" backgroundColor="#E9EAF2" block-size="18" bindchange="onMinAgeChange" /><slider class="range-slider" min="18" max="60" value="{{tempAgeMax}}" activeColor="#7B63D9" backgroundColor="#E9EAF2" block-size="18" bindchange="onMaxAgeChange" /></view>
|
||||
<view class="filter-section"><text class="filter-label">地区</text><view class="tag-group"><view wx:for="{{regions}}" wx:key="*this" class="tag {{tempRegion === item ? 'selected' : ''}}" bindtap="onRegionTap" data-val="{{item}}">{{item}}</view></view></view>
|
||||
<view class="filter-actions"><ui-button variant="ghost" size="md" block bind:tap="onResetFilter">重置</ui-button><ui-button variant="primary" size="md" block bind:tap="onApplyFilter">应用筛选</ui-button></view>
|
||||
</view>
|
||||
|
||||
<!-- 区块标题 -->
|
||||
<ui-section-header
|
||||
wx:if="{{users.length > 0 || loading}}"
|
||||
title="找对象"
|
||||
subtitle="{{hasActiveFilter ? '已应用筛选' : '共 ' + users.length + ' 位'}}"
|
||||
/>
|
||||
|
||||
<!-- 首次加载(骨架屏) -->
|
||||
<ui-loading
|
||||
wx:if="{{loading && users.length === 0}}"
|
||||
mode="skeleton"
|
||||
rows="5"
|
||||
/>
|
||||
|
||||
<!-- 用户列表 -->
|
||||
<block wx:elif="{{users.length > 0}}">
|
||||
<view class="user-list">
|
||||
<ui-user-card
|
||||
wx:for="{{users}}"
|
||||
wx:key="userId"
|
||||
user="{{item}}"
|
||||
bind:tap="onViewDetail"
|
||||
>
|
||||
<view
|
||||
slot="actions"
|
||||
class="card-action"
|
||||
catchtap="onLike"
|
||||
data-user-id="{{item.userId}}"
|
||||
>
|
||||
<ui-button
|
||||
variant="primary"
|
||||
size="sm"
|
||||
loading="{{actionLoadingUserId === item.userId}}"
|
||||
>喜欢</ui-button>
|
||||
</view>
|
||||
</ui-user-card>
|
||||
|
||||
<!-- 加载更多 -->
|
||||
<ui-loading
|
||||
wx:if="{{loadingMore}}"
|
||||
mode="spinner"
|
||||
inline
|
||||
text="加载更多…"
|
||||
/>
|
||||
<view wx:if="{{!hasMore && users.length > 0}}" class="list-end-hint">
|
||||
<text>没有更多了</text>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
|
||||
<!-- 空状态 -->
|
||||
<ui-empty
|
||||
wx:elif="{{!loading}}"
|
||||
illustration="search"
|
||||
title="暂无符合条件的人选"
|
||||
description="尝试调整筛选条件,或看看今天为你推荐的人。"
|
||||
actions="{{emptyActions}}"
|
||||
bind:action="onEmptyAction"
|
||||
/>
|
||||
<view class="result-head" wx:if="{{users.length > 0 || loading}}"><view><text class="result-title">为你推荐</text><text class="result-subtitle">{{hasActiveFilter ? '已按当前条件筛选' : '认真认识,再做选择'}}</text></view><text class="result-count">{{users.length}} 位</text></view>
|
||||
<ui-loading wx:if="{{loading && users.length === 0}}" mode="skeleton" rows="5" />
|
||||
<view wx:elif="{{users.length > 0}}" class="user-list candidate-list">
|
||||
<ui-user-card wx:for="{{users}}" wx:key="userId" user="{{item}}" bind:tap="onViewDetail"><view slot="actions" class="card-action" catchtap="onLike" data-user-id="{{item.userId}}"><view class="like-button {{actionLoadingUserId === item.userId ? 'loading' : ''}}"><image src="/assets/brand/logo-mark.png" mode="aspectFit" /></view></view></ui-user-card>
|
||||
<ui-loading wx:if="{{loadingMore}}" mode="spinner" inline text="加载更多…" />
|
||||
<view wx:if="{{!hasMore && users.length > 0}}" class="list-end-hint">真诚相遇,认真选择</view>
|
||||
</view>
|
||||
<view wx:elif="{{!loading}}" class="discover-empty"><image src="/assets/brand/logo-mark.png" mode="aspectFit" /><text class="empty-title">暂无符合条件的人选</text><text class="empty-desc">Required 条件不会自动放宽,可以调整筛选后再看看</text><view class="empty-action" bindtap="onResetFilter">清空筛选</view></view>
|
||||
</view>
|
||||
|
||||
@@ -1,157 +1,4 @@
|
||||
/**
|
||||
* 找对象页样式(重构后大幅简化,用户卡片主体样式封装在 ui-user-card 内)
|
||||
*/
|
||||
.page {
|
||||
min-height: 100vh;
|
||||
background: var(--color-bg-page);
|
||||
}
|
||||
|
||||
/* ============ 搜索栏 ============ */
|
||||
.search-bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: var(--spacing-3) var(--spacing-page-x);
|
||||
background: var(--color-bg-card);
|
||||
gap: var(--spacing-2);
|
||||
border-bottom: var(--border-width) solid var(--color-divider);
|
||||
}
|
||||
|
||||
.search-input {
|
||||
flex: 1;
|
||||
height: 72rpx;
|
||||
background: var(--color-bg-page);
|
||||
border-radius: var(--radius-full);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 var(--spacing-3);
|
||||
gap: var(--spacing-2);
|
||||
}
|
||||
|
||||
.search-icon {
|
||||
font-size: var(--font-size-md);
|
||||
color: var(--color-text-placeholder);
|
||||
}
|
||||
|
||||
.search-field {
|
||||
flex: 1;
|
||||
font-size: var(--font-size-md);
|
||||
color: var(--color-text-primary);
|
||||
}
|
||||
|
||||
.search-placeholder {
|
||||
color: var(--color-text-placeholder);
|
||||
font-size: var(--font-size-md);
|
||||
}
|
||||
|
||||
.filter-btn {
|
||||
min-width: 120rpx;
|
||||
height: 72rpx;
|
||||
background: var(--color-primary-light);
|
||||
border-radius: var(--radius-full);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: var(--font-size-sm);
|
||||
color: var(--color-primary);
|
||||
position: relative;
|
||||
padding: 0 var(--spacing-3);
|
||||
}
|
||||
|
||||
.filter-btn.active {
|
||||
background: var(--color-primary);
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
.filter-dot {
|
||||
width: 12rpx;
|
||||
height: 12rpx;
|
||||
background: var(--color-primary);
|
||||
border-radius: 50%;
|
||||
position: absolute;
|
||||
top: 12rpx;
|
||||
right: 12rpx;
|
||||
}
|
||||
|
||||
.filter-btn.active .filter-dot {
|
||||
background: #FFFFFF;
|
||||
}
|
||||
|
||||
/* ============ 筛选面板 ============ */
|
||||
.filter-panel {
|
||||
background: var(--color-bg-card);
|
||||
padding: var(--spacing-4) var(--spacing-page-x);
|
||||
border-bottom: var(--border-width) solid var(--color-divider);
|
||||
}
|
||||
|
||||
.filter-section {
|
||||
margin-bottom: var(--spacing-4);
|
||||
}
|
||||
|
||||
.filter-label {
|
||||
font-size: var(--font-size-md);
|
||||
font-weight: var(--font-weight-semibold);
|
||||
color: var(--color-text-primary);
|
||||
display: block;
|
||||
margin-bottom: var(--spacing-2);
|
||||
}
|
||||
|
||||
.range-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--spacing-2);
|
||||
}
|
||||
|
||||
.range-value {
|
||||
min-width: 96rpx;
|
||||
font-size: var(--font-size-sm);
|
||||
color: var(--color-text-secondary);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.range-slider {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.tag-group {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: var(--spacing-2);
|
||||
}
|
||||
|
||||
.tag {
|
||||
padding: var(--spacing-1) var(--spacing-3);
|
||||
border-radius: var(--radius-full);
|
||||
font-size: var(--font-size-sm);
|
||||
background: var(--color-bg-page);
|
||||
color: var(--color-text-secondary);
|
||||
border: 2rpx solid transparent;
|
||||
}
|
||||
|
||||
.tag.selected {
|
||||
background: var(--color-primary);
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
.filter-actions {
|
||||
display: flex;
|
||||
gap: var(--spacing-3);
|
||||
margin-top: var(--spacing-2);
|
||||
}
|
||||
|
||||
/* ============ 用户列表 ============ */
|
||||
.user-list {
|
||||
background: var(--color-bg-card);
|
||||
margin-top: var(--spacing-2);
|
||||
}
|
||||
|
||||
.card-action {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.list-end-hint {
|
||||
text-align: center;
|
||||
padding: var(--spacing-3);
|
||||
color: var(--color-text-tertiary);
|
||||
font-size: var(--font-size-xs);
|
||||
}
|
||||
.page{min-height:100vh;background:#F4F5FA}.discover-hero{padding:env(safe-area-inset-top) 24rpx 24rpx;background:linear-gradient(160deg,var(--mini-night-start),var(--mini-night-end));border-radius:0 0 34rpx 34rpx;box-shadow:var(--mini-shadow)}.discover-nav{height:88rpx;display:flex;align-items:center;justify-content:center;position:relative;color:#fff}.nav-title{font-size:31rpx;font-weight:700}.nav-search{position:absolute;right:0;width:64rpx;height:64rpx;display:flex;align-items:center;justify-content:center;border:1rpx solid rgba(255,255,255,.18);border-radius:32rpx;background:rgba(255,255,255,.08)}.nav-search image{width:38rpx;height:38rpx;filter:brightness(0) invert(1)}
|
||||
.search-bar{display:flex;align-items:center}.search-input{height:70rpx;flex:1;display:flex;align-items:center;padding:0 20rpx;border-radius:35rpx;background:rgba(255,255,255,.12);border:1rpx solid rgba(255,255,255,.14)}.search-label{margin-right:14rpx;padding-right:14rpx;border-right:1rpx solid rgba(255,255,255,.2);font-size:20rpx;color:#fff}.search-field{flex:1;font-size:23rpx;color:#fff}.search-placeholder{font-size:23rpx;color:rgba(255,255,255,.52)}.filter-scroll{margin-top:16rpx;white-space:nowrap}.filter-chips{display:inline-flex;gap:12rpx}.filter-chip{padding:11rpx 20rpx;border-radius:25rpx;background:rgba(255,255,255,.1);color:rgba(255,255,255,.72);font-size:20rpx}.filter-chip.active{background:#fff;color:var(--mini-accent-pink);font-weight:650}
|
||||
.filter-panel{position:relative;z-index:3;margin:-8rpx 24rpx 0;padding:28rpx;background:#fff;border-radius:0 0 26rpx 26rpx;box-shadow:0 14rpx 36rpx rgba(31,32,89,.12)}.filter-section{margin-bottom:28rpx}.filter-heading{display:flex;justify-content:space-between}.filter-label{display:block;font-size:24rpx;font-weight:650;color:#282D4E}.filter-value{font-size:21rpx;color:#777E99}.range-slider{margin:8rpx 0}.tag-group{display:flex;gap:14rpx;margin-top:16rpx}.tag{padding:10rpx 22rpx;border-radius:22rpx;background:#F1F2F7;color:#626981;font-size:21rpx}.tag.selected{background:#FCEBF3;color:var(--mini-accent-pink)}.filter-actions{display:flex;gap:18rpx}
|
||||
.result-head{padding:30rpx 26rpx 16rpx;display:flex;align-items:flex-end;justify-content:space-between}.result-head>view{display:flex;flex-direction:column}.result-title{font-size:30rpx;font-weight:700;color:#252A49}.result-subtitle{margin-top:5rpx;font-size:20rpx;color:#8A8FA4}.result-count{font-size:20rpx;color:#8A8FA4}.user-list{margin:0 24rpx;padding:4rpx 0;background:#fff;border-radius:28rpx;overflow:hidden;box-shadow:0 10rpx 32rpx rgba(34,35,91,.08)}.card-action{display:flex;align-items:center}.like-button{width:62rpx;height:62rpx;display:flex;align-items:center;justify-content:center;border-radius:31rpx;background:#FFF0F5;box-shadow:0 6rpx 18rpx rgba(255,79,145,.16)}.like-button image{width:42rpx;height:42rpx}.like-button.loading{opacity:.45}.list-end-hint{text-align:center;padding:24rpx;font-size:20rpx;color:#9A9EB0}.discover-empty{margin:70rpx 40rpx 0;padding:34rpx;display:flex;flex-direction:column;align-items:center;background:#fff;border-radius:28rpx;box-shadow:0 10rpx 32rpx rgba(34,35,91,.08)}.discover-empty image{width:112rpx;height:112rpx}.empty-title{margin-top:12rpx;font-size:28rpx;font-weight:650;color:#252A49}.empty-desc{margin-top:10rpx;text-align:center;font-size:21rpx;line-height:1.55;color:#858A9E}.empty-action{margin-top:24rpx;min-width:180rpx;height:64rpx;display:flex;align-items:center;justify-content:center;border-radius:32rpx;background:linear-gradient(135deg,var(--mini-accent-coral),var(--mini-accent-pink));color:#fff;font-size:23rpx;font-weight:650}
|
||||
|
||||
@@ -57,10 +57,27 @@ Page({
|
||||
},
|
||||
|
||||
onGoChat(e) {
|
||||
const { conversationId } = e.detail;
|
||||
const { conversationId, canSendMessage } = e.detail;
|
||||
if (!canSendMessage) {
|
||||
appStore.toastError('当前会话已停用,无法继续聊天');
|
||||
return;
|
||||
}
|
||||
wx.navigateTo({ url: to.chat(conversationId) });
|
||||
},
|
||||
|
||||
onShortcutTap(e) {
|
||||
const key = e.currentTarget.dataset.key;
|
||||
if (key === 'new-friends') {
|
||||
wx.switchTab({ url: ROUTE.TAB.DISCOVER });
|
||||
return;
|
||||
}
|
||||
if (key === 'system') {
|
||||
wx.navigateTo({ url: ROUTE.SETTINGS.NOTIFICATIONS });
|
||||
return;
|
||||
}
|
||||
wx.navigateTo({ url: ROUTE.MAIN.FATE_CENTER });
|
||||
},
|
||||
|
||||
onEmptyAction(e) {
|
||||
if (e.detail.event === 'home') {
|
||||
wx.switchTab({ url: ROUTE.TAB.HOME });
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"navigationBarTitleText": "消息",
|
||||
"navigationStyle": "custom",
|
||||
"enablePullDownRefresh": true,
|
||||
"backgroundColor": "#F7F8FA",
|
||||
"backgroundTextStyle": "dark",
|
||||
|
||||
@@ -1,42 +1,52 @@
|
||||
<!-- 消息列表页 U23 -->
|
||||
<view class="page reference-page">
|
||||
<ui-section-header
|
||||
wx:if="{{conversations.length > 0}}"
|
||||
title="消息"
|
||||
subtitle="{{unreadTotal > 0 ? unreadTotal + ' 条未读' : '全部已读'}}"
|
||||
/>
|
||||
<!-- 消息列表页:仅服务端允许的 Mutual Match 会话可进入聊天 -->
|
||||
<view class="page app-page reference-page">
|
||||
<view class="messages-hero">
|
||||
<view class="messages-nav">
|
||||
<text class="messages-title">消息</text>
|
||||
<image class="messages-search" src="/assets/icons/ui/search.png" mode="aspectFit" />
|
||||
</view>
|
||||
<view class="message-shortcuts">
|
||||
<view class="message-shortcut" bindtap="onShortcutTap" data-key="new-friends">
|
||||
<view class="shortcut-icon shortcut-icon--blue"><image src="/assets/icons/home/find-object.png" mode="aspectFit" /></view>
|
||||
<text>新朋友</text>
|
||||
</view>
|
||||
<view class="message-shortcut" bindtap="onShortcutTap" data-key="likes">
|
||||
<view class="shortcut-icon shortcut-icon--pink"><image src="/assets/brand/logo-mark.png" mode="aspectFit" /></view>
|
||||
<text>互动喜欢</text>
|
||||
</view>
|
||||
<view class="message-shortcut" bindtap="onShortcutTap" data-key="following">
|
||||
<view class="shortcut-icon shortcut-icon--purple"><image src="/assets/icons/home/matchmaker.png" mode="aspectFit" /></view>
|
||||
<text>我的关注</text>
|
||||
</view>
|
||||
<view class="message-shortcut" bindtap="onShortcutTap" data-key="system">
|
||||
<view class="shortcut-icon shortcut-icon--coral"><image src="/assets/icons/ui/warning.png" mode="aspectFit" /></view>
|
||||
<text>系统通知</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 加载中(首次) -->
|
||||
<ui-loading
|
||||
wx:if="{{loading && conversations.length === 0}}"
|
||||
mode="skeleton"
|
||||
rows="4"
|
||||
/>
|
||||
<view class="messages-content">
|
||||
<ui-section-header title="最近联系" subtitle="{{unreadTotal > 0 ? unreadTotal + ' 条未读' : '全部已读'}}" />
|
||||
|
||||
<!-- 会话列表 -->
|
||||
<block wx:elif="{{conversations.length > 0}}">
|
||||
<ui-conversation-item
|
||||
wx:for="{{conversations}}"
|
||||
wx:key="conversationId"
|
||||
conversation="{{item}}"
|
||||
bind:tap="onGoChat"
|
||||
<ui-loading wx:if="{{loading && conversations.length === 0}}" mode="skeleton" rows="4" />
|
||||
|
||||
<view wx:elif="{{conversations.length > 0}}" class="conversation-list">
|
||||
<ui-conversation-item
|
||||
wx:for="{{conversations}}"
|
||||
wx:key="conversationId"
|
||||
conversation="{{item}}"
|
||||
bind:tap="onGoChat"
|
||||
/>
|
||||
<ui-loading wx:if="{{loading}}" mode="spinner" text="加载更多会话" inline />
|
||||
</view>
|
||||
|
||||
<ui-empty
|
||||
wx:elif="{{!loading}}"
|
||||
illustration="message"
|
||||
title="还没有消息"
|
||||
description="互相喜欢后可以开始聊天。去看看今天为你推荐的人吧。"
|
||||
actions="{{emptyActions}}"
|
||||
bind:action="onEmptyAction"
|
||||
/>
|
||||
<!-- 加载更多 -->
|
||||
<ui-loading
|
||||
wx:if="{{loading && conversations.length > 0}}"
|
||||
mode="spinner"
|
||||
text="加载更多会话…"
|
||||
inline
|
||||
/>
|
||||
</block>
|
||||
|
||||
<!-- 空状态 -->
|
||||
<ui-empty
|
||||
wx:elif="{{!loading}}"
|
||||
illustration="message"
|
||||
title="还没有消息"
|
||||
description="互相喜欢后可以开始聊天。去看看今天为你推荐的人吧。"
|
||||
actions="{{emptyActions}}"
|
||||
bind:action="onEmptyAction"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
@@ -1,7 +1,79 @@
|
||||
/**
|
||||
* 消息列表页样式(重构后大幅简化,主体样式封装在 ui-conversation-item 内)
|
||||
*/
|
||||
.page {
|
||||
min-height: 100vh;
|
||||
background: var(--color-bg-page);
|
||||
background: #f4f5fa;
|
||||
}
|
||||
|
||||
.messages-hero {
|
||||
padding: env(safe-area-inset-top) 24rpx 34rpx;
|
||||
border-radius: 0 0 36rpx 36rpx;
|
||||
background: linear-gradient(160deg, var(--mini-night-start), var(--mini-night-end));
|
||||
box-shadow: var(--mini-shadow);
|
||||
}
|
||||
|
||||
.messages-nav {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 88rpx;
|
||||
}
|
||||
|
||||
.messages-title {
|
||||
color: #fff;
|
||||
font-size: 31rpx;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.messages-search {
|
||||
position: absolute;
|
||||
right: 14rpx;
|
||||
width: 34rpx;
|
||||
height: 34rpx;
|
||||
}
|
||||
|
||||
.message-shortcuts {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
padding: 22rpx 8rpx 4rpx;
|
||||
}
|
||||
|
||||
.message-shortcut {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
color: rgba(255, 255, 255, .88);
|
||||
font-size: 20rpx;
|
||||
}
|
||||
|
||||
.shortcut-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 72rpx;
|
||||
height: 72rpx;
|
||||
margin-bottom: 12rpx;
|
||||
border: 1rpx solid rgba(255, 255, 255, .2);
|
||||
border-radius: 26rpx;
|
||||
}
|
||||
|
||||
.shortcut-icon image {
|
||||
width: 45rpx;
|
||||
height: 45rpx;
|
||||
}
|
||||
|
||||
.shortcut-icon--blue { background: rgba(79, 139, 255, .28); }
|
||||
.shortcut-icon--pink { background: rgba(255, 92, 130, .28); }
|
||||
.shortcut-icon--purple { background: rgba(154, 107, 255, .28); }
|
||||
.shortcut-icon--coral { background: rgba(240, 106, 100, .28); }
|
||||
|
||||
.messages-content {
|
||||
padding: 16rpx 24rpx 40rpx;
|
||||
}
|
||||
|
||||
.conversation-list {
|
||||
overflow: hidden;
|
||||
margin-top: 8rpx;
|
||||
border-radius: 28rpx;
|
||||
background: #fff;
|
||||
box-shadow: 0 10rpx 32rpx rgba(34, 35, 91, .08);
|
||||
}
|
||||
|
||||
@@ -54,6 +54,19 @@ for (const code of quickEntryCodes) {
|
||||
previousIndex = index
|
||||
}
|
||||
|
||||
const discoverTemplate = read('miniapp/pages/discover/discover.wxml')
|
||||
assert.match(discoverTemplate, /discover-filter-chips/, '找对象页缺少参考图胶囊筛选区')
|
||||
assert.match(discoverTemplate, /candidate-list/, '找对象页缺少参考图候选人列表')
|
||||
assert.match(discoverTemplate, /\/assets\/icons\/ui\/search\.png/, '找对象页必须使用独立搜索图标')
|
||||
|
||||
const messagesTemplate = read('miniapp/pages/messages/messages.wxml')
|
||||
const messagesLogic = read('miniapp/pages/messages/messages.js')
|
||||
assert.match(messagesTemplate, /message-shortcuts/, '消息页缺少四项快捷入口')
|
||||
assert.match(messagesTemplate, /conversation-list/, '消息页缺少会话列表容器')
|
||||
assert.match(messagesTemplate, /ui-conv__badge|unreadTotal/, '消息页缺少未读提示')
|
||||
assert.match(messagesTemplate, /互相喜欢后/, '消息页缺少无 Mutual 状态说明')
|
||||
assert.match(messagesLogic, /canSendMessage/, '消息页进入聊天前必须校验服务端会话能力')
|
||||
|
||||
const theme = read('miniapp/app.wxss')
|
||||
for (const token of [
|
||||
'--mini-night-start',
|
||||
|
||||
Reference in New Issue
Block a user