update permission and product

This commit is contained in:
Timi
2026-09-04 23:07:59 +08:00
parent 1df5748f54
commit fc9e6a5023
48 changed files with 1670 additions and 2475 deletions
+17 -1
View File
@@ -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);
}
-107
View File
@@ -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)]
};
}
-46
View File
@@ -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;
}