重构(会员契约): 会员结构体改用 ts-rs 生成类型
- shared-contracts 为 10 个会员结构体补 ts_rs::TS / ts(export),64 位整数字段补 ts(type = "number") 对齐前端 number - 新增 10 个生成绑定;packages/shared 与 admin-web 改为 re-export 生成类型,仅 kind / status 等前端收窄联合用 Omit 组合保留 - 同步设计文档 §2.5 与决策日志
This commit is contained in:
+20
@@ -0,0 +1,20 @@
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { ProfileMembershipModelAccessToken } from "./ProfileMembershipModelAccessToken";
|
||||
import type { ProfileMembershipPlanToken } from "./ProfileMembershipPlanToken";
|
||||
|
||||
/**
|
||||
* 后台按档位改会员价格与权益;`rank` 不在请求里,升级比较基准由代码内目录决定。
|
||||
*/
|
||||
export type AdminUpsertProfileMembershipPlanRequest = {
|
||||
/**
|
||||
* 档位 token,作为主键即档位身份。
|
||||
*/
|
||||
plan: ProfileMembershipPlanToken, title: string, monthPriceCents: number, yearPriceCents: number, periodPoints: number,
|
||||
/**
|
||||
* 模型权限 token:`basic` / `full`;本期只落字段、不做服务端拦截。
|
||||
*/
|
||||
modelAccess: ProfileMembershipModelAccessToken,
|
||||
/**
|
||||
* 并发上限;`128` 表示不设上限。
|
||||
*/
|
||||
concurrentJobLimit: number, enabled: boolean, };
|
||||
@@ -0,0 +1,3 @@
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
|
||||
export type ProfileDailyFreePointsResponse = { dayKey: number, grantedPoints: number, remainingPoints: number, resetsAt: string, updatedAt: string, };
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { ProfileMembershipPlanResponse } from "./ProfileMembershipPlanResponse";
|
||||
|
||||
export type ProfileMembershipPlanAdminListResponse = { entries: Array<ProfileMembershipPlanResponse>,
|
||||
/**
|
||||
* 并发哨兵阈值:`concurrent_job_limit >= 该值` 即不设上限;由后端下发,前端不硬编码。
|
||||
*/
|
||||
unlimitedConcurrencyThreshold: number, };
|
||||
@@ -0,0 +1,25 @@
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { ProfileMembershipModelAccessToken } from "./ProfileMembershipModelAccessToken";
|
||||
import type { ProfileMembershipPlanToken } from "./ProfileMembershipPlanToken";
|
||||
|
||||
export type ProfileMembershipPlanResponse = {
|
||||
/**
|
||||
* 档位 token:`normal` / `starter` / `plus` / `pro` / `max`;未知取值按 `max` 兜底。
|
||||
*/
|
||||
plan: ProfileMembershipPlanToken, title: string, rank: number, monthPriceCents: number, yearPriceCents: number, periodPoints: number,
|
||||
/**
|
||||
* 模型权限 token:`basic` / `full`;未知取值按 `full` 兜底。
|
||||
*/
|
||||
modelAccess: ProfileMembershipModelAccessToken,
|
||||
/**
|
||||
* 并发上限;`128` 表示不设上限。
|
||||
*/
|
||||
concurrentJobLimit: number,
|
||||
/**
|
||||
* 是否为运营推荐档位;由后端目录决定,前端不再硬编码档位 token。
|
||||
*/
|
||||
recommended: boolean,
|
||||
/**
|
||||
* 是否不设并发上限;由后端按哨兵值派生,前端不再硬编码 `128`。
|
||||
*/
|
||||
unlimitedConcurrency: boolean, enabled: boolean, };
|
||||
@@ -0,0 +1,26 @@
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { ProfileMembershipCycleKindToken } from "./ProfileMembershipCycleKindToken";
|
||||
import type { ProfileMembershipPlanToken } from "./ProfileMembershipPlanToken";
|
||||
import type { ProfileMembershipStatusToken } from "./ProfileMembershipStatusToken";
|
||||
|
||||
export type ProfileMembershipResponse = {
|
||||
/**
|
||||
* 会员状态 token:`normal` / `active`;未知取值按 `active` 兜底。
|
||||
*/
|
||||
status: ProfileMembershipStatusToken,
|
||||
/**
|
||||
* 当前档位 token;非会员与已到期都是 `normal`;未知取值按 `max` 兜底。
|
||||
*/
|
||||
plan: ProfileMembershipPlanToken, startedAt: string | null, expiresAt: string | null, updatedAt: string | null, cycleStartedAt: string | null, cycleResetsAt: string | null, cycleGrantedPoints: number, cycleRemainingPoints: number,
|
||||
/**
|
||||
* 当前期序号(1-based)。
|
||||
*/
|
||||
cycleIndex: number,
|
||||
/**
|
||||
* 本次购买总期数(月付 1 / 年付 12)。
|
||||
*/
|
||||
cycleCount: number,
|
||||
/**
|
||||
* 周期 token:`monthly` / `yearly`;未知取值按 `yearly` 兜底。
|
||||
*/
|
||||
cycleKind: ProfileMembershipCycleKindToken, };
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { ProfileMembershipPlanToken } from "./ProfileMembershipPlanToken";
|
||||
|
||||
export type ProfileMembershipUpgradeQuoteRequest = {
|
||||
/**
|
||||
* 目标档位 token:`starter` / `plus` / `pro` / `max`。
|
||||
*/
|
||||
targetPlan: ProfileMembershipPlanToken, };
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { ProfileMembershipCycleKindToken } from "./ProfileMembershipCycleKindToken";
|
||||
import type { ProfileMembershipPlanToken } from "./ProfileMembershipPlanToken";
|
||||
|
||||
/**
|
||||
* 补差升级报价:付款前展示应付金额、补点与变更后的月度余额;下单时后端会用同一函数重算。
|
||||
*/
|
||||
export type ProfileMembershipUpgradeQuoteResponse = {
|
||||
/**
|
||||
* 当前档位 token;未知取值按 `max` 兜底。
|
||||
*/
|
||||
currentPlan: ProfileMembershipPlanToken,
|
||||
/**
|
||||
* 目标档位 token;未知取值按 `max` 兜底。
|
||||
*/
|
||||
targetPlan: ProfileMembershipPlanToken,
|
||||
/**
|
||||
* 周期 token:`monthly` / `yearly`;有效期内不支持月年互换,所以变更前后一致;
|
||||
* 未知取值按 `yearly` 兜底。
|
||||
*/
|
||||
cycleKind: ProfileMembershipCycleKindToken, cycleIndex: number, cycleCount: number,
|
||||
/**
|
||||
* 应付金额(分);月付 = 月价差,年付 = 年价差 ÷ 12 × (后续完整月数 + 本期剩余比例),向上取整到分。
|
||||
*/
|
||||
amountCents: number,
|
||||
/**
|
||||
* 本期补点;年付按本期剩余比例向下取整。
|
||||
*/
|
||||
grantedPointsDelta: number,
|
||||
/**
|
||||
* 变更后月度余额 = 原剩余月度余额 + 补点(已用点不返还,永久泥点不动)。
|
||||
*/
|
||||
monthlyBalanceAfter: number, expiresAt: string | null, cycleResetsAt: string | null, remainingFullMonths: number, };
|
||||
@@ -0,0 +1,13 @@
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { ProfileDailyFreePointsResponse } from "./ProfileDailyFreePointsResponse";
|
||||
import type { ProfileMembershipPlanResponse } from "./ProfileMembershipPlanResponse";
|
||||
import type { ProfileMembershipResponse } from "./ProfileMembershipResponse";
|
||||
import type { ProfileMudPointBalanceResponse } from "./ProfileMudPointBalanceResponse";
|
||||
import type { ProfileRechargeOrderResponse } from "./ProfileRechargeOrderResponse";
|
||||
import type { ProfileRechargeProductResponse } from "./ProfileRechargeProductResponse";
|
||||
|
||||
export type ProfileRechargeCenterResponse = { mudPointBalance: ProfileMudPointBalanceResponse, membership: ProfileMembershipResponse, pointProducts: Array<ProfileRechargeProductResponse>,
|
||||
/**
|
||||
* 会员档位目录(后台可改价),会员购买 / 升级的价格与权益都以它为准。
|
||||
*/
|
||||
membershipPlans: Array<ProfileMembershipPlanResponse>, latestOrder: ProfileRechargeOrderResponse | null, hasPointsRecharged: boolean, dailyFreePoints: ProfileDailyFreePointsResponse, };
|
||||
@@ -0,0 +1,3 @@
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
|
||||
export type ProfileRechargeOrderResponse = { orderId: string, productId: string, productTitle: string, kind: string, amountCents: number, status: string, paymentChannel: string, paidAt: string | null, providerTransactionId: string | null, createdAt: string, pointsDelta: number, membershipExpiresAt: string | null, expiredAt: string | null, expirationCheckedAt: string | null, expirationProviderState: string | null, expirationLastError: string | null, };
|
||||
@@ -0,0 +1,3 @@
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
|
||||
export type ProfileRechargeProductResponse = { productId: string, title: string, priceCents: number, kind: string, pointsAmount: number, bonusPoints: number, durationDays: number, badgeLabel: string, description: string, };
|
||||
@@ -1,18 +1,37 @@
|
||||
import type { JsonObject } from './common';
|
||||
import type { AdminUpsertProfileMembershipPlanRequest } from './generated/AdminUpsertProfileMembershipPlanRequest';
|
||||
import type { ProfileDailyFreePointsResponse } from './generated/ProfileDailyFreePointsResponse';
|
||||
import type { ProfileMembershipChangeKindToken } from './generated/ProfileMembershipChangeKindToken';
|
||||
import type { ProfileMembershipCycleKindToken } from './generated/ProfileMembershipCycleKindToken';
|
||||
import type { ProfileMembershipModelAccessToken } from './generated/ProfileMembershipModelAccessToken';
|
||||
import type { ProfileMembershipPlanAdminListResponse } from './generated/ProfileMembershipPlanAdminListResponse';
|
||||
import type { ProfileMembershipPlanResponse } from './generated/ProfileMembershipPlanResponse';
|
||||
import type { ProfileMembershipPlanToken } from './generated/ProfileMembershipPlanToken';
|
||||
import type { ProfileMembershipResponse } from './generated/ProfileMembershipResponse';
|
||||
import type { ProfileMembershipStatusToken } from './generated/ProfileMembershipStatusToken';
|
||||
import type { ProfileMembershipUpgradeQuoteRequest } from './generated/ProfileMembershipUpgradeQuoteRequest';
|
||||
import type { ProfileMembershipUpgradeQuoteResponse } from './generated/ProfileMembershipUpgradeQuoteResponse';
|
||||
import type { ProfileMudPointBalanceResponse as ProfileMudPointBalance } from './generated/ProfileMudPointBalanceResponse';
|
||||
import type { ProfileRechargeCenterResponse as GeneratedProfileRechargeCenterResponse } from './generated/ProfileRechargeCenterResponse';
|
||||
import type { ProfileRechargeOrderResponse } from './generated/ProfileRechargeOrderResponse';
|
||||
import type { ProfileRechargeProductResponse } from './generated/ProfileRechargeProductResponse';
|
||||
|
||||
export type {
|
||||
AdminUpsertProfileMembershipPlanRequest,
|
||||
ProfileDailyFreePointsResponse,
|
||||
ProfileMembershipChangeKindToken,
|
||||
ProfileMembershipCycleKindToken,
|
||||
ProfileMembershipModelAccessToken,
|
||||
ProfileMembershipPlanAdminListResponse,
|
||||
ProfileMembershipPlanResponse,
|
||||
ProfileMembershipPlanToken,
|
||||
ProfileMembershipResponse,
|
||||
ProfileMembershipStatusToken,
|
||||
ProfileMembershipUpgradeQuoteRequest,
|
||||
ProfileMembershipUpgradeQuoteResponse,
|
||||
ProfileMudPointBalance,
|
||||
ProfileRechargeOrderResponse,
|
||||
ProfileRechargeProductResponse,
|
||||
};
|
||||
|
||||
export const SAVE_SNAPSHOT_VERSION = 2;
|
||||
@@ -69,13 +88,7 @@ export type ProfileDashboardSummary = {
|
||||
dailyFreePoints?: ProfileDailyFreePoints;
|
||||
};
|
||||
|
||||
export type ProfileDailyFreePoints = {
|
||||
dayKey: number;
|
||||
grantedPoints: number;
|
||||
remainingPoints: number;
|
||||
resetsAt: string;
|
||||
updatedAt: string;
|
||||
};
|
||||
export type ProfileDailyFreePoints = ProfileDailyFreePointsResponse;
|
||||
|
||||
export type ProfileWalletLedgerEntry = {
|
||||
id: string;
|
||||
@@ -148,101 +161,39 @@ export type ProfileRechargeOrderStatus =
|
||||
| 'refunded'
|
||||
| 'expired';
|
||||
|
||||
export type ProfileRechargeProduct = {
|
||||
productId: string;
|
||||
title: string;
|
||||
priceCents: number;
|
||||
/** 充点 / 会员商品;`kind` 是前端收窄的联合类型,其余字段以后端生成为准。 */
|
||||
export type ProfileRechargeProduct = Omit<
|
||||
ProfileRechargeProductResponse,
|
||||
'kind'
|
||||
> & {
|
||||
kind: ProfileRechargeProductKind;
|
||||
pointsAmount: number;
|
||||
bonusPoints: number;
|
||||
durationDays: number;
|
||||
badgeLabel: string;
|
||||
description: string;
|
||||
};
|
||||
|
||||
/** 会员档位目录行;价格与权益的唯一真相源是后端 `profile_membership_plan` 表。 */
|
||||
export type ProfileMembershipPlanRecord = {
|
||||
plan: ProfileMembershipPlan;
|
||||
title: string;
|
||||
rank: number;
|
||||
monthPriceCents: number;
|
||||
yearPriceCents: number;
|
||||
periodPoints: number;
|
||||
modelAccess: ProfileMembershipModelAccess;
|
||||
/** 并发上限;`128` 表示不设上限。 */
|
||||
concurrentJobLimit: number;
|
||||
/** 是否为运营推荐档位;由后端目录给出,前端不再硬编码档位 token。 */
|
||||
recommended: boolean;
|
||||
/** 是否不设并发上限;由后端按哨兵值派生,前端不再硬编码 `128`。 */
|
||||
unlimitedConcurrency: boolean;
|
||||
enabled: boolean;
|
||||
};
|
||||
export type ProfileMembershipPlanRecord = ProfileMembershipPlanResponse;
|
||||
|
||||
export type ProfileMembership = {
|
||||
status: ProfileMembershipStatus;
|
||||
/** 当前档位;非会员与已到期都是 `normal`。 */
|
||||
plan: ProfileMembershipPlan;
|
||||
startedAt: string | null;
|
||||
expiresAt: string | null;
|
||||
updatedAt: string | null;
|
||||
cycleStartedAt: string | null;
|
||||
cycleResetsAt: string | null;
|
||||
cycleGrantedPoints: number;
|
||||
cycleRemainingPoints: number;
|
||||
/** 当前期序号(1-based)。 */
|
||||
cycleIndex: number;
|
||||
/** 本次购买总期数(月付 1 / 年付 12)。 */
|
||||
cycleCount: number;
|
||||
cycleKind: ProfileMembershipCycleKind;
|
||||
};
|
||||
export type ProfileMembership = ProfileMembershipResponse;
|
||||
|
||||
/** 补差升级报价;下单时后端会用同一套规则重算,前端展示的数字不是真相源。 */
|
||||
export type ProfileMembershipUpgradeQuote = {
|
||||
currentPlan: ProfileMembershipPlan;
|
||||
targetPlan: ProfileMembershipPlan;
|
||||
cycleKind: ProfileMembershipCycleKind;
|
||||
cycleIndex: number;
|
||||
cycleCount: number;
|
||||
/** 应付金额(分)。 */
|
||||
amountCents: number;
|
||||
/** 本期补点。 */
|
||||
grantedPointsDelta: number;
|
||||
/** 变更后月度余额 = 原剩余月度余额 + 补点。 */
|
||||
monthlyBalanceAfter: number;
|
||||
expiresAt: string | null;
|
||||
cycleResetsAt: string | null;
|
||||
remainingFullMonths: number;
|
||||
};
|
||||
export type ProfileMembershipUpgradeQuote =
|
||||
ProfileMembershipUpgradeQuoteResponse;
|
||||
|
||||
export type ProfileRechargeOrder = {
|
||||
orderId: string;
|
||||
productId: string;
|
||||
productTitle: string;
|
||||
/** 充值订单;`kind` / `status` 是前端收窄的联合类型,其余字段以后端生成为准。 */
|
||||
export type ProfileRechargeOrder = Omit<
|
||||
ProfileRechargeOrderResponse,
|
||||
'kind' | 'status'
|
||||
> & {
|
||||
kind: ProfileRechargeProductKind;
|
||||
amountCents: number;
|
||||
status: ProfileRechargeOrderStatus;
|
||||
paymentChannel: string;
|
||||
paidAt: string | null;
|
||||
providerTransactionId: string | null;
|
||||
createdAt: string;
|
||||
pointsDelta: number;
|
||||
membershipExpiresAt: string | null;
|
||||
expiredAt?: string | null;
|
||||
expirationCheckedAt?: string | null;
|
||||
expirationProviderState?: string | null;
|
||||
expirationLastError?: string | null;
|
||||
};
|
||||
|
||||
export type ProfileRechargeCenterResponse = {
|
||||
// TODO mirror backend: should not nullable
|
||||
mudPointBalance?: ProfileMudPointBalance;
|
||||
membership: ProfileMembership;
|
||||
/** 充值中心;结构以后端生成为准,仅把商品 / 订单收窄成带联合类型的本地别名。 */
|
||||
export type ProfileRechargeCenterResponse = Omit<
|
||||
GeneratedProfileRechargeCenterResponse,
|
||||
'pointProducts' | 'latestOrder'
|
||||
> & {
|
||||
pointProducts: ProfileRechargeProduct[];
|
||||
/** 会员档位目录(后台可改价);会员购买 / 升级的价格与权益以它为准。 */
|
||||
membershipPlans: ProfileMembershipPlanRecord[];
|
||||
latestOrder: ProfileRechargeOrder | null;
|
||||
hasPointsRecharged: boolean;
|
||||
dailyFreePoints?: ProfileDailyFreePoints;
|
||||
};
|
||||
|
||||
export type WechatMiniProgramPayParams = {
|
||||
|
||||
Reference in New Issue
Block a user