From 65685d1a6a108290bb352570ff40b4ca8bdee4ad Mon Sep 17 00:00:00 2001 From: ZhangAo Date: Mon, 8 Jun 2026 17:31:29 +0800 Subject: [PATCH] 20260608173128 --- bgd/PP-StructureV3.yaml | 235 ++++++++++++++++++ bgd/{ => file}/11.pdf | Bin bgd/{ => file}/22-1.pdf | Bin bgd/{ => file}/33-1.pdf | Bin bgd/{ => file}/44-1.pdf | Bin bgd/{ => file}/55-1.pdf | Bin bgd/{ => file}/66-1.pdf | Bin bgd/{ => file}/77-1.pdf | Bin bgd/{ => file}/990400报.pdf | Bin .../EGLV072100006229-裕锦出库报关单.pdf | Bin bgd/{ => file}/HDMUCGPA26415100报.pdf | Bin bgd/{ => file}/I20210000769540727.pdf | Bin bgd/{ => file}/I20210000769558253.pdf | Bin bgd/{ => file}/I20220000786622159.pdf | Bin bgd/{ => file}/bgd-01.pdf | Bin bgd/{ => file}/bgd-02.pdf | Bin bgd/{ => file}/bgd-03.pdf | Bin bgd/{ => file}/bgd-04.pdf | Bin bgd/{ => file}/bgd-05.pdf | Bin bgd/{ => file}/bgd-06.pdf | Bin bgd/{ => file}/bgd-07.pdf | Bin bgd/{ => file}/bgd.pdf | Bin bgd/{ => file}/报关单.pdf | Bin .../exception/GlobalExceptionHandler.java | 8 +- .../src/main/resources/application.yml | 2 +- .../main/resources/dbconfigs/g3hd.properties | 14 +- .../ocr-uniapp/src/pages-sub/upload/index.vue | 55 +++- demo.txt | 33 --- test.xlsx | Bin 10566 -> 0 bytes 29 files changed, 289 insertions(+), 58 deletions(-) create mode 100644 bgd/PP-StructureV3.yaml rename bgd/{ => file}/11.pdf (100%) rename bgd/{ => file}/22-1.pdf (100%) rename bgd/{ => file}/33-1.pdf (100%) rename bgd/{ => file}/44-1.pdf (100%) rename bgd/{ => file}/55-1.pdf (100%) rename bgd/{ => file}/66-1.pdf (100%) rename bgd/{ => file}/77-1.pdf (100%) rename bgd/{ => file}/990400报.pdf (100%) rename bgd/{ => file}/EGLV072100006229-裕锦出库报关单.pdf (100%) rename bgd/{ => file}/HDMUCGPA26415100报.pdf (100%) rename bgd/{ => file}/I20210000769540727.pdf (100%) rename bgd/{ => file}/I20210000769558253.pdf (100%) rename bgd/{ => file}/I20220000786622159.pdf (100%) rename bgd/{ => file}/bgd-01.pdf (100%) rename bgd/{ => file}/bgd-02.pdf (100%) rename bgd/{ => file}/bgd-03.pdf (100%) rename bgd/{ => file}/bgd-04.pdf (100%) rename bgd/{ => file}/bgd-05.pdf (100%) rename bgd/{ => file}/bgd-06.pdf (100%) rename bgd/{ => file}/bgd-07.pdf (100%) rename bgd/{ => file}/bgd.pdf (100%) rename bgd/{ => file}/报关单.pdf (100%) delete mode 100644 demo.txt delete mode 100644 test.xlsx diff --git a/bgd/PP-StructureV3.yaml b/bgd/PP-StructureV3.yaml new file mode 100644 index 00000000..62278e98 --- /dev/null +++ b/bgd/PP-StructureV3.yaml @@ -0,0 +1,235 @@ + +pipeline_name: PP-StructureV3 + +batch_size: 8 + +use_doc_preprocessor: False +use_seal_recognition: False +use_table_recognition: True +use_formula_recognition: True +use_chart_recognition: False +use_region_detection: True +format_block_content: False +markdown_ignore_labels: + - number + - footnote + - header + - header_image + - footer + - footer_image + - aside_text + +SubModules: + LayoutDetection: + module_name: layout_detection + model_name: PP-DocLayout_plus-L + model_dir: null + batch_size: 8 + threshold: + 0: 0.3 # paragraph_title + 1: 0.5 # image + 2: 0.4 # text + 3: 0.5 # number + 4: 0.5 # abstract + 5: 0.5 # content + 6: 0.5 # figure_table_chart_title + 7: 0.3 # formula + 8: 0.5 # table + 9: 0.5 # reference + 10: 0.5 # doc_title + 11: 0.5 # footnote + 12: 0.5 # header + 13: 0.5 # algorithm + 14: 0.5 # footer + 15: 0.45 # seal + 16: 0.5 # chart + 17: 0.5 # formula_number + 18: 0.5 # aside_text + 19: 0.5 # reference_content + layout_nms: True + layout_unclip_ratio: [1.0, 1.0] + layout_merge_bboxes_mode: + 0: "large" # paragraph_title + 1: "large" # image + 2: "union" # text + 3: "union" # number + 4: "union" # abstract + 5: "union" # content + 6: "union" # figure_table_chart_title + 7: "large" # formula + 8: "union" # table + 9: "union" # reference + 10: "union" # doc_title + 11: "union" # footnote + 12: "union" # header + 13: "union" # algorithm + 14: "union" # footer + 15: "union" # seal + 16: "large" # chart + 17: "union" # formula_number + 18: "union" # aside_text + 19: "union" # reference_content + ChartRecognition: + module_name: chart_recognition + model_name: PP-Chart2Table + model_dir: null + batch_size: 1 + RegionDetection: + module_name: layout_detection + model_name: PP-DocBlockLayout + model_dir: null + layout_nms: True + layout_merge_bboxes_mode: "small" + +SubPipelines: + DocPreprocessor: + pipeline_name: doc_preprocessor + batch_size: 8 + use_doc_orientation_classify: True + use_doc_unwarping: True + SubModules: + DocOrientationClassify: + module_name: doc_text_orientation + model_name: PP-LCNet_x1_0_doc_ori + model_dir: null + batch_size: 8 + DocUnwarping: + module_name: image_unwarping + model_name: UVDoc + model_dir: null + + GeneralOCR: + pipeline_name: OCR + batch_size: 8 + text_type: general + use_doc_preprocessor: False + use_textline_orientation: True + SubModules: + TextDetection: + module_name: text_detection + model_name: PP-OCRv5_server_det + model_dir: null + limit_side_len: 736 + limit_type: min + max_side_limit: 4000 + thresh: 0.3 + box_thresh: 0.6 + unclip_ratio: 1.5 + TextLineOrientation: + module_name: textline_orientation + model_name: PP-LCNet_x1_0_textline_ori + model_dir: null + batch_size: 8 + TextRecognition: + module_name: text_recognition + model_name: PP-OCRv5_server_rec + model_dir: null + batch_size: 8 + score_thresh: 0.0 + + + TableRecognition: + pipeline_name: table_recognition_v2 + use_layout_detection: False + use_doc_preprocessor: False + use_ocr_model: False + SubModules: + TableClassification: + module_name: table_classification + model_name: PP-LCNet_x1_0_table_cls + model_dir: null + + WiredTableStructureRecognition: + module_name: table_structure_recognition + model_name: SLANeXt_wired + model_dir: null + + WirelessTableStructureRecognition: + module_name: table_structure_recognition + model_name: SLANet_plus + model_dir: null + + WiredTableCellsDetection: + module_name: table_cells_detection + model_name: RT-DETR-L_wired_table_cell_det + model_dir: null + + WirelessTableCellsDetection: + module_name: table_cells_detection + model_name: RT-DETR-L_wireless_table_cell_det + model_dir: null + + TableOrientationClassify: + module_name: doc_text_orientation + model_name: PP-LCNet_x1_0_doc_ori + model_dir: null + SubPipelines: + GeneralOCR: + pipeline_name: OCR + text_type: general + use_doc_preprocessor: False + use_textline_orientation: True + SubModules: + TextDetection: + module_name: text_detection + model_name: PP-OCRv5_server_det + model_dir: null + limit_side_len: 736 + limit_type: min + max_side_limit: 4000 + thresh: 0.3 + box_thresh: 0.4 + unclip_ratio: 1.5 + TextLineOrientation: + module_name: textline_orientation + model_name: PP-LCNet_x1_0_textline_ori + model_dir: null + batch_size: 8 + TextRecognition: + module_name: text_recognition + model_name: PP-OCRv5_server_rec + model_dir: null + batch_size: 8 + score_thresh: 0.0 + + SealRecognition: + pipeline_name: seal_recognition + batch_size: 8 + use_layout_detection: False + use_doc_preprocessor: False + SubPipelines: + SealOCR: + pipeline_name: OCR + batch_size: 8 + text_type: seal + use_doc_preprocessor: False + use_textline_orientation: False + SubModules: + TextDetection: + module_name: seal_text_detection + model_name: PP-OCRv4_server_seal_det + model_dir: null + limit_side_len: 736 + limit_type: min + max_side_limit: 4000 + thresh: 0.2 + box_thresh: 0.6 + unclip_ratio: 0.5 + TextRecognition: + module_name: text_recognition + model_name: PP-OCRv5_server_rec + model_dir: null + batch_size: 8 + score_thresh: 0 + + FormulaRecognition: + pipeline_name: formula_recognition + batch_size: 8 + use_layout_detection: False + use_doc_preprocessor: False + SubModules: + FormulaRecognition: + module_name: formula_recognition + model_name: PP-FormulaNet_plus-L + model_dir: null + batch_size: 8 diff --git a/bgd/11.pdf b/bgd/file/11.pdf similarity index 100% rename from bgd/11.pdf rename to bgd/file/11.pdf diff --git a/bgd/22-1.pdf b/bgd/file/22-1.pdf similarity index 100% rename from bgd/22-1.pdf rename to bgd/file/22-1.pdf diff --git a/bgd/33-1.pdf b/bgd/file/33-1.pdf similarity index 100% rename from bgd/33-1.pdf rename to bgd/file/33-1.pdf diff --git a/bgd/44-1.pdf b/bgd/file/44-1.pdf similarity index 100% rename from bgd/44-1.pdf rename to bgd/file/44-1.pdf diff --git a/bgd/55-1.pdf b/bgd/file/55-1.pdf similarity index 100% rename from bgd/55-1.pdf rename to bgd/file/55-1.pdf diff --git a/bgd/66-1.pdf b/bgd/file/66-1.pdf similarity index 100% rename from bgd/66-1.pdf rename to bgd/file/66-1.pdf diff --git a/bgd/77-1.pdf b/bgd/file/77-1.pdf similarity index 100% rename from bgd/77-1.pdf rename to bgd/file/77-1.pdf diff --git a/bgd/990400报.pdf b/bgd/file/990400报.pdf similarity index 100% rename from bgd/990400报.pdf rename to bgd/file/990400报.pdf diff --git a/bgd/EGLV072100006229-裕锦出库报关单.pdf b/bgd/file/EGLV072100006229-裕锦出库报关单.pdf similarity index 100% rename from bgd/EGLV072100006229-裕锦出库报关单.pdf rename to bgd/file/EGLV072100006229-裕锦出库报关单.pdf diff --git a/bgd/HDMUCGPA26415100报.pdf b/bgd/file/HDMUCGPA26415100报.pdf similarity index 100% rename from bgd/HDMUCGPA26415100报.pdf rename to bgd/file/HDMUCGPA26415100报.pdf diff --git a/bgd/I20210000769540727.pdf b/bgd/file/I20210000769540727.pdf similarity index 100% rename from bgd/I20210000769540727.pdf rename to bgd/file/I20210000769540727.pdf diff --git a/bgd/I20210000769558253.pdf b/bgd/file/I20210000769558253.pdf similarity index 100% rename from bgd/I20210000769558253.pdf rename to bgd/file/I20210000769558253.pdf diff --git a/bgd/I20220000786622159.pdf b/bgd/file/I20220000786622159.pdf similarity index 100% rename from bgd/I20220000786622159.pdf rename to bgd/file/I20220000786622159.pdf diff --git a/bgd/bgd-01.pdf b/bgd/file/bgd-01.pdf similarity index 100% rename from bgd/bgd-01.pdf rename to bgd/file/bgd-01.pdf diff --git a/bgd/bgd-02.pdf b/bgd/file/bgd-02.pdf similarity index 100% rename from bgd/bgd-02.pdf rename to bgd/file/bgd-02.pdf diff --git a/bgd/bgd-03.pdf b/bgd/file/bgd-03.pdf similarity index 100% rename from bgd/bgd-03.pdf rename to bgd/file/bgd-03.pdf diff --git a/bgd/bgd-04.pdf b/bgd/file/bgd-04.pdf similarity index 100% rename from bgd/bgd-04.pdf rename to bgd/file/bgd-04.pdf diff --git a/bgd/bgd-05.pdf b/bgd/file/bgd-05.pdf similarity index 100% rename from bgd/bgd-05.pdf rename to bgd/file/bgd-05.pdf diff --git a/bgd/bgd-06.pdf b/bgd/file/bgd-06.pdf similarity index 100% rename from bgd/bgd-06.pdf rename to bgd/file/bgd-06.pdf diff --git a/bgd/bgd-07.pdf b/bgd/file/bgd-07.pdf similarity index 100% rename from bgd/bgd-07.pdf rename to bgd/file/bgd-07.pdf diff --git a/bgd/bgd.pdf b/bgd/file/bgd.pdf similarity index 100% rename from bgd/bgd.pdf rename to bgd/file/bgd.pdf diff --git a/bgd/报关单.pdf b/bgd/file/报关单.pdf similarity index 100% rename from bgd/报关单.pdf rename to bgd/file/报关单.pdf diff --git a/code/container-ocr/ocr-springboot/src/main/java/cn/g3soft/exception/GlobalExceptionHandler.java b/code/container-ocr/ocr-springboot/src/main/java/cn/g3soft/exception/GlobalExceptionHandler.java index bdfb5f97..e9a92755 100644 --- a/code/container-ocr/ocr-springboot/src/main/java/cn/g3soft/exception/GlobalExceptionHandler.java +++ b/code/container-ocr/ocr-springboot/src/main/java/cn/g3soft/exception/GlobalExceptionHandler.java @@ -15,13 +15,7 @@ public class GlobalExceptionHandler { public Result handleException(Exception ex, HttpServletRequest request) { ExceptionDetailInfo info = ExceptionUtils.extractExceptionInfo(ex, request, "cn.g3soft"); - log.error("异常发生在 {}#{}({}:{}),ID: {},信息: {}", - info.getClassName(), - info.getMethodName(), - info.getFileName(), - info.getLineNumber(), - info.getId(), - info.getSummary()); + log.error("系统异常: {}", info); ex.printStackTrace(); diff --git a/code/container-ocr/ocr-springboot/src/main/resources/application.yml b/code/container-ocr/ocr-springboot/src/main/resources/application.yml index 38dff4da..0e5ca111 100644 --- a/code/container-ocr/ocr-springboot/src/main/resources/application.yml +++ b/code/container-ocr/ocr-springboot/src/main/resources/application.yml @@ -16,7 +16,7 @@ spring: time-zone: "Asia/Shanghai" date-format: yyyy-MM-dd HH:mm:ss profiles: - active: dev + active: build file: base-dir: D:/data/file diff --git a/code/container-ocr/ocr-springboot/src/main/resources/dbconfigs/g3hd.properties b/code/container-ocr/ocr-springboot/src/main/resources/dbconfigs/g3hd.properties index 8d6733ef..05bead7b 100644 --- a/code/container-ocr/ocr-springboot/src/main/resources/dbconfigs/g3hd.properties +++ b/code/container-ocr/ocr-springboot/src/main/resources/dbconfigs/g3hd.properties @@ -1,10 +1,10 @@ -url=jdbc:sqlserver://118.89.70.199:1433;databaseName=G3BoxOCR -username=sa -password=zhang520.. -driver=com.microsoft.sqlserver.jdbc.SQLServerDriver - -#url=jdbc:sqlserver://127.0.0.1:1433;databaseName=G3ContainerOCR +#url=jdbc:sqlserver://118.89.70.199:1433;databaseName=G3BoxOCR #username=sa -#password=123456@aaa +#password=zhang520.. #driver=com.microsoft.sqlserver.jdbc.SQLServerDriver +url=jdbc:sqlserver://127.0.0.1:1433;databaseName=G3ContainerOCR +username=sa +password=123456@aaa +driver=com.microsoft.sqlserver.jdbc.SQLServerDriver + diff --git a/code/container-ocr/ocr-uniapp/src/pages-sub/upload/index.vue b/code/container-ocr/ocr-uniapp/src/pages-sub/upload/index.vue index 7212ebf9..692d0e74 100644 --- a/code/container-ocr/ocr-uniapp/src/pages-sub/upload/index.vue +++ b/code/container-ocr/ocr-uniapp/src/pages-sub/upload/index.vue @@ -28,18 +28,30 @@ const subFileList2 = ref([]) // 发货单、签收单、过磅单 const tipContainerNo = ref('') +const initialized = ref(false) + onLoad(async () => { toast.loading('正在初始化中...', { overlay: true, }) - await getUniqueIdApi().then((res) => { + try { + const res = await getUniqueIdApi() if (res.success) { form.value.b_id = res.data + initialized.value = true } - }) - - toast.hide() + else { + toast.fail('初始化失败,请重试') + } + } + catch (err) { + console.error('初始化失败:', err) + toast.fail('初始化失败,请重试') + } + finally { + toast.hide() + } }) function handleBeforeChoose({ fileList, resolve }) { @@ -156,6 +168,11 @@ function handleBeforeRemove({ file, fileList, resolve }) { } async function handleConfirm() { + if (!initialized.value) { + toast.fail('系统初始化未完成,请重试') + return + } + if (!boxImage.value) { toast.fail('集装箱号图片不能为空') return @@ -348,12 +365,31 @@ function validateContainerNo(containerNo) { } async function continueAdd() { - const idRes = await getUniqueIdApi() + initialized.value = false - if (idRes.success) { - resetForm() - form.value.b_id = idRes.data - tipContainerNo.value = '' + toast.loading('正在初始化中...', { + overlay: true, + }) + + try { + const idRes = await getUniqueIdApi() + + if (idRes.success) { + resetForm() + form.value.b_id = idRes.data + tipContainerNo.value = '' + initialized.value = true + } + else { + toast.fail('初始化失败,请重试') + } + } + catch (err) { + console.error('初始化失败:', err) + toast.fail('初始化失败,请重试') + } + finally { + toast.hide() } } @@ -509,7 +545,6 @@ const templateCollapse = ref(['template1']) multiple :accept="fileMode" :max-size="50 * 1024 * 1024" - :before-choose="handleBeforeChoose" /> diff --git a/demo.txt b/demo.txt deleted file mode 100644 index 22a9624f..00000000 --- a/demo.txt +++ /dev/null @@ -1,33 +0,0 @@ -配置一: -CPU:270KPlus -散热:华硕升旗360 -主板:华硕z890pwifi -内存:芝奇幻锋戟 16*2 6800 adie -硬盘:TIPlus 7100 1TB -显卡:华硕prime5070ti -电源:华硕TUF850W -机箱风扇:普通的海景房+风扇 -合计:15299元 - -配置二: -CPU:270KPlus -散热:钛担SJ-A080360黑色一体式CPU水冷散热器 -主板:华硕z890pwifi -内存:宏碁掠夺者冰刃16*2 DDR5 8000频率C36 RGB灯条 -硬盘:宏碁掠夺者GM71TB PCIE4.0 TLC颗粒 -显卡:华硕prime5070ti -电源:先马GT850850W金牌模组ATX3黑色 -机箱风扇:普通的海景房+风扇 -合计:8076元 + 显卡(抖音买可能7000元)= 15076元 - -配置三: -CPU:270KPlus -散热:瓦尔基里B360-GT三排ARGB黑色一体式水冷3.95吋IPS液晶屏 -主板:华硕z890pwifi -内存:金百达刃C3232GDDR56800灯条16G*2根海力士A代 -硬盘:雷克沙ARES战神M.21TB读速7400MB/S TLC颗粒 -显卡:华硕prime5070ti -电源:华硕TUF850W -机箱风扇:乔思伯X400深空灰海景房+钛游FM360三联排风扇*2套FM240双联排风扇*1套 -合计:8049元 + 显卡(抖音买可能7000元)= 15049元 - diff --git a/test.xlsx b/test.xlsx deleted file mode 100644 index 0955481514d333d4153630ddbb7b677e363b1f8b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10566 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

pc7NDyqq%1WV} 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 a=>EkYQjv%G<*XP_)I7K+IeO}6z5fTdiclv2