feat(label): add label page

This commit is contained in:
2026-03-10 18:20:50 +08:00
parent 1ae8509cce
commit 014c34ab76
65 changed files with 23477 additions and 0 deletions

View File

@@ -0,0 +1,49 @@
const deepCloneFallback = <T>(value: T, cache = new WeakMap()): T => {
if (value === null || typeof value !== "object") return value
if (cache.has(value as object)) return cache.get(value as object)
if (value instanceof Date) return new Date(value.getTime()) as T
if (value instanceof Map) {
const clonedMap = new Map()
cache.set(value as object, clonedMap)
value.forEach((mapValue, mapKey) => {
clonedMap.set(
deepCloneFallback(mapKey, cache),
deepCloneFallback(mapValue, cache)
)
})
return clonedMap as T
}
if (value instanceof Set) {
const clonedSet = new Set()
cache.set(value as object, clonedSet)
value.forEach((setValue) => {
clonedSet.add(deepCloneFallback(setValue, cache))
})
return clonedSet as T
}
if (Array.isArray(value)) {
const clonedArr: any[] = []
cache.set(value as object, clonedArr)
value.forEach((item, index) => {
clonedArr[index] = deepCloneFallback(item, cache)
})
return clonedArr as T
}
const clonedObj: Record<string, any> = {}
cache.set(value as object, clonedObj)
Object.keys(value as object).forEach((key) => {
clonedObj[key] = deepCloneFallback((value as any)[key], cache)
})
return clonedObj as T
}
export const safeClone = <T>(value: T): T => {
try {
return structuredClone(value)
} catch (error) {
console.warn("structuredClone failed, fallback to deep clone", error)
return deepCloneFallback(value)
}
}

View File

