Files
gao-customer-h5/src/utils/eventOption.ts
T
2026-08-30 23:36:59 +08:00

148 lines
4.8 KiB
TypeScript

import type { EventItem, EventOption, EventOptionGroup, EventOptionSelectionMap } from "@/types/EventItem";
import type { EventRecordOptionGroup } from "@/types/EventRecord";
export function createEventOptionId(): string {
const uuid = globalThis.crypto?.randomUUID?.();
return uuid || `${Date.now()}-${Math.random().toString(36).slice(2)}`;
}
export function normalizeEventOptionGroupList(groupList?: EventOptionGroup[]): EventOptionGroup[] {
return (groupList || []).map(group => ({
...group,
name: group.name || "",
selectionMode: group.selectionMode || "SINGLE",
required: group.required ?? true,
optionList: (group.optionList || []).map(option => ({
...option,
label: option.label || ""
}))
}));
}
export function prepareEventOptionGroupList(groupList?: EventOptionGroup[]): EventOptionGroup[] {
return normalizeEventOptionGroupList(groupList).map(group => ({
id: group.id,
eventId: group.eventId,
name: group.name,
selectionMode: group.selectionMode,
required: group.required,
sort: group.sort,
optionList: group.optionList.map(option => ({
id: option.id,
label: option.label,
sort: option.sort
}))
}));
}
export function validateEventOptionGroupList(groupList?: EventOptionGroup[]): string | undefined {
const normalizedGroupList = normalizeEventOptionGroupList(groupList);
const groupNameSet = new Set<string>();
const groupIdSet = new Set<string>();
const optionIdSet = new Set<string>();
for (const group of normalizedGroupList) {
const groupName = group.name.trim();
if (!groupName) {
return "选项组名称不能为空";
}
if (groupNameSet.has(groupName)) {
return `选项组名称重复:${groupName}`;
}
groupNameSet.add(groupName);
const groupId = normalizeOptionId(group);
if (groupId && groupIdSet.has(groupId)) {
return "选项组标识重复,请重新添加";
}
if (groupId) {
groupIdSet.add(groupId);
}
if (!group.optionList.length) {
return `请为${groupName}添加选项`;
}
const labelSet = new Set<string>();
for (const option of group.optionList) {
const label = option.label.trim();
if (!label) {
return `${groupName}中存在空选项`;
}
if (labelSet.has(label)) {
return `${groupName}中的选项名称重复:${label}`;
}
labelSet.add(label);
const optionId = normalizeOptionId(option);
if (optionId && optionIdSet.has(optionId)) {
return "选项标识重复,请重新添加";
}
if (optionId) {
optionIdSet.add(optionId);
}
}
}
}
export function resolveSelectedOptionGroupList(event: EventItem, selectionMap: EventOptionSelectionMap): EventRecordOptionGroup[] {
const eventId = normalizeEventId(event);
if (!eventId) {
return [];
}
const eventSelectionMap = selectionMap[eventId] || {};
return normalizeEventOptionGroupList(event.optionGroupList)
.map(group => {
const groupId = normalizeOptionId(group);
const selectedIdSet = new Set(eventSelectionMap[groupId] || []);
return {
groupId,
groupName: group.name,
selectedOptionList: group.optionList.filter(option => selectedIdSet.has(normalizeOptionId(option)))
};
})
.filter(group => group.groupId && group.selectedOptionList.length);
}
export function validateEventOptionSelection(event: EventItem, selectionMap: EventOptionSelectionMap): string | undefined {
const eventId = normalizeEventId(event);
if (!eventId) {
return;
}
const eventSelectionMap = selectionMap[eventId] || {};
for (const group of normalizeEventOptionGroupList(event.optionGroupList)) {
const groupId = normalizeOptionId(group);
const selectedIdList = [...new Set(eventSelectionMap[groupId] || [])];
if (group.required && !selectedIdList.length) {
return `请选择${group.name || "当前选项组"}`;
}
if (group.selectionMode === "SINGLE" && 1 < selectedIdList.length) {
return `${group.name || "当前选项组"}只能选择一个选项`;
}
const optionIdSet = new Set(group.optionList.map(normalizeOptionId));
if (selectedIdList.some(optionId => !optionIdSet.has(optionId))) {
return `${group.name || "当前选项组"}包含无效选项`;
}
}
}
export function normalizeEventId(event: EventItem): string {
return event.id === undefined || event.id === null ? "" : String(event.id);
}
export function normalizeOptionId(option: EventOption | EventOptionGroup): string {
return option.id === undefined || option.id === null ? "" : String(option.id);
}
export function buildEventOptionSelectionMap(
eventId: string,
selectedGroupList?: EventRecordOptionGroup[]
): EventOptionSelectionMap {
const groupMap: Record<string, string[]> = {};
for (const group of selectedGroupList || []) {
if (group.groupId) {
groupMap[group.groupId] = (group.selectedOptionList || [])
.map(option => normalizeOptionId(option))
.filter(Boolean);
}
}
return eventId ? {[eventId]: groupMap} : {};
}