@pisell/private-materials 6.11.181 → 6.11.182

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.
Files changed (35) hide show
  1. package/build/lowcode/assets-daily.json +11 -11
  2. package/build/lowcode/assets-dev.json +2 -2
  3. package/build/lowcode/assets-prod.json +11 -11
  4. package/build/lowcode/meta.js +1 -1
  5. package/build/lowcode/render/default/view.js +1 -1
  6. package/build/lowcode/view.js +1 -1
  7. package/es/components/booking/forms/sendModal/useSendModal.d.ts +0 -1
  8. package/es/components/checkout/PaymentModal.js +2 -1
  9. package/es/components/eftposPay/amount.d.ts +1 -1
  10. package/es/components/eftposPay/app.d.ts +1 -1
  11. package/es/components/eftposPay/device.d.ts +1 -1
  12. package/es/components/ticketBooking/components/ticketBooking/index.d.ts +16 -0
  13. package/es/plus/pisellReservation/PisellReservation.js +113 -12
  14. package/es/plus/pisellReservation/components/bookingDetailModal/ReservationBookingDetailModal.js +2 -2
  15. package/es/plus/pisellSalesManagement/config/booking.d.ts +6 -7
  16. package/es/plus/pisellSalesManagement/hooks/useBookingPerspective.js +3 -1
  17. package/es/plus/pisellSalesManagement/hooks/useSalesGridData.d.ts +0 -1
  18. package/es/plus/pisellSalesManagement/index.js +1 -1
  19. package/lib/components/booking/forms/sendModal/useSendModal.d.ts +0 -1
  20. package/lib/components/checkout/PaymentModal.js +2 -1
  21. package/lib/components/eftposPay/amount.d.ts +1 -1
  22. package/lib/components/eftposPay/app.d.ts +1 -1
  23. package/lib/components/eftposPay/device.d.ts +1 -1
  24. package/lib/components/ticketBooking/components/ticketBooking/index.d.ts +16 -0
  25. package/lib/plus/pisellReservation/PisellReservation.js +8 -3
  26. package/lib/plus/pisellReservation/components/bookingDetailModal/ReservationBookingDetailModal.js +2 -2
  27. package/lib/plus/pisellSalesManagement/config/booking.d.ts +6 -7
  28. package/lib/plus/pisellSalesManagement/hooks/useBookingPerspective.js +2 -1
  29. package/lib/plus/pisellSalesManagement/hooks/useSalesGridData.d.ts +0 -1
  30. package/lib/plus/pisellSalesManagement/index.js +1 -1
  31. package/package.json +4 -4
  32. package/es/plus/pisellReservation/docs/booking-detail-modal-data-ui-map.html +0 -357
  33. package/es/plus/pisellReservation/docs/floor-room-card-data-ui-map.html +0 -841
  34. package/lib/plus/pisellReservation/docs/booking-detail-modal-data-ui-map.html +0 -357
  35. package/lib/plus/pisellReservation/docs/floor-room-card-data-ui-map.html +0 -841
