hejianhao
2026-04-02 0940d56748a73525790c350c393a5be960aab62c
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
/**
 * 数据验证工具
 * 用于验证导入导出数据的格式和完整性
 */
 
/**
 * 验证导入数据格式
 * @param {Object} data - 要验证的数据对象
 * @returns {Object} 验证结果 { valid: boolean, errors: string[] }
 */
export function validateImportData(data) {
  const errors = [];
 
  // 检查基本结构
  if (!data || typeof data !== "object") {
    errors.push("JSON文件必须是一个对象");
    return { valid: false, errors };
  }
 
  // 检查image字段
  if (!data.image || typeof data.image !== "object") {
    errors.push("缺少image字段或格式错误");
  } else {
    if (!data.image.id) errors.push("image.id字段缺失");
    if (!data.image.name) errors.push("image.name字段缺失");
    if (!data.image.path) errors.push("image.path字段缺失");
  }
 
  // 检查categories字段
  if (!Array.isArray(data.categories)) {
    errors.push("categories字段必须是数组");
  } else {
    data.categories.forEach((category, index) => {
      if (!category.key) errors.push(`categories[${index}].key字段缺失`);
      if (!category.title) errors.push(`categories[${index}].title字段缺失`);
      if (!category.color) errors.push(`categories[${index}].color字段缺失`);
    });
  }
 
  // 检查annotations字段
  if (!Array.isArray(data.annotations)) {
    errors.push("annotations字段必须是数组");
  } else {
    data.annotations.forEach((annotation, index) => {
      if (!annotation.id) errors.push(`annotations[${index}].id字段缺失`);
      if (!annotation.type) errors.push(`annotations[${index}].type字段缺失`);
      if (!annotation.categoryId)
        errors.push(`annotations[${index}].categoryId字段缺失`);
 
      // 根据类型验证坐标数据
      if (annotation.type === "rectangle") {
        if (typeof annotation.x !== "number")
          errors.push(`annotations[${index}].x字段缺失或格式错误`);
        if (typeof annotation.y !== "number")
          errors.push(`annotations[${index}].y字段缺失或格式错误`);
        if (typeof annotation.width !== "number")
          errors.push(`annotations[${index}].width字段缺失或格式错误`);
        if (typeof annotation.height !== "number")
          errors.push(`annotations[${index}].height字段缺失或格式错误`);
      } else if (annotation.type === "line-polygon") {
        if (!Array.isArray(annotation.points)) {
          errors.push(`annotations[${index}].points字段缺失或格式错误`);
        } else {
          annotation.points.forEach((point, pointIndex) => {
            if (typeof point.x !== "number")
              errors.push(
                `annotations[${index}].points[${pointIndex}].x字段格式错误`
              );
            if (typeof point.y !== "number")
              errors.push(
                `annotations[${index}].points[${pointIndex}].y字段格式错误`
              );
          });
        }
      } else if (annotation.type === "point") {
        if (typeof annotation.x !== "number")
          errors.push(`annotations[${index}].x字段缺失或格式错误`);
        if (typeof annotation.y !== "number")
          errors.push(`annotations[${index}].y字段缺失或格式错误`);
      }
    });
  }
 
  return {
    valid: errors.length === 0,
    errors,
  };
}
 
/**
 * 验证导出数据格式
 * @param {Object} data - 要验证的导出数据
 * @returns {Object} 验证结果 { valid: boolean, errors: string[] }
 */
export function validateExportData(data) {
  // 可以在这里添加导出数据的验证逻辑
  return validateImportData(data);
}
 
/**
 * 验证项目数据结构
 * @param {Object} projectData - 项目数据对象
 * @returns {Object} 验证结果 { valid: boolean, errors: string[] }
 */
export function validateProjectData(projectData) {
  const errors = [];
 
  if (!projectData || typeof projectData !== "object") {
    errors.push("项目数据必须是一个对象");
    return { valid: false, errors };
  }
 
  // 验证基本项目信息
  if (!projectData.id) errors.push("项目ID缺失");
  if (!projectData.name) errors.push("项目名称缺失");
  if (!projectData.path) errors.push("项目路径缺失");
 
  return {
    valid: errors.length === 0,
    errors,
  };
}