@@ -0,0 +1,248 @@
"use client"
export const dateFormat = "YYYY-MM-DD HH:mm:ss"
export const weekDayText = (data: number) => {
switch (data) {
case 0:
return "星期日"
case 1:
return "星期一"
case 2:
return "星期二"
case 3:
return "星期三"
case 4:
return "星期四"
case 5:
return "星期五"
case 6:
return "星期六"
default:
return "-"
}
}
// 标注任务工序
export const processOpts = [
{ label: "标注", value: "标注" },
{ label: "审核1", value: "审核1" },
{ label: "审核2", value: "审核2" },
]
// 状态码
export const STATUS_CODE = new Map([
[1, "已创建"],
[101, "已创建"], // 审核
[102, "已创建"], // 复审
[103, "已创建"], // 审核3
[180, "数据同步中"],
[190, "Embedding生成中"],
[191, "Embedding生成失败"],
[199, "审核失败"],
[201, "试标阶段"], // 试标中
[202, "试标阶段"], // 试标完成
[203, "试标阶段"], // 试标确认
[500, "标注中"],
[580, "待验收"],
[600, "已完成"],
[700, "已终止"],
])
// 状态码
export const projectStatusOpts = [
{ label: "试标阶段", value: "201,202,203" },
{ label: "标注中", value: 500 },
{ label: "待验收", value: 580 },
{ label: "已完成", value: 600 },
// { label: "审核失败", value: 199 },
{ label: "已终止", value: 700 },
]
export const CREATED_CODE = [1, 101, 102, 103, 190, 191, 199] // 已创建的状态码数组
export const ALL_CODE = [201, 202, 203, 500, 580, 600, 700] // 其他的状态码数组
export const PRELABEL_CODE = [201, 202, 203]
export const LABEL_CODE = [500, 580]
export const projectLabelTypeOpts = [
{ label: "点云框", value: 1 },
{ label: "点云分割", value: 2 },
{ label: "点云分类", value: 3 },
{ label: "图片", value: 4 },
{ label: "大语言基础", value: 5 },
{ label: "大语言QA", value: 6 },
{ label: "视频", value: 7 },
]
// 项目列表中状态码对应值及style
export const statusStyles = {
1: {
label: "已创建",
styleText: "text-[#1874FF] bg-[#E8F0FC]",
},
101: {
label: "已创建",
styleText: "text-[#1874FF] bg-[#E8F0FC]",
},
102: {
label: "已创建",
styleText: "text-[#1874FF] bg-[#E8F0FC]",
},
103: {
label: "已创建",
styleText: "text-[#1874FF] bg-[#E8F0FC]",
},
190: {
label: "Embedding生成中",
styleText: "text-[#1874FF] bg-[#E8F0FC]",
},
191: {
label: "Embedding生成失败",
styleText: "text-[#D9333E] bg-[#FBEBEC]",
},
199: {
label: "审核失败",
styleText: "text-[#D9333E] bg-[#FBEBEC]",
},
201: {
label: "试标阶段",
styleText: "text-[#21D3ED] bg-[#EEFDFF]",
},
202: {
label: "试标阶段",
styleText: "text-[#21D3ED] bg-[#EEFDFF]",
},
203: {
label: "试标阶段",
styleText: "text-[#21D3ED] bg-[#EEFDFF]",
},
500: {
label: "标注中",
styleText: "text-[#1874FF] bg-[#E8F0FC]",
},
580: {
label: "待验收",
styleText: "text-[#FFB84D] bg-[#FEF5E7]",
},
600: {
label: "已完成",
styleText: "text-[#4FD796] bg-[#E7F9F0]",
},
700: {
label: "已终止",
styleText: "text-[#34425F] bg-[#F7F8F9]",
},
}
export const staticsColor = [
{ "8_151_156": 1 },
{ "9_109_217": 2 },
{ "15_15_118": 3 },
{ "28_27_175": 4 },
{ "35_84_116": 5 },
{ "45_69_235": 6 },
{ "53_127_127": 7 },
{ "54_124_171": 8 },
{ "54_207_201": 9 },
{ "56_158_13": 10 },
{ "63_18_119": 11 },
{ "69_151_223": 12 },
{ "81_188_187": 13 },
{ "83_29_171": 14 },
{ "84_119_48": 15 },
{ "95_33_176": 16 },
{ "100_16_23": 17 },
{ "113_249_251": 18 },
{ "116_78_41": 19 },
{ "125_179_75": 20 },
{ "127_48_236": 21 },
{ "127_127_54": 22 },
{ "132_133_239": 23 },
{ "147_210_239": 24 },
{ "151_29_36": 25 },
{ "155_125_62": 26 },
{ "156_239_102": 27 },
{ "161_98_48": 28 },
{ "178_253_253": 29 },
{ "188_136_242": 30 },
{ "189_191_84": 31 },
{ "191_49_47": 32 },
{ "196_29_127": 33 },
{ "202_247_138": 34 },
{ "203_164_81": 35 },
{ "207_19_34": 36 },
{ "212_107_8": 37 },
{ "212_177_6": 38 },
{ "223_134_144": 39 },
{ "233_157_84": 40 },
{ "244_206_159": 41 },
{ "252_202_0": 42 },
{ "252_250_147": 43 },
{ "253_247_87": 44 },
{ "255_191_120": 45 },
{ "255_236_61": 46 },
]
export const labelTypeOpts = [
{ label: "点云框", value: 1 },
{ label: "点云分割", value: 2 },
// { label: '点云分类', value: '点云分类' },
{ label: "2D框", value: 101 },
{ label: "多边形", value: 102 },
{ label: "关键点", value: 103 },
{ label: "多线段", value: 104 },
{ label: "文本描述", value: 201 },
]
export const labelTypeMap = new Map([
[1, "点云框"],
[2, "点云分割"],
[101, "2D框"],
[102, "多边形"],
[103, "关键点"],
[104, "多线段"],
[201, "文本描述"],
])
export const selectModeOpts = [
{ label: "输入", value: 0 },
{ label: "单选", value: 1 },
{ label: "多选", value: 2 },
]
export const selectModeMap = new Map([
[0, "输入"],
[1, "单选"],
[2, "多选"],
])
// 标注任务状态码
export const TaskStatusEnum = new Map([
// [0, "None"],
[1, "待领取"],
[2, "标注中"],
[3, "标注完成"],
[4, "审核中"],
[5, "审核完成"],
[6, "复审中"],
[7, "复审完成"],
[8, "无法标注"],
])
export const OwnTaskStatusOpts = {
0: "全部",
2: "标注中",
4: "审核中",
6: "复审中",
}
export const TaskStatusOpts = {
0: "全部",
1: "待领取",
2: "标注中",
3: "标注完成",
4: "审核中",
5: "审核完成",
6: "复审中",
7: "复审完成",
8: "无法标注",
}

View File

