刘光辉
6 小时以前 cf11e63b659afcc9792ab3e395f1b45d844431a8
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
import type { TemplateBinding, TemplateCheckboxGroup } from './types';
 
export interface CheckboxGroupSummary {
  anomalies: string[];
  code: string;
  members: TemplateBinding[];
  scopes: string[];
}
 
interface CheckboxGroupScope {
  repeatGroupCode?: null | string;
  stepId?: null | string;
}
 
function liveBinding(binding: TemplateBinding): boolean {
  return binding.status === 'ACTIVE' || binding.status === 'PENDING';
}
 
function eligibleMember(binding: TemplateBinding): boolean {
  return (
    (binding.controlRole === 'PRIMARY' || binding.controlRole === 'REPEAT') &&
    binding.controlType === 'CHECKBOX' &&
    !binding.readOnly
  );
}
 
function scopeKey(binding: CheckboxGroupScope): string {
  return binding.repeatGroupCode ? `repeat:${binding.repeatGroupCode}` : `step:${binding.stepId || ''}`;
}
 
function scopeLabel(binding: CheckboxGroupScope): string {
  return binding.repeatGroupCode ? `重复组:${binding.repeatGroupCode}` : `步骤:${binding.stepId || '未设置'}`;
}
 
function defaultChecked(binding: TemplateBinding): boolean {
  return binding.controlConfig?.defaultChecked === true;
}
 
export function checkboxGroupCodeValid(code: string): boolean {
  return /^[\w-]{1,80}$/u.test(code.trim());
}
 
export function summarizeCheckboxGroups(
  bindings: TemplateBinding[],
  configuredGroups: TemplateCheckboxGroup[] = [],
): CheckboxGroupSummary[] {
  const groups = new Map<string, TemplateBinding[]>();
  const rules = new Map(configuredGroups.map((group) => [group.groupCode, group]));
  for (const binding of bindings) {
    const code = binding.checkboxGroupCode?.trim();
    if (!liveBinding(binding) || !code) continue;
    groups.set(code, [...(groups.get(code) ?? []), binding]);
  }
 
  return [...groups.entries()]
    .sort(([left], [right]) => left.localeCompare(right))
    .map(([code, members]) => {
      const anomalies: string[] = [];
      const scopes = [...new Set(members.map(scopeKey))];
      if (!checkboxGroupCodeValid(code)) anomalies.push('选择组编码格式无效');
      if (members.some((member) => !eligibleMember(member))) anomalies.push('包含不允许入组的字段');
      if (scopes.length > 1) anomalies.push('同一选择组跨越多个作用域');
      if (members.length < 2) anomalies.push('只有一个成员,发布前需要补充同组复选框');
      const rule = rules.get(code) ?? { maxSelected: 1, minSelected: 0 };
      const defaultCount = members.filter(defaultChecked).length;
      if (defaultCount < rule.minSelected || (rule.maxSelected !== null && defaultCount > rule.maxSelected)) {
        anomalies.push('默认勾选数不符合数量规则');
      }
      return { anomalies, code, members, scopes: [...new Set(members.map(scopeLabel))] };
    });
}
 
export function checkboxGroupOptions(
  bindings: TemplateBinding[],
  scope: CheckboxGroupScope,
): Array<{ label: string; value: string }> {
  const targetScope = scopeKey(scope);
  return summarizeCheckboxGroups(bindings)
    .filter(
      (group) =>
        checkboxGroupCodeValid(group.code) &&
        group.members.every(eligibleMember) &&
        group.members.every((member) => scopeKey(member) === targetScope),
    )
    .map((group) => ({ label: `${group.code}(${group.members.length} 个成员)`, value: group.code }));
}