CI/CD Pipeline / Test Shell Guard (Phase 23 Gate) (push) Canceled after 0s
CI/CD Pipeline / Backend Build & Test (push) Canceled after 0s
CI/CD Pipeline / Admin Web Build (push) Canceled after 0s
CI/CD Pipeline / Mini Program Compile Check (push) Canceled after 0s
CI/CD Pipeline / Migration Validation (push) Canceled after 0s
CI/CD Pipeline / UI Contracts (source-structure gates) (push) Canceled after 0s
CI/CD Pipeline / E2E (live stack) (push) Canceled after 0s
253 lines
7.4 KiB
TypeScript
253 lines
7.4 KiB
TypeScript
/**
|
||
* 业务类型定义(规范 §134 types 目录)
|
||
*
|
||
* 统一存放 User / Profile / PartnerPreference / MatchRelation / Conversation /
|
||
* Activity / MatchmakerService / Report 等核心类型。
|
||
* 配合 package.json 的 `tsc --noEmit` 提供 IntelliSense 与类型检查。
|
||
* 状态字符串引用 constants/statusEnums.js 的同名常量,避免魔法字符串。
|
||
*/
|
||
|
||
// ============ 统一 API 响应(规范 §1 API 规范) ============
|
||
export interface ApiResponse<T = unknown> {
|
||
success: boolean;
|
||
code: string;
|
||
message: string;
|
||
data: T;
|
||
requestId?: string;
|
||
}
|
||
|
||
export interface ApiError {
|
||
code: string;
|
||
message: string;
|
||
requestId?: string;
|
||
/** 原始错误(仅 NETWORK_ERROR 携带) */
|
||
error?: unknown;
|
||
}
|
||
|
||
// ============ User / Profile(规范 §107-108) ============
|
||
export interface User {
|
||
displayId?: string
|
||
displayNumber?: string
|
||
userDisplayNumber?: string
|
||
serviceDisplayId?: string
|
||
userId: string;
|
||
displayName: string; // 前台显示:王女士
|
||
age: number; // 前台显示:32
|
||
heightCm?: number;
|
||
regionName: string; // 前台显示:丹阳
|
||
educationCode?: string; // 本科 / 大专 / 硕士 等
|
||
occupationCode?: string; // 教师 / 制造业 等(不公开 XX公司XX部门)
|
||
maritalStatus?: MaritalStatus;
|
||
avatarUrl?: string;
|
||
verified?: boolean; // 已实名
|
||
reviewed?: boolean; // 已审核
|
||
photoUrls?: string[];
|
||
}
|
||
|
||
export type MaritalStatus = 'never_married' | 'divorced' | 'widowed';
|
||
|
||
export interface Profile {
|
||
userId: string;
|
||
displayName: string;
|
||
avatarUrl?: string;
|
||
photoUrls: string[];
|
||
birthDate?: string; // 服务端存储完整,前台只显示 age
|
||
heightCm?: number;
|
||
regionName: string;
|
||
educationCode?: string;
|
||
occupationCode?: string;
|
||
maritalStatus: MaritalStatus;
|
||
hasChildren: boolean;
|
||
smoking: boolean;
|
||
drinking?: DrinkingHabit;
|
||
interests: string[];
|
||
intro: string; // 自我介绍
|
||
intent: RelationshipIntent; // 婚恋态度
|
||
}
|
||
|
||
export type DrinkingHabit = 'never' | 'occasionally' | 'frequently';
|
||
|
||
export type RelationshipIntent =
|
||
| 'serious_marriage' // 认真找对象结婚
|
||
| 'getting_to_know' // 先了解
|
||
| 'open_minded'; // 顺其自然
|
||
|
||
// ============ PartnerPreference(择偶条件,规范 §30) ============
|
||
export interface PartnerPreference {
|
||
ageMin: number;
|
||
ageMax: number;
|
||
ageImportance: PreferenceImportance; // 必须符合 / 最好符合
|
||
heightMin?: number;
|
||
heightMax?: number;
|
||
heightImportance: PreferenceImportance;
|
||
region: string[]; // [丹阳]
|
||
regionImportance: PreferenceImportance;
|
||
maritalStatusAccepted: MaritalStatus[];
|
||
educationAccepted: string[]; // [不限/大专+/本科+]
|
||
acceptChildren: 'any' | 'accept' | 'reject';
|
||
intentAligned: boolean; // 婚恋计划一致
|
||
}
|
||
|
||
export type PreferenceImportance = 'required' | 'preferred'; // 必须符合 / 最好符合
|
||
|
||
// ============ MatchRelation / Recommendation(规范 §22-25, §107-108) ============
|
||
export type RelationStatus =
|
||
| 'neutral'
|
||
| 'liked'
|
||
| 'passed'
|
||
| 'mutual_match'
|
||
| 'blocked'
|
||
| 'unmatched';
|
||
|
||
export interface Recommendation extends User {
|
||
recommendationReasons: string[]; // 最多 3~4 条,弱文字
|
||
recommendationLevel?: 'high' | 'medium' | 'normal';
|
||
relationStatus: RelationStatus;
|
||
likeStatus?: 'liked' | 'passed';
|
||
}
|
||
|
||
export interface LikeResult {
|
||
relationStatus: RelationStatus;
|
||
mutualMatch: boolean;
|
||
}
|
||
|
||
// ============ Conversation / Message(规范 §35-38, §61-63) ============
|
||
export interface Conversation {
|
||
conversationId: string;
|
||
targetUserId: string;
|
||
targetDisplayName: string;
|
||
targetAvatarUrl?: string;
|
||
lastMessage?: string;
|
||
lastMessageAt?: number; // 服务端时间戳
|
||
unreadCount: number;
|
||
relationStatus: RelationStatus;
|
||
canSendMessage: boolean; // 仅 mutual_match + 双方正常 + 未拉黑 + 未解除
|
||
}
|
||
|
||
export type MessageSendStatus = 'sending' | 'sent' | 'failed';
|
||
export type ChatBubbleType = 'self' | 'other' | 'system';
|
||
|
||
export interface Message {
|
||
messageId: string; // 前端去重依据(规范 §106)
|
||
conversationId: string;
|
||
senderId: string;
|
||
bubbleType: ChatBubbleType;
|
||
content: string;
|
||
sentAt: number;
|
||
sendStatus?: MessageSendStatus; // 本地消息状态
|
||
}
|
||
|
||
// ============ Activity(规范 §43-46) ============
|
||
export type ActivityStatus =
|
||
| 'draft'
|
||
| 'registration_open'
|
||
| 'registration_closed'
|
||
| 'ongoing'
|
||
| 'ended'
|
||
| 'cancelled';
|
||
|
||
export type RegistrationStatus =
|
||
| 'not_applied'
|
||
| 'pending'
|
||
| 'approved'
|
||
| 'rejected'
|
||
| 'cancelled';
|
||
|
||
export interface Activity {
|
||
displayId?: string
|
||
displayNumber?: string
|
||
userDisplayNumber?: string
|
||
serviceDisplayId?: string
|
||
activityId: string;
|
||
title: string;
|
||
coverUrl?: string;
|
||
startAt: number;
|
||
endAt: number;
|
||
location: string;
|
||
organizer: string; // 主办单位
|
||
suitableFor?: string; // 适合人群
|
||
intro: string;
|
||
schedule?: string;
|
||
notes?: string;
|
||
feeType: 'free' | 'paid'; // 前台重点突出 公益免费
|
||
status: ActivityStatus;
|
||
capacity?: number;
|
||
}
|
||
|
||
// ============ MatchmakerService(规范 §48-50) ============
|
||
export type MatchmakerServiceStatus =
|
||
| 'submitted'
|
||
| 'assigned'
|
||
| 'in_service'
|
||
| 'waiting_user'
|
||
| 'completed'
|
||
| 'cancelled';
|
||
|
||
export type MatchmakerRecommendationStatus =
|
||
| 'pending_view'
|
||
| 'viewed'
|
||
| 'liked'
|
||
| 'passed'
|
||
| 'mutual_match'
|
||
| 'expired';
|
||
|
||
export interface MatchmakerService {
|
||
displayId?: string
|
||
displayNumber?: string
|
||
userDisplayNumber?: string
|
||
serviceDisplayId?: string
|
||
serviceId: string;
|
||
userId: string;
|
||
matchmakerId?: string;
|
||
matchmakerName?: string;
|
||
matchmakerOrg?: string; // 所属公益机构
|
||
status: MatchmakerServiceStatus;
|
||
requirement: string;
|
||
lastFollowUpAt?: number;
|
||
}
|
||
|
||
export interface MatchmakerRecommendation extends User {
|
||
serviceId: string;
|
||
recommendationStatus: MatchmakerRecommendationStatus;
|
||
recommendReason: string;
|
||
}
|
||
|
||
// ============ Report(规范 §41-42) ============
|
||
export type ReportType = 'fraud' | 'harassment' | 'ad' | 'inappropriate' | 'other';
|
||
export type RiskLevel = 'normal' | 'attention' | 'high' | 'banned';
|
||
|
||
export interface Report {
|
||
reportId: string;
|
||
targetUserId: string;
|
||
type: ReportType;
|
||
reason: string;
|
||
evidencePhotoUrls?: string[];
|
||
submittedAt: number;
|
||
status: 'pending' | 'processing' | 'resolved';
|
||
}
|
||
|
||
// ============ 全局用户状态聚合(规范 §6, §141) ============
|
||
export interface UserState {
|
||
isLoggedIn: boolean;
|
||
hasPhone: boolean;
|
||
isRealNameVerified: boolean;
|
||
profileCompletionStatus: 'not_started' | 'in_progress' | 'completed';
|
||
profileReviewStatus: 'not_submitted' | 'pending' | 'approved' | 'need_edit' | 'rejected';
|
||
accountStatus: 'normal' | 'reviewing_risk' | 'limited' | 'suspended' | 'banned' | 'closed';
|
||
relationshipStatus: 'searching' | 'getting_to_know' | 'paused' | 'matched_successfully' | 'service_exited';
|
||
recommendationEnabled: boolean;
|
||
searchVisibility: boolean;
|
||
matchmakerEnabled: boolean;
|
||
activityRecommendationEnabled: boolean;
|
||
}
|
||
|
||
// ============ 隐私设置(规范 §59) ============
|
||
export interface PrivacySettings {
|
||
visibleInRecommendations: boolean;
|
||
visibleInSearch: boolean;
|
||
showOccupation: boolean;
|
||
showLifestylePhotos: boolean;
|
||
receiveActivityRecommendations: boolean;
|
||
acceptMatchmakerRecommendations: boolean;
|
||
}
|