Files
dukang/packages/domain/src/city-partner.ts
T

99 lines
3.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
export type CityPartnerScopeType = 'CITY_WIDE' | 'DISTRICT';
export type CityPartnerStatus = 'ACTIVE' | 'PAUSED';
export interface PartnerCityBindingInput {
id?: string;
partnerAccountId: string;
scopeType: CityPartnerScopeType;
districtCodes?: string[] | null;
bindingStatus?: CityPartnerStatus;
/** 仅用于重合报错文案 */
companyName?: string | null;
}
export interface PartnerCityValidationResult {
ok: boolean;
message?: string;
}
export function validatePartnerCityBinding(
existing: PartnerCityBindingInput[],
input: PartnerCityBindingInput,
excludeId?: string,
): PartnerCityValidationResult {
const others = existing.filter((b) => b.id !== excludeId);
if (others.some((b) => b.partnerAccountId === input.partnerAccountId)) {
return { ok: false, message: '该合伙人已绑定此城市' };
}
if (input.scopeType === 'CITY_WIDE') {
if (others.some((b) => b.scopeType === 'CITY_WIDE')) {
return { ok: false, message: '每城最多 1 名全城合伙人' };
}
return { ok: true };
}
// 区域合伙人所选区县可为空(录入时可稍后补全)
return { ok: true };
}
/** @deprecated use validatePartnerCityBinding */
export const validateCityPartnerBinding = validatePartnerCityBinding;
export const DEFAULT_MAX_PARTNER_COMMISSION_RATE = 0.05;
export function resolveMaxPartnerCommissionRate(maxRate?: number | null): number {
if (maxRate == null || Number.isNaN(Number(maxRate))) {
return DEFAULT_MAX_PARTNER_COMMISSION_RATE;
}
return Number(maxRate);
}
/** 订单佣金 + 核销佣金不得超过城市配置上限(默认 5%) */
export function validatePartnerCommissionRates(
orderCommissionRate: number,
redeemCommissionRate: number,
maxSumRate = DEFAULT_MAX_PARTNER_COMMISSION_RATE,
): PartnerCityValidationResult {
const sum = orderCommissionRate + redeemCommissionRate;
const max = resolveMaxPartnerCommissionRate(maxSumRate);
if (sum > max + 1e-9) {
return {
ok: false,
message: `订单佣金与核销佣金合计不得超过 ${(max * 100).toFixed(2)}%(当前 ${(sum * 100).toFixed(2)}%`,
};
}
return { ok: true };
}
export function assertCanDeleteCityPartner(input: {
storeCount: number;
orderCount: number;
redeemCount: number;
}): PartnerCityValidationResult {
if (input.storeCount > 0) {
return { ok: false, message: '该城市合伙人下还有门店,请先删除门店' };
}
if (input.orderCount > 0) {
return { ok: false, message: '该账号下有关联订单,禁止删除' };
}
if (input.redeemCount > 0) {
return { ok: false, message: '该账号下有关联核销单,禁止删除' };
}
return { ok: true };
}
export function assertCanDeleteStore(input: {
orderCount: number;
redeemCount: number;
}): PartnerCityValidationResult {
if (input.orderCount > 0) {
return { ok: false, message: '该账号下有关联订单,禁止删除' };
}
if (input.redeemCount > 0) {
return { ok: false, message: '该账号下有关联核销单,禁止删除' };
}
return { ok: true };
}