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(); const groupIdSet = new Set(); const optionIdSet = new Set(); 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(); 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 = {}; for (const group of selectedGroupList || []) { if (group.groupId) { groupMap[group.groupId] = (group.selectedOptionList || []) .map(option => normalizeOptionId(option)) .filter(Boolean); } } return eventId ? {[eventId]: groupMap} : {}; }