Files
danyang-match/miniapp/stores/matchmakerStore.js

157 lines
5.1 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* MatchmakerStore(规范 §131)
*
* 职责:
* - 维护我申请的红娘服务列表
* - 维护红娘推荐列表(仅展示,最终 Like/Pass 走 matchStore)
* - 维护当前进行中的服务详情
*
* 不变量(AGENTS.md):
* - 第 5 条:红娘不可替用户 Like——本 Store 不暴露任何代用户 Like/Pass 的方法,
* 用户对红娘推荐做出选择时仍走 matchStore.like/pass(userId)。
* - 第 7 条:普通工作人员不能查看私人聊天——本 Store 无聊天接入。
* - 第 1 条:用户永久免费——红娘服务不引入任何"高级红娘/付费红娘"差异化。
*/
const BaseStore = require('./baseStore');
const { matchmakerService } = require('../services');
const { MATCHMAKER_SERVICE_STATUS } = require('../constants');
class MatchmakerStore extends BaseStore {
constructor() {
super({
/** @type {import('../types').MatchmakerService[]} */
myServices: [],
servicesCursor: null,
servicesHasMore: true,
servicesLoading: false,
/** 当前进行中的服务(status != completed/cancelled) */
activeService: null,
/** @type {import('../types').MatchmakerRecommendation[]} */
recommendations: [],
recommendationsCursor: null,
recommendationsHasMore: true,
recommendationsLoading: false,
lastError: null,
});
}
/** 拉取我的红娘服务列表 */
async fetchMyServices(params = {}) {
if (this.state.servicesLoading) return;
this.setState({ servicesLoading: true, lastError: null });
try {
const result = await matchmakerService.getMyServices(params);
const items = result.items || [];
const active = items.find(
(s) =>
s.status !== MATCHMAKER_SERVICE_STATUS.COMPLETED &&
s.status !== MATCHMAKER_SERVICE_STATUS.CANCELLED,
) || null;
this.setState({
myServices: items,
servicesCursor: result.nextCursor || null,
servicesHasMore: !!result.nextCursor,
servicesLoading: false,
activeService: active,
});
return result;
} catch (err) {
this.setState({ servicesLoading: false, lastError: err });
throw err;
}
}
/** 加载更多服务 */
async loadMoreServices() {
if (this.state.servicesLoading || !this.state.servicesCursor) return;
this.setState({ servicesLoading: true });
try {
const result = await matchmakerService.getMyServices({
cursor: this.state.servicesCursor,
pageSize: 20,
});
this.setState({
myServices: [...this.state.myServices, ...(result.items || [])],
servicesCursor: result.nextCursor || null,
servicesHasMore: !!result.nextCursor,
servicesLoading: false,
});
} catch (err) {
this.setState({ servicesLoading: false, lastError: err });
throw err;
}
}
/** 申请红娘服务 */
async applyService(payload) {
const result = await matchmakerService.applyService(payload);
// 重新拉取列表以反映最新状态
await this.fetchMyServices();
return result;
}
/** 拉取服务详情 */
async fetchServiceDetail(serviceId) {
return matchmakerService.getServiceDetail(serviceId);
}
/** 拉取红娘推荐列表 */
async fetchRecommendations(params = {}) {
if (this.state.recommendationsLoading) return;
this.setState({ recommendationsLoading: true, lastError: null });
try {
const result = await matchmakerService.getRecommendations(params);
this.setState({
recommendations: result.items || [],
recommendationsCursor: result.nextCursor || null,
recommendationsHasMore: !!result.nextCursor,
recommendationsLoading: false,
});
return result;
} catch (err) {
this.setState({ recommendationsLoading: false, lastError: err });
throw err;
}
}
/** 加载更多红娘推荐 */
async loadMoreRecommendations() {
if (this.state.recommendationsLoading || !this.state.recommendationsCursor) return;
this.setState({ recommendationsLoading: true });
try {
const result = await matchmakerService.getRecommendations({
cursor: this.state.recommendationsCursor,
pageSize: 20,
});
this.setState({
recommendations: [...this.state.recommendations, ...(result.items || [])],
recommendationsCursor: result.nextCursor || null,
recommendationsHasMore: !!result.nextCursor,
recommendationsLoading: false,
});
} catch (err) {
this.setState({ recommendationsLoading: false, lastError: err });
throw err;
}
}
/**
* 对红娘推荐的用户表达 Like/Pass(实际走 matchStore)
* 调用方应直接调用 matchStore.like/pass(userId),本方法仅为统一入口的便利封装。
* 注意:本 Store 自身不替用户做决定,仅做接口转发(AGENTS 第 5 条)。
*/
async likeRecommendation(userId, matchStore) {
return matchStore.like(userId);
}
async passRecommendation(userId, matchStore) {
return matchStore.pass(userId);
}
}
const matchmakerStore = new MatchmakerStore();
module.exports = matchmakerStore;