API 參考
主要 API
取得優惠結果排名(getPromotionsRanking)
ts
export interface GetPromotionRankingParam<Data> {
/** 商品與其數量。通常是購物車內商品 */
items: Item<Data>[];
/** 可用優惠 */
promotions: Promotion<Data>[];
/** 取得前幾名。預設 3。數量不足時,則以實際數量為主 */
topN?: number;
/** 贈品自動抵銷模式 */
autoOffsetMode?: AutoOffsetMode;
/** 重現性,即相同的輸入保證得到相同的輸出。
*
* @default true
*/
reproducibility?: boolean;
}ts
export function getPromotionsRanking<Data = undefined>(
param: GetPromotionRankingParam<Data>
): PromotionResult<Data>[]取得優惠結果之統計資料(getAnalyticalData)
總金額、訂單優惠金額等等
ts
/** 取得優惠結果的統計資料 */
export function getAnalyticalData(
promotionResult: PromotionResult
): AnalyticalData取得每個商品使用的優惠與其優惠價格(getItemizedResult)
ts
/** 取得每個商品使用的優惠與其優惠價格 */
export function getItemizedResult(
promotionResult: PromotionResult
): ItemizedResult取得推薦優惠(getRecommendResults)
根據目前商品推薦優惠並提示達成條件
ts
/** 取得推薦結果 */
export function getRecommendResults(
param: GetRecommendResultsParam
): RecommendResult[]檢查優惠結果有效性(checkPromotionResult)
回傳錯誤訊息,空字串表示沒有問題
ts
export function checkPromotionResult(
promotionResult: PromotionResult
): string檢查優惠結果重現性(checkParamsAndRankedResult)
檢查優惠結果是否與指定參數結果一致,可以讓 server 用來檢查結果是否被竄改。
ts
interface CheckParamsAndRankedResultParam<Data> {
/** 商品與其數量。通常是購物車內商品 */
items: Item<Data>[];
/** 可用優惠 */
promotions: Promotion<Data>[];
/** 取得前幾名。預設 3。數量不足時,則以實際數量為主 */
topN?: number;
/** 贈品自動抵銷模式 */
autoOffsetMode?: AutoOffsetMode;
results: RankedPromotionResult<Data>[];
}
export function checkParamsAndRankedResult(
param: CheckParamsAndRankedResultParam
): booleanutils API
處理計算邏輯(operation)
ts
/** 處理 Arithmetic 邏輯
*
* 根據 arithmetic 定義計算 value 結果。
*/
export function operation(
arithmetic: Arithmetic, value: number | Decimal
): number型別定義
優惠基本結構(PromotionBase)
ts
/** 優惠規則 */
interface PromotionBase<Type extends `${PromotionType}`, Content> {
/** 唯一值 */
key: string;
type: Type;
name: string;
description: string;
/** 優惠內容。條件與實際結果在此定義。
*
* 任一個 content 符合條件,即可套用此優惠。
*/
contents: Content[];
/** 優惠群組名稱。分類優惠,可用於限制不可與某 group 一起使用 */
group?: string;
/** 限制。例如一筆訂單只能使用一次,或是排除某優惠(不會同時存在) */
constraints?: Constraint[];
/** 不計入滿額優惠之條件計算 */
notIncludedInSpendTotalPrice?: boolean;
}優惠決策(PromotionDecision)
ts
/** 優惠決策。
*
* 定義候選商品、條件、結果。
*/
export interface PromotionDecision<Data = undefined> {
/** 候選商品 */
list: Commodity<Data>[];
/** 優惠結果 */
result?: SelectableGiveaway<Data> | Arithmetic;
/** 條件 */
comparison: Comparison;
}優惠結果(PromotionResult)
ts
/** 優惠結果 */
export interface PromotionResult<Data = undefined> {
/** 原始購物清單 */
originalItems: Item<Data>[];
/** 剩餘的商品。沒有商品優惠可用,剩下來的商品 */
remainingItems: Item<Data>[];
/** 套用優惠的商品 */
promotedList: PromotedListItem<Data>[];
/** 可用贈品。 */
giveawayList: GiveawayListItem<Data>[];
/** 被贈品抵銷的商品。此區商品要被視為 0 元 */
offsetList: OffsetListItem<Data>[];
/** 所有已使用的優惠,彙整自 promotedList.promotion */
usedPromotions: Promotion[];
}
/** 已套用優惠結果的商品 */
export interface PromotedListItem<Data = undefined> {
/** 符合條件之商品與優惠結果 */
appliedList: Array<{
item: Item<Data>;
/** 優惠結果 */
result?: SelectableGiveaway<Data> | Arithmetic;
}>;
/** 原始優惠 */
promotion: Promotion;
/** 套用的優惠內容 */
promotedContent: Promotion['contents'][number];
/** 匹配的 Decision */
matchedDecision?: PromotionDecision<Data>;
}
/** 可用贈品。
*
* 集結 promotedList.appliedList.result 中的 SelectableGiveaway 資料。
*
* 不包含以自動抵銷的贈品,自動抵銷的贈品在 offsetList 中。
*/
export interface GiveawayListItem<Data = undefined> {
/** 贈品 */
item: SelectableGiveaway<Data>;
/** 原始優惠 */
promotion: Promotion;
/** 套用的優惠內容 */
promotedContent: Promotion['contents'][number];
/** 匹配的 Decision */
matchedDecision?: PromotionDecision<Data>;
}
/** 被贈品抵銷的商品 */
export interface OffsetListItem<Data = undefined> {
/** 商品 */
item: Item<Data>;
/** 原始優惠 */
promotion: Promotion;
/** 套用的優惠內容 */
promotedContent: Promotion['contents'][number];
/** 匹配的 Decision */
matchedDecision?: PromotionDecision<Data>;
}
/** 已排名後的優惠結果 */
export interface RankedPromotionResult<Data> extends PromotionResult<Data> {
/** 統計資料 */
analyticalData: AnalyticalData;
}優惠限制(Constraint)
ts
/** 限制種類 */
export enum ConstraintType {
/** 一筆訂單中指定優惠套用次數,value 為可套用次數 */
USE_TIMES_FOR_ONE_ORDER = 'use-times-for-one-order',
// TODO: 實作全部的 ConstraintType
// /** 不可以一起使用的 promotion,value 為 Promotion ID */
// EXCLUDE_PROMOTION = 'exclude-promotion',
// /** 不可以一起使用的 promotion group,value 為 PromotionBase.group */
// EXCLUDE_PROMOTION_GROUP = 'exclude-promotion-group',
}
/** 限制。value 依照 type 有不同意義 */
export interface Constraint {
type: `${ConstraintType}`;
value: number | string;
}優惠種類細節
商品優惠
ts/** 商品優惠 * * 條件與商品直接相關,過程會取出被套用的商品,不能重複套用商品。 * * - A + B 只要 50 元 * - A + B,A 打折、B 打折 * - 買 A 區送 B 區 * - 任選 10 個 A 系列,打折 * - 任 3 件 84 折 * - 2 件 5000 元 * - 3 件折 500 元 * - 同品項買 2 送 1 */ export type PromotionCommodityOffer<Data = undefined> = PromotionBase<'commodity-offer', { /** 候選商品群組。 * * condition.comparison.target 只能是 `purchase-quantity`,因為滿額邏輯只能定義於滿額優惠中。 * * 必須所有 condition 皆相符,才能套用目前 content。 */ condition: PromotionDecision<Data>[]; /** 整體結果。 * * 優惠結果可以在 condition 分別定義,也可用此值全部帶入。 */ result?: SelectableGiveaway | Arithmetic; }>訂單優惠
ts/** 訂單優惠 * * 條件與商品無直接關連,只與整筆訂單相關。 * * - 整筆訂單 8 折。 */ export type PromotionOrderOffer<Data = undefined> = PromotionBase<'order-offer', { result: SelectableGiveaway<Data> | Arithmetic; }>滿額優惠
ts/** 滿額優惠 * * 依照前兩種優惠的結果,計算其優惠條件。 * * - 單筆消費滿 3 萬元,送 A 商品 * - 任意消費送 A 商品 */ export type PromotionMinimumSpendOffer<Data = undefined> = PromotionBase<'minimum-spend-offer', { condition: Comparison; /** 結果 */ result: SelectableGiveaway<Data> | Arithmetic; }>
計算(Arithmetic )
ts
export enum ArithmeticOperator {
/** 加 */
PLUS = 'plus',
/** 減 */
SUB = 'sub',
/** 乘 */
MUL = 'mul',
/** 設為 */
SET = 'set',
}
/** 計算目標 */
export enum ArithmeticTarget {
/** 每一個商品,而不是全部商品
*
* 通常用於以下優惠:
* - 任選 10 個以上,每個 100 元
* - 任選 A 系列 2 個,每件減 10 元
*/
EVERY = 'every',
}
/** 計算 */
export interface Arithmetic {
operator: `${ArithmeticOperator}`;
/** 為空表示針對全部商品
*
* 只對商品優惠(commodity-offer)有效
*/
target?: `${ArithmeticTarget}`;
value: number;
}比較(Comparison)
ts
export enum ComparisonLogic {
/** 大於 */
GREATER_THAN = 'greater-than',
/** 大於等於 */
GREATER_THAN_EQUAL_TO = 'greater-than-equal-to',
/** 小於 */
LESS_THAN = 'less-than',
/** 小於等於 */
LESS_THAN_EQUAL_TO = 'less-than-equal-to',
/** 等於 */
EQUAL = 'equal',
/** 每次。用於滿額優惠,表示每多少。例:每千送百
*
* 其邏輯等同 greater-than-equal-to
*/
EVERY = 'every',
}
/** 目標對象。此比較條件判斷依據 */
export enum ComparisonTarget {
/** 總金額 */
TOTAL_PRICE = 'total-price',
/** 購買數量 */
PURCHASE_QUANTITY = 'purchase-quantity',
}
/** 比較 */
export interface Comparison {
target: `${ComparisonTarget}`;
logic: `${ComparisonLogic}`;
value: number;
}