@etsoo/appscript 1.6.56 → 1.6.57

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,495 +0,0 @@
1
- import { NumberUtils, WindowStorage } from "@etsoo/shared";
2
- const ShoppingCartKeyField = "ETSOO-CART-KEYS";
3
- /**
4
- * Shopping cart
5
- * 购物篮
6
- */
7
- export class ShoppingCart {
8
- /**
9
- * Create identifier key
10
- * 创建识别键
11
- * @param currency Currency
12
- * @param culture Culture
13
- * @param key Additional key
14
- * @returns Result
15
- */
16
- static createKey(currency, culture, key) {
17
- return `ETSOO-CART-${culture}-${key}-${currency}`;
18
- }
19
- /**
20
- * Clear shopping cart
21
- * 清除购物篮
22
- * @param identifier Identifier
23
- * @param storage Storage
24
- */
25
- static clear(identifier, storage) {
26
- try {
27
- storage.setData(identifier, null);
28
- storage.setPersistedData(identifier, null);
29
- }
30
- catch (error) {
31
- console.warn(`ShoppingCart clear ${identifier} error`, error);
32
- }
33
- }
34
- /**
35
- * Get cart data
36
- * 获取购物篮数据
37
- * @param storage Storage
38
- * @param id Cart id
39
- * @returns Result
40
- */
41
- static getCartData(storage, id) {
42
- try {
43
- return (storage.getPersistedObject(id) ??
44
- storage.getObject(id));
45
- }
46
- catch (error) {
47
- console.warn(`ShoppingCart getCartData ${id} error`, error);
48
- }
49
- }
50
- /**
51
- * ISO currency id
52
- * 标准货币编号
53
- */
54
- get currency() {
55
- return this._currency;
56
- }
57
- set currency(value) {
58
- this._currency = value;
59
- }
60
- /**
61
- * ISO culture id, like zh-Hans
62
- * 标准语言文化编号
63
- */
64
- get culture() {
65
- return this._culture;
66
- }
67
- set culture(value) {
68
- this._culture = value;
69
- }
70
- /**
71
- * Items
72
- * 项目
73
- */
74
- get items() {
75
- return this._items;
76
- }
77
- set items(value) {
78
- this._items = value;
79
- }
80
- /**
81
- * Order level promotions
82
- * 订单层面促销
83
- */
84
- get promotions() {
85
- return this._promotions;
86
- }
87
- set promotions(value) {
88
- this._promotions = value;
89
- }
90
- /**
91
- * Currency symbol
92
- * 币种符号
93
- */
94
- get symbol() {
95
- return this._symbol;
96
- }
97
- set symbol(value) {
98
- this._symbol = value;
99
- }
100
- /**
101
- * Cart identifier
102
- * 购物篮标识
103
- */
104
- get identifier() {
105
- const o = this.owner;
106
- return ShoppingCart.createKey(this.currency, this.culture, this.key);
107
- }
108
- /**
109
- * All data keys
110
- * 所有的数据键
111
- */
112
- get keys() {
113
- return this.storage.getPersistedData(ShoppingCartKeyField, []);
114
- }
115
- set keys(items) {
116
- this.storage.setPersistedData(ShoppingCartKeyField, items);
117
- }
118
- /**
119
- * Lines count
120
- * 项目数量
121
- */
122
- get lines() {
123
- return this.items.length;
124
- }
125
- /**
126
- * Total qty
127
- * 总数量
128
- */
129
- get totalQty() {
130
- return this.items.map((item) => item.qty).sum();
131
- }
132
- /**
133
- * Total amount
134
- * 总金额
135
- */
136
- get totalAmount() {
137
- const subtotal = this.items
138
- .map((item) => item.subtotal - item.discount)
139
- .sum();
140
- const discount = this.promotions.sum("amount");
141
- return subtotal - discount;
142
- }
143
- /**
144
- * Total amount string
145
- * 总金额字符串
146
- */
147
- get totalAmountStr() {
148
- return this.formatAmount(this.totalAmount);
149
- }
150
- /**
151
- * Constructor
152
- * 构造函数
153
- * @param key Key for identifier
154
- * @param currency Currency ISO code
155
- * @param storage Data storage
156
- */
157
- constructor(key, currencyOrState, storage = new WindowStorage()) {
158
- this.storage = storage;
159
- this._items = [];
160
- this._promotions = [];
161
- /**
162
- * Cached prices
163
- * 缓存的价格
164
- */
165
- this.prices = {};
166
- this.key = key;
167
- if (Array.isArray(currencyOrState)) {
168
- this.reset(currencyOrState[0], currencyOrState[1]);
169
- }
170
- else {
171
- this.setCartData(currencyOrState);
172
- this.changeCurrency(currencyOrState.currency);
173
- this.changeCulture(currencyOrState.culture);
174
- }
175
- }
176
- getCartData() {
177
- return (this.storage.getPersistedObject(this.identifier) ??
178
- this.storage.getObject(this.identifier));
179
- }
180
- setCartData(state) {
181
- const { owner, items = [], promotions = [], formData, cache } = state ?? {};
182
- this.owner = owner;
183
- this.items = items;
184
- this.promotions = promotions;
185
- this.formData = formData;
186
- this.cache = cache;
187
- }
188
- doChange(reason, changedItems) {
189
- if (this.onChange)
190
- this.onChange(reason, changedItems);
191
- }
192
- /**
193
- * Add item
194
- * 添加项目
195
- * @param item New item
196
- */
197
- addItem(item) {
198
- this.addItems([item]);
199
- }
200
- /**
201
- * Add items
202
- * @param items New items
203
- */
204
- addItems(items) {
205
- this.items.push(...items);
206
- this.doChange("add", items);
207
- }
208
- /**
209
- * Cache price
210
- * @param id Item id
211
- * @param price Price
212
- * @param overrideExisting Override existing price
213
- */
214
- cachePrice(id, price, overrideExisting = false) {
215
- if (overrideExisting || this.prices[id] == null)
216
- this.prices[id] = price;
217
- }
218
- /**
219
- * Change currency
220
- * @param currency Currency
221
- */
222
- changeCurrency(currency) {
223
- this.currency = currency;
224
- this.symbol = NumberUtils.getCurrencySymbol(this.currency);
225
- }
226
- /**
227
- * Change culture
228
- * @param culture Culture
229
- */
230
- changeCulture(culture) {
231
- this.culture = culture;
232
- }
233
- /**
234
- * Clear storage
235
- * @param keepOwner Keep owner data
236
- */
237
- clear(keepOwner) {
238
- this.items.length = 0;
239
- this.promotions.length = 0;
240
- this.prices = {};
241
- this.cache = undefined;
242
- if (keepOwner) {
243
- this.save();
244
- }
245
- else {
246
- ShoppingCart.clear(this.identifier, this.storage);
247
- this.keys.remove(this.identifier);
248
- }
249
- this.doChange("clear", []);
250
- }
251
- /**
252
- * Format amount
253
- * @param amount Amount
254
- * @returns Result
255
- */
256
- formatAmount(amount) {
257
- return NumberUtils.formatMoney(amount, this.currency);
258
- }
259
- /**
260
- * Get item
261
- * @param id Item id
262
- * @returns Result
263
- */
264
- getItem(id) {
265
- return this.items.find((item) => item.id === id);
266
- }
267
- /**
268
- * Push item
269
- * 推送项目
270
- * @param data Item data
271
- * @returns Added or not
272
- */
273
- pushItem(data) {
274
- if (this.items.some((item) => item.id === data.id)) {
275
- return false;
276
- }
277
- else {
278
- this.addItem(data);
279
- return true;
280
- }
281
- }
282
- /**
283
- * Reset currency and culture
284
- * @param currency New currency
285
- * @param culture New culture
286
- */
287
- reset(currency, culture) {
288
- this.changeCurrency(currency);
289
- this.changeCulture(culture);
290
- this.setCartData(this.getCartData());
291
- }
292
- /**
293
- * Remove item from the index
294
- * @param index Item index
295
- */
296
- removeItem(index) {
297
- const removedItems = this.items.splice(index, 1);
298
- this.doChange("remove", removedItems);
299
- }
300
- /**
301
- * Reset item
302
- * @param item Shopping cart item
303
- */
304
- resetItem(item) {
305
- item.discount = 0;
306
- item.currentPrice = undefined;
307
- item.promotions = [];
308
- }
309
- /**
310
- * Save cart data
311
- * @param persisted For persisted storage
312
- */
313
- save(persisted = true) {
314
- if (this.owner == null)
315
- return;
316
- const { currency, culture, owner, items, promotions, formData, cache } = this;
317
- const data = {
318
- currency,
319
- culture,
320
- owner,
321
- items,
322
- promotions,
323
- formData,
324
- cache
325
- };
326
- try {
327
- if (persisted) {
328
- this.storage.setPersistedData(this.identifier, data);
329
- const keys = this.keys;
330
- if (!keys.includes(this.identifier)) {
331
- keys.push(this.identifier);
332
- this.keys = keys;
333
- }
334
- }
335
- else {
336
- this.storage.setData(this.identifier, data);
337
- }
338
- }
339
- catch (error) {
340
- console.warn(`ShoppingCart save ${this.identifier} error`, error);
341
- }
342
- return data;
343
- }
344
- /**
345
- * Trigger update
346
- * 触发更新
347
- */
348
- update() {
349
- this.doChange("update", []);
350
- }
351
- /**
352
- * Update discount
353
- * @param item Shopping cart item
354
- */
355
- updateDiscount(item) {
356
- item.discount = item.promotions.sum("amount");
357
- }
358
- /**
359
- * Update asset item
360
- * 更新资产项目
361
- * @param id Product id
362
- * @param qty Asset qty
363
- * @param itemCreator New item creator
364
- * @returns Updated or not
365
- */
366
- updateAssetItem(id, assetQty, itemCreator) {
367
- if (assetQty == null || assetQty <= 0)
368
- assetQty = 1;
369
- const index = this.items.findIndex((item) => item.id === id);
370
- if (index === -1) {
371
- // New
372
- if (itemCreator) {
373
- const price = this.prices[id];
374
- const data = itemCreator();
375
- const qty = data.qty;
376
- const newItem = {
377
- ...data,
378
- id,
379
- price,
380
- assetQty,
381
- subtotal: price * qty * assetQty,
382
- discount: 0,
383
- promotions: Array()
384
- };
385
- this.addItem(newItem);
386
- }
387
- return false;
388
- }
389
- else {
390
- // Update
391
- const item = this.items[index];
392
- // Price may be cached first
393
- const price = this.prices[id] ?? item.price;
394
- const qty = item.qty;
395
- const newItem = {
396
- ...item,
397
- price,
398
- assetQty,
399
- subtotal: price * qty * assetQty,
400
- discount: 0
401
- };
402
- this.items.splice(index, 1, newItem);
403
- this.doChange("update", [item, newItem]);
404
- }
405
- return true;
406
- }
407
- /**
408
- * Update item
409
- * 更新项目
410
- * @param id Product id
411
- * @param qty Qty
412
- * @param itemCreator New item creator
413
- * @returns Updated or not
414
- */
415
- updateItem(id, qty, itemCreator) {
416
- const index = this.items.findIndex((item) => item.id === id);
417
- if (qty == null) {
418
- // Remove the item
419
- if (index !== -1) {
420
- this.removeItem(index);
421
- }
422
- }
423
- else if (index === -1) {
424
- // New
425
- if (itemCreator) {
426
- const price = this.prices[id];
427
- const data = itemCreator();
428
- const newItem = {
429
- ...data,
430
- id,
431
- price,
432
- qty,
433
- subtotal: price * qty * (data.assetQty || 1),
434
- discount: 0,
435
- promotions: Array()
436
- };
437
- this.addItem(newItem);
438
- }
439
- return false;
440
- }
441
- else {
442
- // Update
443
- const item = this.items[index];
444
- // Price may be cached first
445
- const price = this.prices[id] ?? item.price;
446
- const newItem = {
447
- ...item,
448
- qty,
449
- price,
450
- subtotal: price * qty * (item.assetQty || 1),
451
- discount: 0
452
- };
453
- this.items.splice(index, 1, newItem);
454
- this.doChange("update", [item, newItem]);
455
- }
456
- return true;
457
- }
458
- /**
459
- * Update price
460
- * @param id Item id
461
- * @param price New price
462
- */
463
- updatePrice(id, price) {
464
- this.cachePrice(id, price, true);
465
- const index = this.items.findIndex((item) => item.id === id);
466
- if (index !== -1) {
467
- const item = this.items[index];
468
- const qty = item.qty;
469
- const assetQty = item.assetQty || 1;
470
- const newItem = {
471
- ...item,
472
- price,
473
- subtotal: price * qty * assetQty
474
- };
475
- this.items.splice(index, 1, newItem);
476
- this.doChange("update", [item, newItem]);
477
- }
478
- }
479
- /**
480
- * Update title
481
- * @param id Item id
482
- * @param title New title
483
- */
484
- updateTitle(id, title) {
485
- const index = this.items.findIndex((item) => item.id === id);
486
- if (index !== -1) {
487
- const item = this.items[index];
488
- const newItem = { ...item, title };
489
- if (newItem.name === newItem.title)
490
- newItem.title = undefined;
491
- this.items.splice(index, 1, newItem);
492
- this.doChange("title", [item, newItem]);
493
- }
494
- }
495
- }