@tbox.cn/app-module-member 0.8.6 → 0.8.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,6 @@
1
1
  // src/server/index.ts
2
2
  import { loadModuleSkills, withCardEmissionHint, withEarlyExecution } from "@tbox.cn/app-sdk/server";
3
+ import { MEMBER_SNAPSHOT_SERVICE } from "@tbox.cn/app-contracts-mall";
3
4
 
4
5
  // src/server/cards/member-info/meta.ts
5
6
  import { memberInfoCardDataSchema } from "@tbox.cn/app-contracts-mall";
@@ -1550,6 +1551,21 @@ var serverModule = {
1550
1551
  ctx.cardActions.register(action);
1551
1552
  }
1552
1553
  ctx.services.register("member.subject-binding", createSubjectBinding(ctx));
1554
+ ctx.services.register(
1555
+ MEMBER_SNAPSHOT_SERVICE,
1556
+ async (reqCtx) => {
1557
+ const [account, benefits, enrollment] = await Promise.all([
1558
+ resolveMemberAccountPort(reqCtx, ctx),
1559
+ resolveMemberBenefitsPort(reqCtx, ctx),
1560
+ resolveMemberEnrollmentPort(reqCtx, ctx).catch(() => null)
1561
+ ]);
1562
+ return {
1563
+ getAccount: (userId) => account.getAccount(userId),
1564
+ queryPoints: (userId) => benefits.queryPoints(userId),
1565
+ ...enrollment?.enrollUrl ? { enrollUrl: enrollment.enrollUrl } : {}
1566
+ };
1567
+ }
1568
+ );
1553
1569
  }
1554
1570
  };
1555
1571
 
@@ -1,5 +1,5 @@
1
1
  // src/client/index.ts
2
- import "./member-QFCIYILN.css";
2
+ import "./member-372B74DY.css";
3
3
 
4
4
  // src/client/cards/member-info/index.tsx
5
5
  import { CalendarBlank, Phone, Tag, UserCircle } from "@phosphor-icons/react";
@@ -696,11 +696,6 @@ var member_enrollment_cta_default = MemberEnrollmentCtaCard;
696
696
  import { useRef as useRef5, useState as useState6 } from "react";
697
697
  import { ArrowSquareOut as ArrowSquareOut2, WarningCircle as WarningCircle3 } from "@phosphor-icons/react";
698
698
  import { sendCardAction as sendCardAction5 } from "@tbox.cn/app-sdk/client";
699
-
700
- // src/client/assets/login-mascot.jpg
701
- var login_mascot_default = "./login-mascot-5D4X6YZ7.jpg";
702
-
703
- // src/client/cards/member-login-cta/index.tsx
704
699
  import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
705
700
  function MemberLoginCtaCard(props) {
706
701
  const { data, cardId, isHistory } = props;
@@ -721,7 +716,7 @@ function MemberLoginCtaCard(props) {
721
716
  /* @__PURE__ */ jsx8("path", { d: "M40 122 c12,-8 20,2 11,9" })
722
717
  ] }),
723
718
  /* @__PURE__ */ jsx8("span", { className: "member-login-cta__ground", "aria-hidden": "true" }),
724
- /* @__PURE__ */ jsx8("img", { className: "member-login-cta__mascot", src: login_mascot_default, alt: "" }),
719
+ /* @__PURE__ */ jsx8("span", { className: "member-login-cta__mascot", "aria-hidden": "true" }),
725
720
  /* @__PURE__ */ jsx8("span", { className: "member-login-cta__grain", "aria-hidden": "true" })
726
721
  ] }),
727
722
  /* @__PURE__ */ jsx8("svg", { className: "member-login-cta__tear", viewBox: "0 0 390 16", preserveAspectRatio: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx8("path", { d: "M0,16 L390,16 L390,6 L358,10 L330,4 L298,11 L266,5 L236,12 L204,6 L174,12 L144,6 L112,13 L82,7 L52,14 L24,8 L0,12 Z" }) }),
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  clientModule
3
- } from "../chunk-KEBILLQ5.js";
3
+ } from "../chunk-QWGRWD5C.js";
4
4
  export {
5
5
  clientModule
6
6
  };
