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
@@ -0,0 +1,69 @@
/**
* SuccessConfirmDialog 成功牵手双确认弹窗(AGENTS.md 第 6 条)
*
* 双角色:
* - 发起方(请求方):mode="request" → 显示"发起牵手请求"
* - 被请求方(确认方):mode="confirm" → 显示"对方请求与你成功牵手"
*
* 不变量(AGENTS.md):
* - 第 6 条:成功牵手必须双确认——本组件是用户侧的唯一确认入口,
* 点击确认后由调用方调用 stores.confirmSuccess(matchId)(内部触发 matchService.confirmSuccess)。
* - 第 6 条(隐式):发起方 7 天内未确认则请求过期,本组件显示过期倒计时(如有 expiresAt)。
*/
Component({
options: { addGlobalClass: true },
properties: {
visible: { type: Boolean, value: false },
mode: { type: String, value: 'request' }, // request | confirm
targetName: { type: String, value: '' },
expiresAt: { type: Number, value: 0 }, // 过期时间戳(mode=confirm 时由调用方传入)
},
data: {
titleText: '',
contentText: '',
confirmText: '',
expiresInText: '',
},
observers: {
'mode, targetName, expiresAt'(mode, name, expiresAt) {
let title = '';
let content = '';
let confirm = '';
if (mode === 'request') {
title = '发起成功牵手';
content = `发起后 ${name || '对方'} 需在 7 天内确认。双方均确认后,关系将置为"成功牵手",平台不再为你推荐其他人。`;
confirm = '发起牵手请求';
} else {
title = '对方发起牵手请求';
content = `${name || '对方'} 希望与你确认成功牵手。确认后你们的关系将置为"成功牵手",平台不再为你们推荐其他人。`;
confirm = '我同意';
}
let expiresInText = '';
if (expiresAt > 0) {
const remain = expiresAt - Date.now();
if (remain > 0) {
const days = Math.floor(remain / (24 * 3600 * 1000));
const hours = Math.floor((remain % (24 * 3600 * 1000)) / (3600 * 1000));
expiresInText = days > 0 ? `剩余 ${days} 天 ${hours} 小时` : `剩余 ${hours} 小时`;
} else {
expiresInText = '已过期';
}
}
this.setData({
titleText: title,
contentText: content,
confirmText: confirm,
expiresInText,
});
},
},
methods: {
onConfirm() {
this.triggerEvent('confirm', { mode: this.data.mode });
},
onCancel() {
this.triggerEvent('cancel', {});
},
onStop() {},
},
});
@@ -0,0 +1,6 @@
{
"component": true,
"usingComponents": {
"ui-button": "../button/index"
}
}
@@ -0,0 +1,14 @@
<view wx:if="{{visible}}" class="ui-success-mask" catchtap="onCancel">
<view class="ui-success" catchtap="onStop">
<view class="ui-success__heart">
<view class="ui-success__heart-icon"></view>
</view>
<view class="ui-success__title">{{titleText}}</view>
<view class="ui-success__content">{{contentText}}</view>
<view wx:if="{{expiresInText}}" class="ui-success__expires">{{expiresInText}}</view>
<view class="ui-success__actions">
<ui-button variant="ghost" size="md" class="ui-success__btn" bindtap="onCancel">再想想</ui-button>
<ui-button variant="primary" size="md" class="ui-success__btn" bindtap="onConfirm">{{confirmText}}</ui-button>
</view>
</view>
</view>
@@ -0,0 +1,67 @@
.ui-success-mask {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: var(--color-bg-overlay);
z-index: var(--z-modal);
display: flex;
align-items: center;
justify-content: center;
padding: 0 var(--spacing-6);
}
.ui-success {
width: 100%;
max-width: 600rpx;
background: var(--color-bg-card);
border-radius: var(--radius-lg);
padding: var(--spacing-6) var(--spacing-4) var(--spacing-4);
text-align: center;
box-shadow: var(--shadow-popup);
animation: ui-success-in var(--motion-normal) var(--ease-standard);
}
@keyframes ui-success-in {
from { transform: scale(0.92); opacity: 0; }
to { transform: scale(1); opacity: 1; }
}
.ui-success__heart {
width: 120rpx;
height: 120rpx;
margin: 0 auto var(--spacing-3);
background: var(--color-primary-light);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
}
.ui-success__heart-icon {
width: 56rpx;
height: 56rpx;
background: var(--color-primary);
clip-path: polygon(50% 100%, 0 38%, 18% 18%, 50% 38%, 82% 18%, 100% 38%);
}
.ui-success__title {
font-size: var(--font-size-xl);
font-weight: var(--font-weight-semibold);
color: var(--color-text-primary);
margin-bottom: var(--spacing-2);
}
.ui-success__content {
font-size: var(--font-size-md);
color: var(--color-text-secondary);
line-height: var(--line-height-relaxed);
margin-bottom: var(--spacing-2);
}
.ui-success__expires {
font-size: var(--font-size-xs);
color: var(--color-warning);
margin-bottom: var(--spacing-4);
}
.ui-success__actions {
display: flex;
gap: var(--spacing-2);
}
.ui-success__btn {
flex: 1;
}