Showing
1 changed file
with
8 additions
and
138 deletions
| ... | @@ -62,7 +62,6 @@ | ... | @@ -62,7 +62,6 @@ |
| 62 | <body> | 62 | <body> |
| 63 | <meta name="csrf-token" content="{{ csrf_token() }}"> | 63 | <meta name="csrf-token" content="{{ csrf_token() }}"> |
| 64 | <div id="app"> | 64 | <div id="app"> |
| 65 | - <!-- Right: PDF viewer + select tool --> | ||
| 66 | <div class="right-panel" > | 65 | <div class="right-panel" > |
| 67 | <div class="pdf-container" ref="pdfContainer" | 66 | <div class="pdf-container" ref="pdfContainer" |
| 68 | @mousedown="startSelect" | 67 | @mousedown="startSelect" |
| ... | @@ -120,17 +119,15 @@ | ... | @@ -120,17 +119,15 @@ |
| 120 | </div> | 119 | </div> |
| 121 | </div> | 120 | </div> |
| 122 | 121 | ||
| 123 | - <!-- Left: Form inputs --> | ||
| 124 | <div class="left-panel"> | 122 | <div class="left-panel"> |
| 125 | <div v-for="field in fieldOptions" :key="field.value" class="form-group"> | 123 | <div v-for="field in fieldOptions" :key="field.value" class="form-group"> |
| 126 | <label>@{{ field.label }}</label> | 124 | <label>@{{ field.label }}</label> |
| 127 | <input v-model="formData[field.value]" | 125 | <input v-model="formData[field.value]" |
| 128 | @focus="highlightField(field.value)" | 126 | @focus="highlightField(field.value)" |
| 129 | @click="onInputClick(field.value)" | 127 | @click="onInputClick(field.value)" |
| 130 | - @blur="onInputBlur(field.value)" | 128 | + @blur="removeAllFocus()" |
| 131 | 129 | ||
| 132 | > | 130 | > |
| 133 | -{{-- :readonly="field.value === 'customer_name' && !hasCustomerNameXY"--}} | ||
| 134 | </div> | 131 | </div> |
| 135 | <button @click="saveTemplate">💾Save</button> | 132 | <button @click="saveTemplate">💾Save</button> |
| 136 | </div> | 133 | </div> |
| ... | @@ -160,7 +157,6 @@ | ... | @@ -160,7 +157,6 @@ |
| 160 | } | 157 | } |
| 161 | }, | 158 | }, |
| 162 | created() { | 159 | created() { |
| 163 | - // Chỉ tạo formData cho các field cần mapping | ||
| 164 | this.fieldOptions | 160 | this.fieldOptions |
| 165 | .forEach(f => { | 161 | .forEach(f => { |
| 166 | this.$set(this.formData, f.value, ""); | 162 | this.$set(this.formData, f.value, ""); |
| ... | @@ -171,7 +167,6 @@ | ... | @@ -171,7 +167,6 @@ |
| 171 | 167 | ||
| 172 | // Thêm event listener để xóa focus khi click ra ngoài | 168 | // Thêm event listener để xóa focus khi click ra ngoài |
| 173 | document.addEventListener('click', (e) => { | 169 | document.addEventListener('click', (e) => { |
| 174 | - // Nếu click không phải vào input hoặc box | ||
| 175 | if (!e.target.closest('.left-panel') && !e.target.closest('.bbox')) { | 170 | if (!e.target.closest('.left-panel') && !e.target.closest('.bbox')) { |
| 176 | this.removeAllFocus(); | 171 | this.removeAllFocus(); |
| 177 | } | 172 | } |
| ... | @@ -191,12 +186,11 @@ | ... | @@ -191,12 +186,11 @@ |
| 191 | 186 | ||
| 192 | // Xóa tất cả box có fieldName trùng lặp, chỉ giữ lại box hiện tại | 187 | // Xóa tất cả box có fieldName trùng lặp, chỉ giữ lại box hiện tại |
| 193 | this.ocrData = this.ocrData.filter((box, i) => { | 188 | this.ocrData = this.ocrData.filter((box, i) => { |
| 194 | - if (i === index) return true; // Giữ lại box hiện tại | 189 | + if (i === index) return true; |
| 195 | if (box.field === fieldName) { | 190 | if (box.field === fieldName) { |
| 196 | - // Xóa box có field trùng lặp | ||
| 197 | return false; | 191 | return false; |
| 198 | } | 192 | } |
| 199 | - return true; // Giữ lại các box khác | 193 | + return true; |
| 200 | }); | 194 | }); |
| 201 | 195 | ||
| 202 | // Cập nhật lại index sau khi filter | 196 | // Cập nhật lại index sau khi filter |
| ... | @@ -214,8 +208,7 @@ | ... | @@ -214,8 +208,7 @@ |
| 214 | this.ocrData[newIndex].field_xy = null; | 208 | this.ocrData[newIndex].field_xy = null; |
| 215 | } | 209 | } |
| 216 | 210 | ||
| 217 | - // Gán field mới | 211 | + const bbox = this.ocrData[newIndex].bbox; |
| 218 | - const bbox = this.ocrData[newIndex].bbox; // tọa độ OCR gốc [x1, y1, x2, y2] | ||
| 219 | 212 | ||
| 220 | const x1 = bbox[0]; | 213 | const x1 = bbox[0]; |
| 221 | const y1 = bbox[1]; | 214 | const y1 = bbox[1]; |
| ... | @@ -223,86 +216,17 @@ | ... | @@ -223,86 +216,17 @@ |
| 223 | const h = bbox[3]; | 216 | const h = bbox[3]; |
| 224 | 217 | ||
| 225 | const xyStr = `${x1},${y1},${w},${h}`; | 218 | const xyStr = `${x1},${y1},${w},${h}`; |
| 226 | - | ||
| 227 | this.ocrData[newIndex].field = fieldName; | 219 | this.ocrData[newIndex].field = fieldName; |
| 228 | this.ocrData[newIndex].field_xy = xyStr; | 220 | this.ocrData[newIndex].field_xy = xyStr; |
| 229 | 221 | ||
| 230 | - // Set text | ||
| 231 | this.formData[fieldName] = (text !== null ? text : (this.ocrData[newIndex].text || '')).trim(); | 222 | this.formData[fieldName] = (text !== null ? text : (this.ocrData[newIndex].text || '')).trim(); |
| 232 | 223 | ||
| 233 | - // KHÔNG set active index (không focus) | ||
| 234 | - | ||
| 235 | - // Nếu là customer_name | ||
| 236 | - if (fieldName === 'customer_name') { | ||
| 237 | - this.hasCustomerNameXY = true; | ||
| 238 | - this.customer_name_xy = xyStr; | ||
| 239 | - } | ||
| 240 | - }, | ||
| 241 | - | ||
| 242 | - assignFieldToBox(index, fieldName, text = null) { | ||
| 243 | - console.log(`Assigning field "${fieldName}" to box at index ${index} with text: "${text}"`); | ||
| 244 | - if (index == null) return; | ||
| 245 | - | ||
| 246 | - // 1. Xóa tất cả box có fieldName trùng lặp, chỉ giữ lại box hiện tại | ||
| 247 | - this.ocrData = this.ocrData.filter((box, i) => { | ||
| 248 | - if (i === index) return true; // Giữ lại box hiện tại | ||
| 249 | - if (box.field === fieldName) { | ||
| 250 | - // Xóa box có field trùng lặp | ||
| 251 | - return false; | ||
| 252 | - } | ||
| 253 | - return true; // Giữ lại các box khác | ||
| 254 | - }); | ||
| 255 | - | ||
| 256 | - // 2. Cập nhật lại index sau khi filter | ||
| 257 | - const newIndex = this.ocrData.findIndex(box => box.bbox === this.ocrData[index]?.bbox); | ||
| 258 | - if (newIndex === -1) return; | ||
| 259 | - | ||
| 260 | - // 3. Nếu box này từng gán field khác thì bỏ | ||
| 261 | - const prev = this.ocrData[newIndex]?.field; | ||
| 262 | - if (prev && prev !== fieldName) { | ||
| 263 | - if (prev === 'customer_name') { | ||
| 264 | - this.hasCustomerNameXY = false; | ||
| 265 | - this.customer_name_xy = ''; | ||
| 266 | - } | ||
| 267 | - this.ocrData[newIndex].field = null; | ||
| 268 | - this.ocrData[newIndex].field_xy = null; | ||
| 269 | - } | ||
| 270 | - | ||
| 271 | - // 4. Gán field mới | ||
| 272 | - const bbox = this.ocrData[newIndex].bbox; // tọa độ OCR gốc [x1, y1, x2, y2] | ||
| 273 | - console.log('bbox', bbox); | ||
| 274 | - const [x1, y1, w, h] = bbox; | ||
| 275 | - const xyStr = `${x1},${y1},${w},${h}`; | ||
| 276 | - | ||
| 277 | - this.ocrData[newIndex].field = fieldName; | ||
| 278 | - this.ocrData[newIndex].field_xy = xyStr; | ||
| 279 | - | ||
| 280 | - // 5. Gán text | ||
| 281 | - const finalText = text !== null ? text : (this.ocrData[newIndex].text || ''); | ||
| 282 | - this.formData[fieldName] = finalText.trim(); | ||
| 283 | - console.log(`formData ${fieldName}`, this.formData[fieldName]); | ||
| 284 | - | ||
| 285 | - // Nếu trong manualBoxData tồn tại field này hoặc muốn tạo lại manual box từ ocrData | ||
| 286 | - if (this.manualBoxData[fieldName]) { | ||
| 287 | - // Lấy tọa độ + text từ box hiện tại để tạo manual box mới | ||
| 288 | - this.createManualBoxFromDB(fieldName, this.ocrData[newIndex].bbox, finalText); | ||
| 289 | - // Cập nhật manualBoxData | ||
| 290 | - this.manualBoxData[fieldName] = { | ||
| 291 | - coords: this.ocrData[newIndex].bbox, | ||
| 292 | - text: finalText | ||
| 293 | - }; | ||
| 294 | - } | ||
| 295 | - | ||
| 296 | - // 6. Active index | ||
| 297 | - this.activeIndex = newIndex; | ||
| 298 | - // 7. Nếu là customer_name | ||
| 299 | if (fieldName === 'customer_name') { | 224 | if (fieldName === 'customer_name') { |
| 300 | this.hasCustomerNameXY = true; | 225 | this.hasCustomerNameXY = true; |
| 301 | this.customer_name_xy = xyStr; | 226 | this.customer_name_xy = xyStr; |
| 302 | } | 227 | } |
| 303 | }, | 228 | }, |
| 304 | 229 | ||
| 305 | - | ||
| 306 | async saveTemplate() { | 230 | async saveTemplate() { |
| 307 | 231 | ||
| 308 | let customer_name = null; | 232 | let customer_name = null; |
| ... | @@ -315,7 +239,6 @@ | ... | @@ -315,7 +239,6 @@ |
| 315 | fields = this.manualBoxData; | 239 | fields = this.manualBoxData; |
| 316 | console.log('Using manualBoxData for customer_name:', customer_name, customer_coords); | 240 | console.log('Using manualBoxData for customer_name:', customer_name, customer_coords); |
| 317 | } else { | 241 | } else { |
| 318 | - // Không có → tìm trong ocrData | ||
| 319 | const found = this.ocrData.find(item => item.field === 'customer_name'); | 242 | const found = this.ocrData.find(item => item.field === 'customer_name'); |
| 320 | if (found) { | 243 | if (found) { |
| 321 | customer_name = found.text; | 244 | customer_name = found.text; |
| ... | @@ -325,20 +248,17 @@ | ... | @@ -325,20 +248,17 @@ |
| 325 | const fieldsByName = {}; | 248 | const fieldsByName = {}; |
| 326 | this.ocrData.forEach(box => { | 249 | this.ocrData.forEach(box => { |
| 327 | if (box.field && !box.isDeleted) { | 250 | if (box.field && !box.isDeleted) { |
| 328 | - // chỉ giữ 1 bản ghi cuối cùng cho mỗi field (box gần nhất) | ||
| 329 | fieldsByName[box.field] = { | 251 | fieldsByName[box.field] = { |
| 330 | text: box.field, | 252 | text: box.field, |
| 331 | coords: box.field_xy || '' | 253 | coords: box.field_xy || '' |
| 332 | }; | 254 | }; |
| 333 | } | 255 | } |
| 334 | }); | 256 | }); |
| 335 | - // // convert to array | 257 | + |
| 336 | fields = (fieldsByName); | 258 | fields = (fieldsByName); |
| 337 | console.log('Using ocrData for customer_name:', customer_name, customer_coords); | 259 | console.log('Using ocrData for customer_name:', customer_name, customer_coords); |
| 338 | } | 260 | } |
| 339 | 261 | ||
| 340 | - // console.log('fields:', fields); | ||
| 341 | - | ||
| 342 | if (!customer_coords || !customer_name) { | 262 | if (!customer_coords || !customer_name) { |
| 343 | alert("Bạn phải map customer_name (quét/select) trước khi lưu."); | 263 | alert("Bạn phải map customer_name (quét/select) trước khi lưu."); |
| 344 | return; | 264 | return; |
| ... | @@ -350,7 +270,7 @@ | ... | @@ -350,7 +270,7 @@ |
| 350 | customer_name_xy: customer_coords || [], | 270 | customer_name_xy: customer_coords || [], |
| 351 | fields: fields | 271 | fields: fields |
| 352 | }; | 272 | }; |
| 353 | - // console.log(fields); | 273 | + |
| 354 | try { | 274 | try { |
| 355 | const res = await fetch('/ocr/save-template', { | 275 | const res = await fetch('/ocr/save-template', { |
| 356 | method: 'POST', | 276 | method: 'POST', |
| ... | @@ -377,7 +297,6 @@ | ... | @@ -377,7 +297,6 @@ |
| 377 | const item = this.ocrData[index]; | 297 | const item = this.ocrData[index]; |
| 378 | if (item.isManual) { | 298 | if (item.isManual) { |
| 379 | const manualBbox = item.bbox; | 299 | const manualBbox = item.bbox; |
| 380 | - | ||
| 381 | // Hiện lại border các box OCR gốc nằm trong vùng thủ công | 300 | // Hiện lại border các box OCR gốc nằm trong vùng thủ công |
| 382 | this.ocrData.forEach(o => { | 301 | this.ocrData.forEach(o => { |
| 383 | if (!o.isManual && this.isBoxInside(o.bbox, manualBbox)) { | 302 | if (!o.isManual && this.isBoxInside(o.bbox, manualBbox)) { |
| ... | @@ -415,17 +334,8 @@ | ... | @@ -415,17 +334,8 @@ |
| 415 | this.ocrData = data.ocrData; | 334 | this.ocrData = data.ocrData; |
| 416 | this.pdfImageUrl = data.pdfImageUrl; | 335 | this.pdfImageUrl = data.pdfImageUrl; |
| 417 | this.fieldOptions = data.fieldOptions; | 336 | this.fieldOptions = data.fieldOptions; |
| 418 | - // this.formData = data.formData; | ||
| 419 | this.dataMapping = data.dataMapping; | 337 | this.dataMapping = data.dataMapping; |
| 420 | this.is_template = data.is_template; | 338 | this.is_template = data.is_template; |
| 421 | - // Đợi image load xong trước khi xử lý | ||
| 422 | - // if (this.$refs.pdfImage && this.$refs.pdfImage.complete) { | ||
| 423 | - // // this.processLoadedData(); | ||
| 424 | - // } else { | ||
| 425 | - // console.log('Image not loaded yet, waiting for onImageLoad'); | ||
| 426 | - // // Image sẽ được xử lý trong onImageLoad | ||
| 427 | - // } | ||
| 428 | - | ||
| 429 | 339 | ||
| 430 | } catch (error) { | 340 | } catch (error) { |
| 431 | console.error('Error in loadOCRData:', error); | 341 | console.error('Error in loadOCRData:', error); |
| ... | @@ -434,16 +344,13 @@ | ... | @@ -434,16 +344,13 @@ |
| 434 | 344 | ||
| 435 | // Xử lý data sau khi image đã load | 345 | // Xử lý data sau khi image đã load |
| 436 | processLoadedData() { | 346 | processLoadedData() { |
| 437 | - // Tự động map field cho các box OCR dựa trên formData đã load | ||
| 438 | this.autoMapFieldsFromFormData(); | 347 | this.autoMapFieldsFromFormData(); |
| 439 | - | ||
| 440 | // Force re-render để đảm bảo các box được vẽ | 348 | // Force re-render để đảm bảo các box được vẽ |
| 441 | this.$nextTick(() => { | 349 | this.$nextTick(() => { |
| 442 | this.$forceUpdate(); | 350 | this.$forceUpdate(); |
| 443 | }); | 351 | }); |
| 444 | }, | 352 | }, |
| 445 | 353 | ||
| 446 | - // Tự động map field cho các box OCR dựa trên formData đã load từ DB | ||
| 447 | autoMapFieldsFromFormData() { | 354 | autoMapFieldsFromFormData() { |
| 448 | this.manualBoxData = {}; // reset | 355 | this.manualBoxData = {}; // reset |
| 449 | 356 | ||
| ... | @@ -452,7 +359,6 @@ | ... | @@ -452,7 +359,6 @@ |
| 452 | } | 359 | } |
| 453 | 360 | ||
| 454 | const tolerance = 20; // ngưỡng chenh lech toa do y cho cùng 1 hàng | 361 | const tolerance = 20; // ngưỡng chenh lech toa do y cho cùng 1 hàng |
| 455 | - | ||
| 456 | Object.keys(this.dataMapping).forEach(fieldName => { | 362 | Object.keys(this.dataMapping).forEach(fieldName => { |
| 457 | let { coords, text } = this.dataMapping[fieldName]; | 363 | let { coords, text } = this.dataMapping[fieldName]; |
| 458 | let foundItems = this.ocrData | 364 | let foundItems = this.ocrData |
| ... | @@ -470,13 +376,10 @@ | ... | @@ -470,13 +376,10 @@ |
| 470 | 376 | ||
| 471 | const combinedText = foundItems.map(f => f.text.trim()); | 377 | const combinedText = foundItems.map(f => f.text.trim()); |
| 472 | const finalText = combinedText.join(" "); | 378 | const finalText = combinedText.join(" "); |
| 473 | - | ||
| 474 | - // Lưu vào dataMapping | ||
| 475 | this.dataMapping[fieldName] = { | 379 | this.dataMapping[fieldName] = { |
| 476 | text: finalText, | 380 | text: finalText, |
| 477 | coords: coords | 381 | coords: coords |
| 478 | }; | 382 | }; |
| 479 | - // Nếu là template thì gán vào formData | ||
| 480 | if (this.is_template) { | 383 | if (this.is_template) { |
| 481 | this.formData[fieldName] = finalText && finalText.trim() !== "" ? finalText : text; | 384 | this.formData[fieldName] = finalText && finalText.trim() !== "" ? finalText : text; |
| 482 | } | 385 | } |
| ... | @@ -493,7 +396,6 @@ | ... | @@ -493,7 +396,6 @@ |
| 493 | const img = this.$refs.pdfImage; | 396 | const img = this.$refs.pdfImage; |
| 494 | this.imageWidth = img.naturalWidth; | 397 | this.imageWidth = img.naturalWidth; |
| 495 | this.imageHeight = img.naturalHeight; | 398 | this.imageHeight = img.naturalHeight; |
| 496 | - // Nếu đã có data, xử lý ngay | ||
| 497 | if (this.ocrData && this.ocrData.length > 0) { | 399 | if (this.ocrData && this.ocrData.length > 0) { |
| 498 | console.log('Image loaded and data exists, processing now'); | 400 | console.log('Image loaded and data exists, processing now'); |
| 499 | this.processLoadedData(); | 401 | this.processLoadedData(); |
| ... | @@ -555,7 +457,6 @@ | ... | @@ -555,7 +457,6 @@ |
| 555 | } | 457 | } |
| 556 | } | 458 | } |
| 557 | 459 | ||
| 558 | - // Nếu có coords thì tạo hoặc hiển thị lại box | ||
| 559 | if (coords) { | 460 | if (coords) { |
| 560 | if (isFromDB) { | 461 | if (isFromDB) { |
| 561 | // Tạo box manual từ DB (không có nút xóa) | 462 | // Tạo box manual từ DB (không có nút xóa) |
| ... | @@ -586,8 +487,6 @@ | ... | @@ -586,8 +487,6 @@ |
| 586 | } | 487 | } |
| 587 | }, | 488 | }, |
| 588 | 489 | ||
| 589 | - | ||
| 590 | - // Scroll đến box tương ứng | ||
| 591 | scrollToBox(index) { | 490 | scrollToBox(index) { |
| 592 | if (!this.$refs.pdfContainer || index < 0 || index >= this.ocrData.length) return; | 491 | if (!this.$refs.pdfContainer || index < 0 || index >= this.ocrData.length) return; |
| 593 | 492 | ||
| ... | @@ -623,8 +522,6 @@ | ... | @@ -623,8 +522,6 @@ |
| 623 | }); | 522 | }); |
| 624 | }, | 523 | }, |
| 625 | 524 | ||
| 626 | - | ||
| 627 | - | ||
| 628 | // Xử lý khi click vào input | 525 | // Xử lý khi click vào input |
| 629 | onInputClick(fieldName) { | 526 | onInputClick(fieldName) { |
| 630 | // Kiểm tra xem field này có data không | 527 | // Kiểm tra xem field này có data không |
| ... | @@ -635,12 +532,6 @@ | ... | @@ -635,12 +532,6 @@ |
| 635 | } | 532 | } |
| 636 | }, | 533 | }, |
| 637 | 534 | ||
| 638 | - // Xử lý khi click ra ngoài input (blur) | ||
| 639 | - onInputBlur(fieldName) { | ||
| 640 | - // Khi không focus vào input nào, xóa tất cả focus | ||
| 641 | - this.removeAllFocus(); | ||
| 642 | - }, | ||
| 643 | - | ||
| 644 | // Xóa tất cả focus | 535 | // Xóa tất cả focus |
| 645 | removeAllFocus() { | 536 | removeAllFocus() { |
| 646 | // Reset active index (chỉ mất màu xanh, không xóa box) | 537 | // Reset active index (chỉ mất màu xanh, không xóa box) |
| ... | @@ -779,8 +670,7 @@ | ... | @@ -779,8 +670,7 @@ |
| 779 | e.stopPropagation(); | 670 | e.stopPropagation(); |
| 780 | e.preventDefault(); | 671 | e.preventDefault(); |
| 781 | 672 | ||
| 782 | - } | 673 | + }, |
| 783 | - , | ||
| 784 | applyMapping() { | 674 | applyMapping() { |
| 785 | const item = this.ocrData[this.selectingIndex]; | 675 | const item = this.ocrData[this.selectingIndex]; |
| 786 | if (!item) return; | 676 | if (!item) return; |
| ... | @@ -790,8 +680,6 @@ | ... | @@ -790,8 +680,6 @@ |
| 790 | box.field = ''; | 680 | box.field = ''; |
| 791 | } | 681 | } |
| 792 | }); | 682 | }); |
| 793 | - | ||
| 794 | - console.log(`mapping box ${this.selectingIndex} with field "${item.field}" item.isManual: ${item.isManual}`); | ||
| 795 | if (item.isManual) { | 683 | if (item.isManual) { |
| 796 | // Nếu là manual box, chuyển sang chế độ manual mapping | 684 | // Nếu là manual box, chuyển sang chế độ manual mapping |
| 797 | this.manualIndex = this.selectingIndex; | 685 | this.manualIndex = this.selectingIndex; |
| ... | @@ -802,12 +690,9 @@ | ... | @@ -802,12 +690,9 @@ |
| 802 | 690 | ||
| 803 | // Xử lý box OCR (có thể chưa có field hoặc đã có field) | 691 | // Xử lý box OCR (có thể chưa có field hoặc đã có field) |
| 804 | if (item.field) { | 692 | if (item.field) { |
| 805 | - // Nếu box đã có field, cập nhật lại | 693 | + |
| 806 | - const oldField = item.field; | ||
| 807 | - console.log(`Updating box OCR at index ${this.selectingIndex} from field "${oldField}" to "${item.field}" "${item.bbox}"`); | ||
| 808 | // Cập nhật formData để hiển thị trong input | 694 | // Cập nhật formData để hiển thị trong input |
| 809 | this.formData[item.field] = item.text || ''; | 695 | this.formData[item.field] = item.text || ''; |
| 810 | - | ||
| 811 | // Cập nhật manualBoxData với tọa độ mới (box OCR không có nút xóa) | 696 | // Cập nhật manualBoxData với tọa độ mới (box OCR không có nút xóa) |
| 812 | this.manualBoxData[item.field] = { | 697 | this.manualBoxData[item.field] = { |
| 813 | coords: item.bbox, | 698 | coords: item.bbox, |
| ... | @@ -819,8 +704,6 @@ | ... | @@ -819,8 +704,6 @@ |
| 819 | if (this.dataMapping && this.dataMapping[item.field]) { | 704 | if (this.dataMapping && this.dataMapping[item.field]) { |
| 820 | delete this.dataMapping[item.field]; | 705 | delete this.dataMapping[item.field]; |
| 821 | } | 706 | } |
| 822 | - | ||
| 823 | - // Set active index | ||
| 824 | this.activeIndex = this.selectingIndex; | 707 | this.activeIndex = this.selectingIndex; |
| 825 | } | 708 | } |
| 826 | 709 | ||
| ... | @@ -871,13 +754,8 @@ | ... | @@ -871,13 +754,8 @@ |
| 871 | 754 | ||
| 872 | const finalText = combinedText.join(" "); | 755 | const finalText = combinedText.join(" "); |
| 873 | 756 | ||
| 874 | - // Gán field trực tiếp cho box manual | ||
| 875 | this.ocrData[manualIndex].field = this.manualField; | 757 | this.ocrData[manualIndex].field = this.manualField; |
| 876 | - | ||
| 877 | - // Cập nhật formData để hiển thị trong input | ||
| 878 | this.formData[this.manualField] = finalText.trim(); | 758 | this.formData[this.manualField] = finalText.trim(); |
| 879 | - | ||
| 880 | - // Cập nhật manualBoxData (box quét chọn có nút xóa) | ||
| 881 | this.manualBoxData[this.manualField] = { | 759 | this.manualBoxData[this.manualField] = { |
| 882 | coords: newBbox, | 760 | coords: newBbox, |
| 883 | text: finalText.trim(), | 761 | text: finalText.trim(), |
| ... | @@ -926,11 +804,7 @@ | ... | @@ -926,11 +804,7 @@ |
| 926 | getPartialText(text, bbox, selectBbox) { | 804 | getPartialText(text, bbox, selectBbox) { |
| 927 | const [x1, y1, x2, y2] = bbox; | 805 | const [x1, y1, x2, y2] = bbox; |
| 928 | const [sx1, sy1, sx2, sy2] = selectBbox; | 806 | const [sx1, sy1, sx2, sy2] = selectBbox; |
| 929 | - // Chiều rộng box OCR | ||
| 930 | const boxWidth = x2 - x1; | 807 | const boxWidth = x2 - x1; |
| 931 | - const boxHeight = y2 - y1; | ||
| 932 | - | ||
| 933 | - // Vị trí start và end tương đối trong text | ||
| 934 | let startRatio = Math.max(0, (sx1 - x1) / boxWidth); | 808 | let startRatio = Math.max(0, (sx1 - x1) / boxWidth); |
| 935 | let endRatio = Math.min(1, (sx2 - x1) / boxWidth); | 809 | let endRatio = Math.min(1, (sx2 - x1) / boxWidth); |
| 936 | 810 | ||
| ... | @@ -982,8 +856,6 @@ | ... | @@ -982,8 +856,6 @@ |
| 982 | 856 | ||
| 983 | // Xóa box cũ có cùng fieldName trước khi tạo mới (chỉ xóa manual box) | 857 | // Xóa box cũ có cùng fieldName trước khi tạo mới (chỉ xóa manual box) |
| 984 | this.ocrData = this.ocrData.filter(box => !(box.field === fieldName && box.isManual)); | 858 | this.ocrData = this.ocrData.filter(box => !(box.field === fieldName && box.isManual)); |
| 985 | - | ||
| 986 | - // Tạo box manual từ DB (không có nút xóa) | ||
| 987 | const manualBox = { | 859 | const manualBox = { |
| 988 | text: text || '', | 860 | text: text || '', |
| 989 | bbox: coords, | 861 | bbox: coords, |
| ... | @@ -1045,8 +917,6 @@ | ... | @@ -1045,8 +917,6 @@ |
| 1045 | }; | 917 | }; |
| 1046 | 918 | ||
| 1047 | this.ocrData.push(manualBox); | 919 | this.ocrData.push(manualBox); |
| 1048 | - console.log(`Manual box shown successfully: ${isFromOCR ? 'from OCR (no delete btn)' : 'from manual selection (with delete btn)'}`); | ||
| 1049 | - | ||
| 1050 | // Force re-render | 920 | // Force re-render |
| 1051 | this.$forceUpdate(); | 921 | this.$forceUpdate(); |
| 1052 | } else { | 922 | } else { | ... | ... |
-
Please register or sign in to post a comment