package/dist/index.js CHANGED
@@ -7,10 +7,10 @@ import {
7
7
  resolveMemberEnrollmentPort,
8
8
  resolveMemberProfilePort,
9
9
  serverModule
10
- } from "./chunk-T4SYPQA5.js";
10
+ } from "./chunk-EPQEF43P.js";
11
11
  import {
12
12
  clientModule
13
- } from "./chunk-KEBILLQ5.js";
13
+ } from "./chunk-QWGRWD5C.js";
14
14
  export {
15
15
  InMemoryMemberService,
16
16
  clientModule,
@@ -1,6 +1,6 @@
1
1
  /* ============================================================
2
2
  * module-member 客户端域样式(0.4.0 D1/D2;头注二轮评审修正)。
3
- * 视觉源:mall-vis 双演示(MembershipMessageCard/MembershipInviteBanner 金系);域色矩阵对照 docs/mall/visual.md
3
+ * 视觉源:mall-vis 双演示(MembershipMessageCard/MembershipInviteBanner 金系);域色矩阵对照 docs/reference/templates.md(视觉体系与域色矩阵)。
4
4
  * 基线(D2):本仓库统一 750 设计稿 2x——源码 px 经 rootValue 100 转 rem,渲染折半(375 下 1px 源码 = 0.5px 物理)。
5
5
  * POC membership 源按 web 物理 px 直觉作稿(如 avatar 76px——该值在 POC 同款 rootValue 100 管线下渲染折半为 38px,
6
6
  * 非设计意图),故本文件按 750 稿基线恢复意图:关键尺寸 ×2 于源值(76→152),其余(卡距/字阶 24/26/34/44)按
@@ -13,7 +13,7 @@
13
13
 
14
14
  /* ===== 域变量 ===== */
15
15
  .member-card {
16
- --member-accent: #b45f06;
16
+ --member-accent: var(--tbox-domain-member-accent, #b45f06);
17
17
  --member-accent-strong: #b45f06;
18
18
  --member-label: #a3925f;
19
19
  --member-accent-soft: #fff6e0;
@@ -23,9 +23,9 @@
23
23
  --member-warning-light: var(--tbox-warning-light, #fff4e0);
24
24
  --member-muted: var(--tbox-text-secondary, #82745e);
25
25
  --member-faint: var(--tbox-text-muted, #a69a83);
26
- --member-border: #ecdec2;
26
+ --member-border: var(--tbox-domain-member-border, #ecdec2);
27
27
  --member-bg-subtle: #fff8eb;
28
- --member-surface: #fffdf8;
28
+ --member-surface: var(--tbox-domain-member-surface, #fffdf8);
29
29
  --member-accent-deep: #8c6a2f;
30
30
  --member-accent-deep-bg: #f9f1df;
31
31
  --member-accent-border: #ecdec2;
@@ -1597,8 +1597,14 @@
1597
1597
  bottom: 4PX;
1598
1598
  z-index: 2;
1599
1599
  width: 132PX;
1600
- height: auto;
1600
+ aspect-ratio: 200 / 194; /* 资产契约 200×194,等比缩放 */
1601
1601
  transform: translateX(-50%);
1602
+ /* 素材变量链(主题品牌资产轨 A1 级联修复):元素只消费不声明(声明会截断主题覆写继承),
1603
+ 兜底 = 中立渐变(零品牌资产——B2),主题包经 html[data-theme] 段覆写 --tbox-asset-member-mascot */
1604
+ background-image: var(--tbox-asset-member-mascot, linear-gradient(135deg, #fff8eb, #fffdf8));
1605
+ background-size: contain;
1606
+ background-repeat: no-repeat;
1607
+ background-position: center bottom;
1602
1608
  /* 顶部淡入:图片上沿伸进天光区,不化开就是一条横切的硬边 */
1603
1609
  -webkit-mask-image: linear-gradient(180deg, rgba(0, 0, 0, 0) 0%, #000 22%, #000 100%);
1604
1610
  mask-image: linear-gradient(180deg, rgba(0, 0, 0, 0) 0%, #000 22%, #000 100%);
@@ -103,19 +103,19 @@ declare const memberCards: {
103
103
  labelRef: zod.ZodString;
104
104
  name: zod.ZodString;
105
105
  }, "strip", zod.ZodTypeAny, {
106
- name: string;
107
106
  labelRef: string;
108
- }, {
109
107
  name: string;
108
+ }, {
110
109
  labelRef: string;
110
+ name: string;
111
111
  }>, "many">;
112
112
  }, "strip", zod.ZodTypeAny, {
113
113
  userId: string;
114
- state: "unknown" | "active" | "not_enrolled" | "closed";
115
114
  authState: "authenticated" | "unauthenticated";
115
+ state: "unknown" | "active" | "not_enrolled" | "closed";
116
116
  labels: {
117
- name: string;
118
117
  labelRef: string;
118
+ name: string;
119
119
  }[];
120
120
  displayName?: string | undefined;
121
121
  avatarUrl?: string | undefined;
@@ -124,11 +124,11 @@ declare const memberCards: {
124
124
  registeredAt?: string | undefined;
125
125
  }, {
126
126
  userId: string;
127
- state: "unknown" | "active" | "not_enrolled" | "closed";
128
127
  authState: "authenticated" | "unauthenticated";
128
+ state: "unknown" | "active" | "not_enrolled" | "closed";
129
129
  labels: {
130
- name: string;
131
130
  labelRef: string;
131
+ name: string;
132
132
  }[];
133
133
  displayName?: string | undefined;
134
134
  avatarUrl?: string | undefined;
@@ -185,14 +185,14 @@ declare const memberCards: {
185
185
  text: zod.ZodOptional<zod.ZodString>;
186
186
  }, "strip", zod.ZodTypeAny, {
187
187
  kind: "toast" | "miniapp" | "dialog";
188
+ title?: string | undefined;
188
189
  url?: string | undefined;
189
190
  text?: string | undefined;
190
- title?: string | undefined;
191
191
  }, {
192
192
  kind: "toast" | "miniapp" | "dialog";
193
+ title?: string | undefined;
193
194
  url?: string | undefined;
194
195
  text?: string | undefined;
195
- title?: string | undefined;
196
196
  }>>;
197
197
  }, "strip", zod.ZodTypeAny, {
198
198
  name: string;
@@ -200,9 +200,9 @@ declare const memberCards: {
200
200
  description?: string | undefined;
201
201
  action?: {
202
202
  kind: "toast" | "miniapp" | "dialog";
203
+ title?: string | undefined;
203
204
  url?: string | undefined;
204
205
  text?: string | undefined;
205
- title?: string | undefined;
206
206
  } | undefined;
207
207
  iconUrl?: string | undefined;
208
208
  }, {
@@ -211,9 +211,9 @@ declare const memberCards: {
211
211
  description?: string | undefined;
212
212
  action?: {
213
213
  kind: "toast" | "miniapp" | "dialog";
214
+ title?: string | undefined;
214
215
  url?: string | undefined;
215
216
  text?: string | undefined;
216
- title?: string | undefined;
217
217
  } | undefined;
218
218
  iconUrl?: string | undefined;
219
219
  }>, "many">>;
@@ -228,8 +228,8 @@ declare const memberCards: {
228
228
  query: string;
229
229
  }>, "many">>;
230
230
  }, "strip", zod.ZodTypeAny, {
231
- status: "unknown" | "active" | "inactive" | "frozen" | "expired";
232
231
  userId: string;
232
+ status: "unknown" | "active" | "inactive" | "frozen" | "expired";
233
233
  cardRef: string;
234
234
  cardDisplay: string;
235
235
  availablePoints: number;
@@ -254,9 +254,9 @@ declare const memberCards: {
254
254
  description?: string | undefined;
255
255
  action?: {
256
256
  kind: "toast" | "miniapp" | "dialog";
257
+ title?: string | undefined;
257
258
  url?: string | undefined;
258
259
  text?: string | undefined;
259
- title?: string | undefined;
260
260
  } | undefined;
261
261
  iconUrl?: string | undefined;
262
262
  }[] | undefined;
@@ -265,8 +265,8 @@ declare const memberCards: {
265
265
  query: string;
266
266
  }[] | undefined;
267
267
  }, {
268
- status: "unknown" | "active" | "inactive" | "frozen" | "expired";
269
268
  userId: string;
269
+ status: "unknown" | "active" | "inactive" | "frozen" | "expired";
270
270
  cardRef: string;
271
271
  cardDisplay: string;
272
272
  availablePoints: number;
@@ -291,9 +291,9 @@ declare const memberCards: {
291
291
  description?: string | undefined;
292
292
  action?: {
293
293
  kind: "toast" | "miniapp" | "dialog";
294
+ title?: string | undefined;
294
295
  url?: string | undefined;
295
296
  text?: string | undefined;
296
- title?: string | undefined;
297
297
  } | undefined;
298
298
  iconUrl?: string | undefined;
299
299
  }[] | undefined;
@@ -313,42 +313,42 @@ declare const memberCards: {
313
313
  usedAt: zod.ZodOptional<zod.ZodString>;
314
314
  description: zod.ZodOptional<zod.ZodString>;
315
315
  }, "strip", zod.ZodTypeAny, {
316
- title: string;
317
316
  usageRecordRef: string;
317
+ title: string;
318
318
  amount: string;
319
- description?: string | undefined;
320
319
  usedAt?: string | undefined;
320
+ description?: string | undefined;
321
321
  }, {
322
- title: string;
323
322
  usageRecordRef: string;
323
+ title: string;
324
324
  amount: string;
325
- description?: string | undefined;
326
325
  usedAt?: string | undefined;
326
+ description?: string | undefined;
327
327
  }>, "many">;
328
328
  total: zod.ZodNumber;
329
329
  }, "strip", zod.ZodTypeAny, {
330
330
  userId: string;
331
- total: number;
331
+ balance: number;
332
332
  items: {
333
- title: string;
334
333
  usageRecordRef: string;
334
+ title: string;
335
335
  amount: string;
336
- description?: string | undefined;
337
336
  usedAt?: string | undefined;
337
+ description?: string | undefined;
338
338
  }[];
339
- balance: number;
339
+ total: number;
340
340
  membershipLabel?: string | undefined;
341
341
  }, {
342
342
  userId: string;
343
- total: number;
343
+ balance: number;
344
344
  items: {
345
- title: string;
346
345
  usageRecordRef: string;
346
+ title: string;
347
347
  amount: string;
348
- description?: string | undefined;
349
348
  usedAt?: string | undefined;
349
+ description?: string | undefined;
350
350
  }[];
351
- balance: number;
351
+ total: number;
352
352
  membershipLabel?: string | undefined;
353
353
  }>>;
354
354
  readonly 'member-enrollment-form': _tbox_cn_app_contracts.CardMeta<zod.ZodObject<{
@@ -390,15 +390,15 @@ declare const memberCards: {
390
390
  required: zod.ZodBoolean;
391
391
  url: zod.ZodOptional<zod.ZodString>;
392
392
  }, "strip", zod.ZodTypeAny, {
393
+ title: string;
393
394
  required: boolean;
394
395
  version: string;
395
- title: string;
396
396
  consentId: string;
397
397
  url?: string | undefined;
398
398
  }, {
399
+ title: string;
399
400
  required: boolean;
400
401
  version: string;
401
- title: string;
402
402
  consentId: string;
403
403
  url?: string | undefined;
404
404
  }>, "many">;
@@ -415,12 +415,11 @@ declare const memberCards: {
415
415
  manualNotice: zod.ZodOptional<zod.ZodString>;
416
416
  }, "strip", zod.ZodTypeAny, {
417
417
  userId: string;
418
+ state: "unknown" | "active" | "not_enrolled" | "closed";
418
419
  authorization: {
419
420
  status: "required" | "unavailable" | "authorized";
420
421
  mobileMasked?: string | undefined;
421
422
  };
422
- state: "unknown" | "active" | "not_enrolled" | "closed";
423
- formVersion: string;
424
423
  fields: {
425
424
  type: "date" | "text" | "tel" | "select";
426
425
  required: boolean;
@@ -431,22 +430,22 @@ declare const memberCards: {
431
430
  prefill?: string | undefined;
432
431
  placeholder?: string | undefined;
433
432
  }[];
433
+ formVersion: string;
434
434
  consents: {
435
+ title: string;
435
436
  required: boolean;
436
437
  version: string;
437
- title: string;
438
438
  consentId: string;
439
439
  url?: string | undefined;
440
440
  }[];
441
441
  manualNotice?: string | undefined;
442
442
  }, {
443
443
  userId: string;
444
+ state: "unknown" | "active" | "not_enrolled" | "closed";
444
445
  authorization: {
445
446
  status: "required" | "unavailable" | "authorized";
446
447
  mobileMasked?: string | undefined;
447
448
  };
448
- state: "unknown" | "active" | "not_enrolled" | "closed";
449
- formVersion: string;
450
449
  fields: {
451
450
  type: "date" | "text" | "tel" | "select";
452
451
  required: boolean;
@@ -457,10 +456,11 @@ declare const memberCards: {
457
456
  prefill?: string | undefined;
458
457
  placeholder?: string | undefined;
459
458
  }[];
459
+ formVersion: string;
460
460
  consents: {
461
+ title: string;
461
462
  required: boolean;
462
463
  version: string;
463
- title: string;
464
464
  consentId: string;
465
465
  url?: string | undefined;
466
466
  }[];
@@ -474,15 +474,15 @@ declare const memberCards: {
474
474
  message: zod.ZodOptional<zod.ZodString>;
475
475
  }, "strip", zod.ZodTypeAny, {
476
476
  userId: string;
477
- state: "failed" | "active" | "pending_confirmation" | "confirmation_timeout";
478
- message?: string | undefined;
477
+ state: "active" | "failed" | "pending_confirmation" | "confirmation_timeout";
479
478
  memberRef?: string | undefined;
479
+ message?: string | undefined;
480
480
  attemptRef?: string | undefined;
481
481
  }, {
482
482
  userId: string;
483
- state: "failed" | "active" | "pending_confirmation" | "confirmation_timeout";
484
- message?: string | undefined;
483
+ state: "active" | "failed" | "pending_confirmation" | "confirmation_timeout";
485
484
  memberRef?: string | undefined;
485
+ message?: string | undefined;
486
486
  attemptRef?: string | undefined;
487
487
  }>>;
488
488
  readonly 'member-enrollment-cta': _tbox_cn_app_contracts.CardMeta<zod.ZodObject<{
@@ -495,16 +495,16 @@ declare const memberCards: {
495
495
  perks: zod.ZodOptional<zod.ZodArray<zod.ZodString, "many">>;
496
496
  }, "strip", zod.ZodTypeAny, {
497
497
  userId: string;
498
- state: "not_enrolled" | "closed";
499
498
  authState: "authenticated";
499
+ state: "not_enrolled" | "closed";
500
500
  title?: string | undefined;
501
501
  subtitle?: string | undefined;
502
502
  enrollUrl?: string | undefined;
503
503
  perks?: string[] | undefined;
504
504
  }, {
505
505
  userId: string;
506
- state: "not_enrolled" | "closed";
507
506
  authState: "authenticated";
507
+ state: "not_enrolled" | "closed";
508
508
  title?: string | undefined;
509
509
  subtitle?: string | undefined;
510
510
  enrollUrl?: string | undefined;
@@ -541,19 +541,19 @@ declare const serverModule: {
541
541
  labelRef: zod.ZodString;
542
542
  name: zod.ZodString;
543
543
  }, "strip", zod.ZodTypeAny, {
544
- name: string;
545
544
  labelRef: string;
546
- }, {
547
545
  name: string;
546
+ }, {
548
547
  labelRef: string;
548
+ name: string;
549
549
  }>, "many">;
550
550
  }, "strip", zod.ZodTypeAny, {
551
551
  userId: string;
552
- state: "unknown" | "active" | "not_enrolled" | "closed";
553
552
  authState: "authenticated" | "unauthenticated";
553
+ state: "unknown" | "active" | "not_enrolled" | "closed";
554
554
  labels: {
555
- name: string;
556
555
  labelRef: string;
556
+ name: string;
557
557
  }[];
558
558
  displayName?: string | undefined;
559
559
  avatarUrl?: string | undefined;
@@ -562,11 +562,11 @@ declare const serverModule: {
562
562
  registeredAt?: string | undefined;
563
563
  }, {
564
564
  userId: string;
565
- state: "unknown" | "active" | "not_enrolled" | "closed";
566
565
  authState: "authenticated" | "unauthenticated";
566
+ state: "unknown" | "active" | "not_enrolled" | "closed";
567
567
  labels: {
568
- name: string;
569
568
  labelRef: string;
569
+ name: string;
570
570
  }[];
571
571
  displayName?: string | undefined;
572
572
  avatarUrl?: string | undefined;
@@ -623,14 +623,14 @@ declare const serverModule: {
623
623
  text: zod.ZodOptional<zod.ZodString>;
624
624
  }, "strip", zod.ZodTypeAny, {
625
625
  kind: "toast" | "miniapp" | "dialog";
626
+ title?: string | undefined;
626
627
  url?: string | undefined;
627
628
  text?: string | undefined;
628
- title?: string | undefined;
629
629
  }, {
630
630
  kind: "toast" | "miniapp" | "dialog";
631
+ title?: string | undefined;
631
632
  url?: string | undefined;
632
633
  text?: string | undefined;
633
- title?: string | undefined;
634
634
  }>>;
635
635
  }, "strip", zod.ZodTypeAny, {
636
636
  name: string;
@@ -638,9 +638,9 @@ declare const serverModule: {
638
638
  description?: string | undefined;
639
639
  action?: {
640
640
  kind: "toast" | "miniapp" | "dialog";
641
+ title?: string | undefined;
641
642
  url?: string | undefined;
642
643
  text?: string | undefined;
643
- title?: string | undefined;
644
644
  } | undefined;
645
645
  iconUrl?: string | undefined;
646
646
  }, {
@@ -649,9 +649,9 @@ declare const serverModule: {
649
649
  description?: string | undefined;
650
650
  action?: {
651
651
  kind: "toast" | "miniapp" | "dialog";
652
+ title?: string | undefined;
652
653
  url?: string | undefined;
653
654
  text?: string | undefined;
654
- title?: string | undefined;
655
655
  } | undefined;
656
656
  iconUrl?: string | undefined;
657
657
  }>, "many">>;
@@ -666,8 +666,8 @@ declare const serverModule: {
666
666
  query: string;
667
667
  }>, "many">>;
668
668
  }, "strip", zod.ZodTypeAny, {
669
- status: "unknown" | "active" | "inactive" | "frozen" | "expired";
670
669
  userId: string;
670
+ status: "unknown" | "active" | "inactive" | "frozen" | "expired";
671
671
  cardRef: string;
672
672
  cardDisplay: string;
673
673
  availablePoints: number;
@@ -692,9 +692,9 @@ declare const serverModule: {
692
692
  description?: string | undefined;
693
693
  action?: {
694
694
  kind: "toast" | "miniapp" | "dialog";
695
+ title?: string | undefined;
695
696
  url?: string | undefined;
696
697
  text?: string | undefined;
697
- title?: string | undefined;
698
698
  } | undefined;
699
699
  iconUrl?: string | undefined;
700
700
  }[] | undefined;
@@ -703,8 +703,8 @@ declare const serverModule: {
703
703
  query: string;
704
704
  }[] | undefined;
705
705
  }, {
706
- status: "unknown" | "active" | "inactive" | "frozen" | "expired";
707
706
  userId: string;
707
+ status: "unknown" | "active" | "inactive" | "frozen" | "expired";
708
708
  cardRef: string;
709
709
  cardDisplay: string;
710
710
  availablePoints: number;
@@ -729,9 +729,9 @@ declare const serverModule: {
729
729
  description?: string | undefined;
730
730
  action?: {
731
731
  kind: "toast" | "miniapp" | "dialog";
732
+ title?: string | undefined;
732
733
  url?: string | undefined;
733
734
  text?: string | undefined;
734
- title?: string | undefined;
735
735
  } | undefined;
736
736
  iconUrl?: string | undefined;
737
737
  }[] | undefined;
@@ -751,42 +751,42 @@ declare const serverModule: {
751
751
  usedAt: zod.ZodOptional<zod.ZodString>;
752
752
  description: zod.ZodOptional<zod.ZodString>;
753
753
  }, "strip", zod.ZodTypeAny, {
754
- title: string;
755
754
  usageRecordRef: string;
755
+ title: string;
756
756
  amount: string;
757
- description?: string | undefined;
758
757
  usedAt?: string | undefined;
758
+ description?: string | undefined;
759
759
  }, {
760
- title: string;
761
760
  usageRecordRef: string;
761
+ title: string;
762
762
  amount: string;
763
- description?: string | undefined;
764
763
  usedAt?: string | undefined;
764
+ description?: string | undefined;
765
765
  }>, "many">;
766
766
  total: zod.ZodNumber;
767
767
  }, "strip", zod.ZodTypeAny, {
768
768
  userId: string;
769
- total: number;
769
+ balance: number;
770
770
  items: {
771
- title: string;
772
771
  usageRecordRef: string;
772
+ title: string;
773
773
  amount: string;
774
- description?: string | undefined;
775
774
  usedAt?: string | undefined;
775
+ description?: string | undefined;
776
776
  }[];
777
- balance: number;
777
+ total: number;
778
778
  membershipLabel?: string | undefined;
779
779
  }, {
780
780
  userId: string;
781
- total: number;
781
+ balance: number;
782
782
  items: {
783
- title: string;
784
783
  usageRecordRef: string;
784
+ title: string;
785
785
  amount: string;
786
- description?: string | undefined;
787
786
  usedAt?: string | undefined;
787
+ description?: string | undefined;
788
788
  }[];
789
- balance: number;
789
+ total: number;
790
790
  membershipLabel?: string | undefined;
791
791
  }>>;
792
792
  readonly 'member-enrollment-form': _tbox_cn_app_contracts.CardMeta<zod.ZodObject<{
@@ -828,15 +828,15 @@ declare const serverModule: {
828
828
  required: zod.ZodBoolean;
829
829
  url: zod.ZodOptional<zod.ZodString>;
830
830
  }, "strip", zod.ZodTypeAny, {
831
+ title: string;
831
832
  required: boolean;
832
833
  version: string;
833
- title: string;
834
834
  consentId: string;
835
835
  url?: string | undefined;
836
836
  }, {
837
+ title: string;
837
838
  required: boolean;
838
839
  version: string;
839
- title: string;
840
840
  consentId: string;
841
841
  url?: string | undefined;
842
842
  }>, "many">;
@@ -853,12 +853,11 @@ declare const serverModule: {
853
853
  manualNotice: zod.ZodOptional<zod.ZodString>;
854
854
  }, "strip", zod.ZodTypeAny, {
855
855
  userId: string;
856
+ state: "unknown" | "active" | "not_enrolled" | "closed";
856
857
  authorization: {
857
858
  status: "required" | "unavailable" | "authorized";
858
859
  mobileMasked?: string | undefined;
859
860
  };
860
- state: "unknown" | "active" | "not_enrolled" | "closed";
861
- formVersion: string;
862
861
  fields: {
863
862
  type: "date" | "text" | "tel" | "select";
864
863
  required: boolean;
@@ -869,22 +868,22 @@ declare const serverModule: {
869
868
  prefill?: string | undefined;
870
869
  placeholder?: string | undefined;
871
870
  }[];
871
+ formVersion: string;
872
872
  consents: {
873
+ title: string;
873
874
  required: boolean;
874
875
  version: string;
875
- title: string;
876
876
  consentId: string;
877
877
  url?: string | undefined;
878
878
  }[];
879
879
  manualNotice?: string | undefined;
880
880
  }, {
881
881
  userId: string;
882
+ state: "unknown" | "active" | "not_enrolled" | "closed";
882
883
  authorization: {
883
884
  status: "required" | "unavailable" | "authorized";
884
885
  mobileMasked?: string | undefined;
885
886
  };
886
- state: "unknown" | "active" | "not_enrolled" | "closed";
887
- formVersion: string;
888
887
  fields: {
889
888
  type: "date" | "text" | "tel" | "select";
890
889
  required: boolean;
@@ -895,10 +894,11 @@ declare const serverModule: {
895
894
  prefill?: string | undefined;
896
895
  placeholder?: string | undefined;
897
896
  }[];
897
+ formVersion: string;
898
898
  consents: {
899
+ title: string;
899
900
  required: boolean;
900
901
  version: string;
901
- title: string;
902
902
  consentId: string;
903
903
  url?: string | undefined;
904
904
  }[];
@@ -912,15 +912,15 @@ declare const serverModule: {
912
912
  message: zod.ZodOptional<zod.ZodString>;
913
913
  }, "strip", zod.ZodTypeAny, {
914
914
  userId: string;
915
- state: "failed" | "active" | "pending_confirmation" | "confirmation_timeout";
916
- message?: string | undefined;
915
+ state: "active" | "failed" | "pending_confirmation" | "confirmation_timeout";
917
916
  memberRef?: string | undefined;
917
+ message?: string | undefined;
918
918
  attemptRef?: string | undefined;
919
919
  }, {
920
920
  userId: string;
921
- state: "failed" | "active" | "pending_confirmation" | "confirmation_timeout";
922
- message?: string | undefined;
921
+ state: "active" | "failed" | "pending_confirmation" | "confirmation_timeout";
923
922
  memberRef?: string | undefined;
923
+ message?: string | undefined;
924
924
  attemptRef?: string | undefined;
925
925
  }>>;
926
926
  readonly 'member-enrollment-cta': _tbox_cn_app_contracts.CardMeta<zod.ZodObject<{
@@ -933,16 +933,16 @@ declare const serverModule: {
933
933
  perks: zod.ZodOptional<zod.ZodArray<zod.ZodString, "many">>;
934
934
  }, "strip", zod.ZodTypeAny, {
935
935
  userId: string;
936
- state: "not_enrolled" | "closed";
937
936
  authState: "authenticated";
937
+ state: "not_enrolled" | "closed";
938
938
  title?: string | undefined;
939
939
  subtitle?: string | undefined;
940
940
  enrollUrl?: string | undefined;
941
941
  perks?: string[] | undefined;
942
942
  }, {
943
943
  userId: string;
944
- state: "not_enrolled" | "closed";
945
944
  authState: "authenticated";
945
+ state: "not_enrolled" | "closed";
946
946
  title?: string | undefined;
947
947
  subtitle?: string | undefined;
948
948
  enrollUrl?: string | undefined;
@@ -7,7 +7,7 @@ import {
7
7
  resolveMemberEnrollmentPort,
8
8
  resolveMemberProfilePort,
9
9
  serverModule
10
- } from "../chunk-T4SYPQA5.js";
10
+ } from "../chunk-EPQEF43P.js";
11
11
  export {
12
12
  InMemoryMemberService,
13
13
  memberCards,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tbox.cn/app-module-member",
3
- "version": "0.8.6",
3
+ "version": "0.8.7",
4
4
  "type": "module",
5
5
  "description": "商圈会员模块:会员账户、会员卡、积分流水与入会流程(codegen 源)。",
6
6
  "exports": {
@@ -18,9 +18,9 @@
18
18
  }
19
19
  },
20
20
  "dependencies": {
21
- "@tbox.cn/app-sdk": "0.17.0",
22
- "@tbox.cn/app-contracts": "0.9.0",
23
- "@tbox.cn/app-contracts-mall": "0.9.0"
21
+ "@tbox.cn/app-sdk": "0.19.0",
22
+ "@tbox.cn/app-contracts": "0.10.0",
23
+ "@tbox.cn/app-contracts-mall": "0.10.0"
24
24
  },
25
25
  "peerDependencies": {
26
26
  "zod": "3.25.76",
@@ -10,7 +10,6 @@
10
10
  import { useRef, useState } from 'react';
11
11
  import { ArrowSquareOut, WarningCircle } from '@phosphor-icons/react';
12
12
  import { sendCardAction } from '@tbox.cn/app-sdk/client';
13
- import mascotUrl from '../../assets/login-mascot.jpg';
14
13
  import type { MemberLoginCtaCardData } from '@tbox.cn/app-contracts-mall';
15
14
 
16
15
  export function MemberLoginCtaCard(props: {
@@ -42,7 +41,8 @@ export function MemberLoginCtaCard(props: {
42
41
  </svg>
43
42
  {/* 地面光斑:把角色钉在台面上,否则它像浮在纸上 */}
44
43
  <span className="member-login-cta__ground" aria-hidden="true" />
45
- <img className="member-login-cta__mascot" src={mascotUrl} alt="" />
44
+ {/* 素材变量链(主题轨 T-2.3):装饰主视觉走 CSS background,主题包经 --tbox-asset-member-mascot 覆写 */}
45
+ <span className="member-login-cta__mascot" aria-hidden="true" />
46
46
  <span className="member-login-cta__grain" aria-hidden="true" />
47
47
  </div>
48
48
 
@@ -1,6 +1,6 @@
1
1
  /* ============================================================
2
2
  * module-member 客户端域样式(0.4.0 D1/D2;头注二轮评审修正)。
3
- * 视觉源:mall-vis 双演示(MembershipMessageCard/MembershipInviteBanner 金系);域色矩阵对照 docs/mall/visual.md
3
+ * 视觉源:mall-vis 双演示(MembershipMessageCard/MembershipInviteBanner 金系);域色矩阵对照 docs/reference/templates.md(视觉体系与域色矩阵)。
4
4
  * 基线(D2):本仓库统一 750 设计稿 2x——源码 px 经 rootValue 100 转 rem,渲染折半(375 下 1px 源码 = 0.5px 物理)。
5
5
  * POC membership 源按 web 物理 px 直觉作稿(如 avatar 76px——该值在 POC 同款 rootValue 100 管线下渲染折半为 38px,
6
6
  * 非设计意图),故本文件按 750 稿基线恢复意图:关键尺寸 ×2 于源值(76→152),其余(卡距/字阶 24/26/34/44)按
@@ -13,7 +13,7 @@
13
13
 
14
14
  /* ===== 域变量 ===== */
15
15
  .member-card {
16
- --member-accent: #b45f06;
16
+ --member-accent: var(--tbox-domain-member-accent, #b45f06);
17
17
  --member-accent-strong: #b45f06;
18
18
  --member-label: #a3925f;
19
19
  --member-accent-soft: #fff6e0;
@@ -23,9 +23,9 @@
23
23
  --member-warning-light: var(--tbox-warning-light, #fff4e0);
24
24
  --member-muted: var(--tbox-text-secondary, #82745e);
25
25
  --member-faint: var(--tbox-text-muted, #a69a83);
26
- --member-border: #ecdec2;
26
+ --member-border: var(--tbox-domain-member-border, #ecdec2);
27
27
  --member-bg-subtle: #fff8eb;
28
- --member-surface: #fffdf8;
28
+ --member-surface: var(--tbox-domain-member-surface, #fffdf8);
29
29
  --member-accent-deep: #8c6a2f;
30
30
  --member-accent-deep-bg: #f9f1df;
31
31
  --member-accent-border: #ecdec2;
@@ -1597,8 +1597,14 @@
1597
1597
  bottom: 4PX;
1598
1598
  z-index: 2;
1599
1599
  width: 132PX;
1600
- height: auto;
1600
+ aspect-ratio: 200 / 194; /* 资产契约 200×194,等比缩放 */
1601
1601
  transform: translateX(-50%);
1602
+ /* 素材变量链(主题品牌资产轨 A1 级联修复):元素只消费不声明(声明会截断主题覆写继承),
1603
+ 兜底 = 中立渐变(零品牌资产——B2),主题包经 html[data-theme] 段覆写 --tbox-asset-member-mascot */
1604
+ background-image: var(--tbox-asset-member-mascot, linear-gradient(135deg, #fff8eb, #fffdf8));
1605
+ background-size: contain;
1606
+ background-repeat: no-repeat;
1607
+ background-position: center bottom;
1602
1608
  /* 顶部淡入:图片上沿伸进天光区,不化开就是一条横切的硬边 */
1603
1609
  -webkit-mask-image: linear-gradient(180deg, rgba(0, 0, 0, 0) 0%, #000 22%, #000 100%);
1604
1610
  mask-image: linear-gradient(180deg, rgba(0, 0, 0, 0) 0%, #000 22%, #000 100%);
@@ -1,6 +1,7 @@
1
1
  import type { ServerContext, ServerModule } from '@tbox.cn/app-sdk/server';
2
2
  import { loadModuleSkills, withCardEmissionHint, withEarlyExecution } from '@tbox.cn/app-sdk/server';
3
3
  import type { RequestContext } from '@tbox.cn/app-contracts';
4
+ import { MEMBER_SNAPSHOT_SERVICE, type MemberSnapshotPort } from '@tbox.cn/app-contracts-mall';
4
5
  import memberInfoMeta from './cards/member-info/meta';
5
6
  import memberCardSummaryMeta from './cards/member-card-summary/meta';
6
7
  import memberPointUsageListMeta from './cards/member-point-usage-list/meta';
@@ -153,5 +154,24 @@ export const serverModule = {
153
154
  // 015 D9:主体绑定(promotion acquire 消费;ctx.services 跨模块 resolveService)
154
155
  ctx.services.register('member.subject-binding', createSubjectBinding(ctx));
155
156
 
157
+ // 会员快览工厂(member.snapshot,W3-3):首页联单面板跨模块消费面
158
+ // (账户/授权三态 + 积分 + 入会引导)。三槽组装——enrollment 槽 fail-soft
159
+ // (缺席不拖垮账户/积分主面);工厂运行期执行(注册期纯净铁律)。
160
+ ctx.services.register(
161
+ MEMBER_SNAPSHOT_SERVICE,
162
+ async (reqCtx: RequestContext): Promise<MemberSnapshotPort> => {
163
+ const [account, benefits, enrollment] = await Promise.all([
164
+ resolveMemberAccountPort(reqCtx, ctx),
165
+ resolveMemberBenefitsPort(reqCtx, ctx),
166
+ resolveMemberEnrollmentPort(reqCtx, ctx).catch(() => null),
167
+ ]);
168
+ return {
169
+ getAccount: (userId: string) => account.getAccount(userId),
170
+ queryPoints: (userId: string) => benefits.queryPoints(userId),
171
+ ...(enrollment?.enrollUrl ? { enrollUrl: enrollment.enrollUrl } : {}),
172
+ };
173
+ },
174
+ );
175
+
156
176
  },
157
177
  } satisfies ServerModule;
@@ -0,0 +1,75 @@
1
+ /**
2
+ * member.snapshot 快览服务回归(W3-3 单一模板统一化):
3
+ * register 注册三槽组装工厂——账户/积分主面透传,enrollment 槽 fail-soft
4
+ * (缺席/失败不拖垮主面,enrollUrl 缺省)。
5
+ */
6
+ import { describe, expect, it, vi } from 'vitest';
7
+
8
+ vi.mock('../src/server/ports', async (importOriginal) => {
9
+ const actual = await importOriginal<typeof import('../src/server/ports')>();
10
+ return {
11
+ ...actual,
12
+ resolveMemberAccountPort: vi.fn(),
13
+ resolveMemberBenefitsPort: vi.fn(),
14
+ resolveMemberEnrollmentPort: vi.fn(),
15
+ };
16
+ });
17
+
18
+ import type { RequestContext } from '@tbox.cn/app-contracts';
19
+ import type { MemberSnapshotPort } from '@tbox.cn/app-contracts-mall';
20
+ import { MEMBER_SNAPSHOT_SERVICE } from '@tbox.cn/app-contracts-mall';
21
+ import { createServerContext } from '@tbox.cn/app-sdk/server';
22
+ import { serverModule } from '../src/server/index';
23
+ import {
24
+ resolveMemberAccountPort,
25
+ resolveMemberBenefitsPort,
26
+ resolveMemberEnrollmentPort,
27
+ } from '../src/server/ports';
28
+
29
+ const makeReqCtx = () =>
30
+ ({
31
+ identity: { userId: 'u_1', source: 'dev' },
32
+ conversationId: 'conv_snapshot',
33
+ attributes: { mall: { miniAppId: 'app', mallId: 'mall-1' } },
34
+ }) as unknown as RequestContext;
35
+
36
+ describe('member.snapshot 快览工厂(register 注册,运行期解析)', () => {
37
+ it('register 注册工厂;三槽主面透传 + enrollUrl 透传', async () => {
38
+ const ctx = createServerContext();
39
+ serverModule.register(ctx);
40
+ const factory = ctx.resolveService<(reqCtx: RequestContext) => Promise<MemberSnapshotPort>>(
41
+ MEMBER_SNAPSHOT_SERVICE,
42
+ );
43
+ expect(factory).toBeTypeOf('function');
44
+
45
+ const getAccount = vi.fn(async () => ({ authState: 'authenticated', state: 'active' }));
46
+ const queryPoints = vi.fn(async () => ({ balance: '100' }));
47
+ vi.mocked(resolveMemberAccountPort).mockResolvedValue({ getAccount } as never);
48
+ vi.mocked(resolveMemberBenefitsPort).mockResolvedValue({ queryPoints } as never);
49
+ vi.mocked(resolveMemberEnrollmentPort).mockResolvedValue({ enrollUrl: 'https://enroll.example' } as never);
50
+
51
+ const port = await factory!(makeReqCtx());
52
+ await port.getAccount('u_1');
53
+ await port.queryPoints('u_1');
54
+ expect(getAccount).toHaveBeenCalledWith('u_1');
55
+ expect(queryPoints).toHaveBeenCalledWith('u_1');
56
+ expect(port.enrollUrl).toBe('https://enroll.example');
57
+ });
58
+
59
+ it('enrollment 槽失败 fail-soft:enrollUrl 缺席,账户/积分主面存活', async () => {
60
+ const ctx = createServerContext();
61
+ serverModule.register(ctx);
62
+ const factory = ctx.resolveService<(reqCtx: RequestContext) => Promise<MemberSnapshotPort>>(
63
+ MEMBER_SNAPSHOT_SERVICE,
64
+ );
65
+
66
+ const getAccount = vi.fn(async () => ({ authState: 'authenticated', state: 'not_enrolled' }));
67
+ vi.mocked(resolveMemberAccountPort).mockResolvedValue({ getAccount } as never);
68
+ vi.mocked(resolveMemberBenefitsPort).mockResolvedValue({ queryPoints: vi.fn() } as never);
69
+ vi.mocked(resolveMemberEnrollmentPort).mockRejectedValue(new Error('enrollment down'));
70
+
71
+ const port = await factory!(makeReqCtx());
72
+ await expect(port.getAccount('u_1')).resolves.toMatchObject({ state: 'not_enrolled' });
73
+ expect(port.enrollUrl).toBeUndefined();
74
+ });
75
+ });
Binary file
Binary file
@@ -1,5 +0,0 @@
1
- /** Static member image assets bundled by Vite/tsup. */
2
- declare module '*.jpg' {
3
- const url: string;
4
- export default url;
5
- }