add event option
This commit is contained in:
@@ -0,0 +1,147 @@
|
||||
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} : {};
|
||||
}
|
||||
Reference in New Issue
Block a user