@@ -1,841 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="zh-CN">
3
- <head>
4
- <meta charset="UTF-8" />
5
- <meta name="viewport" content="width=device-width, initial-scale=1" />
6
- <title>平面图 RoomCard · 数据与 UI 对应</title>
7
- <link rel="preconnect" href="https://fonts.googleapis.com" />
8
- <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
9
- <link
10
- href="https://fonts.googleapis.com/css2?family=DM+Sans:ital,opsz,wght@0,9..40,400;0,9..40,600;0,9..40,700;1,9..40,400&family=JetBrains+Mono:wght@400;600&display=swap"
11
- rel="stylesheet"
12
- />
13
- <style>
14
- :root {
15
- --ink: #1a1f1c;
16
- --muted: #5c6560;
17
- --line: #c8d0ca;
18
- --reserved-bg: #f4f7f5;
19
- --occupied-bg: #17503a;
20
- --occupied-text: #f2f7f4;
21
- --tag-res: #2d6a4f;
22
- --tag-occ: rgba(255, 255, 255, 0.2);
23
- --note-bg: #fff9e6;
24
- --note-border: #e8d48b;
25
- --mono: "JetBrains Mono", monospace;
26
- --sans: "DM Sans", system-ui, sans-serif;
27
- }
28
- * {
29
- box-sizing: border-box;
30
- }
31
- body {
32
- margin: 0;
33
- padding: 32px 24px 48px;
34
- font-family: var(--sans);
35
- color: var(--ink);
36
- background: linear-gradient(165deg, #eef2ef 0%, #e2e8e4 45%, #dce5df 100%);
37
- min-height: 100vh;
38
- }
39
- .page-head {
40
- display: grid;
41
- grid-template-columns: minmax(0, 1fr) minmax(280px, 380px);
42
- gap: 24px 28px;
43
- align-items: start;
44
- margin-bottom: 28px;
45
- max-width: 1280px;
46
- }
47
- @media (max-width: 900px) {
48
- .page-head {
49
- grid-template-columns: 1fr;
50
- }
51
- }
52
- .page-head__main .lead {
53
- margin-bottom: 0;
54
- }
55
- .state-panel {
56
- position: sticky;
57
- top: 16px;
58
- border: 1px solid var(--line);
59
- border-radius: 10px;
60
- background: #fff;
61
- padding: 14px 16px 16px;
62
- box-shadow: 0 4px 18px rgba(26, 31, 28, 0.06);
63
- font-size: 0.72rem;
64
- line-height: 1.45;
65
- }
66
- .state-panel h2 {
67
- margin: 0 0 12px;
68
- font-size: 0.78rem;
69
- font-weight: 700;
70
- letter-spacing: -0.01em;
71
- color: var(--ink);
72
- }
73
- .state-panel section {
74
- margin-bottom: 14px;
75
- }
76
- .state-panel section:last-child {
77
- margin-bottom: 0;
78
- }
79
- .state-panel h3 {
80
- margin: 0 0 6px;
81
- font-size: 0.62rem;
82
- text-transform: uppercase;
83
- letter-spacing: 0.07em;
84
- color: var(--muted);
85
- font-weight: 700;
86
- }
87
- .state-panel dl {
88
- margin: 0;
89
- }
90
- .state-panel dt {
91
- font-family: var(--mono);
92
- font-size: 0.68rem;
93
- font-weight: 600;
94
- color: #2a332e;
95
- margin-top: 8px;
96
- }
97
- .state-panel dt:first-child {
98
- margin-top: 0;
99
- }
100
- .state-panel dd {
101
- margin: 4px 0 0;
102
- padding-left: 0;
103
- color: var(--muted);
104
- }
105
- .state-panel .enum {
106
- font-family: var(--mono);
107
- font-size: 0.65rem;
108
- color: #2d4a3e;
109
- background: #f0f4f1;
110
- padding: 6px 8px;
111
- border-radius: 6px;
112
- margin-top: 4px;
113
- word-break: break-word;
114
- }
115
- .state-panel .arrow-note {
116
- color: var(--muted);
117
- font-size: 0.65rem;
118
- margin-top: 2px;
119
- }
120
- /** 标题区 + 右上角状态参考 */
121
- .page-top {
122
- display: grid;
123
- grid-template-columns: minmax(0, 1fr) minmax(260px, 400px);
124
- gap: 24px 28px;
125
- align-items: start;
126
- max-width: 1120px;
127
- margin-bottom: 28px;
128
- }
129
- @media (max-width: 900px) {
130
- .page-top {
131
- grid-template-columns: 1fr;
132
- }
133
- }
134
- .state-ref {
135
- border: 1px solid var(--line);
136
- border-radius: 10px;
137
- padding: 14px 16px;
138
- background: #fff;
139
- box-shadow: 0 4px 18px rgba(26, 31, 28, 0.06);
140
- font-size: 0.72rem;
141
- line-height: 1.5;
142
- }
143
- .state-ref h2 {
144
- margin: 0 0 10px;
145
- font-size: 0.68rem;
146
- font-weight: 700;
147
- text-transform: uppercase;
148
- letter-spacing: 0.07em;
149
- color: var(--muted);
150
- }
151
- .state-ref section {
152
- margin-bottom: 14px;
153
- }
154
- .state-ref section:last-child {
155
- margin-bottom: 0;
156
- }
157
- .state-ref h3 {
158
- margin: 0 0 6px;
159
- font-size: 0.7rem;
160
- font-weight: 700;
161
- color: var(--ink);
162
- }
163
- .state-ref p {
164
- margin: 0 0 6px;
165
- color: var(--muted);
166
- font-size: 0.68rem;
167
- }
168
- .state-ref ul {
169
- margin: 0;
170
- padding-left: 1.1em;
171
- font-family: var(--mono);
172
- font-size: 0.65rem;
173
- color: #2a332e;
174
- }
175
- .state-ref li {
176
- margin-bottom: 4px;
177
- }
178
- .state-ref li:last-child {
179
- margin-bottom: 0;
180
- }
181
- .state-ref code {
182
- font-family: var(--mono);
183
- font-size: 0.92em;
184
- background: rgba(45, 106, 79, 0.08);
185
- padding: 0 4px;
186
- border-radius: 3px;
187
- }
188
- .state-ref .src-note {
189
- font-family: var(--sans);
190
- font-size: 0.62rem;
191
- color: var(--muted);
192
- margin-top: 4px;
193
- }
194
- h1 {
195
- font-size: 1.35rem;
196
- font-weight: 700;
197
- letter-spacing: -0.02em;
198
- margin: 0 0 8px;
199
- }
200
- .lead {
201
- color: var(--muted);
202
- font-size: 0.9rem;
203
- max-width: 720px;
204
- line-height: 1.5;
205
- margin-bottom: 28px;
206
- }
207
- .flow {
208
- display: grid;
209
- gap: 16px;
210
- margin-bottom: 36px;
211
- max-width: 960px;
212
- }
213
- .flow-row {
214
- display: flex;
215
- flex-wrap: wrap;
216
- align-items: stretch;
217
- gap: 12px;
218
- }
219
- .box {
220
- border: 1px solid var(--line);
221
- border-radius: 10px;
222
- padding: 12px 14px;
223
- background: #fff;
224
- flex: 1;
225
- min-width: 200px;
226
- }
227
- .box h3 {
228
- margin: 0 0 8px;
229
- font-size: 0.72rem;
230
- text-transform: uppercase;
231
- letter-spacing: 0.08em;
232
- color: var(--muted);
233
- font-weight: 600;
234
- }
235
- .box pre {
236
- margin: 0;
237
- font-family: var(--mono);
238
- font-size: 0.68rem;
239
- line-height: 1.45;
240
- white-space: pre-wrap;
241
- word-break: break-all;
242
- color: #2a332e;
243
- }
244
- .arrow {
245
- display: flex;
246
- align-items: center;
247
- justify-content: center;
248
- color: var(--muted);
249
- font-size: 1.2rem;
250
- font-weight: 600;
251
- min-width: 32px;
252
- }
253
- .cards-grid {
254
- display: grid;
255
- grid-template-columns: 1fr;
256
- gap: 40px;
257
- max-width: 920px;
258
- align-items: start;
259
- }
260
- .card-wrap {
261
- overflow: visible;
262
- }
263
- .card-wrap h2 {
264
- font-size: 0.8rem;
265
- color: var(--muted);
266
- margin: 0 0 14px;
267
- font-weight: 600;
268
- }
269
- /* 图元 + 说明并排,说明不再被 overflow 裁切 */
270
- .card-demo {
271
- display: grid;
272
- grid-template-columns: minmax(260px, 300px) minmax(0, 1fr);
273
- gap: 20px 24px;
274
- align-items: start;
275
- }
276
- @media (max-width: 640px) {
277
- .card-demo {
278
- grid-template-columns: 1fr;
279
- }
280
- }
281
- .notes-column {
282
- min-width: 0;
283
- }
284
- /* 模拟 rc:圆角与阴影只在表面层,不把旁注裁掉 */
285
- .rc {
286
- border-radius: 12px;
287
- overflow: hidden;
288
- box-shadow: 0 8px 28px rgba(26, 31, 28, 0.12);
289
- font-size: 12px;
290
- max-width: 300px;
291
- }
292
- .rc--reserved {
293
- background: var(--reserved-bg);
294
- color: var(--ink);
295
- }
296
- .rc--occupied {
297
- background: var(--occupied-bg);
298
- color: var(--occupied-text);
299
- }
300
- .rc-header {
301
- display: flex;
302
- justify-content: space-between;
303
- align-items: flex-start;
304
- padding: 10px 12px;
305
- border-bottom: 1px solid rgba(0, 0, 0, 0.06);
306
- }
307
- .rc--occupied .rc-header {
308
- border-bottom-color: rgba(255, 255, 255, 0.12);
309
- }
310
- .rc-room-name {
311
- font-weight: 700;
312
- font-size: 14px;
313
- display: block;
314
- }
315
- .rc-capacity {
316
- font-size: 11px;
317
- opacity: 0.65;
318
- margin-top: 2px;
319
- }
320
- .rc-tag {
321
- font-size: 10px;
322
- padding: 3px 8px;
323
- border-radius: 999px;
324
- font-weight: 600;
325
- }
326
- .rc-tag--reserved {
327
- background: rgba(45, 106, 79, 0.15);
328
- color: var(--tag-res);
329
- }
330
- .rc-tag--occupied {
331
- background: var(--tag-occ);
332
- color: #fff;
333
- }
334
- .rc-body {
335
- padding: 10px 12px 12px;
336
- }
337
- .rc-contact__name {
338
- font-weight: 600;
339
- font-size: 13px;
340
- }
341
- .rc-contact__phone {
342
- font-size: 11px;
343
- opacity: 0.6;
344
- margin-left: 6px;
345
- }
346
- .rc-time-row {
347
- margin-top: 8px;
348
- font-size: 12px;
349
- line-height: 1.5;
350
- opacity: 0.92;
351
- }
352
- .hl-info {
353
- color: #1677b6;
354
- font-weight: 500;
355
- }
356
- .rc--occupied .hl-info {
357
- color: #9cd3ff;
358
- }
359
- .hl-over {
360
- color: #c9a227;
361
- font-weight: 600;
362
- }
363
- .rc--occupied .hl-over {
364
- color: #f5c542;
365
- }
366
- .hl-danger {
367
- color: #d4380d;
368
- font-weight: 600;
369
- }
370
- .rc--occupied .hl-danger {
371
- color: #ffb4a8;
372
- }
373
- .rc-amount {
374
- margin-top: 10px;
375
- font-weight: 600;
376
- font-size: 14px;
377
- }
378
- .rc--occupied .rc-amount.hl-paid {
379
- color: #7dffb0;
380
- }
381
- .rc-progress {
382
- margin-top: 8px;
383
- }
384
- .rc-progress__bar {
385
- height: 4px;
386
- background: rgba(0, 0, 0, 0.12);
387
- border-radius: 2px;
388
- overflow: hidden;
389
- }
390
- .rc--occupied .rc-progress__bar {
391
- background: rgba(255, 255, 255, 0.2);
392
- }
393
- .rc-progress__fill {
394
- height: 100%;
395
- width: 62%;
396
- background: #fff;
397
- border-radius: 2px;
398
- }
399
- .rc--occupied .rc-progress__fill.warn {
400
- background: #f5c542;
401
- width: 88%;
402
- }
403
- .rc-stamp {
404
- margin-top: 8px;
405
- width: 48px;
406
- height: 48px;
407
- border-radius: 50%;
408
- border: 2px solid #34c759;
409
- display: flex;
410
- align-items: center;
411
- justify-content: center;
412
- font-size: 9px;
413
- font-weight: 700;
414
- color: #34c759;
415
- transform: rotate(-14deg);
416
- opacity: 0.95;
417
- }
418
- .rc--occupied .rc-stamp {
419
- border-color: rgba(255, 255, 255, 0.5);
420
- color: #b8f5ce;
421
- }
422
- .rc-next {
423
- margin-top: 10px;
424
- font-size: 11px;
425
- line-height: 1.45;
426
- opacity: 0.88;
427
- }
428
- .rc-next__label {
429
- font-weight: 700;
430
- text-transform: uppercase;
431
- letter-spacing: 0.04em;
432
- font-size: 10px;
433
- opacity: 0.75;
434
- }
435
- .rc-next__sep {
436
- margin: 0 4px;
437
- opacity: 0.5;
438
- }
439
- .rc--occupied .rc-next {
440
- color: rgba(255, 255, 255, 0.92);
441
- }
442
- .note {
443
- font-family: var(--mono);
444
- font-size: 0.65rem;
445
- line-height: 1.45;
446
- padding: 8px 10px;
447
- background: var(--note-bg);
448
- border: 1px solid var(--note-border);
449
- border-radius: 8px;
450
- color: #4a4428;
451
- margin-bottom: 12px;
452
- }
453
- .note:last-child {
454
- margin-bottom: 0;
455
- }
456
- .note-label {
457
- display: block;
458
- font-family: var(--sans);
459
- font-size: 0.62rem;
460
- font-weight: 700;
461
- text-transform: uppercase;
462
- letter-spacing: 0.06em;
463
- color: var(--muted);
464
- margin-bottom: 6px;
465
- }
466
- .note--dark {
467
- background: #1e2e28;
468
- border-color: #2d4a3e;
469
- color: #d8ebe3;
470
- }
471
- .note--dark .note-label {
472
- color: #8fb5a3;
473
- }
474
- .legend {
475
- margin-top: 40px;
476
- padding: 16px;
477
- background: #fff;
478
- border-radius: 10px;
479
- border: 1px solid var(--line);
480
- max-width: 960px;
481
- }
482
- .legend h3 {
483
- margin: 0 0 10px;
484
- font-size: 0.85rem;
485
- }
486
- .legend table {
487
- width: 100%;
488
- border-collapse: collapse;
489
- font-size: 0.72rem;
490
- font-family: var(--mono);
491
- }
492
- .legend th,
493
- .legend td {
494
- text-align: left;
495
- padding: 6px 8px;
496
- border-bottom: 1px solid #eee;
497
- vertical-align: top;
498
- }
499
- .legend th {
500
- color: var(--muted);
501
- font-weight: 600;
502
- width: 28%;
503
- }
504
- </style>
505
- </head>
506
- <body>
507
- <div class="page-head">
508
- <div class="page-head__main">
509
- <h1>平面图 RoomCard:数据结构 ≈ UI 区域</h1>
510
- <p class="lead">
511
- 对应代码:<code>mapPisellReservationRowToFloorRoomCardData</code> →
512
- <code>FloorRoomCardData</code> → <code>ReservationFloorRoomCard</code>(<code>getFloorRoomCardType</code> 决定
513
- <code>cardType</code> 与皮肤 class)。占用态<strong>金额高亮</strong>仍跟 <code>cardType === 'payed'</code>;<strong>印章
514
- PaymentStamp</strong>单独跟 <code>booking.order.payment_status</code>(经 <code>rawToBooking</code> 写入
515
- <code>order_payment_status</code>,仅 <code>paid</code> 为已付)。下方示意与真实 class(rc-*)一致;<strong>左侧图元、右侧为数据说明</strong>。
516
- </p>
517
- </div>
518
- <aside class="state-panel" aria-label="状态来源与枚举">
519
- <h2>右上角 · 状态来源与枚举</h2>
520
- <section>
521
- <h3>宿主 booking / 资源壳(接口原始)</h3>
522
- <dl>
523
- <dt>booking.status</dt>
524
- <dd>
525
- 合并为行大类:<code>hostBookingStatusToCardStatus</code>
526
- <div class="enum">
527
- 'occupied' → cardStatus occupied<br />
528
- 'reserved' → booked<br />
529
- 'locked' → maintenance<br />
530
- 空 / 其他 → available
531
- </div>
532
- </dd>
533
- <dt>booking.reserved_status</dt>
534
- <dd>
535
- 仅当 <code>status === 'reserved'</code> 时写入行 <code>hostReservedStatus</code>
536
- <div class="enum">'not_arrived' | 'late'</div>
537
- </dd>
538
- <dt>booking.isTimeout</dt>
539
- <dd>
540
- 仅当 <code>status === 'occupied'</code> 时为 <code>true</code> → 行 <code>hostIsTimeout</code>
541
- </dd>
542
- <dt>booking.order.payment_status</dt>
543
- <dd>
544
- <code>rawToBooking</code> 读 <code>order.payment_status</code> → 扁平字段
545
- <code>FloorRoomCardBooking.order_payment_status</code>(<code>paid</code> 忽略大小写归一)。<br />
546
- <strong>仅印章</strong>判断:<code>=== 'paid'</code> → 已付样式;其余一律未付。<strong>不参与</strong>
547
- <code>cardType</code> / 是否占用 / <code>sub_status</code>。
548
- </dd>
549
- <dt>资源壳 shell(无 bookings 命中时)</dt>
550
- <dd>
551
- <code>applyHostResourceShellToBaseRow</code>:同上字段 + <code>shell.status</code>(empty / reserved / occupied / locked)直接改
552
- <code>cardStatus</code> 与宿主标记
553
- </dd>
554
- </dl>
555
- </section>
556
- <section>
557
- <h3>合并行 PisellReservationTableRow</h3>
558
- <dl>
559
- <dt>cardStatus</dt>
560
- <dd>
561
- <div class="enum">
562
- 'occupied' | 'booked' | 'maintenance' | 'barBusy' | 'available'
563
- </div>
564
- <p class="arrow-note">
565
- → <code>mapPisellReservationRowToFloorRoomCardData</code>:<br />
566
- maintenance → status <strong>locked</strong>;available → <strong>empty</strong>;booked →
567
- <strong>reserved</strong>;occupied / barBusy → <strong>occupied</strong>
568
- </p>
569
- </dd>
570
- <dt>hostReservedStatus(预留细分)</dt>
571
- <dd>
572
- <div class="enum">'not_arrived' | 'late'</div>
573
- 兜底:行 <code>lateMinutes &gt; 0</code> → sub_status <strong>late</strong>
574
- </dd>
575
- <dt>占用细分(行级)</dt>
576
- <dd>
577
- <code>hostIsTimeout === true</code> 或 <code>delayMinutes &gt; 0</code> → <strong>timeout</strong><br />
578
- <code>isPaid === false</code> → <strong>payment_required</strong><br />
579
- 否则 → <strong>payed</strong>
580
- </dd>
581
- </dl>
582
- </section>
583
- <section>
584
- <h3>FloorRoomCardData(图元 props)</h3>
585
- <dl>
586
- <dt>status(顶栏标签大类)</dt>
587
- <dd>
588
- <div class="enum">'empty' | 'reserved' | 'occupied' | 'locked'</div>
589
- </dd>
590
- <dt>sub_status(getFloorRoomCardType / 皮肤)</dt>
591
- <dd>
592
- <div class="enum">
593
- 'not_arrived' | 'late' | 'payed' | 'payment_required' | 'timeout' | ''(空串)
594
- </div>
595
- </dd>
596
- <dt>单条 booking 宿主分钟 / 进度</dt>
597
- <dd>
598
- 原始字段 <code>lateTime</code>、<code>timeoutTime</code>、<code>progressPercent</code>(0–100)经
599
- <code>rawToBooking</code> 进入 <code>FloorRoomCardBooking</code>,优先于本地时间推算
600
- </dd>
601
- <dt>order_payment_status(图元内扁平)</dt>
602
- <dd>
603
- 来自宿主 <code>booking.order.payment_status</code>,供 <code>PaymentStamp</code> 专用;缺省或无
604
- <code>paid</code> 时印章为未付
605
- </dd>
606
- <dt>Next 行(多段 <code>bookings</code>)</dt>
607
- <dd>
608
- <code>getFloorRoomCardNextNotStartedBooking(data, now)</code>:<code>bookings.length ≥ 2</code>,
609
- 且 <code>bookings[0]</code> 在当前时刻落在 <strong>[start, end)</strong>(进行中),且
610
- <code>bookings[1..]</code> 中存在 <strong>now &lt; start</strong>(未开始)→ 取第一条未开始,渲染
611
- <code>NextBooking</code>(标签「Next」· 姓名 · <code>start_time - end_time</code>)。<strong>不依赖</strong>
612
- <code>cardType</code> 是否为 <code>late</code> / <code>timeout</code>。标准 <code>CardBody</code>(非
613
- compact)末尾展示;约 60s 定时刷新会带动更新。
614
- </dd>
615
- </dl>
616
- </section>
617
- </aside>
618
- </div>
619
-
620
- <div class="flow">
621
- <div class="flow-row">
622
- <div class="box">
623
- <h3>输入 · PisellReservationTableRow(合并行)</h3>
624
- <pre>id, code, main_field
625
- cardStatus → 映射 status / 分支
626
- capacityLabel → capacity 文案
627
- hostReservedStatus, lateMinutes → reserved.sub_status
628
- hostIsTimeout, delayMinutes, isPaid → occupied.sub_status
629
- floorMapSourceBookings[] → rawToBooking → bookings[]</pre>
630
- </div>
631
- <span class="arrow">→</span>
632
- <div class="box">
633
- <h3>中间 · FloorRoomCardData</h3>
634
- <pre>main_field, capacity
635
- status: empty | reserved | occupied | locked
636
- sub_status: not_arrived | late | payed | payment_required | timeout
637
- bookings: FloorRoomCardBooking[]
638
- Next 行: bookings[0] 进行中 ∧ 后方有未开始
639
- → getFloorRoomCardNextNotStartedBooking(data, now)</pre>
640
- </div>
641
- <span class="arrow">→</span>
642
- <div class="box">
643
- <h3>每条 booking(rawToBooking)</h3>
644
- <pre>start_date, start_time, end_date, end_time
645
- number, amount
646
- holder.name, holder.phone
647
- lateTime, timeoutTime, progressPercent(宿主分钟/进度)
648
- order.payment_status → order_payment_status(印章)</pre>
649
- </div>
650
- </div>
651
- </div>
652
-
653
- <div class="cards-grid">
654
- <div class="card-wrap">
655
- <h2>预留 · cardType = not_arrived / late(rc--reserved)</h2>
656
- <div class="card-demo">
657
- <div class="rc rc--reserved">
658
- <div class="rc-header">
659
- <div>
660
- <span class="rc-room-name">test 1</span>
661
- <span class="rc-capacity">Cap: 100</span>
662
- </div>
663
- <span class="rc-tag rc-tag--reserved">已预订</span>
664
- </div>
665
- <div class="rc-body">
666
- <div>
667
- <span class="rc-contact__name">肉肉6666</span>
668
- <span class="rc-contact__phone">***8745</span>
669
- </div>
670
- <div class="rc-time-row">
671
- 🕐 16:53 开始 · 👥 2
672
- <span class="hl-info"> · 🕐 还有 8 分钟</span>
673
- </div>
674
- <div class="rc-time-row" style="margin-top: 4px">
675
- <span class="hl-over">⚠ +15m</span>
676
- </div>
677
- </div>
678
- </div>
679
- <div class="notes-column">
680
- <div class="note">
681
- <span class="note-label">① 顶栏 rc-header</span>
682
- data.main_field → 房名<br />
683
- data.capacity + i18n「Cap」<br />
684
- data.status → StatusTag(已预订)
685
- </div>
686
- <div class="note">
687
- <span class="note-label">② 联系人 rc-contact</span>
688
- bookings[0].holder.name<br />
689
- holder.phone(脱敏后四位)
690
- </div>
691
- <div class="note">
692
- <span class="note-label">③ 时间行 rc-time-row</span>
693
- booking.start_time + i18n「开始」<br />
694
- booking.number(人数)<br />
695
- 倒计时:resolveFloorRoomCardReservedCountdownMinutes(优先
696
- <code>remainingReserveTime</code> 分钟,否则本地起止推算;仅 not_arrived)
697
- </div>
698
- <div class="note">
699
- <span class="note-label">④ 预留迟到 · rc-highlight--overtime</span>
700
- 仅 cardType = late 时显示「+10m」<br />
701
- 优先 booking.lateTime(分钟)→ format 文案<br />
702
- 否则 getFloorRoomCardLateTime(start_date, start_time)
703
- </div>
704
- </div>
705
- </div>
706
- </div>
707
-
708
- <div class="card-wrap">
709
- <h2>占用 · cardType = payed / payment_required / timeout(rc--occupied)</h2>
710
- <div class="card-demo">
711
- <div class="rc rc--occupied">
712
- <div class="rc-header">
713
- <div>
714
- <span class="rc-room-name">test 1</span>
715
- <span class="rc-capacity">Cap: 100</span>
716
- </div>
717
- <span class="rc-tag rc-tag--occupied">使用中</span>
718
- </div>
719
- <div class="rc-body">
720
- <div>
721
- <span class="rc-contact__name">肉肉6666</span>
722
- <span class="rc-contact__phone">***8745</span>
723
- </div>
724
- <div class="rc-time-row">🕐 17:03 结束 · 👥 2</div>
725
- <div class="rc-time-row" style="margin-top: 4px">
726
- <span class="hl-danger">⚠ late 12m</span>
727
- </div>
728
- <div class="rc-amount hl-paid">$ 10.50</div>
729
- <div class="rc-progress">
730
- <div class="rc-progress__bar">
731
- <div class="rc-progress__fill warn"></div>
732
- </div>
733
- </div>
734
- <div class="rc-stamp">已付</div>
735
- <div class="rc-next">
736
- <span class="rc-next__label">Next</span><span class="rc-next__sep">·</span><span>下一位客人</span><span class="rc-next__sep">·</span><span>19:00 - 21:00</span>
737
- </div>
738
- </div>
739
- </div>
740
- <div class="notes-column">
741
- <div class="note note--dark">
742
- <span class="note-label">① 顶栏</span>
743
- 同预留:main_field、capacity、status → 使用中
744
- </div>
745
- <div class="note note--dark">
746
- <span class="note-label">② 联系人</span>
747
- bookings[0].holder.*
748
- </div>
749
- <div class="note note--dark">
750
- <span class="note-label">③ 时间行</span>
751
- booking.end_time + i18n「结束」<br />
752
- booking.number
753
- </div>
754
- <div class="note note--dark">
755
- <span class="note-label">④ 占用超时 · rc-highlight--danger</span>
756
- 仅 cardType = timeout 时「late 10m」<br />
757
- 优先 booking.timeoutTime(分钟)<br />
758
- 否则 getFloorRoomCardLateTime(start)
759
- </div>
760
- <div class="note note--dark">
761
- <span class="note-label">⑤ 金额 rc-amount</span>
762
- booking.amount<br />
763
- isPaid(cardType payed)→ 高亮 class
764
- </div>
765
- <div class="note note--dark">
766
- <span class="note-label">⑥ 进度条 ProgressBar</span>
767
- 宽度 % ← booking.progressPercent(0–100)<br />
768
- 无则用起止时间 resolveFloorRoomCardProgressPercent<br />
769
- isTimeout → rc-progress__fill--warn 黄色
770
- </div>
771
- <div class="note note--dark">
772
- <span class="note-label">⑦ 印章 PaymentStamp</span>
773
- 仅看 <code>booking.order_payment_status === 'paid'</code>(数据来自宿主
774
- <code>booking.order.payment_status</code>,<code>rawToBooking</code> 里 trim + 大小写归一为
775
- <code>paid</code>)。<br />
776
- 已付 / 未付<strong>与 cardType</strong>(payed / payment_required / timeout)<strong>解耦</strong>。
777
- </div>
778
- <div class="note note--dark">
779
- <span class="note-label">⑧ Next 行 rc-next</span>
780
- <code>getFloorRoomCardNextNotStartedBooking(data, Date.now())</code> 非空时渲染。<br />
781
- 条件:<code>bookings[0]</code> 当前在时段内;<code>bookings[1+]</code> 中第一条
782
- <code>now &lt; start</code>。<br />
783
- 文案:<code>holder.name</code>(示例「下一位客人」)+ <code>start_time - end_time</code>。预留 /
784
- 占用标准体均可能出现;compact 行不展示。
785
- </div>
786
- </div>
787
- </div>
788
- </div>
789
- </div>
790
-
791
- <div class="legend">
792
- <h3>宿主 booking 根字段 → 行 / 图元(摘要)</h3>
793
- <table>
794
- <tr>
795
- <th>status</th>
796
- <td>empty | reserved | occupied | locked → cardStatus → FloorRoomCardData.status</td>
797
- </tr>
798
- <tr>
799
- <th>reserved_status</th>
800
- <td>not_arrived | late → row.hostReservedStatus → sub_status(与 lateMinutes 兜底)</td>
801
- </tr>
802
- <tr>
803
- <th>isTimeout</th>
804
- <td>true → row.hostIsTimeout → occupied sub_status = timeout</td>
805
- </tr>
806
- <tr>
807
- <th>lateTime(分钟)</th>
808
- <td>raw → booking.lateTime → 预留 late 时「+10m」类(优先于本地推算)</td>
809
- </tr>
810
- <tr>
811
- <th>timeoutTime(分钟)</th>
812
- <td>raw → booking.timeoutTime → 占用 timeout 时「late 10m」类(优先于本地推算)</td>
813
- </tr>
814
- <tr>
815
- <th>progressPercent</th>
816
- <td>0–100 → booking.progressPercent → ProgressBar 宽度(优先于起止时间推算)</td>
817
- </tr>
818
- <tr>
819
- <th>order.payment_status</th>
820
- <td>
821
- <strong>行合并</strong>:参与列表侧 <code>isPaid</code> → 占用行
822
- <code>sub_status</code> 为 <code>payed</code> / <code>payment_required</code>(见
823
- <code>mapPisellReservationRowToFloorRoomCardData</code>)。<br />
824
- <strong>单条 booking</strong>:<code>rawToBooking</code> →
825
- <code>FloorRoomCardBooking.order_payment_status</code> → <strong>仅</strong>
826
- <code>PaymentStamp</code>:<code>paid</code> 已付,其余未付。
827
- </td>
828
- </tr>
829
- <tr>
830
- <th>Next 行</th>
831
- <td>
832
- 多段 <code>bookings</code>:<code>bookings[0]</code> 进行中(<code>now ∈ [start, end)</code>)且其后存在未开始(<code>now
833
- &lt; start</code>)→ <code>getFloorRoomCardNextNotStartedBooking</code> →
834
- <code>NextBooking</code>(Next · 姓名 · <code>start_time - end_time</code>)。与
835
- <code>late</code>/<code>timeout</code> 无关;时段由 <code>start_date/start_time/end_date/end_time</code> 解析。
836
- </td>
837
- </tr>
838
- </table>
839
- </div>
840
- </body>
841
- </html>