update permission and product
This commit is contained in:
+17
-1
@@ -2,10 +2,26 @@ import type { EventBizType, EventItem } from "@/types/EventItem";
|
||||
|
||||
/** 返回事件业务类型的前端文案。 */
|
||||
export function getEventBizTypeText(bizType?: EventBizType): string {
|
||||
return bizType === "PACKAGE_PURCHASE" ? "套餐购买" : "普通登记";
|
||||
if (bizType === "PACKAGE_PURCHASE") {
|
||||
return "套餐购买";
|
||||
}
|
||||
if (bizType === "LEGACY_CONSUMPTION") {
|
||||
return "历史消费(退役)";
|
||||
}
|
||||
return "普通登记";
|
||||
}
|
||||
|
||||
/** 判断事件是否为套餐购买事件。 */
|
||||
export function isPackagePurchaseEvent(event?: Pick<EventItem, "bizType">): boolean {
|
||||
return event?.bizType === "PACKAGE_PURCHASE";
|
||||
}
|
||||
|
||||
/** 判断事件是否为历史消费退役事件,此类事件不可再登记或作为规则触发对象。 */
|
||||
export function isLegacyConsumptionEvent(event?: Pick<EventItem, "bizType">): boolean {
|
||||
return event?.bizType === "LEGACY_CONSUMPTION";
|
||||
}
|
||||
|
||||
/** 判断事件是否已退役,退役事件只能通过历史详情查看。 */
|
||||
export function isRetiredEvent(event?: Pick<EventItem, "bizType">): boolean {
|
||||
return isPackagePurchaseEvent(event) || isLegacyConsumptionEvent(event);
|
||||
}
|
||||
|
||||
@@ -1,107 +0,0 @@
|
||||
import PointAPI from "@/api/PointAPI";
|
||||
import type { PointAction, PointRule } from "@/types/Point";
|
||||
|
||||
export type SourceValueConfig = {
|
||||
range: [number, number];
|
||||
action: PointAction;
|
||||
};
|
||||
|
||||
/**
|
||||
* 查询一组事件可用的自定义积分范围,并返回所有规则范围的交集。
|
||||
*
|
||||
* @param eventIdList 事件 ID 列表
|
||||
* @returns 可用范围;没有完整有效的 SOURCE_VALUE 规则时返回 undefined
|
||||
*/
|
||||
export async function loadSourceValueRange(eventIdList: string[]): Promise<[number, number] | undefined> {
|
||||
return (await loadSourceValueConfig(eventIdList))?.range;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询登记时自定义积分的数量范围和积分动作。
|
||||
*
|
||||
* @param eventIdList 事件 ID 列表
|
||||
* @returns 所有事件规则的共同配置
|
||||
*/
|
||||
export async function loadSourceValueConfig(eventIdList: string[]): Promise<SourceValueConfig | undefined> {
|
||||
if (!eventIdList.length) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const resultList = await Promise.all(eventIdList.map(eventId => PointAPI.ruleList({
|
||||
index: 0,
|
||||
size: 1000,
|
||||
equalsExample: {
|
||||
eventId,
|
||||
status: "ACTIVE"
|
||||
}
|
||||
})));
|
||||
const ruleList = resultList.flatMap(result => result.list || []);
|
||||
if (!ruleList.length) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const rangeList = ruleList
|
||||
.map(resolvePointValueRuleConfig)
|
||||
.filter((range): range is SourceValueConfig => !!range);
|
||||
const action = rangeList[0]?.action;
|
||||
if (!action) {
|
||||
return undefined;
|
||||
}
|
||||
if (rangeList.some(range => range.action !== action)) {
|
||||
return undefined;
|
||||
}
|
||||
const min = Math.max(...rangeList.map(range => range.range[0]), 1);
|
||||
const max = Math.min(...rangeList.map(range => range.range[1]));
|
||||
return min <= max ? { range: [min, max], action } : undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析积分规则动作。
|
||||
*
|
||||
* 固定积分优先按 pointValue 正负判定;登记时自定义积分按 conditionJson.min 正负判定。
|
||||
*
|
||||
* @param rule 积分规则
|
||||
* @returns 积分动作;缺少有效积分值时返回 undefined
|
||||
*/
|
||||
export function resolvePointRuleAction(rule: PointRule): PointAction | undefined {
|
||||
if (rule.pointValue !== undefined && rule.pointValue !== null && rule.pointValue !== 0) {
|
||||
return rule.pointValue < 0 ? "CONSUME" : "EARN";
|
||||
}
|
||||
const min = rule.conditionJson?.min;
|
||||
if (min === undefined || min === 0) {
|
||||
return undefined;
|
||||
}
|
||||
return min < 0 ? "CONSUME" : "EARN";
|
||||
}
|
||||
|
||||
function resolvePointValueRuleConfig(rule: PointRule): SourceValueConfig | undefined {
|
||||
if (rule.status !== "ACTIVE" || rule.triggerType !== "SOURCE_VALUE" || rule.pointMode !== "SOURCE_VALUE") {
|
||||
return undefined;
|
||||
}
|
||||
return resolveSourceValueRuleConfig(rule);
|
||||
}
|
||||
|
||||
function resolveSourceValueRuleConfig(rule: PointRule): SourceValueConfig | undefined {
|
||||
const min = rule.conditionJson?.min;
|
||||
const max = rule.conditionJson?.max;
|
||||
const action = resolvePointRuleAction(rule);
|
||||
if (
|
||||
min === undefined
|
||||
|| max === undefined
|
||||
|| action === undefined
|
||||
|| !Number.isSafeInteger(min)
|
||||
|| !Number.isSafeInteger(max)
|
||||
|| min === 0
|
||||
|| max === 0
|
||||
|| (action === "CONSUME") !== (min < 0)
|
||||
|| (action === "CONSUME") !== (max < 0)
|
||||
) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const boundaryList = [Math.abs(min), Math.abs(max)];
|
||||
return {
|
||||
action,
|
||||
range: [Math.min(...boundaryList), Math.max(...boundaryList)]
|
||||
};
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
import type { EventValueUnit } from "@/types/EventItem";
|
||||
import type { PointRuleTierForm } from "@/types/Point";
|
||||
import { formatCentValue, resolveCentValue } from "@/utils/eventValue";
|
||||
|
||||
export function resolveNonNegativeInteger(value: string): number | undefined {
|
||||
if (!value.trim()) {
|
||||
return undefined;
|
||||
}
|
||||
const numberValue = Number(value);
|
||||
return Number.isSafeInteger(numberValue) && !(numberValue < 0) ? numberValue : undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* 按来源事件的存储单位解析分档边界。
|
||||
* CENT 的表单值使用元,解析结果使用分;COUNT 直接使用整数次数。
|
||||
*/
|
||||
export function resolveTierBoundaryValue(value: string, valueUnit?: EventValueUnit | null): number | undefined {
|
||||
return valueUnit === "CENT" ? resolveCentValue(value.trim()) : resolveNonNegativeInteger(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 按来源事件的展示单位格式化分档边界。
|
||||
*/
|
||||
export function formatTierBoundaryValue(value: number, valueUnit?: EventValueUnit | null): string {
|
||||
return valueUnit === "CENT" ? formatCentValue(value) : String(value);
|
||||
}
|
||||
|
||||
export function getTierMinValue(tierList: PointRuleTierForm[], index: number, valueUnit?: EventValueUnit | null): number | undefined {
|
||||
if (index < 1) {
|
||||
return resolveTierBoundaryValue(tierList[0]?.minText || "", valueUnit);
|
||||
}
|
||||
const previousMax = resolveTierBoundaryValue(tierList[index - 1]?.maxText || "", valueUnit);
|
||||
if (previousMax === undefined || !Number.isSafeInteger(previousMax + 1)) {
|
||||
return undefined;
|
||||
}
|
||||
return previousMax + 1;
|
||||
}
|
||||
|
||||
export function getTierMinText(tierList: PointRuleTierForm[], index: number, valueUnit?: EventValueUnit | null): string {
|
||||
const min = getTierMinValue(tierList, index, valueUnit);
|
||||
return min === undefined ? "待填写" : formatTierBoundaryValue(min, valueUnit);
|
||||
}
|
||||
|
||||
export function isLastTier(tierList: PointRuleTierForm[], index: number): boolean {
|
||||
return index === tierList.length - 1;
|
||||
}
|
||||
Reference in New Issue
Block a user