chore: establish V1.1 recovery baseline

This commit is contained in:
2026-09-09 22:05:00 +08:00
commit b46b48eb33
947 changed files with 155471 additions and 0 deletions
+30
View File
@@ -0,0 +1,30 @@
/**
* UserCard 用户卡片(列表项 / Discover / 活动互选)
*
* 不携带任何操作按钮,纯展示;操作按钮由调用方 slot 注入。
* 用法:
* <ui-user-card user="{{user}}" bind:tap="onTap">
* <view slot="actions">…自定义按钮…</view>
* </ui-user-card>
*/
Component({
options: { addGlobalClass: true, multipleSlots: true },
properties: {
user: { type: Object, value: null },
showReasons: { type: Boolean, value: false }, // 是否展示推荐理由
selectable: { type: Boolean, value: false }, // 是否显示选择框
selected: { type: Boolean, value: false },
},
methods: {
onTap() {
if (!this.data.user) return;
this.triggerEvent('tap', { userId: this.data.user.userId });
},
onToggleSelect() {
this.triggerEvent('select', {
userId: this.data.user.userId,
selected: !this.data.selected,
});
},
},
});
+7
View File
@@ -0,0 +1,7 @@
{
"component": true,
"usingComponents": {
"ui-avatar": "../avatar/index",
"ui-status-badge": "../status-badge/index"
}
}
+34
View File
@@ -0,0 +1,34 @@
<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>
</view>
<ui-avatar
src="{{user.avatarUrl}}"
size="lg"
verified="{{user.verified}}"
reviewed="{{user.reviewed}}"
default-text="{{user.displayName}}"
bind:tap="onTap"
/>
<view class="ui-user-card__body">
<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>
</view>
<view class="ui-user-card__meta">
<text wx:if="{{user.heightCm}}">{{user.heightCm}}cm · </text>
<text>{{user.regionName}}</text>
<text wx:if="{{user.educationCode}}"> · {{user.educationCode}}</text>
</view>
<view wx:if="{{user.occupationCode}}" class="ui-user-card__meta">
{{user.occupationCode}}
</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>
</view>
</view>
<view class="ui-user-card__actions">
<slot name="actions"></slot>
</view>
</view>
+64
View File
@@ -0,0 +1,64 @@
.ui-user-card {
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);
}
.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);
}
.ui-user-card__body {
flex: 1;
min-width: 0;
margin-left: var(--spacing-3);
}
.ui-user-card__name-row {
display: flex;
align-items: baseline;
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);
margin-right: var(--spacing-2);
}
.ui-user-card__age {
font-size: var(--font-size-sm);
color: var(--color-text-tertiary);
}
.ui-user-card__meta {
font-size: var(--font-size-sm);
color: var(--color-text-secondary);
line-height: var(--line-height-normal);
margin-top: 4rpx;
}
.ui-user-card__actions {
flex-shrink: 0;
margin-left: var(--spacing-2);
}