1. 推广员功能增强
Some checks failed
CI / Test (ubuntu-latest) (push) Has been cancelled
CI / Test (windows-latest) (push) Has been cancelled
CI / Lint (ubuntu-latest) (push) Has been cancelled
CI / Lint (windows-latest) (push) Has been cancelled
CI / Check (ubuntu-latest) (push) Has been cancelled
CI / Check (windows-latest) (push) Has been cancelled
CI / CI OK (push) Has been cancelled
CodeQL / Analyze (javascript-typescript) (push) Has been cancelled
Deploy Website on push / Deploy Push Playground Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Docs Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Antd Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Element Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Naive Ftp (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled

This commit is contained in:
李琦
2026-06-18 13:24:58 +08:00
parent 9a1435996e
commit f36ef45ee2
37 changed files with 2742 additions and 481 deletions

View File

@@ -0,0 +1,108 @@
export type QuickDiscountOption = { name: string; value: number };
export const DEFAULT_QUICK_OPTIONS: QuickDiscountOption[] = [
{ name: '九五折', value: 95 },
{ name: '九折', value: 90 },
{ name: '八五折', value: 85 },
{ name: '八折', value: 80 },
{ name: '涨10%', value: 110 },
{ name: '涨20%', value: 120 },
];
const DEFAULT_MARKUP_OPTIONS: QuickDiscountOption[] = [
{ name: '涨10%', value: 110 },
{ name: '涨20%', value: 120 },
];
export function normalizeQuickOptions(raw: unknown): QuickDiscountOption[] {
if (!Array.isArray(raw)) return [...DEFAULT_QUICK_OPTIONS];
const list: QuickDiscountOption[] = [];
for (const item of raw) {
if (item && typeof item === 'object' && 'value' in item) {
const val = Number((item as QuickDiscountOption).value);
if (val > 0) {
list.push({
name: String((item as QuickDiscountOption).name || `${val}%`),
value: val,
});
}
} else if (typeof item === 'number' && item > 0) {
list.push({ name: `${item}%`, value: item });
}
}
if (!list.length) return [...DEFAULT_QUICK_OPTIONS];
if (!list.some((o) => o.value > 100)) {
return [...list, ...DEFAULT_MARKUP_OPTIONS];
}
return list;
}
export function applyRatioPrice(originPrice: number, discount: number): number {
if (!originPrice || originPrice <= 0) return 0;
const ratio = discount > 0 ? discount : 100;
return Math.round(originPrice * (ratio / 100) * 10000) / 10000;
}
export function inferDiscountKind(discount: number): 'none' | 'discount' | 'markup' {
const d = Number(discount) || 100;
if (d === 100) return 'none';
return d < 100 ? 'discount' : 'markup';
}
export function formatPriceDiscountLabel(discount: number): string | null {
const d = Number(discount) || 100;
if (d <= 0 || d === 100) return null;
if (d < 100) {
if (d % 10 === 0 && d >= 10) return `${d / 10}`;
return `折扣 ${d}%`;
}
return `${d - 100}%`;
}
export function resolvePriceDiscount(data?: {
priceDiscount?: number | string;
price_discount?: number | string;
}): number {
const raw = data?.priceDiscount ?? data?.price_discount;
const n = Number(raw);
return n > 0 ? n : 100;
}
export function applyRatioToDrug<T extends { price?: number | string; buy_price?: number | string; origin_price?: number | string; origin_buy_price?: number | string }>(
drug: T,
discount: number,
scope: 'both' | 'sale_only',
): T {
const originPrice = Number(drug.origin_price ?? drug.price ?? 0);
const originBuy = Number(drug.origin_buy_price ?? drug.buy_price ?? 0);
const next: T = {
...drug,
origin_price: drug.origin_price ?? originPrice,
origin_buy_price: drug.origin_buy_price ?? originBuy,
price: applyRatioPrice(originPrice, discount),
};
if (scope === 'both' && originBuy > 0) {
next.buy_price = applyRatioPrice(originBuy, discount);
}
return next;
}
export function applyRatioToDrugs<T extends { price?: number | string; buy_price?: number | string; origin_price?: number | string; origin_buy_price?: number | string }>(
drugs: T[],
discount: number,
scope: 'both' | 'sale_only',
): T[] {
return drugs.map((d) => applyRatioToDrug(d, discount, scope));
}
/** @deprecated */
export type AdjustType = 'markup' | 'discount';
/** @deprecated use applyRatioPrice */
export function applyPercentPrice(oldPrice: number, adjustType: AdjustType, percent: number): number {
if (!oldPrice || oldPrice <= 0) return 0;
if (adjustType === 'markup') {
return applyRatioPrice(oldPrice, Math.round(100 + percent));
}
return applyRatioPrice(oldPrice, percent);
}