@stephenchenorg/astro 4.0.3 → 5.0.1
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.
- package/dist/product-variant/ProductVariantSelector.d.ts +42 -0
- package/dist/product-variant/ProductVariantSelector.js +52 -0
- package/dist/product-variant/index.d.ts +2 -0
- package/dist/product-variant/index.js +2 -0
- package/dist/{product-sku → product-variant}/types.d.ts +12 -12
- package/package.json +4 -4
- package/dist/product-sku/index.d.ts +0 -2
- package/dist/product-sku/index.js +0 -2
- package/dist/product-sku/productSku.d.ts +0 -39
- package/dist/product-sku/productSku.js +0 -52
- /package/dist/{product-sku → product-variant}/types.js +0 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { ProductVariant, ProductVariantAttribute } from './types';
|
|
2
|
+
export declare class ProductVariantSelector {
|
|
3
|
+
/**
|
|
4
|
+
* 可用的商品變體列表(所有 SKU)
|
|
5
|
+
*/
|
|
6
|
+
availableVariants: ProductVariant[];
|
|
7
|
+
/**
|
|
8
|
+
* 商品屬性選項列表(如顏色、尺寸等)
|
|
9
|
+
*/
|
|
10
|
+
variantAttributes: ProductVariantAttribute[];
|
|
11
|
+
/**
|
|
12
|
+
* 使用者已選擇的屬性值
|
|
13
|
+
*/
|
|
14
|
+
selectedAttributes: Record<number, {
|
|
15
|
+
optionId: number;
|
|
16
|
+
label: string;
|
|
17
|
+
}>;
|
|
18
|
+
/**
|
|
19
|
+
* 匹配到的商品規格物件
|
|
20
|
+
*/
|
|
21
|
+
currentVariant: ProductVariant | undefined;
|
|
22
|
+
constructor({ availableVariants, variantAttributes }: {
|
|
23
|
+
availableVariants: ProductVariant[];
|
|
24
|
+
variantAttributes: ProductVariantAttribute[];
|
|
25
|
+
});
|
|
26
|
+
/**
|
|
27
|
+
* 選擇商品規格
|
|
28
|
+
*/
|
|
29
|
+
selectVariant(attributeId: number, optionId: number, label: string): void;
|
|
30
|
+
/**
|
|
31
|
+
* 獲取已選擇的商品規格選項標籤
|
|
32
|
+
*/
|
|
33
|
+
getSelectedAttributesLabel(): string;
|
|
34
|
+
/**
|
|
35
|
+
* 確認是否已選擇所有商品規格選項
|
|
36
|
+
*/
|
|
37
|
+
areAllAttributesSelected(): boolean;
|
|
38
|
+
/**
|
|
39
|
+
* 確認是否有足夠的庫存
|
|
40
|
+
*/
|
|
41
|
+
hasEnoughStock(stock: number): boolean;
|
|
42
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
export class ProductVariantSelector {
|
|
2
|
+
/**
|
|
3
|
+
* 可用的商品變體列表(所有 SKU)
|
|
4
|
+
*/
|
|
5
|
+
availableVariants = [];
|
|
6
|
+
/**
|
|
7
|
+
* 商品屬性選項列表(如顏色、尺寸等)
|
|
8
|
+
*/
|
|
9
|
+
variantAttributes = [];
|
|
10
|
+
/**
|
|
11
|
+
* 使用者已選擇的屬性值
|
|
12
|
+
*/
|
|
13
|
+
selectedAttributes = {};
|
|
14
|
+
/**
|
|
15
|
+
* 匹配到的商品規格物件
|
|
16
|
+
*/
|
|
17
|
+
currentVariant = void 0;
|
|
18
|
+
constructor({ availableVariants, variantAttributes }) {
|
|
19
|
+
this.availableVariants = availableVariants;
|
|
20
|
+
this.variantAttributes = variantAttributes;
|
|
21
|
+
if (availableVariants.length === 1 && availableVariants[0].combination_key === null) {
|
|
22
|
+
this.currentVariant = availableVariants[0];
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* 選擇商品規格
|
|
27
|
+
*/
|
|
28
|
+
selectVariant(attributeId, optionId, label) {
|
|
29
|
+
this.selectedAttributes[attributeId] = { optionId, label };
|
|
30
|
+
const variantCombinationKey = Object.values(this.selectedAttributes).map((attr) => attr.optionId).sort((a, b) => a - b).join("-");
|
|
31
|
+
this.currentVariant = this.availableVariants.find((variant) => variant.combination_key === variantCombinationKey);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* 獲取已選擇的商品規格選項標籤
|
|
35
|
+
*/
|
|
36
|
+
getSelectedAttributesLabel() {
|
|
37
|
+
return Object.values(this.selectedAttributes).map((attr) => attr.label).join(", ");
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* 確認是否已選擇所有商品規格選項
|
|
41
|
+
*/
|
|
42
|
+
areAllAttributesSelected() {
|
|
43
|
+
return Object.keys(this.selectedAttributes).length === this.variantAttributes.length;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* 確認是否有足夠的庫存
|
|
47
|
+
*/
|
|
48
|
+
hasEnoughStock(stock) {
|
|
49
|
+
const specificationStock = this.currentVariant?.inventory || 0;
|
|
50
|
+
return specificationStock > 0 && specificationStock >= stock;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
export interface
|
|
2
|
-
id: number;
|
|
3
|
-
title: string;
|
|
4
|
-
items: ProductAttributeItem[];
|
|
5
|
-
}
|
|
6
|
-
export interface ProductAttributeItem {
|
|
7
|
-
id: number;
|
|
8
|
-
title: string;
|
|
9
|
-
}
|
|
10
|
-
export interface ProductSpecification {
|
|
1
|
+
export interface ProductVariant {
|
|
11
2
|
id: number;
|
|
12
3
|
/** 商品規格 Key */
|
|
13
4
|
combination_key: string | null;
|
|
14
5
|
/** 原價 */
|
|
15
|
-
listing_price:
|
|
6
|
+
listing_price: number;
|
|
16
7
|
/** 實際售價 */
|
|
17
|
-
selling_price:
|
|
8
|
+
selling_price: number;
|
|
18
9
|
/** 商品庫存數量 */
|
|
19
10
|
inventory: number;
|
|
20
11
|
}
|
|
12
|
+
export interface ProductVariantAttribute {
|
|
13
|
+
id: number;
|
|
14
|
+
title: string;
|
|
15
|
+
options: ProductVariantAttributeOption[];
|
|
16
|
+
}
|
|
17
|
+
export interface ProductVariantAttributeOption {
|
|
18
|
+
id: number;
|
|
19
|
+
title: string;
|
|
20
|
+
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stephenchenorg/astro",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "5.0.1",
|
|
5
5
|
"description": "Stephenchenorg Astro 前端通用套件",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"homepage": "https://stephenchenorg-astro.netlify.app",
|
|
@@ -41,9 +41,9 @@
|
|
|
41
41
|
"types": "./dist/pagination-vue/index.d.ts",
|
|
42
42
|
"import": "./dist/pagination-vue/index.js"
|
|
43
43
|
},
|
|
44
|
-
"./product-
|
|
45
|
-
"types": "./dist/product-
|
|
46
|
-
"import": "./dist/product-
|
|
44
|
+
"./product-variant": {
|
|
45
|
+
"types": "./dist/product-variant/index.d.ts",
|
|
46
|
+
"import": "./dist/product-variant/index.js"
|
|
47
47
|
},
|
|
48
48
|
"./query-params": {
|
|
49
49
|
"types": "./dist/query-params/index.d.ts",
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import type { ProductAttribute, ProductSpecification } from './types';
|
|
2
|
-
export declare class ProductSkuManager {
|
|
3
|
-
/**
|
|
4
|
-
* 商品規格選項列表
|
|
5
|
-
*/
|
|
6
|
-
attributes: ProductAttribute[];
|
|
7
|
-
/**
|
|
8
|
-
* 商品規格列表
|
|
9
|
-
*/
|
|
10
|
-
specifications: ProductSpecification[];
|
|
11
|
-
/**
|
|
12
|
-
* 已經選中商品規格選項的參數 ID
|
|
13
|
-
*/
|
|
14
|
-
selectedSkuAttrs: Record<number, {
|
|
15
|
-
itemId: number;
|
|
16
|
-
label: string;
|
|
17
|
-
}>;
|
|
18
|
-
/**
|
|
19
|
-
* 匹配到的商品規格 SKU 物件
|
|
20
|
-
*/
|
|
21
|
-
specification: ProductSpecification | undefined;
|
|
22
|
-
constructor({ attributes, specifications }: {
|
|
23
|
-
attributes: ProductAttribute[];
|
|
24
|
-
specifications: ProductSpecification[];
|
|
25
|
-
});
|
|
26
|
-
/**
|
|
27
|
-
* 選擇商品規格選項
|
|
28
|
-
*/
|
|
29
|
-
selectSkuAttr(skuAttrId: number, skuItemId: number, label: string): void;
|
|
30
|
-
getSpecificationLabel(): string;
|
|
31
|
-
/**
|
|
32
|
-
* 確認商品規格選項都已經選擇
|
|
33
|
-
*/
|
|
34
|
-
areAllSkuAttrsSelected(): boolean;
|
|
35
|
-
/**
|
|
36
|
-
* 確認商品規格還有庫存
|
|
37
|
-
*/
|
|
38
|
-
isSpecificationInStock(stock: number): boolean;
|
|
39
|
-
}
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
export class ProductSkuManager {
|
|
2
|
-
/**
|
|
3
|
-
* 商品規格選項列表
|
|
4
|
-
*/
|
|
5
|
-
attributes = [];
|
|
6
|
-
/**
|
|
7
|
-
* 商品規格列表
|
|
8
|
-
*/
|
|
9
|
-
specifications = [];
|
|
10
|
-
/**
|
|
11
|
-
* 已經選中商品規格選項的參數 ID
|
|
12
|
-
*/
|
|
13
|
-
selectedSkuAttrs = {};
|
|
14
|
-
/**
|
|
15
|
-
* 匹配到的商品規格 SKU 物件
|
|
16
|
-
*/
|
|
17
|
-
specification = void 0;
|
|
18
|
-
constructor({ attributes, specifications }) {
|
|
19
|
-
this.attributes = attributes;
|
|
20
|
-
this.specifications = specifications;
|
|
21
|
-
if (specifications.length === 1 && specifications[0].combination_key === null) {
|
|
22
|
-
this.specification = specifications[0];
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* 選擇商品規格選項
|
|
27
|
-
*/
|
|
28
|
-
selectSkuAttr(skuAttrId, skuItemId, label) {
|
|
29
|
-
this.selectedSkuAttrs[skuAttrId] = {
|
|
30
|
-
itemId: skuItemId,
|
|
31
|
-
label
|
|
32
|
-
};
|
|
33
|
-
const skuAttrIds = Object.values(this.selectedSkuAttrs).map((attr) => attr.itemId).sort((a, b) => a - b);
|
|
34
|
-
this.specification = this.specifications.find((specification) => specification.combination_key === skuAttrIds.join("-"));
|
|
35
|
-
}
|
|
36
|
-
getSpecificationLabel() {
|
|
37
|
-
return Object.values(this.selectedSkuAttrs).map((attr) => attr.label).join(", ");
|
|
38
|
-
}
|
|
39
|
-
/**
|
|
40
|
-
* 確認商品規格選項都已經選擇
|
|
41
|
-
*/
|
|
42
|
-
areAllSkuAttrsSelected() {
|
|
43
|
-
return Object.keys(this.selectedSkuAttrs).length === this.attributes.length;
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* 確認商品規格還有庫存
|
|
47
|
-
*/
|
|
48
|
-
isSpecificationInStock(stock) {
|
|
49
|
-
const specificationStock = this.specification?.inventory || 0;
|
|
50
|
-
return specificationStock > 0 && specificationStock >= stock;
|
|
51
|
-
}
|
|
52
|
-
}
|
|
File without changes
|