148 lines
4.8 KiB
TypeScript
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} : {};
|
|
}
|