@@ -0,0 +1,164 @@
import paper from "paper"
const scaleFlatPoint = (point: any, scale: number): [number, number] => {
return [point[0] * scale, point[1] * scale]
}
const scaleSegmentToPoint = (seg: any, scale: number): any => {
if (seg instanceof paper.Point) {
return [seg.x * scale, seg.y * scale]
}
if (seg instanceof paper.Segment) {
return [seg.point.x * scale, seg.point.y * scale]
}
if (
Array.isArray(seg) &&
seg.length >= 2 &&
typeof seg[0] === "number" &&
typeof seg[1] === "number"
) {
return scaleFlatPoint(seg, scale)
}
if (
Array.isArray(seg) &&
Array.isArray(seg[0]) &&
seg[0].length >= 2 &&
typeof seg[0][0] === "number" &&
typeof seg[0][1] === "number"
) {
// Support paper JSON segment format: [[x,y], [handleInX, handleInY], [handleOutX, handleOutY]]
return scaleFlatPoint(seg[0], scale)
}
if (
seg?.point &&
typeof seg.point.x === "number" &&
typeof seg.point.y === "number"
) {
return [seg.point.x * scale, seg.point.y * scale]
}
if (
seg?.point &&
Array.isArray(seg.point) &&
seg.point.length >= 2 &&
typeof seg.point[0] === "number" &&
typeof seg.point[1] === "number"
) {
return [seg.point[0] * scale, seg.point[1] * scale]
}
return seg
}
// 调整原始比例点位到当前图片的缩放比例
export const adjustPoints: (
id: string,
nestedMap: Map<string, Map<string, [number, any[], any, any[]][]>>,
scale: number
) => Map<string, Map<string, [number, any[], any, any[]][]>> = (
id,
nestedMap,
scale
) => {
const adjustedMap = new Map<
string,
Map<string, [number, any[], any, any[]][]>
>()
nestedMap.forEach((innerMap, outerKey) => {
if (id === outerKey) {
const adjustedInnerMap = new Map<
string,
Array<[number, any[], any, any[]]>
>()
innerMap.forEach((array, innerKey) => {
const adjustedArray = array.map(
([id, points, detail, hollowPoints]) => {
// let adjustedPoints = points.map((point) => {
// let flag = point instanceof paper.Point;
// if (flag) {
// return [point.x * scale, point.y * scale];
// } else {
// return point.map((item: any) => item * scale);
// }
// });
let adjustedPoints = points.map((child) => {
return child.map((seg: any) => {
return scaleSegmentToPoint(seg, scale)
})
})
let adjustedHollowPoints = hollowPoints.map((child) => {
return child.map((seg: any) => {
return scaleSegmentToPoint(seg, scale)
})
})
return [id, adjustedPoints, detail, adjustedHollowPoints]
}
)
adjustedInnerMap.set(innerKey, adjustedArray as any)
})
adjustedMap.set(outerKey, adjustedInnerMap)
} else {
adjustedMap.set(outerKey, innerMap)
}
})
return adjustedMap
}
// 根据比例调整不同图片的点位数据
export const adjustAllPoints: (
nestedMap: Map<string, Map<string, [number, any[], any, any[]][]>>,
allScale: { [x: string]: number }
) => Map<string, Map<string, [number, any[], any, any[]][]>> = (
nestedMap,
allScale
) => {
const adjustedMap = new Map<
string,
Map<string, [number, any[], any, any[]][]>
>()
nestedMap.forEach((innerMap, outerKey) => {
const scale = allScale[outerKey]
if (scale) {
const adjustedInnerMap = new Map<
string,
Array<[number, any[], any, any[]]>
>()
innerMap.forEach((array, innerKey) => {
const adjustedArray = array.map(
([id, points, detail, hollowPoints]) => {
// let adjustedPoints = points.map((point) => {
// let flag = point instanceof paper.Point;
// if (flag) {
// return [point.x * scale, point.y * scale];
// } else {
// return point.map((item: any) => item * scale);
// }
// });
let adjustedPoints = points.map((child) => {
return child.map((seg: any) => {
return scaleSegmentToPoint(seg, scale)
})
})
let adjustedHollowPoints = hollowPoints.map((child) => {
return child.map((seg: any) => {
return scaleSegmentToPoint(seg, scale)
})
})
return [id, adjustedPoints, detail, adjustedHollowPoints]
}
)
adjustedInnerMap.set(innerKey, adjustedArray as any)
})
adjustedMap.set(outerKey, adjustedInnerMap)
} else {
adjustedMap.set(outerKey, innerMap)
}
})
return adjustedMap
}

View File

@@ -0,0 +1,15 @@
export const enterFullscreen = (element: any) => {
if (element?.requestFullscreen) {
element.requestFullscreen()
} else if (element?.webkitRequestFullscreen) {
element.webkitRequestFullscreen()
} else if (element?.msRequestFullscreen) {
element.msRequestFullscreen()
}
}
export const exitFullscreen = () => {
if (document.fullscreenElement) {
document.exitFullscreen()
}
}