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
123
124
125
126
127
128
129
130
131
132
|
// lib/vendor-document-list/plant/upload/utils/file-parser.ts
export interface ParsedFileName {
docNumber: string
stageName: string
revision: string
extension: string
originalName: string
isValid: boolean
error?: string
}
export function parseFileName(fileName: string): ParsedFileName {
try {
// 확장자 분리
const lastDotIndex = fileName.lastIndexOf('.')
if (lastDotIndex === -1) {
return {
docNumber: '',
stageName: '',
revision: '',
extension: '',
originalName: fileName,
isValid: false,
error: 'No file extension found'
}
}
const extension = fileName.substring(lastDotIndex + 1)
const nameWithoutExt = fileName.substring(0, lastDotIndex)
// 언더스코어로 분리 (최소 3개 부분 필요)
const parts = nameWithoutExt.split('_')
if (parts.length < 3) {
return {
docNumber: '',
stageName: '',
revision: '',
extension,
originalName: fileName,
isValid: false,
error: `Invalid format. Expected: DocNumber_StageName_Revision.${extension}`
}
}
// 파싱 결과
const docNumber = parts[0]
const stageName = parts.slice(1, -1).join('_') // 중간 부분이 여러 개일 수 있음
const revision = parts[parts.length - 1] // 마지막 부분이 리비전
// 기본 검증
if (!docNumber || !stageName || !revision) {
return {
docNumber: '',
stageName: '',
revision: '',
extension,
originalName: fileName,
isValid: false,
error: 'Missing required parts'
}
}
return {
docNumber,
stageName,
revision,
extension,
originalName: fileName,
isValid: true
}
} catch (error) {
return {
docNumber: '',
stageName: '',
revision: '',
extension: '',
originalName: fileName,
isValid: false,
error: 'Failed to parse filename'
}
}
}
// 리비전 번호 추출 (숫자 우선, 없으면 문자를 숫자로 변환)
export function extractRevisionNumber(revision: string): number {
const cleanRevision = revision.toLowerCase().replace(/[^a-z0-9]/g, '')
// Rev0, Rev1 형식
const revMatch = cleanRevision.match(/rev(\d+)/)
if (revMatch) return parseInt(revMatch[1])
// R0, R1 형식
const rMatch = cleanRevision.match(/r(\d+)/)
if (rMatch) return parseInt(rMatch[1])
// v1, v2 형식
const vMatch = cleanRevision.match(/v(\d+)/)
if (vMatch) return parseInt(vMatch[1])
// 단순 숫자
const numMatch = cleanRevision.match(/^(\d+)$/)
if (numMatch) return parseInt(numMatch[1])
// RevA, RevB 또는 A, B 형식 -> 숫자로 변환 (A=1, B=2, etc.)
const alphaMatch = cleanRevision.match(/^(?:rev)?([a-z])$/i)
if (alphaMatch) {
return alphaMatch[1].toUpperCase().charCodeAt(0) - 64 // A=1, B=2, C=3...
}
// 기본값
return 0
}
// 리비전 코드 정규화 (DB 저장용)
export function normalizeRevisionCode(revision: string): string {
// Rev0 -> 0, RevA -> A, v1 -> 1 등으로 정규화
const cleanRevision = revision.toLowerCase()
// Rev 제거
if (cleanRevision.startsWith('rev')) {
return revision.substring(3)
}
// R, v 제거
if (cleanRevision.startsWith('r') || cleanRevision.startsWith('v')) {
return revision.substring(1)
}
return revision
}
|