From 1d12b3f52986971885cea133f4a4137aed123e19 Mon Sep 17 00:00:00 2001 From: dev <710328466@qq.com> Date: Tue, 16 Jan 2024 11:44:26 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=88=9D=E5=A7=8B=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .dumi/loading.tsx | 5 + .dumi/tsconfig.json | 4 + .dumirc.ts | 5 +- .stylelintrc | 5 +- .vscode/settings.json | 3 + docs/index.md | 39 +- packages/biz/CHANGELOG.md | 13 + .../biz/es/BigImageModal/BigImageModal.d.ts | 23 + .../BigImageModal.js} | 286 ++- .../components/navigation/index.d.ts | 13 + packages/biz/es/BigImageModal/index.d.ts | 3 + packages/biz/es/BigImageModal/index.js | 151 +- packages/biz/es/BigImageModal/index.less | 381 +--- packages/biz/es/BigImageModal/index.temp.js | 789 -------- packages/biz/es/BigImageModal/mock.d.ts | 294 +++ packages/biz/es/Demo/index.d.ts | 3 + .../adapter/BigImageModalAdapter/index.d.ts | 153 ++ .../BigImageModalAdapter/interface.d.ts | 217 --- packages/biz/es/adapter/index.d.ts | 1 + .../hooks/useIntelligentTracking/index.d.ts | 45 + packages/biz/es/index.d.ts | 3 + packages/biz/es/useSocket/index.d.ts | 26 + packages/biz/es/useSocket/onceChannel.d.ts | 2 + packages/biz/es/useSocket/ws.d.ts | 31 + packages/biz/es/useSocket/ws.js | 1 + packages/biz/es/utils/constants.d.ts | 23 + packages/biz/es/utils/constants.js | 10 - .../biz/es/{global.d.ts => utils/index.d.ts} | 0 .../biz/lib/BigImageModal/BigImageModal.d.ts | 23 + .../biz/lib/BigImageModal/BigImageModal.js | 169 ++ .../components/navigation/index.d.ts | 13 + .../components/navigation/index.js | 58 + .../components/navigation/index.less | 44 + .../lib/BigImageModal}/images/emptyImage.png | Bin .../images/percent_background.png | Bin packages/biz/lib/BigImageModal/index.d.ts | 3 + packages/biz/lib/BigImageModal/index.js | 36 + packages/biz/lib/BigImageModal/index.less | 770 ++++++++ packages/biz/lib/BigImageModal/mock.d.ts | 294 +++ packages/biz/lib/BigImageModal/mock.js | 930 +++++++++ packages/biz/lib/Demo/index.d.ts | 3 + packages/biz/lib/Demo/index.js | 41 + .../adapter/BigImageModalAdapter/index.d.ts | 153 ++ .../lib/adapter/BigImageModalAdapter/index.js | 28 + packages/biz/lib/adapter/index.d.ts | 1 + packages/biz/lib/adapter/index.js | 39 + .../hooks/useIntelligentTracking/index.d.ts | 45 + .../lib/hooks/useIntelligentTracking/index.js | 371 ++++ packages/biz/lib/index.d.ts | 3 + packages/biz/lib/index.js | 45 + packages/biz/lib/useSocket/index.d.ts | 26 + packages/biz/lib/useSocket/index.js | 120 ++ packages/biz/lib/useSocket/onceChannel.d.ts | 2 + packages/biz/lib/useSocket/onceChannel.js | 51 + packages/biz/lib/useSocket/ws.d.ts | 31 + packages/biz/lib/useSocket/ws.js | 224 +++ packages/biz/lib/utils/constants.d.ts | 23 + packages/biz/lib/utils/constants.js | 80 + .../lib/utils/index.d.ts} | 0 .../constants.js => biz/lib/utils/index.js} | 0 packages/biz/package.json | 6 +- .../biz/src/BigImageModal/BigImageModal.tsx | 162 ++ packages/biz/src/BigImageModal/index.temp.tsx | 696 ------- packages/biz/src/BigImageModal/index.tsx | 161 +- packages/biz/src/hooks/useTaskState/index.ts | 103 - packages/biz/src/utils/constants.ts | 1 - packages/biz/src/utils/request.ts | 77 - packages/constants/CHANGELOG.md | 6 + packages/constants/package.json | 5 +- packages/constants/src/index.tsx | 1 + packages/constants/src/user/index.ts | 1 + packages/func/CHANGELOG.md | 11 + packages/func/es/camera/constants.d.ts | 41 + packages/func/es/camera/index.d.ts | 40 + packages/func/es/file/index.d.ts | 75 + packages/func/es/file/index.js | 61 +- packages/func/es/index.d.ts | 11 + packages/func/es/index.js | 3 +- packages/func/es/map/index.d.ts | 10 + packages/func/es/math/index.d.ts | 70 + packages/func/es/math/index.js | 63 +- packages/func/es/number/index.d.ts | 14 + packages/func/es/number/index.js | 11 + packages/func/es/performance/index.d.ts | 1 + packages/func/es/string/index.d.ts | 7 + packages/func/es/time/index.d.ts | 11 + packages/func/es/time/index.js | 11 + packages/func/es/upload/index.d.ts | 8 + packages/func/es/upload/index.js | 4 +- packages/func/es/utils/index.d.ts | 36 + packages/func/es/utils/index.js | 2 +- packages/func/es/utils/isChrome.d.ts | 3 + packages/func/es/utils/isChrome.js | 4 +- packages/func/lib/camera/constants.d.ts | 41 + packages/func/lib/camera/constants.js | 90 + packages/func/lib/camera/index.d.ts | 40 + packages/func/lib/camera/index.js | 143 ++ packages/func/lib/file/index.d.ts | 75 + packages/func/lib/file/index.js | 318 ++++ packages/func/lib/index.d.ts | 11 + packages/func/lib/index.js | 43 + packages/func/lib/map/index.d.ts | 10 + packages/func/lib/map/index.js | 54 + packages/func/lib/math/index.d.ts | 70 + packages/func/lib/math/index.js | 358 ++++ packages/func/lib/number/index.d.ts | 14 + packages/func/lib/number/index.js | 53 + packages/func/lib/performance/index.d.ts | 1 + packages/func/lib/performance/index.js | 41 + packages/func/lib/string/index.d.ts | 7 + packages/func/lib/string/index.js | 62 + packages/func/lib/time/index.d.ts | 11 + packages/func/lib/time/index.js | 73 + packages/func/lib/upload/index.d.ts | 8 + packages/func/lib/upload/index.js | 90 + packages/func/lib/utils/index.d.ts | 36 + packages/func/lib/utils/index.js | 171 ++ packages/func/lib/utils/isChrome.d.ts | 3 + packages/func/lib/utils/isChrome.js | 42 + packages/func/package.json | 2 +- packages/func/src/file/index.ts | 6 +- packages/func/src/math/index.ts | 91 +- packages/func/src/upload/index.ts | 1 + packages/func/src/utils/isChrome.ts | 8 +- packages/hooks/CHANGELOG.md | 11 + packages/hooks/package.json | 2 +- packages/material/CHANGELOG.md | 14 + packages/material/README.md | 10 +- packages/material/es/Demo/index.d.ts | 3 + packages/material/es/Demo/index.js | 4 + packages/material/es/index.d.ts | 1 + packages/material/es/index.js | 1 + packages/material/lib/Demo/index.d.ts | 3 + packages/material/lib/Demo/index.js | 38 + packages/material/lib/index.d.ts | 1 + packages/material/lib/index.js | 39 + packages/material/package.json | 2 +- packages/material/src/Demo/index.tsx | 6 +- packages/meta/CHANGELOG.md | 12 + .../es/BigImagePreview/BigImagePreview.d.ts | 35 + .../es/BigImagePreview/BigImagePreview.js | 578 ++++++ .../bigImagePreviewHelper.d.ts} | 0 .../BigImagePreview/bigImagePreviewHelper.js} | 0 .../components/BtnGroup/index.d.ts | 17 + .../components/BtnGroup/index.js | 42 + .../components/BtnGroup/index.less | 51 + .../components/ScreenhotButtons/index.d.ts | 14 + .../components/ScreenhotButtons/index.js} | 233 +-- .../components/ScreenhotButtons/index.less | 21 + packages/meta/es/BigImagePreview/index.d.ts | 3 + packages/meta/es/BigImagePreview/index.js | 2 + packages/meta/es/BigImagePreview/index.less | 123 ++ .../meta/es/CompareImage/CompareImage.d.ts | 20 + .../index.js => CompareImage/CompareImage.js} | 134 +- .../components/CornerScore/index.d.ts | 0 .../components/CornerScore/index.js | 0 .../components/CornerScore/index.less | 3 +- .../CompareImage}/images/emptyImage.png | Bin .../images/percent_background.png | Bin packages/meta/es/CompareImage/index.d.ts | 3 + packages/meta/es/CompareImage/index.js | 2 + .../CompareImage}/index.less | 0 packages/meta/es/ImageEditor/cropper/event.js | 8 +- .../es/ImageEditor/cropper/viewerBridge.js | 6 +- packages/meta/es/ImageEditor/viewer/event.js | 18 +- packages/meta/es/ImagePreview/index.d.ts | 12 - packages/meta/es/VideoPlayer/VideoPlayer.d.ts | 18 + packages/meta/es/VideoPlayer/VideoPlayer.js | 679 +++++++ .../components/FlvPlayer/index.d.ts | 46 + .../VideoPlayer/components/FlvPlayer/index.js | 152 ++ .../VideoPlayer/components/Loading/index.d.ts | 8 + .../VideoPlayer/components/Loading/index.js | 46 + .../VideoPlayer/components/Loading/index.less | 53 + .../components/Progress/index.d.ts | 10 + .../VideoPlayer/components/Progress/index.js | 20 + .../components/Progress/index.less | 49 + packages/meta/es/VideoPlayer/index.d.ts | 3 + packages/meta/es/VideoPlayer/index.js | 2 + packages/meta/es/VideoPlayer/index.less | 75 + .../es/VideoPlayer/videoPlayerHelper.d.ts | 1 + .../meta/es/VideoPlayer/videoPlayerHelper.js | 13 + packages/meta/es/iconfont/iconfont.css | 1679 +++++++++++++++++ packages/meta/es/iconfont/iconfont.js | 43 + packages/meta/es/iconfont/iconfont.ttf | Bin 0 -> 105116 bytes packages/meta/es/iconfont/iconfont.woff | Bin 0 -> 58376 bytes packages/meta/es/iconfont/iconfont.woff2 | Bin 0 -> 48900 bytes packages/meta/es/iconfont/index.d.ts | 1 + packages/meta/es/iconfont/index.js | 1 + packages/meta/es/index.d.ts | 4 +- packages/meta/es/index.js | 4 +- packages/meta/es/utils/constants.d.ts | 12 + packages/meta/es/utils/constants.js | 12 + .../lib/BigImagePreview/BigImagePreview.d.ts | 35 + .../lib/BigImagePreview/BigImagePreview.js | 487 +++++ .../bigImagePreviewHelper.d.ts} | 0 .../bigImagePreviewHelper.js} | 0 .../components/BtnGroup/index.d.ts | 17 + .../components/BtnGroup/index.js | 83 + .../components/BtnGroup/index.less | 51 + .../components/ScreenhotButtons/index.d.ts | 14 + .../components/ScreenhotButtons/index.js | 126 ++ .../components/ScreenhotButtons/index.less | 21 + packages/meta/lib/BigImagePreview/index.d.ts | 3 + packages/meta/lib/BigImagePreview/index.js | 36 + packages/meta/lib/BigImagePreview/index.less | 123 ++ .../meta/lib/CompareImage/CompareImage.d.ts | 20 + .../index.js => CompareImage/CompareImage.js} | 91 +- .../components/CornerScore/index.d.ts | 0 .../components/CornerScore/index.js | 2 +- .../components/CornerScore/index.less | 21 + .../CompareImage}/images/emptyImage.png | Bin .../images/percent_background.png | Bin packages/meta/lib/CompareImage/index.d.ts | 3 + packages/meta/lib/CompareImage/index.js | 36 + packages/meta/lib/CompareImage/index.less | 147 ++ .../meta/lib/ImageEditor/cropper/event.js | 6 +- .../lib/ImageEditor/cropper/viewerBridge.js | 4 +- packages/meta/lib/ImageEditor/viewer/event.js | 12 +- packages/meta/lib/ImagePreview/index.d.ts | 12 - .../meta/lib/VideoPlayer/VideoPlayer.d.ts | 18 + packages/meta/lib/VideoPlayer/VideoPlayer.js | 611 ++++++ .../components/FlvPlayer/index.d.ts | 46 + .../VideoPlayer/components/FlvPlayer/index.js | 144 ++ .../VideoPlayer/components/Loading/index.d.ts | 8 + .../VideoPlayer/components/Loading/index.js | 84 + .../VideoPlayer/components/Loading/index.less | 53 + .../components/Progress/index.d.ts | 10 + .../VideoPlayer/components/Progress/index.js | 60 + .../components/Progress/index.less | 49 + packages/meta/lib/VideoPlayer/index.d.ts | 3 + packages/meta/lib/VideoPlayer/index.js | 36 + packages/meta/lib/VideoPlayer/index.less | 75 + .../lib/VideoPlayer/videoPlayerHelper.d.ts | 1 + .../meta/lib/VideoPlayer/videoPlayerHelper.js | 41 + packages/meta/lib/iconfont/iconfont.css | 1679 +++++++++++++++++ packages/meta/lib/iconfont/iconfont.js | 36 + packages/meta/lib/iconfont/iconfont.ttf | Bin 0 -> 105116 bytes packages/meta/lib/iconfont/iconfont.woff | Bin 0 -> 58376 bytes packages/meta/lib/iconfont/iconfont.woff2 | Bin 0 -> 48900 bytes packages/meta/lib/iconfont/index.d.ts | 1 + packages/meta/lib/iconfont/index.js | 1 + packages/meta/lib/index.d.ts | 4 +- packages/meta/lib/index.js | 12 +- packages/meta/lib/utils/constants.d.ts | 12 + packages/meta/lib/utils/constants.js | 42 + packages/meta/package.json | 2 +- .../src/BigImagePreview/BigImagePreview.tsx | 562 ++++++ .../BigImagePreview/bigImagePreviewHelper.ts | 0 .../components/ScreenhotButtons/index.tsx | 6 +- packages/meta/src/BigImagePreview/index.md | 161 +- packages/meta/src/BigImagePreview/index.tsx | 541 +----- .../CompareImage.tsx} | 104 +- .../components/CornerScore/index.less | 21 + .../components/CornerScore/index.tsx | 0 .../src/CompareImage/images/emptyImage.png | Bin 0 -> 5786 bytes .../images/percent_background.png | Bin 0 -> 514 bytes packages/meta/src/CompareImage/index.less | 147 ++ packages/meta/src/CompareImage/index.md | 50 + packages/meta/src/CompareImage/index.tsx | 5 + packages/meta/src/ImagePreview/index.md | 40 - packages/meta/src/VideoPlayer/VideoPlayer.tsx | 676 +++++++ .../components/FlvPlayer/index.tsx | 28 +- .../VideoPlayer/components/Loading/index.tsx | 2 +- .../VideoPlayer/components/Progress/index.tsx | 5 +- packages/meta/src/VideoPlayer/index.md | 28 +- packages/meta/src/VideoPlayer/index.tsx | 697 +------ .../meta/src/VideoPlayer/videoPlayerHelper.ts | 14 + packages/meta/src/index.md | 57 + packages/meta/src/index.tsx | 2 +- packages/meta/src/utils/constants.ts | 13 + packages/request/CHANGELOG.md | 6 + packages/request/es/index.d.ts | 32 + packages/request/es/index.js | 28 +- packages/request/lib/index.d.ts | 32 + packages/request/lib/index.js | 150 ++ packages/request/package.json | 2 +- packages/request/src/index.ts | 2 +- packages/types/CHANGELOG.md | 6 + packages/types/index.d.ts | 3 +- packages/types/package.json | 21 +- pnpm-lock.yaml | 6 - 281 files changed, 17480 insertions(+), 4592 deletions(-) create mode 100644 .dumi/loading.tsx create mode 100644 .dumi/tsconfig.json create mode 100644 packages/biz/es/BigImageModal/BigImageModal.d.ts rename packages/biz/es/{hooks/useTaskState/index.js => BigImageModal/BigImageModal.js} (67%) create mode 100644 packages/biz/es/BigImageModal/components/navigation/index.d.ts create mode 100644 packages/biz/es/BigImageModal/index.d.ts delete mode 100644 packages/biz/es/BigImageModal/index.temp.js create mode 100644 packages/biz/es/BigImageModal/mock.d.ts create mode 100644 packages/biz/es/Demo/index.d.ts create mode 100644 packages/biz/es/adapter/BigImageModalAdapter/index.d.ts delete mode 100644 packages/biz/es/adapter/BigImageModalAdapter/interface.d.ts create mode 100644 packages/biz/es/adapter/index.d.ts create mode 100644 packages/biz/es/hooks/useIntelligentTracking/index.d.ts create mode 100644 packages/biz/es/index.d.ts create mode 100644 packages/biz/es/useSocket/index.d.ts create mode 100644 packages/biz/es/useSocket/onceChannel.d.ts create mode 100644 packages/biz/es/useSocket/ws.d.ts create mode 100644 packages/biz/es/utils/constants.d.ts rename packages/biz/es/{global.d.ts => utils/index.d.ts} (100%) create mode 100644 packages/biz/lib/BigImageModal/BigImageModal.d.ts create mode 100644 packages/biz/lib/BigImageModal/BigImageModal.js create mode 100644 packages/biz/lib/BigImageModal/components/navigation/index.d.ts create mode 100644 packages/biz/lib/BigImageModal/components/navigation/index.js create mode 100644 packages/biz/lib/BigImageModal/components/navigation/index.less rename packages/{meta/es/ImagePreview => biz/lib/BigImageModal}/images/emptyImage.png (100%) rename packages/{meta/es/ImagePreview => biz/lib/BigImageModal}/images/percent_background.png (100%) create mode 100644 packages/biz/lib/BigImageModal/index.d.ts create mode 100644 packages/biz/lib/BigImageModal/index.js create mode 100644 packages/biz/lib/BigImageModal/index.less create mode 100644 packages/biz/lib/BigImageModal/mock.d.ts create mode 100644 packages/biz/lib/BigImageModal/mock.js create mode 100644 packages/biz/lib/Demo/index.d.ts create mode 100644 packages/biz/lib/Demo/index.js create mode 100644 packages/biz/lib/adapter/BigImageModalAdapter/index.d.ts create mode 100644 packages/biz/lib/adapter/BigImageModalAdapter/index.js create mode 100644 packages/biz/lib/adapter/index.d.ts create mode 100644 packages/biz/lib/adapter/index.js create mode 100644 packages/biz/lib/hooks/useIntelligentTracking/index.d.ts create mode 100644 packages/biz/lib/hooks/useIntelligentTracking/index.js create mode 100644 packages/biz/lib/index.d.ts create mode 100644 packages/biz/lib/index.js create mode 100644 packages/biz/lib/useSocket/index.d.ts create mode 100644 packages/biz/lib/useSocket/index.js create mode 100644 packages/biz/lib/useSocket/onceChannel.d.ts create mode 100644 packages/biz/lib/useSocket/onceChannel.js create mode 100644 packages/biz/lib/useSocket/ws.d.ts create mode 100644 packages/biz/lib/useSocket/ws.js create mode 100644 packages/biz/lib/utils/constants.d.ts create mode 100644 packages/biz/lib/utils/constants.js rename packages/{hooks/es/useIMEComposition/constants.d.ts => biz/lib/utils/index.d.ts} (100%) rename packages/{hooks/es/useIMEComposition/constants.js => biz/lib/utils/index.js} (100%) create mode 100644 packages/biz/src/BigImageModal/BigImageModal.tsx delete mode 100644 packages/biz/src/BigImageModal/index.temp.tsx delete mode 100644 packages/biz/src/hooks/useTaskState/index.ts delete mode 100644 packages/biz/src/utils/request.ts create mode 100644 packages/func/es/camera/constants.d.ts create mode 100644 packages/func/es/camera/index.d.ts create mode 100644 packages/func/es/file/index.d.ts create mode 100644 packages/func/es/index.d.ts create mode 100644 packages/func/es/map/index.d.ts create mode 100644 packages/func/es/math/index.d.ts create mode 100644 packages/func/es/number/index.d.ts create mode 100644 packages/func/es/performance/index.d.ts create mode 100644 packages/func/es/string/index.d.ts create mode 100644 packages/func/es/time/index.d.ts create mode 100644 packages/func/es/upload/index.d.ts create mode 100644 packages/func/es/utils/index.d.ts create mode 100644 packages/func/es/utils/isChrome.d.ts create mode 100644 packages/func/lib/camera/constants.d.ts create mode 100644 packages/func/lib/camera/constants.js create mode 100644 packages/func/lib/camera/index.d.ts create mode 100644 packages/func/lib/camera/index.js create mode 100644 packages/func/lib/file/index.d.ts create mode 100644 packages/func/lib/file/index.js create mode 100644 packages/func/lib/index.d.ts create mode 100644 packages/func/lib/index.js create mode 100644 packages/func/lib/map/index.d.ts create mode 100644 packages/func/lib/map/index.js create mode 100644 packages/func/lib/math/index.d.ts create mode 100644 packages/func/lib/math/index.js create mode 100644 packages/func/lib/number/index.d.ts create mode 100644 packages/func/lib/number/index.js create mode 100644 packages/func/lib/performance/index.d.ts create mode 100644 packages/func/lib/performance/index.js create mode 100644 packages/func/lib/string/index.d.ts create mode 100644 packages/func/lib/string/index.js create mode 100644 packages/func/lib/time/index.d.ts create mode 100644 packages/func/lib/time/index.js create mode 100644 packages/func/lib/upload/index.d.ts create mode 100644 packages/func/lib/upload/index.js create mode 100644 packages/func/lib/utils/index.d.ts create mode 100644 packages/func/lib/utils/index.js create mode 100644 packages/func/lib/utils/isChrome.d.ts create mode 100644 packages/func/lib/utils/isChrome.js create mode 100644 packages/material/es/Demo/index.d.ts create mode 100644 packages/material/es/Demo/index.js create mode 100644 packages/material/es/index.d.ts create mode 100644 packages/material/es/index.js create mode 100644 packages/material/lib/Demo/index.d.ts create mode 100644 packages/material/lib/Demo/index.js create mode 100644 packages/material/lib/index.d.ts create mode 100644 packages/material/lib/index.js create mode 100644 packages/meta/es/BigImagePreview/BigImagePreview.d.ts create mode 100644 packages/meta/es/BigImagePreview/BigImagePreview.js rename packages/{hooks/lib/useIMEComposition/constants.d.ts => meta/es/BigImagePreview/bigImagePreviewHelper.d.ts} (100%) rename packages/{hooks/lib/useIMEComposition/constants.js => meta/es/BigImagePreview/bigImagePreviewHelper.js} (100%) create mode 100644 packages/meta/es/BigImagePreview/components/BtnGroup/index.d.ts create mode 100644 packages/meta/es/BigImagePreview/components/BtnGroup/index.js create mode 100644 packages/meta/es/BigImagePreview/components/BtnGroup/index.less create mode 100644 packages/meta/es/BigImagePreview/components/ScreenhotButtons/index.d.ts rename packages/{biz/es/utils/request.js => meta/es/BigImagePreview/components/ScreenhotButtons/index.js} (53%) create mode 100644 packages/meta/es/BigImagePreview/components/ScreenhotButtons/index.less create mode 100644 packages/meta/es/BigImagePreview/index.d.ts create mode 100644 packages/meta/es/BigImagePreview/index.js create mode 100644 packages/meta/es/BigImagePreview/index.less create mode 100644 packages/meta/es/CompareImage/CompareImage.d.ts rename packages/meta/es/{ImagePreview/index.js => CompareImage/CompareImage.js} (72%) rename packages/meta/es/{ImagePreview => CompareImage}/components/CornerScore/index.d.ts (100%) rename packages/meta/es/{ImagePreview => CompareImage}/components/CornerScore/index.js (100%) rename packages/meta/{src/ImagePreview => es/CompareImage}/components/CornerScore/index.less (94%) rename packages/meta/{lib/ImagePreview => es/CompareImage}/images/emptyImage.png (100%) rename packages/meta/{lib/ImagePreview => es/CompareImage}/images/percent_background.png (100%) create mode 100644 packages/meta/es/CompareImage/index.d.ts create mode 100644 packages/meta/es/CompareImage/index.js rename packages/meta/{src/ImagePreview => es/CompareImage}/index.less (100%) delete mode 100644 packages/meta/es/ImagePreview/index.d.ts create mode 100644 packages/meta/es/VideoPlayer/VideoPlayer.d.ts create mode 100644 packages/meta/es/VideoPlayer/VideoPlayer.js create mode 100644 packages/meta/es/VideoPlayer/components/FlvPlayer/index.d.ts create mode 100644 packages/meta/es/VideoPlayer/components/FlvPlayer/index.js create mode 100644 packages/meta/es/VideoPlayer/components/Loading/index.d.ts create mode 100644 packages/meta/es/VideoPlayer/components/Loading/index.js create mode 100644 packages/meta/es/VideoPlayer/components/Loading/index.less create mode 100644 packages/meta/es/VideoPlayer/components/Progress/index.d.ts create mode 100644 packages/meta/es/VideoPlayer/components/Progress/index.js create mode 100644 packages/meta/es/VideoPlayer/components/Progress/index.less create mode 100644 packages/meta/es/VideoPlayer/index.d.ts create mode 100644 packages/meta/es/VideoPlayer/index.js create mode 100644 packages/meta/es/VideoPlayer/index.less create mode 100644 packages/meta/es/VideoPlayer/videoPlayerHelper.d.ts create mode 100644 packages/meta/es/VideoPlayer/videoPlayerHelper.js create mode 100644 packages/meta/es/iconfont/iconfont.css create mode 100644 packages/meta/es/iconfont/iconfont.js create mode 100644 packages/meta/es/iconfont/iconfont.ttf create mode 100644 packages/meta/es/iconfont/iconfont.woff create mode 100644 packages/meta/es/iconfont/iconfont.woff2 create mode 100644 packages/meta/es/utils/constants.d.ts create mode 100644 packages/meta/es/utils/constants.js create mode 100644 packages/meta/lib/BigImagePreview/BigImagePreview.d.ts create mode 100644 packages/meta/lib/BigImagePreview/BigImagePreview.js rename packages/meta/{es/ImagePreview/components/CornerScore/index.less => lib/BigImagePreview/bigImagePreviewHelper.d.ts} (100%) rename packages/meta/lib/{ImagePreview/components/CornerScore/index.less => BigImagePreview/bigImagePreviewHelper.js} (100%) create mode 100644 packages/meta/lib/BigImagePreview/components/BtnGroup/index.d.ts create mode 100644 packages/meta/lib/BigImagePreview/components/BtnGroup/index.js create mode 100644 packages/meta/lib/BigImagePreview/components/BtnGroup/index.less create mode 100644 packages/meta/lib/BigImagePreview/components/ScreenhotButtons/index.d.ts create mode 100644 packages/meta/lib/BigImagePreview/components/ScreenhotButtons/index.js create mode 100644 packages/meta/lib/BigImagePreview/components/ScreenhotButtons/index.less create mode 100644 packages/meta/lib/BigImagePreview/index.d.ts create mode 100644 packages/meta/lib/BigImagePreview/index.js create mode 100644 packages/meta/lib/BigImagePreview/index.less create mode 100644 packages/meta/lib/CompareImage/CompareImage.d.ts rename packages/meta/lib/{ImagePreview/index.js => CompareImage/CompareImage.js} (79%) rename packages/meta/lib/{ImagePreview => CompareImage}/components/CornerScore/index.d.ts (100%) rename packages/meta/lib/{ImagePreview => CompareImage}/components/CornerScore/index.js (97%) create mode 100644 packages/meta/lib/CompareImage/components/CornerScore/index.less rename packages/meta/{src/ImagePreview => lib/CompareImage}/images/emptyImage.png (100%) rename packages/meta/{src/ImagePreview => lib/CompareImage}/images/percent_background.png (100%) create mode 100644 packages/meta/lib/CompareImage/index.d.ts create mode 100644 packages/meta/lib/CompareImage/index.js create mode 100644 packages/meta/lib/CompareImage/index.less delete mode 100644 packages/meta/lib/ImagePreview/index.d.ts create mode 100644 packages/meta/lib/VideoPlayer/VideoPlayer.d.ts create mode 100644 packages/meta/lib/VideoPlayer/VideoPlayer.js create mode 100644 packages/meta/lib/VideoPlayer/components/FlvPlayer/index.d.ts create mode 100644 packages/meta/lib/VideoPlayer/components/FlvPlayer/index.js create mode 100644 packages/meta/lib/VideoPlayer/components/Loading/index.d.ts create mode 100644 packages/meta/lib/VideoPlayer/components/Loading/index.js create mode 100644 packages/meta/lib/VideoPlayer/components/Loading/index.less create mode 100644 packages/meta/lib/VideoPlayer/components/Progress/index.d.ts create mode 100644 packages/meta/lib/VideoPlayer/components/Progress/index.js create mode 100644 packages/meta/lib/VideoPlayer/components/Progress/index.less create mode 100644 packages/meta/lib/VideoPlayer/index.d.ts create mode 100644 packages/meta/lib/VideoPlayer/index.js create mode 100644 packages/meta/lib/VideoPlayer/index.less create mode 100644 packages/meta/lib/VideoPlayer/videoPlayerHelper.d.ts create mode 100644 packages/meta/lib/VideoPlayer/videoPlayerHelper.js create mode 100644 packages/meta/lib/iconfont/iconfont.css create mode 100644 packages/meta/lib/iconfont/iconfont.js create mode 100644 packages/meta/lib/iconfont/iconfont.ttf create mode 100644 packages/meta/lib/iconfont/iconfont.woff create mode 100644 packages/meta/lib/iconfont/iconfont.woff2 create mode 100644 packages/meta/lib/utils/constants.d.ts create mode 100644 packages/meta/lib/utils/constants.js create mode 100644 packages/meta/src/BigImagePreview/BigImagePreview.tsx create mode 100644 packages/meta/src/BigImagePreview/bigImagePreviewHelper.ts rename packages/meta/src/{ImagePreview/index.tsx => CompareImage/CompareImage.tsx} (80%) create mode 100644 packages/meta/src/CompareImage/components/CornerScore/index.less rename packages/meta/src/{ImagePreview => CompareImage}/components/CornerScore/index.tsx (100%) create mode 100644 packages/meta/src/CompareImage/images/emptyImage.png create mode 100644 packages/meta/src/CompareImage/images/percent_background.png create mode 100644 packages/meta/src/CompareImage/index.less create mode 100644 packages/meta/src/CompareImage/index.md create mode 100644 packages/meta/src/CompareImage/index.tsx delete mode 100644 packages/meta/src/ImagePreview/index.md create mode 100644 packages/meta/src/VideoPlayer/VideoPlayer.tsx create mode 100644 packages/meta/src/VideoPlayer/videoPlayerHelper.ts create mode 100644 packages/meta/src/utils/constants.ts create mode 100644 packages/request/es/index.d.ts create mode 100644 packages/request/lib/index.d.ts create mode 100644 packages/request/lib/index.js diff --git a/.dumi/loading.tsx b/.dumi/loading.tsx new file mode 100644 index 0000000..086748a --- /dev/null +++ b/.dumi/loading.tsx @@ -0,0 +1,5 @@ +import React from 'react'; + +export default () => { + return
客官,您慢点儿...
; +}; diff --git a/.dumi/tsconfig.json b/.dumi/tsconfig.json new file mode 100644 index 0000000..a32dd4f --- /dev/null +++ b/.dumi/tsconfig.json @@ -0,0 +1,4 @@ +{ + "extends": "../tsconfig.json", + "include": ["**/*"] +} diff --git a/.dumirc.ts b/.dumirc.ts index 8ed82c5..24c93a8 100644 --- a/.dumirc.ts +++ b/.dumirc.ts @@ -6,7 +6,10 @@ export default defineConfig({ favicons: ['/logo.jpg'], history: { type: 'hash' }, themeConfig: { - name: 'zhst前端库', + name: 'lambo', + socialLinks: { + gitlab: 'http://10.0.0.88/web-project/zhst-component', + }, }, alias: { '@zhst/hooks': path.join(__dirname, 'packages/hooks/src'), diff --git a/.stylelintrc b/.stylelintrc index e362194..23164e7 100644 --- a/.stylelintrc +++ b/.stylelintrc @@ -1,3 +1,6 @@ { - "extends": "@umijs/lint/dist/config/stylelint" + "extends": "@umijs/lint/dist/config/stylelint", + "rules": { + "selector-class-pattern": null + } } diff --git a/.vscode/settings.json b/.vscode/settings.json index b9685e3..169b84f 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -3,6 +3,9 @@ "ahooks", "antd", "COMPATER", + "flvjs", + "remuxer", + "transmuxer", "zhst" ] } diff --git a/docs/index.md b/docs/index.md index 89c3fc3..8973543 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,7 +1,7 @@ --- hero: - title: zhst - description: 前端工具库合集 + title: lambo + description: 致力于提升前端开发效率与规范 actions: - text: 快速上手 link: /bizs @@ -16,8 +16,23 @@ features: emoji: 🌈 description: 常用函数库 - title: meta - emoji: 🧸 + emoji: ☀️ description: 原子组件库 + - title: constants + emoji: 🈶️ + description: 静态定义库 + - title: request + emoji: 🥣 + description: 网络请求库 + - title: types + emoji: 🈸 + description: typescript 声明库 + - title: material + emoji: 🥱 + description: 物料库 + - title: cli + emoji: 🐔 + description: 脚手架 --- ## 目录结构 @@ -70,6 +85,10 @@ features: material 物料库 +
  • + cli + 脚手架 +
  • @@ -95,7 +114,7 @@ features: ## 本文档食用说明 -目前在开发中的项目为:@zhst/bizs、@zhst/hooks、@zhst/meta、@zhst/func。 +目前在进行中的项目为:@zhst/bizs、@zhst/hooks、@zhst/meta、@zhst/func.. bizs: 基于@zhst/hooks、@zhst/meta、@zhst/func 开发,基本贴近于业务。doing @@ -103,20 +122,20 @@ meta:基于 antd 开发,作为公司的定制化原子组件。doing< hooks:基于 ahooks、@zhst/func 定制化二次开发。doing -func:基于 lodash-es 定制化二次开发 (由于utils包名被使用了)doing +func:基于 lodash-es 定制化二次开发 (由于 utils 包名被使用了)doing ## 后续构思 想做一个,基于智慧视通开发场景和业务场景的前端技术流程化方案,希望它能渗透到整个研发的所有流程中。 -比如:代码规范、git提交规范、物料库、基于electron的前端工具客户端(可集成物料库、图片上传小工具)、api自动生成... +比如:代码规范、git 提交规范、物料库、基于 electron 的前端工具客户端(可集成物料库、图片上传小工具)、api 自动生成... :::info{title=@zhst/lint} -lint工具库,包含:eslint-config、eslint-plugin、commit-lint +lint 工具库,包含:eslint-config、eslint-plugin、commit-lint ::: :::info{title=@zhst/metarial} -物料库,可以直接通过 clone npm 仓库的形式生成模板页面 +物料库,可以直接通过 clone npm 仓库的形式生成模板页面,页面没有任何依赖,一个页面就是一个项目。 ::: :::info{title=@zhst/app} @@ -134,3 +153,7 @@ lint工具库,包含:eslint-config、eslint-plugin、commit-lint :::info{title=@zhst/constants} 静态变量枚举库 ::: + +:::info{title=@zhst/cli} +基于物料库的脚手架,可以直接通过可视化界面搭建项目,偏向于 lowcode+ 思维 +::: diff --git a/packages/biz/CHANGELOG.md b/packages/biz/CHANGELOG.md index 444b4f0..165ebe9 100644 --- a/packages/biz/CHANGELOG.md +++ b/packages/biz/CHANGELOG.md @@ -1,5 +1,18 @@ # @zhst/biz +## 0.3.0 + +### Minor Changes + +- feat: 初始化项目包 + +### Patch Changes + +- Updated dependencies + - @zhst/hooks@0.3.0 + - @zhst/func@0.3.0 + - @zhst/meta@0.3.0 + ## 0.2.4 ### Patch Changes diff --git a/packages/biz/es/BigImageModal/BigImageModal.d.ts b/packages/biz/es/BigImageModal/BigImageModal.d.ts new file mode 100644 index 0000000..05eab4a --- /dev/null +++ b/packages/biz/es/BigImageModal/BigImageModal.d.ts @@ -0,0 +1,23 @@ +import React from 'react'; +import type { ModalProps, DescriptionsProps, TabsProps } from 'antd'; +import './index.less'; +export declare const componentPrefix = "zhst-image"; +export interface BigImageModalProps extends ModalProps { + visible: boolean; + descriptionConfig: { + data: { + title: string; + children: Pick; + }[]; + }; + tabsConfig: { + data: Pick & { + key: 'NORMAL' | 'COMPATER' | 'TRACK'; + }; + }; + dataSource: any; + imageData: any; + relatedData: any; +} +declare const BigImageModal: React.FC; +export default BigImageModal; diff --git a/packages/biz/es/hooks/useTaskState/index.js b/packages/biz/es/BigImageModal/BigImageModal.js similarity index 67% rename from packages/biz/es/hooks/useTaskState/index.js rename to packages/biz/es/BigImageModal/BigImageModal.js index 3446bb4..5fe3e7b 100644 --- a/packages/biz/es/hooks/useTaskState/index.js +++ b/packages/biz/es/BigImageModal/BigImageModal.js @@ -1,153 +1,151 @@ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } -function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); } -function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } -function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } } -function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } -function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); } -function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } -function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } -function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); } -function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); } -function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; } function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return e; }; var t, e = {}, r = Object.prototype, n = r.hasOwnProperty, o = Object.defineProperty || function (t, e, r) { t[e] = r.value; }, i = "function" == typeof Symbol ? Symbol : {}, a = i.iterator || "@@iterator", c = i.asyncIterator || "@@asyncIterator", u = i.toStringTag || "@@toStringTag"; function define(t, e, r) { return Object.defineProperty(t, e, { value: r, enumerable: !0, configurable: !0, writable: !0 }), t[e]; } try { define({}, ""); } catch (t) { define = function define(t, e, r) { return t[e] = r; }; } function wrap(t, e, r, n) { var i = e && e.prototype instanceof Generator ? e : Generator, a = Object.create(i.prototype), c = new Context(n || []); return o(a, "_invoke", { value: makeInvokeMethod(t, r, c) }), a; } function tryCatch(t, e, r) { try { return { type: "normal", arg: t.call(e, r) }; } catch (t) { return { type: "throw", arg: t }; } } e.wrap = wrap; var h = "suspendedStart", l = "suspendedYield", f = "executing", s = "completed", y = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var p = {}; define(p, a, function () { return this; }); var d = Object.getPrototypeOf, v = d && d(d(values([]))); v && v !== r && n.call(v, a) && (p = v); var g = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(p); function defineIteratorMethods(t) { ["next", "throw", "return"].forEach(function (e) { define(t, e, function (t) { return this._invoke(e, t); }); }); } function AsyncIterator(t, e) { function invoke(r, o, i, a) { var c = tryCatch(t[r], t, o); if ("throw" !== c.type) { var u = c.arg, h = u.value; return h && "object" == _typeof(h) && n.call(h, "__await") ? e.resolve(h.__await).then(function (t) { invoke("next", t, i, a); }, function (t) { invoke("throw", t, i, a); }) : e.resolve(h).then(function (t) { u.value = t, i(u); }, function (t) { return invoke("throw", t, i, a); }); } a(c.arg); } var r; o(this, "_invoke", { value: function value(t, n) { function callInvokeWithMethodAndArg() { return new e(function (e, r) { invoke(t, n, e, r); }); } return r = r ? r.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); } }); } function makeInvokeMethod(e, r, n) { var o = h; return function (i, a) { if (o === f) throw new Error("Generator is already running"); if (o === s) { if ("throw" === i) throw a; return { value: t, done: !0 }; } for (n.method = i, n.arg = a;;) { var c = n.delegate; if (c) { var u = maybeInvokeDelegate(c, n); if (u) { if (u === y) continue; return u; } } if ("next" === n.method) n.sent = n._sent = n.arg;else if ("throw" === n.method) { if (o === h) throw o = s, n.arg; n.dispatchException(n.arg); } else "return" === n.method && n.abrupt("return", n.arg); o = f; var p = tryCatch(e, r, n); if ("normal" === p.type) { if (o = n.done ? s : l, p.arg === y) continue; return { value: p.arg, done: n.done }; } "throw" === p.type && (o = s, n.method = "throw", n.arg = p.arg); } }; } function maybeInvokeDelegate(e, r) { var n = r.method, o = e.iterator[n]; if (o === t) return r.delegate = null, "throw" === n && e.iterator.return && (r.method = "return", r.arg = t, maybeInvokeDelegate(e, r), "throw" === r.method) || "return" !== n && (r.method = "throw", r.arg = new TypeError("The iterator does not provide a '" + n + "' method")), y; var i = tryCatch(o, e.iterator, r.arg); if ("throw" === i.type) return r.method = "throw", r.arg = i.arg, r.delegate = null, y; var a = i.arg; return a ? a.done ? (r[e.resultName] = a.value, r.next = e.nextLoc, "return" !== r.method && (r.method = "next", r.arg = t), r.delegate = null, y) : a : (r.method = "throw", r.arg = new TypeError("iterator result is not an object"), r.delegate = null, y); } function pushTryEntry(t) { var e = { tryLoc: t[0] }; 1 in t && (e.catchLoc = t[1]), 2 in t && (e.finallyLoc = t[2], e.afterLoc = t[3]), this.tryEntries.push(e); } function resetTryEntry(t) { var e = t.completion || {}; e.type = "normal", delete e.arg, t.completion = e; } function Context(t) { this.tryEntries = [{ tryLoc: "root" }], t.forEach(pushTryEntry, this), this.reset(!0); } function values(e) { if (e || "" === e) { var r = e[a]; if (r) return r.call(e); if ("function" == typeof e.next) return e; if (!isNaN(e.length)) { var o = -1, i = function next() { for (; ++o < e.length;) if (n.call(e, o)) return next.value = e[o], next.done = !1, next; return next.value = t, next.done = !0, next; }; return i.next = i; } } throw new TypeError(_typeof(e) + " is not iterable"); } return GeneratorFunction.prototype = GeneratorFunctionPrototype, o(g, "constructor", { value: GeneratorFunctionPrototype, configurable: !0 }), o(GeneratorFunctionPrototype, "constructor", { value: GeneratorFunction, configurable: !0 }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, u, "GeneratorFunction"), e.isGeneratorFunction = function (t) { var e = "function" == typeof t && t.constructor; return !!e && (e === GeneratorFunction || "GeneratorFunction" === (e.displayName || e.name)); }, e.mark = function (t) { return Object.setPrototypeOf ? Object.setPrototypeOf(t, GeneratorFunctionPrototype) : (t.__proto__ = GeneratorFunctionPrototype, define(t, u, "GeneratorFunction")), t.prototype = Object.create(g), t; }, e.awrap = function (t) { return { __await: t }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, c, function () { return this; }), e.AsyncIterator = AsyncIterator, e.async = function (t, r, n, o, i) { void 0 === i && (i = Promise); var a = new AsyncIterator(wrap(t, r, n, o), i); return e.isGeneratorFunction(r) ? a : a.next().then(function (t) { return t.done ? t.value : a.next(); }); }, defineIteratorMethods(g), define(g, u, "Generator"), define(g, a, function () { return this; }), define(g, "toString", function () { return "[object Generator]"; }), e.keys = function (t) { var e = Object(t), r = []; for (var n in e) r.push(n); return r.reverse(), function next() { for (; r.length;) { var t = r.pop(); if (t in e) return next.value = t, next.done = !1, next; } return next.done = !0, next; }; }, e.values = values, Context.prototype = { constructor: Context, reset: function reset(e) { if (this.prev = 0, this.next = 0, this.sent = this._sent = t, this.done = !1, this.delegate = null, this.method = "next", this.arg = t, this.tryEntries.forEach(resetTryEntry), !e) for (var r in this) "t" === r.charAt(0) && n.call(this, r) && !isNaN(+r.slice(1)) && (this[r] = t); }, stop: function stop() { this.done = !0; var t = this.tryEntries[0].completion; if ("throw" === t.type) throw t.arg; return this.rval; }, dispatchException: function dispatchException(e) { if (this.done) throw e; var r = this; function handle(n, o) { return a.type = "throw", a.arg = e, r.next = n, o && (r.method = "next", r.arg = t), !!o; } for (var o = this.tryEntries.length - 1; o >= 0; --o) { var i = this.tryEntries[o], a = i.completion; if ("root" === i.tryLoc) return handle("end"); if (i.tryLoc <= this.prev) { var c = n.call(i, "catchLoc"), u = n.call(i, "finallyLoc"); if (c && u) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } else if (c) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); } else { if (!u) throw new Error("try statement without catch or finally"); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } } } }, abrupt: function abrupt(t, e) { for (var r = this.tryEntries.length - 1; r >= 0; --r) { var o = this.tryEntries[r]; if (o.tryLoc <= this.prev && n.call(o, "finallyLoc") && this.prev < o.finallyLoc) { var i = o; break; } } i && ("break" === t || "continue" === t) && i.tryLoc <= e && e <= i.finallyLoc && (i = null); var a = i ? i.completion : {}; return a.type = t, a.arg = e, i ? (this.method = "next", this.next = i.finallyLoc, y) : this.complete(a); }, complete: function complete(t, e) { if ("throw" === t.type) throw t.arg; return "break" === t.type || "continue" === t.type ? this.next = t.arg : "return" === t.type ? (this.rval = this.arg = t.arg, this.method = "return", this.next = "end") : "normal" === t.type && e && (this.next = e), y; }, finish: function finish(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.finallyLoc === t) return this.complete(r.completion, r.afterLoc), resetTryEntry(r), y; } }, catch: function _catch(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.tryLoc === t) { var n = r.completion; if ("throw" === n.type) { var o = n.arg; resetTryEntry(r); } return o; } } throw new Error("illegal catch attempt"); }, delegateYield: function delegateYield(e, r, n) { return this.delegate = { iterator: values(e), resultName: r, nextLoc: n }, "next" === this.method && (this.arg = t), y; } }, e; } function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } -import doRequest from "../../utils/request"; -import { NetworkType, useStores } from '@store/index'; -import { useMount, useUnmount } from '@zhst/hooks'; -import { useRef, useState } from 'react'; -var Streams = ['TASK_OVERVIEW_WAIT_START_STREAM', 'TASK_OVERVIEW_WAIT_STREAM', 'TASK_OVERVIEW_WAIT_START_SVINFER']; -var StreamsNum = [1, 2, 3]; -var RunsNum = [5, 9]; -var ErrorsNum = [7]; -var Runs = ['TASK_OVERVIEW_RUNNING', 'TASK_OVERVIEW_FINISH']; -var Errors = ['TASK_OVERVIEW_ERROR']; -export var getListTaskStatus = /*#__PURE__*/function () { - var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(data) { - var res; - return _regeneratorRuntime().wrap(function _callee$(_context) { - while (1) switch (_context.prev = _context.next) { - case 0: - _context.next = 2; - return doRequest({ - url: '/singer.TaskManagerService/ListTaskStatusResponse', - method: 'POST', - data: data || {} - }); - case 2: - res = _context.sent; - return _context.abrupt("return", res); - case 4: - case "end": - return _context.stop(); - } - }, _callee); - })); - return function getListTaskStatus(_x) { - return _ref.apply(this, arguments); - }; -}(); -export var getCameraStatusFunc = function getCameraStatusFunc(list) { - var useNum = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; - var _Runs = useNum ? RunsNum : Runs; - var _Errors = useNum ? ErrorsNum : Errors; - var _Streams = useNum ? StreamsNum : Streams; - var res = list.reduce(function (res, cur) { - var cameraId = cur.taskIndex.deviceId; - var status = cur.taskOverview; - res.some(function (ids, i) { - if (ids.includes(cameraId)) { - res[i] = ids.filter(function (id) { - return id !== cameraId; - }); - return true; - } - return false; - }); - if (_Runs.includes(status)) { - res[0].push(cameraId); - } else if (_Errors.includes(status)) { - res[1].push(cameraId); - } else if (_Streams.includes(status)) { - res[2].push(cameraId); - } - return res; - }, [[], [], []]); - return _toConsumableArray(res); +function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } +function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); } +function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } +function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } +function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; } +function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } } +function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } +// @ts-nocheck +import React, { useRef, useState } from 'react'; +import { Descriptions, Modal, Tabs } from 'antd'; +import classNames from 'classnames'; +import { get } from '@zhst/func'; +import "./index.less"; +import Navigation from "./components/navigation"; +var DescriptionsItem = Descriptions.Item; +export var componentPrefix = 'zhst-image'; +var initialStyle = { + fontSize: '12px' }; -var camerasStatusStoreList = [[], [], []]; -var num = 0; -var useTaskState = function useTaskState() { - var _useStores = useStores(), - store = _useStores.store; - var _useState = useState(camerasStatusStoreList), +var BigImageModal = function BigImageModal(props) { + var _props$title = props.title, + title = _props$title === void 0 ? '-' : _props$title, + open = props.open, + visible = props.visible, + children = props.children, + _props$descriptionCon = props.descriptionConfig, + descriptionConfig = _props$descriptionCon === void 0 ? { + data: [] + } : _props$descriptionCon, + _props$tabsConfig = props.tabsConfig, + tabsConfig = _props$tabsConfig === void 0 ? { + data: [{ + label: '对比图模式', + key: '1', + children: '对比图组件' + }, { + label: '场景图模式', + key: '2', + children: '场景图组件' + }] + } : _props$tabsConfig, + _props$dataSource = props.dataSource, + dataSource = _props$dataSource === void 0 ? [] : _props$dataSource, + _props$imageData = props.imageData, + imageData = _props$imageData === void 0 ? [] : _props$imageData, + _props$relatedData = props.relatedData, + relatedData = _props$relatedData === void 0 ? [] : _props$relatedData; + var showCropRef = useRef(false); + var scaleRef = useRef(0); + + // ========================== 头切换 ========================= + var _useState = useState(get(tabsConfig, 'data[0].key')), _useState2 = _slicedToArray(_useState, 2), - camerasStatusList = _useState2[0], - setCamerasStatusList = _useState2[1]; - var timerRef = useRef(null); - var getCameraStatus = function getCameraStatus(list) { - var useNum = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; - var res = getCameraStatusFunc(list, useNum); - setCamerasStatusList(res); - }; - var request = function request(data) { - if (data) { - var list = []; - data.forEach(function (v) { - list.push.apply(list, _toConsumableArray(v.taskStatus)); - }); - getCameraStatus(list, store.networkType === NetworkType.NORMAL); - } - }; - useMount( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3() { - var res; - return _regeneratorRuntime().wrap(function _callee3$(_context3) { - while (1) switch (_context3.prev = _context3.next) { - case 0: - num++; - if (!(num - 1 > 0)) { - _context3.next = 3; - break; - } - return _context3.abrupt("return"); - case 3: - _context3.next = 5; - return getListTaskStatus(); - case 5: - res = _context3.sent; - getCameraStatus(res.taskStatus); - if (store.networkType === NetworkType.DUAL_NETWORK) { - timerRef.current = setInterval( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2() { - var res; - return _regeneratorRuntime().wrap(function _callee2$(_context2) { - while (1) switch (_context2.prev = _context2.next) { - case 0: - _context2.next = 2; - return getListTaskStatus(); - case 2: - res = _context2.sent; - request([res]); - case 4: - case "end": - return _context2.stop(); - } - }, _callee2); - })), 2000); - } - case 8: - case "end": - return _context3.stop(); + activeKey = _useState2[0], + setActiveKey = _useState2[1]; + + // ========================= 预览切换下标 ========================= + var _useState3 = useState(0), + _useState4 = _slicedToArray(_useState3, 2), + previewIndex = _useState4[0], + setPreviewIndex = _useState4[1]; + var _useState5 = useState(false), + _useState6 = _slicedToArray(_useState5, 2), + isRelated = _useState6[0], + setIsRelated = _useState6[1]; + return /*#__PURE__*/React.createElement(Modal, _extends({ + destroyOnClose: true, + open: open || visible, + footer: null, + className: componentPrefix, + title: title + }, props), descriptionConfig.data.map(function (descriptions) { + var _descriptions$childre; + return /*#__PURE__*/React.createElement(Descriptions, { + key: descriptions.title, + title: /*#__PURE__*/React.createElement("p", { + style: { + margin: '12px 0 0', + fontSize: initialStyle.fontSize + } + }, descriptions.title), + column: 8, + style: { + padding: '0 64px' } - }, _callee3); - }))); - useUnmount(function () { - clearInterval(timerRef.current); - setCamerasStatusList([[], [], []]); - num--; - if (num === 0) { - camerasStatusStoreList = [[], [], []]; + }, descriptions === null || descriptions === void 0 || (_descriptions$childre = descriptions.children) === null || _descriptions$childre === void 0 ? void 0 : _descriptions$childre.map(function (item) { + return /*#__PURE__*/React.createElement(DescriptionsItem, { + key: item.key, + label: item.label, + span: 1, + contentStyle: { + fontSize: initialStyle.fontSize + }, + labelStyle: { + fontSize: initialStyle.fontSize + } + }, item.children); + })); + }), /*#__PURE__*/React.createElement(Tabs, _extends({ + defaultActiveKey: activeKey, + centered: true, + tabBarStyle: { + fontSize: '18px' + }, + items: tabsConfig.data + }, tabsConfig)), /*#__PURE__*/React.createElement("div", { + className: classNames("".concat(componentPrefix, "-view-container")), + style: activeKey === 'TRACK' ? { + height: '718px', + marginBottom: '0px' + } : {} + }, activeKey !== 'TRACK' && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Navigation, { + className: classNames("".concat(componentPrefix, "-view-container__nav"), previewIndex <= 0 && "".concat(componentPrefix, "-view-container__nav--disabled"), "".concat(componentPrefix, "-view-container__nav--left")), + show: isRelated ? imageData.length > 1 : dataSource.length > 1, + disabled: previewIndex <= 0, + prev: true, + onClick: function onClick() { + setPreviewIndex(function (pre) { + return pre - 1; + }); } - }); - return camerasStatusList; + }), /*#__PURE__*/React.createElement(Navigation, { + className: classNames("".concat(componentPrefix, "-view-container__nav"), (previewIndex >= imageData.length - 1 || previewIndex >= dataSource.length - 1) && "".concat(componentPrefix, "-view-container__nav--disabled"), "".concat(componentPrefix, "-view-container__nav--right")), + show: isRelated ? imageData.length > 1 : dataSource.length > 1, + disabled: previewIndex >= imageData.length - 1 || previewIndex >= dataSource.length - 1, + next: true, + onClick: /*#__PURE__*/function () { + var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(e) { + return _regeneratorRuntime().wrap(function _callee$(_context) { + while (1) switch (_context.prev = _context.next) { + case 0: + setPreviewIndex(function (pre) { + return pre + 1; + }); + case 1: + case "end": + return _context.stop(); + } + }, _callee); + })); + return function (_x) { + return _ref.apply(this, arguments); + }; + }() + })))); }; -export default useTaskState; \ No newline at end of file +export default BigImageModal; \ No newline at end of file diff --git a/packages/biz/es/BigImageModal/components/navigation/index.d.ts b/packages/biz/es/BigImageModal/components/navigation/index.d.ts new file mode 100644 index 0000000..78b1ca8 --- /dev/null +++ b/packages/biz/es/BigImageModal/components/navigation/index.d.ts @@ -0,0 +1,13 @@ +import * as React from 'react'; +import './index.less'; +declare const Navigation: React.FC<{ + show?: boolean; + onClick?: React.MouseEventHandler; + prev?: boolean; + next?: boolean; + disabled?: boolean; + className?: string; + color?: string; + hoverColor?: string; +}>; +export default Navigation; diff --git a/packages/biz/es/BigImageModal/index.d.ts b/packages/biz/es/BigImageModal/index.d.ts new file mode 100644 index 0000000..bb07714 --- /dev/null +++ b/packages/biz/es/BigImageModal/index.d.ts @@ -0,0 +1,3 @@ +import BigImageModal from "./BigImageModal"; +export type { BigImageModalProps } from './BigImageModal'; +export default BigImageModal; diff --git a/packages/biz/es/BigImageModal/index.js b/packages/biz/es/BigImageModal/index.js index 5fe3e7b..417a89d 100644 --- a/packages/biz/es/BigImageModal/index.js +++ b/packages/biz/es/BigImageModal/index.js @@ -1,151 +1,2 @@ -function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } -function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return e; }; var t, e = {}, r = Object.prototype, n = r.hasOwnProperty, o = Object.defineProperty || function (t, e, r) { t[e] = r.value; }, i = "function" == typeof Symbol ? Symbol : {}, a = i.iterator || "@@iterator", c = i.asyncIterator || "@@asyncIterator", u = i.toStringTag || "@@toStringTag"; function define(t, e, r) { return Object.defineProperty(t, e, { value: r, enumerable: !0, configurable: !0, writable: !0 }), t[e]; } try { define({}, ""); } catch (t) { define = function define(t, e, r) { return t[e] = r; }; } function wrap(t, e, r, n) { var i = e && e.prototype instanceof Generator ? e : Generator, a = Object.create(i.prototype), c = new Context(n || []); return o(a, "_invoke", { value: makeInvokeMethod(t, r, c) }), a; } function tryCatch(t, e, r) { try { return { type: "normal", arg: t.call(e, r) }; } catch (t) { return { type: "throw", arg: t }; } } e.wrap = wrap; var h = "suspendedStart", l = "suspendedYield", f = "executing", s = "completed", y = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var p = {}; define(p, a, function () { return this; }); var d = Object.getPrototypeOf, v = d && d(d(values([]))); v && v !== r && n.call(v, a) && (p = v); var g = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(p); function defineIteratorMethods(t) { ["next", "throw", "return"].forEach(function (e) { define(t, e, function (t) { return this._invoke(e, t); }); }); } function AsyncIterator(t, e) { function invoke(r, o, i, a) { var c = tryCatch(t[r], t, o); if ("throw" !== c.type) { var u = c.arg, h = u.value; return h && "object" == _typeof(h) && n.call(h, "__await") ? e.resolve(h.__await).then(function (t) { invoke("next", t, i, a); }, function (t) { invoke("throw", t, i, a); }) : e.resolve(h).then(function (t) { u.value = t, i(u); }, function (t) { return invoke("throw", t, i, a); }); } a(c.arg); } var r; o(this, "_invoke", { value: function value(t, n) { function callInvokeWithMethodAndArg() { return new e(function (e, r) { invoke(t, n, e, r); }); } return r = r ? r.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); } }); } function makeInvokeMethod(e, r, n) { var o = h; return function (i, a) { if (o === f) throw new Error("Generator is already running"); if (o === s) { if ("throw" === i) throw a; return { value: t, done: !0 }; } for (n.method = i, n.arg = a;;) { var c = n.delegate; if (c) { var u = maybeInvokeDelegate(c, n); if (u) { if (u === y) continue; return u; } } if ("next" === n.method) n.sent = n._sent = n.arg;else if ("throw" === n.method) { if (o === h) throw o = s, n.arg; n.dispatchException(n.arg); } else "return" === n.method && n.abrupt("return", n.arg); o = f; var p = tryCatch(e, r, n); if ("normal" === p.type) { if (o = n.done ? s : l, p.arg === y) continue; return { value: p.arg, done: n.done }; } "throw" === p.type && (o = s, n.method = "throw", n.arg = p.arg); } }; } function maybeInvokeDelegate(e, r) { var n = r.method, o = e.iterator[n]; if (o === t) return r.delegate = null, "throw" === n && e.iterator.return && (r.method = "return", r.arg = t, maybeInvokeDelegate(e, r), "throw" === r.method) || "return" !== n && (r.method = "throw", r.arg = new TypeError("The iterator does not provide a '" + n + "' method")), y; var i = tryCatch(o, e.iterator, r.arg); if ("throw" === i.type) return r.method = "throw", r.arg = i.arg, r.delegate = null, y; var a = i.arg; return a ? a.done ? (r[e.resultName] = a.value, r.next = e.nextLoc, "return" !== r.method && (r.method = "next", r.arg = t), r.delegate = null, y) : a : (r.method = "throw", r.arg = new TypeError("iterator result is not an object"), r.delegate = null, y); } function pushTryEntry(t) { var e = { tryLoc: t[0] }; 1 in t && (e.catchLoc = t[1]), 2 in t && (e.finallyLoc = t[2], e.afterLoc = t[3]), this.tryEntries.push(e); } function resetTryEntry(t) { var e = t.completion || {}; e.type = "normal", delete e.arg, t.completion = e; } function Context(t) { this.tryEntries = [{ tryLoc: "root" }], t.forEach(pushTryEntry, this), this.reset(!0); } function values(e) { if (e || "" === e) { var r = e[a]; if (r) return r.call(e); if ("function" == typeof e.next) return e; if (!isNaN(e.length)) { var o = -1, i = function next() { for (; ++o < e.length;) if (n.call(e, o)) return next.value = e[o], next.done = !1, next; return next.value = t, next.done = !0, next; }; return i.next = i; } } throw new TypeError(_typeof(e) + " is not iterable"); } return GeneratorFunction.prototype = GeneratorFunctionPrototype, o(g, "constructor", { value: GeneratorFunctionPrototype, configurable: !0 }), o(GeneratorFunctionPrototype, "constructor", { value: GeneratorFunction, configurable: !0 }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, u, "GeneratorFunction"), e.isGeneratorFunction = function (t) { var e = "function" == typeof t && t.constructor; return !!e && (e === GeneratorFunction || "GeneratorFunction" === (e.displayName || e.name)); }, e.mark = function (t) { return Object.setPrototypeOf ? Object.setPrototypeOf(t, GeneratorFunctionPrototype) : (t.__proto__ = GeneratorFunctionPrototype, define(t, u, "GeneratorFunction")), t.prototype = Object.create(g), t; }, e.awrap = function (t) { return { __await: t }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, c, function () { return this; }), e.AsyncIterator = AsyncIterator, e.async = function (t, r, n, o, i) { void 0 === i && (i = Promise); var a = new AsyncIterator(wrap(t, r, n, o), i); return e.isGeneratorFunction(r) ? a : a.next().then(function (t) { return t.done ? t.value : a.next(); }); }, defineIteratorMethods(g), define(g, u, "Generator"), define(g, a, function () { return this; }), define(g, "toString", function () { return "[object Generator]"; }), e.keys = function (t) { var e = Object(t), r = []; for (var n in e) r.push(n); return r.reverse(), function next() { for (; r.length;) { var t = r.pop(); if (t in e) return next.value = t, next.done = !1, next; } return next.done = !0, next; }; }, e.values = values, Context.prototype = { constructor: Context, reset: function reset(e) { if (this.prev = 0, this.next = 0, this.sent = this._sent = t, this.done = !1, this.delegate = null, this.method = "next", this.arg = t, this.tryEntries.forEach(resetTryEntry), !e) for (var r in this) "t" === r.charAt(0) && n.call(this, r) && !isNaN(+r.slice(1)) && (this[r] = t); }, stop: function stop() { this.done = !0; var t = this.tryEntries[0].completion; if ("throw" === t.type) throw t.arg; return this.rval; }, dispatchException: function dispatchException(e) { if (this.done) throw e; var r = this; function handle(n, o) { return a.type = "throw", a.arg = e, r.next = n, o && (r.method = "next", r.arg = t), !!o; } for (var o = this.tryEntries.length - 1; o >= 0; --o) { var i = this.tryEntries[o], a = i.completion; if ("root" === i.tryLoc) return handle("end"); if (i.tryLoc <= this.prev) { var c = n.call(i, "catchLoc"), u = n.call(i, "finallyLoc"); if (c && u) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } else if (c) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); } else { if (!u) throw new Error("try statement without catch or finally"); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } } } }, abrupt: function abrupt(t, e) { for (var r = this.tryEntries.length - 1; r >= 0; --r) { var o = this.tryEntries[r]; if (o.tryLoc <= this.prev && n.call(o, "finallyLoc") && this.prev < o.finallyLoc) { var i = o; break; } } i && ("break" === t || "continue" === t) && i.tryLoc <= e && e <= i.finallyLoc && (i = null); var a = i ? i.completion : {}; return a.type = t, a.arg = e, i ? (this.method = "next", this.next = i.finallyLoc, y) : this.complete(a); }, complete: function complete(t, e) { if ("throw" === t.type) throw t.arg; return "break" === t.type || "continue" === t.type ? this.next = t.arg : "return" === t.type ? (this.rval = this.arg = t.arg, this.method = "return", this.next = "end") : "normal" === t.type && e && (this.next = e), y; }, finish: function finish(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.finallyLoc === t) return this.complete(r.completion, r.afterLoc), resetTryEntry(r), y; } }, catch: function _catch(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.tryLoc === t) { var n = r.completion; if ("throw" === n.type) { var o = n.arg; resetTryEntry(r); } return o; } } throw new Error("illegal catch attempt"); }, delegateYield: function delegateYield(e, r, n) { return this.delegate = { iterator: values(e), resultName: r, nextLoc: n }, "next" === this.method && (this.arg = t), y; } }, e; } -function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } -function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } -function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } -function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); } -function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } -function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } -function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; } -function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } } -function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } -// @ts-nocheck -import React, { useRef, useState } from 'react'; -import { Descriptions, Modal, Tabs } from 'antd'; -import classNames from 'classnames'; -import { get } from '@zhst/func'; -import "./index.less"; -import Navigation from "./components/navigation"; -var DescriptionsItem = Descriptions.Item; -export var componentPrefix = 'zhst-image'; -var initialStyle = { - fontSize: '12px' -}; -var BigImageModal = function BigImageModal(props) { - var _props$title = props.title, - title = _props$title === void 0 ? '-' : _props$title, - open = props.open, - visible = props.visible, - children = props.children, - _props$descriptionCon = props.descriptionConfig, - descriptionConfig = _props$descriptionCon === void 0 ? { - data: [] - } : _props$descriptionCon, - _props$tabsConfig = props.tabsConfig, - tabsConfig = _props$tabsConfig === void 0 ? { - data: [{ - label: '对比图模式', - key: '1', - children: '对比图组件' - }, { - label: '场景图模式', - key: '2', - children: '场景图组件' - }] - } : _props$tabsConfig, - _props$dataSource = props.dataSource, - dataSource = _props$dataSource === void 0 ? [] : _props$dataSource, - _props$imageData = props.imageData, - imageData = _props$imageData === void 0 ? [] : _props$imageData, - _props$relatedData = props.relatedData, - relatedData = _props$relatedData === void 0 ? [] : _props$relatedData; - var showCropRef = useRef(false); - var scaleRef = useRef(0); - - // ========================== 头切换 ========================= - var _useState = useState(get(tabsConfig, 'data[0].key')), - _useState2 = _slicedToArray(_useState, 2), - activeKey = _useState2[0], - setActiveKey = _useState2[1]; - - // ========================= 预览切换下标 ========================= - var _useState3 = useState(0), - _useState4 = _slicedToArray(_useState3, 2), - previewIndex = _useState4[0], - setPreviewIndex = _useState4[1]; - var _useState5 = useState(false), - _useState6 = _slicedToArray(_useState5, 2), - isRelated = _useState6[0], - setIsRelated = _useState6[1]; - return /*#__PURE__*/React.createElement(Modal, _extends({ - destroyOnClose: true, - open: open || visible, - footer: null, - className: componentPrefix, - title: title - }, props), descriptionConfig.data.map(function (descriptions) { - var _descriptions$childre; - return /*#__PURE__*/React.createElement(Descriptions, { - key: descriptions.title, - title: /*#__PURE__*/React.createElement("p", { - style: { - margin: '12px 0 0', - fontSize: initialStyle.fontSize - } - }, descriptions.title), - column: 8, - style: { - padding: '0 64px' - } - }, descriptions === null || descriptions === void 0 || (_descriptions$childre = descriptions.children) === null || _descriptions$childre === void 0 ? void 0 : _descriptions$childre.map(function (item) { - return /*#__PURE__*/React.createElement(DescriptionsItem, { - key: item.key, - label: item.label, - span: 1, - contentStyle: { - fontSize: initialStyle.fontSize - }, - labelStyle: { - fontSize: initialStyle.fontSize - } - }, item.children); - })); - }), /*#__PURE__*/React.createElement(Tabs, _extends({ - defaultActiveKey: activeKey, - centered: true, - tabBarStyle: { - fontSize: '18px' - }, - items: tabsConfig.data - }, tabsConfig)), /*#__PURE__*/React.createElement("div", { - className: classNames("".concat(componentPrefix, "-view-container")), - style: activeKey === 'TRACK' ? { - height: '718px', - marginBottom: '0px' - } : {} - }, activeKey !== 'TRACK' && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Navigation, { - className: classNames("".concat(componentPrefix, "-view-container__nav"), previewIndex <= 0 && "".concat(componentPrefix, "-view-container__nav--disabled"), "".concat(componentPrefix, "-view-container__nav--left")), - show: isRelated ? imageData.length > 1 : dataSource.length > 1, - disabled: previewIndex <= 0, - prev: true, - onClick: function onClick() { - setPreviewIndex(function (pre) { - return pre - 1; - }); - } - }), /*#__PURE__*/React.createElement(Navigation, { - className: classNames("".concat(componentPrefix, "-view-container__nav"), (previewIndex >= imageData.length - 1 || previewIndex >= dataSource.length - 1) && "".concat(componentPrefix, "-view-container__nav--disabled"), "".concat(componentPrefix, "-view-container__nav--right")), - show: isRelated ? imageData.length > 1 : dataSource.length > 1, - disabled: previewIndex >= imageData.length - 1 || previewIndex >= dataSource.length - 1, - next: true, - onClick: /*#__PURE__*/function () { - var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(e) { - return _regeneratorRuntime().wrap(function _callee$(_context) { - while (1) switch (_context.prev = _context.next) { - case 0: - setPreviewIndex(function (pre) { - return pre + 1; - }); - case 1: - case "end": - return _context.stop(); - } - }, _callee); - })); - return function (_x) { - return _ref.apply(this, arguments); - }; - }() - })))); -}; +import BigImageModal from "./BigImageModal"; export default BigImageModal; \ No newline at end of file diff --git a/packages/biz/es/BigImageModal/index.less b/packages/biz/es/BigImageModal/index.less index b26c6c8..966b5d6 100644 --- a/packages/biz/es/BigImageModal/index.less +++ b/packages/biz/es/BigImageModal/index.less @@ -1,5 +1,4 @@ .zhst-image { - .zhst-dialog-content { box-shadow: 0 4px 12px rgb(0 0 0 / 20%); } @@ -67,256 +66,7 @@ margin-bottom: 24px; } } -.zhst-image__img-view { - position: relative; - width: calc(100% - 46px - 46px - 20px - 20px); - height: 100%; - margin: 0 66px; - &-opt { - position: absolute; - z-index: 99; - top: 0; - } - - &-crop-opt { - position: absolute; - z-index: 99; - top: 0; - right: 0; - } - - &-align { - position: absolute; - top: 0; - left: 0; - pointer-events: none; - } - - &-main { - // height: 532px; - width: 100%; - height: 100%; - - &--cursor { - & canvas { - cursor: pointer !important; - } - } - } - - &-screenshot { - position: absolute; - z-index: 10; - } - - &-attach { - position: absolute; - z-index: 11; - bottom: 0; - - // left: 78px; - left: 0; - min-width: 120px; - height: 202px; - transition: all 200ms; - - &--fixed { - width: 152px !important; - background-color: #fff; - } - - &--zoomin { - height: 532px; - - &--fixed { - width: 398px !important; - } - } - - &__tab { - position: absolute; - top: 0; - left: 0; - display: flex; - - &-item { - display: flex; - width: 30px; - height: 24px; - align-items: center; - justify-content: center; - background: #000; - color: #fff; - cursor: pointer; - font-size: 12px; - opacity: 0.5; - transition: all 200ms; - - &--select { - width: 48px; - height: 34px; - background: #09f; - opacity: 1; - } - } - } - - &__scale { - position: absolute; - top: 4px; - right: 4px; - display: flex; - width: 30px; - height: 30px; - align-items: center; - justify-content: center; - background: rgb(0 0 0 / 60%); - border-radius: 100%; - cursor: pointer; - line-height: 30px; - text-align: center; - } - - &__img { - height: 100%; - object-fit: contain; - - &--fixed { - width: 100%; - object-fit: contain; - } - } - } -} - -.zhst-image__video-view { - position: relative; - overflow: hidden; - width: 100%; - height: 532px; - background-color: #333; - - // &-flv { - // width: 85%; - // } - &-screenshot { - position: absolute; - z-index: 10; - } - - &-crop-container { - position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 0; - } - - &-align { - position: absolute; - top: 0; - left: 0; - pointer-events: none; - } - - &-opt { - position: absolute; - z-index: 99; - bottom: 0; - display: flex; - width: 100%; - height: 32px; - box-sizing: border-box; - align-items: center; - padding: 0 12px; - background-color: rgb(0 0 0 / 80%); - line-height: 32px; - - &>div:first-child { - display: flex; - align-items: center; - margin-right: 12px; - } - - &>div:last-child { - display: flex; - align-items: center; - margin-left: 12px; - } - - &-range { - display: flex; - height: 32px; - flex: 1; - align-items: center; - line-height: 32px; - text-align: center; - - &>div:first-child { - flex: 1; - } - - &>div:last-child { - width: 100px; - margin-left: 8px; - color: #fff; - } - } - } - - &__player-mask { - position: absolute; - z-index: 99; - top: 0; - right: 0; - bottom: 0; - left: 0; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - background-color: rgb(4 4 4 / 70%); - - &--bg { - z-index: 999; - background-color: rgb(4 4 4 / 100%); - } - - i { - cursor: pointer; - } - - &-title { - margin-top: 12px; - color: #fff; - text-align: center; - - & a { - color: #09f; - cursor: pointer; - text-decoration: underline; - } - } - } - - &__icon-wraper { - display: flex; - width: 80px; - height: 80px; - align-items: center; - justify-content: center; - background-color: rgb(255 255 255 / 10%); - border-radius: 50%; - cursor: pointer; - line-height: 80px; - text-align: center; - - // &:hover { - // background: #0099ff; - // } - } -} .zhst-image__tool { display: flex; @@ -504,7 +254,6 @@ display: flex; width: 100%; justify-content: center; - border-color: #f0f0f0; border-bottom-width: 1px; border-bottom-style: solid; @@ -553,57 +302,6 @@ } } -.zhst-image__btn-group { - // display: flex; - width: 30px; - box-shadow: 0 2px 6px 0 rgb(0 0 0 / 40%); - - &__item { - display: flex; - width: 30px; - height: 30px; - align-items: center; - justify-content: center; - background: #000; - - &>button { - padding: 0; - color: #fff; - - &:hover { - color: #09f; - } - - &:active { - color: #09f; - } - - &:focus { - color: #fff; - } - - &>span { - display: flex; - } - } - - &--active { - &>button { - color: #09f; - } - } - } - - &--circle { - background-color: none; - box-shadow: none; - } - - &--circle &__item { - margin-bottom: 4px; - border-radius: 50%; - } -} .zhst-image__compater-view { display: flex; @@ -962,78 +660,6 @@ } } -.zhst-image__score { - display: flex; - flex-direction: column; - align-items: center; - - &-box { - position: relative; - display: flex; - box-sizing: border-box; - align-items: center; - justify-content: center; - margin-bottom: 12px; - border-radius: 50%; - - &-bg { - display: flex; - overflow: hidden; - box-sizing: border-box; - align-items: flex-end; - justify-content: center; - border: 2px solid #fff; - background-color: #fff; - border-radius: 50%; - - &-inner { - width: 100% !important; - height: 0; - } - } - } - - &-score { - position: absolute; - top: 50%; - left: 50%; - color: rgb(0 0 0 / 88%); - font-size: 28px; - transform: translate(-50%, -50%); - } - - &-text { - width: 54px; - height: 24px; - color: rgb(0 0 0 / 88%); - font-size: 18px; - line-height: 24px; - } -} - -.zhst-image__CornerScore { - position: absolute; - right: 0; - bottom: 0; - width: 56px; - height: 22px; - line-height: 22px; - text-align: right; - vertical-align: bottom; - padding-right: 1px; - background-size: 100%; - background-image: url('./images/percent_background.png'); - z-index: 99; - - &>span { - padding-right: 6px; - line-height: 22px; - font-size: 12px; - vertical-align: middle; - color: rgba(255, 255, 255, 1); - } -} - .zhst-image__attributePanel { margin: 0 66px; background: #f6f6f6; @@ -1082,7 +708,6 @@ .relatedContent { width: 100%; height: 100px; - display: flex; .relatedPics { @@ -1108,19 +733,19 @@ } .disabled { - color: rgba(0, 0, 0, 0.25); + color: rgba(0, 0, 0, 25%); } .relatedBtn { flex: 1; font-size: 14px; - color: #333333; + color: #333; display: flex; align-items: flex-end; cursor: pointer; &:hover { - color: #0099ff; + color: #09f; } } } diff --git a/packages/biz/es/BigImageModal/index.temp.js b/packages/biz/es/BigImageModal/index.temp.js deleted file mode 100644 index 227915b..0000000 --- a/packages/biz/es/BigImageModal/index.temp.js +++ /dev/null @@ -1,789 +0,0 @@ -function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } -function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } -function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } -function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } -function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } -function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); } -function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); } -function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return e; }; var t, e = {}, r = Object.prototype, n = r.hasOwnProperty, o = Object.defineProperty || function (t, e, r) { t[e] = r.value; }, i = "function" == typeof Symbol ? Symbol : {}, a = i.iterator || "@@iterator", c = i.asyncIterator || "@@asyncIterator", u = i.toStringTag || "@@toStringTag"; function define(t, e, r) { return Object.defineProperty(t, e, { value: r, enumerable: !0, configurable: !0, writable: !0 }), t[e]; } try { define({}, ""); } catch (t) { define = function define(t, e, r) { return t[e] = r; }; } function wrap(t, e, r, n) { var i = e && e.prototype instanceof Generator ? e : Generator, a = Object.create(i.prototype), c = new Context(n || []); return o(a, "_invoke", { value: makeInvokeMethod(t, r, c) }), a; } function tryCatch(t, e, r) { try { return { type: "normal", arg: t.call(e, r) }; } catch (t) { return { type: "throw", arg: t }; } } e.wrap = wrap; var h = "suspendedStart", l = "suspendedYield", f = "executing", s = "completed", y = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var p = {}; define(p, a, function () { return this; }); var d = Object.getPrototypeOf, v = d && d(d(values([]))); v && v !== r && n.call(v, a) && (p = v); var g = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(p); function defineIteratorMethods(t) { ["next", "throw", "return"].forEach(function (e) { define(t, e, function (t) { return this._invoke(e, t); }); }); } function AsyncIterator(t, e) { function invoke(r, o, i, a) { var c = tryCatch(t[r], t, o); if ("throw" !== c.type) { var u = c.arg, h = u.value; return h && "object" == _typeof(h) && n.call(h, "__await") ? e.resolve(h.__await).then(function (t) { invoke("next", t, i, a); }, function (t) { invoke("throw", t, i, a); }) : e.resolve(h).then(function (t) { u.value = t, i(u); }, function (t) { return invoke("throw", t, i, a); }); } a(c.arg); } var r; o(this, "_invoke", { value: function value(t, n) { function callInvokeWithMethodAndArg() { return new e(function (e, r) { invoke(t, n, e, r); }); } return r = r ? r.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); } }); } function makeInvokeMethod(e, r, n) { var o = h; return function (i, a) { if (o === f) throw new Error("Generator is already running"); if (o === s) { if ("throw" === i) throw a; return { value: t, done: !0 }; } for (n.method = i, n.arg = a;;) { var c = n.delegate; if (c) { var u = maybeInvokeDelegate(c, n); if (u) { if (u === y) continue; return u; } } if ("next" === n.method) n.sent = n._sent = n.arg;else if ("throw" === n.method) { if (o === h) throw o = s, n.arg; n.dispatchException(n.arg); } else "return" === n.method && n.abrupt("return", n.arg); o = f; var p = tryCatch(e, r, n); if ("normal" === p.type) { if (o = n.done ? s : l, p.arg === y) continue; return { value: p.arg, done: n.done }; } "throw" === p.type && (o = s, n.method = "throw", n.arg = p.arg); } }; } function maybeInvokeDelegate(e, r) { var n = r.method, o = e.iterator[n]; if (o === t) return r.delegate = null, "throw" === n && e.iterator.return && (r.method = "return", r.arg = t, maybeInvokeDelegate(e, r), "throw" === r.method) || "return" !== n && (r.method = "throw", r.arg = new TypeError("The iterator does not provide a '" + n + "' method")), y; var i = tryCatch(o, e.iterator, r.arg); if ("throw" === i.type) return r.method = "throw", r.arg = i.arg, r.delegate = null, y; var a = i.arg; return a ? a.done ? (r[e.resultName] = a.value, r.next = e.nextLoc, "return" !== r.method && (r.method = "next", r.arg = t), r.delegate = null, y) : a : (r.method = "throw", r.arg = new TypeError("iterator result is not an object"), r.delegate = null, y); } function pushTryEntry(t) { var e = { tryLoc: t[0] }; 1 in t && (e.catchLoc = t[1]), 2 in t && (e.finallyLoc = t[2], e.afterLoc = t[3]), this.tryEntries.push(e); } function resetTryEntry(t) { var e = t.completion || {}; e.type = "normal", delete e.arg, t.completion = e; } function Context(t) { this.tryEntries = [{ tryLoc: "root" }], t.forEach(pushTryEntry, this), this.reset(!0); } function values(e) { if (e || "" === e) { var r = e[a]; if (r) return r.call(e); if ("function" == typeof e.next) return e; if (!isNaN(e.length)) { var o = -1, i = function next() { for (; ++o < e.length;) if (n.call(e, o)) return next.value = e[o], next.done = !1, next; return next.value = t, next.done = !0, next; }; return i.next = i; } } throw new TypeError(_typeof(e) + " is not iterable"); } return GeneratorFunction.prototype = GeneratorFunctionPrototype, o(g, "constructor", { value: GeneratorFunctionPrototype, configurable: !0 }), o(GeneratorFunctionPrototype, "constructor", { value: GeneratorFunction, configurable: !0 }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, u, "GeneratorFunction"), e.isGeneratorFunction = function (t) { var e = "function" == typeof t && t.constructor; return !!e && (e === GeneratorFunction || "GeneratorFunction" === (e.displayName || e.name)); }, e.mark = function (t) { return Object.setPrototypeOf ? Object.setPrototypeOf(t, GeneratorFunctionPrototype) : (t.__proto__ = GeneratorFunctionPrototype, define(t, u, "GeneratorFunction")), t.prototype = Object.create(g), t; }, e.awrap = function (t) { return { __await: t }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, c, function () { return this; }), e.AsyncIterator = AsyncIterator, e.async = function (t, r, n, o, i) { void 0 === i && (i = Promise); var a = new AsyncIterator(wrap(t, r, n, o), i); return e.isGeneratorFunction(r) ? a : a.next().then(function (t) { return t.done ? t.value : a.next(); }); }, defineIteratorMethods(g), define(g, u, "Generator"), define(g, a, function () { return this; }), define(g, "toString", function () { return "[object Generator]"; }), e.keys = function (t) { var e = Object(t), r = []; for (var n in e) r.push(n); return r.reverse(), function next() { for (; r.length;) { var t = r.pop(); if (t in e) return next.value = t, next.done = !1, next; } return next.done = !0, next; }; }, e.values = values, Context.prototype = { constructor: Context, reset: function reset(e) { if (this.prev = 0, this.next = 0, this.sent = this._sent = t, this.done = !1, this.delegate = null, this.method = "next", this.arg = t, this.tryEntries.forEach(resetTryEntry), !e) for (var r in this) "t" === r.charAt(0) && n.call(this, r) && !isNaN(+r.slice(1)) && (this[r] = t); }, stop: function stop() { this.done = !0; var t = this.tryEntries[0].completion; if ("throw" === t.type) throw t.arg; return this.rval; }, dispatchException: function dispatchException(e) { if (this.done) throw e; var r = this; function handle(n, o) { return a.type = "throw", a.arg = e, r.next = n, o && (r.method = "next", r.arg = t), !!o; } for (var o = this.tryEntries.length - 1; o >= 0; --o) { var i = this.tryEntries[o], a = i.completion; if ("root" === i.tryLoc) return handle("end"); if (i.tryLoc <= this.prev) { var c = n.call(i, "catchLoc"), u = n.call(i, "finallyLoc"); if (c && u) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } else if (c) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); } else { if (!u) throw new Error("try statement without catch or finally"); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } } } }, abrupt: function abrupt(t, e) { for (var r = this.tryEntries.length - 1; r >= 0; --r) { var o = this.tryEntries[r]; if (o.tryLoc <= this.prev && n.call(o, "finallyLoc") && this.prev < o.finallyLoc) { var i = o; break; } } i && ("break" === t || "continue" === t) && i.tryLoc <= e && e <= i.finallyLoc && (i = null); var a = i ? i.completion : {}; return a.type = t, a.arg = e, i ? (this.method = "next", this.next = i.finallyLoc, y) : this.complete(a); }, complete: function complete(t, e) { if ("throw" === t.type) throw t.arg; return "break" === t.type || "continue" === t.type ? this.next = t.arg : "return" === t.type ? (this.rval = this.arg = t.arg, this.method = "return", this.next = "end") : "normal" === t.type && e && (this.next = e), y; }, finish: function finish(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.finallyLoc === t) return this.complete(r.completion, r.afterLoc), resetTryEntry(r), y; } }, catch: function _catch(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.tryLoc === t) { var n = r.completion; if ("throw" === n.type) { var o = n.arg; resetTryEntry(r); } return o; } } throw new Error("illegal catch attempt"); }, delegateYield: function delegateYield(e, r, n) { return this.delegate = { iterator: values(e), resultName: r, nextLoc: n }, "next" === this.method && (this.arg = t), y; } }, e; } -function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } -function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } -function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); } -function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } -function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } -function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; } -function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } } -function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } -// @ts-nocheck -import React, { useEffect, useRef, useState, useMemo } from 'react'; -import { useLatest, useThrottleFn } from 'ahooks'; -import { isFunction, pick, noop, get, isEmpty } from 'lodash-es'; -import classNames from 'classnames'; -import { message, Modal, Tabs as TabPane } from 'antd'; -import KeyCode from 'rc-util/lib/KeyCode'; -import { observer } from 'mobx-react-lite'; -import ImgView from "./ImgView"; -import VideoView from "./VideoView"; -import CompareView from "./CompareView"; -import Tool from "./Tool"; -import Header, { Tabs } from "./Header"; -import Navigation from "./Nav"; -import AttributePanel from "./AttributePanel"; -import { usePropState, cssPrefix, getSolt } from "./utils"; -import { screenshotButtonProp } from "../adapter/BigImageModalAdapter/interface"; -import NullView from "./NullDialog"; -import styles from "./index.module.scss"; -import { generateImg } from '@common/utils'; -import IconFont from "../iconfont/IconFont"; -import addEventListenerWrap from '@common/utils/addEventListener'; -import Carousel from "./Carousel"; -import { doubleClick } from '@common/components/doubleCheck'; -import { store } from '@store/index'; -import { store as achieveStore } from '@pages/archive/store'; -var componentName = cssPrefix; -//查看对比图和场景图组件 -var BigImageDialog = function BigImageDialog(props) { - var _props$hasPre = props.hasPre, - propHasPre = _props$hasPre === void 0 ? false : _props$hasPre, - _props$hasNext = props.hasNext, - propHasNext = _props$hasNext === void 0 ? false : _props$hasNext, - _props$loadNext = props.loadNext, - loadNext = _props$loadNext === void 0 ? noop : _props$loadNext, - _props$loadPre = props.loadPre, - loadPre = _props$loadPre === void 0 ? noop : _props$loadPre, - _props$visible = props.visible, - visible = _props$visible === void 0 ? true : _props$visible, - onClose = props.onClose, - _props$isLoading = props.isLoading, - propIsLoading = _props$isLoading === void 0 ? false : _props$isLoading, - _props$selectIndex = props.selectIndex, - propSelectIndex = _props$selectIndex === void 0 ? 0 : _props$selectIndex, - onSelectIndexChange = props.onSelectIndexChange, - _props$dataSource = props.dataSource, - dataSource = _props$dataSource === void 0 ? [] : _props$dataSource, - _props$relatedData = props.relatedData, - relatedData = _props$relatedData === void 0 ? [] : _props$relatedData, - screenshotButtonRender = props.screenshotButtonRender, - transformPropFunc = props.transformPropFunc, - transformVideoPropFunc = props.transformVideoPropFunc, - _props$defaultModel = props.defaultModel, - defaultModel = _props$defaultModel === void 0 ? 'IMAGE' : _props$defaultModel, - otherImgViewProp = props.imgViewProp, - otherVideoViewProp = props.videoViewProp, - otherCarouselProp = props.carouselProp, - otherToolProp = props.ToolProps, - _props$showTool = props.showTool, - showTool = _props$showTool === void 0 ? true : _props$showTool, - children = props.children, - nullDialogProp = props.nullDialogProp, - _props$showHeader = props.showHeader, - showHeader = _props$showHeader === void 0 ? true : _props$showHeader, - _props$tabsFilter = props.tabsFilter, - tabsFilter = _props$tabsFilter === void 0 ? ['COMPATER', 'NORMAL'] : _props$tabsFilter, - useVirtual = props.useVirtual, - _props$title = props.title, - title = _props$title === void 0 ? '查看大图' : _props$title, - _props$specialTitle = props.specialTitle, - specialTitle = _props$specialTitle === void 0 ? '' : _props$specialTitle, - _props$showCarousel = props.showCarousel, - showCarousel = _props$showCarousel === void 0 ? true : _props$showCarousel, - _props$isRelated = props.isRelated, - isRelated = _props$isRelated === void 0 ? false : _props$isRelated; - console.log('props', props); - //可观测值 - var showCrop$Ref = useRef(false); - var scale$Ref = useRef(0); - var showCrop$ = showCrop$Ref.current; - var scale$ = scale$Ref.current; - // ========================== 头切换 ========================= - var _useState = useState(tabsFilter.length > 1 ? Object.keys(Tabs)[0] : Object.keys(Tabs)[1]), - _useState2 = _slicedToArray(_useState, 2), - tab = _useState2[0], - setTab = _useState2[1]; - var _useState3 = useState('related'), - _useState4 = _slicedToArray(_useState3, 2), - activeKey = _useState4[0], - setActiveKey = _useState4[1]; - var _useState5 = useState(dataSource), - _useState6 = _slicedToArray(_useState5, 2), - similarList = _useState6[0], - setSimilarList = _useState6[1]; // 其他相似目标列表 - var _useState7 = useState(relatedData), - _useState8 = _slicedToArray(_useState7, 2), - relatedList = _useState8[0], - setRelatedList = _useState8[1]; // 已关联列表 - var _useState9 = useState(dataSource), - _useState10 = _slicedToArray(_useState9, 2), - imageData = _useState10[0], - setImageData = _useState10[1]; // 其他相似目标列表 - var lastSimData = useLatest(similarList); - var lastRelatedData = useLatest(relatedList); - - // ========================== 内部转换 ========================= - var _useState11 = useState(defaultModel), - _useState12 = _slicedToArray(_useState11, 2), - model = _useState12[0], - setModel = _useState12[1]; // 图片/视频模式 - useEffect(function () { - if (activeKey === 'unRlated') { - setImageData(lastSimData.current); - setSelectIndex(0); - } - if (activeKey === 'related') { - setImageData(lastRelatedData.current); - setSelectIndex(0); - } - }, [activeKey]); - useEffect(function () { - setSimilarList(dataSource); - if (activeKey === 'unRelated') { - setImageData(dataSource); - } - }, [dataSource]); - var carouseDataSource = useMemo(function () { - return imageData.map(function (v, index) { - return { - url: generateImg(get(v, 'passerbyImage.objectRects.0.fileKey')), - key: index, - passerbyId: get(v, 'passerbyId') - }; - }); - }, [imageData, dataSource]); - - //选择 - var _usePropState = usePropState(propSelectIndex), - _usePropState2 = _slicedToArray(_usePropState, 2), - selectIndex = _usePropState2[0], - setSelectIndex = _usePropState2[1]; - var hasPre = propHasPre ? true : selectIndex > 0; - var changeIndex = isRelated ? imageData.length - 1 : dataSource.length - 1; - var hasNext = propHasNext ? true : selectIndex < changeIndex; - //设置选中 - var latestSelectIndex = useLatest(selectIndex); - var latestDataSource = isRelated ? useLatest(imageData) : useLatest(dataSource); - //加一个防背推 - var seq = useRef(0); - var _useThrottleFn = useThrottleFn( /*#__PURE__*/function () { - var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(arg) { - var _seq, selectIndex, dataSource, newIndex; - return _regeneratorRuntime().wrap(function _callee$(_context) { - while (1) switch (_context.prev = _context.next) { - case 0: - _seq = ++seq.current; - selectIndex = latestSelectIndex.current; - dataSource = latestDataSource.current; - newIndex = isFunction(arg) ? arg(selectIndex) : arg; - if (!(newIndex > dataSource.length - 1)) { - _context.next = 11; - break; - } - if (!propHasNext) { - _context.next = 10; - break; - } - _context.next = 8; - return loadNext(newIndex); - case 8: - _context.next = 11; - break; - case 10: - newIndex = dataSource.length - 1; - case 11: - if (newIndex < 0) { - newIndex = 0; - } - if (!(_seq !== seq.current)) { - _context.next = 14; - break; - } - return _context.abrupt("return"); - case 14: - onSelectIndexChange && onSelectIndexChange(newIndex); - setSelectIndex(newIndex); - case 16: - case "end": - return _context.stop(); - } - }, _callee); - })); - return function (_x) { - return _ref.apply(this, arguments); - }; - }(), { - wait: 500 - }), - setSelectIndexWrapper = _useThrottleFn.run; - - //异步获取数据 - var _useState13 = useState(null), - _useState14 = _slicedToArray(_useState13, 2), - selectItem = _useState14[0], - setSelectItem = _useState14[1]; - var _useState15 = useState(true), - _useState16 = _slicedToArray(_useState15, 2), - isFetching = _useState16[0], - setIsFetching = _useState16[1]; - //人员属性 - var _useState17 = useState([]), - _useState18 = _slicedToArray(_useState17, 2), - attributeList = _useState18[0], - setAttributeList = _useState18[1]; - var isLoading = useMemo(function () { - return propIsLoading || isFetching; - }, [propIsLoading, isFetching]); - useEffect(function () { - _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2() { - var data; - return _regeneratorRuntime().wrap(function _callee2$(_context2) { - while (1) switch (_context2.prev = _context2.next) { - case 0: - setIsFetching(true); - data = {}; - if (!isRelated) { - _context2.next = 8; - break; - } - _context2.next = 5; - return transformPropFunc(imageData[selectIndex]); - case 5: - data = _context2.sent; - _context2.next = 11; - break; - case 8: - _context2.next = 10; - return transformPropFunc(dataSource[selectIndex]); - case 10: - data = _context2.sent; - case 11: - setAttributeList(get(data, 'attributeList', [])); - //防背推 - if (selectIndex === latestSelectIndex.current) { - setSelectItem(data); - setIsFetching(false); - } - case 13: - case "end": - return _context2.stop(); - } - }, _callee2); - }))(); - }, [selectIndex, dataSource, imageData, isRelated]); - var selectqualityScore = useMemo(function () { - return get(selectItem, 'qualityScore'); - }, [selectItem]); - //支持视频url异步获取 - var _useState19 = useState(null), - _useState20 = _slicedToArray(_useState19, 2), - flvUrl = _useState20[0], - setFlvUrl = _useState20[1]; - var _useState21 = useState(null), - _useState22 = _slicedToArray(_useState21, 2), - maxDuration = _useState22[0], - setMaxDuration = _useState22[1]; - useEffect(function () { - _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3() { - var _yield$transformVideo, _flvUrl, _maxDuration; - return _regeneratorRuntime().wrap(function _callee3$(_context3) { - while (1) switch (_context3.prev = _context3.next) { - case 0: - if (!(model === 'IMAGE')) { - _context3.next = 4; - break; - } - setFlvUrl(null); - setMaxDuration(null); - return _context3.abrupt("return"); - case 4: - if (!isFunction(transformVideoPropFunc)) { - _context3.next = 15; - break; - } - //先情空 - setFlvUrl(null); - setMaxDuration(null); - _context3.next = 9; - return transformVideoPropFunc(selectItem); - case 9: - _yield$transformVideo = _context3.sent; - _flvUrl = _yield$transformVideo.flvUrl; - _maxDuration = _yield$transformVideo.maxDuration; - //防背推 - if (selectIndex === latestSelectIndex.current) { - setMaxDuration(_maxDuration); - setFlvUrl(_flvUrl); - } - _context3.next = 17; - break; - case 15: - setFlvUrl(get(selectItem, 'flvUrl')); - setMaxDuration(get(selectItem, 'maxDuration')); - case 17: - case "end": - return _context3.stop(); - } - }, _callee3); - }))(); - }, [selectItem, model]); - - //切换选中index时候变更key 让组件走销毁逻辑 减少大图/视频组件内部逻辑复杂度 - var key = 0; - var imgCmpKey = useMemo(function () { - return "img-key-".concat(key); - }, [key]); - var videoCmpKey = useMemo(function () { - return "video-key-".concat(key); - }, [key]); - - // ========================== 分离参数 ========================= - var CompareViewProp = { - targertImg: generateImg(get(selectItem, 'imgSummary', '')), - // 对比图 - score: get(selectItem, 'score'), - similarScore: get(selectItem, 'similarScore'), - sourceImg: get(selectItem, 'constractKey', '') || get(selectItem, 'compaterImages.0') || generateImg(get(selectItem, 'imgSummary', '')), - compaterImages: get(selectItem, 'compaterImages', []), - specialTitle: specialTitle, - isRelated: isRelated - }; - var carouselProp = _objectSpread({ - selectIndex: selectIndex, - setSelectIndex: setSelectIndexWrapper, - hasPre: hasPre, - hasNext: hasNext, - dataSource: carouseDataSource - }, otherCarouselProp); - var imgViewProp = _objectSpread(_objectSpread(_objectSpread({}, pick(selectItem, ['imageKey', 'odRect', 'attachImg', 'score'])), {}, { - screenshotButtonRender: screenshotButtonRender - }, otherImgViewProp), {}, { - showCrop$: showCrop$, - scale$: scale$ - }); - var videoViewProp = _objectSpread(_objectSpread({ - flvUrl: flvUrl, - maxDuration: maxDuration, - screenshotButtonRender: screenshotButtonRender - }, otherVideoViewProp), {}, { - showCrop$: showCrop$ - }); - var ToolProps = _objectSpread(_objectSpread({}, otherToolProp), {}, { - isGray: true - }); - - // ========================== 插槽参数 ========================= - var imgViewRef = useRef(null); - var VideoViewRef = useRef(null); - scale$; - var param = { - tab: tab, - selectItem: selectItem, - imgViewRef: imgViewRef, - VideoViewRef: VideoViewRef, - model: model, - setModel: setModel, - showCrop$: showCrop$, - scale$: scale$ - }; - var slots = getSolt(children, param); - - // ========================== 监听键盘 ========================= - useEffect(function () { - var onKeyDown = function onKeyDown(event) { - var keyCode = event.keyCode; - if (keyCode === KeyCode.LEFT) { - setSelectIndexWrapper(function (pre) { - return --pre; - }); - } - if (keyCode === KeyCode.RIGHT) { - setSelectIndexWrapper(function (pre) { - return ++pre; - }); - } - }; - document.addEventListener('keydown', onKeyDown); - return function () { - document.removeEventListener('keydownm', onKeyDown); - }; - }, []); - - // ========================== 监听滚轮 ========================= - React.useEffect(function () { - var mousewheelListener = function mousewheelListener(e) { - e.preventDefault(); - var direction = 0; - if (e.wheelDelta) { - //IE/Opera/Chrome - if (e.wheelDelta > 0) { - //向上滚动事件 - direction = 1; - } else { - //向下滚动事件 - direction = -1; - } - } else if (e.detail) { - //Firefox - if (e.detail < 0) { - //向上滚动事件 - direction = 1; - } else { - //向下滚动事件 - direction = -1; - } - } - setSelectIndexWrapper(function (pre) { - return direction < 0 ? pre + 1 : pre - 1; - }); - }; - var handleMouseWheel; - if (store.bigImgScrollEmit) { - handleMouseWheel = addEventListenerWrap(document, 'mousewheel', mousewheelListener); - } else { - var _handleMouseWheel; - (_handleMouseWheel = handleMouseWheel) === null || _handleMouseWheel === void 0 || _handleMouseWheel.remove(); - } - return function () { - var _handleMouseWheel2; - (_handleMouseWheel2 = handleMouseWheel) === null || _handleMouseWheel2 === void 0 || _handleMouseWheel2.remove(); - }; - }, [store.bigImgScrollEmit]); - var tabList = [{ - key: 'related', - label: '关联的目标', - children: /*#__PURE__*/React.createElement("div", { - className: styles.relatedContent - }, showCarousel && /*#__PURE__*/React.createElement("div", { - className: classNames(styles.relatedPics) - }, /*#__PURE__*/React.createElement(Carousel, carouselProp)), /*#__PURE__*/React.createElement("div", { - style: isEmpty(relatedList) ? { - color: 'rgba(0, 0, 0, 0.25)', - cursor: 'not-allowed' - } : {}, - className: classNames(styles.relatedBtn), - onClick: /*#__PURE__*/function () { - var _ref4 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee5(e) { - var archiveId, passerbyId; - return _regeneratorRuntime().wrap(function _callee5$(_context5) { - while (1) switch (_context5.prev = _context5.next) { - case 0: - if (isEmpty(relatedList)) { - e.stopPropagation(); - } else { - try { - archiveId = selectItem.archiveId, passerbyId = selectItem.passerbyId; - if (archiveId && passerbyId) { - doubleClick({ - title: '确认取消关联,取消后可在“其他相似目标推荐”处再次关联', - checkboxLabel: '同时移除档案对应轨迹', - checked: true, - onOk: function () { - var _onOk = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee4() { - var _yield$achieveStore$a, relatedPassersby, _yield$achieveStore$a2, similarPassersby; - return _regeneratorRuntime().wrap(function _callee4$(_context4) { - while (1) switch (_context4.prev = _context4.next) { - case 0: - _context4.prev = 0; - _context4.next = 3; - return achieveStore.archive.UnLinkTarget(passerbyId, archiveId); - case 3: - message.success('目标已成功取消关联!'); - // 更新已关联目标列表 - _context4.next = 6; - return achieveStore.archive.GetRelatedArchive(archiveId); - case 6: - _yield$achieveStore$a = _context4.sent; - relatedPassersby = _yield$achieveStore$a.relatedPassersby; - setRelatedList(relatedPassersby); - setImageData(relatedPassersby); - // 更新当前相似目标列表 - _context4.next = 12; - return achieveStore.archive.GetSimilarPasserbyList(archiveId); - case 12: - _yield$achieveStore$a2 = _context4.sent; - similarPassersby = _yield$achieveStore$a2.similarPassersby; - setSimilarList(similarPassersby); - setSelectIndex(function (pre) { - if (pre > 0) { - return pre - 1; - } else { - return 0; - } - }); - _context4.next = 22; - break; - case 18: - _context4.prev = 18; - _context4.t0 = _context4["catch"](0); - message.success('目标取消关联失败!'); - console.error(_context4.t0); - case 22: - case "end": - return _context4.stop(); - } - }, _callee4, null, [[0, 18]]); - })); - function onOk() { - return _onOk.apply(this, arguments); - } - return onOk; - }() - }); - } - } catch (e) { - console.error(e); - } - } - case 1: - case "end": - return _context5.stop(); - } - }, _callee5); - })); - return function (_x2) { - return _ref4.apply(this, arguments); - }; - }() - }, /*#__PURE__*/React.createElement(IconFont, { - icon: "icon-guanlian", - styles: { - fontWeight: 'bold', - margin: '0px 4px 0px 17px' - }, - size: 16 - }), "\u53D6\u6D88\u5173\u8054")) - }, { - key: 'unRlated', - label: '其他相似目标推荐', - children: /*#__PURE__*/React.createElement("div", { - className: styles.relatedContent - }, showCarousel && /*#__PURE__*/React.createElement("div", { - className: classNames(styles.relatedPics) - }, /*#__PURE__*/React.createElement(Carousel, carouselProp)), /*#__PURE__*/React.createElement("div", { - style: isEmpty(lastSimData.current) ? { - color: 'rgba(0, 0, 0, 0.25)', - cursor: 'not-allowed' - } : {}, - className: classNames(styles.relatedBtn), - onClick: /*#__PURE__*/function () { - var _ref5 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee6(e) { - var archiveId, passerbyId, archiveGroupId, trajectoryId, _yield$achieveStore$a3, similarPassersby, _yield$achieveStore$a4, relatedPassersby; - return _regeneratorRuntime().wrap(function _callee6$(_context6) { - while (1) switch (_context6.prev = _context6.next) { - case 0: - if (!isEmpty(lastSimData.current)) { - _context6.next = 4; - break; - } - e.stopPropagation(); - _context6.next = 28; - break; - case 4: - _context6.prev = 4; - archiveId = selectItem.archiveId, passerbyId = selectItem.passerbyId, archiveGroupId = selectItem.archiveGroupId, trajectoryId = selectItem.trajectoryId; - if (!(archiveId && passerbyId && archiveGroupId && trajectoryId)) { - _context6.next = 22; - break; - } - _context6.next = 9; - return achieveStore.archive.LinkTarget({ - passerbyId: passerbyId, - archiveId: archiveId, - archiveGroupId: archiveGroupId, - trajectoryId: trajectoryId - }); - case 9: - message.success('目标已成功关联!'); - // 更新当前相似目标列表 - _context6.next = 12; - return achieveStore.archive.GetSimilarPasserbyList(archiveId); - case 12: - _yield$achieveStore$a3 = _context6.sent; - similarPassersby = _yield$achieveStore$a3.similarPassersby; - setSimilarList(similarPassersby); - setImageData(similarPassersby); - - // 更新已关联目标列表 - _context6.next = 18; - return achieveStore.archive.GetRelatedArchive(archiveId); - case 18: - _yield$achieveStore$a4 = _context6.sent; - relatedPassersby = _yield$achieveStore$a4.relatedPassersby; - setRelatedList(relatedPassersby); - setSelectIndex(function (pre) { - if (pre > 0) { - return pre - 1; - } else { - return 0; - } - }); - case 22: - _context6.next = 28; - break; - case 24: - _context6.prev = 24; - _context6.t0 = _context6["catch"](4); - message.error('目标关联失败!'); - console.error(_context6.t0); - case 28: - case "end": - return _context6.stop(); - } - }, _callee6, null, [[4, 24]]); - })); - return function (_x3) { - return _ref5.apply(this, arguments); - }; - }() - }, /*#__PURE__*/React.createElement(IconFont, { - icon: "icon-guanlian", - styles: { - fontWeight: 'bold', - margin: '0px 4px 0px 17px' - }, - size: 16 - }), "\u5173\u8054")) - }]; - return /*#__PURE__*/React.createElement(Modal, { - open: visible, - onCancel: onClose, - footer: null, - className: classNames(componentName), - centered: true, - title: title - }, !isEmpty(attributeList) && /*#__PURE__*/React.createElement(AttributePanel, { - attributeList: attributeList - }), showHeader && /*#__PURE__*/React.createElement(Header, { - noBgColor: !isEmpty(attributeList), - value: tab, - onChange: setTab, - tabsFilter: tabsFilter - }), /*#__PURE__*/React.createElement("div", { - className: classNames("".concat(componentName, "-view-container")), - style: tab === 'TRACK' ? { - height: '718px', - marginBottom: '0px' - } : {} - }, tab !== 'TRACK' && /*#__PURE__*/React.createElement(React.Fragment, null, model == 'IMAGE' && tab === 'COMPATER' && !isEmpty(selectItem) && /*#__PURE__*/React.createElement(CompareView, CompareViewProp), !isLoading && model == 'IMAGE' && tab === 'NORMAL' && !isEmpty(selectItem === null || selectItem === void 0 ? void 0 : selectItem.rectList) && /*#__PURE__*/React.createElement(ImgView, _extends({ - key: imgCmpKey - }, imgViewProp, { - ref: imgViewRef - })), !isLoading && model == 'IMAGE' && isEmpty(selectItem) && tab === 'COMPATER' && /*#__PURE__*/React.createElement(NullView, nullDialogProp), !isLoading && model == 'IMAGE' && isEmpty(selectItem.rectList) && tab === 'NORMAL' && /*#__PURE__*/React.createElement(NullView, { - emptyText: isRelated ? '暂无匹配数据' : '暂无数据' - }), !isLoading && model == 'VIDEO' && /*#__PURE__*/React.createElement(VideoView, _extends({ - key: videoCmpKey - }, videoViewProp, { - ref: VideoViewRef - })), /*#__PURE__*/React.createElement(Navigation, { - className: classNames("".concat(componentName, "-view-container__nav"), !hasPre && "".concat(componentName, "-view-container__nav--disabled"), "".concat(componentName, "-view-container__nav--left")), - show: isRelated ? imageData.length !== 1 : dataSource.length !== 1, - disabled: !hasPre, - prev: true, - onClick: function onClick(e) { - if (useVirtual && selectIndex === 0) { - !!loadPre && loadPre(); - //都跳转到第一个 - setSelectIndexWrapper(0); - } else { - setSelectIndexWrapper(function (pre) { - return pre - 1; - }); - } - } - }), /*#__PURE__*/React.createElement(Navigation, { - className: classNames("".concat(componentName, "-view-container__nav"), !hasNext && "".concat(componentName, "-view-container__nav--disabled"), "".concat(componentName, "-view-container__nav--right")), - show: isRelated ? imageData.length !== 1 : dataSource.length !== 1, - disabled: !hasNext, - next: true, - onClick: /*#__PURE__*/function () { - var _ref6 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee7(e) { - return _regeneratorRuntime().wrap(function _callee7$(_context7) { - while (1) switch (_context7.prev = _context7.next) { - case 0: - if (!isRelated) { - _context7.next = 12; - break; - } - if (!(useVirtual && selectIndex === imageData.length - 1)) { - _context7.next = 9; - break; - } - _context7.t0 = !!loadNext; - if (!_context7.t0) { - _context7.next = 6; - break; - } - _context7.next = 6; - return loadNext(); - case 6: - //都跳转到第一个 - setSelectIndexWrapper(0); - _context7.next = 10; - break; - case 9: - setSelectIndexWrapper(function (pre) { - return pre + 1; - }); - case 10: - _context7.next = 21; - break; - case 12: - if (!(useVirtual && selectIndex === dataSource.length - 1)) { - _context7.next = 20; - break; - } - _context7.t1 = !!loadNext; - if (!_context7.t1) { - _context7.next = 17; - break; - } - _context7.next = 17; - return loadNext(); - case 17: - //都跳转到第一个 - setSelectIndexWrapper(0); - _context7.next = 21; - break; - case 20: - setSelectIndexWrapper(function (pre) { - return pre + 1; - }); - case 21: - case "end": - return _context7.stop(); - } - }, _callee7); - })); - return function (_x4) { - return _ref6.apply(this, arguments); - }; - }() - }))), tab !== 'TRACK' && showTool && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", { - className: classNames("".concat(componentName, "-tool-container")) - }, /*#__PURE__*/React.createElement(Tool, _extends({}, ToolProps, { - param: param - }))), slots['after-tool']), !!selectqualityScore && store.user.isfaceScore && model == 'IMAGE' && tab === 'NORMAL' && /*#__PURE__*/React.createElement("div", { - style: isRelated ? { - bottom: 220 - } : { - bottom: 90 - }, - slot: 'after-tool', - className: classNames("".concat(componentName, "__face-score")) - }, "\u4EBA\u8138\u8D28\u91CF\u5206\uFF1A".concat(selectqualityScore.toFixed(2))), isRelated && tab !== 'TRACK' && /*#__PURE__*/React.createElement("div", { - className: styles.relatedWrapper - }, /*#__PURE__*/React.createElement(TabPane, { - className: styles.relatedTabs, - tabPosition: 'left', - activeKey: activeKey, - onChange: function onChange(key) { - setActiveKey(key); - }, - items: tabList.map(function (item) { - return { - label: item.label, - key: item.key, - children: item.children - }; - }) - }))); -}; -export default observer(BigImageDialog); \ No newline at end of file diff --git a/packages/biz/es/BigImageModal/mock.d.ts b/packages/biz/es/BigImageModal/mock.d.ts new file mode 100644 index 0000000..257ed75 --- /dev/null +++ b/packages/biz/es/BigImageModal/mock.d.ts @@ -0,0 +1,294 @@ +export declare const IMAGE_DATA: { + enAbleDeleteFeature: boolean; + tabsFilter: string[]; + dataSources: { + objectId: string; + condition: { + featureInfo: null; + featureData: string; + imageData: string; + alg: string; + rect: { + x: number; + y: number; + w: number; + h: number; + }; + objectImageUrl: string; + srcImageUrl: string; + }; + score: number; + timestamp: number; + deviceId: string; + id: string; + name: string; + dirid: string; + status: string; + longitude: number; + latitude: number; + caseId: string; + caseGroup: string; + isDeleted: string; + extendInfo: { + vmsPlatformId: string; + vmsChannel: string; + vmsCameraDecoderTag: string; + platformPluginType: string; + deviceVender: string; + type: string; + ip: string; + port: string; + username: string; + passwd: string; + rtspAddress: string; + facesnapChannel: string; + edgeDeviceSn: string; + platform1400Id: number; + useRtspAddress: boolean; + frameCheck: boolean; + frameRectX: number; + frameRectY: number; + frameRectW: number; + frameRectH: number; + edgeNodeId: string; + processStatus: string; + }; + objectIndex: { + objectId: string; + solutionId: string; + deviceId: string; + fragmentId: string; + }; + objectType: string; + isObjectTrack: boolean; + pathId: string; + frameInfo: { + frameId: string; + frameTimestamp: string; + width: number; + height: number; + originWidth: number; + originHeight: number; + offsetTime: string; + skipNumber: string; + }; + level: number; + bboxInFrame: { + x: number; + y: number; + w: number; + h: number; + }; + bboxExtInFrame: { + x: number; + y: number; + w: number; + h: number; + }; + objectImageKey: string; + objectExtImageKey: string; + frameImageKey: string; + confidence: number; + sourceObjectId: string; + storeTimestamp: string; + gbNumber: string; + qualityScore: number; + subObjectCount: number; + subObjectType: string[]; + subObjectIds: string[]; + cameraInfo: { + id: string; + name: string; + dirid: string; + status: string; + longitude: number; + latitude: number; + caseId: string; + caseGroup: string; + isDeleted: string; + extendInfo: { + vmsPlatformId: string; + vmsChannel: string; + vmsCameraDecoderTag: string; + platformPluginType: string; + deviceVender: string; + type: string; + ip: string; + port: string; + username: string; + passwd: string; + rtspAddress: string; + facesnapChannel: string; + edgeDeviceSn: string; + platform1400Id: number; + useRtspAddress: boolean; + frameCheck: boolean; + frameRectX: number; + frameRectY: number; + frameRectW: number; + frameRectH: number; + edgeNodeId: string; + processStatus: string; + }; + }; + solutionId: string; + fragmentId: string; + contrastKey: string; + compaterImages: string[]; + imgSummary: string; + imageKey: string; + srcImageUrl: string; + algorithmVersion: string; + cameraId: string; + cameraName: string; + }[]; + selectIndex: number; + disableBtn: number[]; + dataSource: { + objectId: string; + condition: { + featureInfo: null; + featureData: string; + imageData: string; + alg: string; + rect: { + x: number; + y: number; + w: number; + h: number; + }; + objectImageUrl: string; + srcImageUrl: string; + }; + score: number; + timestamp: number; + deviceId: string; + id: string; + name: string; + dirid: string; + status: string; + longitude: number; + latitude: number; + caseId: string; + caseGroup: string; + isDeleted: string; + extendInfo: { + vmsPlatformId: string; + vmsChannel: string; + vmsCameraDecoderTag: string; + platformPluginType: string; + deviceVender: string; + type: string; + ip: string; + port: string; + username: string; + passwd: string; + rtspAddress: string; + facesnapChannel: string; + edgeDeviceSn: string; + platform1400Id: number; + useRtspAddress: boolean; + frameCheck: boolean; + frameRectX: number; + frameRectY: number; + frameRectW: number; + frameRectH: number; + edgeNodeId: string; + processStatus: string; + }; + objectIndex: { + objectId: string; + solutionId: string; + deviceId: string; + fragmentId: string; + }; + objectType: string; + isObjectTrack: boolean; + pathId: string; + frameInfo: { + frameId: string; + frameTimestamp: string; + width: number; + height: number; + originWidth: number; + originHeight: number; + offsetTime: string; + skipNumber: string; + }; + level: number; + bboxInFrame: { + x: number; + y: number; + w: number; + h: number; + }; + bboxExtInFrame: { + x: number; + y: number; + w: number; + h: number; + }; + objectImageKey: string; + objectExtImageKey: string; + frameImageKey: string; + confidence: number; + sourceObjectId: string; + storeTimestamp: string; + gbNumber: string; + qualityScore: number; + subObjectCount: number; + subObjectType: string[]; + subObjectIds: string[]; + cameraInfo: { + id: string; + name: string; + dirid: string; + status: string; + longitude: number; + latitude: number; + caseId: string; + caseGroup: string; + isDeleted: string; + extendInfo: { + vmsPlatformId: string; + vmsChannel: string; + vmsCameraDecoderTag: string; + platformPluginType: string; + deviceVender: string; + type: string; + ip: string; + port: string; + username: string; + passwd: string; + rtspAddress: string; + facesnapChannel: string; + edgeDeviceSn: string; + platform1400Id: number; + useRtspAddress: boolean; + frameCheck: boolean; + frameRectX: number; + frameRectY: number; + frameRectW: number; + frameRectH: number; + edgeNodeId: string; + processStatus: string; + }; + }; + solutionId: string; + fragmentId: string; + contrastKey: string; + compaterImages: string[]; + imgSummary: string; + imageKey: string; + srcImageUrl: string; + algorithmVersion: string; + cameraId: string; + cameraName: string; + }[]; + isArchiveDetail: boolean; + ToolProps: { + renderVideoBtn: boolean; + disableVideo: boolean; + }; + specialTitle: string; +}; diff --git a/packages/biz/es/Demo/index.d.ts b/packages/biz/es/Demo/index.d.ts new file mode 100644 index 0000000..bcc157c --- /dev/null +++ b/packages/biz/es/Demo/index.d.ts @@ -0,0 +1,3 @@ +import React from 'react'; +declare const _default: () => React.JSX.Element; +export default _default; diff --git a/packages/biz/es/adapter/BigImageModalAdapter/index.d.ts b/packages/biz/es/adapter/BigImageModalAdapter/index.d.ts new file mode 100644 index 0000000..dab889b --- /dev/null +++ b/packages/biz/es/adapter/BigImageModalAdapter/index.d.ts @@ -0,0 +1,153 @@ +/** + * 适配老的大屏组件数据格式传入 + */ +import React from 'react'; +import { AlgorithmVersionStr, HumanProperty, ObjectType, Rect, ViewOption, AlignType, IScreenshotButtonProp, ODRECT } from '@zhst/types'; +export type TAB_TYPE = 'COMPATER' | 'NORMAL' | 'TRACK'; +export type MODEL_TYPE = 'VIDEO' | 'IMAGE'; +export interface ImgViewProps extends React.HTMLAttributes { + imageKey: string; + odRect: ODRECT; + attachImg?: Array<{ + label: string; + url: string; + }>; + showAttachImgLabel: boolean; + screenshotButtonAlign: AlignType; + screenshotButtonRender: (screenshotButtonProp: IScreenshotButtonProp) => React.ReactElement; + scale$?: number; + showCrop$?: boolean; + hideLeftTopBtn?: boolean; + score?: number; + viewOption?: ViewOption; +} +export interface VideoViewProps { + flvUrl: string; + maxDuration?: number; + screenshotButtonAlign?: AlignType; + screenshotButtonRender?: (screenshotButtonProp: IScreenshotButtonProp) => React.ReactElement; + defautlNormalizationRect?: Rect; + onCropChange?: (showCrop: boolean, normalizationRect: null | Rect) => void; + showCrop$?: boolean; +} +export interface CarouselProps { + hasPre?: boolean; + hasNext?: boolean; + selectIndex: number; + setSelectIndex: React.Dispatch>; + dataSource: Array<{ + key: string; + url: string; + }>; +} +export type ISelectItem = Partial> & Partial>; +export interface HeaderProps { + value: TAB_TYPE; + onChange: (type: TAB_TYPE) => void; + tabsFilter: TAB_TYPE[]; +} +export interface ImgViewRef { + imgInsRef: React.MutableRefObject; + setShowCrop: React.Dispatch>; +} +export interface VideoViewRef { + cropAble: boolean; + setShowCrop: React.Dispatch>; + downloadVideoframe: () => void; +} +export interface ParamProps { + tab: string; + selectItem: ISelectItem; + imgViewRef: React.MutableRefObject; + VideoViewRef: React.MutableRefObject; + model: MODEL_TYPE; + setModel: React.Dispatch>; + scale$: number; + showCrop$: boolean; +} +export interface BigImageData { + extendRectList: (Rect & { + algorithmVersion: AlgorithmVersionStr; + imageKey: string; + })[]; + rectList: (Rect & { + algorithmVersion: AlgorithmVersionStr; + imageKey: string; + })[]; + attachImg: { + url: string; + label: '形体' | '人脸'; + }[]; + odRect: Rect; + imageKey: string; + imgSummary: string; + objectExtImageKey: string; + attributeList: { + label: string; + list: any[]; + }[]; + archiveImages?: any; + spaceName: string; + objectType: ObjectType; + objectId: string; + bodyObjectId?: string; + faceObjectId?: string; + sourceObjectId?: string; + cameraId: string; + cameraName: string; + selectIndex: number; + humanProperty: HumanProperty; + qualityScore?: number; + score: number; + timestamp: string; + bodyImageUrl: string; + faceImageUrl: string; + algorithmVersion: AlgorithmVersionStr; + bodySpaceName: string; + faceSpaceName: string; + solutionId?: string; + [index: string]: any; +} +interface IOldImageData { + visible?: boolean; + defaultModel?: MODEL_TYPE; + onClose?: () => void; + isLoading?: boolean; + hasPre?: boolean; + hasNext?: boolean; + selectIndex?: number; + onSelectIndexChange?: (i: number) => void; + dataSource: any[]; + dataSources: any[]; + relatedData?: any[]; + transformPropFunc: (item: any) => ISelectItem; + transformVideoPropFunc: (item: ISelectItem) => Promise>; + screenshotButtonRender?: (screenshotButtonProp: IScreenshotButtonProp) => React.ReactElement; + showTool?: boolean; + showCarousel?: boolean; + imgViewProp?: Partial; + videoViewProp?: Partial; + ToolProps?: Partial; + nullDialogProp?: { + emptyText?: string; + }; + showHeader?: boolean; + tabsFilter?: TAB_TYPE[]; + useVirtual?: boolean; + loadNext?: (i: number) => Promise; + loadPre?: (i: number) => Promise; + children: React.ReactNode; + title?: string; + specialTitle?: string; + isRelated?: boolean; + carouselProp?: Partial; +} +export interface ToolProps { + renderRight?: (props: ParamProps) => React.ReactNode; + renderLeft?: (props: ParamProps) => React.ReactNode; + renderVideoBtn?: boolean; + param: ParamProps; + disableVideo: boolean; +} +declare const _default: (data: IOldImageData) => IOldImageData; +export default _default; diff --git a/packages/biz/es/adapter/BigImageModalAdapter/interface.d.ts b/packages/biz/es/adapter/BigImageModalAdapter/interface.d.ts deleted file mode 100644 index 6ba15d7..0000000 --- a/packages/biz/es/adapter/BigImageModalAdapter/interface.d.ts +++ /dev/null @@ -1,217 +0,0 @@ -export type CamerasStatusList = [string[], string[], string[]]; - -export type Rect = { x: number; y: number; w: number; h: number }; - -export type StatusList = { - taskOverview: any; - taskIndex: { - deviceId: string; - solutionId: string; - }; -}[]; - -export enum OperationType { - OPERATION_TYPE_UNKNOW, // 未知状态,传该值会报错 - OPERATION_TYPE_START, - OPERATION_TYPE_STOP -} - - -export enum AlgorithmVersion { - VERSION_MGN_BNN, // MGN+BNN算法 - VERSION_BNN_PRO, // BNNPRO算法 - VERSION_BNN_PRO_ATTR, // BNNPROATTR算法 - VERSION_BNN_PRO_ATTR_SCORE, // BNNPROATTR算法 - VERSION_FACE, // 人脸算法 - VERSION_HEAD, // 头肩算法 - VERSION_NON_MOTOR_VEHICLE, // 非机动车的算法 - VERSION_REID_HEAD_ATTR, // 形体头肩属性三种特征融合的算法 - VERSION_MOTOR_VEHICLE, // 机动车的算法 -} - -export enum AlgorithmVersionStr { - VERSION_MGN_BNN = 'VERSION_MGN_BNN', // MGN+BNN算法 - VERSION_BNN_PRO = 'VERSION_BNN_PRO', // BNNPRO算法 - VERSION_BNN_PRO_ATTR = 'VERSION_BNN_PRO_ATTR', // BNNPROATTR算法 - VERSION_BNN_PRO_ATTR_SCORE = 'VERSION_BNN_PRO_ATTR_SCORE', // BNNPROATTR算法 - VERSION_FACE = 'VERSION_FACE', // 人脸算法 - VERSION_HEAD = 'VERSION_HEAD', // 头肩算法 - VERSION_NON_MOTOR_VEHICLE = 'VERSION_NON_MOTOR_VEHICLE', // 非机动车的算法 - VERSION_REID_HEAD_ATTR = 'VERSION_REID_HEAD_ATTR', // 形体头肩属性三种特征融合的算法 - VERSION_MOTOR_VEHICLE = 'VERSION_MOTOR_VEHICLE', // 机动车的算法 -} - -类型枚举 -export enum ObjectType { - OBJECT_TYPE_NULL, - OBJECT_TYPE_PEDESTRAIN, - OBJECT_TYPE_BICYCLE, - OBJECT_TYPE_CAR, - OBJECT_TYPE_MOTORBIKE, - OBJECT_TYPE_AEROPLANE, - OBJECT_TYPE_BUS, - OBJECT_TYPE_TRAIN, - OBJECT_TYPE_TRUCK, - OBJECT_TYPE_MOTOR_RIDER, - OBJECT_TYPE_BIKE_RIDER, - OBJECT_TYPE_MAX, - OBJECT_TYPE_FACE = 101, -} - -// 性别 -export enum Gender { - GENDER_NONE = 'GENDER_NONE', - GENDER_MAN = 'GENDER_MAN', - GENDER_WOMAN = 'GENDER_WOMAN', -} - -// 年龄 -export enum Age { - AGE_ALL = 'AGE_ALL', - AGE_ZERO = 'AGE_ZERO', - AGE_OVERENGHTEEN = 'AGE_OVERENGHTEEN', - AGE_OVERSIXTY = 'AGE_OVERSIXTY', -} - -// 戴帽子状态 -export enum Hat { - HAT_ALL = 'HAT_ALL', - HAT_NONE = 'HAT_NONE', - HAT_OWNED = 'HAT_OWNED', -} - -// 颜色 -export enum Color { - COLOR_ALL = 'COLOR_ALL', - COLOR_BLACK = 'COLOR_BLACK', - COLOR_WHITE = 'COLOR_WHITE', - COLOR_GRAY = 'COLOR_GRAY', - COLOR_BROWN = 'COLOR_BROWN', - COLOR_PINK = 'COLOR_PINK', - COLOR_REDANDORANGE = 'COLOR_REDANDORANGE', - COLOR_YELLOW = 'COLOR_YELLOW', - COLOR_GREEN = 'COLOR_GREEN', - COLOR_BLUE = 'COLOR_BLUE', - COLOR_PURPLE = 'COLOR_PURPLE', -} - -// 背包 -export enum Package { - PACKAGE_ALL = 'PACKAGE_ALL', - PACKAGE_HANDBAG = 'PACKAGE_HANDBAG', - PACKAGE_BACKPACK = 'PACKAGE_BACKPACK', - PACKAGE_SHOULDERBAG = 'PACKAGE_SHOULDERBAG', - PACKAGE_OTHER = 'PACKAGE_OTHER', - PACKAGE_NONE = 'PACKAGE_NONE', -} - -// 行走模式 -export enum WalkPattern { - WALKPATTERN_ALL = 'WALKPATTERN_ALL', - WALKPATTERN_WALK = 'WALKPATTERN_WALK', - WALKPATTERN_RIDING = 'WALKPATTERN_RIDING', -} - -// 人类属性 -export interface HumanProperty { - age: Age; - downColor: Color; - gender: Gender; - hat: Hat; - package: Package; - upColor: Color; - walkPattern: WalkPattern; -} - -// 人类属性枚举 -export interface EnumHumanProperty { - Gender: typeof Gender; - Age: typeof Age; - Hat: typeof Hat; - Color: typeof Color; - Package: typeof Package; - WalkPattern: typeof WalkPattern; -} - -export interface IScreenshotButtonProp { - model: 'VIDEO' | 'IMAGE'; - getCropInfo: () => Promise; - setShowCrop: React.Dispatch>; - cropType: typeof cropType[number]; - selectAlgorithmVersion: number; -} - -export interface AlignType { - /** - * move point of source node to align with point of target node. - * Such as ['tr','cc'], align top right point of source node with center point of target node. - * Point can be 't'(top), 'b'(bottom), 'c'(center), 'l'(left), 'r'(right) */ - points?: AlignPoint[]; - /** - * offset source node by offset[0] in x and offset[1] in y. - * If offset contains percentage string value, it is relative to sourceNode region. - */ - offset?: number[]; - /** - * offset target node by offset[0] in x and offset[1] in y. - * If targetOffset contains percentage string value, it is relative to targetNode region. - */ - targetOffset?: number[]; - /** - * If adjustX field is true, will adjust source node in x direction if source node is invisible. - * If adjustY field is true, will adjust source node in y direction if source node is invisible. - */ - overflow?: { - adjustX?: boolean | number; - adjustY?: boolean | number; - }; - /** - * Whether use css right instead of left to position - */ - useCssRight?: boolean; - /** - * Whether use css bottom instead of top to position - */ - useCssBottom?: boolean; - /** - * Whether use css transform instead of left/top/right/bottom to position if browser supports. - * Defaults to false. - */ - useCssTransform?: boolean; - ignoreShake?: boolean; -} - -export type ODRECT = { - topleft: { - x: number; - y: number; - }; - width: number; - height: number; -}; - -export interface ViewOption { - /* 图片url */ - image?: string | HTMLImageElement; - - /* 缩放灵敏度(0,1],default: 0.1 */ - wheelZoomRatio?: number; - - /* - * 是否允许缩放 - * @default: true - */ - scaleAble?: boolean; - - /* - * 是否允许拖拽 - * @default: true - */ - dragAble?: boolean; - - /* - * fit scale 作为 最小缩放 - * @default: false - */ - fitScaleAsMinScale?: boolean; -} diff --git a/packages/biz/es/adapter/index.d.ts b/packages/biz/es/adapter/index.d.ts new file mode 100644 index 0000000..f1dd564 --- /dev/null +++ b/packages/biz/es/adapter/index.d.ts @@ -0,0 +1 @@ +export { default as BigImageModalAdapter } from './BigImageModalAdapter'; diff --git a/packages/biz/es/hooks/useIntelligentTracking/index.d.ts b/packages/biz/es/hooks/useIntelligentTracking/index.d.ts new file mode 100644 index 0000000..c1e54ef --- /dev/null +++ b/packages/biz/es/hooks/useIntelligentTracking/index.d.ts @@ -0,0 +1,45 @@ +import { Dayjs as Moment } from 'dayjs'; +export declare const getDefaultRadius: () => number; +export declare const setDefaultRadius: (radius: number) => void; +export declare const setSearchIntervalDuration: (duration: number) => void; +export declare const getSearchIntervalDuration: (time: number) => number; +export declare const operateTrackById: (smartTrackId: number, operationType: OperationType) => Promise; +export declare const deleteTrackById: (smartTrackId: number) => Promise; +export declare const modifyTrackImgs: (smartTrackId: number, images: Array) => Promise; +export declare const modifyTrackConf: (conf: any, smartTrackId: number) => Promise; +export declare const getTrackTaskById: (smartTrackId?: number) => Promise; +export declare const getTackDetailInfo: (smartTrackId?: number) => Promise; +export declare const getTaskCameraByCenterAndPower: (value: { + taskPower: { + facePower: number; + bodyPower: number; + }; + cameraInfos: Array; + center: [number, number]; +}) => Promise; +/**创建追踪任务 */ +export declare const createIntelligentTrack: (value: { + images: Array; + deviceIds: Array; + circleCenter: [number, number]; + model: number; + circleRadius: number; + facePower?: number; + bodyPower?: number; + historyTime?: [Moment, Moment]; + topping?: boolean; +}) => Promise; +export declare const emitHeartbeat: (smartTrackId: number) => Promise; +export declare const ModifyTrackCameras: (value: { + smartTrackId: number; + deviceIds: Array; + centerPoint: [number, number]; +}) => Promise; +export declare const setIntelligentTrackCircleInfo: (smartTrackId: number, circleCenter: [number, number]) => Promise; +export declare const getTackCameraInfo: (value: { + circleCenter: [Moment, Moment]; + radius: number; + zoom: number; +}) => Promise; +export declare const getCameraInfoByCircle: (circleCenter: any, radius: any, zoom?: number) => Promise; +export declare const taskInfoToSearchItem: (taskInfo: any) => any[]; diff --git a/packages/biz/es/index.d.ts b/packages/biz/es/index.d.ts new file mode 100644 index 0000000..ac47c74 --- /dev/null +++ b/packages/biz/es/index.d.ts @@ -0,0 +1,3 @@ +export { default as Demo } from './Demo'; +export * from './adapter'; +export { default as BigImageModal } from './BigImageModal'; diff --git a/packages/biz/es/useSocket/index.d.ts b/packages/biz/es/useSocket/index.d.ts new file mode 100644 index 0000000..08018b5 --- /dev/null +++ b/packages/biz/es/useSocket/index.d.ts @@ -0,0 +1,26 @@ +export declare const SocketApi: { + CameraTaskStatue: string; + DeviceStatus: string; + SubscribeSolutionDeploy: string; + SubscribeTasksSummary: string; + MonitorSubscribeResult: string; + MonitorSubscribeStatus: string; + SubscribeArchiveGroupUpload: string; + SubscribeJointTask: string; + SubscribeGroupFragment: string; + SubscribeGroup: string; + SubscribeStreamEvent: string; +}; +type ApiKeys = keyof typeof SocketApi; +declare const _default: (topic: ApiKeys, iterator?: any, opt?: { + req?: { + [key: string]: any; + } | undefined; + throttle?: number | undefined; + parseData?: boolean | undefined; + beforeLoopTmp?: Function | undefined; + shouldBreak: boolean; + forceRefresh: any; + close?: boolean | undefined; +} | undefined) => void; +export default _default; diff --git a/packages/biz/es/useSocket/onceChannel.d.ts b/packages/biz/es/useSocket/onceChannel.d.ts new file mode 100644 index 0000000..400ffa7 --- /dev/null +++ b/packages/biz/es/useSocket/onceChannel.d.ts @@ -0,0 +1,2 @@ +declare const startChannel: (topic: any, req: any, callback: any) => () => void; +export default startChannel; diff --git a/packages/biz/es/useSocket/ws.d.ts b/packages/biz/es/useSocket/ws.d.ts new file mode 100644 index 0000000..cb4f172 --- /dev/null +++ b/packages/biz/es/useSocket/ws.d.ts @@ -0,0 +1,31 @@ +/// +/// +/// +/// +/// +declare class Channel { + /** + * io 实例化对象 + */ + ioIns: any; + /** + * 已存在的订阅列表 + */ + listeners: never[]; + /** + * 调试信息 记录订阅/反订阅次数 + */ + subscribeListenerId: never[]; + unSubscribeListenerId: never[]; + init: () => void; + retry: (listener: { + [x: string]: any; + lastRetryInterval: number | undefined; + intervalId: NodeJS.Timeout; + } | undefined) => void; + doEmit: (topic: any, req: any, listenerId: any) => void; + subscribe(topic: any, req: any, handle: any): () => void; + unSubscribe(topic: any, req: any, handleId: any, listenerId: any): void; +} +declare const channelIns: Channel; +export default channelIns; diff --git a/packages/biz/es/useSocket/ws.js b/packages/biz/es/useSocket/ws.js index 9e15735..8e53d9c 100644 --- a/packages/biz/es/useSocket/ws.js +++ b/packages/biz/es/useSocket/ws.js @@ -5,6 +5,7 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); } function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); } +// @ts-nocheck import { v4 as uuidv4 } from 'uuid'; import { has } from '@zhst/func'; import io from 'socket.io-client'; diff --git a/packages/biz/es/utils/constants.d.ts b/packages/biz/es/utils/constants.d.ts new file mode 100644 index 0000000..45a9a99 --- /dev/null +++ b/packages/biz/es/utils/constants.d.ts @@ -0,0 +1,23 @@ +export declare const OBJECT_GRNER_THRESHOLD = 0.8; +export declare const OBJECT_AGE_TYPE_THRESHOLD = 0.5; +export declare const MODE_KEY = "test_mode"; +export declare const SEARCH_IMG_COUNT = 10; +export declare const GLOBAL_IS_ITEM_NUMBER_SHOW = false; +export declare const publicPath = "hummingbird"; +export declare const ENTER_CIRCLE = "MONITORTYPE_ENTER_CIRCLE"; +export declare const OUT_CIRCLE = "MONITORTYPE_OUT_CIRCLE"; +export declare const TEMP = "MONITORTYPE_TEMP"; +export declare const GLOBAL_IS_BOX_VMS_SHOW = true; +export declare const BODY_SEARCH_THRESHOID = 0.45; +export declare const RECORD_VERSION = "3.0.0"; +export declare const DeviceTab: { + EMPTY: number; + REAL_CAMERA: number; + PREPROCESS_CAMERA: number; + TAG_CAMERA: number; + HISTORY_VIDEO_GROUP: number; + VIRTUAL_CAMERA: number; + REAL_CAMERA_NOFACE: number; + REAL_CAMERA_ONLYFACE: number; + REAL_CAMERA_NOFACE_NOBOX_NODIRECONNECT: number; +}; diff --git a/packages/biz/es/utils/constants.js b/packages/biz/es/utils/constants.js index 7cb4646..1ad86ba 100644 --- a/packages/biz/es/utils/constants.js +++ b/packages/biz/es/utils/constants.js @@ -1,16 +1,6 @@ -export var isDev = import.meta.env.DEV; -export var host = isDev ? 'http://10.0.0.7' : "".concat(location.protocol, "//").concat(location.hostname); -export var port = isDev ? '30003' : location.port; -export var ProjectUrl = "".concat(host, ":").concat(port); -export var MANAGER_URL = port ? ProjectUrl + '/manager' : host + '/manager'; -export var S3_HOST = location.port ? "".concat(host, ":").concat(port) : host; -export var MapUrl = port ? ProjectUrl + '/map' : host + '/map'; -export var S3_V3_HOST = host; //minio 地址 -export var SOCKET_HOST = port ? ProjectUrl : host; export var OBJECT_GRNER_THRESHOLD = 0.8; //目标图判断性别阈值 export var OBJECT_AGE_TYPE_THRESHOLD = 0.5; //目标图判断年龄段阈值 export var MODE_KEY = 'test_mode'; -export var ROUTER_SHOULD_FILTER = isDev; //是否根据后台配置路由,开发环境全打开 //业务约定 export var SEARCH_IMG_COUNT = 10; //检索图片的最大个数 export var GLOBAL_IS_ITEM_NUMBER_SHOW = false; //是否展示索引 diff --git a/packages/biz/es/global.d.ts b/packages/biz/es/utils/index.d.ts similarity index 100% rename from packages/biz/es/global.d.ts rename to packages/biz/es/utils/index.d.ts diff --git a/packages/biz/lib/BigImageModal/BigImageModal.d.ts b/packages/biz/lib/BigImageModal/BigImageModal.d.ts new file mode 100644 index 0000000..05eab4a --- /dev/null +++ b/packages/biz/lib/BigImageModal/BigImageModal.d.ts @@ -0,0 +1,23 @@ +import React from 'react'; +import type { ModalProps, DescriptionsProps, TabsProps } from 'antd'; +import './index.less'; +export declare const componentPrefix = "zhst-image"; +export interface BigImageModalProps extends ModalProps { + visible: boolean; + descriptionConfig: { + data: { + title: string; + children: Pick; + }[]; + }; + tabsConfig: { + data: Pick & { + key: 'NORMAL' | 'COMPATER' | 'TRACK'; + }; + }; + dataSource: any; + imageData: any; + relatedData: any; +} +declare const BigImageModal: React.FC; +export default BigImageModal; diff --git a/packages/biz/lib/BigImageModal/BigImageModal.js b/packages/biz/lib/BigImageModal/BigImageModal.js new file mode 100644 index 0000000..7973124 --- /dev/null +++ b/packages/biz/lib/BigImageModal/BigImageModal.js @@ -0,0 +1,169 @@ +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// src/BigImageModal/BigImageModal.tsx +var BigImageModal_exports = {}; +__export(BigImageModal_exports, { + componentPrefix: () => componentPrefix, + default: () => BigImageModal_default +}); +module.exports = __toCommonJS(BigImageModal_exports); +var import_react = __toESM(require("react")); +var import_antd = require("antd"); +var import_classnames = __toESM(require("classnames")); +var import_func = require("@zhst/func"); +var import_index = require("./index.less"); +var import_navigation = __toESM(require("./components/navigation")); +var DescriptionsItem = import_antd.Descriptions.Item; +var componentPrefix = "zhst-image"; +var initialStyle = { + fontSize: "12px" +}; +var BigImageModal = (props) => { + const { + title = "-", + open, + visible, + children, + descriptionConfig = { + data: [] + }, + tabsConfig = { + data: [ + { + label: "对比图模式", + key: "1", + children: "对比图组件" + }, + { + label: "场景图模式", + key: "2", + children: "场景图组件" + } + ] + }, + dataSource = [], + imageData = [], + relatedData = [] + } = props; + const showCropRef = (0, import_react.useRef)(false); + const scaleRef = (0, import_react.useRef)(0); + const [activeKey, setActiveKey] = (0, import_react.useState)((0, import_func.get)(tabsConfig, "data[0].key")); + const [previewIndex, setPreviewIndex] = (0, import_react.useState)(0); + const [isRelated, setIsRelated] = (0, import_react.useState)(false); + return /* @__PURE__ */ import_react.default.createElement( + import_antd.Modal, + { + destroyOnClose: true, + open: open || visible, + footer: null, + className: componentPrefix, + title, + ...props + }, + descriptionConfig.data.map((descriptions) => { + var _a; + return /* @__PURE__ */ import_react.default.createElement( + import_antd.Descriptions, + { + key: descriptions.title, + title: /* @__PURE__ */ import_react.default.createElement("p", { style: { margin: "12px 0 0", fontSize: initialStyle.fontSize } }, descriptions.title), + column: 8, + style: { padding: "0 64px" } + }, + (_a = descriptions == null ? void 0 : descriptions.children) == null ? void 0 : _a.map((item) => /* @__PURE__ */ import_react.default.createElement( + DescriptionsItem, + { + key: item.key, + label: item.label, + span: 1, + contentStyle: { fontSize: initialStyle.fontSize }, + labelStyle: { fontSize: initialStyle.fontSize } + }, + item.children + )) + ); + }), + /* @__PURE__ */ import_react.default.createElement( + import_antd.Tabs, + { + defaultActiveKey: activeKey, + centered: true, + tabBarStyle: { fontSize: "18px" }, + items: tabsConfig.data, + ...tabsConfig + } + ), + /* @__PURE__ */ import_react.default.createElement( + "div", + { + className: (0, import_classnames.default)(`${componentPrefix}-view-container`), + style: activeKey === "TRACK" ? { + height: "718px", + marginBottom: "0px" + } : {} + }, + activeKey !== "TRACK" && /* @__PURE__ */ import_react.default.createElement(import_react.default.Fragment, null, /* @__PURE__ */ import_react.default.createElement( + import_navigation.default, + { + className: (0, import_classnames.default)( + `${componentPrefix}-view-container__nav`, + previewIndex <= 0 && `${componentPrefix}-view-container__nav--disabled`, + `${componentPrefix}-view-container__nav--left` + ), + show: isRelated ? imageData.length > 1 : dataSource.length > 1, + disabled: previewIndex <= 0, + prev: true, + onClick: () => { + setPreviewIndex((pre) => pre - 1); + } + } + ), /* @__PURE__ */ import_react.default.createElement( + import_navigation.default, + { + className: (0, import_classnames.default)( + `${componentPrefix}-view-container__nav`, + (previewIndex >= imageData.length - 1 || previewIndex >= dataSource.length - 1) && `${componentPrefix}-view-container__nav--disabled`, + `${componentPrefix}-view-container__nav--right` + ), + show: isRelated ? imageData.length > 1 : dataSource.length > 1, + disabled: previewIndex >= imageData.length - 1 || previewIndex >= dataSource.length - 1, + next: true, + onClick: async (e) => { + setPreviewIndex((pre) => pre + 1); + } + } + )) + ) + ); +}; +var BigImageModal_default = BigImageModal; +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + componentPrefix +}); diff --git a/packages/biz/lib/BigImageModal/components/navigation/index.d.ts b/packages/biz/lib/BigImageModal/components/navigation/index.d.ts new file mode 100644 index 0000000..78b1ca8 --- /dev/null +++ b/packages/biz/lib/BigImageModal/components/navigation/index.d.ts @@ -0,0 +1,13 @@ +import * as React from 'react'; +import './index.less'; +declare const Navigation: React.FC<{ + show?: boolean; + onClick?: React.MouseEventHandler; + prev?: boolean; + next?: boolean; + disabled?: boolean; + className?: string; + color?: string; + hoverColor?: string; +}>; +export default Navigation; diff --git a/packages/biz/lib/BigImageModal/components/navigation/index.js b/packages/biz/lib/BigImageModal/components/navigation/index.js new file mode 100644 index 0000000..d7cc187 --- /dev/null +++ b/packages/biz/lib/BigImageModal/components/navigation/index.js @@ -0,0 +1,58 @@ +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// src/BigImageModal/components/navigation/index.tsx +var navigation_exports = {}; +__export(navigation_exports, { + default: () => navigation_default +}); +module.exports = __toCommonJS(navigation_exports); +var React = __toESM(require("react")); +var import_classnames = __toESM(require("classnames")); +var import_antd = require("antd"); +var import_meta = require("@zhst/meta"); +var import_index = require("./index.less"); +var componentName = `zhst-image__nav`; +var Navigation = (props) => { + const { show, prev, next, disabled, onClick, className, color } = props; + return /* @__PURE__ */ React.createElement( + "div", + { + className: (0, import_classnames.default)( + `${componentName}`, + prev && `${componentName}-prev`, + next && `${componentName}-next`, + disabled && `${componentName}--disable`, + !show && `${componentName}--hide`, + className + ) + }, + /* @__PURE__ */ React.createElement(import_antd.Button, { type: "text", disabled, onClick }, /* @__PURE__ */ React.createElement(import_meta.Icon, { size: 28, color, icon: prev ? "icon-qiehuanzuo" : "icon-qiehuanyou" })) + ); +}; +var navigation_default = Navigation; diff --git a/packages/biz/lib/BigImageModal/components/navigation/index.less b/packages/biz/lib/BigImageModal/components/navigation/index.less new file mode 100644 index 0000000..0a834f9 --- /dev/null +++ b/packages/biz/lib/BigImageModal/components/navigation/index.less @@ -0,0 +1,44 @@ +.zhst-image__nav { + position: absolute; + display: flex; + width: 48px; + height: 100%; + flex-shrink: 0; + align-items: center; + justify-content: center; + cursor: pointer; + font-size: 0; + + &>button { + & span { + display: flex; + } + } + + :global { + i:hover { + color: #f0f0f0 !important; + } + } + + &--disable { + :global { + i { + color: #f0f0f0; + cursor: not-allowed !important; + } + } + } + + &--hide { + display: none; + } + + &-prev { + left: 20px; + } + + &-next { + right: 20px; + } +} diff --git a/packages/meta/es/ImagePreview/images/emptyImage.png b/packages/biz/lib/BigImageModal/images/emptyImage.png similarity index 100% rename from packages/meta/es/ImagePreview/images/emptyImage.png rename to packages/biz/lib/BigImageModal/images/emptyImage.png diff --git a/packages/meta/es/ImagePreview/images/percent_background.png b/packages/biz/lib/BigImageModal/images/percent_background.png similarity index 100% rename from packages/meta/es/ImagePreview/images/percent_background.png rename to packages/biz/lib/BigImageModal/images/percent_background.png diff --git a/packages/biz/lib/BigImageModal/index.d.ts b/packages/biz/lib/BigImageModal/index.d.ts new file mode 100644 index 0000000..bb07714 --- /dev/null +++ b/packages/biz/lib/BigImageModal/index.d.ts @@ -0,0 +1,3 @@ +import BigImageModal from "./BigImageModal"; +export type { BigImageModalProps } from './BigImageModal'; +export default BigImageModal; diff --git a/packages/biz/lib/BigImageModal/index.js b/packages/biz/lib/BigImageModal/index.js new file mode 100644 index 0000000..93ee703 --- /dev/null +++ b/packages/biz/lib/BigImageModal/index.js @@ -0,0 +1,36 @@ +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// src/BigImageModal/index.tsx +var BigImageModal_exports = {}; +__export(BigImageModal_exports, { + default: () => BigImageModal_default +}); +module.exports = __toCommonJS(BigImageModal_exports); +var import_BigImageModal = __toESM(require("./BigImageModal")); +var BigImageModal_default = import_BigImageModal.default; diff --git a/packages/biz/lib/BigImageModal/index.less b/packages/biz/lib/BigImageModal/index.less new file mode 100644 index 0000000..966b5d6 --- /dev/null +++ b/packages/biz/lib/BigImageModal/index.less @@ -0,0 +1,770 @@ +.zhst-image { + .zhst-dialog-content { + box-shadow: 0 4px 12px rgb(0 0 0 / 20%); + } + + + &-view-container { + position: relative; + width: 100%; + height: 532px; + margin-bottom: 16px; + + &__nav { + position: absolute; + z-index: 99; + top: 50%; + width: 40px !important; + height: 40px !important; + background: #d9d9d9; + border-radius: 100%; + cursor: pointer; + transform: translateY(-50%); + + &>button { + display: flex; + align-items: center; + color: #fff !important; + } + + &--disabled { + opacity: 0.3; + + &>button { + color: #fff !important; + } + } + } + + &__nav:hover { + background: #09f; + color: #fff !important; + } + } + + &-tool-container { + width: 100%; + height: 40px; + margin-bottom: 16px; + } + + &__face-score { + position: absolute; + right: 90px; + bottom: 80px; + color: red; + font-family: 'Microsoft YaHei'; + font-size: 19px; + font-weight: bold; + } + + &-carousel-container { + position: relative; + width: 100%; + height: 100px; + margin-top: 16px; + margin-bottom: 24px; + } +} + + +.zhst-image__tool { + display: flex; + width: 100%; + align-items: center; + font-size: 14px; + + &-split { + width: 0; + height: 14px; + + &::before { + display: block; + height: 100%; + border-left: 1px solid #e6e7eb; + content: ''; + } + } + + &-zoom { + display: inline-flex; + align-items: center; + + &> :not(:last-child) { + margin-right: 14px; + } + + &__scale { + display: inline-block; + width: 38px; + height: 14px; + + // margin-left: 15px; + box-sizing: content-box; + border: 1px solid rgb(77 77 77 / 100%); + margin-top: 2px; //对齐 + background: rgb(255 255 255 / 100%); + border-radius: 2px; + color: #4d4d4d; + cursor: default; + font-size: 12px; + line-height: 14px; + text-align: center; + } + } + + &-switch { + display: flex; + width: 30px; + flex-shrink: 0; + align-items: center; + justify-content: center; + margin: 0 26px; + } + + &-left { + display: flex; + flex: 1; + align-items: center; + justify-content: flex-end; + + &> :not(:last-child) { + margin-right: 14px; + } + } + + &-right { + display: flex; + flex: 1; + align-items: center; + justify-content: flex-start; + + &> :not(:first-child) { + margin-left: 20px; + } + } + + &-icon-container { + font-size: 14px; + + &--active { + color: #5584ff !important; + } + + &> :first-child { + margin-right: 2px; + } + } +} + +.zhst-image__carousel { + position: relative; + display: flex; + width: 742px; + height: 100px; + align-items: center; + justify-content: center; + border: 1px solid #f0f0f0; + margin: 0 auto; + background: #fafafa; + border-radius: 2px; + user-select: none; + + &-container { + width: (58px + 8px) * 10; + } + + &-item { + display: flex; + width: 58px + 8px; + align-items: center; + justify-content: center; + } + + &-item-img { + /* 尝试消除transform 副作用 */ + position: relative; + z-index: 99; + + // width: 58px; + // height: 76px; + display: flex; + width: 66px; + height: 84px; + box-sizing: border-box; + align-items: center; + justify-content: center; + background: #fafafa; + cursor: pointer; + + /* 尝试消除transform 副作用 end */ + &--active { + border: 2px solid #09f; + border-radius: 1px; + } + + &>div { + /* 尝试消除transform 副作用 */ + position: relative; + z-index: 99; + overflow: hidden; + width: 58px; + height: 76px; + + /* 尝试消除transform 副作用 end */ + &>img { + width: 58px; + height: 76px; + object-fit: contain; + transition: all 0.2s; + + &:hover { + transform: scale(1.5); + } + } + } + } +} + +.zhst-image__header { + width: 100%; + // margin-top: 3px; + margin-bottom: 10px; + + &__pad0 { + padding: 0; + } + + &__pad66 { + padding: 0 66px; + } + + &__bar { + display: flex; + width: 100%; + background: #f6f6f6; + // box-shadow: 0px 0px 8px 0px rgba(172, 172, 172, 0.5); + justify-content: center; + // border-color: #f0f0f0; + // border-bottom-width: 1px; + // border-bottom-style: solid; + } + + &__barNoColor { + display: flex; + width: 100%; + justify-content: center; + border-color: #f0f0f0; + border-bottom-width: 1px; + border-bottom-style: solid; + } + + &__item { + position: relative; + display: flex; + height: 40px; + align-items: center; + justify-content: center; + margin: 0 15px; + color: #999; + cursor: pointer; + font-size: 14px; + font-weight: bold; + line-height: 19px; + transition: font-size 0.3s ease; + + &:hover { + // font-size: 18px; + color: #333; + } + + &::before { + position: absolute; + bottom: 0; + left: 50%; + width: 0; + border-bottom: 2px solid #09f; + content: ''; + transition: all 0.3s ease; + } + + &--active { + background-color: transparent; + color: #333; + font-size: 18px; + + // color: #0099ff; + &::before { + left: 0; + width: 100%; + } + } + } +} + + +.zhst-image__compater-view { + display: flex; + width: 100%; + align-items: center; + justify-content: center; + + &>div:first-child { + margin-right: 25px; + } + + &>div:last-child { + margin-left: 25px; + } + + &__container { + position: relative; + width: 345px; + height: 460px; + box-sizing: content-box; + border: 1px solid #f0f0f0; + } + + &__view { + width: 345px; + height: 460px; + } + + &__label { + position: absolute; + z-index: 99; + top: 0; + left: 0; + display: flex; + height: 34px; + align-items: center; + justify-content: center; + + // width: 48px; + padding: 0 6px; + background: #09f; + color: #fff; + } + + &__tool { + display: flex; + width: 345px; + height: 40px; + align-items: center; + justify-content: center; + background: #f9f9f9; + + i, + span { + color: #333 !important; + } + + i { + margin-right: 4px; + } + + &>*:not(:last-child) { + margin-right: 20px; + } + + &__scale { + display: inline-block; + width: 38px; + height: 16px; + + // margin-left: 15px; + box-sizing: content-box; + border: 1px solid rgb(77 77 77 / 100%); + background: rgb(255 255 255 / 100%); + border-radius: 2px; + color: #4d4d4d; + cursor: default; + font-size: 12px; + line-height: 16px; + text-align: center; + } + + &__line { + width: 1px; + height: 14px; + background: #e6e6e6; + } + } + + &__empty { + position: absolute; + z-index: 9; + display: flex; + width: 100%; + height: 100%; + flex-direction: column; + align-items: center; + justify-content: center; + background: #f9f9f9; + transform: translateY(-100%); + + &>img { + width: 140px; + height: 80px; + } + + &--text { + color: #999; + font-size: 14px; + line-height: 22px; + } + } + + &__scoll-module { + position: absolute; + top: 0%; + left: 0%; + display: flex; + width: 100%; + height: 100%; + align-items: flex-end; + justify-content: space-between; + pointer-events: none; + + &__btn { + display: flex; + width: 50px; + height: 50px; + align-items: center; + justify-content: center; + margin: 6px; + border-radius: 50%; + opacity: 0.5; + pointer-events: all; + + &>span { + display: flex; + align-items: center; + justify-content: center; + } + } + + &__btn:hover { + background-color: #09f !important; + color: #fff !important; + } + } +} + +.zhst-image__trackmodel { + &__panel { + position: relative; + z-index: 99; + top: 0; + right: 0; + width: 320px; + height: 100%; + background-color: #fff; + + &--head { + width: 100%; + height: 40px; + padding: 0 16px; + border-bottom: 1px solid #f0f0f0; + color: #333; + font-size: 14px; + font-weight: bold; + line-height: 40px; + text-align: left; + } + + &--track { + height: calc(100% - 40px); + } + + &-date { + padding: 10px 6px; + + // position: absolute; + } + } + + &--bigImage { + position: absolute; + z-index: 100; + top: 0; + left: 0; + display: flex; + width: 100%; + height: 100%; + justify-content: center; + padding-top: 59px; + background: rgb(0 0 0 / 40%); + + &--image { + width: 946px; + height: 532px; + + &>img { + width: 946px; + height: 532px; + object-fit: contain; + } + } + + &--close { + margin-left: 16px; + color: #fff; + } + } + + &__flooter { + position: absolute; + z-index: 999; + bottom: -124px; + left: 0; + width: calc(100% - 320px - 10px); + height: 144px; + background: #fff; + box-shadow: 0 0 8px 0 rgb(172 172 172 / 50%); + + &--head { + display: flex; + height: 20px; + align-items: center; + justify-content: center; + background: #f6f6f6; + color: #999; + line-height: 16px; + } + + &--body { + display: flex; + height: calc(100% - 20px); + padding-left: 50px; + + &__title { + color: #333; + font-size: 12px; + font-weight: bold; + line-height: 16px; + } + + &__text { + overflow: hidden; + color: #333; + font-size: 12px; + line-height: 16px; + text-overflow: ellipsis; + white-space: nowrap; + } + + &--left { + display: flex; + width: 75px; + height: 100; + align-items: center; + + &>img { + width: 75px; + height: 100px; + object-fit: contain; + } + } + + &--middle { + display: grid; + width: 331px; + justify-content: flex-start; + padding: 8px 20px; + border-right: 1px solid #f0f0f0; + + &>div { + display: flex; + } + } + + &--right { + display: grid; + width: calc(100% - 331px - 75px); + padding: 8px 20px; + + &>div { + display: flex; + } + + &__button-list { + display: flex; + align-items: center; + + &>button { + margin-right: 20px; + + &>span { + color: #09f !important; + } + + &:hover { + &>span { + color: #247fdb !important; + } + } + } + } + } + } + + @keyframes close { + from { + bottom: 0; + } + + to { + bottom: -124px; + } + } + + @keyframes open { + from { + bottom: -124px; + } + + to { + bottom: 0; + } + } + + &--close { + bottom: -124px; + animation-duration: 1s; + animation-name: close; + } + + &--open { + bottom: 0; + animation-duration: 1s; + animation-name: open; + } + } +} + +.zhst-image__null { + display: flex; + height: 100%; + flex-direction: column; + align-items: center; + justify-content: center; + + &__text { + // margin-left: 105px; + margin-top: 8px; + color: #999; + font-size: 14px; + width: 100%; + text-align: center; + } +} + +.zhst-image__attributePanel { + margin: 0 66px; + background: #f6f6f6; + margin-top: 20px; + padding-top: 16px; + display: flex; + justify-content: center; + + &>div:first-child { + width: fit-content; + display: flex; + flex-direction: column; + } + + &-title { + color: rgb(0 0 0 / 88%); + font-weight: bold; + padding-bottom: 12px; + } + + &-item { + display: flex; + } + + &-label { + color: rgb(0 0 0 / 45%); + } + + &-value { + color: rgb(0 0 0 / 88%); + } +} + +.relatedWrapper { + width: 100%; + height: 100px; + padding: 0 30px; + margin-bottom: 30px; + box-sizing: border-box; + + .relatedTabs { + width: 100%; + height: 100px; + } + + .relatedContent { + width: 100%; + height: 100px; + display: flex; + + .relatedPics { + width: 742px; + height: 100px; + // display: flex; + // box-sizing: border-box; + // background: #fafafa; + // border-radius: 2px; + // border: 1px solid #f0f0f0; + // .LeftBtn, + // .RighttBtn { + // width: 34px; + // height: 100%; + // display: flex; + // justify-content: center; + // align-items: center; + // } + // .ListContent { + // flex: 1; + // height: 100%; + // } + } + + .disabled { + color: rgba(0, 0, 0, 25%); + } + + .relatedBtn { + flex: 1; + font-size: 14px; + color: #333; + display: flex; + align-items: flex-end; + cursor: pointer; + + &:hover { + color: #09f; + } + } + } + + :global { + .ant-tabs-left>.ant-tabs-content-holder>.ant-tabs-content>.ant-tabs-tabpane { + padding-left: 16px; + } + + .ant-tabs-tab { + padding: 8px 12px !important; + text-align: right !important; + } + + .ant-tabs .ant-tabs-tab { + font-size: 14px; + font-weight: bold; + text-align: right; + justify-content: flex-end; + } + } +} diff --git a/packages/biz/lib/BigImageModal/mock.d.ts b/packages/biz/lib/BigImageModal/mock.d.ts new file mode 100644 index 0000000..257ed75 --- /dev/null +++ b/packages/biz/lib/BigImageModal/mock.d.ts @@ -0,0 +1,294 @@ +export declare const IMAGE_DATA: { + enAbleDeleteFeature: boolean; + tabsFilter: string[]; + dataSources: { + objectId: string; + condition: { + featureInfo: null; + featureData: string; + imageData: string; + alg: string; + rect: { + x: number; + y: number; + w: number; + h: number; + }; + objectImageUrl: string; + srcImageUrl: string; + }; + score: number; + timestamp: number; + deviceId: string; + id: string; + name: string; + dirid: string; + status: string; + longitude: number; + latitude: number; + caseId: string; + caseGroup: string; + isDeleted: string; + extendInfo: { + vmsPlatformId: string; + vmsChannel: string; + vmsCameraDecoderTag: string; + platformPluginType: string; + deviceVender: string; + type: string; + ip: string; + port: string; + username: string; + passwd: string; + rtspAddress: string; + facesnapChannel: string; + edgeDeviceSn: string; + platform1400Id: number; + useRtspAddress: boolean; + frameCheck: boolean; + frameRectX: number; + frameRectY: number; + frameRectW: number; + frameRectH: number; + edgeNodeId: string; + processStatus: string; + }; + objectIndex: { + objectId: string; + solutionId: string; + deviceId: string; + fragmentId: string; + }; + objectType: string; + isObjectTrack: boolean; + pathId: string; + frameInfo: { + frameId: string; + frameTimestamp: string; + width: number; + height: number; + originWidth: number; + originHeight: number; + offsetTime: string; + skipNumber: string; + }; + level: number; + bboxInFrame: { + x: number; + y: number; + w: number; + h: number; + }; + bboxExtInFrame: { + x: number; + y: number; + w: number; + h: number; + }; + objectImageKey: string; + objectExtImageKey: string; + frameImageKey: string; + confidence: number; + sourceObjectId: string; + storeTimestamp: string; + gbNumber: string; + qualityScore: number; + subObjectCount: number; + subObjectType: string[]; + subObjectIds: string[]; + cameraInfo: { + id: string; + name: string; + dirid: string; + status: string; + longitude: number; + latitude: number; + caseId: string; + caseGroup: string; + isDeleted: string; + extendInfo: { + vmsPlatformId: string; + vmsChannel: string; + vmsCameraDecoderTag: string; + platformPluginType: string; + deviceVender: string; + type: string; + ip: string; + port: string; + username: string; + passwd: string; + rtspAddress: string; + facesnapChannel: string; + edgeDeviceSn: string; + platform1400Id: number; + useRtspAddress: boolean; + frameCheck: boolean; + frameRectX: number; + frameRectY: number; + frameRectW: number; + frameRectH: number; + edgeNodeId: string; + processStatus: string; + }; + }; + solutionId: string; + fragmentId: string; + contrastKey: string; + compaterImages: string[]; + imgSummary: string; + imageKey: string; + srcImageUrl: string; + algorithmVersion: string; + cameraId: string; + cameraName: string; + }[]; + selectIndex: number; + disableBtn: number[]; + dataSource: { + objectId: string; + condition: { + featureInfo: null; + featureData: string; + imageData: string; + alg: string; + rect: { + x: number; + y: number; + w: number; + h: number; + }; + objectImageUrl: string; + srcImageUrl: string; + }; + score: number; + timestamp: number; + deviceId: string; + id: string; + name: string; + dirid: string; + status: string; + longitude: number; + latitude: number; + caseId: string; + caseGroup: string; + isDeleted: string; + extendInfo: { + vmsPlatformId: string; + vmsChannel: string; + vmsCameraDecoderTag: string; + platformPluginType: string; + deviceVender: string; + type: string; + ip: string; + port: string; + username: string; + passwd: string; + rtspAddress: string; + facesnapChannel: string; + edgeDeviceSn: string; + platform1400Id: number; + useRtspAddress: boolean; + frameCheck: boolean; + frameRectX: number; + frameRectY: number; + frameRectW: number; + frameRectH: number; + edgeNodeId: string; + processStatus: string; + }; + objectIndex: { + objectId: string; + solutionId: string; + deviceId: string; + fragmentId: string; + }; + objectType: string; + isObjectTrack: boolean; + pathId: string; + frameInfo: { + frameId: string; + frameTimestamp: string; + width: number; + height: number; + originWidth: number; + originHeight: number; + offsetTime: string; + skipNumber: string; + }; + level: number; + bboxInFrame: { + x: number; + y: number; + w: number; + h: number; + }; + bboxExtInFrame: { + x: number; + y: number; + w: number; + h: number; + }; + objectImageKey: string; + objectExtImageKey: string; + frameImageKey: string; + confidence: number; + sourceObjectId: string; + storeTimestamp: string; + gbNumber: string; + qualityScore: number; + subObjectCount: number; + subObjectType: string[]; + subObjectIds: string[]; + cameraInfo: { + id: string; + name: string; + dirid: string; + status: string; + longitude: number; + latitude: number; + caseId: string; + caseGroup: string; + isDeleted: string; + extendInfo: { + vmsPlatformId: string; + vmsChannel: string; + vmsCameraDecoderTag: string; + platformPluginType: string; + deviceVender: string; + type: string; + ip: string; + port: string; + username: string; + passwd: string; + rtspAddress: string; + facesnapChannel: string; + edgeDeviceSn: string; + platform1400Id: number; + useRtspAddress: boolean; + frameCheck: boolean; + frameRectX: number; + frameRectY: number; + frameRectW: number; + frameRectH: number; + edgeNodeId: string; + processStatus: string; + }; + }; + solutionId: string; + fragmentId: string; + contrastKey: string; + compaterImages: string[]; + imgSummary: string; + imageKey: string; + srcImageUrl: string; + algorithmVersion: string; + cameraId: string; + cameraName: string; + }[]; + isArchiveDetail: boolean; + ToolProps: { + renderVideoBtn: boolean; + disableVideo: boolean; + }; + specialTitle: string; +}; diff --git a/packages/biz/lib/BigImageModal/mock.js b/packages/biz/lib/BigImageModal/mock.js new file mode 100644 index 0000000..e3072e9 --- /dev/null +++ b/packages/biz/lib/BigImageModal/mock.js @@ -0,0 +1,930 @@ +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// src/BigImageModal/mock.ts +var mock_exports = {}; +__export(mock_exports, { + IMAGE_DATA: () => IMAGE_DATA +}); +module.exports = __toCommonJS(mock_exports); +var IMAGE_DATA = { + "enAbleDeleteFeature": true, + "tabsFilter": [ + "COMPATER", + "NORMAL" + ], + "dataSources": [ + { + "objectId": "1742110565582518272", + "condition": { + "featureInfo": null, + "featureData": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==", + "imageData": "", + "alg": "VERSION_REID_HEAD_ATTR", + "rect": { + "x": 0.271875, + "y": 0.32222223, + "w": 0.2859375, + "h": 0.67777777 + }, + "objectImageUrl": "singer-20240102/1/129529/1742047651878156288.jpg", + "srcImageUrl": "singer-20240102/1/129529/1742047652511496192.jpg" + }, + "score": 0.7163062, + "timestamp": 1704186491979, + "deviceId": "129533", + "id": "129533", + "name": "4楼门口过道人脸", + "dirid": "0", + "status": "1", + "longitude": 120.125, + "latitude": 30.280500411987305, + "caseId": "0", + "caseGroup": "", + "isDeleted": "DEVICEMANAGER_BOOL_DEFAULT", + "extendInfo": { + "vmsPlatformId": "29", + "vmsChannel": "38", + "vmsCameraDecoderTag": "hikvision", + "platformPluginType": "PLATFORM_PLUGIN_TYPE_HAIKANG_NVR", + "deviceVender": "0", + "type": "DEVICEMANAGER_CAMERA_TYPE_NORMAL", + "ip": "", + "port": "0", + "username": "", + "passwd": "", + "rtspAddress": "", + "facesnapChannel": "", + "edgeDeviceSn": "", + "platform1400Id": 0, + "useRtspAddress": false, + "frameCheck": false, + "frameRectX": 0, + "frameRectY": 0, + "frameRectW": 0, + "frameRectH": 0, + "edgeNodeId": "0", + "processStatus": "FILTER_REALTIME_DEFAULT" + }, + "objectIndex": { + "objectId": "1742110565582518272", + "solutionId": "1", + "deviceId": "129533", + "fragmentId": "0" + }, + "objectType": "OBJECT_TYPE_PEDESTRAIN", + "isObjectTrack": true, + "pathId": "1742110532019697664", + "frameInfo": { + "frameId": "0", + "frameTimestamp": "1704186491979", + "width": 0, + "height": 0, + "originWidth": 1920, + "originHeight": 1080, + "offsetTime": "24714687", + "skipNumber": "0" + }, + "level": 1, + "bboxInFrame": { + "x": 0.603125, + "y": 0.3314815, + "w": 0.0578125, + "h": 0.2712963 + }, + "bboxExtInFrame": { + "x": 0.546875, + "y": 0.2638889, + "w": 0.17135416, + "h": 0.40648147 + }, + "objectImageKey": "", + "objectExtImageKey": "http://10.0.0.7:30003/file/singer-20240102/1/129533/1742110565582518272.jpg", + "frameImageKey": "http://10.0.0.7:30003/file/singer-20240102/1/129533/1742110565603489792.jpg", + "confidence": 0.817271, + "sourceObjectId": "1742110565603489792", + "storeTimestamp": "0", + "gbNumber": "", + "qualityScore": 0, + "subObjectCount": 1, + "subObjectType": [ + "OBJECT_TYPE_FACE" + ], + "subObjectIds": [ + "1742110532015503360" + ], + "cameraInfo": { + "id": "129533", + "name": "4楼门口过道人脸", + "dirid": "0", + "status": "1", + "longitude": 120.125, + "latitude": 30.280500411987305, + "caseId": "0", + "caseGroup": "", + "isDeleted": "DEVICEMANAGER_BOOL_DEFAULT", + "extendInfo": { + "vmsPlatformId": "29", + "vmsChannel": "38", + "vmsCameraDecoderTag": "hikvision", + "platformPluginType": "PLATFORM_PLUGIN_TYPE_HAIKANG_NVR", + "deviceVender": "0", + "type": "DEVICEMANAGER_CAMERA_TYPE_NORMAL", + "ip": "", + "port": "0", + "username": "", + "passwd": "", + "rtspAddress": "", + "facesnapChannel": "", + "edgeDeviceSn": "", + "platform1400Id": 0, + "useRtspAddress": false, + "frameCheck": false, + "frameRectX": 0, + "frameRectY": 0, + "frameRectW": 0, + "frameRectH": 0, + "edgeNodeId": "0", + "processStatus": "FILTER_REALTIME_DEFAULT" + } + }, + "solutionId": "1", + "fragmentId": "0", + "contrastKey": "singer-20240102/1/129533/1742110565582518272.jpg", + "compaterImages": [ + "http://10.0.0.7:30003/file/singer-20240102/1/129529/1742047651878156288.jpg" + ], + "imgSummary": "singer-20240102/1/129533/1742110565582518272.jpg", + "imageKey": "http://10.0.0.7:30003/file/singer-20240102/1/129533/1742110565582518272.jpg", + "srcImageUrl": "http://10.0.0.7:30003/file/singer-20240102/1/129533/1742110565603489792.jpg", + "algorithmVersion": "VERSION_REID_HEAD_ATTR", + "cameraId": "129533", + "cameraName": "4楼门口过道人脸" + }, + { + "objectId": "1742092780462684161", + "condition": { + "featureInfo": null, + "featureData": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==", + "imageData": "", + "alg": "VERSION_REID_HEAD_ATTR", + "rect": { + "x": 0.271875, + "y": 0.32222223, + "w": 0.2859375, + "h": 0.67777777 + }, + "objectImageUrl": "singer-20240102/1/129529/1742047651878156288.jpg", + "srcImageUrl": "singer-20240102/1/129529/1742047652511496192.jpg" + }, + "score": 0.70154816, + "timestamp": 1704182251640, + "deviceId": "129533", + "id": "129533", + "name": "4楼门口过道人脸", + "dirid": "0", + "status": "1", + "longitude": 120.125, + "latitude": 30.280500411987305, + "caseId": "0", + "caseGroup": "", + "isDeleted": "DEVICEMANAGER_BOOL_DEFAULT", + "extendInfo": { + "vmsPlatformId": "29", + "vmsChannel": "38", + "vmsCameraDecoderTag": "hikvision", + "platformPluginType": "PLATFORM_PLUGIN_TYPE_HAIKANG_NVR", + "deviceVender": "0", + "type": "DEVICEMANAGER_CAMERA_TYPE_NORMAL", + "ip": "", + "port": "0", + "username": "", + "passwd": "", + "rtspAddress": "", + "facesnapChannel": "", + "edgeDeviceSn": "", + "platform1400Id": 0, + "useRtspAddress": false, + "frameCheck": false, + "frameRectX": 0, + "frameRectY": 0, + "frameRectW": 0, + "frameRectH": 0, + "edgeNodeId": "0", + "processStatus": "FILTER_REALTIME_DEFAULT" + }, + "objectIndex": { + "objectId": "1742092780462684161", + "solutionId": "1", + "deviceId": "129533", + "fragmentId": "0" + }, + "objectType": "OBJECT_TYPE_PEDESTRAIN", + "isObjectTrack": true, + "pathId": "1742092746237163520", + "frameInfo": { + "frameId": "0", + "frameTimestamp": "1704182251640", + "width": 0, + "height": 0, + "originWidth": 1920, + "originHeight": 1080, + "offsetTime": "20474348", + "skipNumber": "0" + }, + "level": 1, + "bboxInFrame": { + "x": 0.63177085, + "y": 0.38333333, + "w": 0.078125, + "h": 0.3537037 + }, + "bboxExtInFrame": { + "x": 0.55885416, + "y": 0.29537037, + "w": 0.22447917, + "h": 0.5314815 + }, + "objectImageKey": "", + "objectExtImageKey": "http://10.0.0.7:30003/file/singer-20240102/1/129533/1742092780462684161.jpg", + "frameImageKey": "http://10.0.0.7:30003/file/singer-20240102/1/129533/1742092780768868352.jpg", + "confidence": 0.888334, + "sourceObjectId": "1742092780768868352", + "storeTimestamp": "0", + "gbNumber": "", + "qualityScore": 0, + "subObjectCount": 1, + "subObjectType": [ + "OBJECT_TYPE_FACE" + ], + "subObjectIds": [ + "1742092746232969217" + ], + "cameraInfo": { + "id": "129533", + "name": "4楼门口过道人脸", + "dirid": "0", + "status": "1", + "longitude": 120.125, + "latitude": 30.280500411987305, + "caseId": "0", + "caseGroup": "", + "isDeleted": "DEVICEMANAGER_BOOL_DEFAULT", + "extendInfo": { + "vmsPlatformId": "29", + "vmsChannel": "38", + "vmsCameraDecoderTag": "hikvision", + "platformPluginType": "PLATFORM_PLUGIN_TYPE_HAIKANG_NVR", + "deviceVender": "0", + "type": "DEVICEMANAGER_CAMERA_TYPE_NORMAL", + "ip": "", + "port": "0", + "username": "", + "passwd": "", + "rtspAddress": "", + "facesnapChannel": "", + "edgeDeviceSn": "", + "platform1400Id": 0, + "useRtspAddress": false, + "frameCheck": false, + "frameRectX": 0, + "frameRectY": 0, + "frameRectW": 0, + "frameRectH": 0, + "edgeNodeId": "0", + "processStatus": "FILTER_REALTIME_DEFAULT" + } + }, + "solutionId": "1", + "fragmentId": "0", + "contrastKey": "singer-20240102/1/129533/1742092780462684161.jpg", + "compaterImages": [ + "http://10.0.0.7:30003/file/singer-20240102/1/129529/1742047651878156288.jpg" + ], + "imgSummary": "singer-20240102/1/129533/1742092780462684161.jpg", + "imageKey": "http://10.0.0.7:30003/file/singer-20240102/1/129533/1742092780462684161.jpg", + "srcImageUrl": "http://10.0.0.7:30003/file/singer-20240102/1/129533/1742092780768868352.jpg", + "algorithmVersion": "VERSION_REID_HEAD_ATTR", + "cameraId": "129533", + "cameraName": "4楼门口过道人脸" + }, + { + "objectId": "1742092514409592832", + "condition": { + "featureInfo": null, + "featureData": "AAAAAAAAAAAAAAA==", + "imageData": "", + "alg": "VERSION_REID_HEAD_ATTR", + "rect": { + "x": 0.271875, + "y": 0.32222223, + "w": 0.2859375, + "h": 0.67777777 + }, + "objectImageUrl": "singer-20240102/1/129529/1742047651878156288.jpg", + "srcImageUrl": "singer-20240102/1/129529/1742047652511496192.jpg" + }, + "score": 0.703765, + "timestamp": 1704182186451, + "deviceId": "129529", + "id": "129529", + "name": "4入口人脸", + "dirid": "0", + "status": "1", + "longitude": 120.12100219726562, + "latitude": 30.280099868774414, + "caseId": "0", + "caseGroup": "", + "isDeleted": "DEVICEMANAGER_BOOL_DEFAULT", + "extendInfo": { + "vmsPlatformId": "29", + "vmsChannel": "34", + "vmsCameraDecoderTag": "hikvision", + "platformPluginType": "PLATFORM_PLUGIN_TYPE_HAIKANG_NVR", + "deviceVender": "0", + "type": "DEVICEMANAGER_CAMERA_TYPE_NORMAL", + "ip": "", + "port": "0", + "username": "", + "passwd": "", + "rtspAddress": "", + "facesnapChannel": "", + "edgeDeviceSn": "", + "platform1400Id": 0, + "useRtspAddress": false, + "frameCheck": false, + "frameRectX": 0, + "frameRectY": 0, + "frameRectW": 0, + "frameRectH": 0, + "edgeNodeId": "0", + "processStatus": "FILTER_REALTIME_DEFAULT" + }, + "objectIndex": { + "objectId": "1742092514409592832", + "solutionId": "1", + "deviceId": "129529", + "fragmentId": "0" + }, + "objectType": "OBJECT_TYPE_PEDESTRAIN", + "isObjectTrack": true, + "pathId": "1742092482440607744", + "frameInfo": { + "frameId": "0", + "frameTimestamp": "1704182186451", + "width": 0, + "height": 0, + "originWidth": 2560, + "originHeight": 1440, + "offsetTime": "20409182", + "skipNumber": "0" + }, + "level": 1, + "bboxInFrame": { + "x": 0.6195313, + "y": 0.24583334, + "w": 0.09804688, + "h": 0.41944444 + }, + "bboxExtInFrame": { + "x": 0.53515625, + "y": 0.14027777, + "w": 0.26640624, + "h": 0.63125 + }, + "objectImageKey": "", + "objectExtImageKey": "http://10.0.0.7:30003/file/singer-20240102/1/129529/1742092514409592832.jpg", + "frameImageKey": "http://10.0.0.7:30003/file/singer-20240102/1/129529/1742092515508500480.jpg", + "confidence": 0.92494, + "sourceObjectId": "1742092515508500480", + "storeTimestamp": "0", + "gbNumber": "", + "qualityScore": 0, + "subObjectCount": 1, + "subObjectType": [ + "OBJECT_TYPE_FACE" + ], + "subObjectIds": [ + "1742092482432219136" + ], + "cameraInfo": { + "id": "129529", + "name": "4入口人脸", + "dirid": "0", + "status": "1", + "longitude": 120.12100219726562, + "latitude": 30.280099868774414, + "caseId": "0", + "caseGroup": "", + "isDeleted": "DEVICEMANAGER_BOOL_DEFAULT", + "extendInfo": { + "vmsPlatformId": "29", + "vmsChannel": "34", + "vmsCameraDecoderTag": "hikvision", + "platformPluginType": "PLATFORM_PLUGIN_TYPE_HAIKANG_NVR", + "deviceVender": "0", + "type": "DEVICEMANAGER_CAMERA_TYPE_NORMAL", + "ip": "", + "port": "0", + "username": "", + "passwd": "", + "rtspAddress": "", + "facesnapChannel": "", + "edgeDeviceSn": "", + "platform1400Id": 0, + "useRtspAddress": false, + "frameCheck": false, + "frameRectX": 0, + "frameRectY": 0, + "frameRectW": 0, + "frameRectH": 0, + "edgeNodeId": "0", + "processStatus": "FILTER_REALTIME_DEFAULT" + } + }, + "solutionId": "1", + "fragmentId": "0", + "contrastKey": "singer-20240102/1/129529/1742092514409592832.jpg", + "compaterImages": [ + "http://10.0.0.7:30003/file/singer-20240102/1/129529/1742047651878156288.jpg" + ], + "imgSummary": "singer-20240102/1/129529/1742092514409592832.jpg", + "imageKey": "http://10.0.0.7:30003/file/singer-20240102/1/129529/1742092514409592832.jpg", + "srcImageUrl": "http://10.0.0.7:30003/file/singer-20240102/1/129529/1742092515508500480.jpg", + "algorithmVersion": "VERSION_REID_HEAD_ATTR", + "cameraId": "129529", + "cameraName": "4入口人脸" + } + ], + "selectIndex": 4, + "disableBtn": [ + 0, + 1, + 4, + 20 + ], + "dataSource": [ + { + "objectId": "1742110565582518272", + "condition": { + "featureInfo": null, + "featureData": "AAAAAAAAAAAAAAAAAAAAAAA==", + "imageData": "", + "alg": "VERSION_REID_HEAD_ATTR", + "rect": { + "x": 0.271875, + "y": 0.32222223, + "w": 0.2859375, + "h": 0.67777777 + }, + "objectImageUrl": "singer-20240102/1/129529/1742047651878156288.jpg", + "srcImageUrl": "singer-20240102/1/129529/1742047652511496192.jpg" + }, + "score": 0.7163062, + "timestamp": 1704186491979, + "deviceId": "129533", + "id": "129533", + "name": "4楼门口过道人脸", + "dirid": "0", + "status": "1", + "longitude": 120.125, + "latitude": 30.280500411987305, + "caseId": "0", + "caseGroup": "", + "isDeleted": "DEVICEMANAGER_BOOL_DEFAULT", + "extendInfo": { + "vmsPlatformId": "29", + "vmsChannel": "38", + "vmsCameraDecoderTag": "hikvision", + "platformPluginType": "PLATFORM_PLUGIN_TYPE_HAIKANG_NVR", + "deviceVender": "0", + "type": "DEVICEMANAGER_CAMERA_TYPE_NORMAL", + "ip": "", + "port": "0", + "username": "", + "passwd": "", + "rtspAddress": "", + "facesnapChannel": "", + "edgeDeviceSn": "", + "platform1400Id": 0, + "useRtspAddress": false, + "frameCheck": false, + "frameRectX": 0, + "frameRectY": 0, + "frameRectW": 0, + "frameRectH": 0, + "edgeNodeId": "0", + "processStatus": "FILTER_REALTIME_DEFAULT" + }, + "objectIndex": { + "objectId": "1742110565582518272", + "solutionId": "1", + "deviceId": "129533", + "fragmentId": "0" + }, + "objectType": "OBJECT_TYPE_PEDESTRAIN", + "isObjectTrack": true, + "pathId": "1742110532019697664", + "frameInfo": { + "frameId": "0", + "frameTimestamp": "1704186491979", + "width": 0, + "height": 0, + "originWidth": 1920, + "originHeight": 1080, + "offsetTime": "24714687", + "skipNumber": "0" + }, + "level": 1, + "bboxInFrame": { + "x": 0.603125, + "y": 0.3314815, + "w": 0.0578125, + "h": 0.2712963 + }, + "bboxExtInFrame": { + "x": 0.546875, + "y": 0.2638889, + "w": 0.17135416, + "h": 0.40648147 + }, + "objectImageKey": "", + "objectExtImageKey": "http://10.0.0.7:30003/file/singer-20240102/1/129533/1742110565582518272.jpg", + "frameImageKey": "http://10.0.0.7:30003/file/singer-20240102/1/129533/1742110565603489792.jpg", + "confidence": 0.817271, + "sourceObjectId": "1742110565603489792", + "storeTimestamp": "0", + "gbNumber": "", + "qualityScore": 0, + "subObjectCount": 1, + "subObjectType": [ + "OBJECT_TYPE_FACE" + ], + "subObjectIds": [ + "1742110532015503360" + ], + "cameraInfo": { + "id": "129533", + "name": "4楼门口过道人脸", + "dirid": "0", + "status": "1", + "longitude": 120.125, + "latitude": 30.280500411987305, + "caseId": "0", + "caseGroup": "", + "isDeleted": "DEVICEMANAGER_BOOL_DEFAULT", + "extendInfo": { + "vmsPlatformId": "29", + "vmsChannel": "38", + "vmsCameraDecoderTag": "hikvision", + "platformPluginType": "PLATFORM_PLUGIN_TYPE_HAIKANG_NVR", + "deviceVender": "0", + "type": "DEVICEMANAGER_CAMERA_TYPE_NORMAL", + "ip": "", + "port": "0", + "username": "", + "passwd": "", + "rtspAddress": "", + "facesnapChannel": "", + "edgeDeviceSn": "", + "platform1400Id": 0, + "useRtspAddress": false, + "frameCheck": false, + "frameRectX": 0, + "frameRectY": 0, + "frameRectW": 0, + "frameRectH": 0, + "edgeNodeId": "0", + "processStatus": "FILTER_REALTIME_DEFAULT" + } + }, + "solutionId": "1", + "fragmentId": "0", + "contrastKey": "singer-20240102/1/129533/1742110565582518272.jpg", + "compaterImages": [ + "http://10.0.0.7:30003/file/singer-20240102/1/129529/1742047651878156288.jpg" + ], + "imgSummary": "singer-20240102/1/129533/1742110565582518272.jpg", + "imageKey": "http://10.0.0.7:30003/file/singer-20240102/1/129533/1742110565582518272.jpg", + "srcImageUrl": "http://10.0.0.7:30003/file/singer-20240102/1/129533/1742110565603489792.jpg", + "algorithmVersion": "VERSION_REID_HEAD_ATTR", + "cameraId": "129533", + "cameraName": "4楼门口过道人脸" + }, + { + "objectId": "1742092680994764802", + "condition": { + "featureInfo": null, + "featureData": "AAAAAAAAAAAAAAAAAAAAAAAAA==", + "imageData": "", + "alg": "VERSION_REID_HEAD_ATTR", + "rect": { + "x": 0.271875, + "y": 0.32222223, + "w": 0.2859375, + "h": 0.67777777 + }, + "objectImageUrl": "singer-20240102/1/129529/1742047651878156288.jpg", + "srcImageUrl": "singer-20240102/1/129529/1742047652511496192.jpg" + }, + "score": 0.7007122, + "timestamp": 1704182225679, + "deviceId": "129533", + "id": "129533", + "name": "4楼门口过道人脸", + "dirid": "0", + "status": "1", + "longitude": 120.125, + "latitude": 30.280500411987305, + "caseId": "0", + "caseGroup": "", + "isDeleted": "DEVICEMANAGER_BOOL_DEFAULT", + "extendInfo": { + "vmsPlatformId": "29", + "vmsChannel": "38", + "vmsCameraDecoderTag": "hikvision", + "platformPluginType": "PLATFORM_PLUGIN_TYPE_HAIKANG_NVR", + "deviceVender": "0", + "type": "DEVICEMANAGER_CAMERA_TYPE_NORMAL", + "ip": "", + "port": "0", + "username": "", + "passwd": "", + "rtspAddress": "", + "facesnapChannel": "", + "edgeDeviceSn": "", + "platform1400Id": 0, + "useRtspAddress": false, + "frameCheck": false, + "frameRectX": 0, + "frameRectY": 0, + "frameRectW": 0, + "frameRectH": 0, + "edgeNodeId": "0", + "processStatus": "FILTER_REALTIME_DEFAULT" + }, + "objectIndex": { + "objectId": "1742092680994764802", + "solutionId": "1", + "deviceId": "129533", + "fragmentId": "0" + }, + "objectType": "OBJECT_TYPE_PEDESTRAIN", + "isObjectTrack": true, + "pathId": "1742092646219790337", + "frameInfo": { + "frameId": "0", + "frameTimestamp": "1704182225679", + "width": 0, + "height": 0, + "originWidth": 1920, + "originHeight": 1080, + "offsetTime": "20448387", + "skipNumber": "0" + }, + "level": 1, + "bboxInFrame": { + "x": 0.5265625, + "y": 0.49537036, + "w": 0.104166664, + "h": 0.35833332 + }, + "bboxExtInFrame": { + "x": 0.465625, + "y": 0.40648147, + "w": 0.22708334, + "h": 0.537963 + }, + "objectImageKey": "", + "objectExtImageKey": "http://10.0.0.7:30003/file/singer-20240102/1/129533/1742092680994764802.jpg", + "frameImageKey": "http://10.0.0.7:30003/file/singer-20240102/1/129533/1742092681720379392.jpg", + "confidence": 0.769764, + "sourceObjectId": "1742092681720379392", + "storeTimestamp": "0", + "gbNumber": "", + "qualityScore": 0, + "subObjectCount": 0, + "subObjectType": [], + "subObjectIds": [], + "cameraInfo": { + "id": "129533", + "name": "4楼门口过道人脸", + "dirid": "0", + "status": "1", + "longitude": 120.125, + "latitude": 30.280500411987305, + "caseId": "0", + "caseGroup": "", + "isDeleted": "DEVICEMANAGER_BOOL_DEFAULT", + "extendInfo": { + "vmsPlatformId": "29", + "vmsChannel": "38", + "vmsCameraDecoderTag": "hikvision", + "platformPluginType": "PLATFORM_PLUGIN_TYPE_HAIKANG_NVR", + "deviceVender": "0", + "type": "DEVICEMANAGER_CAMERA_TYPE_NORMAL", + "ip": "", + "port": "0", + "username": "", + "passwd": "", + "rtspAddress": "", + "facesnapChannel": "", + "edgeDeviceSn": "", + "platform1400Id": 0, + "useRtspAddress": false, + "frameCheck": false, + "frameRectX": 0, + "frameRectY": 0, + "frameRectW": 0, + "frameRectH": 0, + "edgeNodeId": "0", + "processStatus": "FILTER_REALTIME_DEFAULT" + } + }, + "solutionId": "1", + "fragmentId": "0", + "contrastKey": "singer-20240102/1/129533/1742092680994764802.jpg", + "compaterImages": [ + "http://10.0.0.7:30003/file/singer-20240102/1/129529/1742047651878156288.jpg" + ], + "imgSummary": "singer-20240102/1/129533/1742092680994764802.jpg", + "imageKey": "http://10.0.0.7:30003/file/singer-20240102/1/129533/1742092680994764802.jpg", + "srcImageUrl": "http://10.0.0.7:30003/file/singer-20240102/1/129533/1742092681720379392.jpg", + "algorithmVersion": "VERSION_REID_HEAD_ATTR", + "cameraId": "129533", + "cameraName": "4楼门口过道人脸" + }, + { + "objectId": "1742092514409592832", + "condition": { + "featureInfo": null, + "featureData": "AAAAAAAAAAAAAAAAAAAAAAAA==", + "imageData": "", + "alg": "VERSION_REID_HEAD_ATTR", + "rect": { + "x": 0.271875, + "y": 0.32222223, + "w": 0.2859375, + "h": 0.67777777 + }, + "objectImageUrl": "singer-20240102/1/129529/1742047651878156288.jpg", + "srcImageUrl": "singer-20240102/1/129529/1742047652511496192.jpg" + }, + "score": 0.703765, + "timestamp": 1704182186451, + "deviceId": "129529", + "id": "129529", + "name": "4入口人脸", + "dirid": "0", + "status": "1", + "longitude": 120.12100219726562, + "latitude": 30.280099868774414, + "caseId": "0", + "caseGroup": "", + "isDeleted": "DEVICEMANAGER_BOOL_DEFAULT", + "extendInfo": { + "vmsPlatformId": "29", + "vmsChannel": "34", + "vmsCameraDecoderTag": "hikvision", + "platformPluginType": "PLATFORM_PLUGIN_TYPE_HAIKANG_NVR", + "deviceVender": "0", + "type": "DEVICEMANAGER_CAMERA_TYPE_NORMAL", + "ip": "", + "port": "0", + "username": "", + "passwd": "", + "rtspAddress": "", + "facesnapChannel": "", + "edgeDeviceSn": "", + "platform1400Id": 0, + "useRtspAddress": false, + "frameCheck": false, + "frameRectX": 0, + "frameRectY": 0, + "frameRectW": 0, + "frameRectH": 0, + "edgeNodeId": "0", + "processStatus": "FILTER_REALTIME_DEFAULT" + }, + "objectIndex": { + "objectId": "1742092514409592832", + "solutionId": "1", + "deviceId": "129529", + "fragmentId": "0" + }, + "objectType": "OBJECT_TYPE_PEDESTRAIN", + "isObjectTrack": true, + "pathId": "1742092482440607744", + "frameInfo": { + "frameId": "0", + "frameTimestamp": "1704182186451", + "width": 0, + "height": 0, + "originWidth": 2560, + "originHeight": 1440, + "offsetTime": "20409182", + "skipNumber": "0" + }, + "level": 1, + "bboxInFrame": { + "x": 0.6195313, + "y": 0.24583334, + "w": 0.09804688, + "h": 0.41944444 + }, + "bboxExtInFrame": { + "x": 0.53515625, + "y": 0.14027777, + "w": 0.26640624, + "h": 0.63125 + }, + "objectImageKey": "", + "objectExtImageKey": "http://10.0.0.7:30003/file/singer-20240102/1/129529/1742092514409592832.jpg", + "frameImageKey": "http://10.0.0.7:30003/file/singer-20240102/1/129529/1742092515508500480.jpg", + "confidence": 0.92494, + "sourceObjectId": "1742092515508500480", + "storeTimestamp": "0", + "gbNumber": "", + "qualityScore": 0, + "subObjectCount": 1, + "subObjectType": [ + "OBJECT_TYPE_FACE" + ], + "subObjectIds": [ + "1742092482432219136" + ], + "cameraInfo": { + "id": "129529", + "name": "4入口人脸", + "dirid": "0", + "status": "1", + "longitude": 120.12100219726562, + "latitude": 30.280099868774414, + "caseId": "0", + "caseGroup": "", + "isDeleted": "DEVICEMANAGER_BOOL_DEFAULT", + "extendInfo": { + "vmsPlatformId": "29", + "vmsChannel": "34", + "vmsCameraDecoderTag": "hikvision", + "platformPluginType": "PLATFORM_PLUGIN_TYPE_HAIKANG_NVR", + "deviceVender": "0", + "type": "DEVICEMANAGER_CAMERA_TYPE_NORMAL", + "ip": "", + "port": "0", + "username": "", + "passwd": "", + "rtspAddress": "", + "facesnapChannel": "", + "edgeDeviceSn": "", + "platform1400Id": 0, + "useRtspAddress": false, + "frameCheck": false, + "frameRectX": 0, + "frameRectY": 0, + "frameRectW": 0, + "frameRectH": 0, + "edgeNodeId": "0", + "processStatus": "FILTER_REALTIME_DEFAULT" + } + }, + "solutionId": "1", + "fragmentId": "0", + "contrastKey": "singer-20240102/1/129529/1742092514409592832.jpg", + "compaterImages": [ + "http://10.0.0.7:30003/file/singer-20240102/1/129529/1742047651878156288.jpg" + ], + "imgSummary": "singer-20240102/1/129529/1742092514409592832.jpg", + "imageKey": "http://10.0.0.7:30003/file/singer-20240102/1/129529/1742092514409592832.jpg", + "srcImageUrl": "http://10.0.0.7:30003/file/singer-20240102/1/129529/1742092515508500480.jpg", + "algorithmVersion": "VERSION_REID_HEAD_ATTR", + "cameraId": "129529", + "cameraName": "4入口人脸" + } + ], + "isArchiveDetail": false, + "ToolProps": { + "renderVideoBtn": true, + "disableVideo": false + }, + "specialTitle": "" +}; +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + IMAGE_DATA +}); diff --git a/packages/biz/lib/Demo/index.d.ts b/packages/biz/lib/Demo/index.d.ts new file mode 100644 index 0000000..bcc157c --- /dev/null +++ b/packages/biz/lib/Demo/index.d.ts @@ -0,0 +1,3 @@ +import React from 'react'; +declare const _default: () => React.JSX.Element; +export default _default; diff --git a/packages/biz/lib/Demo/index.js b/packages/biz/lib/Demo/index.js new file mode 100644 index 0000000..fd221c7 --- /dev/null +++ b/packages/biz/lib/Demo/index.js @@ -0,0 +1,41 @@ +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// src/Demo/index.tsx +var Demo_exports = {}; +__export(Demo_exports, { + default: () => Demo_default +}); +module.exports = __toCommonJS(Demo_exports); +var import_react = __toESM(require("react")); +var import_antd = require("antd"); +var import_hooks = require("@zhst/hooks"); +var Demo_default = () => { + const { run } = (0, import_hooks.useThrottleFn)(() => console.log("123")); + return /* @__PURE__ */ import_react.default.createElement(import_antd.Button, { onClick: () => run() }, "测试"); +}; diff --git a/packages/biz/lib/adapter/BigImageModalAdapter/index.d.ts b/packages/biz/lib/adapter/BigImageModalAdapter/index.d.ts new file mode 100644 index 0000000..dab889b --- /dev/null +++ b/packages/biz/lib/adapter/BigImageModalAdapter/index.d.ts @@ -0,0 +1,153 @@ +/** + * 适配老的大屏组件数据格式传入 + */ +import React from 'react'; +import { AlgorithmVersionStr, HumanProperty, ObjectType, Rect, ViewOption, AlignType, IScreenshotButtonProp, ODRECT } from '@zhst/types'; +export type TAB_TYPE = 'COMPATER' | 'NORMAL' | 'TRACK'; +export type MODEL_TYPE = 'VIDEO' | 'IMAGE'; +export interface ImgViewProps extends React.HTMLAttributes { + imageKey: string; + odRect: ODRECT; + attachImg?: Array<{ + label: string; + url: string; + }>; + showAttachImgLabel: boolean; + screenshotButtonAlign: AlignType; + screenshotButtonRender: (screenshotButtonProp: IScreenshotButtonProp) => React.ReactElement; + scale$?: number; + showCrop$?: boolean; + hideLeftTopBtn?: boolean; + score?: number; + viewOption?: ViewOption; +} +export interface VideoViewProps { + flvUrl: string; + maxDuration?: number; + screenshotButtonAlign?: AlignType; + screenshotButtonRender?: (screenshotButtonProp: IScreenshotButtonProp) => React.ReactElement; + defautlNormalizationRect?: Rect; + onCropChange?: (showCrop: boolean, normalizationRect: null | Rect) => void; + showCrop$?: boolean; +} +export interface CarouselProps { + hasPre?: boolean; + hasNext?: boolean; + selectIndex: number; + setSelectIndex: React.Dispatch>; + dataSource: Array<{ + key: string; + url: string; + }>; +} +export type ISelectItem = Partial> & Partial>; +export interface HeaderProps { + value: TAB_TYPE; + onChange: (type: TAB_TYPE) => void; + tabsFilter: TAB_TYPE[]; +} +export interface ImgViewRef { + imgInsRef: React.MutableRefObject; + setShowCrop: React.Dispatch>; +} +export interface VideoViewRef { + cropAble: boolean; + setShowCrop: React.Dispatch>; + downloadVideoframe: () => void; +} +export interface ParamProps { + tab: string; + selectItem: ISelectItem; + imgViewRef: React.MutableRefObject; + VideoViewRef: React.MutableRefObject; + model: MODEL_TYPE; + setModel: React.Dispatch>; + scale$: number; + showCrop$: boolean; +} +export interface BigImageData { + extendRectList: (Rect & { + algorithmVersion: AlgorithmVersionStr; + imageKey: string; + })[]; + rectList: (Rect & { + algorithmVersion: AlgorithmVersionStr; + imageKey: string; + })[]; + attachImg: { + url: string; + label: '形体' | '人脸'; + }[]; + odRect: Rect; + imageKey: string; + imgSummary: string; + objectExtImageKey: string; + attributeList: { + label: string; + list: any[]; + }[]; + archiveImages?: any; + spaceName: string; + objectType: ObjectType; + objectId: string; + bodyObjectId?: string; + faceObjectId?: string; + sourceObjectId?: string; + cameraId: string; + cameraName: string; + selectIndex: number; + humanProperty: HumanProperty; + qualityScore?: number; + score: number; + timestamp: string; + bodyImageUrl: string; + faceImageUrl: string; + algorithmVersion: AlgorithmVersionStr; + bodySpaceName: string; + faceSpaceName: string; + solutionId?: string; + [index: string]: any; +} +interface IOldImageData { + visible?: boolean; + defaultModel?: MODEL_TYPE; + onClose?: () => void; + isLoading?: boolean; + hasPre?: boolean; + hasNext?: boolean; + selectIndex?: number; + onSelectIndexChange?: (i: number) => void; + dataSource: any[]; + dataSources: any[]; + relatedData?: any[]; + transformPropFunc: (item: any) => ISelectItem; + transformVideoPropFunc: (item: ISelectItem) => Promise>; + screenshotButtonRender?: (screenshotButtonProp: IScreenshotButtonProp) => React.ReactElement; + showTool?: boolean; + showCarousel?: boolean; + imgViewProp?: Partial; + videoViewProp?: Partial; + ToolProps?: Partial; + nullDialogProp?: { + emptyText?: string; + }; + showHeader?: boolean; + tabsFilter?: TAB_TYPE[]; + useVirtual?: boolean; + loadNext?: (i: number) => Promise; + loadPre?: (i: number) => Promise; + children: React.ReactNode; + title?: string; + specialTitle?: string; + isRelated?: boolean; + carouselProp?: Partial; +} +export interface ToolProps { + renderRight?: (props: ParamProps) => React.ReactNode; + renderLeft?: (props: ParamProps) => React.ReactNode; + renderVideoBtn?: boolean; + param: ParamProps; + disableVideo: boolean; +} +declare const _default: (data: IOldImageData) => IOldImageData; +export default _default; diff --git a/packages/biz/lib/adapter/BigImageModalAdapter/index.js b/packages/biz/lib/adapter/BigImageModalAdapter/index.js new file mode 100644 index 0000000..9deae88 --- /dev/null +++ b/packages/biz/lib/adapter/BigImageModalAdapter/index.js @@ -0,0 +1,28 @@ +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// src/adapter/BigImageModalAdapter/index.tsx +var BigImageModalAdapter_exports = {}; +__export(BigImageModalAdapter_exports, { + default: () => BigImageModalAdapter_default +}); +module.exports = __toCommonJS(BigImageModalAdapter_exports); +var BigImageModalAdapter_default = (data) => { + const newData = data; + return newData; +}; diff --git a/packages/biz/lib/adapter/index.d.ts b/packages/biz/lib/adapter/index.d.ts new file mode 100644 index 0000000..f1dd564 --- /dev/null +++ b/packages/biz/lib/adapter/index.d.ts @@ -0,0 +1 @@ +export { default as BigImageModalAdapter } from './BigImageModalAdapter'; diff --git a/packages/biz/lib/adapter/index.js b/packages/biz/lib/adapter/index.js new file mode 100644 index 0000000..8f1699d --- /dev/null +++ b/packages/biz/lib/adapter/index.js @@ -0,0 +1,39 @@ +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// src/adapter/index.ts +var adapter_exports = {}; +__export(adapter_exports, { + BigImageModalAdapter: () => import_BigImageModalAdapter.default +}); +module.exports = __toCommonJS(adapter_exports); +var import_BigImageModalAdapter = __toESM(require("./BigImageModalAdapter")); +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + BigImageModalAdapter +}); diff --git a/packages/biz/lib/hooks/useIntelligentTracking/index.d.ts b/packages/biz/lib/hooks/useIntelligentTracking/index.d.ts new file mode 100644 index 0000000..c1e54ef --- /dev/null +++ b/packages/biz/lib/hooks/useIntelligentTracking/index.d.ts @@ -0,0 +1,45 @@ +import { Dayjs as Moment } from 'dayjs'; +export declare const getDefaultRadius: () => number; +export declare const setDefaultRadius: (radius: number) => void; +export declare const setSearchIntervalDuration: (duration: number) => void; +export declare const getSearchIntervalDuration: (time: number) => number; +export declare const operateTrackById: (smartTrackId: number, operationType: OperationType) => Promise; +export declare const deleteTrackById: (smartTrackId: number) => Promise; +export declare const modifyTrackImgs: (smartTrackId: number, images: Array) => Promise; +export declare const modifyTrackConf: (conf: any, smartTrackId: number) => Promise; +export declare const getTrackTaskById: (smartTrackId?: number) => Promise; +export declare const getTackDetailInfo: (smartTrackId?: number) => Promise; +export declare const getTaskCameraByCenterAndPower: (value: { + taskPower: { + facePower: number; + bodyPower: number; + }; + cameraInfos: Array; + center: [number, number]; +}) => Promise; +/**创建追踪任务 */ +export declare const createIntelligentTrack: (value: { + images: Array; + deviceIds: Array; + circleCenter: [number, number]; + model: number; + circleRadius: number; + facePower?: number; + bodyPower?: number; + historyTime?: [Moment, Moment]; + topping?: boolean; +}) => Promise; +export declare const emitHeartbeat: (smartTrackId: number) => Promise; +export declare const ModifyTrackCameras: (value: { + smartTrackId: number; + deviceIds: Array; + centerPoint: [number, number]; +}) => Promise; +export declare const setIntelligentTrackCircleInfo: (smartTrackId: number, circleCenter: [number, number]) => Promise; +export declare const getTackCameraInfo: (value: { + circleCenter: [Moment, Moment]; + radius: number; + zoom: number; +}) => Promise; +export declare const getCameraInfoByCircle: (circleCenter: any, radius: any, zoom?: number) => Promise; +export declare const taskInfoToSearchItem: (taskInfo: any) => any[]; diff --git a/packages/biz/lib/hooks/useIntelligentTracking/index.js b/packages/biz/lib/hooks/useIntelligentTracking/index.js new file mode 100644 index 0000000..7cacace --- /dev/null +++ b/packages/biz/lib/hooks/useIntelligentTracking/index.js @@ -0,0 +1,371 @@ +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// src/hooks/useIntelligentTracking/index.tsx +var useIntelligentTracking_exports = {}; +__export(useIntelligentTracking_exports, { + ModifyTrackCameras: () => ModifyTrackCameras, + createIntelligentTrack: () => createIntelligentTrack, + deleteTrackById: () => deleteTrackById, + emitHeartbeat: () => emitHeartbeat, + getCameraInfoByCircle: () => getCameraInfoByCircle, + getDefaultRadius: () => getDefaultRadius, + getSearchIntervalDuration: () => getSearchIntervalDuration, + getTackCameraInfo: () => getTackCameraInfo, + getTackDetailInfo: () => getTackDetailInfo, + getTaskCameraByCenterAndPower: () => getTaskCameraByCenterAndPower, + getTrackTaskById: () => getTrackTaskById, + modifyTrackConf: () => modifyTrackConf, + modifyTrackImgs: () => modifyTrackImgs, + operateTrackById: () => operateTrackById, + setDefaultRadius: () => setDefaultRadius, + setIntelligentTrackCircleInfo: () => setIntelligentTrackCircleInfo, + setSearchIntervalDuration: () => setSearchIntervalDuration, + taskInfoToSearchItem: () => taskInfoToSearchItem +}); +module.exports = __toCommonJS(useIntelligentTracking_exports); +var turf = __toESM(require("@turf/turf")); +var import_useTaskState = require("../useTaskState"); +var import_Tree = __toESM(require("@common/components/CameraTree/Tree")); +var import_request = __toESM(require("../../utils/request")); +var import_antd = require("antd"); +var import_utils = require("@common/components/CameraTree/utils"); +var import_func = require("@zhst/func"); +var defaultFaceThreshold = 0.68; +var defaultBodyThreshold = 0.7; +var defaultFaceResultNum = 5; +var defaultRadius = 0.15; +var defaultQueryCycle = 10; +var getDefaultRadius = () => { + return defaultRadius; +}; +var setDefaultRadius = (radius) => { + defaultRadius = radius; +}; +var searchIntervalDuration = 10; +var setSearchIntervalDuration = (duration) => { + searchIntervalDuration = duration; +}; +var getSearchIntervalDuration = (time) => { + return time; +}; +var operateTrackById = async (smartTrackId, operationType) => { + try { + const data = { + operationType, + smartTrackId + }; + await (0, import_request.default)({ + method: "PUT", + url: "/singer.SmartTrackService/OperationSmartTrack", + data + }); + import_antd.message.success("操作成功"); + } catch (err) { + console.error(err); + import_antd.message.success("操作失败"); + } +}; +var deleteTrackById = async (smartTrackId) => { + try { + await (0, import_request.default)({ + method: "DELETE", + url: "/singer.SmartTrackService/DeleteSmartTrack", + data: { + smartTrackId + } + }); + } catch (err) { + console.error(err); + } +}; +var modifyTrackImgs = async (smartTrackId, images) => { + try { + await (0, import_request.default)({ + method: "PUT", + url: "/singer.SmartTrackService/ModifyTrackImg", + data: { + images, + smartTrackId + } + }); + } catch (err) { + console.log("err", err); + } +}; +var modifyTrackConf = async (conf, smartTrackId) => { + try { + await (0, import_request.default)({ + method: "PUT", + url: "/singer.SmartTrackService/ModifyTrackConf", + data: { + conf, + smartTrackId + } + }); + } catch (err) { + console.log("err", err); + } +}; +var getTrackTaskById = async (smartTrackId = 0) => { + try { + const data = smartTrackId ? { + smartTrackId + } : {}; + let req = await (0, import_request.default)({ + method: "POST", + url: "/singer.SmartTrackService/GetSmartTrack", + data + }); + return req; + } catch (err) { + console.error(err); + } +}; +var getTackDetailInfo = async (smartTrackId = 0) => { + const data = smartTrackId ? { + smartTrackId + } : {}; + let req = await (0, import_request.default)({ + method: "POST", + url: "/singer.SmartTrackService/GetTrackOverView", + data + }); + return req; +}; +var getTaskCameraByCenterAndPower = async (value) => { + let realCameraInfos = value["cameraInfos"]; + let realPreprocessInfos = []; + if (!(0, import_func.isEmpty)(realCameraInfos)) { + const { taskStatus } = await (0, import_useTaskState.getListTaskStatus)(); + realPreprocessInfos = (0, import_useTaskState.getCameraStatusFunc)(taskStatus); + } + const runRealCameraInfos = []; + realCameraInfos = realCameraInfos.filter((v) => { + if (import_Tree.default.judgeOccupyPowerById(v["id"], realPreprocessInfos)) { + runRealCameraInfos.push(v); + } + return !import_Tree.default.judgeOccupyPowerById(v["id"], realPreprocessInfos); + }); + let from = turf.point(value["center"]); + if (realCameraInfos.length > value["taskPower"]["bodyPower"]) { + realCameraInfos.map((v) => { + let dis = turf.distance(from, turf.point([v["longitude"], v["latitude"]])); + return { + ...v, + dis + }; + }).sort((a, b) => { + return a - b; + }); + realCameraInfos = realCameraInfos.slice(0, value["taskPower"]["bodyPower"]); + } + return [...runRealCameraInfos, ...realCameraInfos]; +}; +var createIntelligentTrack = async (value) => { + const data = { + images: value["images"], + type: value["model"], + normalComputerPower: value["bodyPower"] || 0, + faceComputerPower: value["facePower"] || 0, + // deviceIds: ['129537'], + deviceIds: value["deviceIds"], + conf: { + faceThreshold: defaultFaceThreshold, + bodyThreshold: defaultBodyThreshold, + faceResultNum: defaultFaceResultNum, + radius: value["circleRadius"] * 1e3, + queryCycle: defaultQueryCycle + }, + centerConf: { + centerX: value["circleCenter"][0], + centerY: value["circleCenter"][1] + } + }; + const res = await (0, import_request.default)({ + method: "PUT", + url: "/singer.SmartTrackService/CreateSmartTrack", + data + }); + return res; +}; +var emitHeartbeat = async (smartTrackId) => { + try { + await (0, import_request.default)({ + method: "POST", + url: "/singer.SmartTrackService/SmartTrackHeartBeat", + data: { + smartTrackId + } + }); + } catch (err) { + console.error(err); + } +}; +var ModifyTrackCameras = async (value) => { + try { + await setIntelligentTrackCircleInfo(value["smartTrackId"], value["centerPoint"]); + await (0, import_request.default)({ + url: "/singer.SmartTrackService/ModifyTrackCameras", + method: "PUT", + data: { + smartTrackId: value["smartTrackId"], + deviceIds: value["deviceIds"] + } + }); + } catch (err) { + import_antd.message.error(err); + } +}; +var setIntelligentTrackCircleInfo = async (smartTrackId, circleCenter) => { + try { + await (0, import_request.default)({ + url: "/singer.SmartTrackService/ModifyTrackScopeConf", + method: "PUT", + data: { + smartTrackId, + centerConf: { + centerX: (0, import_func.get)(circleCenter, "0"), + centerY: (0, import_func.get)(circleCenter, "1") + } + } + }); + } catch (err) { + import_antd.message.error(err); + } +}; +var getTackCameraInfo = async (value) => { + let circleCameraInfos = await getCameraInfoByCircle( + value["circleCenter"], + value["radius"], + value["zoom"] + ); + return circleCameraInfos; +}; +var getCameraInfoByCircle = async (circleCenter, radius, zoom = 16) => { + try { + let centerFeature = turf.circle(turf.point(circleCenter), radius, { + units: "kilometers", + steps: 64 + }); + let minx = 0; + let maxx = 0; + let miny = 0; + let maxy = 0; + for (let i = 0; i < 4; i++) { + let point2 = turf.destination(turf.point(circleCenter), radius, 90 * i, { + units: "kilometers" + }).geometry.coordinates; + if (point2[0] < minx || minx === 0) { + minx = point2[0]; + } + if (point2[0] > maxx || maxx === 0) { + maxx = point2[0]; + } + if (point2[1] < miny || miny === 0) { + miny = point2[1]; + } + if (point2[1] > maxy || maxy === 0) { + maxy = point2[1]; + } + } + let { clusterPoint } = await (0, import_request.default)({ + url: "/singer.DeviceService/GetClusters", + method: "POST", + data: { + northEast: { X: maxx, Y: maxy }, + southWest: { X: minx, Y: miny }, + zoom + } + }); + let cameraIds = []; + clusterPoint.forEach((v) => { + cameraIds.push(...v["cameraIDs"]); + }); + const { cameras } = await (0, import_utils.SearchCamera)({ + cameraId: cameraIds, + maxResults: cameraIds.length + }); + const cameraInfos = cameras.filter((v) => { + let cameraPoint = turf.point([(0, import_func.get)(v, "longitude"), (0, import_func.get)(v, "latitude")]); + return turf.booleanPointInPolygon(cameraPoint, centerFeature); + }); + return cameraInfos; + } catch (err) { + console.error(err); + return []; + } +}; +var taskInfoToSearchItem = (taskInfo) => { + let imageList = []; + (0, import_func.get)(taskInfo, "images", []).forEach((v) => { + const url = (0, import_func.get)(v, "conds.0.srcImageUrl"); + const objectId = (0, import_func.get)(v, "conds.0.featureInfo.objectId"); + let imageItem = { + index: 0, + url, + objectId, + odRects: (0, import_func.get)(v, "conds").map((item) => { + return { + fileKey: (0, import_func.get)(item, "objectImageUrl"), + extendRect: { + algorithmVersion: (0, import_func.get)(item, "alg", ""), + ...(0, import_func.get)(item, "rect", {}) + }, + rect: { + algorithmVersion: (0, import_func.get)(item, "alg", ""), + rect: (0, import_func.get)(item, "rect", {}) + } + }; + }) + }; + imageList.push(imageItem); + }); + return imageList; +}; +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + ModifyTrackCameras, + createIntelligentTrack, + deleteTrackById, + emitHeartbeat, + getCameraInfoByCircle, + getDefaultRadius, + getSearchIntervalDuration, + getTackCameraInfo, + getTackDetailInfo, + getTaskCameraByCenterAndPower, + getTrackTaskById, + modifyTrackConf, + modifyTrackImgs, + operateTrackById, + setDefaultRadius, + setIntelligentTrackCircleInfo, + setSearchIntervalDuration, + taskInfoToSearchItem +}); diff --git a/packages/biz/lib/index.d.ts b/packages/biz/lib/index.d.ts new file mode 100644 index 0000000..ac47c74 --- /dev/null +++ b/packages/biz/lib/index.d.ts @@ -0,0 +1,3 @@ +export { default as Demo } from './Demo'; +export * from './adapter'; +export { default as BigImageModal } from './BigImageModal'; diff --git a/packages/biz/lib/index.js b/packages/biz/lib/index.js new file mode 100644 index 0000000..85c051d --- /dev/null +++ b/packages/biz/lib/index.js @@ -0,0 +1,45 @@ +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default")); +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// src/index.tsx +var src_exports = {}; +__export(src_exports, { + BigImageModal: () => import_BigImageModal.default, + Demo: () => import_Demo.default +}); +module.exports = __toCommonJS(src_exports); +var import_Demo = __toESM(require("./Demo")); +__reExport(src_exports, require("./adapter"), module.exports); +var import_BigImageModal = __toESM(require("./BigImageModal")); +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + BigImageModal, + Demo, + ...require("./adapter") +}); diff --git a/packages/biz/lib/useSocket/index.d.ts b/packages/biz/lib/useSocket/index.d.ts new file mode 100644 index 0000000..08018b5 --- /dev/null +++ b/packages/biz/lib/useSocket/index.d.ts @@ -0,0 +1,26 @@ +export declare const SocketApi: { + CameraTaskStatue: string; + DeviceStatus: string; + SubscribeSolutionDeploy: string; + SubscribeTasksSummary: string; + MonitorSubscribeResult: string; + MonitorSubscribeStatus: string; + SubscribeArchiveGroupUpload: string; + SubscribeJointTask: string; + SubscribeGroupFragment: string; + SubscribeGroup: string; + SubscribeStreamEvent: string; +}; +type ApiKeys = keyof typeof SocketApi; +declare const _default: (topic: ApiKeys, iterator?: any, opt?: { + req?: { + [key: string]: any; + } | undefined; + throttle?: number | undefined; + parseData?: boolean | undefined; + beforeLoopTmp?: Function | undefined; + shouldBreak: boolean; + forceRefresh: any; + close?: boolean | undefined; +} | undefined) => void; +export default _default; diff --git a/packages/biz/lib/useSocket/index.js b/packages/biz/lib/useSocket/index.js new file mode 100644 index 0000000..f7a3435 --- /dev/null +++ b/packages/biz/lib/useSocket/index.js @@ -0,0 +1,120 @@ +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// src/useSocket/index.ts +var useSocket_exports = {}; +__export(useSocket_exports, { + SocketApi: () => SocketApi, + default: () => useSocket_default +}); +module.exports = __toCommonJS(useSocket_exports); +var import_react = require("react"); +var import_func = require("@zhst/func"); +var import_hooks = require("@zhst/hooks"); +var import_ws = __toESM(require("./ws")); +var noop = (v) => null; +var getSelf = (v) => v; +var SocketApi = { + CameraTaskStatue: "singer.DeviceService/SubScribeCameraTaskStatus", + DeviceStatus: "singer.TaskManagerService/SubscribeTaskStatus", + SubscribeSolutionDeploy: "singer.SolutionManagerService/SubscribeSolutionDeploy", + SubscribeTasksSummary: "singer.TaskManagerService/SubscribeTasksSummary", + MonitorSubscribeResult: "singer.MonitorService/MonitorSubscribeResult", + MonitorSubscribeStatus: "singer.MonitorService/MonitorSubscribeStatus", + SubscribeArchiveGroupUpload: "singer.ArchiveGroupService/CreateArchiveByImport", + SubscribeJointTask: "singer.JointTaskService/SubscribeJointTask", + SubscribeGroupFragment: "singer.VideoService/SubscribeVideoFragmentStatus", + // 监听视频分片状态变化,包括新建、删除、变化 + SubscribeGroup: "singer.VideoService/SubscribeGroup", + // 监听视频分组状态变化,列表变化也通知 + SubscribeStreamEvent: "singer.MediaManagerService/SubscribeStreamEvent" + // 监听视频分组状态变化,列表变化也通知 +}; +var useSocket_default = (topic, iterator = noop, opt) => { + const { + req = {}, + throttle = 0, + parseData = true, + beforeLoopTmp = getSelf, + shouldBreak = false, + forceRefresh, + close + } = opt || {}; + const reqstring = (0, import_react.useMemo)(() => { + const newReq = { + ...req, + extraHeaders: { + authorization: localStorage.getItem("USER-TOKEN") + } + }; + return JSON.stringify(newReq); + }, [req]); + const latestIterator = (0, import_hooks.useLatest)(iterator); + (0, import_hooks.useDeepEffect)(() => { + if (close) { + return; + } + if (shouldBreak) { + return; + } + let tmpData = []; + const throttleUpdate = (0, import_func.throttle)(() => { + if (tmpData.length == 0) { + return; + } + const _tmpData = beforeLoopTmp(tmpData); + latestIterator.current(_tmpData); + tmpData = []; + }, throttle); + const unSubscribe = import_ws.default.subscribe(SocketApi[topic], reqstring, (socketData) => { + try { + if (!throttle) { + latestIterator.current(socketData); + } else { + tmpData.push(socketData); + throttleUpdate(); + } + } catch (error) { + console.error("useSocke:", error); + } + }); + return () => { + try { + unSubscribe(); + throttleUpdate.cancel(); + } catch (error) { + console.error(error); + throw error; + } + }; + }, [topic, reqstring, shouldBreak, forceRefresh, close]); +}; +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + SocketApi +}); diff --git a/packages/biz/lib/useSocket/onceChannel.d.ts b/packages/biz/lib/useSocket/onceChannel.d.ts new file mode 100644 index 0000000..400ffa7 --- /dev/null +++ b/packages/biz/lib/useSocket/onceChannel.d.ts @@ -0,0 +1,2 @@ +declare const startChannel: (topic: any, req: any, callback: any) => () => void; +export default startChannel; diff --git a/packages/biz/lib/useSocket/onceChannel.js b/packages/biz/lib/useSocket/onceChannel.js new file mode 100644 index 0000000..2dc648e --- /dev/null +++ b/packages/biz/lib/useSocket/onceChannel.js @@ -0,0 +1,51 @@ +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// src/useSocket/onceChannel.tsx +var onceChannel_exports = {}; +__export(onceChannel_exports, { + default: () => onceChannel_default +}); +module.exports = __toCommonJS(onceChannel_exports); +var import_ws = __toESM(require("./ws")); +var startChannel = (topic, req, callback) => { + let reqstring = JSON.stringify({ + ...req, + extraHeaders: { + authorization: localStorage.getItem("USER-TOKEN") + } + }); + let unSubscribe = import_ws.default.subscribe(topic, reqstring, (socketData) => { + let shouldStop = callback(socketData); + if (shouldStop) { + unSubscribe == null ? void 0 : unSubscribe(); + } + }); + return unSubscribe; +}; +var onceChannel_default = startChannel; diff --git a/packages/biz/lib/useSocket/ws.d.ts b/packages/biz/lib/useSocket/ws.d.ts new file mode 100644 index 0000000..cb4f172 --- /dev/null +++ b/packages/biz/lib/useSocket/ws.d.ts @@ -0,0 +1,31 @@ +/// +/// +/// +/// +/// +declare class Channel { + /** + * io 实例化对象 + */ + ioIns: any; + /** + * 已存在的订阅列表 + */ + listeners: never[]; + /** + * 调试信息 记录订阅/反订阅次数 + */ + subscribeListenerId: never[]; + unSubscribeListenerId: never[]; + init: () => void; + retry: (listener: { + [x: string]: any; + lastRetryInterval: number | undefined; + intervalId: NodeJS.Timeout; + } | undefined) => void; + doEmit: (topic: any, req: any, listenerId: any) => void; + subscribe(topic: any, req: any, handle: any): () => void; + unSubscribe(topic: any, req: any, handleId: any, listenerId: any): void; +} +declare const channelIns: Channel; +export default channelIns; diff --git a/packages/biz/lib/useSocket/ws.js b/packages/biz/lib/useSocket/ws.js new file mode 100644 index 0000000..8dab6f2 --- /dev/null +++ b/packages/biz/lib/useSocket/ws.js @@ -0,0 +1,224 @@ +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// src/useSocket/ws.ts +var ws_exports = {}; +__export(ws_exports, { + default: () => ws_default +}); +module.exports = __toCommonJS(ws_exports); +var import_uuid = require("uuid"); +var import_func = require("@zhst/func"); +var import_socket = __toESM(require("socket.io-client")); +var import_constants = require("@common/constants"); +var EMITSTATE = { + NOT_CONNECT: 0, + WAITING: 1, + CONNECT: 2 +}; +var initRetryTime = 0; +var intervalTime = 5 * 1e3; +var maxIntervalTime = 1 * 60 * 60 * 1e3; +var Channel = class { + constructor() { + /** + * 已存在的订阅列表 + */ + this.listeners = [ + // { + // topic: "", + // req: "", + // suInfo: {}, + // hasEmit: false,//是否已经订阅 + // lastRetryInterval: 0, + // handles: { + // } + // } + ]; + /** + * 调试信息 记录订阅/反订阅次数 + */ + this.subscribeListenerId = []; + this.unSubscribeListenerId = []; + this.init = () => { + const ioIns = this.ioIns = (0, import_socket.default)(import_constants.SOCKET_HOST, { + reconnection: true, + transports: ["websocket"], + forceNew: true + }); + ioIns.on("connect", (...arg) => { + console.debug("connect", arg); + this.ioIns = ioIns; + this.listeners.forEach((v) => { + this.doEmit(v["topic"], v["req"], v["id"]); + }); + }); + ioIns.on("event", (...arg) => { + console.debug("event", arg); + }); + ioIns.on("disconnect", (...arg) => { + console.debug("disconnect", arg); + this.subscribeListenerId = []; + this.unSubscribeListenerId = []; + }); + ioIns.on("reconnect", (...arg) => { + console.debug("reconnect", arg); + this.listeners.forEach((v) => { + v["hasEmit"] = EMITSTATE.NOT_CONNECT; + this.doEmit(v["topic"], v["req"], v["id"]); + }); + }); + }; + this.retry = (listener) => { + const intervalId = setTimeout(() => { + const hasExit = this.listeners.find( + (v) => v["topic"] === (listener == null ? void 0 : listener["topic"]) && v["req"] === listener["req"] + ); + if (!hasExit) + return; + listener["hasEmit"] = EMITSTATE.NOT_CONNECT; + this.doEmit(listener["topic"], listener["req"], listener["id"]); + }, listener.lastRetryInterval); + listener.intervalId = intervalId; + listener.lastRetryInterval = intervalTime + listener.lastRetryInterval > maxIntervalTime ? maxIntervalTime : intervalTime + listener.lastRetryInterval; + }; + this.doEmit = (topic, req, listenerId) => { + var _a, _b; + if (!this.ioIns) { + this.init(); + } + const hasEmit = this.listeners.find( + (v) => v["topic"] === topic && v["req"] === req && v["hasEmit"] !== EMITSTATE.NOT_CONNECT + ); + if (hasEmit) { + return; + } + const listener = this.listeners.find((v) => v["topic"] === topic && v["req"] === req); + listener["hasEmit"] = EMITSTATE.WAITING; + (_b = (_a = this.ioIns) == null ? void 0 : _a.emit) == null ? void 0 : _b.call(_a, topic, req, (data) => { + var _a2, _b2; + console.info("emit", topic, req, data); + const suInfo = JSON.parse(data); + if ((0, import_func.has)(suInfo, "Error.code")) { + if (suInfo.Error.code === 500) { + this.retry(listener); + } + return; + } + this.subscribeListenerId.push(listenerId); + const currentTopicIndex = this.listeners.findIndex( + (v) => v["topic"] === topic && v["req"] === req && v["id"] === listenerId + ); + if (currentTopicIndex == -1) { + this.ioIns.emit("UnSubscribe", JSON.stringify(suInfo), (data2) => { + this.unSubscribeListenerId.push(listenerId); + console.debug("UNSUBSCRIBE", listenerId, topic, req, data2); + }); + return; + } + if (!suInfo["SubscribeID"]) { + this.listeners.splice(currentTopicIndex, 0); + } else { + this.listeners[currentTopicIndex]["suInfo"] = suInfo; + this.listeners[currentTopicIndex]["hasEmit"] = EMITSTATE.CONNECT; + } + (_b2 = (_a2 = this.ioIns) == null ? void 0 : _a2.on) == null ? void 0 : _b2.call(_a2, suInfo["SubscribeID"], (data2) => { + console.info("on", suInfo["SubscribeID"], data2); + try { + const socketData = JSON.parse(data2); + if ((0, import_func.has)(socketData, "Error.code")) { + if (socketData.Error.code === 500) { + this.retry(listener); + } + return; + } + const { handles = {} } = this.listeners.find((v) => v["topic"] === topic && v["req"] === req) || {}; + Object.keys(handles).forEach((key) => { + try { + const func = handles[key]; + if (!func) + return; + func(socketData); + } catch (error) { + console.error(error); + } + }); + } catch (error) { + console.debug("error", error); + } + }); + }); + }; + } + subscribe(topic, req, handle) { + const handleId = (0, import_uuid.v4)(); + const listenerId = (0, import_uuid.v4)(); + const listener = this.listeners.find((v) => v["topic"] === topic && v["req"] === req); + if (listener) { + listener["handles"][handleId] = handle; + } else { + this.listeners.push({ + topic, + req, + suInfo: {}, + id: listenerId, + hasEmit: EMITSTATE.NOT_CONNECT, + lastRetryInterval: initRetryTime, + handles: { + [`${handleId}`]: handle + } + }); + this.doEmit(topic, req, listenerId); + } + return this.unSubscribe.bind(this, topic, req, handleId, listenerId); + } + unSubscribe(topic, req, handleId, listenerId) { + const listener = this.listeners.find( + (v) => v["topic"] === topic && v["req"] === req && v["id"] === listenerId + ); + const { handles = {}, suInfo } = listener || {}; + if (handles[handleId]) { + delete handles[handleId]; + if (Object.keys(handles).length === 0) { + if (this.intervalId) { + clearTimeout(this.intervalId); + } + if (listener["hasEmit"] === EMITSTATE["CONNECT"]) { + this.ioIns.emit("UnSubscribe", JSON.stringify(suInfo), (data) => { + this.unSubscribeListenerId.push(listenerId); + console.debug("UNSUBSCRIBE", listener["id"], topic, req, data); + }); + } + this.listeners = this.listeners.filter((v) => !(v["topic"] === topic && v["req"] === req)); + } + } + } +}; +var channelIns = new Channel(); +window.__channel__ = channelIns; +var ws_default = channelIns; diff --git a/packages/biz/lib/utils/constants.d.ts b/packages/biz/lib/utils/constants.d.ts new file mode 100644 index 0000000..45a9a99 --- /dev/null +++ b/packages/biz/lib/utils/constants.d.ts @@ -0,0 +1,23 @@ +export declare const OBJECT_GRNER_THRESHOLD = 0.8; +export declare const OBJECT_AGE_TYPE_THRESHOLD = 0.5; +export declare const MODE_KEY = "test_mode"; +export declare const SEARCH_IMG_COUNT = 10; +export declare const GLOBAL_IS_ITEM_NUMBER_SHOW = false; +export declare const publicPath = "hummingbird"; +export declare const ENTER_CIRCLE = "MONITORTYPE_ENTER_CIRCLE"; +export declare const OUT_CIRCLE = "MONITORTYPE_OUT_CIRCLE"; +export declare const TEMP = "MONITORTYPE_TEMP"; +export declare const GLOBAL_IS_BOX_VMS_SHOW = true; +export declare const BODY_SEARCH_THRESHOID = 0.45; +export declare const RECORD_VERSION = "3.0.0"; +export declare const DeviceTab: { + EMPTY: number; + REAL_CAMERA: number; + PREPROCESS_CAMERA: number; + TAG_CAMERA: number; + HISTORY_VIDEO_GROUP: number; + VIRTUAL_CAMERA: number; + REAL_CAMERA_NOFACE: number; + REAL_CAMERA_ONLYFACE: number; + REAL_CAMERA_NOFACE_NOBOX_NODIRECONNECT: number; +}; diff --git a/packages/biz/lib/utils/constants.js b/packages/biz/lib/utils/constants.js new file mode 100644 index 0000000..6c57f12 --- /dev/null +++ b/packages/biz/lib/utils/constants.js @@ -0,0 +1,80 @@ +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// src/utils/constants.ts +var constants_exports = {}; +__export(constants_exports, { + BODY_SEARCH_THRESHOID: () => BODY_SEARCH_THRESHOID, + DeviceTab: () => DeviceTab, + ENTER_CIRCLE: () => ENTER_CIRCLE, + GLOBAL_IS_BOX_VMS_SHOW: () => GLOBAL_IS_BOX_VMS_SHOW, + GLOBAL_IS_ITEM_NUMBER_SHOW: () => GLOBAL_IS_ITEM_NUMBER_SHOW, + MODE_KEY: () => MODE_KEY, + OBJECT_AGE_TYPE_THRESHOLD: () => OBJECT_AGE_TYPE_THRESHOLD, + OBJECT_GRNER_THRESHOLD: () => OBJECT_GRNER_THRESHOLD, + OUT_CIRCLE: () => OUT_CIRCLE, + RECORD_VERSION: () => RECORD_VERSION, + SEARCH_IMG_COUNT: () => SEARCH_IMG_COUNT, + TEMP: () => TEMP, + publicPath: () => publicPath +}); +module.exports = __toCommonJS(constants_exports); +var OBJECT_GRNER_THRESHOLD = 0.8; +var OBJECT_AGE_TYPE_THRESHOLD = 0.5; +var MODE_KEY = "test_mode"; +var SEARCH_IMG_COUNT = 10; +var GLOBAL_IS_ITEM_NUMBER_SHOW = false; +var publicPath = "hummingbird"; +var ENTER_CIRCLE = "MONITORTYPE_ENTER_CIRCLE"; +var OUT_CIRCLE = "MONITORTYPE_OUT_CIRCLE"; +var TEMP = "MONITORTYPE_TEMP"; +var GLOBAL_IS_BOX_VMS_SHOW = true; +var BODY_SEARCH_THRESHOID = 0.45; +var RECORD_VERSION = "3.0.0"; +var DeviceTab = { + EMPTY: 0, + REAL_CAMERA: 1, + PREPROCESS_CAMERA: 2, + //摄像头列表 + TAG_CAMERA: 3, + //预案列表 + HISTORY_VIDEO_GROUP: 4, + //录像回放 + VIRTUAL_CAMERA: 5, + //离线视频 + REAL_CAMERA_NOFACE: 6, + REAL_CAMERA_ONLYFACE: 7, + REAL_CAMERA_NOFACE_NOBOX_NODIRECONNECT: 8 + // 只有普通摄像头,没有人脸、没有盒子、直连 +}; +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + BODY_SEARCH_THRESHOID, + DeviceTab, + ENTER_CIRCLE, + GLOBAL_IS_BOX_VMS_SHOW, + GLOBAL_IS_ITEM_NUMBER_SHOW, + MODE_KEY, + OBJECT_AGE_TYPE_THRESHOLD, + OBJECT_GRNER_THRESHOLD, + OUT_CIRCLE, + RECORD_VERSION, + SEARCH_IMG_COUNT, + TEMP, + publicPath +}); diff --git a/packages/hooks/es/useIMEComposition/constants.d.ts b/packages/biz/lib/utils/index.d.ts similarity index 100% rename from packages/hooks/es/useIMEComposition/constants.d.ts rename to packages/biz/lib/utils/index.d.ts diff --git a/packages/hooks/es/useIMEComposition/constants.js b/packages/biz/lib/utils/index.js similarity index 100% rename from packages/hooks/es/useIMEComposition/constants.js rename to packages/biz/lib/utils/index.js diff --git a/packages/biz/package.json b/packages/biz/package.json index 856a801..8508710 100644 --- a/packages/biz/package.json +++ b/packages/biz/package.json @@ -1,6 +1,6 @@ { "name": "@zhst/biz", - "version": "0.2.4", + "version": "0.3.0", "description": "业务库", "keywords": [ "business", @@ -40,9 +40,7 @@ "@zhst/hooks": "workspace:^", "@zhst/meta": "workspace:^", "antd": "^5.12.5", - "base-64": "^1.0.0", "classnames": "^2.5.1", - "rc-util": "^5.38.1", - "umi-request": "^1.4.0" + "rc-util": "^5.38.1" } } diff --git a/packages/biz/src/BigImageModal/BigImageModal.tsx b/packages/biz/src/BigImageModal/BigImageModal.tsx new file mode 100644 index 0000000..28ae31c --- /dev/null +++ b/packages/biz/src/BigImageModal/BigImageModal.tsx @@ -0,0 +1,162 @@ +// @ts-nocheck +import React, { useRef, useState } from 'react' +import { Descriptions, Modal, Tabs } from 'antd'; +import classNames from 'classnames' +import type { ModalProps, DescriptionsProps, TabsProps } from 'antd' +import { get } from '@zhst/func'; +import './index.less' +import Navigation from './components/navigation'; + +const DescriptionsItem = Descriptions.Item + +export const componentPrefix = 'zhst-image' + +export interface BigImageModalProps extends ModalProps { + visible: boolean // 弹框显示隐藏 + descriptionConfig: { + data: { // 描述列表 + title: string; // 标题 + children: Pick // 描述项 + }[] + } + tabsConfig: { // 导航栏配置 + data: Pick & { + key: 'NORMAL' | 'COMPATER' | 'TRACK' + } // 导航栏列表 + } + dataSource: any + imageData: any + relatedData: any +} + +const initialStyle ={ + fontSize: '12px' +} + +const BigImageModal: React.FC = (props) => { + const { + title = '-', + open, + visible, + children, + descriptionConfig = { + data: [] + }, + tabsConfig = { + data: [ + { + label: '对比图模式', + key: '1', + children: '对比图组件', + }, + { + label: '场景图模式', + key: '2', + children: '场景图组件', + } + ], + }, + dataSource = [], + imageData = [], + relatedData = [], + } = props + + const showCropRef = useRef(false); + const scaleRef = useRef(0); + + // ========================== 头切换 ========================= + const [activeKey, setActiveKey] = useState(get(tabsConfig, 'data[0].key')); + + // ========================= 预览切换下标 ========================= + const [previewIndex, setPreviewIndex] = useState(0) + const [isRelated, setIsRelated] = useState(false) + + return ( + + {descriptionConfig.data.map(descriptions => ( + + {descriptions.title} +

    + } + column={8} + style={{ padding: '0 64px' }} + > + {descriptions?.children?.map(item => ( + {item.children} + ))} +
    + ))} + +
    + { + activeKey !== 'TRACK' && ( + <> + {/* ----------------------------------- 上一张按钮 ---------------------------------- */} + 1) : (dataSource.length > 1)} + disabled={previewIndex <= 0} + prev + onClick={() => { + setPreviewIndex((pre) => pre - 1); + }} + /> + {/* ----------------------------------- 下一张按钮 ---------------------------------- */} + = imageData.length - 1) || (previewIndex >= dataSource.length - 1)) && `${componentPrefix}-view-container__nav--disabled`, + `${componentPrefix}-view-container__nav--right` + )} + show={isRelated ? (imageData.length > 1) : (dataSource.length > 1)} + disabled={((previewIndex >= imageData.length - 1) || (previewIndex >= dataSource.length - 1))} + next + onClick={async (e) => { + setPreviewIndex((pre) => pre + 1); + }} + /> + + ) + } +
    +
    + ) +} + +export default BigImageModal diff --git a/packages/biz/src/BigImageModal/index.temp.tsx b/packages/biz/src/BigImageModal/index.temp.tsx deleted file mode 100644 index 0e861cc..0000000 --- a/packages/biz/src/BigImageModal/index.temp.tsx +++ /dev/null @@ -1,696 +0,0 @@ -// @ts-nocheck -import React, { ReactElement, useEffect, useRef, useState, useMemo } from 'react'; -import { useLatest, useThrottleFn } from 'ahooks'; -import { isFunction, pick, noop, get, isEmpty } from 'lodash-es'; -import classNames from 'classnames'; -import { message, Modal, Tabs as TabPane } from 'antd'; -import KeyCode from 'rc-util/lib/KeyCode'; -import { observer } from 'mobx-react-lite'; -import ImgView, { ImgViewProps, ImgViewRef } from './ImgView'; -import VideoView, { VideoViewProps, VideoViewRef } from './VideoView'; -import CompareView from './CompareView'; -import Tool, { ToolProps } from './Tool'; -import Header, { Tabs, TabsType, tabsFilter } from './Header'; -import Navigation from './Nav'; -import AttributePanel from './AttributePanel'; -import { usePropState, cssPrefix, getSolt } from './utils'; -import { screenshotButtonProp, MODEL_TYPE, Rect } from '../adapter/BigImageModalAdapter/interface'; -import NullView, { NullDialogProp } from './NullDialog'; -import styles from './index.module.scss'; -import { generateImg } from '@common/utils'; -import IconFont from '../iconfont/IconFont'; -import addEventListenerWrap from '@common/utils/addEventListener'; -import Carousel, { CarouselProps } from './Carousel'; -import { doubleClick } from '@common/components/doubleCheck'; -import { store } from '@store/index'; -import { store as achieveStore } from '@pages/archive/store'; -import { ObjectType } from '@store/Monitor'; - -const componentName = cssPrefix; - -export type selecItem = Partial> & - Partial>; - -export interface ParamProps { - tab: string; - selectItem: selecItem; - imgViewRef: React.MutableRefObject; - VideoViewRef: React.MutableRefObject; - model: MODEL_TYPE; - setModel: React.Dispatch>; - /* 可观测值 */ - scale$: number; - showCrop$: boolean; -} - -export interface BigImageData { - //imageKey 小图 - extendRectList: (Rect & { algorithmVersion: AlgorithmVersionStr; imageKey: string })[]; - rectList: (Rect & { algorithmVersion: AlgorithmVersionStr; imageKey: string })[]; - attachImg: { url: string; label: '形体' | '人脸' }[]; - odRect: Rect; - imageKey: string; //大图 - imgSummary: string; //摘要图 - - objectExtImageKey: string; //比对到的目标图扩展图 === imgSummary - attributeList: { label: string; list: any[] }[]; - archiveImages?: any; - spaceName: string; - - objectType: ObjectType; - objectId: string; //这张摘要本身的Id - bodyObjectId?: string; - faceObjectId?: string; //这张摘要下的人脸Id(如果有) - sourceObjectId?: string; //这张摘要上游的形体Id(如果有) - cameraId: string; - cameraName: string; - selectIndex: number; - humanProperty: HumanProperty; - qualityScore?: number; //人脸质量分 - score: number; //相似度 - timestamp: string; - bodyImageUrl: string; - faceImageUrl: string; - algorithmVersion: AlgorithmVersionStr; - - bodySpaceName: string; - faceSpaceName: string; - - solutionId?: Solution; - [index: string]: any; -} - -export interface BigImageDialogProps { - visible?: boolean; - defaultModel?: MODEL_TYPE; - onClose?: () => void; - isLoading?: boolean; - hasPre?: boolean; - hasNext?: boolean; - selectIndex?: number; - onSelectIndexChange?: (index: number) => void; - dataSource: any[]; - relatedData?: any[]; - transformPropFunc: (item: any) => selecItem; - transformVideoPropFunc: ( - item: selecItem - ) => Promise>; - screenshotButtonRender?: (screenshotButtonProp: screenshotButtonProp) => ReactElement; - showTool?: boolean; - showCarousel?: boolean; - imgViewProp?: Partial; - videoViewProp?: Partial; - ToolProps?: Partial; - nullDialogProp?: Partial; - showHeader?: boolean; - tabsFilter?: tabsFilter; - useVirtual?: boolean; - loadNext?: (index: number) => Promise; - loadPre?: (index: number) => Promise; - children: React.ReactNode; - title?: string; - specialTitle?: string; - isRelated?: boolean; - carouselProp?: Partial; -} - -//查看对比图和场景图组件 -const BigImageDialog: React.FC = (props) => { - const { - hasPre: propHasPre = false, - hasNext: propHasNext = false, - loadNext = noop, - loadPre = noop, - visible = true, - onClose, - isLoading: propIsLoading = false, - selectIndex: propSelectIndex = 0, - onSelectIndexChange, - dataSource = [], - relatedData = [], - screenshotButtonRender, - transformPropFunc, - transformVideoPropFunc, - defaultModel = 'IMAGE', - imgViewProp: otherImgViewProp, - videoViewProp: otherVideoViewProp, - carouselProp: otherCarouselProp, - ToolProps: otherToolProp, - showTool = true, - children, - nullDialogProp, - showHeader = true, - tabsFilter = ['COMPATER', 'NORMAL'], - useVirtual, - title = '查看大图', - specialTitle = '', - showCarousel = true, - isRelated = false, - } = props; - - console.log('props', props) - //可观测值 - const showCrop$Ref = useRef(false); - const scale$Ref = useRef(0); - const showCrop$ = showCrop$Ref.current; - const scale$ = scale$Ref.current; - // ========================== 头切换 ========================= - const [tab, setTab] = useState( - tabsFilter.length > 1 ? (Object.keys(Tabs)[0] as TAB_TYPE) : (Object.keys(Tabs)[1] as TAB_TYPE) - ); - const [activeKey, setActiveKey] = useState('related'); - const [similarList, setSimilarList] = useState(dataSource); // 其他相似目标列表 - const [relatedList, setRelatedList] = useState(relatedData); // 已关联列表 - const [imageData, setImageData] = useState(dataSource); // 其他相似目标列表 - const lastSimData = useLatest(similarList); - const lastRelatedData = useLatest(relatedList); - - // ========================== 内部转换 ========================= - const [model, setModel] = useState(defaultModel); // 图片/视频模式 - useEffect(() => { - if (activeKey === 'unRlated') { - setImageData(lastSimData.current); - setSelectIndex(0); - } - if (activeKey === 'related') { - setImageData(lastRelatedData.current); - setSelectIndex(0); - } - }, [activeKey]); - useEffect(() => { - setSimilarList(dataSource); - if (activeKey === 'unRelated') { - setImageData(dataSource); - } - }, [dataSource]); - - const carouseDataSource = useMemo(() => { - return imageData.map((v: any, index: number) => { - return { - url: generateImg(get(v, 'passerbyImage.objectRects.0.fileKey')), - key: index, - passerbyId: get(v, 'passerbyId'), - }; - }); - }, [imageData, dataSource]); - - //选择 - const [selectIndex, setSelectIndex] = usePropState(propSelectIndex); - const hasPre = propHasPre ? true : selectIndex > 0; - const changeIndex = isRelated ? imageData.length - 1 : dataSource.length - 1; - const hasNext = propHasNext ? true : selectIndex < changeIndex; - //设置选中 - const latestSelectIndex = useLatest(selectIndex); - const latestDataSource = isRelated ? useLatest(imageData) : useLatest(dataSource); - //加一个防背推 - const seq = useRef(0); - const { run: setSelectIndexWrapper } = useThrottleFn( - async (arg: ((num: number) => void) | number) => { - const _seq = ++seq.current; - const selectIndex = latestSelectIndex.current; - const dataSource = latestDataSource.current; - let newIndex = isFunction(arg) ? arg(selectIndex) : arg; - if (newIndex > dataSource.length - 1) { - if (propHasNext) { - await loadNext(newIndex); - } else { - newIndex = dataSource.length - 1; - } - } - if (newIndex < 0) { - newIndex = 0; - } - if (_seq !== seq.current) { - return; - } - - onSelectIndexChange && onSelectIndexChange(newIndex); - setSelectIndex(newIndex); - }, - { wait: 500 } - ); - - //异步获取数据 - const [selectItem, setSelectItem] = useState(null); - const [isFetching, setIsFetching] = useState(true); - //人员属性 - const [attributeList, setAttributeList] = useState([]); - const isLoading = useMemo(() => propIsLoading || isFetching, [propIsLoading, isFetching]); - useEffect(() => { - (async () => { - setIsFetching(true); - let data: any = {}; - if (isRelated) { - data = await transformPropFunc(imageData[selectIndex]); - } else { - data = await transformPropFunc(dataSource[selectIndex]); - } - setAttributeList(get(data, 'attributeList', [])); - //防背推 - if (selectIndex === latestSelectIndex.current) { - setSelectItem(data); - setIsFetching(false); - } - })(); - }, [selectIndex, dataSource, imageData, isRelated]); - - const selectqualityScore = useMemo(() => { - return get(selectItem, 'qualityScore'); - }, [selectItem]); - //支持视频url异步获取 - const [flvUrl, setFlvUrl] = useState(null); - const [maxDuration, setMaxDuration] = useState(null); - useEffect(() => { - (async () => { - if (model === 'IMAGE') { - setFlvUrl(null); - setMaxDuration(null); - return; - } - - if (isFunction(transformVideoPropFunc)) { - //先情空 - setFlvUrl(null); - setMaxDuration(null); - const { flvUrl, maxDuration } = await transformVideoPropFunc(selectItem); - //防背推 - if (selectIndex === latestSelectIndex.current) { - setMaxDuration(maxDuration); - setFlvUrl(flvUrl); - } - } else { - setFlvUrl(get(selectItem, 'flvUrl')); - setMaxDuration(get(selectItem, 'maxDuration')); - } - })(); - }, [selectItem, model]); - - //切换选中index时候变更key 让组件走销毁逻辑 减少大图/视频组件内部逻辑复杂度 - const key = 0 - const imgCmpKey = useMemo(() => `img-key-${key}`, [key]); - const videoCmpKey = useMemo(() => `video-key-${key}`, [key]); - - // ========================== 分离参数 ========================= - const CompareViewProp = { - targertImg: generateImg(get(selectItem, 'imgSummary', '')), // 对比图 - score: get(selectItem, 'score'), - similarScore: get(selectItem, 'similarScore'), - sourceImg: - get(selectItem, 'constractKey', '') || - get(selectItem, 'compaterImages.0') || - generateImg(get(selectItem, 'imgSummary', '')), - compaterImages: get(selectItem, 'compaterImages', []), - specialTitle, - isRelated, - }; - const carouselProp = { - selectIndex, - setSelectIndex: setSelectIndexWrapper, - hasPre, - hasNext, - dataSource: carouseDataSource, - ...otherCarouselProp, - } as CarouselProps; - const imgViewProp = { - ...pick(selectItem, ['imageKey', 'odRect', 'attachImg', 'score']), - screenshotButtonRender, - ...otherImgViewProp, - showCrop$, - scale$, - } as ImgViewProps; - - const videoViewProp = { - flvUrl, - maxDuration, - screenshotButtonRender, - ...otherVideoViewProp, - showCrop$, - } as VideoViewProps; - - const ToolProps = { - ...otherToolProp, - isGray: true, - } as ToolProps; - - // ========================== 插槽参数 ========================= - const imgViewRef = useRef(null); - const VideoViewRef = useRef(null); - scale$; - const param: ParamProps = { - tab, - selectItem, - imgViewRef, - VideoViewRef, - model, - setModel, - showCrop$, - scale$, - }; - const slots = getSolt(children, param); - - // ========================== 监听键盘 ========================= - useEffect(() => { - const onKeyDown = (event) => { - const { keyCode } = event; - if (keyCode === KeyCode.LEFT) { - setSelectIndexWrapper((pre) => --pre); - } - if (keyCode === KeyCode.RIGHT) { - setSelectIndexWrapper((pre) => ++pre); - } - }; - document.addEventListener('keydown', onKeyDown); - return () => { - document.removeEventListener('keydownm', onKeyDown); - }; - }, []); - - // ========================== 监听滚轮 ========================= - React.useEffect(() => { - const mousewheelListener = (e) => { - e.preventDefault(); - let direction = 0; - if (e.wheelDelta) { - //IE/Opera/Chrome - if (e.wheelDelta > 0) { - //向上滚动事件 - direction = 1; - } else { - //向下滚动事件 - direction = -1; - } - } else if (e.detail) { - //Firefox - if (e.detail < 0) { - //向上滚动事件 - direction = 1; - } else { - //向下滚动事件 - direction = -1; - } - } - setSelectIndexWrapper((pre) => { - return direction < 0 ? pre + 1 : pre - 1; - }); - }; - let handleMouseWheel; - if (store.bigImgScrollEmit) { - handleMouseWheel = addEventListenerWrap(document, 'mousewheel', mousewheelListener); - } else { - handleMouseWheel?.remove(); - } - return () => { - handleMouseWheel?.remove(); - }; - }, [store.bigImgScrollEmit]); - - const tabList = [ - { - key: 'related', - label: '关联的目标', - children: ( -
    - {showCarousel && ( -
    - -
    - )} -
    { - if (isEmpty(relatedList)) { - e.stopPropagation(); - } else { - try { - const { archiveId, passerbyId } = selectItem; - if (archiveId && passerbyId) { - doubleClick({ - title: '确认取消关联,取消后可在“其他相似目标推荐”处再次关联', - checkboxLabel: '同时移除档案对应轨迹', - checked: true, - onOk: async () => { - try { - await achieveStore.archive.UnLinkTarget(passerbyId, archiveId); - message.success('目标已成功取消关联!'); - // 更新已关联目标列表 - const { relatedPassersby } = await achieveStore.archive.GetRelatedArchive( - archiveId - ); - setRelatedList(relatedPassersby); - setImageData(relatedPassersby); - // 更新当前相似目标列表 - const { similarPassersby } = - await achieveStore.archive.GetSimilarPasserbyList(archiveId); - setSimilarList(similarPassersby); - setSelectIndex((pre) => { - if (pre > 0) { - return pre - 1; - } else { - return 0; - } - }); - } catch (e) { - message.success('目标取消关联失败!'); - console.error(e); - } - }, - }); - } - } catch (e) { - console.error(e); - } - } - }} - > - - 取消关联 -
    -
    - ), - }, - { - key: 'unRlated', - label: '其他相似目标推荐', - children: ( -
    - {showCarousel && ( -
    - -
    - )} - -
    { - if (isEmpty(lastSimData.current)) { - e.stopPropagation(); - } else { - try { - const { archiveId, passerbyId, archiveGroupId, trajectoryId } = selectItem; - - if (archiveId && passerbyId && archiveGroupId && trajectoryId) { - await achieveStore.archive.LinkTarget({ - passerbyId, - archiveId, - archiveGroupId, - trajectoryId, - }); - message.success('目标已成功关联!'); - // 更新当前相似目标列表 - const { similarPassersby } = await achieveStore.archive.GetSimilarPasserbyList( - archiveId - ); - setSimilarList(similarPassersby); - setImageData(similarPassersby); - - // 更新已关联目标列表 - const { relatedPassersby } = await achieveStore.archive.GetRelatedArchive( - archiveId - ); - setRelatedList(relatedPassersby); - setSelectIndex((pre) => { - if (pre > 0) { - return pre - 1; - } else { - return 0; - } - }); - } - } catch (e) { - message.error('目标关联失败!'); - console.error(e); - } - } - }} - > - - 关联 -
    -
    - ), - }, - ]; - return ( - - {!isEmpty(attributeList) && } - {showHeader && ( -
    - )} -
    - {tab !== 'TRACK' && ( - <> - {/* ---------------------------------- 对比图模式 --------------------------------- */} - {model == 'IMAGE' && tab === 'COMPATER' && !isEmpty(selectItem) && ( - - )} - {/* ---------------------------------- 场景图模式 --------------------------------- */} - {!isLoading && - model == 'IMAGE' && - tab === 'NORMAL' && - !isEmpty(selectItem?.rectList) && ( - - )} - {/* -------------------------------- 暂无图片数据 -------------------------------- */} - {!isLoading && model == 'IMAGE' && isEmpty(selectItem) && tab === 'COMPATER' && ( - - )} - {!isLoading && model == 'IMAGE' && isEmpty(selectItem.rectList) && tab === 'NORMAL' && ( - - )} - {/* --------------------------------- 视频播放模式 --------------------------------- */} - {!isLoading && model == 'VIDEO' && ( - - )} - {/* ----------------------------------- 左导航 ---------------------------------- */} - { - if (useVirtual && selectIndex === 0) { - !!loadPre && loadPre(); - //都跳转到第一个 - setSelectIndexWrapper(0); - } else { - setSelectIndexWrapper((pre) => pre - 1); - } - }} - /> - {/* ----------------------------------- 右导航 ---------------------------------- */} - { - if (isRelated) { - if (useVirtual && selectIndex === imageData.length - 1) { - !!loadNext && (await loadNext()); - //都跳转到第一个 - setSelectIndexWrapper(0); - } else { - setSelectIndexWrapper((pre) => pre + 1); - } - } else { - if (useVirtual && selectIndex === dataSource.length - 1) { - !!loadNext && (await loadNext()); - //都跳转到第一个 - setSelectIndexWrapper(0); - } else { - setSelectIndexWrapper((pre) => pre + 1); - } - } - }} - /> - - )} -
    - {/* 工具集合 */} - {tab !== 'TRACK' && showTool && ( - <> -
    - -
    - {slots['after-tool']} - - )} - {/* 人脸质量分 */} - {!!selectqualityScore && store.user.isfaceScore && model == 'IMAGE' && tab === 'NORMAL' && ( -
    {`人脸质量分:${(selectqualityScore as number).toFixed(2)}`}
    - )} - {/* --------------------------------- 模型碰撞组件 --------------------------------- */} - {isRelated && tab !== 'TRACK' && ( -
    - { - setActiveKey(key); - }} - items={tabList.map((item) => { - return { - label: item.label, - key: item.key, - children: item.children, - }; - })} - /> -
    - )} - - ); -}; - -export default observer(BigImageDialog); diff --git a/packages/biz/src/BigImageModal/index.tsx b/packages/biz/src/BigImageModal/index.tsx index 28ae31c..8ee12d5 100644 --- a/packages/biz/src/BigImageModal/index.tsx +++ b/packages/biz/src/BigImageModal/index.tsx @@ -1,162 +1,5 @@ -// @ts-nocheck -import React, { useRef, useState } from 'react' -import { Descriptions, Modal, Tabs } from 'antd'; -import classNames from 'classnames' -import type { ModalProps, DescriptionsProps, TabsProps } from 'antd' -import { get } from '@zhst/func'; -import './index.less' -import Navigation from './components/navigation'; +import BigImageModal from "./BigImageModal"; -const DescriptionsItem = Descriptions.Item - -export const componentPrefix = 'zhst-image' - -export interface BigImageModalProps extends ModalProps { - visible: boolean // 弹框显示隐藏 - descriptionConfig: { - data: { // 描述列表 - title: string; // 标题 - children: Pick // 描述项 - }[] - } - tabsConfig: { // 导航栏配置 - data: Pick & { - key: 'NORMAL' | 'COMPATER' | 'TRACK' - } // 导航栏列表 - } - dataSource: any - imageData: any - relatedData: any -} - -const initialStyle ={ - fontSize: '12px' -} - -const BigImageModal: React.FC = (props) => { - const { - title = '-', - open, - visible, - children, - descriptionConfig = { - data: [] - }, - tabsConfig = { - data: [ - { - label: '对比图模式', - key: '1', - children: '对比图组件', - }, - { - label: '场景图模式', - key: '2', - children: '场景图组件', - } - ], - }, - dataSource = [], - imageData = [], - relatedData = [], - } = props - - const showCropRef = useRef(false); - const scaleRef = useRef(0); - - // ========================== 头切换 ========================= - const [activeKey, setActiveKey] = useState(get(tabsConfig, 'data[0].key')); - - // ========================= 预览切换下标 ========================= - const [previewIndex, setPreviewIndex] = useState(0) - const [isRelated, setIsRelated] = useState(false) - - return ( - - {descriptionConfig.data.map(descriptions => ( - - {descriptions.title} -

    - } - column={8} - style={{ padding: '0 64px' }} - > - {descriptions?.children?.map(item => ( - {item.children} - ))} -
    - ))} - -
    - { - activeKey !== 'TRACK' && ( - <> - {/* ----------------------------------- 上一张按钮 ---------------------------------- */} - 1) : (dataSource.length > 1)} - disabled={previewIndex <= 0} - prev - onClick={() => { - setPreviewIndex((pre) => pre - 1); - }} - /> - {/* ----------------------------------- 下一张按钮 ---------------------------------- */} - = imageData.length - 1) || (previewIndex >= dataSource.length - 1)) && `${componentPrefix}-view-container__nav--disabled`, - `${componentPrefix}-view-container__nav--right` - )} - show={isRelated ? (imageData.length > 1) : (dataSource.length > 1)} - disabled={((previewIndex >= imageData.length - 1) || (previewIndex >= dataSource.length - 1))} - next - onClick={async (e) => { - setPreviewIndex((pre) => pre + 1); - }} - /> - - ) - } -
    -
    - ) -} +export type { BigImageModalProps } from './BigImageModal' export default BigImageModal diff --git a/packages/biz/src/hooks/useTaskState/index.ts b/packages/biz/src/hooks/useTaskState/index.ts deleted file mode 100644 index 0f11dee..0000000 --- a/packages/biz/src/hooks/useTaskState/index.ts +++ /dev/null @@ -1,103 +0,0 @@ -import doRequest from '../../utils/request'; -import { NetworkType, useStores } from '@store/index'; -import { useMount, useUnmount } from '@zhst/hooks'; -import { useRef, useState } from 'react'; -import type { CamerasStatusList, StatusList } from '../../interface' - -const Streams = [ - 'TASK_OVERVIEW_WAIT_START_STREAM', - 'TASK_OVERVIEW_WAIT_STREAM', - 'TASK_OVERVIEW_WAIT_START_SVINFER', -]; - -const StreamsNum = [1, 2, 3]; -const RunsNum = [5, 9]; -const ErrorsNum = [7]; - -const Runs = ['TASK_OVERVIEW_RUNNING', 'TASK_OVERVIEW_FINISH']; - -const Errors = ['TASK_OVERVIEW_ERROR']; - -export const getListTaskStatus = async (data?: { taskIndex: { deviceId: string }[] }) => { - const res = await doRequest<{ - taskStatus: StatusList; - }>({ - url: '/singer.TaskManagerService/ListTaskStatusResponse', - method: 'POST', - data: data || {} - }); - return res; -}; -export const getCameraStatusFunc = (list: StatusList, useNum = false) => { - const _Runs: any = useNum ? RunsNum : Runs; - const _Errors: any = useNum ? ErrorsNum : Errors; - const _Streams: any = useNum ? StreamsNum : Streams; - const res = list.reduce((res, cur) => { - const cameraId = cur.taskIndex.deviceId; - const status = cur.taskOverview; - res.some((ids, i) => { - if (ids.includes(cameraId)) { - res[i] = ids.filter((id) => id !== cameraId); - return true; - } - return false; - }); - if (_Runs.includes(status)) { - res[0].push(cameraId); - } else if (_Errors.includes(status)) { - res[1].push(cameraId); - } else if (_Streams.includes(status)) { - res[2].push(cameraId); - } - return res; - }, [[], [], []]); - return [...res]; -}; -let camerasStatusStoreList: CamerasStatusList = [[], [], []]; -let num = 0; -const useTaskState = () => { - const { store } = useStores(); - const [camerasStatusList, setCamerasStatusList] = - useState(camerasStatusStoreList); - const timerRef = useRef(null); - - const getCameraStatus = (list: StatusList, useNum = false) => { - const res = getCameraStatusFunc(list, useNum); - setCamerasStatusList(res); - }; - const request = (data: { taskStatus: StatusList }[]) => { - if (data) { - const list: StatusList = []; - data.forEach((v) => { - list.push(...v.taskStatus); - }); - getCameraStatus(list, store.networkType === NetworkType.NORMAL); - } - }; - useMount(async () => { - num++; - if (num - 1 > 0) { - return; - } - const res = await getListTaskStatus(); - getCameraStatus(res.taskStatus); - if (store.networkType === NetworkType.DUAL_NETWORK) { - timerRef.current = setInterval(async () => { - const res = await getListTaskStatus(); - request([res]); - }, 2000); - } - }); - useUnmount(() => { - clearInterval(timerRef.current); - setCamerasStatusList([[], [], []]); - num--; - if (num === 0) { - camerasStatusStoreList = [[], [], []]; - } - }); - - return camerasStatusList; -}; - -export default useTaskState; diff --git a/packages/biz/src/utils/constants.ts b/packages/biz/src/utils/constants.ts index a4836c1..465736f 100644 --- a/packages/biz/src/utils/constants.ts +++ b/packages/biz/src/utils/constants.ts @@ -1,7 +1,6 @@ export const OBJECT_GRNER_THRESHOLD = 0.8; //目标图判断性别阈值 export const OBJECT_AGE_TYPE_THRESHOLD = 0.5; //目标图判断年龄段阈值 export const MODE_KEY = 'test_mode'; -export const ROUTER_SHOULD_FILTER = isDev; //是否根据后台配置路由,开发环境全打开 //业务约定 export const SEARCH_IMG_COUNT = 10; //检索图片的最大个数 export const GLOBAL_IS_ITEM_NUMBER_SHOW = false; //是否展示索引 diff --git a/packages/biz/src/utils/request.ts b/packages/biz/src/utils/request.ts deleted file mode 100644 index 2681359..0000000 --- a/packages/biz/src/utils/request.ts +++ /dev/null @@ -1,77 +0,0 @@ -import { extend } from 'umi-request'; -import type { RequestOptionsInit } from 'umi-request'; -import { get } from '@zhst/func'; -import { message } from 'antd'; -import base64 from 'base-64'; - -export class ResponseError extends Error { - name; - data; - response; - request; - type; - constructor( - response: Response, - text: string, - data: D, - request: { - url: string; - options: RequestOptionsInit; - }, - type = 'ResponseError' - ) { - super(text || response.statusText); - this.name = 'ResponseError'; - this.data = data; - this.response = response; - this.request = request; - this.type = type; - } -} - -export const request = extend({ - getResponse: true, - // timeout: 1000, - parseResponse: false, -}); - -//错误处理中间件 -request.use(async (ctx, next) => { - const { req } = ctx; - const { toast = true } = req?.options || {}; - try { - await next(); - const { res } = ctx; - const d = await res.text(); - if (res.status === 401) { - message.warning('登录过期,请重新登录!'); - return; - } - const isEmptyRes = d === ''; //有些后端接口成功会返回空 做下兼容 - const body = !isEmptyRes ? JSON.parse(d) : d; - if (res.status >= 200 && res.status < 300) { - ctx.res = body; - } else { - // 先判断Grpc-Metadata-Errorx-Message - let errMsg = res.headers.get('Grpc-Metadata-Errorx-Message'); - if (errMsg) { - errMsg = window.utf8?.decode(base64.decode(errMsg)); - // 后判断 body中的message - } else if (!errMsg && get(body, 'message')) { - errMsg = `${get(body, 'message')}`; - } else { - // 最后看状态码 - errMsg = '您的网络发生异常,无法连接服务器'; - } - toast && message.error(errMsg); - throw new ResponseError(res, errMsg, d, req, 'CustomError'); - } - } catch (error) { - if (get(error, 'type') !== 'CustomError') { - toast && message.error('您的网络发生异常,无法连接服务器'); - } - throw error; - } -}); - -export default request diff --git a/packages/constants/CHANGELOG.md b/packages/constants/CHANGELOG.md index 444b4f0..4f2555a 100644 --- a/packages/constants/CHANGELOG.md +++ b/packages/constants/CHANGELOG.md @@ -1,5 +1,11 @@ # @zhst/biz +## 0.3.0 + +### Minor Changes + +- feat: 初始化项目包 + ## 0.2.4 ### Patch Changes diff --git a/packages/constants/package.json b/packages/constants/package.json index 423601e..b639d51 100644 --- a/packages/constants/package.json +++ b/packages/constants/package.json @@ -1,6 +1,6 @@ { "name": "@zhst/constants", - "version": "0.2.4", + "version": "0.3.0", "description": "常量库", "keywords": [ "constants", @@ -33,6 +33,5 @@ "access": "public", "registry": "http://10.0.0.77:4874" }, - "dependencies": { - } + "dependencies": {} } diff --git a/packages/constants/src/index.tsx b/packages/constants/src/index.tsx index ac0e8bf..6aa4e57 100644 --- a/packages/constants/src/index.tsx +++ b/packages/constants/src/index.tsx @@ -1,2 +1,3 @@ export * from './camera' export * from './base' +export * from './user' diff --git a/packages/constants/src/user/index.ts b/packages/constants/src/user/index.ts index e69de29..b1c6ea4 100644 --- a/packages/constants/src/user/index.ts +++ b/packages/constants/src/user/index.ts @@ -0,0 +1 @@ +export default {} diff --git a/packages/func/CHANGELOG.md b/packages/func/CHANGELOG.md index 19b1dcf..be9f906 100644 --- a/packages/func/CHANGELOG.md +++ b/packages/func/CHANGELOG.md @@ -1,5 +1,16 @@ # @zhst/utils +## 0.3.0 + +### Minor Changes + +- feat: 初始化项目包 + +### Patch Changes + +- Updated dependencies + - @zhst/request@0.3.0 + ## 0.2.4 ### Patch Changes diff --git a/packages/func/es/camera/constants.d.ts b/packages/func/es/camera/constants.d.ts new file mode 100644 index 0000000..0658bd8 --- /dev/null +++ b/packages/func/es/camera/constants.d.ts @@ -0,0 +1,41 @@ +/** + * 设备类型枚举 + */ +export declare const DeviceType: { + VMS: string; + DIR: string; + CAMERA: string; +}; +export declare const LOCAL_KEY = "local"; +export declare const DIRE_CONNECT_KEY = "direconnect"; +export declare const BOX_LIST_KEY = "boxlist"; +export declare enum VmsplatformOpt { + VMSPLATFORMOPT_ID = 0, + VMSPLATFORMOPT_PLATFORMNAME = 1, + VMSPLATFORMOPT_PLUGINNAME = 2, + VMSPLATFORMOPT_IP = 3, + VMSPLATFORMOPT_PORT = 4, + VMSPLATFORMOPT_USERNAME = 5, + VMSPLATFORMOPT_PASSWORD = 6 +} +export declare enum OPT { + OR = 0, + AND = 1, + ORNOT = 2, + ANDNOT = 3 +} +export declare enum DevicemanagerCameraType { + DEVICEMANAGER_CAMERA_TYPE_DEFAULT = 0, + DEVICEMANAGER_CAMERA_TYPE_NORMAL = 1, + DEVICEMANAGER_CAMERA_TYPE_1400 = 97, + DEVICEMANAGER_CAMERA_TYPE_DHGRABBER = 98, + DEVICEMANAGER_CAMERA_TYPE_HKGRABBER = 99, + DEVICEMANAGER_CAMERA_TYPE_LOCAL = 100 +} +export declare const BOX_DIRECONNECT_PLATFORM_FILTER: { + filtervmsplatformList: { + opt: OPT; + vmsplatformOpt: VmsplatformOpt; + value: string; + }[]; +}; diff --git a/packages/func/es/camera/index.d.ts b/packages/func/es/camera/index.d.ts new file mode 100644 index 0000000..c47dcdd --- /dev/null +++ b/packages/func/es/camera/index.d.ts @@ -0,0 +1,40 @@ +import { DevicemanagerCameraType } from './constants'; +export declare const isFaceCamera: (type: DevicemanagerCameraType) => boolean; +/** + * + * @param value 传入的数据 可以是 item(camera/vms/dirs)/ deviceID + * @param isId + */ +export declare function getDeviceType(value: { + [x: string]: any; + id: any; +} | string): any; +/** + * 后端设备id/vmsid/dirid是三张表 合并在一起不保证唯一 前端生成唯一key + * @param id 设备id + * @param type 设备类型 + */ +export declare function deviceIDToDeviceKey(id: any, type: string, vmsId?: any): string; +/** + * 后端设备id/vmsid/dirid是三张表 合并在一起不保证唯一 前端生成唯一key + * @param item camera/vms/dirs + */ +export declare function deviceToDeviceKey(item: { + [x: string]: any; + id: any; +}): string; +/** + * 设备树key 转 后端设备原始id dirid是string/vms&camera 是number 和后端保持一致 + * @param deviceKey 设备树的id + */ +export declare function deviceKeyToDeviceId(deviceKey: { + split: (arg0: string) => [any, any]; +}): any; +export declare const getVmsIdByDeviceId: (key: string) => string; +/** + * 通过设备id或设备key在树里面找摄像头 + * @param ids cameraId + * @param deviceTree 树 + * @param type "id" | "key" + */ +export declare const findCamerasByInDeviceTree: (ids: never[] | undefined, deviceTree: any, type?: string) => any[]; diff --git a/packages/func/es/file/index.d.ts b/packages/func/es/file/index.d.ts new file mode 100644 index 0000000..7997a29 --- /dev/null +++ b/packages/func/es/file/index.d.ts @@ -0,0 +1,75 @@ +import { Rect } from '@zhst/types'; +/** + * + * @param url 需要转为图片的链接 + * @returns 图片的 dom + */ +export declare const urlToImg: (url: string) => Promise; +export declare const base64DecodeImageKey: (base64ImgKey: string) => string; +/** + * 通过url获取图片的base64字符串 + * @param src 图片链接 + * @param outputFormat 图片格式 + * @returns base64 @string + */ +export declare const getBase64ByUrl: (src: string | URL, outputFormat?: string) => Promise; +/** + * 把文件转base64 + * @param file @file 文件 + * @returns @string + */ +export declare const fileToBase64: (file: any) => Promise; +/** + * + * @param image @file 图片文件 + * @param width @number 宽度 + * @param height @number 高度 + * @returns @string base64 + */ +export declare const getBase64Image: (image: any, width?: any, height?: any) => string; +/** + * 通过图片获取base64 + * @param src 图片地址 + * @returns @string + */ +export declare const getBase64ByImage: (src: string) => Promise; +/** + * url转base64 + * @param {String} url - url地址 + */ +export declare const urlToBase64V2: (url: string) => Promise; +/** + * base64转Blob + * @param {String} base64 - base64 + */ +export declare function base64toBlob(base64: string): Blob | undefined; +/** + * 图片集打包压缩下载 + * 1. url -> base64 -> blob + * 2. 将blob加入jsZip文件夹内,用file-saver保存 + * @param {Array<{url:string,name:string}>} imgDataList + * @param {string} zipName + */ +export declare const downloadPackageImages: (imgDataList: string | any[], zipName: string) => Promise; +export declare function getFileSize(size: number): string; +export declare const dataURLToBlob: (dataurl: string) => Blob; +/** + * key 转 http 链接 + * @param originImgkey 图片的值 ,可以是 base64 也可以是 http链接 + * @param host 图片的域值 + * @returns {string} + */ +export declare const generateImg: (imgKey: string, host?: string) => string; +/** + * 获取指定字符串后面的部分 + * @param imageKey v1_开头的字符串 + * @returns + */ +export declare const getImageKey: (imageKey: string, preFix?: string) => string; +/** + * 获取图片 + * @param img 图片的url链接 + * @param odRect + * @returns file + */ +export declare const getFileByRect: (img: string, odRect: Rect) => Promise; diff --git a/packages/func/es/file/index.js b/packages/func/es/file/index.js index e495fba..1fd9c37 100644 --- a/packages/func/es/file/index.js +++ b/packages/func/es/file/index.js @@ -12,8 +12,7 @@ import Base64 from 'base-64'; import JSZip from 'jszip'; import FileSaver from 'file-saver'; import { matchS3Prefix } from "../utils"; -import { get } from 'lodash-es'; - +import { get, isString } from 'lodash-es'; /** * * @param url 需要转为图片的链接 @@ -323,9 +322,10 @@ export var generateImg = function generateImg(_imgKey) { var imgUrl = ''; //判空 if (!imgKey) return ''; - if (/^(http:|https:)/.test(imgKey)) { + if (/(http|https):\/\/([\w.]+\/?)\S*/ig.test(imgKey)) { return imgKey; } + console.log('imgKey', imgKey); try { if (matchS3Prefix(imgKey)) { imgKey = base64DecodeImageKey(imgKey); @@ -357,4 +357,57 @@ export var getImageKey = function getImageKey(imageKey, preFix) { } else { return imageKey; } -}; \ No newline at end of file +}; + +/** + * 获取图片 + * @param img 图片的url链接 + * @param odRect + * @returns file + */ +export var getFileByRect = /*#__PURE__*/function () { + var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2(img, odRect) { + var _commonCanvas$parentN; + var image, url, commonCanvas, commonCtx, base64, blobData, file; + return _regeneratorRuntime().wrap(function _callee2$(_context2) { + while (1) switch (_context2.prev = _context2.next) { + case 0: + if (!isString(img)) { + _context2.next = 7; + break; + } + url = generateImg(img); + _context2.next = 4; + return urlToImg(url); + case 4: + image = _context2.sent; + _context2.next = 8; + break; + case 7: + image = img; + case 8: + commonCanvas = document.createElement('canvas'); + commonCanvas.width = odRect.w * image.width; + commonCanvas.height = odRect.h * image.height; + commonCanvas.style.display = 'none'; + document.body.appendChild(commonCanvas); + commonCtx = commonCanvas.getContext('2d'); + commonCtx === null || commonCtx === void 0 || commonCtx.translate(-odRect.x * image.width, -odRect.y * image.height); + commonCtx === null || commonCtx === void 0 || commonCtx.drawImage(image, 0, 0); + base64 = commonCanvas.toDataURL('image/jpeg'); + blobData = dataURLToBlob(base64); + (_commonCanvas$parentN = commonCanvas.parentNode) === null || _commonCanvas$parentN === void 0 || _commonCanvas$parentN.removeChild(commonCanvas); + file = new window.File([blobData], "".concat(new Date().getTime()), { + type: 'image/jpeg' + }); + return _context2.abrupt("return", file); + case 21: + case "end": + return _context2.stop(); + } + }, _callee2); + })); + return function getFileByRect(_x3, _x4) { + return _ref2.apply(this, arguments); + }; +}(); \ No newline at end of file diff --git a/packages/func/es/index.d.ts b/packages/func/es/index.d.ts new file mode 100644 index 0000000..c7f2505 --- /dev/null +++ b/packages/func/es/index.d.ts @@ -0,0 +1,11 @@ +export * from 'lodash-es'; +export * from './file'; +export * from './map'; +export * from './performance'; +export * from './string'; +export * from './number'; +export * from './time'; +export * from './utils'; +export * from './camera'; +export * from './math'; +export * from './upload'; diff --git a/packages/func/es/index.js b/packages/func/es/index.js index 598dbef..614979f 100644 --- a/packages/func/es/index.js +++ b/packages/func/es/index.js @@ -7,4 +7,5 @@ export * from "./number"; export * from "./time"; export * from "./utils"; export * from "./camera"; -export * from "./math"; \ No newline at end of file +export * from "./math"; +export * from "./upload"; \ No newline at end of file diff --git a/packages/func/es/map/index.d.ts b/packages/func/es/map/index.d.ts new file mode 100644 index 0000000..08fa4a2 --- /dev/null +++ b/packages/func/es/map/index.d.ts @@ -0,0 +1,10 @@ +/** + * 获取经纬信息 + * @param lngLat 位置信息 + * @returns @object { long, lat } + */ +export declare const fixedLngLat: (lngLat?: string) => string; +export declare const transformLngLat: (lngLat?: string) => { + longitude: number; + latitude: number; +} | null; diff --git a/packages/func/es/math/index.d.ts b/packages/func/es/math/index.d.ts new file mode 100644 index 0000000..1ea0b01 --- /dev/null +++ b/packages/func/es/math/index.d.ts @@ -0,0 +1,70 @@ +import { IOdRectOrigin, Rect } from '@zhst/types'; +export declare const ALGORITHM_VERSION: { + 7: string; + 4: string; + 6: string; +}; +export declare const algorithmVersions: string[]; +export declare const getBikeExtendRect: (rect: Rect, maxW: number) => { + x: number; + y: number; + w: number; + h: number; +}; +export declare const getOtherExtendRect: (srcRect: Rect, maxW: number, maxH: number, type: string) => { + x: number; + y: number; + w: number; + h: number; +}; +export declare const getNormalization: (srcRect: Rect, maxW: number, maxH: number) => { + x: number; + y: number; + w: number; + h: number; +}; +export declare const getExtendRect: (normalizationRect: Rect, imgW: number, imgH: number, type: string) => { + x: number; + y: number; + w: number; + h: number; +}; +export declare const getTransformRect: (image: { + height: number; + width: number; +}, transform: { + translateX: any; + translateY: any; + scale: any; + rotate: any; +}, rect: Rect) => { + x: number; + y: number; + w: number; + h: number; +}; +export declare const getRotateImg: (image: HTMLImageElement, rotate: number) => File; +/** + * 格式化工具 + * @param originData + * @returns + */ +export declare const getOdRect: (originData: IOdRectOrigin) => { + x: any; + y: any; + w: any; + h: any; + id: any; + qualityScore: any; + algorithmVersion: string; + featureData: any; + objectRectIndex: number; + objectType: any; + objectId: any; + frameTimestamp: any; + sourceObjectId: any; + extendBox: any; +}[]; +export declare const getOdRectV2: (originData: { + odv2Result: any[]; +}) => any; diff --git a/packages/func/es/math/index.js b/packages/func/es/math/index.js index 16da47f..d9d6d04 100644 --- a/packages/func/es/math/index.js +++ b/packages/func/es/math/index.js @@ -1,8 +1,5 @@ var _ALGORITHM_VERSION; function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } -function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return e; }; var t, e = {}, r = Object.prototype, n = r.hasOwnProperty, o = Object.defineProperty || function (t, e, r) { t[e] = r.value; }, i = "function" == typeof Symbol ? Symbol : {}, a = i.iterator || "@@iterator", c = i.asyncIterator || "@@asyncIterator", u = i.toStringTag || "@@toStringTag"; function define(t, e, r) { return Object.defineProperty(t, e, { value: r, enumerable: !0, configurable: !0, writable: !0 }), t[e]; } try { define({}, ""); } catch (t) { define = function define(t, e, r) { return t[e] = r; }; } function wrap(t, e, r, n) { var i = e && e.prototype instanceof Generator ? e : Generator, a = Object.create(i.prototype), c = new Context(n || []); return o(a, "_invoke", { value: makeInvokeMethod(t, r, c) }), a; } function tryCatch(t, e, r) { try { return { type: "normal", arg: t.call(e, r) }; } catch (t) { return { type: "throw", arg: t }; } } e.wrap = wrap; var h = "suspendedStart", l = "suspendedYield", f = "executing", s = "completed", y = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var p = {}; define(p, a, function () { return this; }); var d = Object.getPrototypeOf, v = d && d(d(values([]))); v && v !== r && n.call(v, a) && (p = v); var g = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(p); function defineIteratorMethods(t) { ["next", "throw", "return"].forEach(function (e) { define(t, e, function (t) { return this._invoke(e, t); }); }); } function AsyncIterator(t, e) { function invoke(r, o, i, a) { var c = tryCatch(t[r], t, o); if ("throw" !== c.type) { var u = c.arg, h = u.value; return h && "object" == _typeof(h) && n.call(h, "__await") ? e.resolve(h.__await).then(function (t) { invoke("next", t, i, a); }, function (t) { invoke("throw", t, i, a); }) : e.resolve(h).then(function (t) { u.value = t, i(u); }, function (t) { return invoke("throw", t, i, a); }); } a(c.arg); } var r; o(this, "_invoke", { value: function value(t, n) { function callInvokeWithMethodAndArg() { return new e(function (e, r) { invoke(t, n, e, r); }); } return r = r ? r.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); } }); } function makeInvokeMethod(e, r, n) { var o = h; return function (i, a) { if (o === f) throw new Error("Generator is already running"); if (o === s) { if ("throw" === i) throw a; return { value: t, done: !0 }; } for (n.method = i, n.arg = a;;) { var c = n.delegate; if (c) { var u = maybeInvokeDelegate(c, n); if (u) { if (u === y) continue; return u; } } if ("next" === n.method) n.sent = n._sent = n.arg;else if ("throw" === n.method) { if (o === h) throw o = s, n.arg; n.dispatchException(n.arg); } else "return" === n.method && n.abrupt("return", n.arg); o = f; var p = tryCatch(e, r, n); if ("normal" === p.type) { if (o = n.done ? s : l, p.arg === y) continue; return { value: p.arg, done: n.done }; } "throw" === p.type && (o = s, n.method = "throw", n.arg = p.arg); } }; } function maybeInvokeDelegate(e, r) { var n = r.method, o = e.iterator[n]; if (o === t) return r.delegate = null, "throw" === n && e.iterator.return && (r.method = "return", r.arg = t, maybeInvokeDelegate(e, r), "throw" === r.method) || "return" !== n && (r.method = "throw", r.arg = new TypeError("The iterator does not provide a '" + n + "' method")), y; var i = tryCatch(o, e.iterator, r.arg); if ("throw" === i.type) return r.method = "throw", r.arg = i.arg, r.delegate = null, y; var a = i.arg; return a ? a.done ? (r[e.resultName] = a.value, r.next = e.nextLoc, "return" !== r.method && (r.method = "next", r.arg = t), r.delegate = null, y) : a : (r.method = "throw", r.arg = new TypeError("iterator result is not an object"), r.delegate = null, y); } function pushTryEntry(t) { var e = { tryLoc: t[0] }; 1 in t && (e.catchLoc = t[1]), 2 in t && (e.finallyLoc = t[2], e.afterLoc = t[3]), this.tryEntries.push(e); } function resetTryEntry(t) { var e = t.completion || {}; e.type = "normal", delete e.arg, t.completion = e; } function Context(t) { this.tryEntries = [{ tryLoc: "root" }], t.forEach(pushTryEntry, this), this.reset(!0); } function values(e) { if (e || "" === e) { var r = e[a]; if (r) return r.call(e); if ("function" == typeof e.next) return e; if (!isNaN(e.length)) { var o = -1, i = function next() { for (; ++o < e.length;) if (n.call(e, o)) return next.value = e[o], next.done = !1, next; return next.value = t, next.done = !0, next; }; return i.next = i; } } throw new TypeError(_typeof(e) + " is not iterable"); } return GeneratorFunction.prototype = GeneratorFunctionPrototype, o(g, "constructor", { value: GeneratorFunctionPrototype, configurable: !0 }), o(GeneratorFunctionPrototype, "constructor", { value: GeneratorFunction, configurable: !0 }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, u, "GeneratorFunction"), e.isGeneratorFunction = function (t) { var e = "function" == typeof t && t.constructor; return !!e && (e === GeneratorFunction || "GeneratorFunction" === (e.displayName || e.name)); }, e.mark = function (t) { return Object.setPrototypeOf ? Object.setPrototypeOf(t, GeneratorFunctionPrototype) : (t.__proto__ = GeneratorFunctionPrototype, define(t, u, "GeneratorFunction")), t.prototype = Object.create(g), t; }, e.awrap = function (t) { return { __await: t }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, c, function () { return this; }), e.AsyncIterator = AsyncIterator, e.async = function (t, r, n, o, i) { void 0 === i && (i = Promise); var a = new AsyncIterator(wrap(t, r, n, o), i); return e.isGeneratorFunction(r) ? a : a.next().then(function (t) { return t.done ? t.value : a.next(); }); }, defineIteratorMethods(g), define(g, u, "Generator"), define(g, a, function () { return this; }), define(g, "toString", function () { return "[object Generator]"; }), e.keys = function (t) { var e = Object(t), r = []; for (var n in e) r.push(n); return r.reverse(), function next() { for (; r.length;) { var t = r.pop(); if (t in e) return next.value = t, next.done = !1, next; } return next.done = !0, next; }; }, e.values = values, Context.prototype = { constructor: Context, reset: function reset(e) { if (this.prev = 0, this.next = 0, this.sent = this._sent = t, this.done = !1, this.delegate = null, this.method = "next", this.arg = t, this.tryEntries.forEach(resetTryEntry), !e) for (var r in this) "t" === r.charAt(0) && n.call(this, r) && !isNaN(+r.slice(1)) && (this[r] = t); }, stop: function stop() { this.done = !0; var t = this.tryEntries[0].completion; if ("throw" === t.type) throw t.arg; return this.rval; }, dispatchException: function dispatchException(e) { if (this.done) throw e; var r = this; function handle(n, o) { return a.type = "throw", a.arg = e, r.next = n, o && (r.method = "next", r.arg = t), !!o; } for (var o = this.tryEntries.length - 1; o >= 0; --o) { var i = this.tryEntries[o], a = i.completion; if ("root" === i.tryLoc) return handle("end"); if (i.tryLoc <= this.prev) { var c = n.call(i, "catchLoc"), u = n.call(i, "finallyLoc"); if (c && u) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } else if (c) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); } else { if (!u) throw new Error("try statement without catch or finally"); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } } } }, abrupt: function abrupt(t, e) { for (var r = this.tryEntries.length - 1; r >= 0; --r) { var o = this.tryEntries[r]; if (o.tryLoc <= this.prev && n.call(o, "finallyLoc") && this.prev < o.finallyLoc) { var i = o; break; } } i && ("break" === t || "continue" === t) && i.tryLoc <= e && e <= i.finallyLoc && (i = null); var a = i ? i.completion : {}; return a.type = t, a.arg = e, i ? (this.method = "next", this.next = i.finallyLoc, y) : this.complete(a); }, complete: function complete(t, e) { if ("throw" === t.type) throw t.arg; return "break" === t.type || "continue" === t.type ? this.next = t.arg : "return" === t.type ? (this.rval = this.arg = t.arg, this.method = "return", this.next = "end") : "normal" === t.type && e && (this.next = e), y; }, finish: function finish(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.finallyLoc === t) return this.complete(r.completion, r.afterLoc), resetTryEntry(r), y; } }, catch: function _catch(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.tryLoc === t) { var n = r.completion; if ("throw" === n.type) { var o = n.arg; resetTryEntry(r); } return o; } } throw new Error("illegal catch attempt"); }, delegateYield: function delegateYield(e, r, n) { return this.delegate = { iterator: values(e), resultName: r, nextLoc: n }, "next" === this.method && (this.arg = t), y; } }, e; } -function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } -function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); } @@ -14,8 +11,8 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); } function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); } -import { cloneDeep, get, isNull, isString } from 'lodash-es'; -import { dataURLToBlob, generateImg, urlToImg } from "../file"; +import { cloneDeep, get, isNull } from 'lodash-es'; +import { dataURLToBlob } from "../file"; var proto = { Common: { AlgorithmVersion: { @@ -239,7 +236,7 @@ export var getRotateImg = function getRotateImg(image, rotate) { }; /** - * + * 格式化工具 * @param originData * @returns */ @@ -290,7 +287,6 @@ export var getOdRect = function getOdRect(originData) { //档案库od export var getOdRectV2 = function getOdRectV2(originData) { - // const fileKey = 'v1_' + window.btoa('public_' + imgKey.split('public/')[1]); var resp = originData.odv2Result[0]; var subObjects = []; //形体 var data = get(resp, 'objects', []).filter(function (v) { @@ -359,55 +355,4 @@ export var getOdRectV2 = function getOdRectV2(originData) { } console.log(brr); return brr; -}; - -//获取图片 - -export var getFileByRect = /*#__PURE__*/function () { - var _ref3 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(img, odRect) { - var _commonCanvas$parentN2; - var image, url, commonCanvas, commonCtx, base64, blobData, file; - return _regeneratorRuntime().wrap(function _callee$(_context) { - while (1) switch (_context.prev = _context.next) { - case 0: - if (!isString(img)) { - _context.next = 9; - break; - } - url = generateImg(img); - console.log(url, '获取图片'); - _context.next = 5; - return urlToImg(url); - case 5: - image = _context.sent; - console.log(image, '获取的图片'); - _context.next = 10; - break; - case 9: - image = img; - case 10: - commonCanvas = document.createElement('canvas'); - commonCanvas.width = odRect.w * image.width; - commonCanvas.height = odRect.h * image.height; - commonCanvas.style.display = 'none'; - document.body.appendChild(commonCanvas); - commonCtx = commonCanvas.getContext('2d'); - commonCtx === null || commonCtx === void 0 || commonCtx.translate(-odRect.x * image.width, -odRect.y * image.height); - commonCtx === null || commonCtx === void 0 || commonCtx.drawImage(image, 0, 0); - base64 = commonCanvas.toDataURL('image/jpeg'); - blobData = dataURLToBlob(base64); - commonCanvas === null || commonCanvas === void 0 || (_commonCanvas$parentN2 = commonCanvas.parentNode) === null || _commonCanvas$parentN2 === void 0 || _commonCanvas$parentN2.removeChild(commonCanvas); - file = new window.File([blobData], "".concat(new Date().getTime()), { - type: 'image/jpeg' - }); - return _context.abrupt("return", file); - case 23: - case "end": - return _context.stop(); - } - }, _callee); - })); - return function getFileByRect(_x, _x2) { - return _ref3.apply(this, arguments); - }; -}(); \ No newline at end of file +}; \ No newline at end of file diff --git a/packages/func/es/number/index.d.ts b/packages/func/es/number/index.d.ts new file mode 100644 index 0000000..b8e65be --- /dev/null +++ b/packages/func/es/number/index.d.ts @@ -0,0 +1,14 @@ +/** + * 设置数据的精度 + * @param originNumber + * @param accuracy 精度 以原点为中心向左为正,向右为负, + * @param isCeil 是否为向上取整 + * @returns number + */ +export declare const setNumberAccuracy: (originNumber: number, accuracy?: number, isCeil?: boolean) => number; +/** + * 获取数字 + * @param number 需要校验的数值 + * @returns @number + */ +export declare const toRealNumber: (number: any) => any; diff --git a/packages/func/es/number/index.js b/packages/func/es/number/index.js index 784dc8d..2d44a2a 100644 --- a/packages/func/es/number/index.js +++ b/packages/func/es/number/index.js @@ -24,4 +24,15 @@ export var setNumberAccuracy = function setNumberAccuracy(originNumber) { returnData = Number(returnData.toFixed(0)); } return returnData; +}; + +/** + * 获取数字 + * @param number 需要校验的数值 + * @returns @number + */ +export var toRealNumber = function toRealNumber(number) { + if (isNaN(number) || number === Infinity) { + return 0; + } else return number; }; \ No newline at end of file diff --git a/packages/func/es/performance/index.d.ts b/packages/func/es/performance/index.d.ts new file mode 100644 index 0000000..22dd838 --- /dev/null +++ b/packages/func/es/performance/index.d.ts @@ -0,0 +1 @@ +export declare const speedConvert: (bps: number, contertUnit?: number) => string; diff --git a/packages/func/es/string/index.d.ts b/packages/func/es/string/index.d.ts new file mode 100644 index 0000000..a209796 --- /dev/null +++ b/packages/func/es/string/index.d.ts @@ -0,0 +1,7 @@ +export declare const getStrLength: (str: string) => number; +/** + * js截取字符串,中英文都能用 + * @param str:需要截取的字符串 + * @param len: 需要截取的长度 + */ +export declare const cutStr: (str: string, len: number) => string | String | undefined; diff --git a/packages/func/es/time/index.d.ts b/packages/func/es/time/index.d.ts new file mode 100644 index 0000000..28b4d03 --- /dev/null +++ b/packages/func/es/time/index.d.ts @@ -0,0 +1,11 @@ +export declare const formateDuration: (diff: number) => string; +export declare function generateTime(): { + startDateTime: number; + endDateTime: number; +}; +/** + * 格式化时间为 00:00 + * @param seconds 时间,单位秒 + * @returns + */ +export declare function formatDurationTime(seconds: number): string; diff --git a/packages/func/es/time/index.js b/packages/func/es/time/index.js index 9feb0a8..b60c8aa 100644 --- a/packages/func/es/time/index.js +++ b/packages/func/es/time/index.js @@ -46,4 +46,15 @@ export function generateTime() { startDateTime: startDateTime, endDateTime: endDateTime }; +} + +/** + * 格式化时间为 00:00 + * @param seconds 时间,单位秒 + * @returns + */ +export function formatDurationTime(seconds) { + var minutes = Math.floor(seconds / 60) || 0; + var remainingSeconds = Math.floor(seconds % 60); + return (minutes < 10 ? "0".concat(minutes) : minutes) + ":" + (remainingSeconds < 10 ? "0" : "") + remainingSeconds; } \ No newline at end of file diff --git a/packages/func/es/upload/index.d.ts b/packages/func/es/upload/index.d.ts new file mode 100644 index 0000000..8c370db --- /dev/null +++ b/packages/func/es/upload/index.d.ts @@ -0,0 +1,8 @@ +type uploadOption = { + bucket?: string; + dir?: string; + withSuFuffix?: boolean; +}; +export declare const commonUpload: (file: File, option: uploadOption | undefined, type: string) => Promise; +export declare const upload: (file: File, option?: uploadOption) => Promise; +export {}; diff --git a/packages/func/es/upload/index.js b/packages/func/es/upload/index.js index 6157f92..e978a53 100644 --- a/packages/func/es/upload/index.js +++ b/packages/func/es/upload/index.js @@ -7,6 +7,7 @@ import { getFileSuffix, getImageSuffixByFileType } from "../utils"; import base64 from "base-64"; import { v4 as uuidV4 } from 'uuid'; import { get } from "lodash-es"; +import request from '@zhst/request'; //小文件上传走s3 var defaultBucket = 'public'; @@ -60,7 +61,7 @@ export var commonUpload = /*#__PURE__*/function () { break; } _context.next = 3; - return doRequest({ + return request({ method: 'PUT', url: '/singer.FileServerService/PutObject', data: { @@ -71,6 +72,7 @@ export var commonUpload = /*#__PURE__*/function () { putObjectOption: { contentType: file.type }, + // @ts-ignore fileDataBase64: (_reader$result = reader.result) === null || _reader$result === void 0 ? void 0 : _reader$result.split(';base64,')[1] } }); diff --git a/packages/func/es/utils/index.d.ts b/packages/func/es/utils/index.d.ts new file mode 100644 index 0000000..4a5e574 --- /dev/null +++ b/packages/func/es/utils/index.d.ts @@ -0,0 +1,36 @@ +export { default as isChrome } from './isChrome'; +export declare const matchS3Prefix: (str: string) => boolean; +/** + * 通过文件名获取文件类型 + * @param fileName 文件名称 + * @returns 文件类型 + */ +export declare const getFileSuffix: (fileName: string) => string; +/** + * 通过类型获取文件名 + * @param type 类型 + * @returns + */ +export declare const getImageSuffixByFileType: (type: string) => string; +export declare function getChromeVersion(): number | false; +export declare const nextTick: (func: (value: void) => void | PromiseLike) => void; +export declare const loop: (items: string | any[], callback: (arg0: any) => any) => void; +export declare const addEventListenerWrapper: (target: any, eventType: string, cb: any, option?: any) => { + remove: () => void; +}; +/** + * Get transforms base on the given object. + * @param {Object} obj - The target object. + * @returns {string} A string contains transform values. + */ +export declare function getTransforms({ rotate, scaleX, scaleY, translateX, translateY, }: { + rotate?: number; + scaleX?: number; + scaleY?: number; + translateX?: number; + translateY?: number; +}): { + WebkitTransform: string; + msTransform: string; + transform: string; +}; diff --git a/packages/func/es/utils/index.js b/packages/func/es/utils/index.js index 4316375..a463b52 100644 --- a/packages/func/es/utils/index.js +++ b/packages/func/es/utils/index.js @@ -89,7 +89,7 @@ export var loop = function loop(items, callback) { } } }; -export var addEventListener = function addEventListener(target, eventType, cb, option) { +export var addEventListenerWrapper = function addEventListenerWrapper(target, eventType, cb, option) { /* eslint camelcase: 2 */ var callback = ReactDOM.unstable_batchedUpdates ? function run(e) { ReactDOM.unstable_batchedUpdates(cb, e); diff --git a/packages/func/es/utils/isChrome.d.ts b/packages/func/es/utils/isChrome.d.ts new file mode 100644 index 0000000..2d07ceb --- /dev/null +++ b/packages/func/es/utils/isChrome.d.ts @@ -0,0 +1,3 @@ +export declare const isBrowser: boolean; +declare const isChrome: () => boolean; +export default isChrome; diff --git a/packages/func/es/utils/isChrome.js b/packages/func/es/utils/isChrome.js index 7cfe2e3..6c1ad42 100644 --- a/packages/func/es/utils/isChrome.js +++ b/packages/func/es/utils/isChrome.js @@ -1,7 +1,7 @@ -export var isBrowser = !!(typeof window !== 'undefined' && window); +export var isBrowser = !!(typeof window !== 'undefined' && window.document && window.document.createElement); var isChrome = function isChrome() { var winNav = isBrowser && window.navigator; - var vendorName = winNav && winNav.vendor; + var vendorName = winNav && (winNav === null || winNav === void 0 ? void 0 : winNav.vendor); var userAgent = winNav && winNav.userAgent; //@ts-ignore diff --git a/packages/func/lib/camera/constants.d.ts b/packages/func/lib/camera/constants.d.ts new file mode 100644 index 0000000..0658bd8 --- /dev/null +++ b/packages/func/lib/camera/constants.d.ts @@ -0,0 +1,41 @@ +/** + * 设备类型枚举 + */ +export declare const DeviceType: { + VMS: string; + DIR: string; + CAMERA: string; +}; +export declare const LOCAL_KEY = "local"; +export declare const DIRE_CONNECT_KEY = "direconnect"; +export declare const BOX_LIST_KEY = "boxlist"; +export declare enum VmsplatformOpt { + VMSPLATFORMOPT_ID = 0, + VMSPLATFORMOPT_PLATFORMNAME = 1, + VMSPLATFORMOPT_PLUGINNAME = 2, + VMSPLATFORMOPT_IP = 3, + VMSPLATFORMOPT_PORT = 4, + VMSPLATFORMOPT_USERNAME = 5, + VMSPLATFORMOPT_PASSWORD = 6 +} +export declare enum OPT { + OR = 0, + AND = 1, + ORNOT = 2, + ANDNOT = 3 +} +export declare enum DevicemanagerCameraType { + DEVICEMANAGER_CAMERA_TYPE_DEFAULT = 0, + DEVICEMANAGER_CAMERA_TYPE_NORMAL = 1, + DEVICEMANAGER_CAMERA_TYPE_1400 = 97, + DEVICEMANAGER_CAMERA_TYPE_DHGRABBER = 98, + DEVICEMANAGER_CAMERA_TYPE_HKGRABBER = 99, + DEVICEMANAGER_CAMERA_TYPE_LOCAL = 100 +} +export declare const BOX_DIRECONNECT_PLATFORM_FILTER: { + filtervmsplatformList: { + opt: OPT; + vmsplatformOpt: VmsplatformOpt; + value: string; + }[]; +}; diff --git a/packages/func/lib/camera/constants.js b/packages/func/lib/camera/constants.js new file mode 100644 index 0000000..efd28fa --- /dev/null +++ b/packages/func/lib/camera/constants.js @@ -0,0 +1,90 @@ +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// src/camera/constants.ts +var constants_exports = {}; +__export(constants_exports, { + BOX_DIRECONNECT_PLATFORM_FILTER: () => BOX_DIRECONNECT_PLATFORM_FILTER, + BOX_LIST_KEY: () => BOX_LIST_KEY, + DIRE_CONNECT_KEY: () => DIRE_CONNECT_KEY, + DeviceType: () => DeviceType, + DevicemanagerCameraType: () => DevicemanagerCameraType, + LOCAL_KEY: () => LOCAL_KEY, + OPT: () => OPT, + VmsplatformOpt: () => VmsplatformOpt +}); +module.exports = __toCommonJS(constants_exports); +var DeviceType = { + VMS: "vms", + DIR: "dir", + CAMERA: "camera" +}; +var LOCAL_KEY = "local"; +var DIRE_CONNECT_KEY = "direconnect"; +var BOX_LIST_KEY = "boxlist"; +var VmsplatformOpt = /* @__PURE__ */ ((VmsplatformOpt2) => { + VmsplatformOpt2[VmsplatformOpt2["VMSPLATFORMOPT_ID"] = 0] = "VMSPLATFORMOPT_ID"; + VmsplatformOpt2[VmsplatformOpt2["VMSPLATFORMOPT_PLATFORMNAME"] = 1] = "VMSPLATFORMOPT_PLATFORMNAME"; + VmsplatformOpt2[VmsplatformOpt2["VMSPLATFORMOPT_PLUGINNAME"] = 2] = "VMSPLATFORMOPT_PLUGINNAME"; + VmsplatformOpt2[VmsplatformOpt2["VMSPLATFORMOPT_IP"] = 3] = "VMSPLATFORMOPT_IP"; + VmsplatformOpt2[VmsplatformOpt2["VMSPLATFORMOPT_PORT"] = 4] = "VMSPLATFORMOPT_PORT"; + VmsplatformOpt2[VmsplatformOpt2["VMSPLATFORMOPT_USERNAME"] = 5] = "VMSPLATFORMOPT_USERNAME"; + VmsplatformOpt2[VmsplatformOpt2["VMSPLATFORMOPT_PASSWORD"] = 6] = "VMSPLATFORMOPT_PASSWORD"; + return VmsplatformOpt2; +})(VmsplatformOpt || {}); +var OPT = /* @__PURE__ */ ((OPT2) => { + OPT2[OPT2["OR"] = 0] = "OR"; + OPT2[OPT2["AND"] = 1] = "AND"; + OPT2[OPT2["ORNOT"] = 2] = "ORNOT"; + OPT2[OPT2["ANDNOT"] = 3] = "ANDNOT"; + return OPT2; +})(OPT || {}); +var DevicemanagerCameraType = /* @__PURE__ */ ((DevicemanagerCameraType2) => { + DevicemanagerCameraType2[DevicemanagerCameraType2["DEVICEMANAGER_CAMERA_TYPE_DEFAULT"] = 0] = "DEVICEMANAGER_CAMERA_TYPE_DEFAULT"; + DevicemanagerCameraType2[DevicemanagerCameraType2["DEVICEMANAGER_CAMERA_TYPE_NORMAL"] = 1] = "DEVICEMANAGER_CAMERA_TYPE_NORMAL"; + DevicemanagerCameraType2[DevicemanagerCameraType2["DEVICEMANAGER_CAMERA_TYPE_1400"] = 97] = "DEVICEMANAGER_CAMERA_TYPE_1400"; + DevicemanagerCameraType2[DevicemanagerCameraType2["DEVICEMANAGER_CAMERA_TYPE_DHGRABBER"] = 98] = "DEVICEMANAGER_CAMERA_TYPE_DHGRABBER"; + DevicemanagerCameraType2[DevicemanagerCameraType2["DEVICEMANAGER_CAMERA_TYPE_HKGRABBER"] = 99] = "DEVICEMANAGER_CAMERA_TYPE_HKGRABBER"; + DevicemanagerCameraType2[DevicemanagerCameraType2["DEVICEMANAGER_CAMERA_TYPE_LOCAL"] = 100] = "DEVICEMANAGER_CAMERA_TYPE_LOCAL"; + return DevicemanagerCameraType2; +})(DevicemanagerCameraType || {}); +var BOX_DIRECONNECT_PLATFORM_FILTER = { + filtervmsplatformList: [ + { + opt: 0 /* OR */, + vmsplatformOpt: 1 /* VMSPLATFORMOPT_PLATFORMNAME */, + value: "direconnect" + }, + { + opt: 0 /* OR */, + vmsplatformOpt: 1 /* VMSPLATFORMOPT_PLATFORMNAME */, + value: "boxlist" + } + ] +}; +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + BOX_DIRECONNECT_PLATFORM_FILTER, + BOX_LIST_KEY, + DIRE_CONNECT_KEY, + DeviceType, + DevicemanagerCameraType, + LOCAL_KEY, + OPT, + VmsplatformOpt +}); diff --git a/packages/func/lib/camera/index.d.ts b/packages/func/lib/camera/index.d.ts new file mode 100644 index 0000000..c47dcdd --- /dev/null +++ b/packages/func/lib/camera/index.d.ts @@ -0,0 +1,40 @@ +import { DevicemanagerCameraType } from './constants'; +export declare const isFaceCamera: (type: DevicemanagerCameraType) => boolean; +/** + * + * @param value 传入的数据 可以是 item(camera/vms/dirs)/ deviceID + * @param isId + */ +export declare function getDeviceType(value: { + [x: string]: any; + id: any; +} | string): any; +/** + * 后端设备id/vmsid/dirid是三张表 合并在一起不保证唯一 前端生成唯一key + * @param id 设备id + * @param type 设备类型 + */ +export declare function deviceIDToDeviceKey(id: any, type: string, vmsId?: any): string; +/** + * 后端设备id/vmsid/dirid是三张表 合并在一起不保证唯一 前端生成唯一key + * @param item camera/vms/dirs + */ +export declare function deviceToDeviceKey(item: { + [x: string]: any; + id: any; +}): string; +/** + * 设备树key 转 后端设备原始id dirid是string/vms&camera 是number 和后端保持一致 + * @param deviceKey 设备树的id + */ +export declare function deviceKeyToDeviceId(deviceKey: { + split: (arg0: string) => [any, any]; +}): any; +export declare const getVmsIdByDeviceId: (key: string) => string; +/** + * 通过设备id或设备key在树里面找摄像头 + * @param ids cameraId + * @param deviceTree 树 + * @param type "id" | "key" + */ +export declare const findCamerasByInDeviceTree: (ids: never[] | undefined, deviceTree: any, type?: string) => any[]; diff --git a/packages/func/lib/camera/index.js b/packages/func/lib/camera/index.js new file mode 100644 index 0000000..b7ae6f1 --- /dev/null +++ b/packages/func/lib/camera/index.js @@ -0,0 +1,143 @@ +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// src/camera/index.ts +var camera_exports = {}; +__export(camera_exports, { + deviceIDToDeviceKey: () => deviceIDToDeviceKey, + deviceKeyToDeviceId: () => deviceKeyToDeviceId, + deviceToDeviceKey: () => deviceToDeviceKey, + findCamerasByInDeviceTree: () => findCamerasByInDeviceTree, + getDeviceType: () => getDeviceType, + getVmsIdByDeviceId: () => getVmsIdByDeviceId, + isFaceCamera: () => isFaceCamera +}); +module.exports = __toCommonJS(camera_exports); +var import_lodash_es = require("lodash-es"); +var import_utils = require("../utils"); +var import_constants = require("./constants"); +var isFaceCamera = (type) => { + return [ + import_constants.DevicemanagerCameraType.DEVICEMANAGER_CAMERA_TYPE_1400, + import_constants.DevicemanagerCameraType.DEVICEMANAGER_CAMERA_TYPE_HKGRABBER, + import_constants.DevicemanagerCameraType.DEVICEMANAGER_CAMERA_TYPE_DHGRABBER + ].includes(type); +}; +function getDeviceType(value) { + let type; + let isDeviceKey = (0, import_lodash_es.isString)(value); + if (isDeviceKey) { + type = value.split("_")[0]; + } else { + if ((0, import_lodash_es.has)(value, "longitude")) { + type = import_constants.DeviceType["CAMERA"]; + } + if ((0, import_lodash_es.has)(value, "ip")) { + type = import_constants.DeviceType["VMS"]; + } + if (!type) { + type = import_constants.DeviceType["DIR"]; + } + } + return type; +} +function deviceIDToDeviceKey(id, type, vmsId) { + if (type == import_constants.DeviceType["DIR"]) { + return `${type}_${id}_${vmsId}`; + } else { + return `${type}_${id}`; + } +} +function deviceToDeviceKey(item) { + let deviceKey = ""; + let type = getDeviceType(item); + if (!type) { + console.error("device type is null!"); + } + switch (type) { + case import_constants.DeviceType["DIR"]: + { + let dirId = item["dirid"] || item["dirId"]; + if (!dirId && dirId !== 0) { + console.error("dirId type is null!"); + } + let vmsId = (0, import_lodash_es.get)(item, "extendInfo.vmsPlatformId"); + if (!vmsId && vmsId !== 0) { + console.error("vmsId type is null!"); + } + deviceKey = `${type}_${dirId}_${vmsId}`; + } + break; + case import_constants.DeviceType["VMS"]: + deviceKey = `${type}_${item["id"]}`; + break; + case import_constants.DeviceType["CAMERA"]: + { + let vmsId = (0, import_lodash_es.get)(item, "extendInfo.vmsPlatformId"); + if (!vmsId && vmsId !== 0) { + console.error("vmsId type is null!"); + } + deviceKey = `${type}_${item.id}`; + } + break; + } + return deviceKey; +} +function deviceKeyToDeviceId(deviceKey) { + let [type, id] = deviceKey.split("_"); + return type === import_constants.DeviceType["DIR"] ? id : Number(id); +} +var getVmsIdByDeviceId = (key) => { + const type = getDeviceType(key); + let vmsId = ""; + switch (type) { + case import_constants.DeviceType["CAMERA"]: + case import_constants.DeviceType["DIR"]: + vmsId = key.split("_")[2]; + break; + case import_constants.DeviceType["VMS"]: + vmsId = key.split("_")[1]; + break; + } + if (!vmsId) { + console.error("vmsid is null!"); + } + return vmsId; +}; +var findCamerasByInDeviceTree = (ids = [], deviceTree, type = "id") => { + let cameraInfoList = []; + let _ids = ids.map((v) => String(v)); + (0, import_utils.loop)(deviceTree, (item) => { + let isCamera = getDeviceType((0, import_lodash_es.get)(item, "key", "")) === import_constants.DeviceType["CAMERA"]; + let isMatch = type === "key" ? _ids.includes((0, import_lodash_es.get)(item, "key")) : _ids.includes(`${(0, import_lodash_es.get)(item, "origin.id")}`); + if (isCamera && isMatch) { + cameraInfoList.push(item); + } + }); + return cameraInfoList; +}; +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + deviceIDToDeviceKey, + deviceKeyToDeviceId, + deviceToDeviceKey, + findCamerasByInDeviceTree, + getDeviceType, + getVmsIdByDeviceId, + isFaceCamera +}); diff --git a/packages/func/lib/file/index.d.ts b/packages/func/lib/file/index.d.ts new file mode 100644 index 0000000..7997a29 --- /dev/null +++ b/packages/func/lib/file/index.d.ts @@ -0,0 +1,75 @@ +import { Rect } from '@zhst/types'; +/** + * + * @param url 需要转为图片的链接 + * @returns 图片的 dom + */ +export declare const urlToImg: (url: string) => Promise; +export declare const base64DecodeImageKey: (base64ImgKey: string) => string; +/** + * 通过url获取图片的base64字符串 + * @param src 图片链接 + * @param outputFormat 图片格式 + * @returns base64 @string + */ +export declare const getBase64ByUrl: (src: string | URL, outputFormat?: string) => Promise; +/** + * 把文件转base64 + * @param file @file 文件 + * @returns @string + */ +export declare const fileToBase64: (file: any) => Promise; +/** + * + * @param image @file 图片文件 + * @param width @number 宽度 + * @param height @number 高度 + * @returns @string base64 + */ +export declare const getBase64Image: (image: any, width?: any, height?: any) => string; +/** + * 通过图片获取base64 + * @param src 图片地址 + * @returns @string + */ +export declare const getBase64ByImage: (src: string) => Promise; +/** + * url转base64 + * @param {String} url - url地址 + */ +export declare const urlToBase64V2: (url: string) => Promise; +/** + * base64转Blob + * @param {String} base64 - base64 + */ +export declare function base64toBlob(base64: string): Blob | undefined; +/** + * 图片集打包压缩下载 + * 1. url -> base64 -> blob + * 2. 将blob加入jsZip文件夹内,用file-saver保存 + * @param {Array<{url:string,name:string}>} imgDataList + * @param {string} zipName + */ +export declare const downloadPackageImages: (imgDataList: string | any[], zipName: string) => Promise; +export declare function getFileSize(size: number): string; +export declare const dataURLToBlob: (dataurl: string) => Blob; +/** + * key 转 http 链接 + * @param originImgkey 图片的值 ,可以是 base64 也可以是 http链接 + * @param host 图片的域值 + * @returns {string} + */ +export declare const generateImg: (imgKey: string, host?: string) => string; +/** + * 获取指定字符串后面的部分 + * @param imageKey v1_开头的字符串 + * @returns + */ +export declare const getImageKey: (imageKey: string, preFix?: string) => string; +/** + * 获取图片 + * @param img 图片的url链接 + * @param odRect + * @returns file + */ +export declare const getFileByRect: (img: string, odRect: Rect) => Promise; diff --git a/packages/func/lib/file/index.js b/packages/func/lib/file/index.js new file mode 100644 index 0000000..5199612 --- /dev/null +++ b/packages/func/lib/file/index.js @@ -0,0 +1,318 @@ +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// src/file/index.ts +var file_exports = {}; +__export(file_exports, { + base64DecodeImageKey: () => base64DecodeImageKey, + base64toBlob: () => base64toBlob, + dataURLToBlob: () => dataURLToBlob, + downloadPackageImages: () => downloadPackageImages, + fileToBase64: () => fileToBase64, + generateImg: () => generateImg, + getBase64ByImage: () => getBase64ByImage, + getBase64ByUrl: () => getBase64ByUrl, + getBase64Image: () => getBase64Image, + getFileByRect: () => getFileByRect, + getFileSize: () => getFileSize, + getImageKey: () => getImageKey, + urlToBase64V2: () => urlToBase64V2, + urlToImg: () => urlToImg +}); +module.exports = __toCommonJS(file_exports); +var import_base_64 = __toESM(require("base-64")); +var import_jszip = __toESM(require("jszip")); +var import_file_saver = __toESM(require("file-saver")); +var import_utils = require("../utils"); +var import_lodash_es = require("lodash-es"); +var urlToImg = (url) => { + const resImage = new Promise((resolve) => { + const image = new Image(); + image.crossOrigin = ""; + image.src = url; + image.onload = () => { + resolve(image); + }; + }); + return resImage; +}; +var base64DecodeImageKey = (base64ImgKey) => { + let tempStr = base64ImgKey; + if ((0, import_utils.matchS3Prefix)(tempStr)) { + tempStr = tempStr.replace(/^v[0-9]_/, ""); + tempStr = import_base_64.default.decode(tempStr); + } + const [bucket, ...pathArr] = tempStr.split("_"); + return tempStr = `${bucket}/${pathArr.join("_")}`; +}; +var getBase64ByUrl = function(src, outputFormat = "image/png") { + return new Promise((resolve, reject) => { + const xhr = new XMLHttpRequest(); + xhr.open("GET", src, true); + xhr.responseType = "arraybuffer"; + xhr.onload = function(e) { + if (Number(xhr.status) === 200) { + const uInt8Array = new Uint8Array(xhr.response); + let i = uInt8Array.length; + const binaryString = new Array(i); + while (i--) { + binaryString[i] = String.fromCharCode(uInt8Array[i]); + } + const data = binaryString.join(""); + const base64 = window.btoa(data); + const dataUrl = "data:" + (outputFormat || "image/png") + ";base64," + base64; + resolve(dataUrl); + } else { + reject(e); + } + }; + xhr.onerror = (e) => { + reject(e); + }; + xhr.send(); + }); +}; +var fileToBase64 = (file) => { + return new Promise((resolve, reject) => { + const reader = new FileReader(); + reader.readAsDataURL(file); + reader.onload = function(e) { + resolve(e == null ? void 0 : e.target.result); + }; + reader.onerror = function(e) { + reject(e); + }; + }); +}; +var getBase64Image = (image, width, height) => { + const canvas = document.createElement("canvas"); + canvas.width = width !== void 0 ? width : image.width; + canvas.height = height !== void 0 ? height : image.height; + const ctx = canvas.getContext("2d"); + ctx == null ? void 0 : ctx.drawImage(image, 0, 0, canvas.width, canvas.height); + const ext = image.src.substring(image.src.lastIndexOf(".") + 1).toLowerCase(); + const dataURL = canvas.toDataURL("image/" + ext); + return dataURL; +}; +var getBase64ByImage = function(src) { + return new Promise((resolve, reject) => { + const image = new Image(); + const timestamp = (/* @__PURE__ */ new Date()).getTime(); + const imgUrl = src + "?" + timestamp; + image.src = imgUrl; + image.onload = function() { + function getBase64Image2(img) { + const canvas = document.createElement("canvas"); + canvas.width = img.width; + canvas.height = img.height; + const ctx = canvas.getContext("2d"); + ctx == null ? void 0 : ctx.drawImage(img, 0, 0, img.width, img.height); + const ext = img.src.substring(img.src.lastIndexOf(".") + 1).toLowerCase(); + const dataURL = canvas.toDataURL("image/" + ext); + return dataURL; + } + const base64 = getBase64Image2(image); + resolve(base64); + }; + image.onerror = (e) => { + reject(e); + }; + }); +}; +var urlToBase64V2 = (url) => { + return new Promise((resolve, reject) => { + let image = new Image(); + image.onload = function() { + var _a; + let canvas = document.createElement("canvas"); + canvas.width = image.naturalWidth; + canvas.height = image.naturalHeight; + (_a = canvas == null ? void 0 : canvas.getContext("2d")) == null ? void 0 : _a.drawImage(image, 0, 0); + let result = canvas.toDataURL("image/png"); + resolve(result); + }; + const imgUrl = url; + image.setAttribute("crossOrigin", "Anonymous"); + image.src = imgUrl; + image.onerror = () => { + reject(new Error("Images fail to load")); + }; + }).catch((error) => { + throw new Error(error); + }); +}; +function base64toBlob(base64) { + if (!base64) + return; + var arr = base64.split(","), mime = arr[0].match(/:(.*?);/)[1], bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n); + while (n--) { + u8arr[n] = bstr.charCodeAt(n); + } + return new Blob([u8arr], { type: mime }); +} +var downloadPackageImages = async (imgDataList, zipName) => { + let imgDataDownLoadList = []; + let imgBlobList = []; + let imageSuffix = []; + let zip = new import_jszip.default(); + let img = zip.folder(zipName); + try { + for (let i2 = 0; i2 < imgDataList.length; i2++) { + let src = imgDataList[i2].url; + let suffix = src.substring(src.lastIndexOf(".")); + let base64ByUrl = await urlToBase64V2(imgDataList[i2].url); + if (!base64ByUrl) + continue; + let blob = base64toBlob(base64ByUrl); + imgDataDownLoadList.push(imgDataList[i2]); + imgBlobList.push(blob); + imageSuffix.push(suffix); + } + if (imgBlobList.length === 0) + throw new Error("The number of pictures is zero !"); + if (imgBlobList.length > 0) { + for (var i = 0; i < imgBlobList.length; i++) { + img == null ? void 0 : img.file( + imgDataDownLoadList[i].name + (0, import_lodash_es.get)(imageSuffix, `.${i}`, imageSuffix[0]), + // @ts-ignore + imgBlobList[i], + { + base64: true + } + ); + } + } + zip.generateAsync({ type: "blob" }).then(function(content) { + import_file_saver.default.saveAs(content, zipName + ".zip"); + }); + } catch (error) { + throw new Error(error); + } +}; +function getFileSize(size) { + if (!size) + return ""; + var num = 1024; + if (size < num) + return size + "B"; + if (size < Math.pow(num, 2)) + return (size / num).toFixed(2) + "K"; + if (size < Math.pow(num, 3)) + return (size / Math.pow(num, 2)).toFixed(2) + "M"; + if (size < Math.pow(num, 4)) + return (size / Math.pow(num, 3)).toFixed(2) + "G"; + return (size / Math.pow(num, 4)).toFixed(2) + "T"; +} +var dataURLToBlob = (dataurl) => { + const arr = dataurl.split(","); + const mime = arr[0].match(/:(.*?);/)[1]; + const bstr = atob(arr[1]); + let n = bstr.length; + const u8arr = new Uint8Array(n); + while (n--) { + u8arr[n] = bstr.charCodeAt(n); + } + return new Blob([u8arr], { type: mime }); +}; +var generateImg = (_imgKey, host = "http://10.0.0.120") => { + let imgKey = _imgKey; + let imgUrl = ""; + if (!imgKey) + return ""; + if (/(http|https):\/\/([\w.]+\/?)\S*/ig.test(imgKey)) { + return imgKey; + } + console.log("imgKey", imgKey); + try { + if ((0, import_utils.matchS3Prefix)(imgKey)) { + imgKey = base64DecodeImageKey(imgKey); + if (imgKey.endsWith("/")) { + const i = imgKey.substring(0, imgKey.length - 1); + imgKey = i; + } + } + imgUrl = `${host}/file/${imgKey}`; + if (_imgKey.includes("v3")) { + imgUrl = `${host}/minio/${imgKey}`; + } + } catch (error) { + console.error(error); + imgUrl = ""; + } + return imgUrl; +}; +var getImageKey = (imageKey, preFix) => { + const splitIndex = preFix || "v1_"; + if (imageKey.startsWith(splitIndex)) { + return window.atob(imageKey.split(splitIndex)[1]).replace("_", "/"); + } else { + return imageKey; + } +}; +var getFileByRect = async (img, odRect) => { + var _a; + let image; + if ((0, import_lodash_es.isString)(img)) { + const url = generateImg(img); + image = await urlToImg(url); + } else { + image = img; + } + const commonCanvas = document.createElement("canvas"); + commonCanvas.width = odRect.w * image.width; + commonCanvas.height = odRect.h * image.height; + commonCanvas.style.display = "none"; + document.body.appendChild(commonCanvas); + const commonCtx = commonCanvas.getContext("2d"); + commonCtx == null ? void 0 : commonCtx.translate(-odRect.x * image.width, -odRect.y * image.height); + commonCtx == null ? void 0 : commonCtx.drawImage(image, 0, 0); + const base64 = commonCanvas.toDataURL("image/jpeg"); + const blobData = dataURLToBlob(base64); + (_a = commonCanvas.parentNode) == null ? void 0 : _a.removeChild(commonCanvas); + const file = new window.File([blobData], `${(/* @__PURE__ */ new Date()).getTime()}`, { + type: "image/jpeg" + }); + return file; +}; +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + base64DecodeImageKey, + base64toBlob, + dataURLToBlob, + downloadPackageImages, + fileToBase64, + generateImg, + getBase64ByImage, + getBase64ByUrl, + getBase64Image, + getFileByRect, + getFileSize, + getImageKey, + urlToBase64V2, + urlToImg +}); diff --git a/packages/func/lib/index.d.ts b/packages/func/lib/index.d.ts new file mode 100644 index 0000000..c7f2505 --- /dev/null +++ b/packages/func/lib/index.d.ts @@ -0,0 +1,11 @@ +export * from 'lodash-es'; +export * from './file'; +export * from './map'; +export * from './performance'; +export * from './string'; +export * from './number'; +export * from './time'; +export * from './utils'; +export * from './camera'; +export * from './math'; +export * from './upload'; diff --git a/packages/func/lib/index.js b/packages/func/lib/index.js new file mode 100644 index 0000000..b25df00 --- /dev/null +++ b/packages/func/lib/index.js @@ -0,0 +1,43 @@ +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default")); +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// src/index.ts +var src_exports = {}; +module.exports = __toCommonJS(src_exports); +__reExport(src_exports, require("lodash-es"), module.exports); +__reExport(src_exports, require("./file"), module.exports); +__reExport(src_exports, require("./map"), module.exports); +__reExport(src_exports, require("./performance"), module.exports); +__reExport(src_exports, require("./string"), module.exports); +__reExport(src_exports, require("./number"), module.exports); +__reExport(src_exports, require("./time"), module.exports); +__reExport(src_exports, require("./utils"), module.exports); +__reExport(src_exports, require("./camera"), module.exports); +__reExport(src_exports, require("./math"), module.exports); +__reExport(src_exports, require("./upload"), module.exports); +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + ...require("lodash-es"), + ...require("./file"), + ...require("./map"), + ...require("./performance"), + ...require("./string"), + ...require("./number"), + ...require("./time"), + ...require("./utils"), + ...require("./camera"), + ...require("./math"), + ...require("./upload") +}); diff --git a/packages/func/lib/map/index.d.ts b/packages/func/lib/map/index.d.ts new file mode 100644 index 0000000..08fa4a2 --- /dev/null +++ b/packages/func/lib/map/index.d.ts @@ -0,0 +1,10 @@ +/** + * 获取经纬信息 + * @param lngLat 位置信息 + * @returns @object { long, lat } + */ +export declare const fixedLngLat: (lngLat?: string) => string; +export declare const transformLngLat: (lngLat?: string) => { + longitude: number; + latitude: number; +} | null; diff --git a/packages/func/lib/map/index.js b/packages/func/lib/map/index.js new file mode 100644 index 0000000..39c614a --- /dev/null +++ b/packages/func/lib/map/index.js @@ -0,0 +1,54 @@ +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// src/map/index.ts +var map_exports = {}; +__export(map_exports, { + fixedLngLat: () => fixedLngLat, + transformLngLat: () => transformLngLat +}); +module.exports = __toCommonJS(map_exports); +var fixedLngLat = (lngLat) => { + if (!lngLat) { + return ""; + } + const lngLatArr = lngLat.split(","); + const longitude = Number(lngLatArr[0]).toFixed(6); + const latitude = Number(lngLatArr[1]).toFixed(6); + if (lngLatArr.length < 2) { + return ""; + } + return `${longitude},${latitude}`; +}; +var transformLngLat = (lngLat) => { + if (lngLat) { + const lngLatArr = lngLat ? lngLat.split(",") : []; + const longitude = Number(lngLatArr[0]); + const latitude = Number(lngLatArr[1]); + if (lngLatArr.length < 2) { + return null; + } + return { longitude, latitude }; + } + return null; +}; +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + fixedLngLat, + transformLngLat +}); diff --git a/packages/func/lib/math/index.d.ts b/packages/func/lib/math/index.d.ts new file mode 100644 index 0000000..1ea0b01 --- /dev/null +++ b/packages/func/lib/math/index.d.ts @@ -0,0 +1,70 @@ +import { IOdRectOrigin, Rect } from '@zhst/types'; +export declare const ALGORITHM_VERSION: { + 7: string; + 4: string; + 6: string; +}; +export declare const algorithmVersions: string[]; +export declare const getBikeExtendRect: (rect: Rect, maxW: number) => { + x: number; + y: number; + w: number; + h: number; +}; +export declare const getOtherExtendRect: (srcRect: Rect, maxW: number, maxH: number, type: string) => { + x: number; + y: number; + w: number; + h: number; +}; +export declare const getNormalization: (srcRect: Rect, maxW: number, maxH: number) => { + x: number; + y: number; + w: number; + h: number; +}; +export declare const getExtendRect: (normalizationRect: Rect, imgW: number, imgH: number, type: string) => { + x: number; + y: number; + w: number; + h: number; +}; +export declare const getTransformRect: (image: { + height: number; + width: number; +}, transform: { + translateX: any; + translateY: any; + scale: any; + rotate: any; +}, rect: Rect) => { + x: number; + y: number; + w: number; + h: number; +}; +export declare const getRotateImg: (image: HTMLImageElement, rotate: number) => File; +/** + * 格式化工具 + * @param originData + * @returns + */ +export declare const getOdRect: (originData: IOdRectOrigin) => { + x: any; + y: any; + w: any; + h: any; + id: any; + qualityScore: any; + algorithmVersion: string; + featureData: any; + objectRectIndex: number; + objectType: any; + objectId: any; + frameTimestamp: any; + sourceObjectId: any; + extendBox: any; +}[]; +export declare const getOdRectV2: (originData: { + odv2Result: any[]; +}) => any; diff --git a/packages/func/lib/math/index.js b/packages/func/lib/math/index.js new file mode 100644 index 0000000..85be6ff --- /dev/null +++ b/packages/func/lib/math/index.js @@ -0,0 +1,358 @@ +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// src/math/index.ts +var math_exports = {}; +__export(math_exports, { + ALGORITHM_VERSION: () => ALGORITHM_VERSION, + algorithmVersions: () => algorithmVersions, + getBikeExtendRect: () => getBikeExtendRect, + getExtendRect: () => getExtendRect, + getNormalization: () => getNormalization, + getOdRect: () => getOdRect, + getOdRectV2: () => getOdRectV2, + getOtherExtendRect: () => getOtherExtendRect, + getRotateImg: () => getRotateImg, + getTransformRect: () => getTransformRect +}); +module.exports = __toCommonJS(math_exports); +var import_lodash_es = require("lodash-es"); +var import_file = require("../file"); +var proto = { + Common: { + AlgorithmVersion: { + VERSION_REID_HEAD_ATTR: "形体", + VERSION_FACE: "人脸", + VERSION_NON_MOTOR_VEHICLE: "非机动车" + } + } +}; +var ALGORITHM_VERSION = { + ["7"]: "形体", + ["4"]: "人脸", + ["6"]: "非机动车" +}; +var algorithmVersions = [...Object.keys(ALGORITHM_VERSION)]; +var getBikeExtendRect = (rect, maxW) => { + const newRect = { ...rect }; + const oldY = (0, import_lodash_es.cloneDeep)(rect.y); + newRect.y = newRect.y - newRect.h < 0 ? 0 : newRect.y - newRect.h; + newRect.h += oldY - newRect.y; + let newX = Math.round(newRect.x - newRect.w * 0.15); + if (newX < 0) { + newX = 0; + } + let newW = newRect.x - newX + newRect.w + Math.round(newRect.w * 0.15); + if (newX + newW > maxW) { + newW = maxW - newX; + } + newRect.x = newX; + newRect.w = newW; + return newRect; +}; +var getOtherExtendRect = (srcRect, maxW, maxH, type) => { + const wExtendRadio = 0.25; + const upExtendRadio = 0.25; + const downExtendRadio = 0.25; + const fixPersonExtend = true; + let nx = 0; + let nw = 0; + nx = srcRect.x - Math.round(srcRect.w * wExtendRadio); + if (nx < 0) { + nx = 0; + } + nw = srcRect.x - nx + srcRect.w + Math.round(srcRect.w * wExtendRadio); + if (nx + nw > maxW) { + nw = maxW - nx; + } + let ny = 0; + let nh = 0; + ny = srcRect.y - Math.round(upExtendRadio * srcRect.h); + if (ny < 0) { + ny = 0; + } + nh = srcRect.y - ny + srcRect.h + Math.round(srcRect.h * downExtendRadio); + if (ny + nh > maxH) { + nh = maxH - ny; + } + let newRect = { + x: nx, + y: ny, + w: nw, + h: nh + }; + if ((type === proto.Common.AlgorithmVersion.VERSION_REID_HEAD_ATTR || type === proto.Common.AlgorithmVersion.VERSION_FACE) && fixPersonExtend) { + const fixW = Math.round(nh * 0.75); + if (nw < fixW) { + let newX = nx + Math.round(nw / 2 - 0.5 * fixW); + if (newX < 0) { + newX = 0; + } + let newW = fixW; + if (newW + newX > maxW) { + newW = maxW - newX; + } + newRect = { + x: newX, + y: ny, + w: newW, + h: nh + }; + } else if (nw > fixW) { + const fixH = Math.round(nw * 1.333); + let newY = ny + Math.round(nh / 2 - 0.5 * fixH); + if (newY < 0) { + newY = 0; + } + let newH = fixH; + if (newY + newH > maxH) { + newH = maxH - newY; + } + newRect = { + x: nx, + y: newY, + w: nw, + h: newH + }; + } + } + return newRect; +}; +var getNormalization = (srcRect, maxW, maxH) => { + const newRect = { + ...srcRect + }; + newRect.x = srcRect.x / maxW; + newRect.y = srcRect.y / maxH; + newRect.w = srcRect.w / maxW; + newRect.h = srcRect.h / maxH; + if (newRect.x + newRect.w > 1) { + newRect.w = 1 - newRect.x; + } + if (newRect.y + newRect.h > 1) { + newRect.h = 1 - newRect.y; + } + return newRect; +}; +var getExtendRect = (normalizationRect, imgW, imgH, type) => { + const rect = { + x: normalizationRect.x * imgW, + y: normalizationRect.y * imgH, + w: normalizationRect.w * imgW, + h: normalizationRect.h * imgH + }; + let newRect; + if (type === proto.Common.AlgorithmVersion.VERSION_NON_MOTOR_VEHICLE) { + newRect = getBikeExtendRect(rect, imgW); + } else { + newRect = getOtherExtendRect(rect, imgW, imgH, type); + } + newRect = getNormalization(newRect, imgW, imgH); + return newRect; +}; +var getTransformRect = (image, transform, rect) => { + const canvasRect = { + x: rect.x, + y: rect.y, + x2: rect.x + rect.w, + y2: rect.h + rect.y + }; + const { translateX, translateY, scale, rotate } = transform; + const originAxisRect = { + x: (canvasRect.x - translateX) / scale, + y: (canvasRect.y - translateY) / scale, + x2: (canvasRect.x2 - translateX) / scale, + y2: (canvasRect.y2 - translateY) / scale + }; + let imgAxisRect = originAxisRect; + if (rotate % 180 !== 0) { + const offsetX = -(image.height - image.width) / 2; + const offsetY = -(image.width - image.height) / 2; + imgAxisRect = { + x: originAxisRect.x - offsetX, + y: originAxisRect.y - offsetY, + x2: originAxisRect.x2 - offsetX, + y2: originAxisRect.y2 - offsetY + }; + } + let imgW = image.width; + let imgH = image.height; + if (rotate % 180 !== 0) { + [imgW, imgH] = [imgH, imgW]; + } + imgAxisRect.x = Math.min(imgW, Math.max(imgAxisRect.x, 0)); + imgAxisRect.y = Math.min(imgH, Math.max(imgAxisRect.y, 0)); + imgAxisRect.x2 = Math.min(imgW, Math.max(imgAxisRect.x2, 0)); + imgAxisRect.y2 = Math.min(imgH, Math.max(imgAxisRect.y2, 0)); + const endRect = { + x: imgAxisRect.x2 > imgAxisRect.x ? imgAxisRect.x : imgAxisRect.x2, + y: imgAxisRect.y2 > imgAxisRect.y ? imgAxisRect.y : imgAxisRect.y2, + w: Math.abs(imgAxisRect.x2 - imgAxisRect.x), + h: Math.abs(imgAxisRect.y2 - imgAxisRect.y) + }; + return getNormalization(endRect, imgW, imgH); +}; +var getRotateImg = (image, rotate) => { + var _a; + let imgW = image.width; + let imgH = image.height; + if (rotate % 180 !== 0) { + [imgW, imgH] = [imgH, imgW]; + } + const commonCanvas = document.createElement("canvas"); + commonCanvas.width = imgW; + commonCanvas.height = imgH; + commonCanvas.style.display = "none"; + document.body.appendChild(commonCanvas); + const commonCtx = commonCanvas.getContext("2d"); + commonCtx == null ? void 0 : commonCtx.save(); + if (rotate % 180 !== 0) { + commonCtx == null ? void 0 : commonCtx.translate((image.height - image.width) / 2, (image.width - image.height) / 2); + } + commonCtx == null ? void 0 : commonCtx.translate(image.width / 2, image.height / 2); + commonCtx == null ? void 0 : commonCtx.rotate(rotate / 180 * Math.PI); + commonCtx == null ? void 0 : commonCtx.translate(-image.width / 2, -image.height / 2); + commonCtx == null ? void 0 : commonCtx.drawImage(image, 0, 0); + commonCtx == null ? void 0 : commonCtx.restore(); + const dataUrl = commonCanvas.toDataURL("image/jpeg"); + const blobData = (0, import_file.dataURLToBlob)(dataUrl); + const file = new window.File([blobData], `${(/* @__PURE__ */ new Date()).getTime()}`, { + type: "image/jpeg" + }); + (_a = commonCanvas.parentNode) == null ? void 0 : _a.removeChild(commonCanvas); + return file; +}; +var getOdRect = (originData) => { + let data = (0, import_lodash_es.get)(originData, "objects", []).filter((v) => !(0, import_lodash_es.isNull)((0, import_lodash_es.get)(v, "infoOnSource.bboxInFrame.bboxRatio"))).map((v, index) => { + const rect = (0, import_lodash_es.get)(v, "infoOnSource.bboxInFrame.bboxRatio"); + const extendBox = (0, import_lodash_es.get)(v, "infoOnSource.bboxInFrame.extendBoxRatio"); + const frameTimestamp = (0, import_lodash_es.get)(v, "timestamp"); + const qualityScore = (0, import_lodash_es.get)(v, "qualityScore"); + const algorithmVersion = (0, import_lodash_es.get)(v, "objectType") === "OBJECT_TYPE_PEDESTRAIN" ? "VERSION_REID_HEAD_ATTR" : (0, import_lodash_es.get)(v, "objectType") === "OBJECT_TYPE_FACE" ? "VERSION_FACE" : "VERSION_REID_HEAD_ATTR"; + const featureData = (0, import_lodash_es.get)(v, "feature", []).filter( + (v2) => v2.type === "FEATURE_TYPE_BYTE" + ); + const objectRectIndex = algorithmVersion === "VERSION_FACE" ? 0 : 1; + const objectType = (0, import_lodash_es.get)(v, "objectType"); + const objectId = (0, import_lodash_es.get)(v, "objectIndex.objectId"); + const sourceObjectId = (0, import_lodash_es.get)(v, "sourceObjectId"); + return { + x: rect.x, + y: rect.y, + w: rect.w, + h: rect.h, + // faceCorrectImage: faceCorrectImage, + id: index, + qualityScore, + algorithmVersion, + featureData: (0, import_lodash_es.get)(featureData, "0.featureByte"), + objectRectIndex, + objectType, + objectId, + frameTimestamp, + sourceObjectId, + extendBox + }; + }); + if (data.length > 0) { + data = data.filter((v) => v.objectId !== "0"); + } else { + throw new Error("empty"); + } + return data; +}; +var getOdRectV2 = (originData) => { + const resp = originData.odv2Result[0]; + const subObjects = []; + const data = (0, import_lodash_es.get)(resp, "objects", []).filter((v) => !(0, import_lodash_es.isNull)((0, import_lodash_es.get)(v, "subObjects[0].infoOnSource.bboxInFrame.bboxRatio"))).map((v, index) => { + const rect = (0, import_lodash_es.get)(v, "infoOnSource.bboxInFrame.bboxRatio"); + const qualityScore = (0, import_lodash_es.get)(v, "qualityScore"); + const algorithmVersion = (0, import_lodash_es.get)(v, "objectType"); + const featrueData = (0, import_lodash_es.get)(v, "feature", []).filter( + (v2) => v2.name === "feature-body" || v2.name === "feature-face" + ); + const objectRectIndex = algorithmVersion === "OBJECT_TYPE_FACE" ? 0 : 1; + const objectType = (0, import_lodash_es.get)(v, "objectType"); + const objectId = (0, import_lodash_es.get)(v, "objectIndex.objectId"); + if ((0, import_lodash_es.get)(v, "subObjects", []).length) { + (0, import_lodash_es.get)(v, "subObjects", []).forEach((e) => { + const rect2 = (0, import_lodash_es.get)(e, "infoOnSource.bboxInFrame.bboxRatio"); + const qualityScore2 = (0, import_lodash_es.get)(e, "qualityScore"); + const algorithmVersion2 = (0, import_lodash_es.get)(e, "objectType"); + const featrueData2 = (0, import_lodash_es.get)(e, "feature", []).filter( + (v2) => v2.name === "feature-body" || v2.name === "feature-face" + ); + const objectRectIndex2 = algorithmVersion2 === "OBJECT_TYPE_FACE" ? 0 : 1; + const objectType2 = (0, import_lodash_es.get)(e, "objectType"); + const objectId2 = (0, import_lodash_es.get)(e, "objectIndex.objectId"); + subObjects.push({ + x: rect2.x, + y: rect2.y, + w: rect2.w, + h: rect2.h, + id: index, + qualityScore: qualityScore2, + algorithmVersion: algorithmVersion2, + featrueData: featrueData2.length ? featrueData2[0].featureByte : "", + objectRectIndex: objectRectIndex2, + objectType: objectType2, + objectId: objectId2 + }); + }); + } + return { + x: rect.x, + y: rect.y, + w: rect.w, + h: rect.h, + id: index, + qualityScore, + algorithmVersion, + featrueData: featrueData[0].featureByte, + objectRectIndex, + objectType, + objectId + }; + }); + const brr = data.concat(subObjects).map((v, vs) => { + if (String(v.id)) { + v.id = vs; + } + return v; + }); + if (brr.length > 0) { + console.log(brr, "data111"); + } else { + throw new Error("empty"); + } + console.log(brr); + return brr; +}; +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + ALGORITHM_VERSION, + algorithmVersions, + getBikeExtendRect, + getExtendRect, + getNormalization, + getOdRect, + getOdRectV2, + getOtherExtendRect, + getRotateImg, + getTransformRect +}); diff --git a/packages/func/lib/number/index.d.ts b/packages/func/lib/number/index.d.ts new file mode 100644 index 0000000..b8e65be --- /dev/null +++ b/packages/func/lib/number/index.d.ts @@ -0,0 +1,14 @@ +/** + * 设置数据的精度 + * @param originNumber + * @param accuracy 精度 以原点为中心向左为正,向右为负, + * @param isCeil 是否为向上取整 + * @returns number + */ +export declare const setNumberAccuracy: (originNumber: number, accuracy?: number, isCeil?: boolean) => number; +/** + * 获取数字 + * @param number 需要校验的数值 + * @returns @number + */ +export declare const toRealNumber: (number: any) => any; diff --git a/packages/func/lib/number/index.js b/packages/func/lib/number/index.js new file mode 100644 index 0000000..371a003 --- /dev/null +++ b/packages/func/lib/number/index.js @@ -0,0 +1,53 @@ +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// src/number/index.ts +var number_exports = {}; +__export(number_exports, { + setNumberAccuracy: () => setNumberAccuracy, + toRealNumber: () => toRealNumber +}); +module.exports = __toCommonJS(number_exports); +var setNumberAccuracy = (originNumber, accuracy = 0, isCeil = true) => { + if (originNumber === 0) { + return 0; + } + let returnData = 0; + if (isCeil) { + returnData = Math.ceil(originNumber / Math.pow(10, accuracy)) * Math.pow(10, accuracy); + } else { + returnData = Math.floor(originNumber / Math.pow(10, accuracy)) * Math.pow(10, accuracy); + } + if (accuracy < 0) { + returnData = Number(returnData.toFixed(-accuracy)); + } else { + returnData = Number(returnData.toFixed(0)); + } + return returnData; +}; +var toRealNumber = (number) => { + if (isNaN(number) || number === Infinity) { + return 0; + } else + return number; +}; +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + setNumberAccuracy, + toRealNumber +}); diff --git a/packages/func/lib/performance/index.d.ts b/packages/func/lib/performance/index.d.ts new file mode 100644 index 0000000..22dd838 --- /dev/null +++ b/packages/func/lib/performance/index.d.ts @@ -0,0 +1 @@ +export declare const speedConvert: (bps: number, contertUnit?: number) => string; diff --git a/packages/func/lib/performance/index.js b/packages/func/lib/performance/index.js new file mode 100644 index 0000000..1d12f21 --- /dev/null +++ b/packages/func/lib/performance/index.js @@ -0,0 +1,41 @@ +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// src/performance/index.ts +var performance_exports = {}; +__export(performance_exports, { + speedConvert: () => speedConvert +}); +module.exports = __toCommonJS(performance_exports); +var speedConvert = (bps, contertUnit = 8) => { + if (bps === void 0) + return `0KB/s`; + const byte = bps / contertUnit; + if (bps > 1024 * 1024 * 1024) { + return `${(byte / 1024 / 1024 / 1024).toFixed(2)}GB/s`; + } else if (byte > 1024 * 1024) { + return `${(byte / 1024 / 1024).toFixed(2)}MB/s`; + } else if (byte > 1024) { + return `${(byte / 1024).toFixed(2)}KB/s`; + } + return `${byte}KB/s`; +}; +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + speedConvert +}); diff --git a/packages/func/lib/string/index.d.ts b/packages/func/lib/string/index.d.ts new file mode 100644 index 0000000..a209796 --- /dev/null +++ b/packages/func/lib/string/index.d.ts @@ -0,0 +1,7 @@ +export declare const getStrLength: (str: string) => number; +/** + * js截取字符串,中英文都能用 + * @param str:需要截取的字符串 + * @param len: 需要截取的长度 + */ +export declare const cutStr: (str: string, len: number) => string | String | undefined; diff --git a/packages/func/lib/string/index.js b/packages/func/lib/string/index.js new file mode 100644 index 0000000..4297b5a --- /dev/null +++ b/packages/func/lib/string/index.js @@ -0,0 +1,62 @@ +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// src/string/index.ts +var string_exports = {}; +__export(string_exports, { + cutStr: () => cutStr, + getStrLength: () => getStrLength +}); +module.exports = __toCommonJS(string_exports); +var getStrLength = function(str) { + var realLength = 0, len = str.length, charCode = -1; + for (var i = 0; i < len; i++) { + charCode = str.charCodeAt(i); + if (charCode >= 0 && charCode <= 128) + realLength += 1; + else + realLength += 2; + } + return realLength; +}; +var cutStr = function cutstr(str, len) { + var str_length = 0; + var str_len = 0; + let str_cut = new String(); + str_len = str.length; + for (var i = 0; i < str_len; i++) { + let a = str.charAt(i); + str_length++; + if (escape(a).length > 4) { + str_length++; + } + str_cut = str_cut.concat(a); + if (str_length >= len) { + str_cut = str_cut.concat("..."); + return str_cut; + } + } + if (str_length < len) { + return str; + } +}; +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + cutStr, + getStrLength +}); diff --git a/packages/func/lib/time/index.d.ts b/packages/func/lib/time/index.d.ts new file mode 100644 index 0000000..28b4d03 --- /dev/null +++ b/packages/func/lib/time/index.d.ts @@ -0,0 +1,11 @@ +export declare const formateDuration: (diff: number) => string; +export declare function generateTime(): { + startDateTime: number; + endDateTime: number; +}; +/** + * 格式化时间为 00:00 + * @param seconds 时间,单位秒 + * @returns + */ +export declare function formatDurationTime(seconds: number): string; diff --git a/packages/func/lib/time/index.js b/packages/func/lib/time/index.js new file mode 100644 index 0000000..cf77388 --- /dev/null +++ b/packages/func/lib/time/index.js @@ -0,0 +1,73 @@ +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// src/time/index.ts +var time_exports = {}; +__export(time_exports, { + formatDurationTime: () => formatDurationTime, + formateDuration: () => formateDuration, + generateTime: () => generateTime +}); +module.exports = __toCommonJS(time_exports); +var import_dayjs = __toESM(require("dayjs")); +var formateDuration = (diff) => { + var days = Math.floor(diff / (24 * 3600 * 1e3)); + var leave1 = diff % (24 * 3600 * 1e3); + var hours = Math.floor(leave1 / (3600 * 1e3)); + var leave2 = leave1 % (3600 * 1e3); + var minutes = Math.floor(leave2 / (60 * 1e3)); + var leave3 = leave2 % (60 * 1e3); + var seconds = Math.round(leave3 / 1e3); + var returnStr = seconds + "秒"; + if (minutes > 0) { + returnStr = minutes + "分"; + } + if (hours > 0) { + returnStr = hours + "小时"; + } + if (days > 0) { + returnStr = days + "天"; + } + return returnStr; +}; +function generateTime() { + let endDateTime = (0, import_dayjs.default)().endOf("day").unix(); + let startDateTime = (0, import_dayjs.default)().startOf("day").unix(); + return { startDateTime, endDateTime }; +} +function formatDurationTime(seconds) { + var minutes = Math.floor(seconds / 60) || 0; + var remainingSeconds = Math.floor(seconds % 60); + return (minutes < 10 ? `0${minutes}` : minutes) + ":" + (remainingSeconds < 10 ? "0" : "") + remainingSeconds; +} +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + formatDurationTime, + formateDuration, + generateTime +}); diff --git a/packages/func/lib/upload/index.d.ts b/packages/func/lib/upload/index.d.ts new file mode 100644 index 0000000..8c370db --- /dev/null +++ b/packages/func/lib/upload/index.d.ts @@ -0,0 +1,8 @@ +type uploadOption = { + bucket?: string; + dir?: string; + withSuFuffix?: boolean; +}; +export declare const commonUpload: (file: File, option: uploadOption | undefined, type: string) => Promise; +export declare const upload: (file: File, option?: uploadOption) => Promise; +export {}; diff --git a/packages/func/lib/upload/index.js b/packages/func/lib/upload/index.js new file mode 100644 index 0000000..0c549fb --- /dev/null +++ b/packages/func/lib/upload/index.js @@ -0,0 +1,90 @@ +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// src/upload/index.ts +var upload_exports = {}; +__export(upload_exports, { + commonUpload: () => commonUpload, + upload: () => upload +}); +module.exports = __toCommonJS(upload_exports); +var import_dayjs = __toESM(require("dayjs")); +var import_utils = require("../utils"); +var import_base_64 = __toESM(require("base-64")); +var import_uuid = require("uuid"); +var import_lodash_es = require("lodash-es"); +var import_request = __toESM(require("@zhst/request")); +var defaultBucket = "public"; +var commonUpload = async (file, option = {}, type) => { + const { bucket = defaultBucket, dir = "file", withSuFuffix = false } = option; + const prefix = `${(0, import_dayjs.default)().format("YYYYMMDD")}`; + const fileSuffix = withSuFuffix ? (0, import_utils.getFileSuffix)((0, import_lodash_es.get)(file, "name")) : ""; + const fileType = file["type"].split("/", 2); + let imageSuffix = ""; + if (fileType["0"] === "image") { + imageSuffix = (0, import_utils.getImageSuffixByFileType)(fileType["1"]); + } + const key = `${prefix}/${dir ? `${dir}/` : ""}${(0, import_uuid.v4)()}${!fileSuffix ? "" : `.${fileSuffix}`}`; + let imgKey = `${bucket}_${bucket}_${key}${imageSuffix}`; + if (type === "upload") { + imgKey = `v1_${import_base_64.default.encode(imgKey)}`; + return new Promise((resolve) => { + const reader = new FileReader(); + reader.readAsDataURL(file); + reader.onload = async () => { + var _a; + if (reader.result) { + await (0, import_request.default)({ + method: "PUT", + url: "/singer.FileServerService/PutObject", + data: { + version: 1, + bucket: defaultBucket, + objectName: `${bucket}_${key}${imageSuffix}`, + // fileData: reader.result, + putObjectOption: { + contentType: file.type + }, + // @ts-ignore + fileDataBase64: (_a = reader.result) == null ? void 0 : _a.split(";base64,")[1] + } + }); + resolve(imgKey); + } + }; + }); + } +}; +var upload = async (file, option = {}) => { + return await commonUpload(file, option, "upload"); +}; +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + commonUpload, + upload +}); diff --git a/packages/func/lib/utils/index.d.ts b/packages/func/lib/utils/index.d.ts new file mode 100644 index 0000000..4a5e574 --- /dev/null +++ b/packages/func/lib/utils/index.d.ts @@ -0,0 +1,36 @@ +export { default as isChrome } from './isChrome'; +export declare const matchS3Prefix: (str: string) => boolean; +/** + * 通过文件名获取文件类型 + * @param fileName 文件名称 + * @returns 文件类型 + */ +export declare const getFileSuffix: (fileName: string) => string; +/** + * 通过类型获取文件名 + * @param type 类型 + * @returns + */ +export declare const getImageSuffixByFileType: (type: string) => string; +export declare function getChromeVersion(): number | false; +export declare const nextTick: (func: (value: void) => void | PromiseLike) => void; +export declare const loop: (items: string | any[], callback: (arg0: any) => any) => void; +export declare const addEventListenerWrapper: (target: any, eventType: string, cb: any, option?: any) => { + remove: () => void; +}; +/** + * Get transforms base on the given object. + * @param {Object} obj - The target object. + * @returns {string} A string contains transform values. + */ +export declare function getTransforms({ rotate, scaleX, scaleY, translateX, translateY, }: { + rotate?: number; + scaleX?: number; + scaleY?: number; + translateX?: number; + translateY?: number; +}): { + WebkitTransform: string; + msTransform: string; + transform: string; +}; diff --git a/packages/func/lib/utils/index.js b/packages/func/lib/utils/index.js new file mode 100644 index 0000000..78022ad --- /dev/null +++ b/packages/func/lib/utils/index.js @@ -0,0 +1,171 @@ +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// src/utils/index.ts +var utils_exports = {}; +__export(utils_exports, { + addEventListenerWrapper: () => addEventListenerWrapper, + getChromeVersion: () => getChromeVersion, + getFileSuffix: () => getFileSuffix, + getImageSuffixByFileType: () => getImageSuffixByFileType, + getTransforms: () => getTransforms, + isChrome: () => import_isChrome.default, + loop: () => loop, + matchS3Prefix: () => matchS3Prefix, + nextTick: () => nextTick +}); +module.exports = __toCommonJS(utils_exports); +var import_lodash_es = require("lodash-es"); +var import_react_dom = __toESM(require("react-dom")); +var import_isChrome = __toESM(require("./isChrome")); +var matchS3Prefix = (str) => { + return /^v[0-9]_/.test(str); +}; +var getFileSuffix = (fileName) => { + const splitArr = fileName.split("."); + return splitArr.length < 2 ? "" : splitArr[splitArr.length - 1]; +}; +var getImageSuffixByFileType = (type) => { + let imageSuffix = ""; + switch (type) { + case "jpeg": { + imageSuffix = ".jpg"; + break; + } + case "gif": { + imageSuffix = ".gif"; + break; + } + case "png": { + imageSuffix = ".png"; + break; + } + case "vnd.wap.wbmp": { + imageSuffix = ".wbmp"; + break; + } + case "x-up-wpng": { + imageSuffix = ".wpng"; + break; + } + case "nbmp": { + imageSuffix = ".nbmp"; + break; + } + } + return imageSuffix; +}; +function getChromeVersion() { + const arr = navigator.userAgent.split(" "); + let chromeVersion = ""; + for (let i = 0; i < arr.length; i++) { + if (/chrome/i.test(arr[i])) + chromeVersion = arr[i]; + } + if (chromeVersion) { + return Number(chromeVersion.split("/")[1].split(".")[0]); + } else { + return false; + } +} +var nextTick = (func) => { + if (queueMicrotask) { + queueMicrotask(func); + return; + } + Promise.resolve().then(func); +}; +var loop = (items, callback) => { + for (let i = 0; i < items.length; i++) { + const element = items[i]; + let isBreak = callback(element); + if (isBreak) { + return; + } + if (element["children"]) { + loop(element["children"], callback); + } + } +}; +var addEventListenerWrapper = (target, eventType, cb, option) => { + const callback = import_react_dom.default.unstable_batchedUpdates ? function run(e) { + import_react_dom.default.unstable_batchedUpdates(cb, e); + } : cb; + if (target.addEventListener) { + target.addEventListener(eventType, callback, option); + } + return { + remove: () => { + if (target.removeEventListener) { + target.removeEventListener(eventType, callback); + } + } + }; +}; +function getTransforms({ + rotate, + scaleX, + scaleY, + translateX, + translateY +}) { + const values = []; + if ((0, import_lodash_es.isNumber)(translateX) && translateX !== 0) { + values.push(`translateX(${translateX}px)`); + } + if ((0, import_lodash_es.isNumber)(translateY) && translateY !== 0) { + values.push(`translateY(${translateY}px)`); + } + if ((0, import_lodash_es.isNumber)(rotate) && rotate !== 0) { + values.push(`rotate(${rotate}deg)`); + } + if ((0, import_lodash_es.isNumber)(scaleX) && scaleX !== 1) { + values.push(`scaleX(${scaleX})`); + } + if ((0, import_lodash_es.isNumber)(scaleY) && scaleY !== 1) { + values.push(`scaleY(${scaleY})`); + } + const transform = values.length ? values.join(" ") : "none"; + return { + WebkitTransform: transform, + msTransform: transform, + transform + }; +} +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + addEventListenerWrapper, + getChromeVersion, + getFileSuffix, + getImageSuffixByFileType, + getTransforms, + isChrome, + loop, + matchS3Prefix, + nextTick +}); diff --git a/packages/func/lib/utils/isChrome.d.ts b/packages/func/lib/utils/isChrome.d.ts new file mode 100644 index 0000000..2d07ceb --- /dev/null +++ b/packages/func/lib/utils/isChrome.d.ts @@ -0,0 +1,3 @@ +export declare const isBrowser: boolean; +declare const isChrome: () => boolean; +export default isChrome; diff --git a/packages/func/lib/utils/isChrome.js b/packages/func/lib/utils/isChrome.js new file mode 100644 index 0000000..4ad2681 --- /dev/null +++ b/packages/func/lib/utils/isChrome.js @@ -0,0 +1,42 @@ +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// src/utils/isChrome.ts +var isChrome_exports = {}; +__export(isChrome_exports, { + default: () => isChrome_default, + isBrowser: () => isBrowser +}); +module.exports = __toCommonJS(isChrome_exports); +var isBrowser = !!(typeof window !== "undefined" && window.document && window.document.createElement); +var isChrome = () => { + const winNav = isBrowser && window.navigator; + const vendorName = winNav && (winNav == null ? void 0 : winNav.vendor); + const userAgent = winNav && winNav.userAgent; + const isChromium = isBrowser && typeof chrome !== "undefined"; + const isOpera = isBrowser && typeof opr !== "undefined"; + const isIEedge = userAgent && userAgent.indexOf("Edge") > -1; + const isIOSChrome = !!(userAgent && userAgent.match("CriOS")); + const isDesktopChrome = isChromium && vendorName === "Google Inc." && !isOpera && !isIEedge; + return isIOSChrome || isDesktopChrome; +}; +var isChrome_default = isChrome; +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + isBrowser +}); diff --git a/packages/func/package.json b/packages/func/package.json index 83e18e6..248ca30 100644 --- a/packages/func/package.json +++ b/packages/func/package.json @@ -1,6 +1,6 @@ { "name": "@zhst/func", - "version": "0.2.4", + "version": "0.3.0", "description": "函数合集", "keywords": [ "hooks" diff --git a/packages/func/src/file/index.ts b/packages/func/src/file/index.ts index 20b93ec..ea7fbd4 100644 --- a/packages/func/src/file/index.ts +++ b/packages/func/src/file/index.ts @@ -275,9 +275,13 @@ export const generateImg: (imgKey: string, host?: string) => string = (_imgKey, //判空 if (!imgKey) return '' - if (/^(http:|https:)/.test(imgKey)) { + + if (/(http|https):\/\/([\w.]+\/?)\S*/ig.test(imgKey)) { return imgKey; } + + console.log('imgKey', imgKey) + try { if (matchS3Prefix(imgKey)) { imgKey = base64DecodeImageKey(imgKey); diff --git a/packages/func/src/math/index.ts b/packages/func/src/math/index.ts index fb4d317..9b80d2f 100644 --- a/packages/func/src/math/index.ts +++ b/packages/func/src/math/index.ts @@ -40,7 +40,7 @@ export const getBikeExtendRect = (rect: Rect, maxW: number) => { return newRect; }; -export const getOtherExtendRect = (srcRect, maxW, maxH, type) => { +export const getOtherExtendRect = (srcRect: Rect, maxW: number, maxH: number, type: string) => { const wExtendRadio = 0.25; const upExtendRadio = 0.25; const downExtendRadio = 0.25; @@ -296,24 +296,23 @@ export const getOdRect = (originData: IOdRectOrigin) => { //档案库od export const getOdRectV2 = (originData: { odv2Result: any[]; }) => { - // const fileKey = 'v1_' + window.btoa('public_' + imgKey.split('public/')[1]); const resp = originData.odv2Result[0]; const subObjects: { x: any; y: any; w: any; h: any; id: any; qualityScore: any; algorithmVersion: any; featrueData: any; objectRectIndex: number; objectType: any; objectId: any; }[] = []; //形体 const data = get(resp, 'objects', []) - .filter((v) => !isNull(get(v, 'subObjects[0].infoOnSource.bboxInFrame.bboxRatio'))) - .map((v, index) => { + .filter((v: any) => !isNull(get(v, 'subObjects[0].infoOnSource.bboxInFrame.bboxRatio'))) + .map((v: any, index: any) => { const rect = get(v, 'infoOnSource.bboxInFrame.bboxRatio'); const qualityScore = get(v, 'qualityScore'); const algorithmVersion = get(v, 'objectType'); const featrueData = get(v, 'feature', []).filter( - (v) => v.name === 'feature-body' || v.name === 'feature-face' + (v: { name: string; }) => v.name === 'feature-body' || v.name === 'feature-face' ); const objectRectIndex = algorithmVersion === 'OBJECT_TYPE_FACE' ? 0 : 1; const objectType = get(v, 'objectType'); const objectId = get(v, 'objectIndex.objectId'); //如果存在subObjects的数组不为null表示形体里面带人脸,人脸的od框也要显示出来 if (get(v, 'subObjects', []).length) { - get(v, 'subObjects', []).forEach((e) => { + get(v, 'subObjects', []).forEach((e: any) => { const rect = get(e, 'infoOnSource.bboxInFrame.bboxRatio'); const qualityScore = get(e, 'qualityScore'); const algorithmVersion = get(e, 'objectType'); @@ -366,83 +365,3 @@ export const getOdRectV2 = (originData: { odv2Result: any[]; }) => { console.log(brr); return brr; }; - -//获取图片 - -export const getFileByRect = async (img: any, odRect: Rect) => { - let image; - if (isString(img)) { - const url = generateImg(img); - console.log(url, '获取图片'); - image = await urlToImg(url); - console.log(image, '获取的图片'); - } else { - image = img; - } - const commonCanvas = document.createElement('canvas'); - commonCanvas.width = odRect.w * image.width; - commonCanvas.height = odRect.h * image.height; - commonCanvas.style.display = 'none'; - document.body.appendChild(commonCanvas); - const commonCtx = commonCanvas.getContext('2d'); - commonCtx?.translate(-odRect.x * image.width, -odRect.y * image.height); - commonCtx?.drawImage(image, 0, 0); - const base64 = commonCanvas.toDataURL('image/jpeg'); - const blobData = dataURLToBlob(base64); - commonCanvas?.parentNode?.removeChild(commonCanvas); - const file = new window.File([blobData], `${new Date().getTime()}`, { - type: 'image/jpeg', - }); - return file; -}; - - -/** - * Get transforms base on the given object. - * @param {Object} obj - The target object. - * @returns {string} A string contains transform values. - */ -export function getTransforms({ - rotate, - scaleX, - scaleY, - translateX, - translateY, -}: { - rotate?: number; - scaleX?: number; - scaleY?: number; - translateX?: number; - translateY?: number; -}) { - const values = []; - - if (isNumber(translateX) && translateX !== 0) { - values.push(`translateX(${translateX}px)`); - } - - if (isNumber(translateY) && translateY !== 0) { - values.push(`translateY(${translateY}px)`); - } - - // Rotate should come first before scale to match orientation transform - if (isNumber(rotate) && rotate !== 0) { - values.push(`rotate(${rotate}deg)`); - } - - if (isNumber(scaleX) && scaleX !== 1) { - values.push(`scaleX(${scaleX})`); - } - - if (isNumber(scaleY) && scaleY !== 1) { - values.push(`scaleY(${scaleY})`); - } - - const transform = values.length ? values.join(' ') : 'none'; - - return { - WebkitTransform: transform, - msTransform: transform, - transform, - }; -} diff --git a/packages/func/src/upload/index.ts b/packages/func/src/upload/index.ts index 1224ba3..5d4b5ff 100644 --- a/packages/func/src/upload/index.ts +++ b/packages/func/src/upload/index.ts @@ -43,6 +43,7 @@ export const commonUpload = async (file: File, option: uploadOption = {}, type: putObjectOption: { contentType: file.type, }, + // @ts-ignore fileDataBase64: reader.result?.split(';base64,')[1], }, }); diff --git a/packages/func/src/utils/isChrome.ts b/packages/func/src/utils/isChrome.ts index e03a2f3..160b30c 100644 --- a/packages/func/src/utils/isChrome.ts +++ b/packages/func/src/utils/isChrome.ts @@ -1,8 +1,12 @@ -export const isBrowser = !!(typeof window !== 'undefined' && window); +export const isBrowser = !!( + typeof window !== 'undefined' && + window.document && + window.document.createElement +); const isChrome = () =>{ const winNav = isBrowser && window.navigator; - const vendorName = winNav && winNav.vendor; + const vendorName = winNav && winNav?.vendor; const userAgent = winNav && winNav.userAgent; //@ts-ignore diff --git a/packages/hooks/CHANGELOG.md b/packages/hooks/CHANGELOG.md index 299ee29..0b60bc9 100644 --- a/packages/hooks/CHANGELOG.md +++ b/packages/hooks/CHANGELOG.md @@ -1,5 +1,16 @@ # @zhst/hooks +## 0.3.0 + +### Minor Changes + +- feat: 初始化项目包 + +### Patch Changes + +- Updated dependencies + - @zhst/func@0.3.0 + ## 0.2.4 ### Patch Changes diff --git a/packages/hooks/package.json b/packages/hooks/package.json index 1c0dba5..b872541 100644 --- a/packages/hooks/package.json +++ b/packages/hooks/package.json @@ -1,6 +1,6 @@ { "name": "@zhst/hooks", - "version": "0.2.4", + "version": "0.3.0", "description": "hooks合集", "keywords": [ "hooks" diff --git a/packages/material/CHANGELOG.md b/packages/material/CHANGELOG.md index 444b4f0..ee89e63 100644 --- a/packages/material/CHANGELOG.md +++ b/packages/material/CHANGELOG.md @@ -1,5 +1,19 @@ # @zhst/biz +## 0.3.0 + +### Minor Changes + +- feat: 初始化项目包 + +### Patch Changes + +- Updated dependencies + - @zhst/hooks@0.3.0 + - @zhst/func@0.3.0 + - @zhst/meta@0.3.0 + - @zhst/biz@0.3.0 + ## 0.2.4 ### Patch Changes diff --git a/packages/material/README.md b/packages/material/README.md index 23ba41e..96d7ea4 100644 --- a/packages/material/README.md +++ b/packages/material/README.md @@ -1,16 +1,20 @@ +:::warning{title=待开始} +目前项目正在如火如荼的筹备中... +::: + ## 介绍 -业务库 +物料库,每一个物料都是单独存在的个体,不需要任何依赖,就能形成一个页面,甚至一个项目 ## 安装 -> pnpm install @zhst/biz +> pnpm install @zhst/material ## 使用 ```jsx import React from 'react'; -import { Demo } from '@zhst/biz' +import { Demo } from '@zhst/material' export default () => ``` diff --git a/packages/material/es/Demo/index.d.ts b/packages/material/es/Demo/index.d.ts new file mode 100644 index 0000000..bcc157c --- /dev/null +++ b/packages/material/es/Demo/index.d.ts @@ -0,0 +1,3 @@ +import React from 'react'; +declare const _default: () => React.JSX.Element; +export default _default; diff --git a/packages/material/es/Demo/index.js b/packages/material/es/Demo/index.js new file mode 100644 index 0000000..9c21809 --- /dev/null +++ b/packages/material/es/Demo/index.js @@ -0,0 +1,4 @@ +import React from 'react'; +export default (function () { + return /*#__PURE__*/React.createElement("div", null, "hi"); +}); \ No newline at end of file diff --git a/packages/material/es/index.d.ts b/packages/material/es/index.d.ts new file mode 100644 index 0000000..31f4c03 --- /dev/null +++ b/packages/material/es/index.d.ts @@ -0,0 +1 @@ +export { default as Demo } from './Demo'; diff --git a/packages/material/es/index.js b/packages/material/es/index.js new file mode 100644 index 0000000..dd020e4 --- /dev/null +++ b/packages/material/es/index.js @@ -0,0 +1 @@ +export { default as Demo } from "./Demo"; \ No newline at end of file diff --git a/packages/material/lib/Demo/index.d.ts b/packages/material/lib/Demo/index.d.ts new file mode 100644 index 0000000..bcc157c --- /dev/null +++ b/packages/material/lib/Demo/index.d.ts @@ -0,0 +1,3 @@ +import React from 'react'; +declare const _default: () => React.JSX.Element; +export default _default; diff --git a/packages/material/lib/Demo/index.js b/packages/material/lib/Demo/index.js new file mode 100644 index 0000000..09e6968 --- /dev/null +++ b/packages/material/lib/Demo/index.js @@ -0,0 +1,38 @@ +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// src/Demo/index.tsx +var Demo_exports = {}; +__export(Demo_exports, { + default: () => Demo_default +}); +module.exports = __toCommonJS(Demo_exports); +var import_react = __toESM(require("react")); +var Demo_default = () => { + return /* @__PURE__ */ import_react.default.createElement("div", null, "hi"); +}; diff --git a/packages/material/lib/index.d.ts b/packages/material/lib/index.d.ts new file mode 100644 index 0000000..31f4c03 --- /dev/null +++ b/packages/material/lib/index.d.ts @@ -0,0 +1 @@ +export { default as Demo } from './Demo'; diff --git a/packages/material/lib/index.js b/packages/material/lib/index.js new file mode 100644 index 0000000..7462083 --- /dev/null +++ b/packages/material/lib/index.js @@ -0,0 +1,39 @@ +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// src/index.tsx +var src_exports = {}; +__export(src_exports, { + Demo: () => import_Demo.default +}); +module.exports = __toCommonJS(src_exports); +var import_Demo = __toESM(require("./Demo")); +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + Demo +}); diff --git a/packages/material/package.json b/packages/material/package.json index 93f39cf..b6785eb 100644 --- a/packages/material/package.json +++ b/packages/material/package.json @@ -1,6 +1,6 @@ { "name": "@zhst/material", - "version": "0.2.4", + "version": "0.3.0", "description": "物料库", "keywords": [ "business", diff --git a/packages/material/src/Demo/index.tsx b/packages/material/src/Demo/index.tsx index 7545062..614fa16 100644 --- a/packages/material/src/Demo/index.tsx +++ b/packages/material/src/Demo/index.tsx @@ -1,12 +1,8 @@ import React from 'react' -import { Button } from '@zhst/meta' -import { useThrottleFn } from '@zhst/hooks' export default () => { - const { run } = useThrottleFn(() => console.log('123')) - return ( - +
    hi
    ) } diff --git a/packages/meta/CHANGELOG.md b/packages/meta/CHANGELOG.md index 19b1dcf..8d08acb 100644 --- a/packages/meta/CHANGELOG.md +++ b/packages/meta/CHANGELOG.md @@ -1,5 +1,17 @@ # @zhst/utils +## 0.3.0 + +### Minor Changes + +- feat: 初始化项目包 + +### Patch Changes + +- Updated dependencies + - @zhst/hooks@0.3.0 + - @zhst/func@0.3.0 + ## 0.2.4 ### Patch Changes diff --git a/packages/meta/es/BigImagePreview/BigImagePreview.d.ts b/packages/meta/es/BigImagePreview/BigImagePreview.d.ts new file mode 100644 index 0000000..45d7836 --- /dev/null +++ b/packages/meta/es/BigImagePreview/BigImagePreview.d.ts @@ -0,0 +1,35 @@ +import React, { ReactElement } from 'react'; +import { type Rect, type IScreenshotButtonProp, type AlignType, type ViewOption, type IOdRectOrigin } from '@zhst/types'; +import './index.less'; +export interface ImgViewProps extends React.HTMLAttributes { + dataSource: Array<{ + url?: string; + imageKey: string; + attachImg?: Array<{ + label: string; + url: string; + }>; + odRect?: Rect; + score?: number; + showScore?: boolean; + cameraPosition?: string; + time?: string | number; + objects: any[]; + }>; + showAttachImgLabel: boolean; + showOpt: boolean; + width?: string | number; + height?: string | number; + screenshotButtonAlign: AlignType; + screenshotButtonRender: (screenshotButtonProp: IScreenshotButtonProp) => ReactElement; + hideLeftTopBtn?: boolean; + showScore?: boolean; + viewOption?: ViewOption; + objects: IOdRectOrigin[]; +} +export interface ImgViewRef { + imgInsRef: React.MutableRefObject; + setShowCrop: React.Dispatch>; +} +export declare const BigImagePreview: React.ForwardRefExoticComponent>; +export default BigImagePreview; diff --git a/packages/meta/es/BigImagePreview/BigImagePreview.js b/packages/meta/es/BigImagePreview/BigImagePreview.js new file mode 100644 index 0000000..31fffcb --- /dev/null +++ b/packages/meta/es/BigImagePreview/BigImagePreview.js @@ -0,0 +1,578 @@ +function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } +function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return e; }; var t, e = {}, r = Object.prototype, n = r.hasOwnProperty, o = Object.defineProperty || function (t, e, r) { t[e] = r.value; }, i = "function" == typeof Symbol ? Symbol : {}, a = i.iterator || "@@iterator", c = i.asyncIterator || "@@asyncIterator", u = i.toStringTag || "@@toStringTag"; function define(t, e, r) { return Object.defineProperty(t, e, { value: r, enumerable: !0, configurable: !0, writable: !0 }), t[e]; } try { define({}, ""); } catch (t) { define = function define(t, e, r) { return t[e] = r; }; } function wrap(t, e, r, n) { var i = e && e.prototype instanceof Generator ? e : Generator, a = Object.create(i.prototype), c = new Context(n || []); return o(a, "_invoke", { value: makeInvokeMethod(t, r, c) }), a; } function tryCatch(t, e, r) { try { return { type: "normal", arg: t.call(e, r) }; } catch (t) { return { type: "throw", arg: t }; } } e.wrap = wrap; var h = "suspendedStart", l = "suspendedYield", f = "executing", s = "completed", y = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var p = {}; define(p, a, function () { return this; }); var d = Object.getPrototypeOf, v = d && d(d(values([]))); v && v !== r && n.call(v, a) && (p = v); var g = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(p); function defineIteratorMethods(t) { ["next", "throw", "return"].forEach(function (e) { define(t, e, function (t) { return this._invoke(e, t); }); }); } function AsyncIterator(t, e) { function invoke(r, o, i, a) { var c = tryCatch(t[r], t, o); if ("throw" !== c.type) { var u = c.arg, h = u.value; return h && "object" == _typeof(h) && n.call(h, "__await") ? e.resolve(h.__await).then(function (t) { invoke("next", t, i, a); }, function (t) { invoke("throw", t, i, a); }) : e.resolve(h).then(function (t) { u.value = t, i(u); }, function (t) { return invoke("throw", t, i, a); }); } a(c.arg); } var r; o(this, "_invoke", { value: function value(t, n) { function callInvokeWithMethodAndArg() { return new e(function (e, r) { invoke(t, n, e, r); }); } return r = r ? r.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); } }); } function makeInvokeMethod(e, r, n) { var o = h; return function (i, a) { if (o === f) throw new Error("Generator is already running"); if (o === s) { if ("throw" === i) throw a; return { value: t, done: !0 }; } for (n.method = i, n.arg = a;;) { var c = n.delegate; if (c) { var u = maybeInvokeDelegate(c, n); if (u) { if (u === y) continue; return u; } } if ("next" === n.method) n.sent = n._sent = n.arg;else if ("throw" === n.method) { if (o === h) throw o = s, n.arg; n.dispatchException(n.arg); } else "return" === n.method && n.abrupt("return", n.arg); o = f; var p = tryCatch(e, r, n); if ("normal" === p.type) { if (o = n.done ? s : l, p.arg === y) continue; return { value: p.arg, done: n.done }; } "throw" === p.type && (o = s, n.method = "throw", n.arg = p.arg); } }; } function maybeInvokeDelegate(e, r) { var n = r.method, o = e.iterator[n]; if (o === t) return r.delegate = null, "throw" === n && e.iterator.return && (r.method = "return", r.arg = t, maybeInvokeDelegate(e, r), "throw" === r.method) || "return" !== n && (r.method = "throw", r.arg = new TypeError("The iterator does not provide a '" + n + "' method")), y; var i = tryCatch(o, e.iterator, r.arg); if ("throw" === i.type) return r.method = "throw", r.arg = i.arg, r.delegate = null, y; var a = i.arg; return a ? a.done ? (r[e.resultName] = a.value, r.next = e.nextLoc, "return" !== r.method && (r.method = "next", r.arg = t), r.delegate = null, y) : a : (r.method = "throw", r.arg = new TypeError("iterator result is not an object"), r.delegate = null, y); } function pushTryEntry(t) { var e = { tryLoc: t[0] }; 1 in t && (e.catchLoc = t[1]), 2 in t && (e.finallyLoc = t[2], e.afterLoc = t[3]), this.tryEntries.push(e); } function resetTryEntry(t) { var e = t.completion || {}; e.type = "normal", delete e.arg, t.completion = e; } function Context(t) { this.tryEntries = [{ tryLoc: "root" }], t.forEach(pushTryEntry, this), this.reset(!0); } function values(e) { if (e || "" === e) { var r = e[a]; if (r) return r.call(e); if ("function" == typeof e.next) return e; if (!isNaN(e.length)) { var o = -1, i = function next() { for (; ++o < e.length;) if (n.call(e, o)) return next.value = e[o], next.done = !1, next; return next.value = t, next.done = !0, next; }; return i.next = i; } } throw new TypeError(_typeof(e) + " is not iterable"); } return GeneratorFunction.prototype = GeneratorFunctionPrototype, o(g, "constructor", { value: GeneratorFunctionPrototype, configurable: !0 }), o(GeneratorFunctionPrototype, "constructor", { value: GeneratorFunction, configurable: !0 }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, u, "GeneratorFunction"), e.isGeneratorFunction = function (t) { var e = "function" == typeof t && t.constructor; return !!e && (e === GeneratorFunction || "GeneratorFunction" === (e.displayName || e.name)); }, e.mark = function (t) { return Object.setPrototypeOf ? Object.setPrototypeOf(t, GeneratorFunctionPrototype) : (t.__proto__ = GeneratorFunctionPrototype, define(t, u, "GeneratorFunction")), t.prototype = Object.create(g), t; }, e.awrap = function (t) { return { __await: t }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, c, function () { return this; }), e.AsyncIterator = AsyncIterator, e.async = function (t, r, n, o, i) { void 0 === i && (i = Promise); var a = new AsyncIterator(wrap(t, r, n, o), i); return e.isGeneratorFunction(r) ? a : a.next().then(function (t) { return t.done ? t.value : a.next(); }); }, defineIteratorMethods(g), define(g, u, "Generator"), define(g, a, function () { return this; }), define(g, "toString", function () { return "[object Generator]"; }), e.keys = function (t) { var e = Object(t), r = []; for (var n in e) r.push(n); return r.reverse(), function next() { for (; r.length;) { var t = r.pop(); if (t in e) return next.value = t, next.done = !1, next; } return next.done = !0, next; }; }, e.values = values, Context.prototype = { constructor: Context, reset: function reset(e) { if (this.prev = 0, this.next = 0, this.sent = this._sent = t, this.done = !1, this.delegate = null, this.method = "next", this.arg = t, this.tryEntries.forEach(resetTryEntry), !e) for (var r in this) "t" === r.charAt(0) && n.call(this, r) && !isNaN(+r.slice(1)) && (this[r] = t); }, stop: function stop() { this.done = !0; var t = this.tryEntries[0].completion; if ("throw" === t.type) throw t.arg; return this.rval; }, dispatchException: function dispatchException(e) { if (this.done) throw e; var r = this; function handle(n, o) { return a.type = "throw", a.arg = e, r.next = n, o && (r.method = "next", r.arg = t), !!o; } for (var o = this.tryEntries.length - 1; o >= 0; --o) { var i = this.tryEntries[o], a = i.completion; if ("root" === i.tryLoc) return handle("end"); if (i.tryLoc <= this.prev) { var c = n.call(i, "catchLoc"), u = n.call(i, "finallyLoc"); if (c && u) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } else if (c) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); } else { if (!u) throw new Error("try statement without catch or finally"); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } } } }, abrupt: function abrupt(t, e) { for (var r = this.tryEntries.length - 1; r >= 0; --r) { var o = this.tryEntries[r]; if (o.tryLoc <= this.prev && n.call(o, "finallyLoc") && this.prev < o.finallyLoc) { var i = o; break; } } i && ("break" === t || "continue" === t) && i.tryLoc <= e && e <= i.finallyLoc && (i = null); var a = i ? i.completion : {}; return a.type = t, a.arg = e, i ? (this.method = "next", this.next = i.finallyLoc, y) : this.complete(a); }, complete: function complete(t, e) { if ("throw" === t.type) throw t.arg; return "break" === t.type || "continue" === t.type ? this.next = t.arg : "return" === t.type ? (this.rval = this.arg = t.arg, this.method = "return", this.next = "end") : "normal" === t.type && e && (this.next = e), y; }, finish: function finish(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.finallyLoc === t) return this.complete(r.completion, r.afterLoc), resetTryEntry(r), y; } }, catch: function _catch(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.tryLoc === t) { var n = r.completion; if ("throw" === n.type) { var o = n.arg; resetTryEntry(r); } return o; } } throw new Error("illegal catch attempt"); }, delegateYield: function delegateYield(e, r, n) { return this.delegate = { iterator: values(e), resultName: r, nextLoc: n }, "next" === this.method && (this.arg = t), y; } }, e; } +function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } +function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } +function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } +function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } +function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } +function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); } +function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); } +function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); } +function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } +function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } +function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; } +function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } } +function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } +import React, { useEffect, useState, useCallback, useRef, useImperativeHandle } from 'react'; +import classNames from 'classnames'; +import { useLatest } from '@zhst/hooks'; +import { get, pick, isNull, generateImg, dataURLToBlob, getOdRect, getExtendRect, getTransformRect, getRotateImg, getTransforms, addEventListenerWrapper, upload, getFileByRect } from '@zhst/func'; +import Align from 'rc-align'; +import { Button, Empty } from 'antd'; +import Icon from "../iconfont"; +import { Cropper, Viewer, EVENT_VIEWER_TRANSFORM_CHANGE, EVENT_VIEWER_READY, EVENT_CROP_START, EVENT_CROP_END } from "../ImageEditor"; +import BtnGroup from "./components/BtnGroup"; +import "./index.less"; +import getScreenshotButtonRender from "./components/ScreenhotButtons"; +import { defaultAlignOption, CROP_TYPE } from "../utils/constants"; +var componentName = "zhst-image__img-view"; +var cropBtnDataSource = [{ + key: 'close', + icon: 'icon-danchuangguanbi', + title: '退出' +}, { + key: 'autoCrop', + icon: 'icon-zidong', + title: '智能框选' +}, { + key: 'customCrop', + icon: 'icon-shoudong', + title: '手动框选' +}]; +var operateBtnDataSource = [{ + key: 'zoomOut', + icon: 'icon-fangda', + title: '放大' +}, { + key: 'zoomIn', + icon: 'icon-suoxiao', + title: '缩小' +}, { + key: 'reset', + icon: 'icon-zhongzhi3', + title: '重置图片' +}]; +export var BigImagePreview = /*#__PURE__*/React.forwardRef(function (props, ref) { + var _dataSource$currentIn2, _dataSource$currentIn3; + var _props$dataSource = props.dataSource, + dataSource = _props$dataSource === void 0 ? [] : _props$dataSource, + width = props.width, + height = props.height, + _props$showScore = props.showScore, + showScore = _props$showScore === void 0 ? true : _props$showScore, + _props$objects = props.objects, + objects = _props$objects === void 0 ? [] : _props$objects, + _props$showOpt = props.showOpt, + showOpt = _props$showOpt === void 0 ? false : _props$showOpt, + _props$showAttachImgL = props.showAttachImgLabel, + showAttachImgLabel = _props$showAttachImgL === void 0 ? true : _props$showAttachImgL, + _props$screenshotButt = props.screenshotButtonAlign, + screenshotButtonAlign = _props$screenshotButt === void 0 ? defaultAlignOption : _props$screenshotButt, + _props$screenshotButt2 = props.screenshotButtonRender, + screenshotButtonRender = _props$screenshotButt2 === void 0 ? getScreenshotButtonRender({ + onBigImageActionClick: function onBigImageActionClick() {}, + disableBtn: [] + }) : _props$screenshotButt2, + _props$hideLeftTopBtn = props.hideLeftTopBtn, + hideLeftTopBtn = _props$hideLeftTopBtn === void 0 ? true : _props$hideLeftTopBtn, + _props$viewOption = props.viewOption, + viewOption = _props$viewOption === void 0 ? {} : _props$viewOption; + var imgContainerRef = React.useRef(null); + var _useState = useState(false), + _useState2 = _slicedToArray(_useState, 2), + isReady = _useState2[0], + setIsReady = _useState2[1]; + var _useState3 = useState(0), + _useState4 = _slicedToArray(_useState3, 2), + currentIndex = _useState4[0], + setCurrentIndex = _useState4[1]; + console.log('props', props); + var init = useCallback(function ($container) { + imgContainerRef.current = $container; + setIsReady(true); + }, []); + // ============================= viewer ========================= + var imgInsRef = useRef(null); + var _useState5 = useState(false), + _useState6 = _slicedToArray(_useState5, 2), + isImgReady = _useState6[0], + setIsImgReady = _useState6[1]; + useEffect(function () { + var _dataSource$currentIn; + console.log('123', 123); + if (!isReady || !(imgContainerRef !== null && imgContainerRef !== void 0 && imgContainerRef.current)) return; + var handleReady = addEventListenerWrapper(imgContainerRef.current, EVENT_VIEWER_READY, function () { + setIsImgReady(true); + }); + var handleTransformChange = addEventListenerWrapper(imgContainerRef.current, EVENT_VIEWER_TRANSFORM_CHANGE, function () {}); + imgInsRef.current = new Viewer(imgContainerRef.current, _objectSpread(_objectSpread({}, viewOption), {}, { + fitScaleAsMinScale: true, + image: generateImg((_dataSource$currentIn = dataSource[currentIndex]) === null || _dataSource$currentIn === void 0 ? void 0 : _dataSource$currentIn.imageKey) + })); + return function () { + var _imgInsRef$current, _imgInsRef$current$de; + handleReady === null || handleReady === void 0 || handleReady.remove(); + handleTransformChange === null || handleTransformChange === void 0 || handleTransformChange.remove(); + imgInsRef === null || imgInsRef === void 0 || (_imgInsRef$current = imgInsRef.current) === null || _imgInsRef$current === void 0 || (_imgInsRef$current$de = _imgInsRef$current.destroy) === null || _imgInsRef$current$de === void 0 || _imgInsRef$current$de.call(_imgInsRef$current); + imgInsRef.current = null; + }; + }, [isReady, currentIndex]); + + // ============================= viewer操作按钮 ========================= + var handleOptClick = function handleOptClick(v) { + var _imgInsRef$current2, _imgInsRef$current2$s, _imgInsRef$current3, _imgInsRef$current3$s, _imgInsRef$current4, _imgInsRef$current4$r; + switch (v) { + case 'zoomOut': + imgInsRef === null || imgInsRef === void 0 || (_imgInsRef$current2 = imgInsRef.current) === null || _imgInsRef$current2 === void 0 || (_imgInsRef$current2$s = _imgInsRef$current2.scaleTo) === null || _imgInsRef$current2$s === void 0 || _imgInsRef$current2$s.call(_imgInsRef$current2, 0.1); + break; + case 'zoomIn': + imgInsRef === null || imgInsRef === void 0 || (_imgInsRef$current3 = imgInsRef.current) === null || _imgInsRef$current3 === void 0 || (_imgInsRef$current3$s = _imgInsRef$current3.scaleTo) === null || _imgInsRef$current3$s === void 0 || _imgInsRef$current3$s.call(_imgInsRef$current3, -0.1); + break; + case 'reset': + imgInsRef === null || imgInsRef === void 0 || (_imgInsRef$current4 = imgInsRef.current) === null || _imgInsRef$current4 === void 0 || (_imgInsRef$current4$r = _imgInsRef$current4.reset) === null || _imgInsRef$current4$r === void 0 || _imgInsRef$current4$r.call(_imgInsRef$current4, -0.1); + break; + } + }; + + // ============================= cropper ========================= + // 手动截图相关参数 + var cropInsRef = useRef(null); + var _useState7 = useState(showOpt), + _useState8 = _slicedToArray(_useState7, 2), + showCrop = _useState8[0], + setShowCrop = _useState8[1]; + var _useState9 = useState(CROP_TYPE['AUTO']), + _useState10 = _slicedToArray(_useState9, 2), + cropType = _useState10[0], + setCropType = _useState10[1]; + + // 自动截图相关参数 + var _useState11 = useState([]), + _useState12 = _slicedToArray(_useState11, 2), + odList = _useState12[0], + setOdList = _useState12[1]; + var _useState13 = useState([]), + _useState14 = _slicedToArray(_useState13, 2), + extendOdList = _useState14[0], + setExtendOdList = _useState14[1]; + var _useState15 = useState(null), + _useState16 = _slicedToArray(_useState15, 2), + selectRectId = _useState16[0], + setSelectRectId = _useState16[1]; + + // 定位按钮相关参数 + var alginContainerRef = useRef(null); + var alignRef = useRef(null); + var _useState17 = useState(null), + _useState18 = _slicedToArray(_useState17, 2), + cropRect = _useState18[0], + setCropRect = _useState18[1]; + + // 选中的版本号 + var _useState19 = useState(null), + _useState20 = _slicedToArray(_useState19, 2), + selectAlgorithmVersion = _useState20[0], + setSelectAlgorithmVersion = _useState20[1]; + var handlerCropStartRef = useRef(null); + var handlerCropEndRef = useRef(null); + var handleShapeSelectRef = useRef(null); + useEffect(function () { + initData(dataSource[currentIndex].objects || objects); + return function () { + var _imgInsRef$current5, _imgInsRef$current5$c, _handlerCropStartRef$, _handlerCropEndRef$cu, _handleShapeSelectRef, _cropInsRef$current, _cropInsRef$current$d; + (_imgInsRef$current5 = imgInsRef.current) === null || _imgInsRef$current5 === void 0 || (_imgInsRef$current5$c = _imgInsRef$current5.clearShape) === null || _imgInsRef$current5$c === void 0 || _imgInsRef$current5$c.call(_imgInsRef$current5); + (_handlerCropStartRef$ = handlerCropStartRef.current) === null || _handlerCropStartRef$ === void 0 || _handlerCropStartRef$.remove(); + (_handlerCropEndRef$cu = handlerCropEndRef.current) === null || _handlerCropEndRef$cu === void 0 || _handlerCropEndRef$cu.remove(); + (_handleShapeSelectRef = handleShapeSelectRef.current) === null || _handleShapeSelectRef === void 0 || _handleShapeSelectRef.remove(); + cropInsRef === null || cropInsRef === void 0 || (_cropInsRef$current = cropInsRef.current) === null || _cropInsRef$current === void 0 || (_cropInsRef$current$d = _cropInsRef$current.destroy) === null || _cropInsRef$current$d === void 0 || _cropInsRef$current$d.call(_cropInsRef$current); + cropInsRef.current = null; + }; + }, [isImgReady, showCrop, cropType, currentIndex]); + var initData = function initData(_objects) { + var imgIns = imgInsRef.current; + var _odRect = dataSource[currentIndex].odRect; + //清理crop + setCropRect(null); + if (!isImgReady) return; + if (!showCrop) { + var _imgIns$addShape; + imgIns === null || imgIns === void 0 || (_imgIns$addShape = imgIns.addShape) === null || _imgIns$addShape === void 0 || _imgIns$addShape.call(imgIns, { + x: get(_odRect, 'x', 0), + y: get(_odRect, 'y', 0), + w: get(_odRect, 'w', 0), + h: get(_odRect, 'h', 0), + selectAble: false + }); + return; + } + + // 自动模式 + if (cropType === CROP_TYPE['AUTO']) { + var handleGetOD = function handleGetOD(odList) { + var imgSize = imgIns.getImgSize(); + var shapeList = odList.map(function (rect) { + return _objectSpread(_objectSpread({}, rect), {}, { + selectAble: true, + id: rect['id'], + algorithmVersion: rect.algorithmVersion + }); + }); + imgIns.replaceShape(shapeList); + //顺便吧扩展框拿到 + var extendRect = shapeList.map(function (rect) { + // @ts-ignore + var _extendRect = getExtendRect(rect, imgSize.w, imgSize.h, rect.algorithmVersion); + return _objectSpread(_objectSpread({}, rect), _extendRect); + }); + setExtendOdList(extendRect); + imgIns.replaceShape(shapeList); + handleShapeSelectRef.current = addEventListenerWrapper(imgContainerRef.current, 'shape-select', function (e) { + var id = e.detail; + setSelectRectId(id); + var selectShape = shapeList.find(function (v) { + return v['id'] === id; + }); + if (selectShape) { + setSelectAlgorithmVersion(selectShape['algorithmVersion']); + //换算成屏幕坐标 + var axisRect = imgIns.imgRectAxisToCanvasAxisRect(selectShape); + var _rect = { + x: axisRect.x2 > axisRect.x ? axisRect.x : axisRect.x2, + y: axisRect.y2 > axisRect.y ? axisRect.y : axisRect.y2, + w: Math.abs(axisRect.x2 - axisRect.x), + h: Math.abs(axisRect.y2 - axisRect.y) + }; + setCropRect(_rect); + } else { + // @ts-ignore + setCropRect(null); + } + }); + }; + // @ts-ignore + var rect = getOdRect({ + objects: _objects + }); + setOdList(rect); + handleGetOD(rect); + } + + // 手动模式 + if (cropType === CROP_TYPE['CUSTOM']) { + var _imgIns$clearShape; + // 手动框选状态预先清除imgIns + imgIns === null || imgIns === void 0 || (_imgIns$clearShape = imgIns.clearShape) === null || _imgIns$clearShape === void 0 || _imgIns$clearShape.call(imgIns); + handlerCropStartRef.current = addEventListenerWrapper(imgContainerRef.current, EVENT_CROP_START, function () { + setSelectAlgorithmVersion(null); + setCropRect(null); + }); + handlerCropEndRef.current = addEventListenerWrapper(imgContainerRef.current, EVENT_CROP_END, function (event) { + var _alignRef$current, _alignRef$current$for; + var data = event.detail; + setSelectAlgorithmVersion(null); + setCropRect({ + x: data.left, + y: data.top, + w: data.width, + h: data.height + }); + alignRef === null || alignRef === void 0 || (_alignRef$current = alignRef.current) === null || _alignRef$current === void 0 || (_alignRef$current$for = _alignRef$current.forceAlign) === null || _alignRef$current$for === void 0 || _alignRef$current$for.call(_alignRef$current); + }); + cropInsRef.current = new Cropper(imgContainerRef.current, { + showMask: true, + viewer: imgIns + }); + } + }; + + // 获取框选的截图框信息 + var latestCropType = useLatest(cropType); + var latestImgKey = useLatest(dataSource[currentIndex].imageKey); + var latestCropRect = useLatest(cropRect); + var getCropInfo = /*#__PURE__*/function () { + var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3() { + var cropType, cropRect, imgIns, transform, newImgKey, rectList, extendRectList, selectIndex, shapes, shapeIds, newRect, data; + return _regeneratorRuntime().wrap(function _callee3$(_context3) { + while (1) switch (_context3.prev = _context3.next) { + case 0: + cropType = latestCropType.current; + cropRect = latestCropRect.current; + imgIns = imgInsRef.current; + transform = imgIns.targetTransform; + newImgKey = latestImgKey.current; + rectList = []; + extendRectList = []; + selectIndex = 0; + _context3.t0 = cropType; + _context3.next = _context3.t0 === CROP_TYPE['AUTO'] ? 11 : 17; + break; + case 11: + shapes = imgIns.getSelectShape(); + shapeIds = shapes.map(function (v) { + return v['id']; + }); + rectList = odList.filter(function (v) { + return shapeIds.includes(v['id']); + }).map(function (item) { + if (item.algorithmVersion === 'OBJECT_TYPE_FACE' || item.objectType === 'OBJECT_TYPE_FACE') { + if (!isNull(item.extendBox)) { + return _objectSpread(_objectSpread({}, item), {}, { + w: get(item, 'extendBox.w'), + h: get(item, 'extendBox.h'), + x: get(item, 'extendBox.x'), + y: get(item, 'extendBox.y') + }); + } + } else { + return item; + } + }); + extendRectList = extendOdList.filter(function (v) { + return shapeIds.includes(v['id']); + }).map(function (v) { + return pick(v, ['x', 'y', 'w', 'h', 'algorithmVersion', 'id']); + }); + selectIndex = rectList.findIndex(function (v) { + return v['id'] === selectRectId; + }); + return _context3.abrupt("break", 26); + case 17: + //获取旋转过的坐标 + // @ts-ignore + newRect = getTransformRect(imgIns.image, transform, cropRect); //判断是不是旋转过 + if (!(get(transform, 'rotate', 0) % 360 != 0)) { + _context3.next = 23; + break; + } + data = getRotateImg(imgIns.image, get(transform, 'rotate', 0)); //在画布上画旋转后的图片 + _context3.next = 22; + return upload(data); + case 22: + newImgKey = _context3.sent; + case 23: + rectList.push(newRect); + extendRectList.push(newRect); + return _context3.abrupt("break", 26); + case 26: + _context3.next = 28; + return Promise.all(extendRectList.map( /*#__PURE__*/function () { + var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(rect, index) { + var file, imgKey; + return _regeneratorRuntime().wrap(function _callee$(_context) { + while (1) switch (_context.prev = _context.next) { + case 0: + _context.next = 2; + return getFileByRect(imgIns.image, rect); + case 2: + file = _context.sent; + _context.next = 5; + return upload(file); + case 5: + imgKey = _context.sent; + extendRectList[index] = _objectSpread(_objectSpread({}, rect), {}, { + imgKey: imgKey + }); + case 7: + case "end": + return _context.stop(); + } + }, _callee); + })); + return function (_x, _x2) { + return _ref2.apply(this, arguments); + }; + }())); + case 28: + _context3.next = 30; + return Promise.all(rectList.map( /*#__PURE__*/function () { + var _ref3 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2(rect, index) { + var faceCorrectImage, faceCorrectImageKey, base64, blobData, file, newRect; + return _regeneratorRuntime().wrap(function _callee2$(_context2) { + while (1) switch (_context2.prev = _context2.next) { + case 0: + faceCorrectImage = rect['faceCorrectImage']; + if (!faceCorrectImage) { + _context2.next = 8; + break; + } + base64 = "data:image/jpg;base64,".concat(faceCorrectImage); + blobData = dataURLToBlob(base64); + file = new window.File([blobData], "".concat(new Date().getTime())); + _context2.next = 7; + return upload(file); + case 7: + faceCorrectImageKey = _context2.sent; + case 8: + newRect = _objectSpread(_objectSpread({}, rect), faceCorrectImageKey ? { + faceCorrectImageKey: faceCorrectImageKey + } : {}); + delete newRect['faceCorrectImage']; + rectList[index] = newRect; + case 11: + case "end": + return _context2.stop(); + } + }, _callee2); + })); + return function (_x3, _x4) { + return _ref3.apply(this, arguments); + }; + }())); + case 30: + return _context3.abrupt("return", { + rectList: rectList, + extendRectList: extendRectList, + selectIndex: selectIndex, + imgKey: newImgKey + }); + case 31: + case "end": + return _context3.stop(); + } + }, _callee3); + })); + return function getCropInfo() { + return _ref.apply(this, arguments); + }; + }(); + + // 操作界面判断 + var handleCropBtnClick = function handleCropBtnClick(v) { + switch (v) { + case 'close': + setShowCrop(false); + break; + case 'autoCrop': + setCropType(CROP_TYPE['AUTO']); + break; + case 'customCrop': + setCropType(CROP_TYPE['CUSTOM']); + break; + } + }; + + // ============================= attact img ========================= + var _useState21 = useState(0), + _useState22 = _slicedToArray(_useState21, 2), + selectAttachImgIndex = _useState22[0], + setSelectAttachImgIndex = _useState22[1]; + var _useState23 = useState(false), + _useState24 = _slicedToArray(_useState23, 2), + isZoomin = _useState24[0], + setIsZoomin = _useState24[1]; + + /** + * 修改当前图片预览下标 + * @param diff 跳转强度 正向后翻、负值向前翻 + */ + var handleChangeIndex = function handleChangeIndex(diff) { + var _dataSource$_index; + var _index = currentIndex + diff; + if (!(dataSource !== null && dataSource !== void 0 && (_dataSource$_index = dataSource[_index]) !== null && _dataSource$_index !== void 0 && _dataSource$_index.imageKey)) return; + setCurrentIndex(_index); + }; + + // ============================== Ref =============================== + useImperativeHandle(ref, function () { + return { + imgInsRef: imgInsRef, + setShowCrop: setShowCrop, + initData: initData, + getCropInfo: getCropInfo, + handleChangeIndex: handleChangeIndex + }; + }); + return /*#__PURE__*/React.createElement("div", { + className: classNames("".concat(componentName)), + style: { + height: height, + width: width + } + }, dataSource.length ? /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", { + className: classNames("".concat(componentName, "-main"), cropType === CROP_TYPE['AUTO'] && "".concat(componentName, "-main--cursor")), + ref: init + }), !hideLeftTopBtn && /*#__PURE__*/React.createElement(BtnGroup, { + className: classNames("".concat(componentName, "-opt")), + dataSource: operateBtnDataSource, + onClick: handleOptClick, + placement: "left" + }), showCrop && /*#__PURE__*/React.createElement(BtnGroup, { + circle: true, + className: classNames("".concat(componentName, "-crop-opt")), + dataSource: cropBtnDataSource, + onClick: handleCropBtnClick, + selectKey: cropType === CROP_TYPE['AUTO'] ? 'autoCrop' : 'customCrop' + }), showCrop && cropRect && screenshotButtonRender && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", { + ref: alginContainerRef, + className: classNames("".concat(componentName, "-align")), + style: Object.assign({ + width: cropRect.w, + height: cropRect.h + }, getTransforms({ + translateX: cropRect.x, + translateY: cropRect.y + })) + }), /*#__PURE__*/React.createElement(Align, { + ref: alignRef, + monitorWindowResize: true, + align: screenshotButtonAlign, + target: function target() { + return alginContainerRef.current; + } + }, screenshotButtonRender({ + model: 'IMAGE', + getCropInfo: getCropInfo, + setShowCrop: setShowCrop, + cropType: cropType, + selectAlgorithmVersion: selectAlgorithmVersion + }))), ((_dataSource$currentIn2 = dataSource[currentIndex].attachImg) === null || _dataSource$currentIn2 === void 0 ? void 0 : _dataSource$currentIn2.length) && !showCrop && /*#__PURE__*/React.createElement("div", { + className: classNames("".concat(componentName, "-attach"), isZoomin && "".concat(componentName, "-attach--zoomin"), "".concat(componentName, "-attach--fixed"), isZoomin && "".concat(componentName, "-attach--zoomin--fixed")) + }, /*#__PURE__*/React.createElement("div", { + className: classNames("".concat(componentName, "-attach__tab")) + }, showAttachImgLabel ? (_dataSource$currentIn3 = dataSource[currentIndex].attachImg) === null || _dataSource$currentIn3 === void 0 ? void 0 : _dataSource$currentIn3.map(function (_ref4, index) { + var label = _ref4.label; + return /*#__PURE__*/React.createElement("div", { + key: index, + className: classNames("".concat(componentName, "-attach__tab-item"), selectAttachImgIndex === index && "".concat(componentName, "-attach__tab-item--select")), + onMouseEnter: function onMouseEnter() { + setSelectAttachImgIndex(index); + } + }, label); + }) : null), /*#__PURE__*/React.createElement("div", { + className: classNames("".concat(componentName, "-attach__scale")) + }, /*#__PURE__*/React.createElement(Button, { + type: "text" + //绝对定位下onClick事件失效采用onMouseDown + , + onMouseDown: function onMouseDown(e) { + //如果是左键执行 + if (e.button == 0) { + setIsZoomin(function (pre) { + return !pre; + }); + } + }, + style: { + color: '#fff' + } + }, /*#__PURE__*/React.createElement(Icon, { + styles: { + display: 'flex' + }, + icon: isZoomin ? 'icon-cancle_fullscreen' : 'icon-fullscreen' + }))), /*#__PURE__*/React.createElement("img", { + draggable: "false", + className: classNames("".concat(componentName, "-attach__img"), "".concat(componentName, "-attach__img--fixed")), + src: get(dataSource[currentIndex].attachImg, "".concat(selectAttachImgIndex, ".url"), '') + })), showScore && /*#__PURE__*/React.createElement("div", { + style: { + bottom: 20 + }, + className: classNames("".concat(componentName, "__face-score")) + }, "\u4EBA\u8138\u8D28\u91CF\u5206\uFF1A".concat(Number(dataSource[currentIndex].score).toFixed(2)))) : /*#__PURE__*/React.createElement(Empty, { + image: Empty.PRESENTED_IMAGE_SIMPLE, + description: "\u6682\u65E0\u6570\u636E" + })); +}); +BigImagePreview.displayName = 'BigImagePreview'; +export default BigImagePreview; \ No newline at end of file diff --git a/packages/hooks/lib/useIMEComposition/constants.d.ts b/packages/meta/es/BigImagePreview/bigImagePreviewHelper.d.ts similarity index 100% rename from packages/hooks/lib/useIMEComposition/constants.d.ts rename to packages/meta/es/BigImagePreview/bigImagePreviewHelper.d.ts diff --git a/packages/hooks/lib/useIMEComposition/constants.js b/packages/meta/es/BigImagePreview/bigImagePreviewHelper.js similarity index 100% rename from packages/hooks/lib/useIMEComposition/constants.js rename to packages/meta/es/BigImagePreview/bigImagePreviewHelper.js diff --git a/packages/meta/es/BigImagePreview/components/BtnGroup/index.d.ts b/packages/meta/es/BigImagePreview/components/BtnGroup/index.d.ts new file mode 100644 index 0000000..960a037 --- /dev/null +++ b/packages/meta/es/BigImagePreview/components/BtnGroup/index.d.ts @@ -0,0 +1,17 @@ +import React, { MouseEvent } from 'react'; +import { TooltipProps } from 'antd'; +import './index.less'; +export interface BtnGroupProps { + className: string; + dataSource: Array<{ + key: string; + icon: string; + title: string; + }>; + onClick: (v: string, e: MouseEvent) => void; + selectKey?: string; + circle?: boolean; + placement?: TooltipProps['placement']; +} +export declare const BtnGroup: React.FC; +export default BtnGroup; diff --git a/packages/meta/es/BigImagePreview/components/BtnGroup/index.js b/packages/meta/es/BigImagePreview/components/BtnGroup/index.js new file mode 100644 index 0000000..52e621c --- /dev/null +++ b/packages/meta/es/BigImagePreview/components/BtnGroup/index.js @@ -0,0 +1,42 @@ +import React from 'react'; +import classNames from 'classnames'; +import { Button, Tooltip } from 'antd'; +import Icon from "../../../iconfont"; +import "./index.less"; +var componentName = "zhst-image__btn-group"; +export var BtnGroup = function BtnGroup(props) { + var dataSource = props.dataSource, + _onClick = props.onClick, + className = props.className, + circle = props.circle, + _props$selectKey = props.selectKey, + selectKey = _props$selectKey === void 0 ? '' : _props$selectKey, + _props$placement = props.placement, + placement = _props$placement === void 0 ? 'right' : _props$placement; + return /*#__PURE__*/React.createElement("div", { + className: classNames(componentName, circle && "".concat(componentName, "--circle"), className) + }, dataSource.map(function (_ref) { + var key = _ref.key, + icon = _ref.icon, + title = _ref.title; + var isSelect = key === selectKey; + return /*#__PURE__*/React.createElement(Tooltip, { + key: key, + placement: placement, + title: title + }, /*#__PURE__*/React.createElement("div", { + key: key, + className: classNames("".concat(componentName, "__item"), isSelect && "".concat(componentName, "__item--active")) + }, /*#__PURE__*/React.createElement(Button, { + type: "text", + onClick: function onClick(e) { + _onClick(key, e); + } + }, /*#__PURE__*/React.createElement(Icon, { + size: 18, + icon: icon + })))); + })); +}; +BtnGroup.displayName = 'BtnGroup'; +export default BtnGroup; \ No newline at end of file diff --git a/packages/meta/es/BigImagePreview/components/BtnGroup/index.less b/packages/meta/es/BigImagePreview/components/BtnGroup/index.less new file mode 100644 index 0000000..db03187 --- /dev/null +++ b/packages/meta/es/BigImagePreview/components/BtnGroup/index.less @@ -0,0 +1,51 @@ +.zhst-image__btn-group { + // display: flex; + width: 30px; + box-shadow: 0 2px 6px 0 rgb(0 0 0 / 40%); + + &__item { + display: flex; + width: 30px; + height: 30px; + align-items: center; + justify-content: center; + background: #000; + + &>button { + padding: 0; + color: #fff; + + &:hover { + color: #09f; + } + + &:active { + color: #09f; + } + + &:focus { + color: #fff; + } + + &>span { + display: flex; + } + } + + &--active { + &>button { + color: #09f; + } + } + } + + &--circle { + background-color: none; + box-shadow: none; + } + + &--circle &__item { + margin-bottom: 4px; + border-radius: 50%; + } +} diff --git a/packages/meta/es/BigImagePreview/components/ScreenhotButtons/index.d.ts b/packages/meta/es/BigImagePreview/components/ScreenhotButtons/index.d.ts new file mode 100644 index 0000000..cb09279 --- /dev/null +++ b/packages/meta/es/BigImagePreview/components/ScreenhotButtons/index.d.ts @@ -0,0 +1,14 @@ +import React from 'react'; +import type { AlgorithmVersion } from '@zhst/types'; +import './index.less'; +interface IScreenShotButton { + getCropInfo: () => void; + setShowCrop: any; + cropType: string; + selectAlgorithmVersion?: AlgorithmVersion | null; +} +declare const getScreenshotButtonRender: (arg: { + disableBtn: number[]; + onBigImageActionClick: (type: number, item: any) => void; +}) => (param: IScreenShotButton) => React.JSX.Element; +export default getScreenshotButtonRender; diff --git a/packages/biz/es/utils/request.js b/packages/meta/es/BigImagePreview/components/ScreenhotButtons/index.js similarity index 53% rename from packages/biz/es/utils/request.js rename to packages/meta/es/BigImagePreview/components/ScreenhotButtons/index.js index 9eb1054..64121a6 100644 --- a/packages/biz/es/utils/request.js +++ b/packages/meta/es/BigImagePreview/components/ScreenhotButtons/index.js @@ -2,120 +2,123 @@ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return e; }; var t, e = {}, r = Object.prototype, n = r.hasOwnProperty, o = Object.defineProperty || function (t, e, r) { t[e] = r.value; }, i = "function" == typeof Symbol ? Symbol : {}, a = i.iterator || "@@iterator", c = i.asyncIterator || "@@asyncIterator", u = i.toStringTag || "@@toStringTag"; function define(t, e, r) { return Object.defineProperty(t, e, { value: r, enumerable: !0, configurable: !0, writable: !0 }), t[e]; } try { define({}, ""); } catch (t) { define = function define(t, e, r) { return t[e] = r; }; } function wrap(t, e, r, n) { var i = e && e.prototype instanceof Generator ? e : Generator, a = Object.create(i.prototype), c = new Context(n || []); return o(a, "_invoke", { value: makeInvokeMethod(t, r, c) }), a; } function tryCatch(t, e, r) { try { return { type: "normal", arg: t.call(e, r) }; } catch (t) { return { type: "throw", arg: t }; } } e.wrap = wrap; var h = "suspendedStart", l = "suspendedYield", f = "executing", s = "completed", y = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var p = {}; define(p, a, function () { return this; }); var d = Object.getPrototypeOf, v = d && d(d(values([]))); v && v !== r && n.call(v, a) && (p = v); var g = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(p); function defineIteratorMethods(t) { ["next", "throw", "return"].forEach(function (e) { define(t, e, function (t) { return this._invoke(e, t); }); }); } function AsyncIterator(t, e) { function invoke(r, o, i, a) { var c = tryCatch(t[r], t, o); if ("throw" !== c.type) { var u = c.arg, h = u.value; return h && "object" == _typeof(h) && n.call(h, "__await") ? e.resolve(h.__await).then(function (t) { invoke("next", t, i, a); }, function (t) { invoke("throw", t, i, a); }) : e.resolve(h).then(function (t) { u.value = t, i(u); }, function (t) { return invoke("throw", t, i, a); }); } a(c.arg); } var r; o(this, "_invoke", { value: function value(t, n) { function callInvokeWithMethodAndArg() { return new e(function (e, r) { invoke(t, n, e, r); }); } return r = r ? r.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); } }); } function makeInvokeMethod(e, r, n) { var o = h; return function (i, a) { if (o === f) throw new Error("Generator is already running"); if (o === s) { if ("throw" === i) throw a; return { value: t, done: !0 }; } for (n.method = i, n.arg = a;;) { var c = n.delegate; if (c) { var u = maybeInvokeDelegate(c, n); if (u) { if (u === y) continue; return u; } } if ("next" === n.method) n.sent = n._sent = n.arg;else if ("throw" === n.method) { if (o === h) throw o = s, n.arg; n.dispatchException(n.arg); } else "return" === n.method && n.abrupt("return", n.arg); o = f; var p = tryCatch(e, r, n); if ("normal" === p.type) { if (o = n.done ? s : l, p.arg === y) continue; return { value: p.arg, done: n.done }; } "throw" === p.type && (o = s, n.method = "throw", n.arg = p.arg); } }; } function maybeInvokeDelegate(e, r) { var n = r.method, o = e.iterator[n]; if (o === t) return r.delegate = null, "throw" === n && e.iterator.return && (r.method = "return", r.arg = t, maybeInvokeDelegate(e, r), "throw" === r.method) || "return" !== n && (r.method = "throw", r.arg = new TypeError("The iterator does not provide a '" + n + "' method")), y; var i = tryCatch(o, e.iterator, r.arg); if ("throw" === i.type) return r.method = "throw", r.arg = i.arg, r.delegate = null, y; var a = i.arg; return a ? a.done ? (r[e.resultName] = a.value, r.next = e.nextLoc, "return" !== r.method && (r.method = "next", r.arg = t), r.delegate = null, y) : a : (r.method = "throw", r.arg = new TypeError("iterator result is not an object"), r.delegate = null, y); } function pushTryEntry(t) { var e = { tryLoc: t[0] }; 1 in t && (e.catchLoc = t[1]), 2 in t && (e.finallyLoc = t[2], e.afterLoc = t[3]), this.tryEntries.push(e); } function resetTryEntry(t) { var e = t.completion || {}; e.type = "normal", delete e.arg, t.completion = e; } function Context(t) { this.tryEntries = [{ tryLoc: "root" }], t.forEach(pushTryEntry, this), this.reset(!0); } function values(e) { if (e || "" === e) { var r = e[a]; if (r) return r.call(e); if ("function" == typeof e.next) return e; if (!isNaN(e.length)) { var o = -1, i = function next() { for (; ++o < e.length;) if (n.call(e, o)) return next.value = e[o], next.done = !1, next; return next.value = t, next.done = !0, next; }; return i.next = i; } } throw new TypeError(_typeof(e) + " is not iterable"); } return GeneratorFunction.prototype = GeneratorFunctionPrototype, o(g, "constructor", { value: GeneratorFunctionPrototype, configurable: !0 }), o(GeneratorFunctionPrototype, "constructor", { value: GeneratorFunction, configurable: !0 }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, u, "GeneratorFunction"), e.isGeneratorFunction = function (t) { var e = "function" == typeof t && t.constructor; return !!e && (e === GeneratorFunction || "GeneratorFunction" === (e.displayName || e.name)); }, e.mark = function (t) { return Object.setPrototypeOf ? Object.setPrototypeOf(t, GeneratorFunctionPrototype) : (t.__proto__ = GeneratorFunctionPrototype, define(t, u, "GeneratorFunction")), t.prototype = Object.create(g), t; }, e.awrap = function (t) { return { __await: t }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, c, function () { return this; }), e.AsyncIterator = AsyncIterator, e.async = function (t, r, n, o, i) { void 0 === i && (i = Promise); var a = new AsyncIterator(wrap(t, r, n, o), i); return e.isGeneratorFunction(r) ? a : a.next().then(function (t) { return t.done ? t.value : a.next(); }); }, defineIteratorMethods(g), define(g, u, "Generator"), define(g, a, function () { return this; }), define(g, "toString", function () { return "[object Generator]"; }), e.keys = function (t) { var e = Object(t), r = []; for (var n in e) r.push(n); return r.reverse(), function next() { for (; r.length;) { var t = r.pop(); if (t in e) return next.value = t, next.done = !1, next; } return next.done = !0, next; }; }, e.values = values, Context.prototype = { constructor: Context, reset: function reset(e) { if (this.prev = 0, this.next = 0, this.sent = this._sent = t, this.done = !1, this.delegate = null, this.method = "next", this.arg = t, this.tryEntries.forEach(resetTryEntry), !e) for (var r in this) "t" === r.charAt(0) && n.call(this, r) && !isNaN(+r.slice(1)) && (this[r] = t); }, stop: function stop() { this.done = !0; var t = this.tryEntries[0].completion; if ("throw" === t.type) throw t.arg; return this.rval; }, dispatchException: function dispatchException(e) { if (this.done) throw e; var r = this; function handle(n, o) { return a.type = "throw", a.arg = e, r.next = n, o && (r.method = "next", r.arg = t), !!o; } for (var o = this.tryEntries.length - 1; o >= 0; --o) { var i = this.tryEntries[o], a = i.completion; if ("root" === i.tryLoc) return handle("end"); if (i.tryLoc <= this.prev) { var c = n.call(i, "catchLoc"), u = n.call(i, "finallyLoc"); if (c && u) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } else if (c) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); } else { if (!u) throw new Error("try statement without catch or finally"); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } } } }, abrupt: function abrupt(t, e) { for (var r = this.tryEntries.length - 1; r >= 0; --r) { var o = this.tryEntries[r]; if (o.tryLoc <= this.prev && n.call(o, "finallyLoc") && this.prev < o.finallyLoc) { var i = o; break; } } i && ("break" === t || "continue" === t) && i.tryLoc <= e && e <= i.finallyLoc && (i = null); var a = i ? i.completion : {}; return a.type = t, a.arg = e, i ? (this.method = "next", this.next = i.finallyLoc, y) : this.complete(a); }, complete: function complete(t, e) { if ("throw" === t.type) throw t.arg; return "break" === t.type || "continue" === t.type ? this.next = t.arg : "return" === t.type ? (this.rval = this.arg = t.arg, this.method = "return", this.next = "end") : "normal" === t.type && e && (this.next = e), y; }, finish: function finish(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.finallyLoc === t) return this.complete(r.completion, r.afterLoc), resetTryEntry(r), y; } }, catch: function _catch(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.tryLoc === t) { var n = r.completion; if ("throw" === n.type) { var o = n.arg; resetTryEntry(r); } return o; } } throw new Error("illegal catch attempt"); }, delegateYield: function delegateYield(e, r, n) { return this.delegate = { iterator: values(e), resultName: r, nextLoc: n }, "next" === this.method && (this.arg = t), y; } }, e; } function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } -function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } } -function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); } -function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } -function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); } -function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } -function _wrapNativeSuper(Class) { var _cache = typeof Map === "function" ? new Map() : undefined; _wrapNativeSuper = function _wrapNativeSuper(Class) { if (Class === null || !_isNativeFunction(Class)) return Class; if (typeof Class !== "function") { throw new TypeError("Super expression must either be null or a function"); } if (typeof _cache !== "undefined") { if (_cache.has(Class)) return _cache.get(Class); _cache.set(Class, Wrapper); } function Wrapper() { return _construct(Class, arguments, _getPrototypeOf(this).constructor); } Wrapper.prototype = Object.create(Class.prototype, { constructor: { value: Wrapper, enumerable: false, writable: true, configurable: true } }); return _setPrototypeOf(Wrapper, Class); }; return _wrapNativeSuper(Class); } -function _construct(Parent, args, Class) { if (_isNativeReflectConstruct()) { _construct = Reflect.construct.bind(); } else { _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Function.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); } -function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } -function _isNativeFunction(fn) { try { return Function.toString.call(fn).indexOf("[native code]") !== -1; } catch (e) { return typeof fn === "function"; } } -function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } -function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } -function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } -function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); } -function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); } -import { extend } from 'umi-request'; -import { get } from '@zhst/func'; -import { message } from 'antd'; -import base64 from 'base-64'; -export var ResponseError = /*#__PURE__*/function (_Error) { - _inherits(ResponseError, _Error); - var _super = _createSuper(ResponseError); - function ResponseError(response, text, data, request) { - var _this; - var type = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 'ResponseError'; - _classCallCheck(this, ResponseError); - _this = _super.call(this, text || response.statusText); - _defineProperty(_assertThisInitialized(_this), "name", void 0); - _defineProperty(_assertThisInitialized(_this), "data", void 0); - _defineProperty(_assertThisInitialized(_this), "response", void 0); - _defineProperty(_assertThisInitialized(_this), "request", void 0); - _defineProperty(_assertThisInitialized(_this), "type", void 0); - _this.name = 'ResponseError'; - _this.data = data; - _this.response = response; - _this.request = request; - _this.type = type; - return _this; - } - return _createClass(ResponseError); -}( /*#__PURE__*/_wrapNativeSuper(Error)); -export var request = extend({ - getResponse: true, - // timeout: 1000, - parseResponse: false -}); - -//错误处理中间件 -request.use( /*#__PURE__*/function () { - var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(ctx, next) { - var req, _ref2, _ref2$toast, toast, res, d, isEmptyRes, body, errMsg, _window$utf; - return _regeneratorRuntime().wrap(function _callee$(_context) { - while (1) switch (_context.prev = _context.next) { - case 0: - req = ctx.req; - _ref2 = (req === null || req === void 0 ? void 0 : req.options) || {}, _ref2$toast = _ref2.toast, toast = _ref2$toast === void 0 ? true : _ref2$toast; - _context.prev = 2; - _context.next = 5; - return next(); - case 5: - res = ctx.res; - _context.next = 8; - return res.text(); - case 8: - d = _context.sent; - if (!(res.status === 401)) { - _context.next = 12; - break; - } - message.warning('登录过期,请重新登录!'); - return _context.abrupt("return"); - case 12: - isEmptyRes = d === ''; //有些后端接口成功会返回空 做下兼容 - body = !isEmptyRes ? JSON.parse(d) : d; - if (!(res.status >= 200 && res.status < 300)) { - _context.next = 18; - break; - } - ctx.res = body; - _context.next = 22; - break; - case 18: - // 先判断Grpc-Metadata-Errorx-Message - errMsg = res.headers.get('Grpc-Metadata-Errorx-Message'); - if (errMsg) { - errMsg = (_window$utf = window.utf8) === null || _window$utf === void 0 ? void 0 : _window$utf.decode(base64.decode(errMsg)); - // 后判断 body中的message - } else if (!errMsg && get(body, 'message')) { - errMsg = "".concat(get(body, 'message')); - } else { - // 最后看状态码 - errMsg = '您的网络发生异常,无法连接服务器'; - } - toast && message.error(errMsg); - throw new ResponseError(res, errMsg, d, req, 'CustomError'); - case 22: - _context.next = 28; - break; - case 24: - _context.prev = 24; - _context.t0 = _context["catch"](2); - if (get(_context.t0, 'type') !== 'CustomError') { - toast && message.error('您的网络发生异常,无法连接服务器'); - } - throw _context.t0; - case 28: - case "end": - return _context.stop(); +import React from 'react'; +import { Button } from 'antd'; +import classNames from 'classnames'; +import { IBigImageOpt } from '@zhst/types/BigImageModal'; +import "./index.less"; +var componentName = 'bigImageWrapper--v2'; +var getScreenshotButtonRender = function getScreenshotButtonRender(arg) { + var _arg$disableBtn = arg.disableBtn, + disableBtn = _arg$disableBtn === void 0 ? [] : _arg$disableBtn, + onBigImageActionClick = arg.onBigImageActionClick; + return function (param) { + var getCropInfo = param.getCropInfo, + setShowCrop = param.setShowCrop, + cropType = param.cropType, + selectAlgorithmVersion = param.selectAlgorithmVersion; + var isAuto = cropType === 'AUTO'; + return /*#__PURE__*/React.createElement("div", { + className: classNames("".concat(componentName, "__screenshot")), + style: { + zIndex: 100, + position: 'absolute', + width: '86px' } - }, _callee, null, [[2, 24]]); - })); - return function (_x, _x2) { - return _ref.apply(this, arguments); + }, !disableBtn.includes(IBigImageOpt['ADD_HISTORY_WITH_CROP']) && isAuto && /*#__PURE__*/React.createElement(Button, { + type: 'text', + onClick: /*#__PURE__*/function () { + var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(e) { + var image; + return _regeneratorRuntime().wrap(function _callee$(_context) { + while (1) switch (_context.prev = _context.next) { + case 0: + e.stopPropagation(); + _context.next = 3; + return getCropInfo(); + case 3: + image = _context.sent; + setShowCrop(false); + onBigImageActionClick(IBigImageOpt['ADD_HISTORY_WITH_CROP'], image); + case 6: + case "end": + return _context.stop(); + } + }, _callee); + })); + return function (_x) { + return _ref.apply(this, arguments); + }; + }() + }, "\u76EE\u6807\u68C0\u7D22"), !disableBtn.includes(IBigImageOpt['ADD_HISTORY_WITH_CROP_BODY']) && !isAuto && /*#__PURE__*/React.createElement(Button, { + type: 'text', + onClick: /*#__PURE__*/function () { + var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2(e) { + var image; + return _regeneratorRuntime().wrap(function _callee2$(_context2) { + while (1) switch (_context2.prev = _context2.next) { + case 0: + e.stopPropagation(); + _context2.next = 3; + return getCropInfo(); + case 3: + image = _context2.sent; + setShowCrop(false); + onBigImageActionClick(IBigImageOpt['ADD_HISTORY_WITH_CROP_BODY'], image); + case 6: + case "end": + return _context2.stop(); + } + }, _callee2); + })); + return function (_x2) { + return _ref2.apply(this, arguments); + }; + }() + }, "\u641C\u5F62\u4F53"), !disableBtn.includes(IBigImageOpt['ADD_HISTORY_WITH_CROP_VEHICLE']) && !isAuto && /*#__PURE__*/React.createElement(Button, { + type: 'text', + onClick: /*#__PURE__*/function () { + var _ref3 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3(e) { + var image; + return _regeneratorRuntime().wrap(function _callee3$(_context3) { + while (1) switch (_context3.prev = _context3.next) { + case 0: + e.stopPropagation(); + _context3.next = 3; + return getCropInfo(); + case 3: + image = _context3.sent; + setShowCrop(false); + onBigImageActionClick(IBigImageOpt['ADD_HISTORY_WITH_CROP_VEHICLE'], image); + case 6: + case "end": + return _context3.stop(); + } + }, _callee3); + })); + return function (_x3) { + return _ref3.apply(this, arguments); + }; + }() + }, "\u641C\u975E\u673A\u52A8\u8F66"), !disableBtn.includes(IBigImageOpt['ADD_HISTORY_WITH_CROP_ARCHIVE']) && selectAlgorithmVersion !== 0 && /*#__PURE__*/React.createElement(Button, { + type: 'text', + onClick: function onClick(e) { + e.stopPropagation(); + var image = getCropInfo(); + setShowCrop(false); + if (!image.rectList[0].algorithmVersion) { + image.rectList[0].algorithmVersion = 0; + image.extendRectList[0].algorithmVersion = 0; + } + onBigImageActionClick(IBigImageOpt['ADD_HISTORY_WITH_CROP_ARCHIVE'], image); + } + }, "\u6863\u6848\u68C0\u7D22"), /*#__PURE__*/React.createElement(Button, { + type: 'text', + onClick: function onClick(e) { + e.stopPropagation(); + setShowCrop(false); + } + }, "\u9000\u51FA\u6846\u9009")); }; -}()); -export default request; \ No newline at end of file +}; +export default getScreenshotButtonRender; \ No newline at end of file diff --git a/packages/meta/es/BigImagePreview/components/ScreenhotButtons/index.less b/packages/meta/es/BigImagePreview/components/ScreenhotButtons/index.less new file mode 100644 index 0000000..ca407fa --- /dev/null +++ b/packages/meta/es/BigImagePreview/components/ScreenhotButtons/index.less @@ -0,0 +1,21 @@ +.bigImageWrapper--v2__screenshot { + min-width: 90px; + background: rgb(0 0 0 / 50%); + border-radius: 0; + + &>button { + width: 100%; + color: #fff !important; + font-family: 'Microsoft YaHei'; + font-size: 12px !important; + border-radius: 0; + + &>span { + color: #fff; + } + + &:hover { + background-color: #09f !important; + } + } +} diff --git a/packages/meta/es/BigImagePreview/index.d.ts b/packages/meta/es/BigImagePreview/index.d.ts new file mode 100644 index 0000000..7469634 --- /dev/null +++ b/packages/meta/es/BigImagePreview/index.d.ts @@ -0,0 +1,3 @@ +import BigImagePreview from './BigImagePreview'; +export type { ImgViewProps } from './BigImagePreview'; +export default BigImagePreview; diff --git a/packages/meta/es/BigImagePreview/index.js b/packages/meta/es/BigImagePreview/index.js new file mode 100644 index 0000000..abc99c3 --- /dev/null +++ b/packages/meta/es/BigImagePreview/index.js @@ -0,0 +1,2 @@ +import BigImagePreview from "./BigImagePreview"; +export default BigImagePreview; \ No newline at end of file diff --git a/packages/meta/es/BigImagePreview/index.less b/packages/meta/es/BigImagePreview/index.less new file mode 100644 index 0000000..d192880 --- /dev/null +++ b/packages/meta/es/BigImagePreview/index.less @@ -0,0 +1,123 @@ +.zhst-image__img-view { + position: relative; + width: calc(100%); + height: 100%; + + &__face-score { + position: absolute; + right: 20px; + bottom: 80px; + color: red; + font-family: 'Microsoft YaHei'; + font-size: 19px; + font-weight: bold; + } + + &-opt { + position: absolute; + z-index: 99; + top: 0; + } + + &-crop-opt { + position: absolute; + z-index: 99; + top: 0; + right: 0; + } + + &-align { + position: absolute; + top: 0; + left: 0; + pointer-events: none; + } + + &-main { + width: 100%; + height: 100%; + font-size: 0; + + &--cursor { + & canvas { + min-height: 320px; + cursor: pointer; + } + } + } + + &-screenshot { + position: absolute; + z-index: 10; + } + + &-attach { + position: absolute; + z-index: 11; + bottom: 0; + + // left: 78px; + left: 0; + min-width: 120px; + height: 202px; + transition: all 200ms; + + &--zoomin { + height: 100%; + } + + &__tab { + position: absolute; + top: 0; + left: 0; + display: flex; + + &-item { + display: flex; + width: 30px; + height: 24px; + align-items: center; + justify-content: center; + background: #000; + color: #fff; + cursor: pointer; + font-size: 12px; + opacity: 0.5; + transition: all 200ms; + + &--select { + width: 48px; + height: 34px; + background: #09f; + opacity: 1; + } + } + } + + &__scale { + position: absolute; + top: 4px; + right: 4px; + display: flex; + width: 30px; + height: 30px; + align-items: center; + justify-content: center; + background: rgb(0 0 0 / 60%); + border-radius: 100%; + cursor: pointer; + line-height: 30px; + text-align: center; + } + + &__img { + height: 100%; + object-fit: contain; + + &--fixed { + width: 100%; + object-fit: contain; + } + } + } +} diff --git a/packages/meta/es/CompareImage/CompareImage.d.ts b/packages/meta/es/CompareImage/CompareImage.d.ts new file mode 100644 index 0000000..18fbaca --- /dev/null +++ b/packages/meta/es/CompareImage/CompareImage.d.ts @@ -0,0 +1,20 @@ +import React from 'react'; +import './index.less'; +export interface CompareImageProps { + /** + * @description 属性描述 + * @default "默认值" + */ + label: string; + openRoll?: boolean; + dataSource?: Array<{ + url: string; + score: number; + }>; + showScore?: boolean; + current: number; +} +export interface CompareImageRefProps { +} +declare const CompareImage: React.ForwardRefExoticComponent>; +export default CompareImage; diff --git a/packages/meta/es/ImagePreview/index.js b/packages/meta/es/CompareImage/CompareImage.js similarity index 72% rename from packages/meta/es/ImagePreview/index.js rename to packages/meta/es/CompareImage/CompareImage.js index 6bc9061..290df60 100644 --- a/packages/meta/es/ImagePreview/index.js +++ b/packages/meta/es/CompareImage/CompareImage.js @@ -4,24 +4,27 @@ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o = function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; } function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } } function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } -import React, { useRef, useState, useEffect, useCallback } from 'react'; -import { generateImg, get, addEventListener } from '@zhst/func'; +import React, { useRef, useState, useEffect, forwardRef, useImperativeHandle } from 'react'; +import { generateImg, get, addEventListenerWrapper } from '@zhst/func'; import { useUpdateEffect } from '@zhst/hooks'; import { Button } from 'antd'; import classNames from 'classnames'; import Viewer from "../ImageEditor/viewer"; import Icon from "../iconfont"; import CornerScore from "./components/CornerScore"; +import "./index.less"; var componentName = "zhst-image__compater-view"; // 对比图组件 -var CompaterImage = function CompaterImage(props) { - var url = props.url, - label = props.label, +var CompareImage = /*#__PURE__*/forwardRef(function (props, ref) { + var label = props.label, _props$openRoll = props.openRoll, openRoll = _props$openRoll === void 0 ? false : _props$openRoll, - _props$urls = props.urls, - urls = _props$urls === void 0 ? [] : _props$urls, - score = props.score; + _props$dataSource = props.dataSource, + dataSource = _props$dataSource === void 0 ? [] : _props$dataSource, + _props$showScore = props.showScore, + showScore = _props$showScore === void 0 ? true : _props$showScore, + _props$current = props.current, + current = _props$current === void 0 ? 0 : _props$current; var imgContainerRef = useRef(null); var imgInsRef = useRef(null); var _useState = useState(0), @@ -29,65 +32,56 @@ var CompaterImage = function CompaterImage(props) { scale = _useState2[0], setScale = _useState2[1]; //图片翻页机制 - var _useState3 = useState(generateImg(url)), + var _useState3 = useState(current), _useState4 = _slicedToArray(_useState3, 2), - showUrl = _useState4[0], - setShowUrl = _useState4[1]; //记录显示的图片 + currentIndex = _useState4[0], + setCurrentIndex = _useState4[1]; - useUpdateEffect(function () { - setShowUrl(generateImg(url)); - if (imgInsRef.current) { - var _imgInsRef$current; - (_imgInsRef$current = imgInsRef.current) === null || _imgInsRef$current === void 0 || _imgInsRef$current.refleshImage({ - image: generateImg(url) - }); - } - }, [url]); + // 初始化页面 useEffect(function () { - setShowUrl(url); - var handleTransformChange = addEventListener(imgContainerRef.current, 'viewer-transform-change', function (event) { + var handleTransformChange = addEventListenerWrapper(imgContainerRef.current, 'viewer-transform-change', function (event) { var data = event.detail; setScale(get(data, 'scale', 0)); }); - imgInsRef.current = new Viewer(imgContainerRef.current, { - image: generateImg(url) - }); + if (generateImg(dataSource[currentIndex].url)) { + imgInsRef.current = new Viewer(imgContainerRef.current, { + image: generateImg(dataSource[currentIndex].url) + }); + } return function () { - var _imgInsRef$current2, _imgInsRef$current2$d; + var _imgInsRef$current, _imgInsRef$current$de; handleTransformChange === null || handleTransformChange === void 0 || handleTransformChange.remove(); - imgInsRef === null || imgInsRef === void 0 || (_imgInsRef$current2 = imgInsRef.current) === null || _imgInsRef$current2 === void 0 || (_imgInsRef$current2$d = _imgInsRef$current2.destroy) === null || _imgInsRef$current2$d === void 0 || _imgInsRef$current2$d.call(_imgInsRef$current2); + imgInsRef === null || imgInsRef === void 0 || (_imgInsRef$current = imgInsRef.current) === null || _imgInsRef$current === void 0 || (_imgInsRef$current$de = _imgInsRef$current.destroy) === null || _imgInsRef$current$de === void 0 || _imgInsRef$current$de.call(_imgInsRef$current); imgInsRef.current = null; }; }, []); - //向前翻页 - var handlePre = useCallback(function () { - var index = urls.findIndex(function (v) { - return v === showUrl; - }); - if (index > 0) { - var _imgInsRef$current3; - var newUrl = urls[index - 1]; - setShowUrl(newUrl); - (_imgInsRef$current3 = imgInsRef.current) === null || _imgInsRef$current3 === void 0 || _imgInsRef$current3.refleshImage({ - image: newUrl + // 监听下标变化 + useUpdateEffect(function () { + if (imgInsRef.current) { + var _imgInsRef$current2; + (_imgInsRef$current2 = imgInsRef.current) === null || _imgInsRef$current2 === void 0 || _imgInsRef$current2.refleshImage({ + image: generateImg(dataSource[currentIndex].url) }); } - }, [showUrl, urls]); - //向后翻页 - var handleNext = useCallback(function () { - var index = urls.findIndex(function (v) { - return v === showUrl; + }, [currentIndex]); + + // 翻页实践 + var handleIndexChange = function handleIndexChange(changeVal) { + var _dataSource$_index, _imgInsRef$current3; + var _index = currentIndex + changeVal; + if (!(dataSource !== null && dataSource !== void 0 && (_dataSource$_index = dataSource[_index]) !== null && _dataSource$_index !== void 0 && _dataSource$_index.url)) return; + (_imgInsRef$current3 = imgInsRef.current) === null || _imgInsRef$current3 === void 0 || _imgInsRef$current3.refleshImage({ + image: generateImg(dataSource[_index].url) }); - if (index >= 0 && !!urls[index + 1]) { - var _imgInsRef$current4; - var newUrl = urls[index + 1]; - setShowUrl(newUrl); - (_imgInsRef$current4 = imgInsRef.current) === null || _imgInsRef$current4 === void 0 || _imgInsRef$current4.refleshImage({ - image: newUrl - }); - } - }, [showUrl, urls]); + setCurrentIndex(_index); + }; + useImperativeHandle(ref, function () { + return { + imgInsRef: imgInsRef, + handleIndexChange: handleIndexChange + }; + }); return /*#__PURE__*/React.createElement("div", { className: classNames("".concat(componentName, "__container")) }, /*#__PURE__*/React.createElement("div", { @@ -95,23 +89,21 @@ var CompaterImage = function CompaterImage(props) { }, label), /*#__PURE__*/React.createElement("div", { ref: imgContainerRef, className: classNames("".concat(componentName, "__view")) - }), !url && /*#__PURE__*/React.createElement("div", { + }), !dataSource.length && /*#__PURE__*/React.createElement("div", { className: classNames("".concat(componentName, "__empty")) }, /*#__PURE__*/React.createElement("img", { src: "data:image/png;base64,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", title: "\u6682\u65E0\u6570\u636E" }), /*#__PURE__*/React.createElement("span", { className: classNames("".concat(componentName, "__empty--text")) - }, "\u6682\u65E0\u5339\u914D\u6570\u636E")), !!url && openRoll && /*#__PURE__*/React.createElement("div", { + }, "\u6682\u65E0\u5339\u914D\u6570\u636E")), !!dataSource.length && openRoll && /*#__PURE__*/React.createElement("div", { className: classNames("".concat(componentName, "__scoll-module")) }, /*#__PURE__*/React.createElement(Button, { type: 'default', className: classNames("".concat(componentName, "__scoll-module__btn")), - disabled: !urls[urls.findIndex(function (v) { - return v === showUrl; - }) - 1], + disabled: currentIndex <= 0, onClick: function onClick() { - handlePre(); + handleIndexChange(-1); } }, /*#__PURE__*/React.createElement(Icon, { icon: "icon-qiehuanzuo", @@ -119,24 +111,22 @@ var CompaterImage = function CompaterImage(props) { })), /*#__PURE__*/React.createElement(Button, { type: 'default', className: classNames("".concat(componentName, "__scoll-module__btn")), - disabled: !urls[urls.findIndex(function (v) { - return v === showUrl; - }) + 1], + disabled: currentIndex >= dataSource.length - 1, onClick: function onClick() { - handleNext(); + handleIndexChange(1); } }, /*#__PURE__*/React.createElement(Icon, { icon: "icon-qiehuanyou", size: 40 - }))), !!score && /*#__PURE__*/React.createElement(CornerScore, { - scoreTxt: score + }))), showScore && /*#__PURE__*/React.createElement(CornerScore, { + scoreTxt: dataSource[currentIndex].score }), /*#__PURE__*/React.createElement("div", { className: classNames("".concat(componentName, "__tool")) }, /*#__PURE__*/React.createElement(Button, { type: "text", onClick: function onClick() { - var _imgInsRef$current5, _imgInsRef$current5$s; - imgInsRef === null || imgInsRef === void 0 || (_imgInsRef$current5 = imgInsRef.current) === null || _imgInsRef$current5 === void 0 || (_imgInsRef$current5$s = _imgInsRef$current5.scaleTo) === null || _imgInsRef$current5$s === void 0 || _imgInsRef$current5$s.call(_imgInsRef$current5, 0.1); + var _imgInsRef$current4, _imgInsRef$current4$s; + imgInsRef === null || imgInsRef === void 0 || (_imgInsRef$current4 = imgInsRef.current) === null || _imgInsRef$current4 === void 0 || (_imgInsRef$current4$s = _imgInsRef$current4.scaleTo) === null || _imgInsRef$current4$s === void 0 || _imgInsRef$current4$s.call(_imgInsRef$current4, 0.1); } }, /*#__PURE__*/React.createElement(Icon, { size: 16, @@ -144,8 +134,8 @@ var CompaterImage = function CompaterImage(props) { }), /*#__PURE__*/React.createElement("span", null, '放大')), /*#__PURE__*/React.createElement(Button, { type: "text", onClick: function onClick() { - var _imgInsRef$current6, _imgInsRef$current6$s; - imgInsRef === null || imgInsRef === void 0 || (_imgInsRef$current6 = imgInsRef.current) === null || _imgInsRef$current6 === void 0 || (_imgInsRef$current6$s = _imgInsRef$current6.scaleTo) === null || _imgInsRef$current6$s === void 0 || _imgInsRef$current6$s.call(_imgInsRef$current6, -0.1); + var _imgInsRef$current5, _imgInsRef$current5$s; + imgInsRef === null || imgInsRef === void 0 || (_imgInsRef$current5 = imgInsRef.current) === null || _imgInsRef$current5 === void 0 || (_imgInsRef$current5$s = _imgInsRef$current5.scaleTo) === null || _imgInsRef$current5$s === void 0 || _imgInsRef$current5$s.call(_imgInsRef$current5, -0.1); } }, /*#__PURE__*/React.createElement(Icon, { size: 16, @@ -157,12 +147,12 @@ var CompaterImage = function CompaterImage(props) { }), /*#__PURE__*/React.createElement(Button, { type: "text", onClick: function onClick() { - var _imgInsRef$current7, _imgInsRef$current7$r; - imgInsRef === null || imgInsRef === void 0 || (_imgInsRef$current7 = imgInsRef.current) === null || _imgInsRef$current7 === void 0 || (_imgInsRef$current7$r = _imgInsRef$current7.reset) === null || _imgInsRef$current7$r === void 0 || _imgInsRef$current7$r.call(_imgInsRef$current7); + var _imgInsRef$current6, _imgInsRef$current6$r; + imgInsRef === null || imgInsRef === void 0 || (_imgInsRef$current6 = imgInsRef.current) === null || _imgInsRef$current6 === void 0 || (_imgInsRef$current6$r = _imgInsRef$current6.reset) === null || _imgInsRef$current6$r === void 0 || _imgInsRef$current6$r.call(_imgInsRef$current6); } }, /*#__PURE__*/React.createElement(Icon, { size: 16, icon: 'icon-zhongzhi3' }), /*#__PURE__*/React.createElement("span", null, '重置')))); -}; -export default CompaterImage; \ No newline at end of file +}); +export default CompareImage; \ No newline at end of file diff --git a/packages/meta/es/ImagePreview/components/CornerScore/index.d.ts b/packages/meta/es/CompareImage/components/CornerScore/index.d.ts similarity index 100% rename from packages/meta/es/ImagePreview/components/CornerScore/index.d.ts rename to packages/meta/es/CompareImage/components/CornerScore/index.d.ts diff --git a/packages/meta/es/ImagePreview/components/CornerScore/index.js b/packages/meta/es/CompareImage/components/CornerScore/index.js similarity index 100% rename from packages/meta/es/ImagePreview/components/CornerScore/index.js rename to packages/meta/es/CompareImage/components/CornerScore/index.js diff --git a/packages/meta/src/ImagePreview/components/CornerScore/index.less b/packages/meta/es/CompareImage/components/CornerScore/index.less similarity index 94% rename from packages/meta/src/ImagePreview/components/CornerScore/index.less rename to packages/meta/es/CompareImage/components/CornerScore/index.less index 432e1b2..cb8bf35 100644 --- a/packages/meta/src/ImagePreview/components/CornerScore/index.less +++ b/packages/meta/es/CompareImage/components/CornerScore/index.less @@ -6,7 +6,6 @@ height: 22px; line-height: 22px; text-align: right; - vertical-align: bottom; padding-right: 1px; background-size: 100%; background-image: url('data: image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHAAAAAsCAYAAAC9rDzHAAAByUlEQVR4Xu2cO08DMRCEJy0tlNBCSwmU0EIJLbS0UEILLTX/Fo3kk1AUHrrsjB3dWIoUnZTdvfnOZ6+1mxXGGHsADgEcA9hvnyMAvJ7xiwKrjuoQ0HmDxu8ZMxToAZDQrgAE2gxg6z9xAjwFcAvgoCDumGgKuADeA7iI6vUKqAFyE/KU12U9uMmiGuBr4Ong0bIS4A2Aa234sa4CyFzuPfLqFVABfGg5nv4OFu5BAZAbl4+F62q7fQVAJul3tjtYuCMFwEcATNozDAooAL7ltMVATngS8+kLP54UMzAAjc9VABrFVrgKQIWqRpsBaBRb4SoAFaoabQagUWyFqwBUqGq0GYBGsRWuAlChqtFmABrFVrgKQIWqRpsBaBRb4SoAFaoabVYDZLU1K9EyTApUA2RzyrMp9rgRlBWylIIlFRkmBapnIIuZ0hJmgkc3lQBTzGQEN7mqApjNSwd4VTOQr8yXFDL1IbjtDOTMY/dR1r0+/LZaA1n7yb6/wOsEb+4rlMDYdZR0oSO4uZuYtEkPAO17CP9dA3nCwll3Mlj8iw/nL4ABN/gj8hPAgBsc3KY1kJuTs7Y5yV+B7BBA5nKXrSUsKcGOgJvC/ALSJBp5mBHCFAAAAABJRU5ErkJggg=='); @@ -17,6 +16,6 @@ line-height: 22px; font-size: 12px; vertical-align: middle; - color: rgba(255, 255, 255, 1); + color: rgba(255, 255, 255, 100%); } } diff --git a/packages/meta/lib/ImagePreview/images/emptyImage.png b/packages/meta/es/CompareImage/images/emptyImage.png similarity index 100% rename from packages/meta/lib/ImagePreview/images/emptyImage.png rename to packages/meta/es/CompareImage/images/emptyImage.png diff --git a/packages/meta/lib/ImagePreview/images/percent_background.png b/packages/meta/es/CompareImage/images/percent_background.png similarity index 100% rename from packages/meta/lib/ImagePreview/images/percent_background.png rename to packages/meta/es/CompareImage/images/percent_background.png diff --git a/packages/meta/es/CompareImage/index.d.ts b/packages/meta/es/CompareImage/index.d.ts new file mode 100644 index 0000000..a72b6a9 --- /dev/null +++ b/packages/meta/es/CompareImage/index.d.ts @@ -0,0 +1,3 @@ +import CompareImage from "./CompareImage"; +export type { CompareImageProps } from './CompareImage'; +export default CompareImage; diff --git a/packages/meta/es/CompareImage/index.js b/packages/meta/es/CompareImage/index.js new file mode 100644 index 0000000..7922666 --- /dev/null +++ b/packages/meta/es/CompareImage/index.js @@ -0,0 +1,2 @@ +import CompareImage from "./CompareImage"; +export default CompareImage; \ No newline at end of file diff --git a/packages/meta/src/ImagePreview/index.less b/packages/meta/es/CompareImage/index.less similarity index 100% rename from packages/meta/src/ImagePreview/index.less rename to packages/meta/es/CompareImage/index.less diff --git a/packages/meta/es/ImageEditor/cropper/event.js b/packages/meta/es/ImageEditor/cropper/event.js index c7e0485..c51cbc9 100644 --- a/packages/meta/es/ImageEditor/cropper/event.js +++ b/packages/meta/es/ImageEditor/cropper/event.js @@ -1,6 +1,6 @@ //@ts-nocheck import { addClass, removeClass } from 'rc-util/lib/Dom/class'; -import { addEventlistener, isNumber, get } from '@zhst/func'; +import { addEventListenerWrapper, isNumber, get } from '@zhst/func'; import warn from 'rc-util/lib/warn'; import { getData, getPointer, getOffset, dispatchEvent } from "../utils"; import { @@ -18,12 +18,12 @@ export default { _this$eventHandleList = this.eventHandleList, eventHandleList = _this$eventHandleList === void 0 ? [] : _this$eventHandleList, option = this.option; - var handleCropStart = addEventlistener(container, EVENT_POINTER_DOWN, this.onCropStart.bind(this)); + var handleCropStart = addEventListenerWrapper(container, EVENT_POINTER_DOWN, this.onCropStart.bind(this)); eventHandleList.push(handleCropStart); - var handleCropMove = addEventlistener(element.ownerDocument, EVENT_POINTER_MOVE, this.onCropMove.bind(this)); + var handleCropMove = addEventListenerWrapper(element.ownerDocument, EVENT_POINTER_MOVE, this.onCropMove.bind(this)); eventHandleList.push(handleCropMove); EVENT_POINTER_UP.trim().split(REGEXP_SPACES).forEach(function (eventName) { - var handleCropEnd = addEventlistener(element.ownerDocument, eventName, _this.onCropEnd.bind(_this)); + var handleCropEnd = addEventListenerWrapper(element.ownerDocument, eventName, _this.onCropEnd.bind(_this)); eventHandleList.push(handleCropEnd); }); }, diff --git a/packages/meta/es/ImageEditor/cropper/viewerBridge.js b/packages/meta/es/ImageEditor/cropper/viewerBridge.js index 0b2a340..ab55778 100644 --- a/packages/meta/es/ImageEditor/cropper/viewerBridge.js +++ b/packages/meta/es/ImageEditor/cropper/viewerBridge.js @@ -1,5 +1,5 @@ //@ts-nocheck -import { addEventlistener } from '@zhst/func'; +import { addEventListenerWrapper } from '@zhst/func'; import { EVENT_WHEEL } from "./constants"; import { EVENT_VIEWER_TRANSFORM_CHANGE } from "../viewer/constants"; export default { @@ -13,12 +13,12 @@ export default { if (this.options.viewer) { var viewer = this.options.viewer; //添加缩放事件 - var handleWhele = addEventlistener(container, EVENT_WHEEL, this.onWheel.bind(this)); + var handleWhele = addEventListenerWrapper(container, EVENT_WHEEL, this.onWheel.bind(this)); eventHandleList.push(handleWhele); //添加事件监听 获取limit crop box & 渲染canvas this.onTransformChange(viewer); this.limited = true; - var handleTransformChange = addEventlistener(viewer.element, EVENT_VIEWER_TRANSFORM_CHANGE, function (event) { + var handleTransformChange = addEventListenerWrapper(viewer.element, EVENT_VIEWER_TRANSFORM_CHANGE, function (event) { _this.onTransformChange(viewer); }); eventHandleList.push(handleTransformChange); diff --git a/packages/meta/es/ImageEditor/viewer/event.js b/packages/meta/es/ImageEditor/viewer/event.js index 93f8638..8f41e1e 100644 --- a/packages/meta/es/ImageEditor/viewer/event.js +++ b/packages/meta/es/ImageEditor/viewer/event.js @@ -5,7 +5,7 @@ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key i function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); } function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); } //@ts-nocheck -import { isNumber, get, addEventListener } from '@zhst/func'; +import { isNumber, get, addEventListenerWrapper } from '@zhst/func'; import { addClass, removeClass } from 'rc-util/lib/Dom/class.js'; import guid from 'rc-util/lib/guid'; import warn from 'rc-util/lib/warn'; @@ -33,27 +33,27 @@ export default { //图片事件 var scaleAble = get(options, 'scaleAble', true); if (scaleAble) { - var handleWhele = addEventListener(canvas, EVENT_WHEEL, this.onWheel.bind(this)); + var handleWhele = addEventListenerWrapper(canvas, EVENT_WHEEL, this.onWheel.bind(this)); eventHandleList.push(handleWhele); } var dragAble = get(options, 'dragAble', true); if (dragAble) { - var handleDragStart = addEventListener(canvas, EVENT_POINTER_DOWN, this.onDragStart.bind(this)); - eventHandleList.push(addEventListener); - var handleDragMove = addEventListener(element.ownerDocument, EVENT_POINTER_MOVE, this.onDragMove.bind(this)); + var handleDragStart = addEventListenerWrapper(canvas, EVENT_POINTER_DOWN, this.onDragStart.bind(this)); + eventHandleList.push(addEventListenerWrapper); + var handleDragMove = addEventListenerWrapper(element.ownerDocument, EVENT_POINTER_MOVE, this.onDragMove.bind(this)); eventHandleList.push(handleDragMove); EVENT_POINTER_UP.trim().split(REGEXP_SPACES).forEach(function (eventName) { - var handleDragEnd = addEventListener(element.ownerDocument, eventName, _this.onDragEnd.bind(_this)); + var handleDragEnd = addEventListenerWrapper(element.ownerDocument, eventName, _this.onDragEnd.bind(_this)); eventHandleList.push(handleDragEnd); }); } //rect事件 - var handleClick = addEventListener(canvas, EVENT_CLICK, this.onClick.bind(this)); + var handleClick = addEventListenerWrapper(canvas, EVENT_CLICK, this.onClick.bind(this)); eventHandleList.push(handleClick); - // const handleLeveal = addEventListener(canvas, EVENT_LEAVEL, this.onLeavel.bind(this)); + // const handleLeveal = addEventListenerWrapper(canvas, EVENT_LEAVEL, this.onLeavel.bind(this)); // eventHandleList.push(handleLeveal); - // const handleEnter = addEventListener(canvas, EVENT_ENTER, this.onEnter.bind(this)); + // const handleEnter = addEventListenerWrapper(canvas, EVENT_ENTER, this.onEnter.bind(this)); // eventHandleList.push(handleEnter); }, unbind: function unbind() { diff --git a/packages/meta/es/ImagePreview/index.d.ts b/packages/meta/es/ImagePreview/index.d.ts deleted file mode 100644 index 31fba43..0000000 --- a/packages/meta/es/ImagePreview/index.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { FC } from 'react'; -export interface CompaterImageProps { - url: string; - label: string; - openRoll?: boolean; - urls?: Array; - specialTitle: String; - noTargetImageTip?: string; - score?: number; -} -declare const CompaterImage: FC; -export default CompaterImage; diff --git a/packages/meta/es/VideoPlayer/VideoPlayer.d.ts b/packages/meta/es/VideoPlayer/VideoPlayer.d.ts new file mode 100644 index 0000000..cf56091 --- /dev/null +++ b/packages/meta/es/VideoPlayer/VideoPlayer.d.ts @@ -0,0 +1,18 @@ +import React, { Dispatch, ReactElement, SetStateAction } from 'react'; +import { Rect, IScreenshotButtonProp, AlignType } from '@zhst/types'; +import './index.less'; +export interface VideoViewProps { + url: string; + maxDuration?: number; + screenshotButtonAlign?: AlignType; + screenshotButtonRender?: (screenshotButtonProp: IScreenshotButtonProp) => ReactElement; + defautlNormalizationRect?: Rect; + onCropChange?: (showCrop: boolean, normalizationRect: null | Rect) => void; +} +export interface VideoViewRef { + cropAble: boolean; + setShowCrop: Dispatch>; + downloadVideoframe: () => void; +} +declare const VideoPlayer: React.ForwardRefExoticComponent>; +export default VideoPlayer; diff --git a/packages/meta/es/VideoPlayer/VideoPlayer.js b/packages/meta/es/VideoPlayer/VideoPlayer.js new file mode 100644 index 0000000..119f86f --- /dev/null +++ b/packages/meta/es/VideoPlayer/VideoPlayer.js @@ -0,0 +1,679 @@ +function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } +function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } +function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } +function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } +function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); } +function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); } +function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return e; }; var t, e = {}, r = Object.prototype, n = r.hasOwnProperty, o = Object.defineProperty || function (t, e, r) { t[e] = r.value; }, i = "function" == typeof Symbol ? Symbol : {}, a = i.iterator || "@@iterator", c = i.asyncIterator || "@@asyncIterator", u = i.toStringTag || "@@toStringTag"; function define(t, e, r) { return Object.defineProperty(t, e, { value: r, enumerable: !0, configurable: !0, writable: !0 }), t[e]; } try { define({}, ""); } catch (t) { define = function define(t, e, r) { return t[e] = r; }; } function wrap(t, e, r, n) { var i = e && e.prototype instanceof Generator ? e : Generator, a = Object.create(i.prototype), c = new Context(n || []); return o(a, "_invoke", { value: makeInvokeMethod(t, r, c) }), a; } function tryCatch(t, e, r) { try { return { type: "normal", arg: t.call(e, r) }; } catch (t) { return { type: "throw", arg: t }; } } e.wrap = wrap; var h = "suspendedStart", l = "suspendedYield", f = "executing", s = "completed", y = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var p = {}; define(p, a, function () { return this; }); var d = Object.getPrototypeOf, v = d && d(d(values([]))); v && v !== r && n.call(v, a) && (p = v); var g = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(p); function defineIteratorMethods(t) { ["next", "throw", "return"].forEach(function (e) { define(t, e, function (t) { return this._invoke(e, t); }); }); } function AsyncIterator(t, e) { function invoke(r, o, i, a) { var c = tryCatch(t[r], t, o); if ("throw" !== c.type) { var u = c.arg, h = u.value; return h && "object" == _typeof(h) && n.call(h, "__await") ? e.resolve(h.__await).then(function (t) { invoke("next", t, i, a); }, function (t) { invoke("throw", t, i, a); }) : e.resolve(h).then(function (t) { u.value = t, i(u); }, function (t) { return invoke("throw", t, i, a); }); } a(c.arg); } var r; o(this, "_invoke", { value: function value(t, n) { function callInvokeWithMethodAndArg() { return new e(function (e, r) { invoke(t, n, e, r); }); } return r = r ? r.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); } }); } function makeInvokeMethod(e, r, n) { var o = h; return function (i, a) { if (o === f) throw new Error("Generator is already running"); if (o === s) { if ("throw" === i) throw a; return { value: t, done: !0 }; } for (n.method = i, n.arg = a;;) { var c = n.delegate; if (c) { var u = maybeInvokeDelegate(c, n); if (u) { if (u === y) continue; return u; } } if ("next" === n.method) n.sent = n._sent = n.arg;else if ("throw" === n.method) { if (o === h) throw o = s, n.arg; n.dispatchException(n.arg); } else "return" === n.method && n.abrupt("return", n.arg); o = f; var p = tryCatch(e, r, n); if ("normal" === p.type) { if (o = n.done ? s : l, p.arg === y) continue; return { value: p.arg, done: n.done }; } "throw" === p.type && (o = s, n.method = "throw", n.arg = p.arg); } }; } function maybeInvokeDelegate(e, r) { var n = r.method, o = e.iterator[n]; if (o === t) return r.delegate = null, "throw" === n && e.iterator.return && (r.method = "return", r.arg = t, maybeInvokeDelegate(e, r), "throw" === r.method) || "return" !== n && (r.method = "throw", r.arg = new TypeError("The iterator does not provide a '" + n + "' method")), y; var i = tryCatch(o, e.iterator, r.arg); if ("throw" === i.type) return r.method = "throw", r.arg = i.arg, r.delegate = null, y; var a = i.arg; return a ? a.done ? (r[e.resultName] = a.value, r.next = e.nextLoc, "return" !== r.method && (r.method = "next", r.arg = t), r.delegate = null, y) : a : (r.method = "throw", r.arg = new TypeError("iterator result is not an object"), r.delegate = null, y); } function pushTryEntry(t) { var e = { tryLoc: t[0] }; 1 in t && (e.catchLoc = t[1]), 2 in t && (e.finallyLoc = t[2], e.afterLoc = t[3]), this.tryEntries.push(e); } function resetTryEntry(t) { var e = t.completion || {}; e.type = "normal", delete e.arg, t.completion = e; } function Context(t) { this.tryEntries = [{ tryLoc: "root" }], t.forEach(pushTryEntry, this), this.reset(!0); } function values(e) { if (e || "" === e) { var r = e[a]; if (r) return r.call(e); if ("function" == typeof e.next) return e; if (!isNaN(e.length)) { var o = -1, i = function next() { for (; ++o < e.length;) if (n.call(e, o)) return next.value = e[o], next.done = !1, next; return next.value = t, next.done = !0, next; }; return i.next = i; } } throw new TypeError(_typeof(e) + " is not iterable"); } return GeneratorFunction.prototype = GeneratorFunctionPrototype, o(g, "constructor", { value: GeneratorFunctionPrototype, configurable: !0 }), o(GeneratorFunctionPrototype, "constructor", { value: GeneratorFunction, configurable: !0 }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, u, "GeneratorFunction"), e.isGeneratorFunction = function (t) { var e = "function" == typeof t && t.constructor; return !!e && (e === GeneratorFunction || "GeneratorFunction" === (e.displayName || e.name)); }, e.mark = function (t) { return Object.setPrototypeOf ? Object.setPrototypeOf(t, GeneratorFunctionPrototype) : (t.__proto__ = GeneratorFunctionPrototype, define(t, u, "GeneratorFunction")), t.prototype = Object.create(g), t; }, e.awrap = function (t) { return { __await: t }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, c, function () { return this; }), e.AsyncIterator = AsyncIterator, e.async = function (t, r, n, o, i) { void 0 === i && (i = Promise); var a = new AsyncIterator(wrap(t, r, n, o), i); return e.isGeneratorFunction(r) ? a : a.next().then(function (t) { return t.done ? t.value : a.next(); }); }, defineIteratorMethods(g), define(g, u, "Generator"), define(g, a, function () { return this; }), define(g, "toString", function () { return "[object Generator]"; }), e.keys = function (t) { var e = Object(t), r = []; for (var n in e) r.push(n); return r.reverse(), function next() { for (; r.length;) { var t = r.pop(); if (t in e) return next.value = t, next.done = !1, next; } return next.done = !0, next; }; }, e.values = values, Context.prototype = { constructor: Context, reset: function reset(e) { if (this.prev = 0, this.next = 0, this.sent = this._sent = t, this.done = !1, this.delegate = null, this.method = "next", this.arg = t, this.tryEntries.forEach(resetTryEntry), !e) for (var r in this) "t" === r.charAt(0) && n.call(this, r) && !isNaN(+r.slice(1)) && (this[r] = t); }, stop: function stop() { this.done = !0; var t = this.tryEntries[0].completion; if ("throw" === t.type) throw t.arg; return this.rval; }, dispatchException: function dispatchException(e) { if (this.done) throw e; var r = this; function handle(n, o) { return a.type = "throw", a.arg = e, r.next = n, o && (r.method = "next", r.arg = t), !!o; } for (var o = this.tryEntries.length - 1; o >= 0; --o) { var i = this.tryEntries[o], a = i.completion; if ("root" === i.tryLoc) return handle("end"); if (i.tryLoc <= this.prev) { var c = n.call(i, "catchLoc"), u = n.call(i, "finallyLoc"); if (c && u) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } else if (c) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); } else { if (!u) throw new Error("try statement without catch or finally"); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } } } }, abrupt: function abrupt(t, e) { for (var r = this.tryEntries.length - 1; r >= 0; --r) { var o = this.tryEntries[r]; if (o.tryLoc <= this.prev && n.call(o, "finallyLoc") && this.prev < o.finallyLoc) { var i = o; break; } } i && ("break" === t || "continue" === t) && i.tryLoc <= e && e <= i.finallyLoc && (i = null); var a = i ? i.completion : {}; return a.type = t, a.arg = e, i ? (this.method = "next", this.next = i.finallyLoc, y) : this.complete(a); }, complete: function complete(t, e) { if ("throw" === t.type) throw t.arg; return "break" === t.type || "continue" === t.type ? this.next = t.arg : "return" === t.type ? (this.rval = this.arg = t.arg, this.method = "return", this.next = "end") : "normal" === t.type && e && (this.next = e), y; }, finish: function finish(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.finallyLoc === t) return this.complete(r.completion, r.afterLoc), resetTryEntry(r), y; } }, catch: function _catch(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.tryLoc === t) { var n = r.completion; if ("throw" === n.type) { var o = n.arg; resetTryEntry(r); } return o; } } throw new Error("illegal catch attempt"); }, delegateYield: function delegateYield(e, r, n) { return this.delegate = { iterator: values(e), resultName: r, nextLoc: n }, "next" === this.method && (this.arg = t), y; } }, e; } +function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } +function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } +function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); } +function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } +function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } +function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; } +function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } } +function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } +import React, { forwardRef, useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react'; +import { noop, get, addEventListenerWrapper, dataURLToBlob, nextTick, toRealNumber, getTransforms, formatDurationTime } from '@zhst/func'; +import Align from 'rc-align'; +import { useLatest, useUpdateEffect, useFullscreen, useUnmount } from '@zhst/hooks'; +import classNames from 'classnames'; +import download from 'downloadjs'; +import { Button, message } from 'antd'; +import Icon from "../iconfont"; +import { Cropper, EVENT_CROP_START, EVENT_CROP_END } from "../ImageEditor"; +import FlvPlayer, { FLV_EVENT } from "./components/FlvPlayer"; +import Range from "./components/Progress"; +import Loading from "./components/Loading"; +import getScreenshotButtonRender from "../BigImagePreview/components/ScreenhotButtons"; +import { CROP_TYPE } from "../utils/constants"; +import { getShowStatus } from "./videoPlayerHelper"; +import "./index.less"; +var componentName = "zhst-image__video-view"; +var VideoPlayer = /*#__PURE__*/forwardRef(function (props, ref) { + var url = props.url, + maxDuration = props.maxDuration, + _props$screenshotButt = props.screenshotButtonAlign, + screenshotButtonAlign = _props$screenshotButt === void 0 ? { + points: ['bl', 'br'], + offset: [6, 0], + overflow: { + adjustX: true, + adjustY: true + } + } : _props$screenshotButt, + _props$screenshotButt2 = props.screenshotButtonRender, + screenshotButtonRender = _props$screenshotButt2 === void 0 ? getScreenshotButtonRender({ + onBigImageActionClick: function onBigImageActionClick() {}, + disableBtn: [] + }) : _props$screenshotButt2, + onCropChange = props.onCropChange, + defaultNormalizationRect = props.defautlNormalizationRect; + var videoType = useMemo(function () { + return url && url.startsWith('http') ? 'mp4' : 'flv'; + }, [url]); + // ========================== 播放 ========================= + //实例参数 + var containerRef = useRef(null); //容器ref + var videoRef = useRef(null); //video 标签dom + var videoInsRef = useRef(null); //flv 实例 + var _useState = useState(0), + _useState2 = _slicedToArray(_useState, 2), + playSeq = _useState2[0], + setPlaySeq = _useState2[1]; // 通过重置playid使FLV组件重新渲染 + var videoRemoveListener = useRef(noop); //移除dom监听的中间函数 + var loadingTimeRef = useRef(0); //最后一次加载时间 + var delayLoadingTimer = useRef(null); //算loading的定时器 + //状态参数 + var _useState3 = useState(false), + _useState4 = _slicedToArray(_useState3, 2), + isReady = _useState4[0], + setIsReady = _useState4[1]; // + var _useState5 = useState(false), + _useState6 = _slicedToArray(_useState5, 2), + isPlay = _useState6[0], + setIsPlay = _useState6[1]; //当前是否播放 + + var _useState7 = useState(false), + _useState8 = _slicedToArray(_useState7, 2), + isEnd = _useState8[0], + setIsEnd = _useState8[1]; //是否播放结束 + var _useState9 = useState(false), + _useState10 = _slicedToArray(_useState9, 2), + isError = _useState10[0], + setIsError = _useState10[1]; //播放出错 + var _useState11 = useState(false), + _useState12 = _slicedToArray(_useState11, 2), + isVideoLoadFinished = _useState12[0], + setIsVideoLoadFinish = _useState12[1]; //是否缓存加载完成 + var _useState13 = useState(0), + _useState14 = _slicedToArray(_useState13, 2), + playTime = _useState14[0], + setPlayTime = _useState14[1]; //当前播放时间 + var _useState15 = useState(true), + _useState16 = _slicedToArray(_useState15, 2), + isLoadingVideo = _useState16[0], + setIsLoadingVideo = _useState16[1]; //是否加载中 + var _useState17 = useState(false), + _useState18 = _slicedToArray(_useState17, 2), + isDelayLoading = _useState18[0], + setIsDelayLoading = _useState18[1]; //显示的转圈loading 延迟0.2s显示 + //设置延迟转圈圈 + var latestIsLoadingVideo = useLatest(isLoadingVideo); + var setIsLoadingVideoWrapper = function setIsLoadingVideoWrapper(isLoading) { + setIsLoadingVideo(function (preLoading) { + if (!preLoading && isLoading) { + loadingTimeRef.current = new Date().getTime(); + } + if (!isLoading) { + loadingTimeRef.current = null; + } + //延迟0。2s相关 + if (!isLoading) { + setIsDelayLoading(false); + } + if (!delayLoadingTimer.current && preLoading) { + delayLoadingTimer.current = setTimeout(function () { + if (latestIsLoadingVideo.current) { + //0.2s后才显示 + setIsDelayLoading(true); + } + delayLoadingTimer.current = null; + }, 200); + } + return isLoading; + }); + }; + // 初始化loading 30s 直接显示错误 + // TODO :逻辑忘记了 不应该是每次init player吗? + useEffect(function () { + var timer = setInterval(function () { + if (loadingTimeRef.current) { + if (new Date().getTime() - loadingTimeRef.current > 1000 * 30) { + checkIsErr(); + } + } + }, 1000); + return function () { + clearInterval(timer); + }; + }, []); + + //结束的时候暂停 保证不播了 + useUpdateEffect(function () { + if (isEnd) { + var _videoInsRef$current, _videoInsRef$current$; + videoInsRef === null || videoInsRef === void 0 || (_videoInsRef$current = videoInsRef.current) === null || _videoInsRef$current === void 0 || (_videoInsRef$current$ = _videoInsRef$current.pause) === null || _videoInsRef$current$ === void 0 || _videoInsRef$current$.call(_videoInsRef$current); + } + }, [isEnd]); + + // 捕捉视频播放报错 + var checkIsErr = function checkIsErr() { + setIsError(true); + try { + var _videoInsRef$current2, _videoInsRef$current3; + videoInsRef === null || videoInsRef === void 0 || (_videoInsRef$current2 = videoInsRef.current) === null || _videoInsRef$current2 === void 0 || (_videoInsRef$current3 = _videoInsRef$current2.destroy) === null || _videoInsRef$current3 === void 0 || _videoInsRef$current3.call(_videoInsRef$current2); + } catch (error) { + console.error(error); + } + }; + + // 初始化 + var latestMaxDuration = useLatest(maxDuration); + var initPlayer = useCallback(function (ins, dom) { + videoRef.current = dom; + videoInsRef.current = ins; + var maxDuration = latestMaxDuration.current || 0; + //监听播放事件 + var video = dom; + var errorLister = function errorLister(e) { + checkIsErr(); + console.error('视频出错了', e, video.currentTime); + }; + var waitingListener = function waitingListener(e) { + setIsLoadingVideoWrapper(true); + console.debug('视频加载等待', e, video.currentTime); + }; + var playingListener = function playingListener(e) { + setIsLoadingVideoWrapper(false); + setIsError(false); + console.debug('视频从等待中播放', e, video.currentTime); + }; + var playLister = function playLister(e) { + setIsPlay(true); + setIsError(false); + console.debug('提示该视频正在播放中', e, video.currentTime); + }; + var pauseListener = function pauseListener(e) { + setIsPlay(false); + console.debug('暂停播放', e, video.currentTime); + }; + var endedListner = function endedListner(e) { + setIsEnd(true); + setIsVideoLoadFinish(true); + console.debug('视频播放完了', e, video.currentTime); + }; + var timeupdateListner = function timeupdateListner(e) { + var _videoRef$current; + console.debug('视频播放时间更新', e, video.currentTime, (_videoRef$current = videoRef.current) === null || _videoRef$current === void 0 ? void 0 : _videoRef$current.duration, maxDuration); + var nowTime = video.currentTime; + if (nowTime >= maxDuration) { + setIsEnd(true); + setIsVideoLoadFinish(true); + } + setPlayTime(nowTime); + }; + // see https://github.com/bilibili/flv.js/issues/337 + var windowErrorHandle = function windowErrorHandle(errorEvent) { + try { + if (errorEvent['message'] == "Uncaught TypeError: Cannot read property 'flushStashedSamples' of null") { + checkIsErr(); + console.error('视频出错了 window监听', errorEvent); + } + } catch (error) { + console.error(error); + } + }; + video.addEventListener('error', errorLister); + video.addEventListener('waiting', waitingListener); + video.addEventListener('playing', playingListener); + video.addEventListener('play', playLister); + video.addEventListener('pause', pauseListener); + video.addEventListener('ended', endedListner); + video.addEventListener('timeupdate', timeupdateListner); + window.addEventListener('error', windowErrorHandle); + videoRemoveListener.current = function () { + video.removeEventListener('error', errorLister); + video.removeEventListener('waiting', waitingListener); + video.removeEventListener('playing', playingListener); + video.removeEventListener('play', playLister); + video.removeEventListener('pause', pauseListener); + video.removeEventListener('ended', endedListner); + video.removeEventListener('timeupdate', timeupdateListner); + window.removeEventListener('error', windowErrorHandle); + }; + videoInsRef === null || videoInsRef === void 0 || videoInsRef.current.on(FLV_EVENT.ERROR, function (type, errDetail, info) { + checkIsErr(); + console.error('videoInsRef 错误', type, errDetail, info, video.currentTime); + }); + var playPromise = videoInsRef === null || videoInsRef === void 0 ? void 0 : videoInsRef.current.play(); + //先ready 遮挡会导致播放失败 + setIsReady(true); + playPromise.then(function () { + setIsReady(true); + }).catch(function () { + try {} catch (error) {} + // setIsError(true); + for (var _len = arguments.length, arg = new Array(_len), _key = 0; _key < _len; _key++) { + arg[_key] = arguments[_key]; + } + console.error('playPromise视频出错了', arg); + }); + }, []); + useUnmount(function () { + try { + videoRemoveListener.current(); + } catch (e) { + console.error(e); + } + }); + var _reload = /*#__PURE__*/function () { + var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee() { + var oldTime; + return _regeneratorRuntime().wrap(function _callee$(_context) { + while (1) switch (_context.prev = _context.next) { + case 0: + if (!videoInsRef.current) { + _context.next = 15; + break; + } + oldTime = videoInsRef.current.currentTime; + videoInsRef.current.currentTime = 0; + + //如果修改时间不成功,则走重新加载的逻辑 + if (!(oldTime === videoInsRef.current.currentTime)) { + _context.next = 14; + break; + } + //重置状态 + setIsReady(false); + setIsPlay(false); + setIsLoadingVideoWrapper(false); + setIsReady(false); + setIsEnd(false); + setIsVideoLoadFinish(false); + setPlayTime(0); + + //清楚dom事件监听 + try { + videoRemoveListener.current(); + } catch (error) { + console.error(error); + } + setPlaySeq(function (pre) { + return pre + 1; + }); + return _context.abrupt("return"); + case 14: + videoInsRef.current.play(); + case 15: + setPlayTime(0); + setIsEnd(false); + case 17: + case "end": + return _context.stop(); + } + }, _callee); + })); + return function reload() { + return _ref.apply(this, arguments); + }; + }(); + var seek = function seek(v) { + if (videoInsRef.current && isVideoLoadFinished) { + setPlayTime(parseFloat(v)); + videoInsRef.current.currentTime = parseFloat(v); + } else { + message.warning('待视频加载完,才可操作进度条'); + } + }; + // ========================== 视频opt bar ========================= + var _useFullscreen = useFullscreen(containerRef, { + pageFullscreen: true + }), + _useFullscreen2 = _slicedToArray(_useFullscreen, 2), + isFullscreen = _useFullscreen2[0], + toggleFullscreen = _useFullscreen2[1].toggleFullscreen; + var showMaxDuration = !!maxDuration ? maxDuration : toRealNumber(get(videoRef, 'current.duration', 0)); + var showSlider = videoInsRef.current && isVideoLoadFinished; + var showStatus = getShowStatus(isDelayLoading, isEnd, isError); + + // ========================== 截图 ========================= + var corpContainerRef = useRef(); + var cropInsRef = useRef(null); + var _useState19 = useState(false), + _useState20 = _slicedToArray(_useState19, 2), + showCrop = _useState20[0], + _setShowCrop = _useState20[1]; + + //回显默认框选 + var isFirstFlagRef = useRef(true); + useEffect(function () { + var isFirst = isFirstFlagRef.current; + if (!isLoadingVideo && isReady && isFirst && defaultNormalizationRect && !showStatus) { + nextTick(function () { + _setShowCrop(true); + }); + } + }, [isLoadingVideo, showStatus]); + + //定位按钮相关参数 + var alginContainerRef = useRef(null); + var alignRef = useRef(null); + var _useState21 = useState(null), + _useState22 = _slicedToArray(_useState21, 2), + cropRect = _useState22[0], + setCropRect = _useState22[1]; + useEffect(function () { + var _videoInsRef$current4, _videoInsRef$current5; + showCrop ? videoInsRef === null || videoInsRef === void 0 || (_videoInsRef$current4 = videoInsRef.current) === null || _videoInsRef$current4 === void 0 ? void 0 : _videoInsRef$current4.pause() : videoInsRef === null || videoInsRef === void 0 || (_videoInsRef$current5 = videoInsRef.current) === null || _videoInsRef$current5 === void 0 ? void 0 : _videoInsRef$current5.play(); + }, [showCrop]); + useEffect(function () { + var handlerCropStart; + var handlerCropEnd; + setCropRect(null); + if (!isReady) return; + if (showCrop) { + var _canvas$parentNode; + handlerCropStart = addEventListenerWrapper(corpContainerRef.current, EVENT_CROP_START, function () { + setCropRect(null); + }); + handlerCropEnd = addEventListenerWrapper(corpContainerRef.current, EVENT_CROP_END, function (event) { + var _alignRef$current, _alignRef$current$for; + var data = event.detail; + setCropRect({ + x: data.left, + y: data.top, + w: data.width, + h: data.height + }); + alignRef === null || alignRef === void 0 || (_alignRef$current = alignRef.current) === null || _alignRef$current === void 0 || (_alignRef$current$for = _alignRef$current.forceAlign) === null || _alignRef$current$for === void 0 || _alignRef$current$for.call(_alignRef$current); + }); + var video = videoRef.current; + //计算 limitcroppbox + var scale = Math.min(video.offsetWidth / video.videoWidth, video.offsetHeight / video.videoHeight); + var finalVideoWidth = video.videoWidth * scale; + var finalVideoHeight = video.videoHeight * scale; + var cropBoxLimited = { + width: finalVideoWidth, + height: finalVideoHeight, + top: (video.offsetHeight - finalVideoHeight) / 2, + left: (video.offsetWidth - finalVideoWidth) / 2 + }; + //获取视频图片 + var canvas = document.createElement('canvas'); + canvas.width = video.offsetWidth; + canvas.height = video.offsetHeight; + canvas.style.display = 'none'; + document.body.appendChild(canvas); + var ctx = canvas.getContext('2d'); + ctx === null || ctx === void 0 || ctx.drawImage(video, (video.offsetWidth - finalVideoWidth) / 2, (video.offsetHeight - finalVideoHeight) / 2, finalVideoWidth, finalVideoHeight); + var imageData = canvas.toDataURL('image/png'); + (_canvas$parentNode = canvas.parentNode) === null || _canvas$parentNode === void 0 || _canvas$parentNode.removeChild(canvas); + //回显编辑框 + var isFirst = isFirstFlagRef.current; + var initialCropBoxData = null; + if (isFirst && defaultNormalizationRect) { + initialCropBoxData = { + left: defaultNormalizationRect.x * finalVideoWidth + cropBoxLimited.left, + top: defaultNormalizationRect.y * finalVideoHeight + cropBoxLimited.top, + width: defaultNormalizationRect.w * finalVideoWidth, + height: defaultNormalizationRect.h * finalVideoHeight + }; + } + isFirstFlagRef.current = false; + cropInsRef.current = new Cropper(corpContainerRef.current, { + showMask: true, + cropBoxLimited: cropBoxLimited, + img: imageData, + initialCropBoxData: initialCropBoxData + }); + } + return function () { + var _handlerCropStart, _handlerCropEnd, _cropInsRef$current, _cropInsRef$current$d; + (_handlerCropStart = handlerCropStart) === null || _handlerCropStart === void 0 || _handlerCropStart.remove(); + (_handlerCropEnd = handlerCropEnd) === null || _handlerCropEnd === void 0 || _handlerCropEnd.remove(); + cropInsRef === null || cropInsRef === void 0 || (_cropInsRef$current = cropInsRef.current) === null || _cropInsRef$current === void 0 || (_cropInsRef$current$d = _cropInsRef$current.destroy) === null || _cropInsRef$current$d === void 0 || _cropInsRef$current$d.call(_cropInsRef$current); + cropInsRef.current = null; + }; + }, [showCrop, isReady]); + var latestCropRect = useLatest(cropRect); + var getCropInfo = /*#__PURE__*/function () { + var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3() { + var _canvas$parentNode2; + var cropRect, video, rectList, extendRectList, selectIndex, scale, finalVideoWidth, finalVideoHeight, canvas, ctx, base64, blobData, file, newRect; + return _regeneratorRuntime().wrap(function _callee3$(_context3) { + while (1) switch (_context3.prev = _context3.next) { + case 0: + cropRect = latestCropRect.current; + video = videoRef.current; + if (video) { + _context3.next = 4; + break; + } + return _context3.abrupt("return"); + case 4: + rectList = []; + extendRectList = []; + selectIndex = 0; //获取视频图片的url + scale = Math.min(video.offsetWidth / video.videoWidth, video.offsetHeight / video.videoHeight); + finalVideoWidth = video.videoWidth * scale; + finalVideoHeight = video.videoHeight * scale; + canvas = document.createElement('canvas'); + canvas.width = finalVideoWidth; + canvas.height = finalVideoHeight; + canvas.style.display = 'none'; + document.body.appendChild(canvas); + ctx = canvas.getContext('2d'); + ctx.drawImage(video, 0, 0, finalVideoWidth, finalVideoHeight); + base64 = canvas.toDataURL('image/jpeg'); + blobData = dataURLToBlob(base64); + (_canvas$parentNode2 = canvas.parentNode) === null || _canvas$parentNode2 === void 0 || _canvas$parentNode2.removeChild(canvas); + file = new window.File([blobData], "".concat(new Date().getTime())); + newRect = { + w: cropRect.w / finalVideoWidth, + h: cropRect.h / finalVideoHeight, + x: (cropRect.x - (video.offsetWidth - finalVideoWidth) / 2) / finalVideoWidth, + y: (cropRect.y - (video.offsetHeight - finalVideoHeight) / 2) / finalVideoHeight + }; + rectList.push(newRect); + extendRectList.push(newRect); + //扩展框获取imgkey + extendRectList.forEach( /*#__PURE__*/function () { + var _ref3 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2(rect, index) { + return _regeneratorRuntime().wrap(function _callee2$(_context2) { + while (1) switch (_context2.prev = _context2.next) { + case 0: + extendRectList[index] = _objectSpread({}, rect); + case 1: + case "end": + return _context2.stop(); + } + }, _callee2); + })); + return function (_x, _x2) { + return _ref3.apply(this, arguments); + }; + }()); + return _context3.abrupt("return", { + rectList: rectList, + extendRectList: extendRectList, + selectIndex: selectIndex, + file: file + }); + case 26: + case "end": + return _context3.stop(); + } + }, _callee3); + })); + return function getCropInfo() { + return _ref2.apply(this, arguments); + }; + }(); + + //回调 + useEffect(function () { + //计算归一化crop rect + var normalizationRect = null; + if (showCrop && cropRect) { + var video = videoRef.current; + var scale = Math.min(video.offsetWidth / video.videoWidth, video.offsetHeight / video.videoHeight); + var finalVideoWidth = video.videoWidth * scale; + var finalVideoHeight = video.videoHeight * scale; + var cropBoxLimited = { + width: finalVideoWidth, + height: finalVideoHeight, + top: (video.offsetHeight - finalVideoHeight) / 2, + left: (video.offsetWidth - finalVideoWidth) / 2 + }; + normalizationRect = { + x: (cropRect.x - cropBoxLimited.left) / cropBoxLimited.width, + y: (cropRect.y - cropBoxLimited.top) / cropBoxLimited.height, + w: cropRect.w / cropBoxLimited.width, + h: cropRect.h / cropBoxLimited.height + }; + } + onCropChange === null || onCropChange === void 0 || onCropChange(showCrop, normalizationRect); + }, [showCrop, cropRect]); + + // ========================== 截帧 ========================= + var downloadVideoframe = useCallback( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee4() { + var _videoInsRef$current6, _videoInsRef$current7, video, canvas, ctx, base64; + return _regeneratorRuntime().wrap(function _callee4$(_context4) { + while (1) switch (_context4.prev = _context4.next) { + case 0: + try { + videoInsRef === null || videoInsRef === void 0 || (_videoInsRef$current6 = videoInsRef.current) === null || _videoInsRef$current6 === void 0 || (_videoInsRef$current7 = _videoInsRef$current6.pause) === null || _videoInsRef$current7 === void 0 || _videoInsRef$current7.call(_videoInsRef$current6); + video = videoRef.current; + canvas = document.createElement('canvas'); + ctx = canvas.getContext('2d'); + //当视频处于还未加载出来时,截屏为黑色图片 + if (video.readyState === 0) { + ctx === null || ctx === void 0 || ctx.clearRect(0, 0, canvas.width, canvas.height); + canvas.width = video.offsetWidth; + canvas.height = video.offsetHeight; + // @ts-ignore + ctx.fillStyle = 'black'; + ctx === null || ctx === void 0 || ctx.fillRect(0, 0, canvas.width, canvas.height); + base64 = canvas.toDataURL(); + } else { + canvas.width = video.videoWidth; + canvas.height = video.videoHeight; + ctx === null || ctx === void 0 || ctx.drawImage(video, 0, 0, canvas.width, canvas.height); + base64 = canvas.toDataURL('image/png'); + } + download(base64); + } catch (error) { + console.error(error); + } + case 1: + case "end": + return _context4.stop(); + } + }, _callee4); + })), []); + + // ============================== 暴露出去的方法 =============================== + var latestIsReady = useLatest(isReady); + var cropAble = !showStatus && isReady; + useImperativeHandle(ref, function () { + return { + cropAble: cropAble, + setShowCrop: function setShowCrop(dispatch) { + var isReady = latestIsReady.current; + if (!isReady) return; + _setShowCrop(dispatch); + }, + downloadVideoframe: downloadVideoframe + }; + }); + return /*#__PURE__*/React.createElement("div", { + className: classNames("".concat(componentName)), + ref: containerRef + }, url && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(FlvPlayer, { + playId: playSeq, + autoPlay: true, + className: classNames("".concat(componentName, "-flv")), + type: videoType, + url: url, + config: { + enableStashBuffer: true, + stashInitialSize: 1024 * 700, + isLive: true, + hasAudio: false, + hasVideo: true + }, + onCreat: initPlayer + }), /*#__PURE__*/React.createElement("div", { + className: classNames("".concat(componentName, "-crop-container")), + ref: corpContainerRef, + style: { + display: isFullscreen ? 'none' : 'block' + } + }), showCrop && cropRect && screenshotButtonRender && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", { + ref: alginContainerRef, + className: classNames("".concat(componentName, "-align")), + style: Object.assign({ + width: cropRect.w, + height: cropRect.h + }, getTransforms({ + translateX: cropRect.x, + translateY: cropRect.y + })) + }), /*#__PURE__*/React.createElement(Align, { + ref: alignRef, + monitorWindowResize: true, + align: screenshotButtonAlign, + target: function target() { + return alginContainerRef.current; + } + }, screenshotButtonRender({ + model: 'IMAGE', + getCropInfo: getCropInfo, + setShowCrop: _setShowCrop, + cropType: CROP_TYPE['CUSTOM'] + }))), !showCrop && /*#__PURE__*/React.createElement("div", { + className: "".concat(componentName, "-opt") + }, /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(Button, { + type: "text", + onClick: function onClick(e) { + if (!isPlay) { + var _videoInsRef$current8; + //播放中暂停 + videoInsRef === null || videoInsRef === void 0 || (_videoInsRef$current8 = videoInsRef.current) === null || _videoInsRef$current8 === void 0 || _videoInsRef$current8.play(); + _setShowCrop(false); + } else { + var _videoInsRef$current9; + videoInsRef === null || videoInsRef === void 0 || (_videoInsRef$current9 = videoInsRef.current) === null || _videoInsRef$current9 === void 0 || _videoInsRef$current9.pause(); + } + } + }, /*#__PURE__*/React.createElement(Icon, { + styles: { + color: '#fff', + display: 'flex' + }, + color: "#1890ff", + icon: !isPlay ? 'icon-shipinbofang' : 'icon-shipinzanting' + }))), /*#__PURE__*/React.createElement("div", { + className: "".concat(componentName, "-opt-range"), + onClick: function onClick(e) { + e.stopPropagation(); + } + }, /*#__PURE__*/React.createElement(Range, { + value: playTime, + min: 0, + max: showMaxDuration, + showSlider: showSlider, + onChange: seek + }), /*#__PURE__*/React.createElement("div", null, formatDurationTime(playTime), "/", formatDurationTime(showMaxDuration))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(Button, { + type: "text", + onClick: function onClick(e) { + e.stopPropagation(); + toggleFullscreen(); + } + }, /*#__PURE__*/React.createElement(Icon, { + styles: { + color: '#fff', + display: 'flex' + }, + size: 18, + icon: isFullscreen ? 'icon-cancle_fullscreen' : 'icon-fullscreen' + })))), !!showStatus && /*#__PURE__*/React.createElement(Loading, { + status: showStatus, + reload: function reload() { + return _reload(); + } + }))); +}); +export default VideoPlayer; \ No newline at end of file diff --git a/packages/meta/es/VideoPlayer/components/FlvPlayer/index.d.ts b/packages/meta/es/VideoPlayer/components/FlvPlayer/index.d.ts new file mode 100644 index 0000000..646b267 --- /dev/null +++ b/packages/meta/es/VideoPlayer/components/FlvPlayer/index.d.ts @@ -0,0 +1,46 @@ +import React, { Component, CSSProperties } from 'react'; +import flvjs from 'flv.js'; +export declare const FLV_EVENT: Readonly; +export interface VideoPlayerProps { + className: string; + style?: CSSProperties; + type: string; + isLive?: boolean; + cors?: boolean; + withCredentials?: boolean; + playId?: number; + hasAudio?: boolean; + hasVideo?: boolean; + duration?: number; + filesize?: number; + url?: string; + autoPlay?: boolean; + onCreat?: any; + /** + * @see https://github.com/Bilibili/flv.js/blob/master/docs/api.md#config + */ + config: object; +} +export default class VideoPlayer extends Component { + state: { + curPlayUrl: string; + shouldReinit: boolean; + }; + flvPlayer: any; + videoElement: null; + static getDerivedStateFromProps: (nextProps: { + url?: any; + playId?: any; + }, prevState: { + curPlayUrl?: any; + playId?: any; + }) => { + playId: any; + curPlayUrl: any; + shouldReinit: boolean; + } | null; + initFlv: ($video: null) => void; + componentWillUnmount(): void; + componentDidUpdate(): void; + render(): React.JSX.Element; +} diff --git a/packages/meta/es/VideoPlayer/components/FlvPlayer/index.js b/packages/meta/es/VideoPlayer/components/FlvPlayer/index.js new file mode 100644 index 0000000..8514dcd --- /dev/null +++ b/packages/meta/es/VideoPlayer/components/FlvPlayer/index.js @@ -0,0 +1,152 @@ +var _excluded = ["className", "autoPlay", "config", "onCreat", "playId"]; +function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } +function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } +function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } +function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; } +function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } +function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } } +function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); } +function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } +function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } +function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); } +function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } +function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } +function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } +function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } +function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); } +function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); } +import React, { Component } from 'react'; +import flvjs from 'flv.js'; +import { isEqual } from '@zhst/func'; +export var FLV_EVENT = flvjs.Events; +var VideoPlayer = /*#__PURE__*/function (_Component) { + _inherits(VideoPlayer, _Component); + var _super = _createSuper(VideoPlayer); + function VideoPlayer() { + var _this; + _classCallCheck(this, VideoPlayer); + for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + _this = _super.call.apply(_super, [this].concat(args)); + _defineProperty(_assertThisInitialized(_this), "state", { + curPlayUrl: '', + shouldReinit: false + }); + _defineProperty(_assertThisInitialized(_this), "flvPlayer", null); + _defineProperty(_assertThisInitialized(_this), "videoElement", null); + _defineProperty(_assertThisInitialized(_this), "initFlv", function ($video) { + _this.videoElement = $video; + var _this$props = _this.props, + className = _this$props.className, + _this$props$autoPlay = _this$props.autoPlay, + autoPlay = _this$props$autoPlay === void 0 ? true : _this$props$autoPlay, + _this$props$config = _this$props.config, + config = _this$props$config === void 0 ? {} : _this$props$config, + onCreat = _this$props.onCreat, + playId = _this$props.playId, + others = _objectWithoutProperties(_this$props, _excluded); + if ($video) { + if (flvjs.isSupported() && _this.props.url && _this.props.url) { + var reload = function reload() { + if (_this.flvPlayer && _this.flvPlayer.destroy) { + try { + _this.flvPlayer.destroy(); + } catch (error) { + console.error(error); + } + } + var flvPlayer = flvjs.createPlayer(_objectSpread({}, others), _objectSpread({ + deferLoadAfterSourceOpen: false + }, config)); + flvPlayer.attachMediaElement($video); + flvPlayer.load(); + _this.flvPlayer = flvPlayer; + // @ts-ignore + var controller = _this.flvPlayer._transmuxer._controller; + var wsLoader = controller._ioctl._loader; + var oldWsOnCompleteFunc = wsLoader._onComplete; + wsLoader._onComplete = function () { + if (!controller._remuxer) { + controller._remuxer = { + destroy: function destroy() { + console.log('组件销毁'); + }, + flushStashedSamples: function flushStashedSamples() { + console.log("flushStashedSamples"); + } + }; + } + oldWsOnCompleteFunc(); + }; + _this.flvPlayer.reload = reload; + onCreat && onCreat(_this.flvPlayer, $video); + }; + reload(); + onCreat && onCreat(_this.flvPlayer, $video); + } + } + }); + return _this; + } + _createClass(VideoPlayer, [{ + key: "componentWillUnmount", + value: function componentWillUnmount() { + if (this.flvPlayer) { + var _this$flvPlayer, _this$flvPlayer2; + (_this$flvPlayer = this.flvPlayer) === null || _this$flvPlayer === void 0 || _this$flvPlayer.unload(); + (_this$flvPlayer2 = this.flvPlayer) === null || _this$flvPlayer2 === void 0 || _this$flvPlayer2.detachMediaElement(); + } + } + }, { + key: "componentDidUpdate", + value: function componentDidUpdate() { + if (this.state.shouldReinit) { + this.setState({ + shouldReinit: false + }); + this.initFlv(this.videoElement); + } + } + }, { + key: "render", + value: function render() { + var _this$props2 = this.props, + className = _this$props2.className, + style = _this$props2.style; + return /*#__PURE__*/React.createElement("video", { + muted: true, + preload: "metadata", + className: className + // controls={true} + , + style: Object.assign({ + width: '100%', + height: '100%' + }, style ? style : {}), + ref: this.initFlv + }); + } + }]); + return VideoPlayer; +}(Component); +_defineProperty(VideoPlayer, "getDerivedStateFromProps", function (nextProps, prevState) { + var _nextProps$playId = nextProps.playId, + playId = _nextProps$playId === void 0 ? 0 : _nextProps$playId; + var _prevState$playId = prevState.playId, + prePlayId = _prevState$playId === void 0 ? 0 : _prevState$playId; + if (nextProps.url !== undefined) { + if (!isEqual(nextProps.url, prevState.curPlayUrl) || !isEqual(playId, prePlayId)) { + return { + playId: playId, + curPlayUrl: nextProps.url, + shouldReinit: true + }; + } + } + // 否则,对于state不进行任何操作 + return null; +}); +export { VideoPlayer as default }; \ No newline at end of file diff --git a/packages/meta/es/VideoPlayer/components/Loading/index.d.ts b/packages/meta/es/VideoPlayer/components/Loading/index.d.ts new file mode 100644 index 0000000..1509947 --- /dev/null +++ b/packages/meta/es/VideoPlayer/components/Loading/index.d.ts @@ -0,0 +1,8 @@ +import { FC } from 'react'; +import './index.less'; +export interface ILoading { + status: 'LOADING' | 'COMPLETED' | 'END' | 'ERROR' | null; + reload: () => void; +} +declare const Loading: FC; +export default Loading; diff --git a/packages/meta/es/VideoPlayer/components/Loading/index.js b/packages/meta/es/VideoPlayer/components/Loading/index.js new file mode 100644 index 0000000..d7d18b6 --- /dev/null +++ b/packages/meta/es/VideoPlayer/components/Loading/index.js @@ -0,0 +1,46 @@ +import React from 'react'; +import { Spin } from 'antd'; +import classNames from 'classnames'; +import Icon from "../../../iconfont"; +import "./index.less"; +var componentName = "zhst-image__video-view"; +var Loading = function Loading(props) { + var status = props.status, + reload = props.reload; + return /*#__PURE__*/React.createElement("div", { + className: classNames("".concat(componentName, "__player-mask")), + onClick: function onClick(e) { + e.stopPropagation(); + } + }, status === 'LOADING' && /*#__PURE__*/React.createElement(Spin, { + tip: "\u52A0\u8F7D\u4E2D...", + spinning: status === 'LOADING' + }), status === 'END' && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", { + onClick: function onClick() { + reload(); + }, + className: classNames("".concat(componentName, "__icon-wraper")) + }, /*#__PURE__*/React.createElement(Icon, { + styles: { + fill: '#ffffff', + color: '#ffffff' + }, + size: 54, + icon: 'icon-shuaxin' + })), /*#__PURE__*/React.createElement("div", { + className: classNames("".concat(componentName, "__player-mask-title")) + }, '点击刷新后,将重新播放')), status === 'ERROR' && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", { + className: classNames("".concat(componentName, "__icon-wraper")) + }, /*#__PURE__*/React.createElement(Icon, { + styles: { + color: '#ffffff' + }, + size: 54, + icon: 'icon-jiazaishibai' + })), /*#__PURE__*/React.createElement("div", { + className: classNames("".concat(componentName, "__player-mask-title")) + }, '视频加载失败,', /*#__PURE__*/React.createElement("a", { + onClick: reload + }, " ", '刷新')))); +}; +export default Loading; \ No newline at end of file diff --git a/packages/meta/es/VideoPlayer/components/Loading/index.less b/packages/meta/es/VideoPlayer/components/Loading/index.less new file mode 100644 index 0000000..b6c11a2 --- /dev/null +++ b/packages/meta/es/VideoPlayer/components/Loading/index.less @@ -0,0 +1,53 @@ +.zhst-image__video-view__player-mask { + position: absolute; + width: 100%; + height: 100%; + z-index: 99; + top: 0; + right: 0; + bottom: 0; + left: 0; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + background-color: rgb(4 4 4 / 70%); + + &--bg { + z-index: 999; + background-color: rgb(4 4 4 / 100%); + } + + i { + cursor: pointer; + } + + &-title { + margin-top: 12px; + color: #fff; + text-align: center; + + & a { + color: #09f; + cursor: pointer; + text-decoration: underline; + } + } +} + +.zhst-image__video-view__icon-wraper { + display: flex; + width: 80px; + height: 80px; + align-items: center; + justify-content: center; + background-color: rgb(255 255 255 / 10%); + border-radius: 50%; + cursor: pointer; + line-height: 80px; + text-align: center; + + // &:hover { + // background: #0099ff; + // } +} diff --git a/packages/meta/es/VideoPlayer/components/Progress/index.d.ts b/packages/meta/es/VideoPlayer/components/Progress/index.d.ts new file mode 100644 index 0000000..7fb0a10 --- /dev/null +++ b/packages/meta/es/VideoPlayer/components/Progress/index.d.ts @@ -0,0 +1,10 @@ +import React from 'react'; +import type { SliderSingleProps } from 'antd'; +import './index.less'; +export interface RangeWrapperProps extends SliderSingleProps { + showSlider: boolean; + className?: string; + min: number; +} +export declare const Range: React.FC; +export default Range; diff --git a/packages/meta/es/VideoPlayer/components/Progress/index.js b/packages/meta/es/VideoPlayer/components/Progress/index.js new file mode 100644 index 0000000..0eeb850 --- /dev/null +++ b/packages/meta/es/VideoPlayer/components/Progress/index.js @@ -0,0 +1,20 @@ +var _excluded = ["className", "style", "showSlider"]; +function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; } +function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } +import React from 'react'; +import classNames from 'classnames'; +import { Slider } from 'antd'; +import "./index.less"; +var componentName = "zhst-image__range"; +export var Range = function Range(props) { + var className = props.className, + style = props.style, + _props$showSlider = props.showSlider, + showSlider = _props$showSlider === void 0 ? true : _props$showSlider, + others = _objectWithoutProperties(props, _excluded); + return /*#__PURE__*/React.createElement("div", { + style: style, + className: classNames("".concat(componentName), !showSlider && "".concat(componentName, "--no-slider"), className) + }, /*#__PURE__*/React.createElement(Slider, others)); +}; +export default Range; \ No newline at end of file diff --git a/packages/meta/es/VideoPlayer/components/Progress/index.less b/packages/meta/es/VideoPlayer/components/Progress/index.less new file mode 100644 index 0000000..e922211 --- /dev/null +++ b/packages/meta/es/VideoPlayer/components/Progress/index.less @@ -0,0 +1,49 @@ +.zhst-image__range { + position: relative; + + &--no-slider { + .next-range-slider { + display: none; + } + } + + & .next-range .next-range-track { + height: 8px; + margin-top: -4px; + border-radius: 8px; + } + + & .next-range .next-range-selected { + height: 8px; + margin-top: -4px; + border-radius: 8px; + } + + & .next-range .next-range-slider-inner { + width: 14px; + height: 14px; + border-color: #fff; + margin-top: -7px; + margin-left: -7px; + background-color: #0098ff; + } + + & .next-range .next-range-slider { + width: 14px; + height: 14px; + margin-top: -7px; + margin-left: -7px; + } + + & .next-range.simulation-click>.next-range-slider-inner { + border: 2px solid #fff !important; + } + + & .next-range .next-range-frag.next-range-active .next-range-slider .next-range-slider-inner { + border: 2px solid #fff !important; + } + + & .next-range .next-range-slider.next-range-slider-moving .next-range-slider-inner { + border: 2px solid #fff !important; + } +} diff --git a/packages/meta/es/VideoPlayer/index.d.ts b/packages/meta/es/VideoPlayer/index.d.ts new file mode 100644 index 0000000..a1993e1 --- /dev/null +++ b/packages/meta/es/VideoPlayer/index.d.ts @@ -0,0 +1,3 @@ +import VideoPlayer from './VideoPlayer'; +export type { VideoViewProps, VideoViewRef } from './VideoPlayer'; +export default VideoPlayer; diff --git a/packages/meta/es/VideoPlayer/index.js b/packages/meta/es/VideoPlayer/index.js new file mode 100644 index 0000000..5863364 --- /dev/null +++ b/packages/meta/es/VideoPlayer/index.js @@ -0,0 +1,2 @@ +import VideoPlayer from "./VideoPlayer"; +export default VideoPlayer; \ No newline at end of file diff --git a/packages/meta/es/VideoPlayer/index.less b/packages/meta/es/VideoPlayer/index.less new file mode 100644 index 0000000..181e65c --- /dev/null +++ b/packages/meta/es/VideoPlayer/index.less @@ -0,0 +1,75 @@ +.zhst-image__video-view { + position: relative; + overflow: hidden; + width: 100%; + height: 532px; + background-color: #333; + + // &-flv { + // width: 85%; + // } + &-screenshot { + position: absolute; + z-index: 10; + } + + &-crop-container { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + } + + &-align { + position: absolute; + top: 0; + left: 0; + pointer-events: none; + } + + &-opt { + position: absolute; + z-index: 99; + bottom: 0; + display: flex; + width: 100%; + height: 32px; + box-sizing: border-box; + align-items: center; + padding: 0 12px; + background-color: rgb(0 0 0 / 80%); + line-height: 32px; + + &>div:first-child { + display: flex; + align-items: center; + margin-right: 12px; + } + + &>div:last-child { + display: flex; + align-items: center; + margin-left: 12px; + } + + &-range { + display: flex; + height: 32px; + flex: 1; + align-items: center; + line-height: 32px; + text-align: center; + + &>div:first-child { + flex: 1; + } + + &>div:last-child { + width: 100px; + margin-left: 8px; + color: #fff; + } + } + } +} diff --git a/packages/meta/es/VideoPlayer/videoPlayerHelper.d.ts b/packages/meta/es/VideoPlayer/videoPlayerHelper.d.ts new file mode 100644 index 0000000..661a7c1 --- /dev/null +++ b/packages/meta/es/VideoPlayer/videoPlayerHelper.d.ts @@ -0,0 +1 @@ +export declare function getShowStatus(isLoadingVideo: boolean, isEnd: boolean, isError: boolean): string | null; diff --git a/packages/meta/es/VideoPlayer/videoPlayerHelper.js b/packages/meta/es/VideoPlayer/videoPlayerHelper.js new file mode 100644 index 0000000..b5e91eb --- /dev/null +++ b/packages/meta/es/VideoPlayer/videoPlayerHelper.js @@ -0,0 +1,13 @@ +export function getShowStatus(isLoadingVideo, isEnd, isError) { + var status = null; + if (isLoadingVideo) { + status = 'LOADING'; + } + if (isError) { + status = 'ERROR'; + } + if (isEnd) { + status = 'END'; + } + return status; +} \ No newline at end of file diff --git a/packages/meta/es/iconfont/iconfont.css b/packages/meta/es/iconfont/iconfont.css new file mode 100644 index 0000000..8bde390 --- /dev/null +++ b/packages/meta/es/iconfont/iconfont.css @@ -0,0 +1,1679 @@ +@font-face { + font-family: iconfont; /* Project id 1739270 */ + src: url('iconfont.woff2?t=1689583241972') format('woff2'), + url('iconfont.woff?t=1689583241972') format('woff'), + url('iconfont.ttf?t=1689583241972') format('truetype'); +} + +.iconfont { + font-family: iconfont !important; + font-size: 16px; + font-style: normal; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.icon-danganxiangqing_hangweifenxi::before { + content: "\e78d"; +} + +.icon-danganxiangqing_shujuganzhi::before { + content: "\e78e"; +} + +.icon-danganxiangqing_huodongguiji::before { + content: "\e78f"; +} + +.icon-danganxiangqing_jibenxinxi::before { + content: "\e7ea"; +} + +.icon-danganxiangqing_fushuwupin::before { + content: "\e7eb"; +} + +.icon-danganxiangqing_jizhanyingyong::before { + content: "\e7ec"; +} + +.icon-jiarudanganku::before { + content: "\e787"; +} + +.icon-dangankunor::before { + content: "\e793"; +} + +.icon-bukongrenwuselect::before { + content: "\e799"; +} + +.icon-bukongrenwunor1::before { + content: "\e79a"; +} + +.icon-dangankuselect::before { + content: "\e79b"; +} + +.icon-jizhanfanor::before { + content: "\e79c"; +} + +.icon-feijidongchechaxunnor::before { + content: "\e79d"; +} + +.icon-jidongchechaxunselect::before { + content: "\e79e"; +} + +.icon-a-lixianfenxiselect2::before { + content: "\e7a1"; +} + +.icon-huisufenxiselect::before { + content: "\e7a2"; +} + +.icon-jizhanfaselect::before { + content: "\e7a3"; +} + +.icon-mubiaojiansuonor::before { + content: "\e7ae"; +} + +.icon-lurenkuselect::before { + content: "\e7b1"; +} + +.icon-shujujiashicangselect::before { + content: "\e7b2"; +} + +.icon-shishijiexiselect::before { + content: "\e7b4"; +} + +.icon-shishijiexinor::before { + content: "\e7b9"; +} + +.icon-jidongchechaxunnor::before { + content: "\e7c1"; +} + +.icon-lurenkunor1::before { + content: "\e7cf"; +} + +.icon-mubiaotezhengchaxunnor::before { + content: "\e7e1"; +} + +.icon-yujingjiluselect::before { + content: "\e7e2"; +} + +.icon-mubiaotezhengchaxunselect::before { + content: "\e7e3"; +} + +.icon-feijidongchechaxunselect::before { + content: "\e7e4"; +} + +.icon-yujingjilunor::before { + content: "\e7e5"; +} + +.icon-lixianfenxiselect::before { + content: "\e7e6"; +} + +.icon-huisufenxinor::before { + content: "\e7e7"; +} + +.icon-shujujiashicangnor::before { + content: "\e7e8"; +} + +.icon-mubiaojiansuoselect::before { + content: "\e7e9"; +} + +.icon-kuangxuangongju::before { + content: "\e796"; +} + +.icon-fengniao::before { + content: "\e792"; +} + +.icon-zhankai::before { + content: "\e790"; +} + +.icon-shouqi::before { + content: "\e791"; +} + +.icon-shijian::before { + content: "\e786"; +} + +.icon-dingwei2::before { + content: "\e613"; +} + +.icon-renyuan::before { + content: "\e784"; +} + +.icon-houtai::before { + content: "\e785"; +} + +.icon-zuo::before { + content: "\e781"; +} + +.icon-you::before { + content: "\e783"; +} + +.icon-kakou::before { + content: "\e780"; +} + +.icon-yujing1::before { + content: "\e77e"; +} + +.icon-yuan2::before { + content: "\e77d"; +} + +.icon-moxingpengzhuang::before { + content: "\e777"; +} + +.icon-moxingpengzhuangnor::before { + content: "\e778"; +} + +.icon-lurenku::before { + content: "\e77b"; +} + +.icon-lurenkunor::before { + content: "\e77c"; +} + +.icon-shiming::before { + content: "\e776"; +} + +.icon-suoxiao2::before { + content: "\e774"; +} + +.icon-fangda1::before { + content: "\e775"; +} + +.icon-guanbi2::before { + content: "\e772"; +} + +.icon-fanhui1::before { + content: "\e773"; +} + +.icon-xiansuomopai::before { + content: "\e76f"; +} + +.icon-xiansuomopainor::before { + content: "\e76e"; +} + +.icon-zhajiyujing::before { + content: "\e770"; +} + +.icon-zhajiyujingnor::before { + content: "\e771"; +} + +.icon-zhuizongpeizhi::before { + content: "\e76c"; +} + +.icon-zhuizongpeizhinor::before { + content: "\e76d"; +} + +.icon-dapingqiehuan::before { + content: "\e76b"; +} + +.icon-xuanze::before { + content: "\e769"; +} + +.icon-shaixuan1::before { + content: "\e76a"; +} + +.icon-chekashebei::before { + content: "\e764"; +} + +.icon-imsishebei::before { + content: "\e765"; +} + +.icon-xingtishebei::before { + content: "\e766"; +} + +.icon-renlianshebei::before { + content: "\e767"; +} + +.icon-wifishebei::before { + content: "\e768"; +} + +.icon-a-miaozhun2::before { + content: "\e762"; +} + +.icon-a-bianzu19::before { + content: "\e763"; +} + +.icon-fanye::before { + content: "\e75e"; +} + +.icon-shenfenzheng::before { + content: "\e75f"; +} + +.icon-dizhi::before { + content: "\e760"; +} + +.icon-guanbi::before { + content: "\e761"; +} + +.icon-dianwei1::before { + content: "\e75b"; +} + +.icon-weikakou::before { + content: "\e757"; +} + +.icon-weikakounor::before { + content: "\e758"; +} + +.icon-changsuoma::before { + content: "\e759"; +} + +.icon-changsuomanor::before { + content: "\e75a"; +} + +.icon-yujing::before { + content: "\e756"; +} + +.icon-jiansuonor::before { + content: "\e747"; +} + +.icon-tonghangrenfenxinor1::before { + content: "\e748"; +} + +.icon-zhinengyanpannor::before { + content: "\e749"; +} + +.icon-bukongyujingnor::before { + content: "\e74a"; +} + +.icon-bukongrenwunor::before { + content: "\e74b"; +} + +.icon-dianziditunor::before { + content: "\e754"; +} + +.icon-zhuizongnor1::before { + content: "\e755"; +} + +.icon-zhuizong1::before { + content: "\e746"; +} + +.icon-bukongrenwu3::before { + content: "\e74c"; +} + +.icon-dianziditu::before { + content: "\e74d"; +} + +.icon-bukongyujing::before { + content: "\e750"; +} + +.icon-tonghangrenfenxi1::before { + content: "\e751"; +} + +.icon-zhinengyanpan::before { + content: "\e752"; +} + +.icon-jiansuo1::before { + content: "\e753"; +} + +.icon-kaiqijulei::before { + content: "\e745"; +} + +.icon-tongbu::before { + content: "\e744"; +} + +.icon-tonghangrenfenxi::before { + content: "\e743"; +} + +.icon-tonghangrenfenxinor::before { + content: "\e742"; +} + +.icon-jizhanyingyong::before { + content: "\e741"; +} + +.icon-haikangrenlianbukongnor::before { + content: "\e740"; +} + +.icon-haikangrenlianbukong::before { + content: "\e73f"; +} + +.icon-tuozhanshouduantishi::before { + content: "\e73e"; +} + +.icon-fanhuimopailiebiao::before { + content: "\e73d"; +} + +.icon-toukuijiancenor::before { + content: "\e73c"; +} + +.icon-toukuijiance::before { + content: "\e718"; +} + +.icon-zhuixing::before { + content: "\e717"; +} + +.icon-tishi4::before { + content: "\e73b"; +} + +.icon-a-shaixuanfeiji::before { + content: "\e733"; +} + +.icon-a-zidongtiaozhengfanweifeiji::before { + content: "\e73a"; +} + +.icon-heziyunwei::before { + content: "\e739"; +} + +.icon-qiehuan::before { + content: "\e738"; +} + +.icon-disanfangxiaoxinor::before { + content: "\e737"; +} + +.icon-disanfangxiaoxi::before { + content: "\e736"; +} + +.icon-daohang::before { + content: "\e735"; +} + +.icon-yonghu::before { + content: "\e734"; +} + +.icon-feiji::before { + content: "\e732"; +} + +.icon-jieshuzhuizong::before { + content: "\e730"; +} + +.icon-huisuzhoubian::before { + content: "\e731"; +} + +.icon-jixuzhuizong::before { + content: "\e72d"; +} + +.icon-tiaozhengfanwei::before { + content: "\e72e"; +} + +.icon-jiansuo::before { + content: "\e72f"; +} + +.icon-guiji::before { + content: "\e72c"; +} + +.icon-jichuxinxi::before { + content: "\e72b"; +} + +.icon-danganzhaiyao::before { + content: "\e72a"; +} + +.icon-jingzhunbukongicon_on::before { + content: "\e728"; +} + +.icon-jingzhunbukongicon_off::before { + content: "\e729"; +} + +.icon-tiaozhuan::before { + content: "\e727"; +} + +.icon-shezhi::before { + content: "\e726"; +} + +.icon-bangzhu1::before { + content: "\e725"; +} + +.icon-shuaxin1::before { + content: "\e724"; +} + +.icon-duosucaibeifen::before { + content: "\e722"; +} + +.icon-duosucai::before { + content: "\e723"; +} + +.icon-shujutongji::before { + content: "\e721"; +} + +.icon-renlian::before { + content: "\e71c"; +} + +.icon-xingti::before { + content: "\e71d"; +} + +.icon-jidongche::before { + content: "\e71e"; +} + +.icon-huisufenxi4::before { + content: "\e71f"; +} + +.icon-lixianfenxi4::before { + content: "\e720"; +} + +.icon-feijidongche::before { + content: "\e71b"; +} + +.icon-shujudaping::before { + content: "\e71a"; +} + +.icon-peizhisuanfa::before { + content: "\e719"; +} + +.icon-zhuizong::before { + content: "\e715"; +} + +.icon-zhuizongnor::before { + content: "\e716"; +} + +.icon-dianwei::before { + content: "\e714"; +} + +.icon-Container::before { + content: "\e713"; +} + +.icon-Attachment::before { + content: "\e712"; +} + +.icon-cha::before { + content: "\e711"; +} + +.icon-gou::before { + content: "\e710"; +} + +.icon-daoru::before { + content: "\e70f"; +} + +.icon-quanxijiansuo::before { + content: "\e70e"; +} + +.icon-chakanjiankong::before { + content: "\e70c"; +} + +.icon-tishi3::before { + content: "\e70d"; +} + +.icon-heiyemoshi::before { + content: "\e70b"; +} + +.icon-zhengchangmoshi::before { + content: "\e70a"; +} + +.icon-dingwei1::before { + content: "\e709"; +} + +.icon-paixu::before { + content: "\e708"; +} + +.icon-tianjiayuan::before { + content: "\e707"; +} + +.icon-juleidangankunor::before { + content: "\e705"; +} + +.icon-juleidanganku::before { + content: "\e706"; +} + +.icon-guanlian::before { + content: "\e704"; +} + +.icon-renlianbiaozhu::before { + content: "\e703"; +} + +.icon-juleijieguo::before { + content: "\e6ec"; +} + +.icon-juleirenwunor::before { + content: "\e6fb"; +} + +.icon-juleijieguonor::before { + content: "\e701"; +} + +.icon-juleirenwu::before { + content: "\e702"; +} + +.icon-zhongzhi3::before { + content: "\e8ff"; +} + +.icon-xuanzhuan1::before { + content: "\e6fd"; +} + +.icon-shuangmubiaozhu1::before { + content: "\e700"; +} + +.icon-shoudongkuangxuan::before { + content: "\e6f9"; +} + +.icon-zanting1::before { + content: "\e6fe"; +} + +.icon-zhongzhi1::before { + content: "\e6ff"; +} + +.icon-shoudong::before { + content: "\e6fa"; +} + +.icon-zidong::before { + content: "\e6fc"; +} + +.icon-zhenduan::before { + content: "\e6f8"; +} + +.icon-Check-Circle-Fill1::before { + content: "\e6f3"; +} + +.icon-Info--Circle-Fill::before { + content: "\e6f4"; +} + +.icon-Close-Circle-Fill::before { + content: "\e6f5"; +} + +.icon-Warning-Circle-Fill::before { + content: "\e6f6"; +} + +.icon-Question-Circle-Fill::before { + content: "\e6f7"; +} + +.icon-zancunjia::before { + content: "\e6f2"; +} + +.icon-Check-Circle-Fill::before { + content: "\e6f1"; +} + +.icon-tupianji::before { + content: "\e6f0"; +} + +.icon-quanping1::before { + content: "\e6ed"; +} + +.icon-yinliang::before { + content: "\e6ee"; +} + +.icon-suoxiao1::before { + content: "\e6ef"; +} + +.icon-home::before { + content: "\e6eb"; +} + +.icon-zuixiaohua::before { + content: "\e6e9"; +} + +.icon-zuidahua::before { + content: "\e6ea"; +} + +.icon-biaozhunhua::before { + content: "\e6e6"; +} + +.icon-julei::before { + content: "\e6e5"; +} + +.icon-bianzu::before { + content: "\e6e7"; +} + +.icon-bianzu3::before { + content: "\e6e8"; +} + +.icon-bianzu7::before { + content: "\e6e3"; +} + +.icon-bianzu2::before { + content: "\e6e4"; +} + +.icon-kapianqiehuan::before { + content: "\e6e2"; +} + +.icon-duobianxing1::before { + content: "\e6e0"; +} + +.icon-fang1::before { + content: "\e6e1"; +} + +.icon-yuan1::before { + content: "\e6df"; +} + +.icon-cejuli::before { + content: "\e6de"; +} + +.icon-wanggekuangxuannor::before { + content: "\e6dc"; +} + +.icon-lujingkuangxuannor::before { + content: "\e6dd"; +} + +.icon-chuansuo::before { + content: "\e6db"; +} + +.icon-bianyuanhezinor::before { + content: "\e6d8"; +} + +.icon-wujiankuhov::before { + content: "\e6d9"; +} + +.icon-caozuorizhinor::before { + content: "\e6da"; +} + +.icon-collect_dot::before { + content: "\e619"; +} + +.icon-chuxiandingweibg::before { + content: "\e6d4"; +} + +.icon-chuxiandingweiicon::before { + content: "\e6d5"; +} + +.icon-shexiangtoudingweibg::before { + content: "\e6d6"; +} + +.icon-shexiangtoudingweiicon::before { + content: "\e6d7"; +} + +.icon-xiafajieguo::before { + content: "\e6d2"; +} + +.icon-daochu1::before { + content: "\e6d3"; +} + +.icon-zuijinchuxian::before { + content: "\e6cc"; +} + +.icon-leijizhuapai::before { + content: "\e6d0"; +} + +.icon-yichangshijian::before { + content: "\e6d1"; +} + +.icon-dingwei::before { + content: "\e6cb"; +} + +.icon-tupian::before { + content: "\e6ad"; +} + +.icon-wenti::before { + content: "\e6ac"; +} + +.icon-lixian1::before { + content: "\e6ab"; +} + +.icon-yichang::before { + content: "\e6a8"; +} + +.icon-zhuixing-xiugaidianwei::before { + content: "\e6a7"; +} + +.icon-wenhao1::before { + content: "\e69e"; +} + +.icon-ditu_dingwei::before { + content: "\e69d"; +} + +.icon-ditu_fangda::before { + content: "\e689"; +} + +.icon-ditu_suoxiao::before { + content: "\e69a"; +} + +.icon-chakanbukongrenwu::before { + content: "\e688"; +} + +.icon-lietu::before { + content: "\e687"; +} + +.icon-zhongzhi::before { + content: "\e67e"; +} + +.icon-xialada::before { + content: "\e67f"; +} + +.icon-zhinengguanlian_xingti::before { + content: "\e67b"; +} + +.icon-zhinengguanlian_renlian::before { + content: "\e67c"; +} + +.icon-xiajiantou::before { + content: "\e75c"; +} + +.icon-zhinengguanlian_xiaojiantou::before { + content: "\e67d"; +} + +.icon-zhinengguanlian_jiantou::before { + content: "\e67a"; +} + +.icon-shangjiantou::before { + content: "\e75d"; +} + +.icon-banbenxinxi::before { + content: "\e679"; +} + +.icon-wenhao::before { + content: "\e61f"; +} + +.icon-bianjirenyuan::before { + content: "\e7e0"; +} + +.icon-tishi2::before { + content: "\e7df"; +} + +.icon-shexiangji2::before { + content: "\e7de"; +} + +.icon-guijizhuizong::before { + content: "\e7dd"; +} + +.icon-jiezhen1::before { + content: "\e7dc"; +} + +.icon-tianjiaguijihuisu::before { + content: "\e7db"; +} + +.icon-tingzhi::before { + content: "\e7cd"; +} + +.icon-baoweiquan::before { + content: "\e7ce"; +} + +.icon-shangchuanshipin::before { + content: "\e7d0"; +} + +.icon-yidong::before { + content: "\e7d1"; +} + +.icon-chuangjianxinbukong1::before { + content: "\e7d2"; +} + +.icon-yichu1::before { + content: "\e7d3"; +} + +.icon-tishi1::before { + content: "\e7d4"; +} + +.icon-VS::before { + content: "\e7d5"; +} + +.icon-quanjuzonglan::before { + content: "\e7d6"; +} + +.icon-chakanfenxirenwu1::before { + content: "\e7d7"; +} + +.icon-xiaoxi::before { + content: "\e7d8"; +} + +.icon-yonghuming::before { + content: "\e7d9"; +} + +.icon-tuichu::before { + content: "\e7da"; +} + +.icon-guijizhuizongnor::before { + content: "\e7cb"; +} + +.icon-guijizhuizong2::before { + content: "\e7cc"; +} + +.icon-bukongrenwu1::before { + content: "\e7b7"; +} + +.icon-shexiangji::before { + content: "\e7b8"; +} + +.icon-yujingditu::before { + content: "\e7ba"; +} + +.icon-lixianfenxi2::before { + content: "\e7bb"; +} + +.icon-yuanguanli1::before { + content: "\e7bc"; +} + +.icon-danganku::before { + content: "\e7bd"; +} + +.icon-huisufenxi2::before { + content: "\e7be"; +} + +.icon-kuneijiansuo::before { + content: "\e7bf"; +} + +.icon-jiegouhuachaxun::before { + content: "\e7c0"; +} + +.icon-bukongrenwu2::before { + content: "\e7c2"; +} + +.icon-yuanguanli2::before { + content: "\e7c3"; +} + +.icon-shexiangji1::before { + content: "\e7c4"; +} + +.icon-kuneijiansuo1::before { + content: "\e7c5"; +} + +.icon-lixianfenxi3::before { + content: "\e7c6"; +} + +.icon-danganku1::before { + content: "\e7c7"; +} + +.icon-yujingditu1::before { + content: "\e7c8"; +} + +.icon-huisufenxi3::before { + content: "\e7c9"; +} + +.icon-jiegouhuachaxunnor::before { + content: "\e7ca"; +} + +.icon-chuangjianxinbukong::before { + content: "\e7b6"; +} + +.icon-kuangxuan::before { + content: "\e77f"; +} + +.icon-gaojishaixuan::before { + content: "\e779"; +} + +.icon-gaojishaixuanshouqi::before { + content: "\e77a"; +} + +.icon-bukongrenwu::before { + content: "\e7b5"; +} + +.icon-riqi::before { + content: "\e74f"; +} + +.icon-shijianqiehuan::before { + content: "\e797"; +} + +.icon-shouquan1::before { + content: "\e7b3"; +} + +.icon-video-play::before { + content: "\e653"; +} + +.icon-shishifenxi::before { + content: "\e7af"; +} + +.icon-chakanfenxirenwu::before { + content: "\e7b0"; +} + +.icon-jiegouhuafenxi::before { + content: "\e7ad"; +} + +.icon-tianjiaguiji2::before { + content: "\e6aa"; +} + +.icon-tianjiajiansuomubiao::before { + content: "\e6b0"; +} + +.icon-add::before { + content: "\e661"; +} + +.icon-didian::before { + content: "\e798"; +} + +.icon-bofanghov::before { + content: "\e79f"; +} + +.icon-bofang3::before { + content: "\e7a0"; +} + +.icon-jinggao::before { + content: "\e788"; +} + +.icon-tishi::before { + content: "\e789"; +} + +.icon-bangzhu::before { + content: "\e78a"; +} + +.icon-guanbi1::before { + content: "\e78b"; +} + +.icon-chenggong::before { + content: "\e78c"; +} + +.icon-qianwang::before { + content: "\e7ac"; +} + +.icon-shouquan::before { + content: "\e7ab"; +} + +.icon-jingweidu::before { + content: "\e7aa"; +} + +.icon-shanchu1::before { + content: "\e74e"; +} + +.icon-daochu::before { + content: "\e782"; +} + +.icon-ziyuanguanli::before { + content: "\e7a4"; +} + +.icon-fuwuqishouquan::before { + content: "\e7a5"; +} + +.icon-xiugaimima::before { + content: "\e7a6"; +} + +.icon-zhanghaoguanli::before { + content: "\e7a7"; +} + +.icon-suanlipeie::before { + content: "\e7a8"; +} + +.icon-VMSpeizhi::before { + content: "\e7a9"; +} + +.icon-tianjia1::before { + content: "\e794"; +} + +.icon-yichu::before { + content: "\e795"; +} + +.icon-lujing::before { + content: "\e6cf"; +} + +.icon-jiankongxinxi::before { + content: "\e6c8"; +} + +.icon-fanwei::before { + content: "\e6c9"; +} + +.icon-anfadidian::before { + content: "\e6ca"; +} + +.icon-gongjuxiang::before { + content: "\e6cd"; +} + +.icon-gongjuxiangguanbi1::before { + content: "\e6ce"; +} + +.icon-jiezhen::before { + content: "\e6c2"; +} + +.icon-huisufenxi1::before { + content: "\e6c6"; +} + +.icon-huisufenxi::before { + content: "\e6c7"; +} + +.icon-tianjiashipinwenjian1::before { + content: "\e6c5"; +} + +.icon-jiazaishibai::before { + content: "\e6c3"; +} + +.icon-shuaxin::before { + content: "\e6c4"; +} + +.icon-quanping::before { + content: "\e6c0"; +} + +.icon-quxiaoquanping::before { + content: "\e6c1"; +} + +.icon-shipinbofang::before { + content: "\e6be"; +} + +.icon-shipinzanting::before { + content: "\e6bf"; +} + +.icon-lixianguiji::before { + content: "\e6bd"; +} + +.icon-lixian::before { + content: "\e6bc"; +} + +.icon-xiaojiaobiao::before { + content: "\e6bb"; +} + +.icon-shangchuan1::before { + content: "\e6ba"; +} + +.icon-tianjiaweijiansuoduixiang::before { + content: "\e6b8"; +} + +.icon-tianjiaweijiansuojilu::before { + content: "\e6b9"; +} + +.icon-lixianfenxi1::before { + content: "\e6b7"; +} + +.icon-kuaisujiansuohov::before { + content: "\e6b5"; +} + +.icon-kuaisujiansuo1::before { + content: "\e6b6"; +} + +.icon-kuaisujiansuo::before { + content: "\e6b4"; +} + +.icon-yuanguanli::before { + content: "\e6b1"; +} + +.icon-shexiangtou::before { + content: "\e6b2"; +} + +.icon-lixianfenxi::before { + content: "\e6b3"; +} + +.icon-filter::before { + content: "\e61a"; +} + +.icon-tianjiaweizhuizongduixiang2::before { + content: "\e6af"; +} + +.icon-tianjiaweizhuizongduixiang1::before { + content: "\e6ae"; +} + +.icon-baocun1::before { + content: "\e6a9"; +} + +.icon-tianjiashipinwenjianjia::before { + content: "\e6a5"; +} + +.icon-tianjiashipinwenjian::before { + content: "\e6a6"; +} + +.icon-ditu::before { + content: "\e6a4"; +} + +.icon-xinjianshexiangtou::before { + content: "\e6a3"; +} + +.icon-lishihuisu::before { + content: "\e6a2"; +} + +.icon-decoyitianjiaweiguiji::before { + content: "\e69f"; +} + +.icon-bofangqiehuan::before { + content: "\e6a0"; +} + +.icon-tianjia::before { + content: "\e6a1"; +} + +.icon-baocun::before { + content: "\e698"; +} + +.icon-gongjuxiangguanbi::before { + content: "\e699"; +} + +.icon-shangchuan::before { + content: "\e69b"; +} + +.icon-gongjuxiang1::before { + content: "\e69c"; +} + +.icon-logo::before { + content: "\e692"; +} + +.icon-setting::before { + content: "\e627"; +} + +.icon-user::before { + content: "\e628"; +} + +.icon-quit::before { + content: "\e629"; +} + +.icon-arrowzhankaimeixuanzhong::before { + content: "\e693"; +} + +.icon-arrowzhankaixuanzhong::before { + content: "\e694"; +} + +.icon-xuanzexuanzhong::before { + content: "\e695"; +} + +.icon-xuanzebanxuan::before { + content: "\e696"; +} + +.icon-xuanzenor::before { + content: "\e697"; +} + +.icon-shaixuanguanbinor::before { + content: "\e691"; +} + +.icon-gengduo::before { + content: "\e68e"; +} + +.icon-youzhankai::before { + content: "\e68f"; +} + +.icon-zuoshouqi::before { + content: "\e690"; +} + +.icon-yuan::before { + content: "\e68a"; +} + +.icon-duobianxing::before { + content: "\e68b"; +} + +.icon-fang::before { + content: "\e68c"; +} + +.icon-ceju::before { + content: "\e68d"; +} + +.icon-shishizhuizong1::before { + content: "\e683"; +} + +.icon-guijihuisu1::before { + content: "\e684"; +} + +.icon-tianjiaguiji::before { + content: "\e685"; +} + +.icon-yichuguiji::before { + content: "\e686"; +} + +.icon-fangda::before { + content: "\e680"; +} + +.icon-suoxiao::before { + content: "\e681"; +} + +.icon-xiazai::before { + content: "\e682"; +} + +.icon-fanhui::before { + content: "\e678"; +} + +.icon-sousuo::before { + content: "\e669"; +} + +.icon-quxiaoxuanzhong::before { + content: "\e66a"; +} + +.icon-piliangxuanzenor::before { + content: "\e66b"; +} + +.icon-kaiqifenxi::before { + content: "\e66c"; +} + +.icon-quxiaofenxi::before { + content: "\e66d"; +} + +.icon-shaixuan::before { + content: "\e66e"; +} + +.icon-dangan::before { + content: "\e66f"; +} + +.icon-bofang::before { + content: "\e670"; +} + +.icon-zanting::before { + content: "\e671"; +} + +.icon-shanchu::before { + content: "\e672"; +} + +.icon-tianjiaweizhuizongduixiang::before { + content: "\e673"; +} + +.icon-chakandatu::before { + content: "\e674"; +} + +.icon-jiansuojilu::before { + content: "\e675"; +} + +.icon-yuzhi::before { + content: "\e676"; +} + +.icon-chakanxiangqing::before { + content: "\e677"; +} + +.icon-guijihuisu::before { + content: "\e65c"; +} + +.icon-dianweipeizhinor::before { + content: "\e65d"; +} + +.icon-yirenyidang::before { + content: "\e65e"; +} + +.icon-tongbanfenxi::before { + content: "\e65f"; +} + +.icon-qiehuanzuo::before { + content: "\e662"; +} + +.icon-qiehuanyou::before { + content: "\e663"; +} + +.icon-tingzhidengdai::before { + content: "\e664"; +} + +.icon-yiguanbi::before { + content: "\e665"; +} + +.icon-danchuangguanbi::before { + content: "\e666"; +} + +.icon-lishijilu::before { + content: "\e64a"; +} + +.icon-xuanzhuan::before { + content: "\e648"; +} + +.icon-qingchu::before { + content: "\e649"; +} + +.icon-dangantianjia::before { + content: "\e63d"; +} + +.icon-bianji::before { + content: "\e63e"; +} + +.icon-fullscreen::before { + content: "\e63b"; +} + +.icon-cancle_fullscreen::before { + content: "\e63c"; +} + +.icon-quanyujiansuo_nor::before { + content: "\e639"; +} + +.icon-guijihuisu_nor::before { + content: "\e63a"; +} + diff --git a/packages/meta/es/iconfont/iconfont.js b/packages/meta/es/iconfont/iconfont.js new file mode 100644 index 0000000..6eeb914 --- /dev/null +++ b/packages/meta/es/iconfont/iconfont.js @@ -0,0 +1,43 @@ +window._iconfont_svg_string_1739270 = '', function (h) { + var a = (a = document.getElementsByTagName("script"))[a.length - 1], + l = a.getAttribute("data-injectcss"), + a = a.getAttribute("data-disable-injectsvg"); + if (!a) { + var i, + _c, + o, + t, + z, + v = function v(a, l) { + l.parentNode.insertBefore(a, l); + }; + if (l && !h.__iconfont__svg__cssinject__) { + h.__iconfont__svg__cssinject__ = !0; + try { + document.write(""); + } catch (a) { + console && console.log(a); + } + } + i = function i() { + var a, + l = document.createElement("div"); + l.innerHTML = h._iconfont_svg_string_1739270, (l = l.getElementsByTagName("svg")[0]) && (l.setAttribute("aria-hidden", "true"), l.style.position = "absolute", l.style.width = 0, l.style.height = 0, l.style.overflow = "hidden", l = l, (a = document.body).firstChild ? v(l, a.firstChild) : a.appendChild(l)); + }, document.addEventListener ? ~["complete", "loaded", "interactive"].indexOf(document.readyState) ? setTimeout(i, 0) : (_c = function c() { + document.removeEventListener("DOMContentLoaded", _c, !1), i(); + }, document.addEventListener("DOMContentLoaded", _c, !1)) : document.attachEvent && (o = i, t = h.document, z = !1, p(), t.onreadystatechange = function () { + "complete" == t.readyState && (t.onreadystatechange = null, m()); + }); + } + function m() { + z || (z = !0, o()); + } + function p() { + try { + t.documentElement.doScroll("left"); + } catch (a) { + return void setTimeout(p, 50); + } + m(); + } +}(window); \ No newline at end of file diff --git a/packages/meta/es/iconfont/iconfont.ttf b/packages/meta/es/iconfont/iconfont.ttf new file mode 100644 index 0000000000000000000000000000000000000000..0043e6adb470d27d9eb668a85699dab6ac06590f GIT binary patch literal 105116 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�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 literal 0 HcmV?d00001 diff --git a/packages/meta/es/iconfont/iconfont.woff2 b/packages/meta/es/iconfont/iconfont.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..81733409e71fc4817fe0404afb2dc8294fcd6a6a GIT binary patch literal 48900 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 literal 0 HcmV?d00001 diff --git a/packages/meta/es/iconfont/index.d.ts b/packages/meta/es/iconfont/index.d.ts index e769332..fcafc45 100644 --- a/packages/meta/es/iconfont/index.d.ts +++ b/packages/meta/es/iconfont/index.d.ts @@ -1,4 +1,5 @@ import React from 'react'; +import './iconfont.css'; interface IconFontProps { styles?: React.CSSProperties; icon?: string; diff --git a/packages/meta/es/iconfont/index.js b/packages/meta/es/iconfont/index.js index f5914bd..6a980e4 100644 --- a/packages/meta/es/iconfont/index.js +++ b/packages/meta/es/iconfont/index.js @@ -6,6 +6,7 @@ function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _ty function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); } import React from 'react'; import classNames from 'classnames'; +import "./iconfont.css"; var IconFont = function IconFont(props) { var _ref = props || {}, _ref$title = _ref.title, diff --git a/packages/meta/es/index.d.ts b/packages/meta/es/index.d.ts index 241716b..e0961ce 100644 --- a/packages/meta/es/index.d.ts +++ b/packages/meta/es/index.d.ts @@ -1,3 +1,5 @@ export { default as doubleClick } from './doubleClick'; export { default as Icon } from './iconfont'; -export { default as ImagePreview } from './ImagePreview'; +export { default as CompareImage } from './CompareImage'; +export { default as BigImagePreview } from './BigImagePreview'; +export { default as VideoPlayer } from './VideoPlayer'; diff --git a/packages/meta/es/index.js b/packages/meta/es/index.js index e85eac4..85ebaa1 100644 --- a/packages/meta/es/index.js +++ b/packages/meta/es/index.js @@ -1,3 +1,5 @@ export { default as doubleClick } from "./doubleClick"; export { default as Icon } from "./iconfont"; -export { default as ImagePreview } from "./ImagePreview"; \ No newline at end of file +export { default as CompareImage } from "./CompareImage"; +export { default as BigImagePreview } from "./BigImagePreview"; +export { default as VideoPlayer } from "./VideoPlayer"; \ No newline at end of file diff --git a/packages/meta/es/utils/constants.d.ts b/packages/meta/es/utils/constants.d.ts new file mode 100644 index 0000000..f9bb021 --- /dev/null +++ b/packages/meta/es/utils/constants.d.ts @@ -0,0 +1,12 @@ +export declare const CROP_TYPE: { + CUSTOM: string; + AUTO: string; +}; +export declare const defaultAlignOption: { + points: string[]; + offset: number[]; + overflow: { + adjustX: boolean; + adjustY: boolean; + }; +}; diff --git a/packages/meta/es/utils/constants.js b/packages/meta/es/utils/constants.js new file mode 100644 index 0000000..e2357aa --- /dev/null +++ b/packages/meta/es/utils/constants.js @@ -0,0 +1,12 @@ +export var CROP_TYPE = { + CUSTOM: 'CSUTOM', + AUTO: 'AUTO' +}; +export var defaultAlignOption = { + points: ['bl', 'br'], + offset: [6, 0], + overflow: { + adjustX: true, + adjustY: true + } +}; \ No newline at end of file diff --git a/packages/meta/lib/BigImagePreview/BigImagePreview.d.ts b/packages/meta/lib/BigImagePreview/BigImagePreview.d.ts new file mode 100644 index 0000000..45d7836 --- /dev/null +++ b/packages/meta/lib/BigImagePreview/BigImagePreview.d.ts @@ -0,0 +1,35 @@ +import React, { ReactElement } from 'react'; +import { type Rect, type IScreenshotButtonProp, type AlignType, type ViewOption, type IOdRectOrigin } from '@zhst/types'; +import './index.less'; +export interface ImgViewProps extends React.HTMLAttributes { + dataSource: Array<{ + url?: string; + imageKey: string; + attachImg?: Array<{ + label: string; + url: string; + }>; + odRect?: Rect; + score?: number; + showScore?: boolean; + cameraPosition?: string; + time?: string | number; + objects: any[]; + }>; + showAttachImgLabel: boolean; + showOpt: boolean; + width?: string | number; + height?: string | number; + screenshotButtonAlign: AlignType; + screenshotButtonRender: (screenshotButtonProp: IScreenshotButtonProp) => ReactElement; + hideLeftTopBtn?: boolean; + showScore?: boolean; + viewOption?: ViewOption; + objects: IOdRectOrigin[]; +} +export interface ImgViewRef { + imgInsRef: React.MutableRefObject; + setShowCrop: React.Dispatch>; +} +export declare const BigImagePreview: React.ForwardRefExoticComponent>; +export default BigImagePreview; diff --git a/packages/meta/lib/BigImagePreview/BigImagePreview.js b/packages/meta/lib/BigImagePreview/BigImagePreview.js new file mode 100644 index 0000000..af9f764 --- /dev/null +++ b/packages/meta/lib/BigImagePreview/BigImagePreview.js @@ -0,0 +1,487 @@ +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// src/BigImagePreview/BigImagePreview.tsx +var BigImagePreview_exports = {}; +__export(BigImagePreview_exports, { + BigImagePreview: () => BigImagePreview, + default: () => BigImagePreview_default +}); +module.exports = __toCommonJS(BigImagePreview_exports); +var import_react = __toESM(require("react")); +var import_classnames = __toESM(require("classnames")); +var import_hooks = require("@zhst/hooks"); +var import_func = require("@zhst/func"); +var import_rc_align = __toESM(require("rc-align")); +var import_antd = require("antd"); +var import_iconfont = __toESM(require("../iconfont")); +var import_ImageEditor = require("../ImageEditor"); +var import_BtnGroup = __toESM(require("./components/BtnGroup")); +var import_index = require("./index.less"); +var import_ScreenhotButtons = __toESM(require("./components/ScreenhotButtons")); +var import_constants = require("../utils/constants"); +var componentName = `zhst-image__img-view`; +var cropBtnDataSource = [ + { + key: "close", + icon: "icon-danchuangguanbi", + title: "退出" + }, + { + key: "autoCrop", + icon: "icon-zidong", + title: "智能框选" + }, + { + key: "customCrop", + icon: "icon-shoudong", + title: "手动框选" + } +]; +var operateBtnDataSource = [ + { + key: "zoomOut", + icon: "icon-fangda", + title: "放大" + }, + { + key: "zoomIn", + icon: "icon-suoxiao", + title: "缩小" + }, + { + key: "reset", + icon: "icon-zhongzhi3", + title: "重置图片" + } +]; +var BigImagePreview = import_react.default.forwardRef((props, ref) => { + var _a, _b; + const { + dataSource = [], + width, + height, + showScore = true, + objects = [], + showOpt = false, + showAttachImgLabel = true, + screenshotButtonAlign = import_constants.defaultAlignOption, + screenshotButtonRender = (0, import_ScreenhotButtons.default)({ + onBigImageActionClick: () => { + }, + disableBtn: [] + }), + hideLeftTopBtn = true, + viewOption = {} + } = props; + const imgContainerRef = import_react.default.useRef(null); + const [isReady, setIsReady] = (0, import_react.useState)(false); + const [currentIndex, setCurrentIndex] = (0, import_react.useState)(0); + console.log("props", props); + const init = (0, import_react.useCallback)(($container) => { + imgContainerRef.current = $container; + setIsReady(true); + }, []); + const imgInsRef = (0, import_react.useRef)(null); + const [isImgReady, setIsImgReady] = (0, import_react.useState)(false); + (0, import_react.useEffect)(() => { + var _a2; + console.log("123", 123); + if (!isReady || !(imgContainerRef == null ? void 0 : imgContainerRef.current)) + return; + const handleReady = (0, import_func.addEventListenerWrapper)(imgContainerRef.current, import_ImageEditor.EVENT_VIEWER_READY, () => { + setIsImgReady(true); + }); + const handleTransformChange = (0, import_func.addEventListenerWrapper)( + imgContainerRef.current, + import_ImageEditor.EVENT_VIEWER_TRANSFORM_CHANGE, + () => { + } + ); + imgInsRef.current = new import_ImageEditor.Viewer(imgContainerRef.current, { + ...viewOption, + fitScaleAsMinScale: true, + image: (0, import_func.generateImg)((_a2 = dataSource[currentIndex]) == null ? void 0 : _a2.imageKey) + }); + return () => { + var _a3, _b2; + handleReady == null ? void 0 : handleReady.remove(); + handleTransformChange == null ? void 0 : handleTransformChange.remove(); + (_b2 = (_a3 = imgInsRef == null ? void 0 : imgInsRef.current) == null ? void 0 : _a3.destroy) == null ? void 0 : _b2.call(_a3); + imgInsRef.current = null; + }; + }, [isReady, currentIndex]); + const handleOptClick = (v) => { + var _a2, _b2, _c, _d, _e, _f; + switch (v) { + case "zoomOut": + (_b2 = (_a2 = imgInsRef == null ? void 0 : imgInsRef.current) == null ? void 0 : _a2.scaleTo) == null ? void 0 : _b2.call(_a2, 0.1); + break; + case "zoomIn": + (_d = (_c = imgInsRef == null ? void 0 : imgInsRef.current) == null ? void 0 : _c.scaleTo) == null ? void 0 : _d.call(_c, -0.1); + break; + case "reset": + (_f = (_e = imgInsRef == null ? void 0 : imgInsRef.current) == null ? void 0 : _e.reset) == null ? void 0 : _f.call(_e, -0.1); + break; + } + }; + const cropInsRef = (0, import_react.useRef)(null); + const [showCrop, setShowCrop] = (0, import_react.useState)(showOpt); + const [cropType, setCropType] = (0, import_react.useState)(import_constants.CROP_TYPE["AUTO"]); + const [odList, setOdList] = (0, import_react.useState)([]); + const [extendOdList, setExtendOdList] = (0, import_react.useState)([]); + const [selectRectId, setSelectRectId] = (0, import_react.useState)(null); + const alginContainerRef = (0, import_react.useRef)(null); + const alignRef = (0, import_react.useRef)(null); + const [cropRect, setCropRect] = (0, import_react.useState)(null); + const [selectAlgorithmVersion, setSelectAlgorithmVersion] = (0, import_react.useState)(null); + const handlerCropStartRef = (0, import_react.useRef)(null); + const handlerCropEndRef = (0, import_react.useRef)(null); + const handleShapeSelectRef = (0, import_react.useRef)(null); + (0, import_react.useEffect)(() => { + initData(dataSource[currentIndex].objects || objects); + return () => { + var _a2, _b2, _c, _d, _e, _f, _g; + (_b2 = (_a2 = imgInsRef.current) == null ? void 0 : _a2.clearShape) == null ? void 0 : _b2.call(_a2); + (_c = handlerCropStartRef.current) == null ? void 0 : _c.remove(); + (_d = handlerCropEndRef.current) == null ? void 0 : _d.remove(); + (_e = handleShapeSelectRef.current) == null ? void 0 : _e.remove(); + (_g = (_f = cropInsRef == null ? void 0 : cropInsRef.current) == null ? void 0 : _f.destroy) == null ? void 0 : _g.call(_f); + cropInsRef.current = null; + }; + }, [isImgReady, showCrop, cropType, currentIndex]); + const initData = (_objects) => { + var _a2, _b2; + const imgIns = imgInsRef.current; + const _odRect = dataSource[currentIndex].odRect; + setCropRect(null); + if (!isImgReady) + return; + if (!showCrop) { + (_a2 = imgIns == null ? void 0 : imgIns.addShape) == null ? void 0 : _a2.call(imgIns, { + x: (0, import_func.get)(_odRect, "x", 0), + y: (0, import_func.get)(_odRect, "y", 0), + w: (0, import_func.get)(_odRect, "w", 0), + h: (0, import_func.get)(_odRect, "h", 0), + selectAble: false + }); + return; + } + if (cropType === import_constants.CROP_TYPE["AUTO"]) { + const handleGetOD = (odList2) => { + const imgSize = imgIns.getImgSize(); + const shapeList = odList2.map((rect2) => ({ + ...rect2, + selectAble: true, + id: rect2["id"], + algorithmVersion: rect2.algorithmVersion + })); + imgIns.replaceShape(shapeList); + const extendRect = shapeList.map((rect2) => { + const _extendRect = (0, import_func.getExtendRect)(rect2, imgSize.w, imgSize.h, rect2.algorithmVersion); + return { ...rect2, ..._extendRect }; + }); + setExtendOdList(extendRect); + imgIns.replaceShape(shapeList); + handleShapeSelectRef.current = (0, import_func.addEventListenerWrapper)(imgContainerRef.current, "shape-select", (e) => { + const id = e.detail; + setSelectRectId(id); + const selectShape = shapeList.find((v) => v["id"] === id); + if (selectShape) { + setSelectAlgorithmVersion(selectShape["algorithmVersion"]); + const axisRect = imgIns.imgRectAxisToCanvasAxisRect(selectShape); + const rect2 = { + x: axisRect.x2 > axisRect.x ? axisRect.x : axisRect.x2, + y: axisRect.y2 > axisRect.y ? axisRect.y : axisRect.y2, + w: Math.abs(axisRect.x2 - axisRect.x), + h: Math.abs(axisRect.y2 - axisRect.y) + }; + setCropRect(rect2); + } else { + setCropRect(null); + } + }); + }; + const rect = (0, import_func.getOdRect)({ objects: _objects }); + setOdList(rect); + handleGetOD(rect); + } + if (cropType === import_constants.CROP_TYPE["CUSTOM"]) { + (_b2 = imgIns == null ? void 0 : imgIns.clearShape) == null ? void 0 : _b2.call(imgIns); + handlerCropStartRef.current = (0, import_func.addEventListenerWrapper)(imgContainerRef.current, import_ImageEditor.EVENT_CROP_START, () => { + setSelectAlgorithmVersion(null); + setCropRect(null); + }); + handlerCropEndRef.current = (0, import_func.addEventListenerWrapper)(imgContainerRef.current, import_ImageEditor.EVENT_CROP_END, (event) => { + var _a3, _b3; + const data = event.detail; + setSelectAlgorithmVersion(null); + setCropRect({ + x: data.left, + y: data.top, + w: data.width, + h: data.height + }); + (_b3 = (_a3 = alignRef == null ? void 0 : alignRef.current) == null ? void 0 : _a3.forceAlign) == null ? void 0 : _b3.call(_a3); + }); + cropInsRef.current = new import_ImageEditor.Cropper(imgContainerRef.current, { + showMask: true, + viewer: imgIns + }); + } + }; + const latestCropType = (0, import_hooks.useLatest)(cropType); + const latestImgKey = (0, import_hooks.useLatest)(dataSource[currentIndex].imageKey); + const latestCropRect = (0, import_hooks.useLatest)(cropRect); + const getCropInfo = async () => { + const cropType2 = latestCropType.current; + const cropRect2 = latestCropRect.current; + const imgIns = imgInsRef.current; + const transform = imgIns.targetTransform; + let newImgKey = latestImgKey.current; + let rectList = []; + let extendRectList = []; + let selectIndex = 0; + switch (cropType2) { + case import_constants.CROP_TYPE["AUTO"]: + const shapes = imgIns.getSelectShape(); + const shapeIds = shapes.map((v) => v["id"]); + rectList = odList.filter((v) => shapeIds.includes(v["id"])).map((item) => { + if (item.algorithmVersion === "OBJECT_TYPE_FACE" || item.objectType === "OBJECT_TYPE_FACE") { + if (!(0, import_func.isNull)(item.extendBox)) { + return { + ...item, + w: (0, import_func.get)(item, "extendBox.w"), + h: (0, import_func.get)(item, "extendBox.h"), + x: (0, import_func.get)(item, "extendBox.x"), + y: (0, import_func.get)(item, "extendBox.y") + }; + } + } else { + return item; + } + }); + extendRectList = extendOdList.filter((v) => shapeIds.includes(v["id"])).map((v) => (0, import_func.pick)(v, ["x", "y", "w", "h", "algorithmVersion", "id"])); + selectIndex = rectList.findIndex((v) => v["id"] === selectRectId); + break; + default: + const newRect = (0, import_func.getTransformRect)(imgIns.image, transform, cropRect2); + if ((0, import_func.get)(transform, "rotate", 0) % 360 != 0) { + const data = (0, import_func.getRotateImg)(imgIns.image, (0, import_func.get)(transform, "rotate", 0)); + newImgKey = await (0, import_func.upload)(data); + } + rectList.push(newRect); + extendRectList.push(newRect); + break; + } + await Promise.all( + extendRectList.map(async (rect, index) => { + const file = await (0, import_func.getFileByRect)(imgIns.image, rect); + const imgKey = await (0, import_func.upload)(file); + extendRectList[index] = { ...rect, imgKey }; + }) + ); + await Promise.all( + rectList.map(async (rect, index) => { + const faceCorrectImage = rect["faceCorrectImage"]; + let faceCorrectImageKey; + if (faceCorrectImage) { + const base64 = `data:image/jpg;base64,${faceCorrectImage}`; + const blobData = (0, import_func.dataURLToBlob)(base64); + const file = new window.File([blobData], `${(/* @__PURE__ */ new Date()).getTime()}`); + faceCorrectImageKey = await (0, import_func.upload)(file); + } + const newRect = { + ...rect, + ...faceCorrectImageKey ? { faceCorrectImageKey } : {} + }; + delete newRect["faceCorrectImage"]; + rectList[index] = newRect; + }) + ); + return { rectList, extendRectList, selectIndex, imgKey: newImgKey }; + }; + const handleCropBtnClick = (v) => { + switch (v) { + case "close": + setShowCrop(false); + break; + case "autoCrop": + setCropType(import_constants.CROP_TYPE["AUTO"]); + break; + case "customCrop": + setCropType(import_constants.CROP_TYPE["CUSTOM"]); + break; + } + }; + const [selectAttachImgIndex, setSelectAttachImgIndex] = (0, import_react.useState)(0); + const [isZoomin, setIsZoomin] = (0, import_react.useState)(false); + const handleChangeIndex = (diff) => { + var _a2; + const _index = currentIndex + diff; + if (!((_a2 = dataSource == null ? void 0 : dataSource[_index]) == null ? void 0 : _a2.imageKey)) + return; + setCurrentIndex(_index); + }; + (0, import_react.useImperativeHandle)(ref, () => ({ + imgInsRef, + setShowCrop, + initData, + getCropInfo, + handleChangeIndex + })); + return /* @__PURE__ */ import_react.default.createElement("div", { className: (0, import_classnames.default)(`${componentName}`), style: { height, width } }, dataSource.length ? /* @__PURE__ */ import_react.default.createElement(import_react.default.Fragment, null, /* @__PURE__ */ import_react.default.createElement( + "div", + { + className: (0, import_classnames.default)( + `${componentName}-main`, + cropType === import_constants.CROP_TYPE["AUTO"] && `${componentName}-main--cursor` + ), + ref: init + } + ), !hideLeftTopBtn && /* @__PURE__ */ import_react.default.createElement( + import_BtnGroup.default, + { + className: (0, import_classnames.default)(`${componentName}-opt`), + dataSource: operateBtnDataSource, + onClick: handleOptClick, + placement: "left" + } + ), showCrop && /* @__PURE__ */ import_react.default.createElement( + import_BtnGroup.default, + { + circle: true, + className: (0, import_classnames.default)(`${componentName}-crop-opt`), + dataSource: cropBtnDataSource, + onClick: handleCropBtnClick, + selectKey: cropType === import_constants.CROP_TYPE["AUTO"] ? "autoCrop" : "customCrop" + } + ), showCrop && cropRect && screenshotButtonRender && /* @__PURE__ */ import_react.default.createElement(import_react.default.Fragment, null, /* @__PURE__ */ import_react.default.createElement( + "div", + { + ref: alginContainerRef, + className: (0, import_classnames.default)(`${componentName}-align`), + style: Object.assign( + { + width: cropRect.w, + height: cropRect.h + }, + (0, import_func.getTransforms)({ + translateX: cropRect.x, + translateY: cropRect.y + }) + ) + } + ), /* @__PURE__ */ import_react.default.createElement( + import_rc_align.default, + { + ref: alignRef, + monitorWindowResize: true, + align: screenshotButtonAlign, + target: function() { + return alginContainerRef.current; + } + }, + screenshotButtonRender({ + model: "IMAGE", + getCropInfo, + setShowCrop, + cropType, + selectAlgorithmVersion + }) + )), ((_a = dataSource[currentIndex].attachImg) == null ? void 0 : _a.length) && !showCrop && /* @__PURE__ */ import_react.default.createElement( + "div", + { + className: (0, import_classnames.default)( + `${componentName}-attach`, + isZoomin && `${componentName}-attach--zoomin`, + `${componentName}-attach--fixed`, + isZoomin && `${componentName}-attach--zoomin--fixed` + ) + }, + /* @__PURE__ */ import_react.default.createElement("div", { className: (0, import_classnames.default)(`${componentName}-attach__tab`) }, showAttachImgLabel ? (_b = dataSource[currentIndex].attachImg) == null ? void 0 : _b.map(({ label }, index) => /* @__PURE__ */ import_react.default.createElement( + "div", + { + key: index, + className: (0, import_classnames.default)( + `${componentName}-attach__tab-item`, + selectAttachImgIndex === index && `${componentName}-attach__tab-item--select` + ), + onMouseEnter: () => { + setSelectAttachImgIndex(index); + } + }, + label + )) : null), + /* @__PURE__ */ import_react.default.createElement("div", { className: (0, import_classnames.default)(`${componentName}-attach__scale`) }, /* @__PURE__ */ import_react.default.createElement( + import_antd.Button, + { + type: "text", + onMouseDown: (e) => { + if (e.button == 0) { + setIsZoomin((pre) => !pre); + } + }, + style: { + color: "#fff" + } + }, + /* @__PURE__ */ import_react.default.createElement( + import_iconfont.default, + { + styles: { display: "flex" }, + icon: isZoomin ? "icon-cancle_fullscreen" : "icon-fullscreen" + } + ) + )), + /* @__PURE__ */ import_react.default.createElement( + "img", + { + draggable: "false", + className: (0, import_classnames.default)( + `${componentName}-attach__img`, + `${componentName}-attach__img--fixed` + ), + src: (0, import_func.get)(dataSource[currentIndex].attachImg, `${selectAttachImgIndex}.url`, "") + } + ) + ), showScore && /* @__PURE__ */ import_react.default.createElement( + "div", + { + style: { bottom: 20 }, + className: (0, import_classnames.default)(`${componentName}__face-score`) + }, + `人脸质量分:${Number(dataSource[currentIndex].score).toFixed(2)}` + )) : /* @__PURE__ */ import_react.default.createElement(import_antd.Empty, { image: import_antd.Empty.PRESENTED_IMAGE_SIMPLE, description: "暂无数据" })); +}); +BigImagePreview.displayName = "BigImagePreview"; +var BigImagePreview_default = BigImagePreview; +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + BigImagePreview +}); diff --git a/packages/meta/es/ImagePreview/components/CornerScore/index.less b/packages/meta/lib/BigImagePreview/bigImagePreviewHelper.d.ts similarity index 100% rename from packages/meta/es/ImagePreview/components/CornerScore/index.less rename to packages/meta/lib/BigImagePreview/bigImagePreviewHelper.d.ts diff --git a/packages/meta/lib/ImagePreview/components/CornerScore/index.less b/packages/meta/lib/BigImagePreview/bigImagePreviewHelper.js similarity index 100% rename from packages/meta/lib/ImagePreview/components/CornerScore/index.less rename to packages/meta/lib/BigImagePreview/bigImagePreviewHelper.js diff --git a/packages/meta/lib/BigImagePreview/components/BtnGroup/index.d.ts b/packages/meta/lib/BigImagePreview/components/BtnGroup/index.d.ts new file mode 100644 index 0000000..960a037 --- /dev/null +++ b/packages/meta/lib/BigImagePreview/components/BtnGroup/index.d.ts @@ -0,0 +1,17 @@ +import React, { MouseEvent } from 'react'; +import { TooltipProps } from 'antd'; +import './index.less'; +export interface BtnGroupProps { + className: string; + dataSource: Array<{ + key: string; + icon: string; + title: string; + }>; + onClick: (v: string, e: MouseEvent) => void; + selectKey?: string; + circle?: boolean; + placement?: TooltipProps['placement']; +} +export declare const BtnGroup: React.FC; +export default BtnGroup; diff --git a/packages/meta/lib/BigImagePreview/components/BtnGroup/index.js b/packages/meta/lib/BigImagePreview/components/BtnGroup/index.js new file mode 100644 index 0000000..8413f3f --- /dev/null +++ b/packages/meta/lib/BigImagePreview/components/BtnGroup/index.js @@ -0,0 +1,83 @@ +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// src/BigImagePreview/components/BtnGroup/index.tsx +var BtnGroup_exports = {}; +__export(BtnGroup_exports, { + BtnGroup: () => BtnGroup, + default: () => BtnGroup_default +}); +module.exports = __toCommonJS(BtnGroup_exports); +var import_react = __toESM(require("react")); +var import_classnames = __toESM(require("classnames")); +var import_antd = require("antd"); +var import_iconfont = __toESM(require("../../../iconfont")); +var import_index = require("./index.less"); +var componentName = `zhst-image__btn-group`; +var BtnGroup = (props) => { + const { dataSource, onClick, className, circle, selectKey = "", placement = "right" } = props; + return /* @__PURE__ */ import_react.default.createElement( + "div", + { + className: (0, import_classnames.default)( + componentName, + circle && `${componentName}--circle`, + className + ) + }, + dataSource.map(({ key, icon, title }) => { + const isSelect = key === selectKey; + return /* @__PURE__ */ import_react.default.createElement(import_antd.Tooltip, { key, placement, title }, /* @__PURE__ */ import_react.default.createElement( + "div", + { + key, + className: (0, import_classnames.default)( + `${componentName}__item`, + isSelect && `${componentName}__item--active` + ) + }, + /* @__PURE__ */ import_react.default.createElement( + import_antd.Button, + { + type: "text", + onClick: (e) => { + onClick(key, e); + } + }, + /* @__PURE__ */ import_react.default.createElement(import_iconfont.default, { size: 18, icon }) + ) + )); + }) + ); +}; +BtnGroup.displayName = "BtnGroup"; +var BtnGroup_default = BtnGroup; +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + BtnGroup +}); diff --git a/packages/meta/lib/BigImagePreview/components/BtnGroup/index.less b/packages/meta/lib/BigImagePreview/components/BtnGroup/index.less new file mode 100644 index 0000000..db03187 --- /dev/null +++ b/packages/meta/lib/BigImagePreview/components/BtnGroup/index.less @@ -0,0 +1,51 @@ +.zhst-image__btn-group { + // display: flex; + width: 30px; + box-shadow: 0 2px 6px 0 rgb(0 0 0 / 40%); + + &__item { + display: flex; + width: 30px; + height: 30px; + align-items: center; + justify-content: center; + background: #000; + + &>button { + padding: 0; + color: #fff; + + &:hover { + color: #09f; + } + + &:active { + color: #09f; + } + + &:focus { + color: #fff; + } + + &>span { + display: flex; + } + } + + &--active { + &>button { + color: #09f; + } + } + } + + &--circle { + background-color: none; + box-shadow: none; + } + + &--circle &__item { + margin-bottom: 4px; + border-radius: 50%; + } +} diff --git a/packages/meta/lib/BigImagePreview/components/ScreenhotButtons/index.d.ts b/packages/meta/lib/BigImagePreview/components/ScreenhotButtons/index.d.ts new file mode 100644 index 0000000..cb09279 --- /dev/null +++ b/packages/meta/lib/BigImagePreview/components/ScreenhotButtons/index.d.ts @@ -0,0 +1,14 @@ +import React from 'react'; +import type { AlgorithmVersion } from '@zhst/types'; +import './index.less'; +interface IScreenShotButton { + getCropInfo: () => void; + setShowCrop: any; + cropType: string; + selectAlgorithmVersion?: AlgorithmVersion | null; +} +declare const getScreenshotButtonRender: (arg: { + disableBtn: number[]; + onBigImageActionClick: (type: number, item: any) => void; +}) => (param: IScreenShotButton) => React.JSX.Element; +export default getScreenshotButtonRender; diff --git a/packages/meta/lib/BigImagePreview/components/ScreenhotButtons/index.js b/packages/meta/lib/BigImagePreview/components/ScreenhotButtons/index.js new file mode 100644 index 0000000..d39af2e --- /dev/null +++ b/packages/meta/lib/BigImagePreview/components/ScreenhotButtons/index.js @@ -0,0 +1,126 @@ +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// src/BigImagePreview/components/ScreenhotButtons/index.tsx +var ScreenhotButtons_exports = {}; +__export(ScreenhotButtons_exports, { + default: () => ScreenhotButtons_default +}); +module.exports = __toCommonJS(ScreenhotButtons_exports); +var import_react = __toESM(require("react")); +var import_antd = require("antd"); +var import_classnames = __toESM(require("classnames")); +var import_BigImageModal = require("@zhst/types/BigImageModal"); +var import_index = require("./index.less"); +var componentName = "bigImageWrapper--v2"; +var getScreenshotButtonRender = (arg) => { + const { disableBtn = [], onBigImageActionClick } = arg; + return (param) => { + const { getCropInfo, setShowCrop, cropType, selectAlgorithmVersion } = param; + let isAuto = cropType === "AUTO"; + return /* @__PURE__ */ import_react.default.createElement( + "div", + { + className: (0, import_classnames.default)(`${componentName}__screenshot`), + style: { + zIndex: 100, + position: "absolute", + width: "86px" + } + }, + !disableBtn.includes(import_BigImageModal.IBigImageOpt["ADD_HISTORY_WITH_CROP"]) && isAuto && /* @__PURE__ */ import_react.default.createElement( + import_antd.Button, + { + type: "text", + onClick: async (e) => { + e.stopPropagation(); + const image = await getCropInfo(); + setShowCrop(false); + onBigImageActionClick(import_BigImageModal.IBigImageOpt["ADD_HISTORY_WITH_CROP"], image); + } + }, + "目标检索" + ), + !disableBtn.includes(import_BigImageModal.IBigImageOpt["ADD_HISTORY_WITH_CROP_BODY"]) && !isAuto && /* @__PURE__ */ import_react.default.createElement( + import_antd.Button, + { + type: "text", + onClick: async (e) => { + e.stopPropagation(); + const image = await getCropInfo(); + setShowCrop(false); + onBigImageActionClick(import_BigImageModal.IBigImageOpt["ADD_HISTORY_WITH_CROP_BODY"], image); + } + }, + "搜形体" + ), + !disableBtn.includes(import_BigImageModal.IBigImageOpt["ADD_HISTORY_WITH_CROP_VEHICLE"]) && !isAuto && /* @__PURE__ */ import_react.default.createElement( + import_antd.Button, + { + type: "text", + onClick: async (e) => { + e.stopPropagation(); + const image = await getCropInfo(); + setShowCrop(false); + onBigImageActionClick(import_BigImageModal.IBigImageOpt["ADD_HISTORY_WITH_CROP_VEHICLE"], image); + } + }, + "搜非机动车" + ), + !disableBtn.includes(import_BigImageModal.IBigImageOpt["ADD_HISTORY_WITH_CROP_ARCHIVE"]) && selectAlgorithmVersion !== 0 && /* @__PURE__ */ import_react.default.createElement( + import_antd.Button, + { + type: "text", + onClick: (e) => { + e.stopPropagation(); + let image = getCropInfo(); + setShowCrop(false); + if (!image.rectList[0].algorithmVersion) { + image.rectList[0].algorithmVersion = 0; + image.extendRectList[0].algorithmVersion = 0; + } + onBigImageActionClick(import_BigImageModal.IBigImageOpt["ADD_HISTORY_WITH_CROP_ARCHIVE"], image); + } + }, + "档案检索" + ), + /* @__PURE__ */ import_react.default.createElement( + import_antd.Button, + { + type: "text", + onClick: (e) => { + e.stopPropagation(); + setShowCrop(false); + } + }, + "退出框选" + ) + ); + }; +}; +var ScreenhotButtons_default = getScreenshotButtonRender; diff --git a/packages/meta/lib/BigImagePreview/components/ScreenhotButtons/index.less b/packages/meta/lib/BigImagePreview/components/ScreenhotButtons/index.less new file mode 100644 index 0000000..ca407fa --- /dev/null +++ b/packages/meta/lib/BigImagePreview/components/ScreenhotButtons/index.less @@ -0,0 +1,21 @@ +.bigImageWrapper--v2__screenshot { + min-width: 90px; + background: rgb(0 0 0 / 50%); + border-radius: 0; + + &>button { + width: 100%; + color: #fff !important; + font-family: 'Microsoft YaHei'; + font-size: 12px !important; + border-radius: 0; + + &>span { + color: #fff; + } + + &:hover { + background-color: #09f !important; + } + } +} diff --git a/packages/meta/lib/BigImagePreview/index.d.ts b/packages/meta/lib/BigImagePreview/index.d.ts new file mode 100644 index 0000000..7469634 --- /dev/null +++ b/packages/meta/lib/BigImagePreview/index.d.ts @@ -0,0 +1,3 @@ +import BigImagePreview from './BigImagePreview'; +export type { ImgViewProps } from './BigImagePreview'; +export default BigImagePreview; diff --git a/packages/meta/lib/BigImagePreview/index.js b/packages/meta/lib/BigImagePreview/index.js new file mode 100644 index 0000000..3944af4 --- /dev/null +++ b/packages/meta/lib/BigImagePreview/index.js @@ -0,0 +1,36 @@ +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// src/BigImagePreview/index.tsx +var BigImagePreview_exports = {}; +__export(BigImagePreview_exports, { + default: () => BigImagePreview_default +}); +module.exports = __toCommonJS(BigImagePreview_exports); +var import_BigImagePreview = __toESM(require("./BigImagePreview")); +var BigImagePreview_default = import_BigImagePreview.default; diff --git a/packages/meta/lib/BigImagePreview/index.less b/packages/meta/lib/BigImagePreview/index.less new file mode 100644 index 0000000..d192880 --- /dev/null +++ b/packages/meta/lib/BigImagePreview/index.less @@ -0,0 +1,123 @@ +.zhst-image__img-view { + position: relative; + width: calc(100%); + height: 100%; + + &__face-score { + position: absolute; + right: 20px; + bottom: 80px; + color: red; + font-family: 'Microsoft YaHei'; + font-size: 19px; + font-weight: bold; + } + + &-opt { + position: absolute; + z-index: 99; + top: 0; + } + + &-crop-opt { + position: absolute; + z-index: 99; + top: 0; + right: 0; + } + + &-align { + position: absolute; + top: 0; + left: 0; + pointer-events: none; + } + + &-main { + width: 100%; + height: 100%; + font-size: 0; + + &--cursor { + & canvas { + min-height: 320px; + cursor: pointer; + } + } + } + + &-screenshot { + position: absolute; + z-index: 10; + } + + &-attach { + position: absolute; + z-index: 11; + bottom: 0; + + // left: 78px; + left: 0; + min-width: 120px; + height: 202px; + transition: all 200ms; + + &--zoomin { + height: 100%; + } + + &__tab { + position: absolute; + top: 0; + left: 0; + display: flex; + + &-item { + display: flex; + width: 30px; + height: 24px; + align-items: center; + justify-content: center; + background: #000; + color: #fff; + cursor: pointer; + font-size: 12px; + opacity: 0.5; + transition: all 200ms; + + &--select { + width: 48px; + height: 34px; + background: #09f; + opacity: 1; + } + } + } + + &__scale { + position: absolute; + top: 4px; + right: 4px; + display: flex; + width: 30px; + height: 30px; + align-items: center; + justify-content: center; + background: rgb(0 0 0 / 60%); + border-radius: 100%; + cursor: pointer; + line-height: 30px; + text-align: center; + } + + &__img { + height: 100%; + object-fit: contain; + + &--fixed { + width: 100%; + object-fit: contain; + } + } + } +} diff --git a/packages/meta/lib/CompareImage/CompareImage.d.ts b/packages/meta/lib/CompareImage/CompareImage.d.ts new file mode 100644 index 0000000..18fbaca --- /dev/null +++ b/packages/meta/lib/CompareImage/CompareImage.d.ts @@ -0,0 +1,20 @@ +import React from 'react'; +import './index.less'; +export interface CompareImageProps { + /** + * @description 属性描述 + * @default "默认值" + */ + label: string; + openRoll?: boolean; + dataSource?: Array<{ + url: string; + score: number; + }>; + showScore?: boolean; + current: number; +} +export interface CompareImageRefProps { +} +declare const CompareImage: React.ForwardRefExoticComponent>; +export default CompareImage; diff --git a/packages/meta/lib/ImagePreview/index.js b/packages/meta/lib/CompareImage/CompareImage.js similarity index 79% rename from packages/meta/lib/ImagePreview/index.js rename to packages/meta/lib/CompareImage/CompareImage.js index 79d5a26..78f4153 100644 --- a/packages/meta/lib/ImagePreview/index.js +++ b/packages/meta/lib/CompareImage/CompareImage.js @@ -26,12 +26,12 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); -// src/ImagePreview/index.tsx -var ImagePreview_exports = {}; -__export(ImagePreview_exports, { - default: () => ImagePreview_default +// src/CompareImage/CompareImage.tsx +var CompareImage_exports = {}; +__export(CompareImage_exports, { + default: () => CompareImage_default }); -module.exports = __toCommonJS(ImagePreview_exports); +module.exports = __toCommonJS(CompareImage_exports); var import_react = __toESM(require("react")); var import_func = require("@zhst/func"); var import_hooks = require("@zhst/hooks"); @@ -40,25 +40,16 @@ var import_classnames = __toESM(require("classnames")); var import_viewer = __toESM(require("../ImageEditor/viewer")); var import_iconfont = __toESM(require("../iconfont")); var import_CornerScore = __toESM(require("./components/CornerScore")); +var import_index = require("./index.less"); var componentName = `zhst-image__compater-view`; -var CompaterImage = (props) => { - const { url, label, openRoll = false, urls = [], score } = props; +var CompareImage = (0, import_react.forwardRef)((props, ref) => { + const { label, openRoll = false, dataSource = [], showScore = true, current = 0 } = props; const imgContainerRef = (0, import_react.useRef)(null); const imgInsRef = (0, import_react.useRef)(null); const [scale, setScale] = (0, import_react.useState)(0); - const [showUrl, setShowUrl] = (0, import_react.useState)((0, import_func.generateImg)(url)); - (0, import_hooks.useUpdateEffect)(() => { - var _a; - setShowUrl((0, import_func.generateImg)(url)); - if (imgInsRef.current) { - (_a = imgInsRef.current) == null ? void 0 : _a.refleshImage({ - image: (0, import_func.generateImg)(url) - }); - } - }, [url]); + const [currentIndex, setCurrentIndex] = (0, import_react.useState)(current); (0, import_react.useEffect)(() => { - setShowUrl(url); - const handleTransformChange = (0, import_func.addEventListener)( + const handleTransformChange = (0, import_func.addEventListenerWrapper)( imgContainerRef.current, "viewer-transform-change", (event) => { @@ -66,9 +57,11 @@ var CompaterImage = (props) => { setScale((0, import_func.get)(data, "scale", 0)); } ); - imgInsRef.current = new import_viewer.default(imgContainerRef.current, { - image: (0, import_func.generateImg)(url) - }); + if ((0, import_func.generateImg)(dataSource[currentIndex].url)) { + imgInsRef.current = new import_viewer.default(imgContainerRef.current, { + image: (0, import_func.generateImg)(dataSource[currentIndex].url) + }); + } return () => { var _a, _b; handleTransformChange == null ? void 0 : handleTransformChange.remove(); @@ -76,42 +69,42 @@ var CompaterImage = (props) => { imgInsRef.current = null; }; }, []); - const handlePre = (0, import_react.useCallback)(() => { + (0, import_hooks.useUpdateEffect)(() => { var _a; - const index = urls.findIndex((v) => v === showUrl); - if (index > 0) { - const newUrl = urls[index - 1]; - setShowUrl(newUrl); + if (imgInsRef.current) { (_a = imgInsRef.current) == null ? void 0 : _a.refleshImage({ - image: newUrl + image: (0, import_func.generateImg)(dataSource[currentIndex].url) }); } - }, [showUrl, urls]); - const handleNext = (0, import_react.useCallback)(() => { - var _a; - const index = urls.findIndex((v) => v === showUrl); - if (index >= 0 && !!urls[index + 1]) { - const newUrl = urls[index + 1]; - setShowUrl(newUrl); - (_a = imgInsRef.current) == null ? void 0 : _a.refleshImage({ - image: newUrl - }); - } - }, [showUrl, urls]); - return /* @__PURE__ */ import_react.default.createElement("div", { className: (0, import_classnames.default)(`${componentName}__container`) }, /* @__PURE__ */ import_react.default.createElement("div", { className: (0, import_classnames.default)(`${componentName}__label`) }, label), /* @__PURE__ */ import_react.default.createElement("div", { ref: imgContainerRef, className: (0, import_classnames.default)(`${componentName}__view`) }), !url && /* @__PURE__ */ import_react.default.createElement("div", { className: (0, import_classnames.default)(`${componentName}__empty`) }, /* @__PURE__ */ import_react.default.createElement( + }, [currentIndex]); + const handleIndexChange = (changeVal) => { + var _a, _b; + const _index = currentIndex + changeVal; + if (!((_a = dataSource == null ? void 0 : dataSource[_index]) == null ? void 0 : _a.url)) + return; + (_b = imgInsRef.current) == null ? void 0 : _b.refleshImage({ + image: (0, import_func.generateImg)(dataSource[_index].url) + }); + setCurrentIndex(_index); + }; + (0, import_react.useImperativeHandle)(ref, () => ({ + imgInsRef, + handleIndexChange + })); + return /* @__PURE__ */ import_react.default.createElement("div", { className: (0, import_classnames.default)(`${componentName}__container`) }, /* @__PURE__ */ import_react.default.createElement("div", { className: (0, import_classnames.default)(`${componentName}__label`) }, label), /* @__PURE__ */ import_react.default.createElement("div", { ref: imgContainerRef, className: (0, import_classnames.default)(`${componentName}__view`) }), !dataSource.length && /* @__PURE__ */ import_react.default.createElement("div", { className: (0, import_classnames.default)(`${componentName}__empty`) }, /* @__PURE__ */ import_react.default.createElement( "img", { src: "data:image/png;base64,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", title: "暂无数据" } - ), /* @__PURE__ */ import_react.default.createElement("span", { className: (0, import_classnames.default)(`${componentName}__empty--text`) }, "暂无匹配数据")), !!url && openRoll && /* @__PURE__ */ import_react.default.createElement("div", { className: (0, import_classnames.default)(`${componentName}__scoll-module`) }, /* @__PURE__ */ import_react.default.createElement( + ), /* @__PURE__ */ import_react.default.createElement("span", { className: (0, import_classnames.default)(`${componentName}__empty--text`) }, "暂无匹配数据")), !!dataSource.length && openRoll && /* @__PURE__ */ import_react.default.createElement("div", { className: (0, import_classnames.default)(`${componentName}__scoll-module`) }, /* @__PURE__ */ import_react.default.createElement( import_antd.Button, { type: "default", className: (0, import_classnames.default)(`${componentName}__scoll-module__btn`), - disabled: !urls[urls.findIndex((v) => v === showUrl) - 1], + disabled: currentIndex <= 0, onClick: () => { - handlePre(); + handleIndexChange(-1); } }, /* @__PURE__ */ import_react.default.createElement(import_iconfont.default, { icon: "icon-qiehuanzuo", size: 40 }) @@ -120,13 +113,13 @@ var CompaterImage = (props) => { { type: "default", className: (0, import_classnames.default)(`${componentName}__scoll-module__btn`), - disabled: !urls[urls.findIndex((v) => v === showUrl) + 1], + disabled: currentIndex >= dataSource.length - 1, onClick: () => { - handleNext(); + handleIndexChange(1); } }, /* @__PURE__ */ import_react.default.createElement(import_iconfont.default, { icon: "icon-qiehuanyou", size: 40 }) - )), !!score && /* @__PURE__ */ import_react.default.createElement(import_CornerScore.default, { scoreTxt: score }), /* @__PURE__ */ import_react.default.createElement("div", { className: (0, import_classnames.default)(`${componentName}__tool`) }, /* @__PURE__ */ import_react.default.createElement( + )), showScore && /* @__PURE__ */ import_react.default.createElement(import_CornerScore.default, { scoreTxt: dataSource[currentIndex].score }), /* @__PURE__ */ import_react.default.createElement("div", { className: (0, import_classnames.default)(`${componentName}__tool`) }, /* @__PURE__ */ import_react.default.createElement( import_antd.Button, { type: "text", @@ -160,5 +153,5 @@ var CompaterImage = (props) => { /* @__PURE__ */ import_react.default.createElement(import_iconfont.default, { size: 16, icon: "icon-zhongzhi3" }), /* @__PURE__ */ import_react.default.createElement("span", null, "重置") ))); -}; -var ImagePreview_default = CompaterImage; +}); +var CompareImage_default = CompareImage; diff --git a/packages/meta/lib/ImagePreview/components/CornerScore/index.d.ts b/packages/meta/lib/CompareImage/components/CornerScore/index.d.ts similarity index 100% rename from packages/meta/lib/ImagePreview/components/CornerScore/index.d.ts rename to packages/meta/lib/CompareImage/components/CornerScore/index.d.ts diff --git a/packages/meta/lib/ImagePreview/components/CornerScore/index.js b/packages/meta/lib/CompareImage/components/CornerScore/index.js similarity index 97% rename from packages/meta/lib/ImagePreview/components/CornerScore/index.js rename to packages/meta/lib/CompareImage/components/CornerScore/index.js index f4800a2..916d94f 100644 --- a/packages/meta/lib/ImagePreview/components/CornerScore/index.js +++ b/packages/meta/lib/CompareImage/components/CornerScore/index.js @@ -26,7 +26,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); -// src/ImagePreview/components/CornerScore/index.tsx +// src/CompareImage/components/CornerScore/index.tsx var CornerScore_exports = {}; __export(CornerScore_exports, { CornerScore: () => CornerScore, diff --git a/packages/meta/lib/CompareImage/components/CornerScore/index.less b/packages/meta/lib/CompareImage/components/CornerScore/index.less new file mode 100644 index 0000000..cb8bf35 --- /dev/null +++ b/packages/meta/lib/CompareImage/components/CornerScore/index.less @@ -0,0 +1,21 @@ +.zhst-image__CornerScore { + position: absolute; + right: 0; + bottom: 0; + width: 56px; + height: 22px; + line-height: 22px; + text-align: right; + padding-right: 1px; + background-size: 100%; + background-image: url('data: image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHAAAAAsCAYAAAC9rDzHAAAByUlEQVR4Xu2cO08DMRCEJy0tlNBCSwmU0EIJLbS0UEILLTX/Fo3kk1AUHrrsjB3dWIoUnZTdvfnOZ6+1mxXGGHsADgEcA9hvnyMAvJ7xiwKrjuoQ0HmDxu8ZMxToAZDQrgAE2gxg6z9xAjwFcAvgoCDumGgKuADeA7iI6vUKqAFyE/KU12U9uMmiGuBr4Ong0bIS4A2Aa234sa4CyFzuPfLqFVABfGg5nv4OFu5BAZAbl4+F62q7fQVAJul3tjtYuCMFwEcATNozDAooAL7ltMVATngS8+kLP54UMzAAjc9VABrFVrgKQIWqRpsBaBRb4SoAFaoabQagUWyFqwBUqGq0GYBGsRWuAlChqtFmABrFVrgKQIWqRpsBaBRb4SoAFaoabVYDZLU1K9EyTApUA2RzyrMp9rgRlBWylIIlFRkmBapnIIuZ0hJmgkc3lQBTzGQEN7mqApjNSwd4VTOQr8yXFDL1IbjtDOTMY/dR1r0+/LZaA1n7yb6/wOsEb+4rlMDYdZR0oSO4uZuYtEkPAO17CP9dA3nCwll3Mlj8iw/nL4ABN/gj8hPAgBsc3KY1kJuTs7Y5yV+B7BBA5nKXrSUsKcGOgJvC/ALSJBp5mBHCFAAAAABJRU5ErkJggg=='); + z-index: 99; + + &>span { + padding-right: 6px; + line-height: 22px; + font-size: 12px; + vertical-align: middle; + color: rgba(255, 255, 255, 100%); + } +} diff --git a/packages/meta/src/ImagePreview/images/emptyImage.png b/packages/meta/lib/CompareImage/images/emptyImage.png similarity index 100% rename from packages/meta/src/ImagePreview/images/emptyImage.png rename to packages/meta/lib/CompareImage/images/emptyImage.png diff --git a/packages/meta/src/ImagePreview/images/percent_background.png b/packages/meta/lib/CompareImage/images/percent_background.png similarity index 100% rename from packages/meta/src/ImagePreview/images/percent_background.png rename to packages/meta/lib/CompareImage/images/percent_background.png diff --git a/packages/meta/lib/CompareImage/index.d.ts b/packages/meta/lib/CompareImage/index.d.ts new file mode 100644 index 0000000..a72b6a9 --- /dev/null +++ b/packages/meta/lib/CompareImage/index.d.ts @@ -0,0 +1,3 @@ +import CompareImage from "./CompareImage"; +export type { CompareImageProps } from './CompareImage'; +export default CompareImage; diff --git a/packages/meta/lib/CompareImage/index.js b/packages/meta/lib/CompareImage/index.js new file mode 100644 index 0000000..2db3382 --- /dev/null +++ b/packages/meta/lib/CompareImage/index.js @@ -0,0 +1,36 @@ +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// src/CompareImage/index.tsx +var CompareImage_exports = {}; +__export(CompareImage_exports, { + default: () => CompareImage_default +}); +module.exports = __toCommonJS(CompareImage_exports); +var import_CompareImage = __toESM(require("./CompareImage")); +var CompareImage_default = import_CompareImage.default; diff --git a/packages/meta/lib/CompareImage/index.less b/packages/meta/lib/CompareImage/index.less new file mode 100644 index 0000000..378f365 --- /dev/null +++ b/packages/meta/lib/CompareImage/index.less @@ -0,0 +1,147 @@ +.zhst-image__compater-view { + display: flex; + width: 100%; + align-items: center; + justify-content: center; + + &>div:first-child { + margin-right: 25px; + } + + &>div:last-child { + margin-left: 25px; + } + + &__container { + position: relative; + width: 345px; + height: 460px; + box-sizing: content-box; + border: 1px solid #f0f0f0; + } + + &__view { + width: 345px; + height: 460px; + } + + &__label { + position: absolute; + z-index: 99; + top: 0; + left: 0; + display: flex; + height: 34px; + align-items: center; + justify-content: center; + + // width: 48px; + padding: 0 6px; + background: #09f; + color: #fff; + } + + &__tool { + display: flex; + width: 345px; + height: 40px; + align-items: center; + justify-content: center; + background: #f9f9f9; + + i, + span { + color: #333 !important; + } + + i { + margin-right: 4px; + } + + &>*:not(:last-child) { + margin-right: 20px; + } + + &__scale { + display: inline-block; + width: 38px; + height: 16px; + + // margin-left: 15px; + box-sizing: content-box; + border: 1px solid rgb(77 77 77 / 100%); + background: rgb(255 255 255 / 100%); + border-radius: 2px; + color: #4d4d4d; + cursor: default; + font-size: 12px; + line-height: 16px; + text-align: center; + } + + &__line { + width: 1px; + height: 14px; + background: #e6e6e6; + } + } + + &__empty { + position: absolute; + z-index: 9; + display: flex; + width: 100%; + height: 100%; + flex-direction: column; + align-items: center; + justify-content: center; + background: #f9f9f9; + transform: translateY(-100%); + + &>img { + width: 140px; + height: 80px; + } + + &--text { + color: #999; + font-size: 14px; + line-height: 22px; + } + } + + &__scoll-module { + position: absolute; + top: 0%; + left: 0%; + display: flex; + width: 100%; + height: 100%; + align-items: flex-end; + justify-content: space-between; + pointer-events: none; + + &__btn { + display: flex; + width: 50px; + height: 50px; + align-items: center; + justify-content: center; + margin: 6px; + border-radius: 50%; + opacity: 0.5; + pointer-events: all; + + &>span { + display: flex; + align-items: center; + justify-content: center; + } + } + + &__btn:hover { + background-color: #09f !important; + color: #fff !important; + } + } +} diff --git a/packages/meta/lib/ImageEditor/cropper/event.js b/packages/meta/lib/ImageEditor/cropper/event.js index 22b83e9..d47e644 100644 --- a/packages/meta/lib/ImageEditor/cropper/event.js +++ b/packages/meta/lib/ImageEditor/cropper/event.js @@ -40,20 +40,20 @@ var import_constants = require("./constants"); var event_default = { bind() { const { container, element, eventHandleList = [], option } = this; - const handleCropStart = (0, import_func.addEventlistener)( + const handleCropStart = (0, import_func.addEventListenerWrapper)( container, import_constants.EVENT_POINTER_DOWN, this.onCropStart.bind(this) ); eventHandleList.push(handleCropStart); - const handleCropMove = (0, import_func.addEventlistener)( + const handleCropMove = (0, import_func.addEventListenerWrapper)( element.ownerDocument, import_constants.EVENT_POINTER_MOVE, this.onCropMove.bind(this) ); eventHandleList.push(handleCropMove); import_constants.EVENT_POINTER_UP.trim().split(import_constants.REGEXP_SPACES).forEach((eventName) => { - const handleCropEnd = (0, import_func.addEventlistener)( + const handleCropEnd = (0, import_func.addEventListenerWrapper)( element.ownerDocument, eventName, this.onCropEnd.bind(this) diff --git a/packages/meta/lib/ImageEditor/cropper/viewerBridge.js b/packages/meta/lib/ImageEditor/cropper/viewerBridge.js index aebd446..f0ac94d 100644 --- a/packages/meta/lib/ImageEditor/cropper/viewerBridge.js +++ b/packages/meta/lib/ImageEditor/cropper/viewerBridge.js @@ -30,11 +30,11 @@ var viewerBridge_default = { const { container, element, eventHandleList = [], option } = this; if (this.options.viewer) { const viewer = this.options.viewer; - const handleWhele = (0, import_func.addEventlistener)(container, import_constants.EVENT_WHEEL, this.onWheel.bind(this)); + const handleWhele = (0, import_func.addEventListenerWrapper)(container, import_constants.EVENT_WHEEL, this.onWheel.bind(this)); eventHandleList.push(handleWhele); this.onTransformChange(viewer); this.limited = true; - const handleTransformChange = (0, import_func.addEventlistener)( + const handleTransformChange = (0, import_func.addEventListenerWrapper)( viewer.element, import_constants2.EVENT_VIEWER_TRANSFORM_CHANGE, (event) => { diff --git a/packages/meta/lib/ImageEditor/viewer/event.js b/packages/meta/lib/ImageEditor/viewer/event.js index 40d67c0..d830963 100644 --- a/packages/meta/lib/ImageEditor/viewer/event.js +++ b/packages/meta/lib/ImageEditor/viewer/event.js @@ -50,25 +50,25 @@ var event_default = { const { canvas, element, eventHandleList = [], options } = this; const scaleAble = (0, import_func.get)(options, "scaleAble", true); if (scaleAble) { - const handleWhele = (0, import_func.addEventListener)(canvas, import_constants.EVENT_WHEEL, this.onWheel.bind(this)); + const handleWhele = (0, import_func.addEventListenerWrapper)(canvas, import_constants.EVENT_WHEEL, this.onWheel.bind(this)); eventHandleList.push(handleWhele); } const dragAble = (0, import_func.get)(options, "dragAble", true); if (dragAble) { - const handleDragStart = (0, import_func.addEventListener)( + const handleDragStart = (0, import_func.addEventListenerWrapper)( canvas, import_constants.EVENT_POINTER_DOWN, this.onDragStart.bind(this) ); - eventHandleList.push(import_func.addEventListener); - const handleDragMove = (0, import_func.addEventListener)( + eventHandleList.push(import_func.addEventListenerWrapper); + const handleDragMove = (0, import_func.addEventListenerWrapper)( element.ownerDocument, import_constants.EVENT_POINTER_MOVE, this.onDragMove.bind(this) ); eventHandleList.push(handleDragMove); import_constants.EVENT_POINTER_UP.trim().split(import_constants.REGEXP_SPACES).forEach((eventName) => { - const handleDragEnd = (0, import_func.addEventListener)( + const handleDragEnd = (0, import_func.addEventListenerWrapper)( element.ownerDocument, eventName, this.onDragEnd.bind(this) @@ -76,7 +76,7 @@ var event_default = { eventHandleList.push(handleDragEnd); }); } - const handleClick = (0, import_func.addEventListener)(canvas, import_constants.EVENT_CLICK, this.onClick.bind(this)); + const handleClick = (0, import_func.addEventListenerWrapper)(canvas, import_constants.EVENT_CLICK, this.onClick.bind(this)); eventHandleList.push(handleClick); }, unbind() { diff --git a/packages/meta/lib/ImagePreview/index.d.ts b/packages/meta/lib/ImagePreview/index.d.ts deleted file mode 100644 index 31fba43..0000000 --- a/packages/meta/lib/ImagePreview/index.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { FC } from 'react'; -export interface CompaterImageProps { - url: string; - label: string; - openRoll?: boolean; - urls?: Array; - specialTitle: String; - noTargetImageTip?: string; - score?: number; -} -declare const CompaterImage: FC; -export default CompaterImage; diff --git a/packages/meta/lib/VideoPlayer/VideoPlayer.d.ts b/packages/meta/lib/VideoPlayer/VideoPlayer.d.ts new file mode 100644 index 0000000..cf56091 --- /dev/null +++ b/packages/meta/lib/VideoPlayer/VideoPlayer.d.ts @@ -0,0 +1,18 @@ +import React, { Dispatch, ReactElement, SetStateAction } from 'react'; +import { Rect, IScreenshotButtonProp, AlignType } from '@zhst/types'; +import './index.less'; +export interface VideoViewProps { + url: string; + maxDuration?: number; + screenshotButtonAlign?: AlignType; + screenshotButtonRender?: (screenshotButtonProp: IScreenshotButtonProp) => ReactElement; + defautlNormalizationRect?: Rect; + onCropChange?: (showCrop: boolean, normalizationRect: null | Rect) => void; +} +export interface VideoViewRef { + cropAble: boolean; + setShowCrop: Dispatch>; + downloadVideoframe: () => void; +} +declare const VideoPlayer: React.ForwardRefExoticComponent>; +export default VideoPlayer; diff --git a/packages/meta/lib/VideoPlayer/VideoPlayer.js b/packages/meta/lib/VideoPlayer/VideoPlayer.js new file mode 100644 index 0000000..00c8880 --- /dev/null +++ b/packages/meta/lib/VideoPlayer/VideoPlayer.js @@ -0,0 +1,611 @@ +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// src/VideoPlayer/VideoPlayer.tsx +var VideoPlayer_exports = {}; +__export(VideoPlayer_exports, { + default: () => VideoPlayer_default +}); +module.exports = __toCommonJS(VideoPlayer_exports); +var import_react = __toESM(require("react")); +var import_func = require("@zhst/func"); +var import_rc_align = __toESM(require("rc-align")); +var import_hooks = require("@zhst/hooks"); +var import_classnames = __toESM(require("classnames")); +var import_downloadjs = __toESM(require("downloadjs")); +var import_antd = require("antd"); +var import_iconfont = __toESM(require("../iconfont")); +var import_ImageEditor = require("../ImageEditor"); +var import_FlvPlayer = __toESM(require("./components/FlvPlayer")); +var import_Progress = __toESM(require("./components/Progress")); +var import_Loading = __toESM(require("./components/Loading")); +var import_ScreenhotButtons = __toESM(require("../BigImagePreview/components/ScreenhotButtons")); +var import_constants = require("../utils/constants"); +var import_videoPlayerHelper = require("./videoPlayerHelper"); +var import_index = require("./index.less"); +var componentName = `zhst-image__video-view`; +var VideoPlayer = (0, import_react.forwardRef)((props, ref) => { + const { + url, + maxDuration, + screenshotButtonAlign = { + points: ["bl", "br"], + offset: [6, 0], + overflow: { + adjustX: true, + adjustY: true + } + }, + screenshotButtonRender = (0, import_ScreenhotButtons.default)({ + onBigImageActionClick: () => { + }, + disableBtn: [] + }), + onCropChange, + defautlNormalizationRect: defaultNormalizationRect + } = props; + const videoType = (0, import_react.useMemo)(() => url && url.startsWith("http") ? "mp4" : "flv", [url]); + const containerRef = (0, import_react.useRef)(null); + const videoRef = (0, import_react.useRef)(null); + const videoInsRef = (0, import_react.useRef)(null); + const [playSeq, setPlaySeq] = (0, import_react.useState)(0); + const videoRemoveListener = (0, import_react.useRef)(import_func.noop); + const loadingTimeRef = (0, import_react.useRef)(0); + const delayLoadingTimer = (0, import_react.useRef)(null); + const [isReady, setIsReady] = (0, import_react.useState)(false); + const [isPlay, setIsPlay] = (0, import_react.useState)(false); + const [isEnd, setIsEnd] = (0, import_react.useState)(false); + const [isError, setIsError] = (0, import_react.useState)(false); + const [isVideoLoadFinished, setIsVideoLoadFinish] = (0, import_react.useState)(false); + const [playTime, setPlayTime] = (0, import_react.useState)(0); + const [isLoadingVideo, setIsLoadingVideo] = (0, import_react.useState)(true); + const [isDelayLoading, setIsDelayLoading] = (0, import_react.useState)(false); + const latestIsLoadingVideo = (0, import_hooks.useLatest)(isLoadingVideo); + const setIsLoadingVideoWrapper = (isLoading) => { + setIsLoadingVideo((preLoading) => { + if (!preLoading && isLoading) { + loadingTimeRef.current = (/* @__PURE__ */ new Date()).getTime(); + } + if (!isLoading) { + loadingTimeRef.current = null; + } + if (!isLoading) { + setIsDelayLoading(false); + } + if (!delayLoadingTimer.current && preLoading) { + delayLoadingTimer.current = setTimeout(() => { + if (latestIsLoadingVideo.current) { + setIsDelayLoading(true); + } + delayLoadingTimer.current = null; + }, 200); + } + return isLoading; + }); + }; + (0, import_react.useEffect)(() => { + let timer = setInterval(() => { + if (loadingTimeRef.current) { + if ((/* @__PURE__ */ new Date()).getTime() - loadingTimeRef.current > 1e3 * 30) { + checkIsErr(); + } + } + }, 1e3); + return () => { + clearInterval(timer); + }; + }, []); + (0, import_hooks.useUpdateEffect)(() => { + var _a, _b; + if (isEnd) { + (_b = (_a = videoInsRef == null ? void 0 : videoInsRef.current) == null ? void 0 : _a.pause) == null ? void 0 : _b.call(_a); + } + }, [isEnd]); + const checkIsErr = () => { + var _a, _b; + setIsError(true); + try { + (_b = (_a = videoInsRef == null ? void 0 : videoInsRef.current) == null ? void 0 : _a.destroy) == null ? void 0 : _b.call(_a); + } catch (error) { + console.error(error); + } + }; + const latestMaxDuration = (0, import_hooks.useLatest)(maxDuration); + const initPlayer = (0, import_react.useCallback)((ins, dom) => { + videoRef.current = dom; + videoInsRef.current = ins; + const maxDuration2 = latestMaxDuration.current || 0; + let video = dom; + let errorLister = (e) => { + checkIsErr(); + console.error("视频出错了", e, video.currentTime); + }; + let waitingListener = (e) => { + setIsLoadingVideoWrapper(true); + console.debug("视频加载等待", e, video.currentTime); + }; + let playingListener = (e) => { + setIsLoadingVideoWrapper(false); + setIsError(false); + console.debug("视频从等待中播放", e, video.currentTime); + }; + let playLister = (e) => { + setIsPlay(true); + setIsError(false); + console.debug("提示该视频正在播放中", e, video.currentTime); + }; + let pauseListener = (e) => { + setIsPlay(false); + console.debug("暂停播放", e, video.currentTime); + }; + let endedListner = (e) => { + setIsEnd(true); + setIsVideoLoadFinish(true); + console.debug("视频播放完了", e, video.currentTime); + }; + let timeupdateListner = (e) => { + var _a; + console.debug( + "视频播放时间更新", + e, + video.currentTime, + (_a = videoRef.current) == null ? void 0 : _a.duration, + maxDuration2 + ); + let nowTime = video.currentTime; + if (nowTime >= maxDuration2) { + setIsEnd(true); + setIsVideoLoadFinish(true); + } + setPlayTime(nowTime); + }; + let windowErrorHandle = (errorEvent) => { + try { + if (errorEvent["message"] == "Uncaught TypeError: Cannot read property 'flushStashedSamples' of null") { + checkIsErr(); + console.error("视频出错了 window监听", errorEvent); + } + } catch (error) { + console.error(error); + } + }; + video.addEventListener("error", errorLister); + video.addEventListener("waiting", waitingListener); + video.addEventListener("playing", playingListener); + video.addEventListener("play", playLister); + video.addEventListener("pause", pauseListener); + video.addEventListener("ended", endedListner); + video.addEventListener("timeupdate", timeupdateListner); + window.addEventListener("error", windowErrorHandle); + videoRemoveListener.current = () => { + video.removeEventListener("error", errorLister); + video.removeEventListener("waiting", waitingListener); + video.removeEventListener("playing", playingListener); + video.removeEventListener("play", playLister); + video.removeEventListener("pause", pauseListener); + video.removeEventListener("ended", endedListner); + video.removeEventListener("timeupdate", timeupdateListner); + window.removeEventListener("error", windowErrorHandle); + }; + videoInsRef == null ? void 0 : videoInsRef.current.on(import_FlvPlayer.FLV_EVENT.ERROR, (type, errDetail, info) => { + checkIsErr(); + console.error("videoInsRef 错误", type, errDetail, info, video.currentTime); + }); + let playPromise = videoInsRef == null ? void 0 : videoInsRef.current.play(); + setIsReady(true); + playPromise.then(() => { + setIsReady(true); + }).catch((...arg) => { + try { + } catch (error) { + } + console.error("playPromise视频出错了", arg); + }); + }, []); + (0, import_hooks.useUnmount)(() => { + try { + videoRemoveListener.current(); + } catch (e) { + console.error(e); + } + }); + const reload = async () => { + if (videoInsRef.current) { + let oldTime = videoInsRef.current.currentTime; + videoInsRef.current.currentTime = 0; + if (oldTime === videoInsRef.current.currentTime) { + setIsReady(false); + setIsPlay(false); + setIsLoadingVideoWrapper(false); + setIsReady(false); + setIsEnd(false); + setIsVideoLoadFinish(false); + setPlayTime(0); + try { + videoRemoveListener.current(); + } catch (error) { + console.error(error); + } + setPlaySeq((pre) => pre + 1); + return; + } + videoInsRef.current.play(); + } + setPlayTime(0); + setIsEnd(false); + }; + const seek = (v) => { + if (videoInsRef.current && isVideoLoadFinished) { + setPlayTime(parseFloat(v)); + videoInsRef.current.currentTime = parseFloat(v); + } else { + import_antd.message.warning("待视频加载完,才可操作进度条"); + } + }; + const [isFullscreen, { toggleFullscreen }] = (0, import_hooks.useFullscreen)(containerRef, { + pageFullscreen: true + }); + const showMaxDuration = !!maxDuration ? maxDuration : (0, import_func.toRealNumber)((0, import_func.get)(videoRef, "current.duration", 0)); + const showSlider = videoInsRef.current && isVideoLoadFinished; + const showStatus = (0, import_videoPlayerHelper.getShowStatus)(isDelayLoading, isEnd, isError); + const corpContainerRef = (0, import_react.useRef)(); + const cropInsRef = (0, import_react.useRef)(null); + const [showCrop, setShowCrop] = (0, import_react.useState)(false); + const isFirstFlagRef = (0, import_react.useRef)(true); + (0, import_react.useEffect)(() => { + const isFirst = isFirstFlagRef.current; + if (!isLoadingVideo && isReady && isFirst && defaultNormalizationRect && !showStatus) { + (0, import_func.nextTick)(() => { + setShowCrop(true); + }); + } + }, [isLoadingVideo, showStatus]); + const alginContainerRef = (0, import_react.useRef)(null); + const alignRef = (0, import_react.useRef)(null); + const [cropRect, setCropRect] = (0, import_react.useState)(null); + (0, import_react.useEffect)(() => { + var _a, _b; + showCrop ? (_a = videoInsRef == null ? void 0 : videoInsRef.current) == null ? void 0 : _a.pause() : (_b = videoInsRef == null ? void 0 : videoInsRef.current) == null ? void 0 : _b.play(); + }, [showCrop]); + (0, import_react.useEffect)(() => { + var _a; + let handlerCropStart; + let handlerCropEnd; + setCropRect(null); + if (!isReady) + return; + if (showCrop) { + handlerCropStart = (0, import_func.addEventListenerWrapper)(corpContainerRef.current, import_ImageEditor.EVENT_CROP_START, () => { + setCropRect(null); + }); + handlerCropEnd = (0, import_func.addEventListenerWrapper)(corpContainerRef.current, import_ImageEditor.EVENT_CROP_END, (event) => { + var _a2, _b; + const data = event.detail; + setCropRect({ + x: data.left, + y: data.top, + w: data.width, + h: data.height + }); + (_b = (_a2 = alignRef == null ? void 0 : alignRef.current) == null ? void 0 : _a2.forceAlign) == null ? void 0 : _b.call(_a2); + }); + let video = videoRef.current; + let scale = Math.min( + video.offsetWidth / video.videoWidth, + video.offsetHeight / video.videoHeight + ); + let finalVideoWidth = video.videoWidth * scale; + let finalVideoHeight = video.videoHeight * scale; + let cropBoxLimited = { + width: finalVideoWidth, + height: finalVideoHeight, + top: (video.offsetHeight - finalVideoHeight) / 2, + left: (video.offsetWidth - finalVideoWidth) / 2 + }; + let canvas = document.createElement("canvas"); + canvas.width = video.offsetWidth; + canvas.height = video.offsetHeight; + canvas.style.display = "none"; + document.body.appendChild(canvas); + let ctx = canvas.getContext("2d"); + ctx == null ? void 0 : ctx.drawImage( + video, + (video.offsetWidth - finalVideoWidth) / 2, + (video.offsetHeight - finalVideoHeight) / 2, + finalVideoWidth, + finalVideoHeight + ); + let imageData = canvas.toDataURL("image/png"); + (_a = canvas.parentNode) == null ? void 0 : _a.removeChild(canvas); + const isFirst = isFirstFlagRef.current; + let initialCropBoxData = null; + if (isFirst && defaultNormalizationRect) { + initialCropBoxData = { + left: defaultNormalizationRect.x * finalVideoWidth + cropBoxLimited.left, + top: defaultNormalizationRect.y * finalVideoHeight + cropBoxLimited.top, + width: defaultNormalizationRect.w * finalVideoWidth, + height: defaultNormalizationRect.h * finalVideoHeight + }; + } + isFirstFlagRef.current = false; + cropInsRef.current = new import_ImageEditor.Cropper(corpContainerRef.current, { + showMask: true, + cropBoxLimited, + img: imageData, + initialCropBoxData + }); + } + return () => { + var _a2, _b; + handlerCropStart == null ? void 0 : handlerCropStart.remove(); + handlerCropEnd == null ? void 0 : handlerCropEnd.remove(); + (_b = (_a2 = cropInsRef == null ? void 0 : cropInsRef.current) == null ? void 0 : _a2.destroy) == null ? void 0 : _b.call(_a2); + cropInsRef.current = null; + }; + }, [showCrop, isReady]); + const latestCropRect = (0, import_hooks.useLatest)(cropRect); + const getCropInfo = async () => { + var _a; + const cropRect2 = latestCropRect.current; + let video = videoRef.current; + if (!video) + return; + let rectList = []; + let extendRectList = []; + let selectIndex = 0; + let scale = Math.min( + video.offsetWidth / video.videoWidth, + video.offsetHeight / video.videoHeight + ); + let finalVideoWidth = video.videoWidth * scale; + let finalVideoHeight = video.videoHeight * scale; + let canvas = document.createElement("canvas"); + canvas.width = finalVideoWidth; + canvas.height = finalVideoHeight; + canvas.style.display = "none"; + document.body.appendChild(canvas); + let ctx = canvas.getContext("2d"); + ctx.drawImage( + video, + 0, + 0, + finalVideoWidth, + finalVideoHeight + ); + let base64 = canvas.toDataURL("image/jpeg"); + const blobData = (0, import_func.dataURLToBlob)(base64); + (_a = canvas.parentNode) == null ? void 0 : _a.removeChild(canvas); + const file = new window.File([blobData], `${(/* @__PURE__ */ new Date()).getTime()}`); + let newRect = { + w: cropRect2.w / finalVideoWidth, + h: cropRect2.h / finalVideoHeight, + x: (cropRect2.x - (video.offsetWidth - finalVideoWidth) / 2) / finalVideoWidth, + y: (cropRect2.y - (video.offsetHeight - finalVideoHeight) / 2) / finalVideoHeight + }; + rectList.push(newRect); + extendRectList.push(newRect); + extendRectList.forEach(async (rect, index) => { + extendRectList[index] = { + ...rect + }; + }); + return { + rectList, + extendRectList, + selectIndex, + file + }; + }; + (0, import_react.useEffect)(() => { + let normalizationRect = null; + if (showCrop && cropRect) { + let video = videoRef.current; + let scale = Math.min( + video.offsetWidth / video.videoWidth, + video.offsetHeight / video.videoHeight + ); + let finalVideoWidth = video.videoWidth * scale; + let finalVideoHeight = video.videoHeight * scale; + let cropBoxLimited = { + width: finalVideoWidth, + height: finalVideoHeight, + top: (video.offsetHeight - finalVideoHeight) / 2, + left: (video.offsetWidth - finalVideoWidth) / 2 + }; + normalizationRect = { + x: (cropRect.x - cropBoxLimited.left) / cropBoxLimited.width, + y: (cropRect.y - cropBoxLimited.top) / cropBoxLimited.height, + w: cropRect.w / cropBoxLimited.width, + h: cropRect.h / cropBoxLimited.height + }; + } + onCropChange == null ? void 0 : onCropChange(showCrop, normalizationRect); + }, [showCrop, cropRect]); + const downloadVideoframe = (0, import_react.useCallback)(async () => { + var _a, _b; + try { + (_b = (_a = videoInsRef == null ? void 0 : videoInsRef.current) == null ? void 0 : _a.pause) == null ? void 0 : _b.call(_a); + let video = videoRef.current; + var canvas = document.createElement("canvas"); + const ctx = canvas.getContext("2d"); + let base64; + if (video.readyState === 0) { + ctx == null ? void 0 : ctx.clearRect(0, 0, canvas.width, canvas.height); + canvas.width = video.offsetWidth; + canvas.height = video.offsetHeight; + ctx.fillStyle = "black"; + ctx == null ? void 0 : ctx.fillRect(0, 0, canvas.width, canvas.height); + base64 = canvas.toDataURL(); + } else { + canvas.width = video.videoWidth; + canvas.height = video.videoHeight; + ctx == null ? void 0 : ctx.drawImage(video, 0, 0, canvas.width, canvas.height); + base64 = canvas.toDataURL("image/png"); + } + (0, import_downloadjs.default)(base64); + } catch (error) { + console.error(error); + } + }, []); + const latestIsReady = (0, import_hooks.useLatest)(isReady); + const cropAble = !showStatus && isReady; + (0, import_react.useImperativeHandle)(ref, () => ({ + cropAble, + setShowCrop: (dispatch) => { + const isReady2 = latestIsReady.current; + if (!isReady2) + return; + setShowCrop(dispatch); + }, + downloadVideoframe + })); + return /* @__PURE__ */ import_react.default.createElement("div", { className: (0, import_classnames.default)(`${componentName}`), ref: containerRef }, url && /* @__PURE__ */ import_react.default.createElement(import_react.default.Fragment, null, /* @__PURE__ */ import_react.default.createElement( + import_FlvPlayer.default, + { + playId: playSeq, + autoPlay: true, + className: (0, import_classnames.default)(`${componentName}-flv`), + type: videoType, + url, + config: { + enableStashBuffer: true, + stashInitialSize: 1024 * 700, + isLive: true, + hasAudio: false, + hasVideo: true + }, + onCreat: initPlayer + } + ), /* @__PURE__ */ import_react.default.createElement( + "div", + { + className: (0, import_classnames.default)(`${componentName}-crop-container`), + ref: corpContainerRef, + style: { + display: isFullscreen ? "none" : "block" + } + } + ), showCrop && cropRect && screenshotButtonRender && /* @__PURE__ */ import_react.default.createElement(import_react.default.Fragment, null, /* @__PURE__ */ import_react.default.createElement( + "div", + { + ref: alginContainerRef, + className: (0, import_classnames.default)(`${componentName}-align`), + style: Object.assign( + { + width: cropRect.w, + height: cropRect.h + }, + (0, import_func.getTransforms)({ + translateX: cropRect.x, + translateY: cropRect.y + }) + ) + } + ), /* @__PURE__ */ import_react.default.createElement( + import_rc_align.default, + { + ref: alignRef, + monitorWindowResize: true, + align: screenshotButtonAlign, + target: function() { + return alginContainerRef.current; + } + }, + screenshotButtonRender({ + model: "IMAGE", + getCropInfo, + setShowCrop, + cropType: import_constants.CROP_TYPE["CUSTOM"] + }) + )), !showCrop && /* @__PURE__ */ import_react.default.createElement("div", { className: `${componentName}-opt` }, /* @__PURE__ */ import_react.default.createElement("div", null, /* @__PURE__ */ import_react.default.createElement( + import_antd.Button, + { + type: "text", + onClick: (e) => { + var _a, _b; + if (!isPlay) { + (_a = videoInsRef == null ? void 0 : videoInsRef.current) == null ? void 0 : _a.play(); + setShowCrop(false); + } else { + (_b = videoInsRef == null ? void 0 : videoInsRef.current) == null ? void 0 : _b.pause(); + } + } + }, + /* @__PURE__ */ import_react.default.createElement( + import_iconfont.default, + { + styles: { + color: "#fff", + display: "flex" + }, + color: "#1890ff", + icon: !isPlay ? "icon-shipinbofang" : "icon-shipinzanting" + } + ) + )), /* @__PURE__ */ import_react.default.createElement( + "div", + { + className: `${componentName}-opt-range`, + onClick: (e) => { + e.stopPropagation(); + } + }, + /* @__PURE__ */ import_react.default.createElement( + import_Progress.default, + { + value: playTime, + min: 0, + max: showMaxDuration, + showSlider, + onChange: seek + } + ), + /* @__PURE__ */ import_react.default.createElement("div", null, (0, import_func.formatDurationTime)(playTime), "/", (0, import_func.formatDurationTime)(showMaxDuration)) + ), /* @__PURE__ */ import_react.default.createElement("div", null, /* @__PURE__ */ import_react.default.createElement( + import_antd.Button, + { + type: "text", + onClick: (e) => { + e.stopPropagation(); + toggleFullscreen(); + } + }, + /* @__PURE__ */ import_react.default.createElement( + import_iconfont.default, + { + styles: { + color: "#fff", + display: "flex" + }, + size: 18, + icon: isFullscreen ? "icon-cancle_fullscreen" : "icon-fullscreen" + } + ) + ))), !!showStatus && /* @__PURE__ */ import_react.default.createElement(import_Loading.default, { status: showStatus, reload: () => reload() }))); +}); +var VideoPlayer_default = VideoPlayer; diff --git a/packages/meta/lib/VideoPlayer/components/FlvPlayer/index.d.ts b/packages/meta/lib/VideoPlayer/components/FlvPlayer/index.d.ts new file mode 100644 index 0000000..646b267 --- /dev/null +++ b/packages/meta/lib/VideoPlayer/components/FlvPlayer/index.d.ts @@ -0,0 +1,46 @@ +import React, { Component, CSSProperties } from 'react'; +import flvjs from 'flv.js'; +export declare const FLV_EVENT: Readonly; +export interface VideoPlayerProps { + className: string; + style?: CSSProperties; + type: string; + isLive?: boolean; + cors?: boolean; + withCredentials?: boolean; + playId?: number; + hasAudio?: boolean; + hasVideo?: boolean; + duration?: number; + filesize?: number; + url?: string; + autoPlay?: boolean; + onCreat?: any; + /** + * @see https://github.com/Bilibili/flv.js/blob/master/docs/api.md#config + */ + config: object; +} +export default class VideoPlayer extends Component { + state: { + curPlayUrl: string; + shouldReinit: boolean; + }; + flvPlayer: any; + videoElement: null; + static getDerivedStateFromProps: (nextProps: { + url?: any; + playId?: any; + }, prevState: { + curPlayUrl?: any; + playId?: any; + }) => { + playId: any; + curPlayUrl: any; + shouldReinit: boolean; + } | null; + initFlv: ($video: null) => void; + componentWillUnmount(): void; + componentDidUpdate(): void; + render(): React.JSX.Element; +} diff --git a/packages/meta/lib/VideoPlayer/components/FlvPlayer/index.js b/packages/meta/lib/VideoPlayer/components/FlvPlayer/index.js new file mode 100644 index 0000000..38230d2 --- /dev/null +++ b/packages/meta/lib/VideoPlayer/components/FlvPlayer/index.js @@ -0,0 +1,144 @@ +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// src/VideoPlayer/components/FlvPlayer/index.tsx +var FlvPlayer_exports = {}; +__export(FlvPlayer_exports, { + FLV_EVENT: () => FLV_EVENT, + default: () => VideoPlayer +}); +module.exports = __toCommonJS(FlvPlayer_exports); +var import_react = __toESM(require("react")); +var import_flv = __toESM(require("flv.js")); +var import_func = require("@zhst/func"); +var FLV_EVENT = import_flv.default.Events; +var VideoPlayer = class extends import_react.Component { + constructor() { + super(...arguments); + this.state = { + curPlayUrl: "", + shouldReinit: false + }; + this.flvPlayer = null; + this.videoElement = null; + this.initFlv = ($video) => { + this.videoElement = $video; + const { className, autoPlay = true, config = {}, onCreat, playId, ...others } = this.props; + if ($video) { + if (import_flv.default.isSupported() && this.props.url && this.props.url) { + const reload = () => { + if (this.flvPlayer && this.flvPlayer.destroy) { + try { + this.flvPlayer.destroy(); + } catch (error) { + console.error(error); + } + } + let flvPlayer = import_flv.default.createPlayer({ ...others }, { + deferLoadAfterSourceOpen: false, + ...config + }); + flvPlayer.attachMediaElement($video); + flvPlayer.load(); + this.flvPlayer = flvPlayer; + let controller = this.flvPlayer._transmuxer._controller; + let wsLoader = controller._ioctl._loader; + const oldWsOnCompleteFunc = wsLoader._onComplete; + wsLoader._onComplete = function() { + if (!controller._remuxer) { + controller._remuxer = { + destroy: () => { + console.log("组件销毁"); + }, + flushStashedSamples: () => { + console.log("flushStashedSamples"); + } + }; + } + oldWsOnCompleteFunc(); + }; + this.flvPlayer.reload = reload; + onCreat && onCreat(this.flvPlayer, $video); + }; + reload(); + onCreat && onCreat(this.flvPlayer, $video); + } + } + }; + } + componentWillUnmount() { + var _a, _b; + if (this.flvPlayer) { + (_a = this.flvPlayer) == null ? void 0 : _a.unload(); + (_b = this.flvPlayer) == null ? void 0 : _b.detachMediaElement(); + } + } + componentDidUpdate() { + if (this.state.shouldReinit) { + this.setState({ shouldReinit: false }); + this.initFlv(this.videoElement); + } + } + render() { + const { className, style } = this.props; + return /* @__PURE__ */ import_react.default.createElement( + "video", + { + muted: true, + preload: "metadata", + className, + style: Object.assign( + { + width: "100%", + height: "100%" + }, + style ? style : {} + ), + ref: this.initFlv + } + ); + } +}; +VideoPlayer.getDerivedStateFromProps = (nextProps, prevState) => { + const { playId = 0 } = nextProps; + const { playId: prePlayId = 0 } = prevState; + if (nextProps.url !== void 0) { + if (!(0, import_func.isEqual)(nextProps.url, prevState.curPlayUrl) || !(0, import_func.isEqual)(playId, prePlayId)) { + return { + playId, + curPlayUrl: nextProps.url, + shouldReinit: true + }; + } + } + return null; +}; +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + FLV_EVENT +}); diff --git a/packages/meta/lib/VideoPlayer/components/Loading/index.d.ts b/packages/meta/lib/VideoPlayer/components/Loading/index.d.ts new file mode 100644 index 0000000..1509947 --- /dev/null +++ b/packages/meta/lib/VideoPlayer/components/Loading/index.d.ts @@ -0,0 +1,8 @@ +import { FC } from 'react'; +import './index.less'; +export interface ILoading { + status: 'LOADING' | 'COMPLETED' | 'END' | 'ERROR' | null; + reload: () => void; +} +declare const Loading: FC; +export default Loading; diff --git a/packages/meta/lib/VideoPlayer/components/Loading/index.js b/packages/meta/lib/VideoPlayer/components/Loading/index.js new file mode 100644 index 0000000..150c54d --- /dev/null +++ b/packages/meta/lib/VideoPlayer/components/Loading/index.js @@ -0,0 +1,84 @@ +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// src/VideoPlayer/components/Loading/index.tsx +var Loading_exports = {}; +__export(Loading_exports, { + default: () => Loading_default +}); +module.exports = __toCommonJS(Loading_exports); +var import_react = __toESM(require("react")); +var import_antd = require("antd"); +var import_classnames = __toESM(require("classnames")); +var import_iconfont = __toESM(require("../../../iconfont")); +var import_index = require("./index.less"); +var componentName = `zhst-image__video-view`; +var Loading = (props) => { + const { status, reload } = props; + return /* @__PURE__ */ import_react.default.createElement( + "div", + { + className: (0, import_classnames.default)(`${componentName}__player-mask`), + onClick: (e) => { + e.stopPropagation(); + } + }, + status === "LOADING" && /* @__PURE__ */ import_react.default.createElement(import_antd.Spin, { tip: "加载中...", spinning: status === "LOADING" }), + status === "END" && /* @__PURE__ */ import_react.default.createElement(import_react.default.Fragment, null, /* @__PURE__ */ import_react.default.createElement( + "div", + { + onClick: () => { + reload(); + }, + className: (0, import_classnames.default)(`${componentName}__icon-wraper`) + }, + /* @__PURE__ */ import_react.default.createElement( + import_iconfont.default, + { + styles: { + fill: "#ffffff", + color: "#ffffff" + }, + size: 54, + icon: "icon-shuaxin" + } + ) + ), /* @__PURE__ */ import_react.default.createElement("div", { className: (0, import_classnames.default)(`${componentName}__player-mask-title`) }, "点击刷新后,将重新播放")), + status === "ERROR" && /* @__PURE__ */ import_react.default.createElement(import_react.default.Fragment, null, /* @__PURE__ */ import_react.default.createElement("div", { className: (0, import_classnames.default)(`${componentName}__icon-wraper`) }, /* @__PURE__ */ import_react.default.createElement( + import_iconfont.default, + { + styles: { + color: "#ffffff" + }, + size: 54, + icon: "icon-jiazaishibai" + } + )), /* @__PURE__ */ import_react.default.createElement("div", { className: (0, import_classnames.default)(`${componentName}__player-mask-title`) }, "视频加载失败,", /* @__PURE__ */ import_react.default.createElement("a", { onClick: reload }, " ", "刷新"))) + ); +}; +var Loading_default = Loading; diff --git a/packages/meta/lib/VideoPlayer/components/Loading/index.less b/packages/meta/lib/VideoPlayer/components/Loading/index.less new file mode 100644 index 0000000..b6c11a2 --- /dev/null +++ b/packages/meta/lib/VideoPlayer/components/Loading/index.less @@ -0,0 +1,53 @@ +.zhst-image__video-view__player-mask { + position: absolute; + width: 100%; + height: 100%; + z-index: 99; + top: 0; + right: 0; + bottom: 0; + left: 0; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + background-color: rgb(4 4 4 / 70%); + + &--bg { + z-index: 999; + background-color: rgb(4 4 4 / 100%); + } + + i { + cursor: pointer; + } + + &-title { + margin-top: 12px; + color: #fff; + text-align: center; + + & a { + color: #09f; + cursor: pointer; + text-decoration: underline; + } + } +} + +.zhst-image__video-view__icon-wraper { + display: flex; + width: 80px; + height: 80px; + align-items: center; + justify-content: center; + background-color: rgb(255 255 255 / 10%); + border-radius: 50%; + cursor: pointer; + line-height: 80px; + text-align: center; + + // &:hover { + // background: #0099ff; + // } +} diff --git a/packages/meta/lib/VideoPlayer/components/Progress/index.d.ts b/packages/meta/lib/VideoPlayer/components/Progress/index.d.ts new file mode 100644 index 0000000..7fb0a10 --- /dev/null +++ b/packages/meta/lib/VideoPlayer/components/Progress/index.d.ts @@ -0,0 +1,10 @@ +import React from 'react'; +import type { SliderSingleProps } from 'antd'; +import './index.less'; +export interface RangeWrapperProps extends SliderSingleProps { + showSlider: boolean; + className?: string; + min: number; +} +export declare const Range: React.FC; +export default Range; diff --git a/packages/meta/lib/VideoPlayer/components/Progress/index.js b/packages/meta/lib/VideoPlayer/components/Progress/index.js new file mode 100644 index 0000000..92e0d85 --- /dev/null +++ b/packages/meta/lib/VideoPlayer/components/Progress/index.js @@ -0,0 +1,60 @@ +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// src/VideoPlayer/components/Progress/index.tsx +var Progress_exports = {}; +__export(Progress_exports, { + Range: () => Range, + default: () => Progress_default +}); +module.exports = __toCommonJS(Progress_exports); +var import_react = __toESM(require("react")); +var import_classnames = __toESM(require("classnames")); +var import_antd = require("antd"); +var import_index = require("./index.less"); +var componentName = `zhst-image__range`; +var Range = (props) => { + const { className, style, showSlider = true, ...others } = props; + return /* @__PURE__ */ import_react.default.createElement( + "div", + { + style, + className: (0, import_classnames.default)( + `${componentName}`, + !showSlider && `${componentName}--no-slider`, + className + ) + }, + /* @__PURE__ */ import_react.default.createElement(import_antd.Slider, { ...others }) + ); +}; +var Progress_default = Range; +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + Range +}); diff --git a/packages/meta/lib/VideoPlayer/components/Progress/index.less b/packages/meta/lib/VideoPlayer/components/Progress/index.less new file mode 100644 index 0000000..e922211 --- /dev/null +++ b/packages/meta/lib/VideoPlayer/components/Progress/index.less @@ -0,0 +1,49 @@ +.zhst-image__range { + position: relative; + + &--no-slider { + .next-range-slider { + display: none; + } + } + + & .next-range .next-range-track { + height: 8px; + margin-top: -4px; + border-radius: 8px; + } + + & .next-range .next-range-selected { + height: 8px; + margin-top: -4px; + border-radius: 8px; + } + + & .next-range .next-range-slider-inner { + width: 14px; + height: 14px; + border-color: #fff; + margin-top: -7px; + margin-left: -7px; + background-color: #0098ff; + } + + & .next-range .next-range-slider { + width: 14px; + height: 14px; + margin-top: -7px; + margin-left: -7px; + } + + & .next-range.simulation-click>.next-range-slider-inner { + border: 2px solid #fff !important; + } + + & .next-range .next-range-frag.next-range-active .next-range-slider .next-range-slider-inner { + border: 2px solid #fff !important; + } + + & .next-range .next-range-slider.next-range-slider-moving .next-range-slider-inner { + border: 2px solid #fff !important; + } +} diff --git a/packages/meta/lib/VideoPlayer/index.d.ts b/packages/meta/lib/VideoPlayer/index.d.ts new file mode 100644 index 0000000..a1993e1 --- /dev/null +++ b/packages/meta/lib/VideoPlayer/index.d.ts @@ -0,0 +1,3 @@ +import VideoPlayer from './VideoPlayer'; +export type { VideoViewProps, VideoViewRef } from './VideoPlayer'; +export default VideoPlayer; diff --git a/packages/meta/lib/VideoPlayer/index.js b/packages/meta/lib/VideoPlayer/index.js new file mode 100644 index 0000000..7d136ea --- /dev/null +++ b/packages/meta/lib/VideoPlayer/index.js @@ -0,0 +1,36 @@ +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// src/VideoPlayer/index.tsx +var VideoPlayer_exports = {}; +__export(VideoPlayer_exports, { + default: () => VideoPlayer_default +}); +module.exports = __toCommonJS(VideoPlayer_exports); +var import_VideoPlayer = __toESM(require("./VideoPlayer")); +var VideoPlayer_default = import_VideoPlayer.default; diff --git a/packages/meta/lib/VideoPlayer/index.less b/packages/meta/lib/VideoPlayer/index.less new file mode 100644 index 0000000..181e65c --- /dev/null +++ b/packages/meta/lib/VideoPlayer/index.less @@ -0,0 +1,75 @@ +.zhst-image__video-view { + position: relative; + overflow: hidden; + width: 100%; + height: 532px; + background-color: #333; + + // &-flv { + // width: 85%; + // } + &-screenshot { + position: absolute; + z-index: 10; + } + + &-crop-container { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + } + + &-align { + position: absolute; + top: 0; + left: 0; + pointer-events: none; + } + + &-opt { + position: absolute; + z-index: 99; + bottom: 0; + display: flex; + width: 100%; + height: 32px; + box-sizing: border-box; + align-items: center; + padding: 0 12px; + background-color: rgb(0 0 0 / 80%); + line-height: 32px; + + &>div:first-child { + display: flex; + align-items: center; + margin-right: 12px; + } + + &>div:last-child { + display: flex; + align-items: center; + margin-left: 12px; + } + + &-range { + display: flex; + height: 32px; + flex: 1; + align-items: center; + line-height: 32px; + text-align: center; + + &>div:first-child { + flex: 1; + } + + &>div:last-child { + width: 100px; + margin-left: 8px; + color: #fff; + } + } + } +} diff --git a/packages/meta/lib/VideoPlayer/videoPlayerHelper.d.ts b/packages/meta/lib/VideoPlayer/videoPlayerHelper.d.ts new file mode 100644 index 0000000..661a7c1 --- /dev/null +++ b/packages/meta/lib/VideoPlayer/videoPlayerHelper.d.ts @@ -0,0 +1 @@ +export declare function getShowStatus(isLoadingVideo: boolean, isEnd: boolean, isError: boolean): string | null; diff --git a/packages/meta/lib/VideoPlayer/videoPlayerHelper.js b/packages/meta/lib/VideoPlayer/videoPlayerHelper.js new file mode 100644 index 0000000..6ef0b97 --- /dev/null +++ b/packages/meta/lib/VideoPlayer/videoPlayerHelper.js @@ -0,0 +1,41 @@ +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// src/VideoPlayer/videoPlayerHelper.ts +var videoPlayerHelper_exports = {}; +__export(videoPlayerHelper_exports, { + getShowStatus: () => getShowStatus +}); +module.exports = __toCommonJS(videoPlayerHelper_exports); +function getShowStatus(isLoadingVideo, isEnd, isError) { + let status = null; + if (isLoadingVideo) { + status = "LOADING"; + } + if (isError) { + status = "ERROR"; + } + if (isEnd) { + status = "END"; + } + return status; +} +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + getShowStatus +}); diff --git a/packages/meta/lib/iconfont/iconfont.css b/packages/meta/lib/iconfont/iconfont.css new file mode 100644 index 0000000..8bde390 --- /dev/null +++ b/packages/meta/lib/iconfont/iconfont.css @@ -0,0 +1,1679 @@ +@font-face { + font-family: iconfont; /* Project id 1739270 */ + src: url('iconfont.woff2?t=1689583241972') format('woff2'), + url('iconfont.woff?t=1689583241972') format('woff'), + url('iconfont.ttf?t=1689583241972') format('truetype'); +} + +.iconfont { + font-family: iconfont !important; + font-size: 16px; + font-style: normal; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.icon-danganxiangqing_hangweifenxi::before { + content: "\e78d"; +} + +.icon-danganxiangqing_shujuganzhi::before { + content: "\e78e"; +} + +.icon-danganxiangqing_huodongguiji::before { + content: "\e78f"; +} + +.icon-danganxiangqing_jibenxinxi::before { + content: "\e7ea"; +} + +.icon-danganxiangqing_fushuwupin::before { + content: "\e7eb"; +} + +.icon-danganxiangqing_jizhanyingyong::before { + content: "\e7ec"; +} + +.icon-jiarudanganku::before { + content: "\e787"; +} + +.icon-dangankunor::before { + content: "\e793"; +} + +.icon-bukongrenwuselect::before { + content: "\e799"; +} + +.icon-bukongrenwunor1::before { + content: "\e79a"; +} + +.icon-dangankuselect::before { + content: "\e79b"; +} + +.icon-jizhanfanor::before { + content: "\e79c"; +} + +.icon-feijidongchechaxunnor::before { + content: "\e79d"; +} + +.icon-jidongchechaxunselect::before { + content: "\e79e"; +} + +.icon-a-lixianfenxiselect2::before { + content: "\e7a1"; +} + +.icon-huisufenxiselect::before { + content: "\e7a2"; +} + +.icon-jizhanfaselect::before { + content: "\e7a3"; +} + +.icon-mubiaojiansuonor::before { + content: "\e7ae"; +} + +.icon-lurenkuselect::before { + content: "\e7b1"; +} + +.icon-shujujiashicangselect::before { + content: "\e7b2"; +} + +.icon-shishijiexiselect::before { + content: "\e7b4"; +} + +.icon-shishijiexinor::before { + content: "\e7b9"; +} + +.icon-jidongchechaxunnor::before { + content: "\e7c1"; +} + +.icon-lurenkunor1::before { + content: "\e7cf"; +} + +.icon-mubiaotezhengchaxunnor::before { + content: "\e7e1"; +} + +.icon-yujingjiluselect::before { + content: "\e7e2"; +} + +.icon-mubiaotezhengchaxunselect::before { + content: "\e7e3"; +} + +.icon-feijidongchechaxunselect::before { + content: "\e7e4"; +} + +.icon-yujingjilunor::before { + content: "\e7e5"; +} + +.icon-lixianfenxiselect::before { + content: "\e7e6"; +} + +.icon-huisufenxinor::before { + content: "\e7e7"; +} + +.icon-shujujiashicangnor::before { + content: "\e7e8"; +} + +.icon-mubiaojiansuoselect::before { + content: "\e7e9"; +} + +.icon-kuangxuangongju::before { + content: "\e796"; +} + +.icon-fengniao::before { + content: "\e792"; +} + +.icon-zhankai::before { + content: "\e790"; +} + +.icon-shouqi::before { + content: "\e791"; +} + +.icon-shijian::before { + content: "\e786"; +} + +.icon-dingwei2::before { + content: "\e613"; +} + +.icon-renyuan::before { + content: "\e784"; +} + +.icon-houtai::before { + content: "\e785"; +} + +.icon-zuo::before { + content: "\e781"; +} + +.icon-you::before { + content: "\e783"; +} + +.icon-kakou::before { + content: "\e780"; +} + +.icon-yujing1::before { + content: "\e77e"; +} + +.icon-yuan2::before { + content: "\e77d"; +} + +.icon-moxingpengzhuang::before { + content: "\e777"; +} + +.icon-moxingpengzhuangnor::before { + content: "\e778"; +} + +.icon-lurenku::before { + content: "\e77b"; +} + +.icon-lurenkunor::before { + content: "\e77c"; +} + +.icon-shiming::before { + content: "\e776"; +} + +.icon-suoxiao2::before { + content: "\e774"; +} + +.icon-fangda1::before { + content: "\e775"; +} + +.icon-guanbi2::before { + content: "\e772"; +} + +.icon-fanhui1::before { + content: "\e773"; +} + +.icon-xiansuomopai::before { + content: "\e76f"; +} + +.icon-xiansuomopainor::before { + content: "\e76e"; +} + +.icon-zhajiyujing::before { + content: "\e770"; +} + +.icon-zhajiyujingnor::before { + content: "\e771"; +} + +.icon-zhuizongpeizhi::before { + content: "\e76c"; +} + +.icon-zhuizongpeizhinor::before { + content: "\e76d"; +} + +.icon-dapingqiehuan::before { + content: "\e76b"; +} + +.icon-xuanze::before { + content: "\e769"; +} + +.icon-shaixuan1::before { + content: "\e76a"; +} + +.icon-chekashebei::before { + content: "\e764"; +} + +.icon-imsishebei::before { + content: "\e765"; +} + +.icon-xingtishebei::before { + content: "\e766"; +} + +.icon-renlianshebei::before { + content: "\e767"; +} + +.icon-wifishebei::before { + content: "\e768"; +} + +.icon-a-miaozhun2::before { + content: "\e762"; +} + +.icon-a-bianzu19::before { + content: "\e763"; +} + +.icon-fanye::before { + content: "\e75e"; +} + +.icon-shenfenzheng::before { + content: "\e75f"; +} + +.icon-dizhi::before { + content: "\e760"; +} + +.icon-guanbi::before { + content: "\e761"; +} + +.icon-dianwei1::before { + content: "\e75b"; +} + +.icon-weikakou::before { + content: "\e757"; +} + +.icon-weikakounor::before { + content: "\e758"; +} + +.icon-changsuoma::before { + content: "\e759"; +} + +.icon-changsuomanor::before { + content: "\e75a"; +} + +.icon-yujing::before { + content: "\e756"; +} + +.icon-jiansuonor::before { + content: "\e747"; +} + +.icon-tonghangrenfenxinor1::before { + content: "\e748"; +} + +.icon-zhinengyanpannor::before { + content: "\e749"; +} + +.icon-bukongyujingnor::before { + content: "\e74a"; +} + +.icon-bukongrenwunor::before { + content: "\e74b"; +} + +.icon-dianziditunor::before { + content: "\e754"; +} + +.icon-zhuizongnor1::before { + content: "\e755"; +} + +.icon-zhuizong1::before { + content: "\e746"; +} + +.icon-bukongrenwu3::before { + content: "\e74c"; +} + +.icon-dianziditu::before { + content: "\e74d"; +} + +.icon-bukongyujing::before { + content: "\e750"; +} + +.icon-tonghangrenfenxi1::before { + content: "\e751"; +} + +.icon-zhinengyanpan::before { + content: "\e752"; +} + +.icon-jiansuo1::before { + content: "\e753"; +} + +.icon-kaiqijulei::before { + content: "\e745"; +} + +.icon-tongbu::before { + content: "\e744"; +} + +.icon-tonghangrenfenxi::before { + content: "\e743"; +} + +.icon-tonghangrenfenxinor::before { + content: "\e742"; +} + +.icon-jizhanyingyong::before { + content: "\e741"; +} + +.icon-haikangrenlianbukongnor::before { + content: "\e740"; +} + +.icon-haikangrenlianbukong::before { + content: "\e73f"; +} + +.icon-tuozhanshouduantishi::before { + content: "\e73e"; +} + +.icon-fanhuimopailiebiao::before { + content: "\e73d"; +} + +.icon-toukuijiancenor::before { + content: "\e73c"; +} + +.icon-toukuijiance::before { + content: "\e718"; +} + +.icon-zhuixing::before { + content: "\e717"; +} + +.icon-tishi4::before { + content: "\e73b"; +} + +.icon-a-shaixuanfeiji::before { + content: "\e733"; +} + +.icon-a-zidongtiaozhengfanweifeiji::before { + content: "\e73a"; +} + +.icon-heziyunwei::before { + content: "\e739"; +} + +.icon-qiehuan::before { + content: "\e738"; +} + +.icon-disanfangxiaoxinor::before { + content: "\e737"; +} + +.icon-disanfangxiaoxi::before { + content: "\e736"; +} + +.icon-daohang::before { + content: "\e735"; +} + +.icon-yonghu::before { + content: "\e734"; +} + +.icon-feiji::before { + content: "\e732"; +} + +.icon-jieshuzhuizong::before { + content: "\e730"; +} + +.icon-huisuzhoubian::before { + content: "\e731"; +} + +.icon-jixuzhuizong::before { + content: "\e72d"; +} + +.icon-tiaozhengfanwei::before { + content: "\e72e"; +} + +.icon-jiansuo::before { + content: "\e72f"; +} + +.icon-guiji::before { + content: "\e72c"; +} + +.icon-jichuxinxi::before { + content: "\e72b"; +} + +.icon-danganzhaiyao::before { + content: "\e72a"; +} + +.icon-jingzhunbukongicon_on::before { + content: "\e728"; +} + +.icon-jingzhunbukongicon_off::before { + content: "\e729"; +} + +.icon-tiaozhuan::before { + content: "\e727"; +} + +.icon-shezhi::before { + content: "\e726"; +} + +.icon-bangzhu1::before { + content: "\e725"; +} + +.icon-shuaxin1::before { + content: "\e724"; +} + +.icon-duosucaibeifen::before { + content: "\e722"; +} + +.icon-duosucai::before { + content: "\e723"; +} + +.icon-shujutongji::before { + content: "\e721"; +} + +.icon-renlian::before { + content: "\e71c"; +} + +.icon-xingti::before { + content: "\e71d"; +} + +.icon-jidongche::before { + content: "\e71e"; +} + +.icon-huisufenxi4::before { + content: "\e71f"; +} + +.icon-lixianfenxi4::before { + content: "\e720"; +} + +.icon-feijidongche::before { + content: "\e71b"; +} + +.icon-shujudaping::before { + content: "\e71a"; +} + +.icon-peizhisuanfa::before { + content: "\e719"; +} + +.icon-zhuizong::before { + content: "\e715"; +} + +.icon-zhuizongnor::before { + content: "\e716"; +} + +.icon-dianwei::before { + content: "\e714"; +} + +.icon-Container::before { + content: "\e713"; +} + +.icon-Attachment::before { + content: "\e712"; +} + +.icon-cha::before { + content: "\e711"; +} + +.icon-gou::before { + content: "\e710"; +} + +.icon-daoru::before { + content: "\e70f"; +} + +.icon-quanxijiansuo::before { + content: "\e70e"; +} + +.icon-chakanjiankong::before { + content: "\e70c"; +} + +.icon-tishi3::before { + content: "\e70d"; +} + +.icon-heiyemoshi::before { + content: "\e70b"; +} + +.icon-zhengchangmoshi::before { + content: "\e70a"; +} + +.icon-dingwei1::before { + content: "\e709"; +} + +.icon-paixu::before { + content: "\e708"; +} + +.icon-tianjiayuan::before { + content: "\e707"; +} + +.icon-juleidangankunor::before { + content: "\e705"; +} + +.icon-juleidanganku::before { + content: "\e706"; +} + +.icon-guanlian::before { + content: "\e704"; +} + +.icon-renlianbiaozhu::before { + content: "\e703"; +} + +.icon-juleijieguo::before { + content: "\e6ec"; +} + +.icon-juleirenwunor::before { + content: "\e6fb"; +} + +.icon-juleijieguonor::before { + content: "\e701"; +} + +.icon-juleirenwu::before { + content: "\e702"; +} + +.icon-zhongzhi3::before { + content: "\e8ff"; +} + +.icon-xuanzhuan1::before { + content: "\e6fd"; +} + +.icon-shuangmubiaozhu1::before { + content: "\e700"; +} + +.icon-shoudongkuangxuan::before { + content: "\e6f9"; +} + +.icon-zanting1::before { + content: "\e6fe"; +} + +.icon-zhongzhi1::before { + content: "\e6ff"; +} + +.icon-shoudong::before { + content: "\e6fa"; +} + +.icon-zidong::before { + content: "\e6fc"; +} + +.icon-zhenduan::before { + content: "\e6f8"; +} + +.icon-Check-Circle-Fill1::before { + content: "\e6f3"; +} + +.icon-Info--Circle-Fill::before { + content: "\e6f4"; +} + +.icon-Close-Circle-Fill::before { + content: "\e6f5"; +} + +.icon-Warning-Circle-Fill::before { + content: "\e6f6"; +} + +.icon-Question-Circle-Fill::before { + content: "\e6f7"; +} + +.icon-zancunjia::before { + content: "\e6f2"; +} + +.icon-Check-Circle-Fill::before { + content: "\e6f1"; +} + +.icon-tupianji::before { + content: "\e6f0"; +} + +.icon-quanping1::before { + content: "\e6ed"; +} + +.icon-yinliang::before { + content: "\e6ee"; +} + +.icon-suoxiao1::before { + content: "\e6ef"; +} + +.icon-home::before { + content: "\e6eb"; +} + +.icon-zuixiaohua::before { + content: "\e6e9"; +} + +.icon-zuidahua::before { + content: "\e6ea"; +} + +.icon-biaozhunhua::before { + content: "\e6e6"; +} + +.icon-julei::before { + content: "\e6e5"; +} + +.icon-bianzu::before { + content: "\e6e7"; +} + +.icon-bianzu3::before { + content: "\e6e8"; +} + +.icon-bianzu7::before { + content: "\e6e3"; +} + +.icon-bianzu2::before { + content: "\e6e4"; +} + +.icon-kapianqiehuan::before { + content: "\e6e2"; +} + +.icon-duobianxing1::before { + content: "\e6e0"; +} + +.icon-fang1::before { + content: "\e6e1"; +} + +.icon-yuan1::before { + content: "\e6df"; +} + +.icon-cejuli::before { + content: "\e6de"; +} + +.icon-wanggekuangxuannor::before { + content: "\e6dc"; +} + +.icon-lujingkuangxuannor::before { + content: "\e6dd"; +} + +.icon-chuansuo::before { + content: "\e6db"; +} + +.icon-bianyuanhezinor::before { + content: "\e6d8"; +} + +.icon-wujiankuhov::before { + content: "\e6d9"; +} + +.icon-caozuorizhinor::before { + content: "\e6da"; +} + +.icon-collect_dot::before { + content: "\e619"; +} + +.icon-chuxiandingweibg::before { + content: "\e6d4"; +} + +.icon-chuxiandingweiicon::before { + content: "\e6d5"; +} + +.icon-shexiangtoudingweibg::before { + content: "\e6d6"; +} + +.icon-shexiangtoudingweiicon::before { + content: "\e6d7"; +} + +.icon-xiafajieguo::before { + content: "\e6d2"; +} + +.icon-daochu1::before { + content: "\e6d3"; +} + +.icon-zuijinchuxian::before { + content: "\e6cc"; +} + +.icon-leijizhuapai::before { + content: "\e6d0"; +} + +.icon-yichangshijian::before { + content: "\e6d1"; +} + +.icon-dingwei::before { + content: "\e6cb"; +} + +.icon-tupian::before { + content: "\e6ad"; +} + +.icon-wenti::before { + content: "\e6ac"; +} + +.icon-lixian1::before { + content: "\e6ab"; +} + +.icon-yichang::before { + content: "\e6a8"; +} + +.icon-zhuixing-xiugaidianwei::before { + content: "\e6a7"; +} + +.icon-wenhao1::before { + content: "\e69e"; +} + +.icon-ditu_dingwei::before { + content: "\e69d"; +} + +.icon-ditu_fangda::before { + content: "\e689"; +} + +.icon-ditu_suoxiao::before { + content: "\e69a"; +} + +.icon-chakanbukongrenwu::before { + content: "\e688"; +} + +.icon-lietu::before { + content: "\e687"; +} + +.icon-zhongzhi::before { + content: "\e67e"; +} + +.icon-xialada::before { + content: "\e67f"; +} + +.icon-zhinengguanlian_xingti::before { + content: "\e67b"; +} + +.icon-zhinengguanlian_renlian::before { + content: "\e67c"; +} + +.icon-xiajiantou::before { + content: "\e75c"; +} + +.icon-zhinengguanlian_xiaojiantou::before { + content: "\e67d"; +} + +.icon-zhinengguanlian_jiantou::before { + content: "\e67a"; +} + +.icon-shangjiantou::before { + content: "\e75d"; +} + +.icon-banbenxinxi::before { + content: "\e679"; +} + +.icon-wenhao::before { + content: "\e61f"; +} + +.icon-bianjirenyuan::before { + content: "\e7e0"; +} + +.icon-tishi2::before { + content: "\e7df"; +} + +.icon-shexiangji2::before { + content: "\e7de"; +} + +.icon-guijizhuizong::before { + content: "\e7dd"; +} + +.icon-jiezhen1::before { + content: "\e7dc"; +} + +.icon-tianjiaguijihuisu::before { + content: "\e7db"; +} + +.icon-tingzhi::before { + content: "\e7cd"; +} + +.icon-baoweiquan::before { + content: "\e7ce"; +} + +.icon-shangchuanshipin::before { + content: "\e7d0"; +} + +.icon-yidong::before { + content: "\e7d1"; +} + +.icon-chuangjianxinbukong1::before { + content: "\e7d2"; +} + +.icon-yichu1::before { + content: "\e7d3"; +} + +.icon-tishi1::before { + content: "\e7d4"; +} + +.icon-VS::before { + content: "\e7d5"; +} + +.icon-quanjuzonglan::before { + content: "\e7d6"; +} + +.icon-chakanfenxirenwu1::before { + content: "\e7d7"; +} + +.icon-xiaoxi::before { + content: "\e7d8"; +} + +.icon-yonghuming::before { + content: "\e7d9"; +} + +.icon-tuichu::before { + content: "\e7da"; +} + +.icon-guijizhuizongnor::before { + content: "\e7cb"; +} + +.icon-guijizhuizong2::before { + content: "\e7cc"; +} + +.icon-bukongrenwu1::before { + content: "\e7b7"; +} + +.icon-shexiangji::before { + content: "\e7b8"; +} + +.icon-yujingditu::before { + content: "\e7ba"; +} + +.icon-lixianfenxi2::before { + content: "\e7bb"; +} + +.icon-yuanguanli1::before { + content: "\e7bc"; +} + +.icon-danganku::before { + content: "\e7bd"; +} + +.icon-huisufenxi2::before { + content: "\e7be"; +} + +.icon-kuneijiansuo::before { + content: "\e7bf"; +} + +.icon-jiegouhuachaxun::before { + content: "\e7c0"; +} + +.icon-bukongrenwu2::before { + content: "\e7c2"; +} + +.icon-yuanguanli2::before { + content: "\e7c3"; +} + +.icon-shexiangji1::before { + content: "\e7c4"; +} + +.icon-kuneijiansuo1::before { + content: "\e7c5"; +} + +.icon-lixianfenxi3::before { + content: "\e7c6"; +} + +.icon-danganku1::before { + content: "\e7c7"; +} + +.icon-yujingditu1::before { + content: "\e7c8"; +} + +.icon-huisufenxi3::before { + content: "\e7c9"; +} + +.icon-jiegouhuachaxunnor::before { + content: "\e7ca"; +} + +.icon-chuangjianxinbukong::before { + content: "\e7b6"; +} + +.icon-kuangxuan::before { + content: "\e77f"; +} + +.icon-gaojishaixuan::before { + content: "\e779"; +} + +.icon-gaojishaixuanshouqi::before { + content: "\e77a"; +} + +.icon-bukongrenwu::before { + content: "\e7b5"; +} + +.icon-riqi::before { + content: "\e74f"; +} + +.icon-shijianqiehuan::before { + content: "\e797"; +} + +.icon-shouquan1::before { + content: "\e7b3"; +} + +.icon-video-play::before { + content: "\e653"; +} + +.icon-shishifenxi::before { + content: "\e7af"; +} + +.icon-chakanfenxirenwu::before { + content: "\e7b0"; +} + +.icon-jiegouhuafenxi::before { + content: "\e7ad"; +} + +.icon-tianjiaguiji2::before { + content: "\e6aa"; +} + +.icon-tianjiajiansuomubiao::before { + content: "\e6b0"; +} + +.icon-add::before { + content: "\e661"; +} + +.icon-didian::before { + content: "\e798"; +} + +.icon-bofanghov::before { + content: "\e79f"; +} + +.icon-bofang3::before { + content: "\e7a0"; +} + +.icon-jinggao::before { + content: "\e788"; +} + +.icon-tishi::before { + content: "\e789"; +} + +.icon-bangzhu::before { + content: "\e78a"; +} + +.icon-guanbi1::before { + content: "\e78b"; +} + +.icon-chenggong::before { + content: "\e78c"; +} + +.icon-qianwang::before { + content: "\e7ac"; +} + +.icon-shouquan::before { + content: "\e7ab"; +} + +.icon-jingweidu::before { + content: "\e7aa"; +} + +.icon-shanchu1::before { + content: "\e74e"; +} + +.icon-daochu::before { + content: "\e782"; +} + +.icon-ziyuanguanli::before { + content: "\e7a4"; +} + +.icon-fuwuqishouquan::before { + content: "\e7a5"; +} + +.icon-xiugaimima::before { + content: "\e7a6"; +} + +.icon-zhanghaoguanli::before { + content: "\e7a7"; +} + +.icon-suanlipeie::before { + content: "\e7a8"; +} + +.icon-VMSpeizhi::before { + content: "\e7a9"; +} + +.icon-tianjia1::before { + content: "\e794"; +} + +.icon-yichu::before { + content: "\e795"; +} + +.icon-lujing::before { + content: "\e6cf"; +} + +.icon-jiankongxinxi::before { + content: "\e6c8"; +} + +.icon-fanwei::before { + content: "\e6c9"; +} + +.icon-anfadidian::before { + content: "\e6ca"; +} + +.icon-gongjuxiang::before { + content: "\e6cd"; +} + +.icon-gongjuxiangguanbi1::before { + content: "\e6ce"; +} + +.icon-jiezhen::before { + content: "\e6c2"; +} + +.icon-huisufenxi1::before { + content: "\e6c6"; +} + +.icon-huisufenxi::before { + content: "\e6c7"; +} + +.icon-tianjiashipinwenjian1::before { + content: "\e6c5"; +} + +.icon-jiazaishibai::before { + content: "\e6c3"; +} + +.icon-shuaxin::before { + content: "\e6c4"; +} + +.icon-quanping::before { + content: "\e6c0"; +} + +.icon-quxiaoquanping::before { + content: "\e6c1"; +} + +.icon-shipinbofang::before { + content: "\e6be"; +} + +.icon-shipinzanting::before { + content: "\e6bf"; +} + +.icon-lixianguiji::before { + content: "\e6bd"; +} + +.icon-lixian::before { + content: "\e6bc"; +} + +.icon-xiaojiaobiao::before { + content: "\e6bb"; +} + +.icon-shangchuan1::before { + content: "\e6ba"; +} + +.icon-tianjiaweijiansuoduixiang::before { + content: "\e6b8"; +} + +.icon-tianjiaweijiansuojilu::before { + content: "\e6b9"; +} + +.icon-lixianfenxi1::before { + content: "\e6b7"; +} + +.icon-kuaisujiansuohov::before { + content: "\e6b5"; +} + +.icon-kuaisujiansuo1::before { + content: "\e6b6"; +} + +.icon-kuaisujiansuo::before { + content: "\e6b4"; +} + +.icon-yuanguanli::before { + content: "\e6b1"; +} + +.icon-shexiangtou::before { + content: "\e6b2"; +} + +.icon-lixianfenxi::before { + content: "\e6b3"; +} + +.icon-filter::before { + content: "\e61a"; +} + +.icon-tianjiaweizhuizongduixiang2::before { + content: "\e6af"; +} + +.icon-tianjiaweizhuizongduixiang1::before { + content: "\e6ae"; +} + +.icon-baocun1::before { + content: "\e6a9"; +} + +.icon-tianjiashipinwenjianjia::before { + content: "\e6a5"; +} + +.icon-tianjiashipinwenjian::before { + content: "\e6a6"; +} + +.icon-ditu::before { + content: "\e6a4"; +} + +.icon-xinjianshexiangtou::before { + content: "\e6a3"; +} + +.icon-lishihuisu::before { + content: "\e6a2"; +} + +.icon-decoyitianjiaweiguiji::before { + content: "\e69f"; +} + +.icon-bofangqiehuan::before { + content: "\e6a0"; +} + +.icon-tianjia::before { + content: "\e6a1"; +} + +.icon-baocun::before { + content: "\e698"; +} + +.icon-gongjuxiangguanbi::before { + content: "\e699"; +} + +.icon-shangchuan::before { + content: "\e69b"; +} + +.icon-gongjuxiang1::before { + content: "\e69c"; +} + +.icon-logo::before { + content: "\e692"; +} + +.icon-setting::before { + content: "\e627"; +} + +.icon-user::before { + content: "\e628"; +} + +.icon-quit::before { + content: "\e629"; +} + +.icon-arrowzhankaimeixuanzhong::before { + content: "\e693"; +} + +.icon-arrowzhankaixuanzhong::before { + content: "\e694"; +} + +.icon-xuanzexuanzhong::before { + content: "\e695"; +} + +.icon-xuanzebanxuan::before { + content: "\e696"; +} + +.icon-xuanzenor::before { + content: "\e697"; +} + +.icon-shaixuanguanbinor::before { + content: "\e691"; +} + +.icon-gengduo::before { + content: "\e68e"; +} + +.icon-youzhankai::before { + content: "\e68f"; +} + +.icon-zuoshouqi::before { + content: "\e690"; +} + +.icon-yuan::before { + content: "\e68a"; +} + +.icon-duobianxing::before { + content: "\e68b"; +} + +.icon-fang::before { + content: "\e68c"; +} + +.icon-ceju::before { + content: "\e68d"; +} + +.icon-shishizhuizong1::before { + content: "\e683"; +} + +.icon-guijihuisu1::before { + content: "\e684"; +} + +.icon-tianjiaguiji::before { + content: "\e685"; +} + +.icon-yichuguiji::before { + content: "\e686"; +} + +.icon-fangda::before { + content: "\e680"; +} + +.icon-suoxiao::before { + content: "\e681"; +} + +.icon-xiazai::before { + content: "\e682"; +} + +.icon-fanhui::before { + content: "\e678"; +} + +.icon-sousuo::before { + content: "\e669"; +} + +.icon-quxiaoxuanzhong::before { + content: "\e66a"; +} + +.icon-piliangxuanzenor::before { + content: "\e66b"; +} + +.icon-kaiqifenxi::before { + content: "\e66c"; +} + +.icon-quxiaofenxi::before { + content: "\e66d"; +} + +.icon-shaixuan::before { + content: "\e66e"; +} + +.icon-dangan::before { + content: "\e66f"; +} + +.icon-bofang::before { + content: "\e670"; +} + +.icon-zanting::before { + content: "\e671"; +} + +.icon-shanchu::before { + content: "\e672"; +} + +.icon-tianjiaweizhuizongduixiang::before { + content: "\e673"; +} + +.icon-chakandatu::before { + content: "\e674"; +} + +.icon-jiansuojilu::before { + content: "\e675"; +} + +.icon-yuzhi::before { + content: "\e676"; +} + +.icon-chakanxiangqing::before { + content: "\e677"; +} + +.icon-guijihuisu::before { + content: "\e65c"; +} + +.icon-dianweipeizhinor::before { + content: "\e65d"; +} + +.icon-yirenyidang::before { + content: "\e65e"; +} + +.icon-tongbanfenxi::before { + content: "\e65f"; +} + +.icon-qiehuanzuo::before { + content: "\e662"; +} + +.icon-qiehuanyou::before { + content: "\e663"; +} + +.icon-tingzhidengdai::before { + content: "\e664"; +} + +.icon-yiguanbi::before { + content: "\e665"; +} + +.icon-danchuangguanbi::before { + content: "\e666"; +} + +.icon-lishijilu::before { + content: "\e64a"; +} + +.icon-xuanzhuan::before { + content: "\e648"; +} + +.icon-qingchu::before { + content: "\e649"; +} + +.icon-dangantianjia::before { + content: "\e63d"; +} + +.icon-bianji::before { + content: "\e63e"; +} + +.icon-fullscreen::before { + content: "\e63b"; +} + +.icon-cancle_fullscreen::before { + content: "\e63c"; +} + +.icon-quanyujiansuo_nor::before { + content: "\e639"; +} + +.icon-guijihuisu_nor::before { + content: "\e63a"; +} + diff --git a/packages/meta/lib/iconfont/iconfont.js b/packages/meta/lib/iconfont/iconfont.js new file mode 100644 index 0000000..16d543e --- /dev/null +++ b/packages/meta/lib/iconfont/iconfont.js @@ -0,0 +1,36 @@ +// src/iconfont/iconfont.js +window._iconfont_svg_string_1739270 = '', function(h) { + var a = (a = document.getElementsByTagName("script"))[a.length - 1], l = a.getAttribute("data-injectcss"), a = a.getAttribute("data-disable-injectsvg"); + if (!a) { + var i, c, o, t, z, v = function(a2, l2) { + l2.parentNode.insertBefore(a2, l2); + }; + if (l && !h.__iconfont__svg__cssinject__) { + h.__iconfont__svg__cssinject__ = true; + try { + document.write(""); + } catch (a2) { + console && console.log(a2); + } + } + i = function() { + var a2, l2 = document.createElement("div"); + l2.innerHTML = h._iconfont_svg_string_1739270, (l2 = l2.getElementsByTagName("svg")[0]) && (l2.setAttribute("aria-hidden", "true"), l2.style.position = "absolute", l2.style.width = 0, l2.style.height = 0, l2.style.overflow = "hidden", l2 = l2, (a2 = document.body).firstChild ? v(l2, a2.firstChild) : a2.appendChild(l2)); + }, document.addEventListener ? ~["complete", "loaded", "interactive"].indexOf(document.readyState) ? setTimeout(i, 0) : (c = function() { + document.removeEventListener("DOMContentLoaded", c, false), i(); + }, document.addEventListener("DOMContentLoaded", c, false)) : document.attachEvent && (o = i, t = h.document, z = false, p(), t.onreadystatechange = function() { + "complete" == t.readyState && (t.onreadystatechange = null, m()); + }); + } + function m() { + z || (z = true, o()); + } + function p() { + try { + t.documentElement.doScroll("left"); + } catch (a2) { + return void setTimeout(p, 50); + } + m(); + } +}(window); diff --git a/packages/meta/lib/iconfont/iconfont.ttf b/packages/meta/lib/iconfont/iconfont.ttf new file mode 100644 index 0000000000000000000000000000000000000000..0043e6adb470d27d9eb668a85699dab6ac06590f GIT binary patch literal 105116 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�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 literal 0 HcmV?d00001 diff --git a/packages/meta/lib/iconfont/iconfont.woff2 b/packages/meta/lib/iconfont/iconfont.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..81733409e71fc4817fe0404afb2dc8294fcd6a6a GIT binary patch literal 48900 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 literal 0 HcmV?d00001 diff --git a/packages/meta/lib/iconfont/index.d.ts b/packages/meta/lib/iconfont/index.d.ts index e769332..fcafc45 100644 --- a/packages/meta/lib/iconfont/index.d.ts +++ b/packages/meta/lib/iconfont/index.d.ts @@ -1,4 +1,5 @@ import React from 'react'; +import './iconfont.css'; interface IconFontProps { styles?: React.CSSProperties; icon?: string; diff --git a/packages/meta/lib/iconfont/index.js b/packages/meta/lib/iconfont/index.js index 900a9ac..c1cfc88 100644 --- a/packages/meta/lib/iconfont/index.js +++ b/packages/meta/lib/iconfont/index.js @@ -34,6 +34,7 @@ __export(iconfont_exports, { module.exports = __toCommonJS(iconfont_exports); var import_react = __toESM(require("react")); var import_classnames = __toESM(require("classnames")); +var import_iconfont = require("./iconfont.css"); var IconFont = (props) => { const { title = "", diff --git a/packages/meta/lib/index.d.ts b/packages/meta/lib/index.d.ts index 241716b..e0961ce 100644 --- a/packages/meta/lib/index.d.ts +++ b/packages/meta/lib/index.d.ts @@ -1,3 +1,5 @@ export { default as doubleClick } from './doubleClick'; export { default as Icon } from './iconfont'; -export { default as ImagePreview } from './ImagePreview'; +export { default as CompareImage } from './CompareImage'; +export { default as BigImagePreview } from './BigImagePreview'; +export { default as VideoPlayer } from './VideoPlayer'; diff --git a/packages/meta/lib/index.js b/packages/meta/lib/index.js index f9d0355..bbf718b 100644 --- a/packages/meta/lib/index.js +++ b/packages/meta/lib/index.js @@ -29,17 +29,23 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru // src/index.tsx var src_exports = {}; __export(src_exports, { + BigImagePreview: () => import_BigImagePreview.default, + CompareImage: () => import_CompareImage.default, Icon: () => import_iconfont.default, - ImagePreview: () => import_ImagePreview.default, + VideoPlayer: () => import_VideoPlayer.default, doubleClick: () => import_doubleClick.default }); module.exports = __toCommonJS(src_exports); var import_doubleClick = __toESM(require("./doubleClick")); var import_iconfont = __toESM(require("./iconfont")); -var import_ImagePreview = __toESM(require("./ImagePreview")); +var import_CompareImage = __toESM(require("./CompareImage")); +var import_BigImagePreview = __toESM(require("./BigImagePreview")); +var import_VideoPlayer = __toESM(require("./VideoPlayer")); // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { + BigImagePreview, + CompareImage, Icon, - ImagePreview, + VideoPlayer, doubleClick }); diff --git a/packages/meta/lib/utils/constants.d.ts b/packages/meta/lib/utils/constants.d.ts new file mode 100644 index 0000000..f9bb021 --- /dev/null +++ b/packages/meta/lib/utils/constants.d.ts @@ -0,0 +1,12 @@ +export declare const CROP_TYPE: { + CUSTOM: string; + AUTO: string; +}; +export declare const defaultAlignOption: { + points: string[]; + offset: number[]; + overflow: { + adjustX: boolean; + adjustY: boolean; + }; +}; diff --git a/packages/meta/lib/utils/constants.js b/packages/meta/lib/utils/constants.js new file mode 100644 index 0000000..caa5deb --- /dev/null +++ b/packages/meta/lib/utils/constants.js @@ -0,0 +1,42 @@ +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// src/utils/constants.ts +var constants_exports = {}; +__export(constants_exports, { + CROP_TYPE: () => CROP_TYPE, + defaultAlignOption: () => defaultAlignOption +}); +module.exports = __toCommonJS(constants_exports); +var CROP_TYPE = { + CUSTOM: "CSUTOM", + AUTO: "AUTO" +}; +var defaultAlignOption = { + points: ["bl", "br"], + offset: [6, 0], + overflow: { + adjustX: true, + adjustY: true + } +}; +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + CROP_TYPE, + defaultAlignOption +}); diff --git a/packages/meta/package.json b/packages/meta/package.json index 511d81a..9ffc250 100644 --- a/packages/meta/package.json +++ b/packages/meta/package.json @@ -1,6 +1,6 @@ { "name": "@zhst/meta", - "version": "0.2.4", + "version": "0.3.0", "description": "原子组件", "keywords": [ "meta", diff --git a/packages/meta/src/BigImagePreview/BigImagePreview.tsx b/packages/meta/src/BigImagePreview/BigImagePreview.tsx new file mode 100644 index 0000000..f7fbf93 --- /dev/null +++ b/packages/meta/src/BigImagePreview/BigImagePreview.tsx @@ -0,0 +1,562 @@ +import React, { useEffect, ReactElement, useState, useCallback, useRef, useImperativeHandle } from 'react'; +import classNames from 'classnames'; +import { useLatest } from '@zhst/hooks'; +import { + get, + pick, + isNull, + generateImg, + dataURLToBlob, + getOdRect, + getExtendRect, + getTransformRect, + getRotateImg, + getTransforms, + addEventListenerWrapper, + upload, + getFileByRect +} from '@zhst/func'; +import Align from 'rc-align'; +import { Button, Empty } from 'antd'; +import { type Rect, type IScreenshotButtonProp, type ODRECT, type AlignType, type ViewOption, type IOdRectOrigin, AlgorithmVersion } from '@zhst/types' +import Icon from '../iconfont'; +import { + Cropper, + Viewer, + EVENT_VIEWER_TRANSFORM_CHANGE, + EVENT_VIEWER_READY, + EVENT_CROP_START, + EVENT_CROP_END, +} from '../ImageEditor'; +import BtnGroup from './components/BtnGroup'; +import './index.less' +import getScreenshotButtonRender from './components/ScreenhotButtons'; +import { defaultAlignOption, CROP_TYPE } from '../utils/constants' + +const componentName = `zhst-image__img-view`; + +export interface ImgViewProps extends React.HTMLAttributes { + dataSource: Array<{ + url?: string + imageKey: string + attachImg?: Array<{ label: string; url: string }>; // 缩略图列表 + odRect?: Rect + score?: number + showScore?: boolean + cameraPosition?: string + time?: string | number + objects: any[] + }> + showAttachImgLabel: boolean; // 是否显示缩略图 + showOpt: boolean; // 是否显示操作面板 + width?: string | number; // 画布宽度 + height?: string | number; // 画布高度 + /* 截图渲染 */ + screenshotButtonAlign: AlignType; + screenshotButtonRender: (screenshotButtonProp: IScreenshotButtonProp) => ReactElement; + hideLeftTopBtn?: boolean; + showScore?: boolean // 是否显示相似度 + viewOption?: ViewOption; + objects: IOdRectOrigin[] // 图片人物框选 +} +export interface ImgViewRef { + /* 图片实例 */ + imgInsRef: React.MutableRefObject; + /* 切换编辑模式 */ + setShowCrop: React.Dispatch>; +} + +const cropBtnDataSource = [ + { + key: 'close', + icon: 'icon-danchuangguanbi', + title: '退出', + }, + { + key: 'autoCrop', + icon: 'icon-zidong', + title: '智能框选', + }, + { + key: 'customCrop', + icon: 'icon-shoudong', + title: '手动框选', + }, +]; + +const operateBtnDataSource = [ + { + key: 'zoomOut', + icon: 'icon-fangda', + title: '放大', + }, + { + key: 'zoomIn', + icon: 'icon-suoxiao', + title: '缩小', + }, + { + key: 'reset', + icon: 'icon-zhongzhi3', + title: '重置图片', + }, +]; + +export const BigImagePreview = React.forwardRef((props, ref) => { + const { + dataSource = [], + width, + height, + showScore = true, + objects = [], + showOpt = false, + showAttachImgLabel = true, + screenshotButtonAlign = defaultAlignOption, + screenshotButtonRender = getScreenshotButtonRender({ + onBigImageActionClick: () => {}, + disableBtn: [], + }), + hideLeftTopBtn = true, + viewOption = {} + } = props; + const imgContainerRef = React.useRef(null); + const [isReady, setIsReady] = useState(false); + const [currentIndex, setCurrentIndex] = useState(0) + + console.log('props', props) + + const init = useCallback(($container: null) => { + imgContainerRef.current = $container; + setIsReady(true); + }, []); + // ============================= viewer ========================= + const imgInsRef = useRef(null); + const [isImgReady, setIsImgReady] = useState(false); + + useEffect(() => { + console.log('123', 123) + if (!isReady || !imgContainerRef?.current) return; + const handleReady = addEventListenerWrapper(imgContainerRef.current, EVENT_VIEWER_READY, () => { + setIsImgReady(true); + }); + const handleTransformChange = addEventListenerWrapper( + imgContainerRef.current, + EVENT_VIEWER_TRANSFORM_CHANGE, + () => { + } + ); + imgInsRef.current = new Viewer(imgContainerRef.current, { + ...viewOption, + fitScaleAsMinScale: true, + image: generateImg(dataSource[currentIndex]?.imageKey), + }); + return () => { + handleReady?.remove(); + handleTransformChange?.remove(); + imgInsRef?.current?.destroy?.(); + imgInsRef.current = null; + }; + }, [isReady, currentIndex]); + + // ============================= viewer操作按钮 ========================= + const handleOptClick = (v: string) => { + switch (v) { + case 'zoomOut': + imgInsRef?.current?.scaleTo?.(0.1); + break; + case 'zoomIn': + imgInsRef?.current?.scaleTo?.(-0.1); + break; + case 'reset': + imgInsRef?.current?.reset?.(-0.1); + break; + } + }; + + // ============================= cropper ========================= + // 手动截图相关参数 + const cropInsRef: any = useRef(null); + const [showCrop, setShowCrop] = useState(showOpt); + const [cropType, setCropType] = useState(CROP_TYPE['AUTO']); + + // 自动截图相关参数 + const [odList, setOdList] = useState([]); + const [extendOdList, setExtendOdList] = useState([]); + const [selectRectId, setSelectRectId] = useState(null); + + // 定位按钮相关参数 + const alginContainerRef: any = useRef(null); + const alignRef: any = useRef(null); + const [cropRect, setCropRect] = useState(null); + + // 选中的版本号 + const [selectAlgorithmVersion, setSelectAlgorithmVersion] = useState(null); + const handlerCropStartRef: any = useRef(null); + const handlerCropEndRef: any = useRef(null); + const handleShapeSelectRef: any = useRef(null); + + useEffect(() => { + initData(dataSource[currentIndex].objects || objects) + return () => { + imgInsRef.current?.clearShape?.(); + handlerCropStartRef.current?.remove(); + handlerCropEndRef.current?.remove(); + handleShapeSelectRef.current?.remove(); + cropInsRef?.current?.destroy?.(); + cropInsRef.current = null; + }; + }, [isImgReady, showCrop, cropType, currentIndex]); + + const initData = (_objects: IOdRectOrigin[]) => { + const imgIns = imgInsRef.current; + const _odRect = dataSource[currentIndex].odRect + //清理crop + setCropRect(null); + if (!isImgReady) return; + if (!showCrop) { + imgIns?.addShape?.({ + x: get(_odRect, 'x', 0), + y: get(_odRect, 'y', 0), + w: get(_odRect, 'w', 0), + h: get(_odRect, 'h', 0), + selectAble: false, + }); + return; + } + + // 自动模式 + if (cropType === CROP_TYPE['AUTO']) { + const handleGetOD = (odList: any) => { + const imgSize = imgIns.getImgSize(); + const shapeList = odList.map((rect: { [x: string]: any; algorithmVersion: any; }) => ({ + ...rect, + selectAble: true, + id: rect['id'], + algorithmVersion: rect.algorithmVersion, + })); + imgIns.replaceShape(shapeList); + //顺便吧扩展框拿到 + const extendRect = shapeList.map((rect: { algorithmVersion: string; }) => { + // @ts-ignore + const _extendRect = getExtendRect(rect, imgSize.w, imgSize.h, rect.algorithmVersion); + return { ...rect, ..._extendRect }; + }); + setExtendOdList(extendRect); + imgIns.replaceShape(shapeList); + handleShapeSelectRef.current = addEventListenerWrapper(imgContainerRef.current, 'shape-select', (e: { detail: any; }) => { + const id = e.detail; + setSelectRectId(id); + const selectShape = shapeList.find((v: { [x: string]: any; }) => v['id'] === id); + if (selectShape) { + setSelectAlgorithmVersion(selectShape['algorithmVersion']); + //换算成屏幕坐标 + const axisRect = imgIns.imgRectAxisToCanvasAxisRect(selectShape); + const rect = { + x: axisRect.x2 > axisRect.x ? axisRect.x : axisRect.x2, + y: axisRect.y2 > axisRect.y ? axisRect.y : axisRect.y2, + w: Math.abs(axisRect.x2 - axisRect.x), + h: Math.abs(axisRect.y2 - axisRect.y), + }; + setCropRect(rect); + } else { + // @ts-ignore + setCropRect(null); + } + }); + }; + // @ts-ignore + const rect = getOdRect({ objects: _objects }) + setOdList(rect); + handleGetOD(rect); + } + + // 手动模式 + if (cropType === CROP_TYPE['CUSTOM']) { + // 手动框选状态预先清除imgIns + imgIns?.clearShape?.(); + handlerCropStartRef.current = addEventListenerWrapper(imgContainerRef.current, EVENT_CROP_START, () => { + setSelectAlgorithmVersion(null); + setCropRect(null); + }); + handlerCropEndRef.current = addEventListenerWrapper(imgContainerRef.current, EVENT_CROP_END, (event: { detail: any; }) => { + const data = event.detail; + setSelectAlgorithmVersion(null); + setCropRect({ + x: data.left, + y: data.top, + w: data.width, + h: data.height, + }); + alignRef?.current?.forceAlign?.(); + }); + cropInsRef.current = new Cropper(imgContainerRef.current, { + showMask: true, + viewer: imgIns, + }); + } + } + + // 获取框选的截图框信息 + const latestCropType = useLatest(cropType); + const latestImgKey = useLatest(dataSource[currentIndex].imageKey); + const latestCropRect = useLatest(cropRect); + const getCropInfo = async () => { + const cropType = latestCropType.current; + const cropRect = latestCropRect.current; + const imgIns = imgInsRef.current; + const transform = imgIns.targetTransform; + let newImgKey = latestImgKey.current; + let rectList: any = []; + let extendRectList = []; + let selectIndex = 0; + switch (cropType) { + case CROP_TYPE['AUTO']: + const shapes = imgIns.getSelectShape(); + const shapeIds = shapes.map((v: { [x: string]: any; }) => v['id']); + rectList = odList + .filter((v: { [x: string]: any; }) => shapeIds.includes(v['id'])) + .map((item: any) => { + if ( + item.algorithmVersion === 'OBJECT_TYPE_FACE' || + item.objectType === 'OBJECT_TYPE_FACE' + ) { + if (!isNull(item.extendBox)) { + return { + ...item, + w: get(item, 'extendBox.w'), + h: get(item, 'extendBox.h'), + x: get(item, 'extendBox.x'), + y: get(item, 'extendBox.y'), + }; + } + } else { + return item; + } + }); + extendRectList = extendOdList + .filter((v) => shapeIds.includes(v['id'])) + .map((v) => pick(v, ['x', 'y', 'w', 'h', 'algorithmVersion', 'id'])); + selectIndex = rectList.findIndex((v: { [x: string]: null; }) => v['id'] === selectRectId); + break; + default: + //获取旋转过的坐标 + // @ts-ignore + const newRect = getTransformRect(imgIns.image, transform, cropRect); + //判断是不是旋转过 + if (get(transform, 'rotate', 0) % 360 != 0) { + const data = getRotateImg(imgIns.image, get(transform, 'rotate', 0)) as any; + //在画布上画旋转后的图片 + newImgKey = await upload(data) as any; + } + rectList.push(newRect); + extendRectList.push(newRect); + break; + } + //扩展框获取imgkey + await Promise.all( + extendRectList.map(async (rect, index) => { + const file = await getFileByRect(imgIns.image, rect); + const imgKey = await upload(file); + extendRectList[index] = { ...rect, imgKey }; + }) + ); + //人脸图获取矫正图 + await Promise.all( + rectList.map(async (rect: { [x: string]: any; }, index: string | number) => { + const faceCorrectImage = rect['faceCorrectImage']; + let faceCorrectImageKey; + if (faceCorrectImage) { + const base64 = `data:image/jpg;base64,${faceCorrectImage}`; + const blobData = dataURLToBlob(base64); + const file = new window.File([blobData], `${new Date().getTime()}`); + faceCorrectImageKey = await upload(file); + } + const newRect: any = { + ...rect, + ...(faceCorrectImageKey ? { faceCorrectImageKey } : {}), + }; + delete newRect['faceCorrectImage']; + rectList[index] = newRect; + }) + ); + return { rectList, extendRectList, selectIndex, imgKey: newImgKey }; + }; + + // 操作界面判断 + const handleCropBtnClick = (v: string) => { + switch (v) { + case 'close': + setShowCrop(false); + break; + case 'autoCrop': + setCropType(CROP_TYPE['AUTO']); + break; + case 'customCrop': + setCropType(CROP_TYPE['CUSTOM']); + break; + } + }; + + // ============================= attact img ========================= + const [selectAttachImgIndex, setSelectAttachImgIndex] = useState(0); + const [isZoomin, setIsZoomin] = useState(false); + + /** + * 修改当前图片预览下标 + * @param diff 跳转强度 正向后翻、负值向前翻 + */ + const handleChangeIndex = (diff: number) => { + const _index = currentIndex + diff + + if (!dataSource?.[_index]?.imageKey) return + setCurrentIndex(_index) + } + + // ============================== Ref =============================== + useImperativeHandle(ref, () => ({ + imgInsRef, + setShowCrop, + initData, + getCropInfo, + handleChangeIndex + })); + + return ( +
    + {/*场景图大图 */} + {dataSource.length ? + <> +
    + {/* 图片操作 */} + {!hideLeftTopBtn && ( + + )} + {showCrop && ( + + )} + {showCrop && cropRect && screenshotButtonRender && ( + <> +
    + + {screenshotButtonRender({ + model: 'IMAGE', + getCropInfo, + setShowCrop, + cropType, + selectAlgorithmVersion, + })} + + + )} + {/* 场景图小图 */} + {dataSource[currentIndex].attachImg?.length && !showCrop && ( +
    +
    + {showAttachImgLabel + ? dataSource[currentIndex].attachImg?.map(({ label }, index) => ( +
    { + setSelectAttachImgIndex(index); + }} + > + {label} +
    + )) + : null} +
    +
    + +
    + +
    + )} + {showScore &&
    + {`人脸质量分:${(Number(dataSource[currentIndex].score) as number).toFixed(2)}`} +
    } + + : + + } +
    + ); +}); + +BigImagePreview.displayName = 'BigImagePreview'; + +export default BigImagePreview; diff --git a/packages/meta/src/BigImagePreview/bigImagePreviewHelper.ts b/packages/meta/src/BigImagePreview/bigImagePreviewHelper.ts new file mode 100644 index 0000000..e69de29 diff --git a/packages/meta/src/BigImagePreview/components/ScreenhotButtons/index.tsx b/packages/meta/src/BigImagePreview/components/ScreenhotButtons/index.tsx index 8ce3fdb..c50a562 100644 --- a/packages/meta/src/BigImagePreview/components/ScreenhotButtons/index.tsx +++ b/packages/meta/src/BigImagePreview/components/ScreenhotButtons/index.tsx @@ -11,7 +11,7 @@ interface IScreenShotButton { getCropInfo: () => void setShowCrop: any cropType: string - selectAlgorithmVersion: AlgorithmVersion + selectAlgorithmVersion?: AlgorithmVersion | null } const getScreenshotButtonRender = (arg: { @@ -75,9 +75,9 @@ const getScreenshotButtonRender = (arg: { selectAlgorithmVersion !== 0 && ( + diff --git a/packages/meta/src/BigImagePreview/index.tsx b/packages/meta/src/BigImagePreview/index.tsx index 36dc99f..b24e175 100644 --- a/packages/meta/src/BigImagePreview/index.tsx +++ b/packages/meta/src/BigImagePreview/index.tsx @@ -1,540 +1,5 @@ -import React, { useEffect, ReactElement, useState, useCallback, useRef, useImperativeHandle } from 'react'; -import classNames from 'classnames'; -import { useLatest } from '@zhst/hooks'; -import { - get, - pick, - isNull, - generateImg, - dataURLToBlob, - getOdRect, - getExtendRect, - getTransformRect, - getRotateImg, - getTransforms, - addEventListenerWrapper, - upload, - getFileByRect -} from '@zhst/func'; -import Align from 'rc-align'; -import { Button } from 'antd'; -import type { Rect, IScreenshotButtonProp, ODRECT, AlignType, ViewOption, IOdRectOrigin } from '@zhst/types' -import Icon from '../iconfont'; -import { - Cropper, - Viewer, - EVENT_VIEWER_TRANSFORM_CHANGE, - EVENT_VIEWER_READY, - EVENT_CROP_START, - EVENT_CROP_END, -} from '../ImageEditor'; -import BtnGroup from './components/BtnGroup'; -import './index.less' -import getScreenshotButtonRender from './components/ScreenhotButtons'; +import BigImagePreview from './BigImagePreview' -const componentName = `zhst-image__img-view`; +export type { ImgViewProps } from './BigImagePreview' -export const CROP_TYPE = { - CUSTOM: 'CSUTOM', - AUTO: 'AUTO', -}; - -export const defaultAlignOption = { - points: ['bl', 'br'], - offset: [6, 0], - overflow: { - adjustX: true, - adjustY: true, - }, -}; - -export interface ImgViewProps extends React.HTMLAttributes { - imageKey: string; //不在监听url变化 更新走销毁 - odRect: ODRECT; - attachImg?: Array<{ label: string; url: string }>; // 缩略图列表 - showAttachImgLabel: boolean; // 是否显示缩略图 - showOpt: boolean; // 是否显示操作面板 - width?: string | number; - height?: string | number; - /* 截图渲染 */ - screenshotButtonAlign: AlignType; - screenshotButtonRender: (screenshotButtonProp: IScreenshotButtonProp) => ReactElement; - hideLeftTopBtn?: boolean; - score?: number; - viewOption?: ViewOption; - objects: IOdRectOrigin[] -} -export interface ImgViewRef { - /* 图片实例 */ - imgInsRef: React.MutableRefObject; - /* 切换编辑模式 */ - setShowCrop: React.Dispatch>; -} - -const cropBtnDataSource = [ - { - key: 'close', - icon: 'icon-danchuangguanbi', - title: '退出', - }, - { - key: 'autoCrop', - icon: 'icon-zidong', - title: '智能框选', - }, - { - key: 'customCrop', - icon: 'icon-shoudong', - title: '手动框选', - }, -]; - -const operateBtnDataSource = [ - { - key: 'zoomOut', - icon: 'icon-fangda', - title: '放大', - }, - { - key: 'zoomIn', - icon: 'icon-suoxiao', - title: '缩小', - }, - { - key: 'reset', - icon: 'icon-zhongzhi3', - title: '重置图片', - }, -]; - -export const ImgView = React.forwardRef((props, ref) => { - const { - imageKey, - width, - height, - odRect, - score = 0, - attachImg = [], - objects = [], - showOpt = false, - showAttachImgLabel = true, - screenshotButtonAlign = defaultAlignOption, - screenshotButtonRender = getScreenshotButtonRender({ - onBigImageActionClick: () => {}, - disableBtn: [], - }), - hideLeftTopBtn = true, - viewOption = {} - } = props; - const imgContainerRef = React.useRef(null); - const [isReady, setIsReady] = useState(false); - - console.log('props', props) - - const init = useCallback(($container: null) => { - imgContainerRef.current = $container; - setIsReady(true); - }, []); - // ============================= viewer ========================= - const imgInsRef = useRef(null); - const [isImgReady, setIsImgReady] = useState(false); - - useEffect(() => { - if (!isReady) return; - const handleReady = addEventListenerWrapper(imgContainerRef.current, EVENT_VIEWER_READY, () => { - setIsImgReady(true); - }); - const handleTransformChange = addEventListenerWrapper( - imgContainerRef.current, - EVENT_VIEWER_TRANSFORM_CHANGE, - () => { - } - ); - imgInsRef.current = new Viewer(imgContainerRef.current, { - ...viewOption, - fitScaleAsMinScale: true, - image: generateImg(imageKey), - }); - return () => { - handleReady?.remove(); - handleTransformChange?.remove(); - imgInsRef?.current?.destroy?.(); - imgInsRef.current = null; - }; - }, [isReady, imageKey]); - - // ============================= viewer操作按钮 ========================= - const handleOptClick = (v: string) => { - switch (v) { - case 'zoomOut': - imgInsRef?.current?.scaleTo?.(0.1); - break; - case 'zoomIn': - imgInsRef?.current?.scaleTo?.(-0.1); - break; - case 'reset': - imgInsRef?.current?.reset?.(-0.1); - break; - } - }; - - // ============================= cropper ========================= - // 手动截图相关参数 - const cropInsRef = useRef(null); - const [showCrop, setShowCrop] = useState(showOpt); - const [cropType, setCropType] = useState(CROP_TYPE['AUTO']); - - // 自动截图相关参数 - const [odList, setOdList] = useState([]); - const [extendOdList, setExtendOdList] = useState([]); - const [selectRectId, setSelectRectId] = useState(null); - - // 定位按钮相关参数 - const aliginContainerRef = useRef(null); - const alignRef = useRef(null); - const [cropRect, setCropRect] = useState(null); - - // 选中的版本号 - const [selectAlgorithmVersion, setSelectAlgorithmVersion] = useState(null); - const handlerCropStartRef = useRef(null); - const handlerCropEndRef = useRef(null); - const handleShapeSelectRef = useRef(null); - - useEffect(() => { - initData(objects) - return () => { - imgInsRef.current?.clearShape?.(); - handlerCropStartRef.current?.remove(); - handlerCropEndRef.current?.remove(); - handleShapeSelectRef.current?.remove(); - cropInsRef?.current?.destroy?.(); - cropInsRef.current = null; - }; - }, [isImgReady, showCrop, cropType]); - - const initData = (_objects: IOdRectOrigin[]) => { - const imgIns = imgInsRef.current; - //清理crop - setCropRect(null); - if (!isImgReady) return; - if (!showCrop) { - imgIns?.addShape?.({ - x: get(odRect, 'x', 0), - y: get(odRect, 'y', 0), - w: get(odRect, 'w', 0), - h: get(odRect, 'h', 0), - selectAble: false, - }); - return; - } - if (cropType === CROP_TYPE['AUTO']) { - const handleGetOD = (odList: any) => { - const imgSize = imgIns.getImgSize(); - const shapeList = odList.map((rect: { [x: string]: any; algorithmVersion: any; }) => ({ - ...rect, - selectAble: true, - id: rect['id'], - algorithmVersion: rect.algorithmVersion, - })); - imgIns.replaceShape(shapeList); - //顺便吧扩展框拿到 - const extendRect = shapeList.map((rect: { algorithmVersion: string; }) => { - const extendRect = getExtendRect(rect, imgSize.w, imgSize.h, rect.algorithmVersion); - return { ...rect, ...extendRect }; - }); - setExtendOdList(extendRect); - imgIns.replaceShape(shapeList); - handleShapeSelectRef.current = addEventListenerWrapper(imgContainerRef.current, 'shape-select', (e) => { - const id = e.detail; - setSelectRectId(id); - const selectShape = shapeList.find((v) => v['id'] === id); - if (selectShape) { - setSelectAlgorithmVersion(selectShape['algorithmVersion']); - //换算成屏幕坐标 - const axisRect = imgIns.imgRectAxisToCanvasAxisRect(selectShape); - const rect = { - x: axisRect.x2 > axisRect.x ? axisRect.x : axisRect.x2, - y: axisRect.y2 > axisRect.y ? axisRect.y : axisRect.y2, - w: Math.abs(axisRect.x2 - axisRect.x), - h: Math.abs(axisRect.y2 - axisRect.y), - }; - setCropRect(rect); - } else { - // @ts-ignore - setCropRect(null); - } - }); - }; - const rect = getOdRect({ objects }) - setOdList(rect); - handleGetOD(rect); - } - - if (cropType === CROP_TYPE['CUSTOM']) { - // 手动框选状态预先清除imgIns - imgIns?.clearShape?.(); - handlerCropStartRef.current = addEventListenerWrapper(imgContainerRef.current, EVENT_CROP_START, (event) => { - setSelectAlgorithmVersion(null); - setCropRect(null); - }); - handlerCropEndRef.current = addEventListenerWrapper(imgContainerRef.current, EVENT_CROP_END, (event) => { - const data = event.detail; - setSelectAlgorithmVersion(null); - setCropRect({ - x: data.left, - y: data.top, - w: data.width, - h: data.height, - }); - alignRef?.current?.forceAlign?.(); - }); - cropInsRef.current = new Cropper(imgContainerRef.current, { - showMask: true, - viewer: imgIns, - }); - } - } - - // 获取框选的截图框信息 - const latestCropType = useLatest(cropType); - const latestImgKey = useLatest(imageKey); - const latestCropRect = useLatest(cropRect); - const getCropInfo = async () => { - const cropType = latestCropType.current; - const cropRect = latestCropRect.current; - const imgIns = imgInsRef.current; - const transform = imgIns.targetTransform; - let newImgKey = latestImgKey.current; - let rectList = []; - let extendRectList = []; - let selectIndex = 0; - switch (cropType) { - case CROP_TYPE['AUTO']: - const shapes = imgIns.getSelectShape(); - const shapeIds = shapes.map((v) => v['id']); - rectList = odList - .filter((v) => shapeIds.includes(v['id'])) - .map((item: any) => { - if ( - item.algorithmVersion === 'OBJECT_TYPE_FACE' || - item.objectType === 'OBJECT_TYPE_FACE' - ) { - if (!isNull(item.extendBox)) { - return { - ...item, - w: get(item, 'extendBox.w'), - h: get(item, 'extendBox.h'), - x: get(item, 'extendBox.x'), - y: get(item, 'extendBox.y'), - }; - } - } else { - return item; - } - }); - extendRectList = extendOdList - .filter((v) => shapeIds.includes(v['id'])) - .map((v) => pick(v, ['x', 'y', 'w', 'h', 'algorithmVersion', 'id'])); - selectIndex = rectList.findIndex((v) => v['id'] === selectRectId); - break; - default: - //获取旋转过的坐标 - const newRect = getTransformRect(imgIns.image, transform, cropRect); - //判断是不是旋转过 - if (get(transform, 'rotate', 0) % 360 != 0) { - const data = getRotateImg(imgIns.image, get(transform, 'rotate', 0)); - //在画布上画旋转后的图片 - newImgKey = await upload(data); - } - rectList.push(newRect); - extendRectList.push(newRect); - break; - } - //扩展框获取imgkey - await Promise.all( - extendRectList.map(async (rect, index) => { - const file = await getFileByRect(imgIns.image, rect); - const imgKey = await upload(file); - extendRectList[index] = { ...rect, imgKey }; - }) - ); - //人脸图获取矫正图 - await Promise.all( - rectList.map(async (rect, index) => { - const faceCorrectImage = rect['faceCorrectImage']; - let faceCorrectImageKey; - if (faceCorrectImage) { - const base64 = `data:image/jpg;base64,${faceCorrectImage}`; - const blobData = dataURLToBlob(base64); - const file = new window.File([blobData], `${new Date().getTime()}`); - faceCorrectImageKey = await upload(file); - } - const newRect = { - ...rect, - ...(faceCorrectImageKey ? { faceCorrectImageKey } : {}), - }; - delete newRect['faceCorrectImage']; - rectList[index] = newRect; - }) - ); - return { rectList, extendRectList, selectIndex, imgKey: newImgKey }; - }; - - // 操作界面判断 - const handleCropBtnClick = (v: string) => { - switch (v) { - case 'close': - setShowCrop(false); - break; - case 'autoCrop': - setCropType(CROP_TYPE['AUTO']); - break; - case 'customCrop': - setCropType(CROP_TYPE['CUSTOM']); - break; - } - }; - - // ============================= attact img ========================= - const showAttachImg = attachImg.length !== 0; - const [selectAttachImgIndex, setSelectAttachImgIndex] = useState(0); - const [isZoomin, setIsZoomin] = useState(false); - - // ============================== Ref =============================== - useImperativeHandle(ref, () => ({ - imgInsRef, - setShowCrop, - initData, - })); - - return ( -
    - {/*场景图大图 */} -
    - {/* 图片操作 */} - {!hideLeftTopBtn && ( - - )} - {showCrop && ( - - )} - {showCrop && cropRect && screenshotButtonRender && ( - <> -
    - - {screenshotButtonRender({ - model: 'IMAGE', - getCropInfo, - setShowCrop, - cropType, - selectAlgorithmVersion, - })} - - - )} - {/* 场景图小图 */} - {showAttachImg && !showCrop && ( -
    -
    - {showAttachImgLabel - ? attachImg.map(({ label, url }, index) => ( -
    { - setSelectAttachImgIndex(index); - }} - > - {label} -
    - )) - : null} -
    -
    - -
    - -
    - )} -
    {`人脸质量分:${(score as number).toFixed(2)}`}
    -
    - ); -}); - -ImgView.displayName = 'ImgView'; - -export default ImgView; +export default BigImagePreview diff --git a/packages/meta/src/ImagePreview/index.tsx b/packages/meta/src/CompareImage/CompareImage.tsx similarity index 80% rename from packages/meta/src/ImagePreview/index.tsx rename to packages/meta/src/CompareImage/CompareImage.tsx index 03e8d5c..8ad3926 100644 --- a/packages/meta/src/ImagePreview/index.tsx +++ b/packages/meta/src/CompareImage/CompareImage.tsx @@ -1,4 +1,4 @@ -import React, { useRef, useState, FC, useEffect, useCallback } from 'react' +import React, { useRef, useState, FC, useEffect, forwardRef, useImperativeHandle } from 'react' import { generateImg, get, addEventListenerWrapper } from '@zhst/func'; import { useUpdateEffect } from '@zhst/hooks'; import { Button } from 'antd'; @@ -10,39 +10,36 @@ import './index.less' const componentName = `zhst-image__compater-view`; -export interface CompaterImageProps { +export interface CompareImageProps { /** * @description 属性描述 * @default "默认值" */ - url: string; label: string; openRoll?: boolean; //开启滚动模式 - urls?: Array; - specialTitle: String; - noTargetImageTip?: string; - score?: number; + dataSource?: Array<{ + url: string; + score: number; + }>; + showScore?: boolean; // 是否展示相似度 + current: number; // 当前图片下标 } + +export interface CompareImageRefProps { + +} + // 对比图组件 -const CompaterImage: FC = (props) => { - const { url, label, openRoll = false, urls = [], score } = props; +const CompareImage = forwardRef((props, ref) => { + const { label, openRoll = false, dataSource = [], showScore = true, current = 0 } = props; const imgContainerRef = useRef(null); const imgInsRef = useRef(null); const [scale, setScale] = useState(0); //图片翻页机制 - const [showUrl, setShowUrl] = useState(generateImg(url)); //记录显示的图片 - - useUpdateEffect(() => { - setShowUrl(generateImg(url)); - if (imgInsRef.current) { - imgInsRef.current?.refleshImage({ - image: generateImg(url), - }); - } - }, [url]); + const [currentIndex, setCurrentIndex] = useState(current) + // 初始化页面 useEffect(() => { - setShowUrl(url); const handleTransformChange = addEventListenerWrapper( imgContainerRef.current, 'viewer-transform-change', @@ -52,9 +49,11 @@ const CompaterImage: FC = (props) => { } ); - imgInsRef.current = new Viewer(imgContainerRef.current, { - image: generateImg(url), - }); + if (generateImg(dataSource[currentIndex].url)) { + imgInsRef.current = new Viewer(imgContainerRef.current, { + image: generateImg(dataSource[currentIndex].url), + }); + } return () => { handleTransformChange?.remove(); @@ -63,34 +62,36 @@ const CompaterImage: FC = (props) => { }; }, []); - //向前翻页 - const handlePre = useCallback(() => { - const index = urls.findIndex((v) => v === showUrl); - if (index > 0) { - const newUrl = urls[index - 1]; - setShowUrl(newUrl); + // 监听下标变化 + useUpdateEffect(() => { + if (imgInsRef.current) { imgInsRef.current?.refleshImage({ - image: newUrl, + image: generateImg(dataSource[currentIndex].url), }); } - }, [showUrl, urls]); - //向后翻页 - const handleNext = useCallback(() => { - const index = urls.findIndex((v) => v === showUrl); - if (index >= 0 && !!urls[index + 1]) { - const newUrl = urls[index + 1]; - setShowUrl(newUrl); - imgInsRef.current?.refleshImage({ - image: newUrl, - }); - } - }, [showUrl, urls]); + }, [currentIndex]); + + // 翻页实践 + const handleIndexChange = (changeVal: number) => { + const _index = currentIndex + changeVal + + if (!dataSource?.[_index]?.url) return + imgInsRef.current?.refleshImage({ + image: generateImg(dataSource[_index].url), + }); + setCurrentIndex(_index) + } + + useImperativeHandle(ref, () => ({ + imgInsRef, + handleIndexChange + })); return (
    {label}
    - {!url && ( + {!dataSource.length && (
    = (props) => { 暂无匹配数据
    )} - {score && } - {!!url && openRoll && ( + {/* 翻页组件 */} + {!!dataSource.length && openRoll && (
    {/*
    */}
    )} + {showScore && }
    ); -}; +}) -export default CompaterImage +export default CompareImage diff --git a/packages/meta/src/CompareImage/components/CornerScore/index.less b/packages/meta/src/CompareImage/components/CornerScore/index.less new file mode 100644 index 0000000..cb8bf35 --- /dev/null +++ b/packages/meta/src/CompareImage/components/CornerScore/index.less @@ -0,0 +1,21 @@ +.zhst-image__CornerScore { + position: absolute; + right: 0; + bottom: 0; + width: 56px; + height: 22px; + line-height: 22px; + text-align: right; + padding-right: 1px; + background-size: 100%; + background-image: url('data: image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHAAAAAsCAYAAAC9rDzHAAAByUlEQVR4Xu2cO08DMRCEJy0tlNBCSwmU0EIJLbS0UEILLTX/Fo3kk1AUHrrsjB3dWIoUnZTdvfnOZ6+1mxXGGHsADgEcA9hvnyMAvJ7xiwKrjuoQ0HmDxu8ZMxToAZDQrgAE2gxg6z9xAjwFcAvgoCDumGgKuADeA7iI6vUKqAFyE/KU12U9uMmiGuBr4Ong0bIS4A2Aa234sa4CyFzuPfLqFVABfGg5nv4OFu5BAZAbl4+F62q7fQVAJul3tjtYuCMFwEcATNozDAooAL7ltMVATngS8+kLP54UMzAAjc9VABrFVrgKQIWqRpsBaBRb4SoAFaoabQagUWyFqwBUqGq0GYBGsRWuAlChqtFmABrFVrgKQIWqRpsBaBRb4SoAFaoabVYDZLU1K9EyTApUA2RzyrMp9rgRlBWylIIlFRkmBapnIIuZ0hJmgkc3lQBTzGQEN7mqApjNSwd4VTOQr8yXFDL1IbjtDOTMY/dR1r0+/LZaA1n7yb6/wOsEb+4rlMDYdZR0oSO4uZuYtEkPAO17CP9dA3nCwll3Mlj8iw/nL4ABN/gj8hPAgBsc3KY1kJuTs7Y5yV+B7BBA5nKXrSUsKcGOgJvC/ALSJBp5mBHCFAAAAABJRU5ErkJggg=='); + z-index: 99; + + &>span { + padding-right: 6px; + line-height: 22px; + font-size: 12px; + vertical-align: middle; + color: rgba(255, 255, 255, 100%); + } +} diff --git a/packages/meta/src/ImagePreview/components/CornerScore/index.tsx b/packages/meta/src/CompareImage/components/CornerScore/index.tsx similarity index 100% rename from packages/meta/src/ImagePreview/components/CornerScore/index.tsx rename to packages/meta/src/CompareImage/components/CornerScore/index.tsx diff --git a/packages/meta/src/CompareImage/images/emptyImage.png b/packages/meta/src/CompareImage/images/emptyImage.png new file mode 100644 index 0000000000000000000000000000000000000000..97629573a5196529f63a8365baeeadab76209c1a GIT binary patch literal 5786 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 YKZ_v3%v7MbF#rGn07*qoM6N<$g4h-+kpKVy literal 0 HcmV?d00001 diff --git a/packages/meta/src/CompareImage/images/percent_background.png b/packages/meta/src/CompareImage/images/percent_background.png new file mode 100644 index 0000000000000000000000000000000000000000..ebde317c473fda46d686dce6ffba98db676f331e GIT binary patch literal 514 zcmeAS@N?(olHy`uVBq!ia0vp^1wgFB!3HGvuCY1Jz`%IY)5S5QBJS-RYky`#ffjXL z-6Hmn8Q4;CoAn~}k_ zgW(?Yj*eGfxmGY134fY$J=J!{$wg8RvLC#BaB-8+1Kx)0+#eg)F`bBcXZz`uXaHkP zhUL6}d}8k$87D|j?{9sbwY!$pLG5MvHtUET%B%<68GLRT^KfY}?0dT9sDodH(C3%j z_VYxH4H$aQhcZYV4co!x(7MWPHe-fJ^g}HM(N$8pYzqQ&T30iKtjO9T+2FQObRAQ` z!c`a3uqzH@PT6XzebLB=D}*_v_|#_2Z#x91h;EwFq$(<@#=0t9p?l^fp|mD<^QjEM zXHrQ%!{C#rY{sXUB^51Ds zIdG$NO36ay9Xn^w*y730@V1)ce=Kw5p+k}7MiGCy`Jd}IFq;2R{v>>$L0aa{GSdmO yCvVdiv:first-child { + margin-right: 25px; + } + + &>div:last-child { + margin-left: 25px; + } + + &__container { + position: relative; + width: 345px; + height: 460px; + box-sizing: content-box; + border: 1px solid #f0f0f0; + } + + &__view { + width: 345px; + height: 460px; + } + + &__label { + position: absolute; + z-index: 99; + top: 0; + left: 0; + display: flex; + height: 34px; + align-items: center; + justify-content: center; + + // width: 48px; + padding: 0 6px; + background: #09f; + color: #fff; + } + + &__tool { + display: flex; + width: 345px; + height: 40px; + align-items: center; + justify-content: center; + background: #f9f9f9; + + i, + span { + color: #333 !important; + } + + i { + margin-right: 4px; + } + + &>*:not(:last-child) { + margin-right: 20px; + } + + &__scale { + display: inline-block; + width: 38px; + height: 16px; + + // margin-left: 15px; + box-sizing: content-box; + border: 1px solid rgb(77 77 77 / 100%); + background: rgb(255 255 255 / 100%); + border-radius: 2px; + color: #4d4d4d; + cursor: default; + font-size: 12px; + line-height: 16px; + text-align: center; + } + + &__line { + width: 1px; + height: 14px; + background: #e6e6e6; + } + } + + &__empty { + position: absolute; + z-index: 9; + display: flex; + width: 100%; + height: 100%; + flex-direction: column; + align-items: center; + justify-content: center; + background: #f9f9f9; + transform: translateY(-100%); + + &>img { + width: 140px; + height: 80px; + } + + &--text { + color: #999; + font-size: 14px; + line-height: 22px; + } + } + + &__scoll-module { + position: absolute; + top: 0%; + left: 0%; + display: flex; + width: 100%; + height: 100%; + align-items: flex-end; + justify-content: space-between; + pointer-events: none; + + &__btn { + display: flex; + width: 50px; + height: 50px; + align-items: center; + justify-content: center; + margin: 6px; + border-radius: 50%; + opacity: 0.5; + pointer-events: all; + + &>span { + display: flex; + align-items: center; + justify-content: center; + } + } + + &__btn:hover { + background-color: #09f !important; + color: #fff !important; + } + } +} diff --git a/packages/meta/src/CompareImage/index.md b/packages/meta/src/CompareImage/index.md new file mode 100644 index 0000000..0e7b9e9 --- /dev/null +++ b/packages/meta/src/CompareImage/index.md @@ -0,0 +1,50 @@ +--- +nav: + title: 元组件 + order: 1 +group: + title: 通用 + order: 3 +--- + +# CompareImage 图片预览 + +```jsx +import React, { useRef } from 'react'; +import { CompareImage } from '@zhst/meta' +import { Button, Space } from 'antd' + +const props = { + label: "目标图", + openRoll:true, + dataSource:[ + { + url: 'http://10.0.0.120:30003/file/public/public_20240110/file/60f26318-19fc-40b3-b249-91bd2a4da3f3.jpg', + score: '0.5' + }, + { + url: 'http://10.0.0.120:30003/file/public/public_20240110/file/7c9b33a8-5106-4982-9d58-a593ad8acbf6.jpg', + score: '0.8' + }, + ] +} + +export default () => { + const ref = useRef(null) + + return ( + + + + + + ) +} +``` + +| 参数名 | 参数类型 | 参数说明 | +| ------ | -------- | ---- | +|label|string|左上角标题| +|openRoll|boolean|是否支持鼠标滚动放大缩小| +|urls|string[]|链接数组| +|score|string|相似度| diff --git a/packages/meta/src/CompareImage/index.tsx b/packages/meta/src/CompareImage/index.tsx new file mode 100644 index 0000000..56bc164 --- /dev/null +++ b/packages/meta/src/CompareImage/index.tsx @@ -0,0 +1,5 @@ +import CompareImage from "./CompareImage"; + +export type { CompareImageProps } from './CompareImage' + +export default CompareImage diff --git a/packages/meta/src/ImagePreview/index.md b/packages/meta/src/ImagePreview/index.md deleted file mode 100644 index c487093..0000000 --- a/packages/meta/src/ImagePreview/index.md +++ /dev/null @@ -1,40 +0,0 @@ ---- -nav: - title: 元组件 - order: 1 -group: - title: 通用 - order: 3 ---- - -# ImagePreview 图片预览 - -```jsx -import React from 'react'; -import { ImagePreview } from '@zhst/meta' - -const props = { - label:"目标图", - url:"http://10.0.0.120:30003/file/public/public_20240110/file/60f26318-19fc-40b3-b249-91bd2a4da3f3.jpg", - openRoll:true, - score: 0.8, - urls:[ - "http://10.0.0.120:30003/file/public/public_20240110/file/60f26318-19fc-40b3-b249-91bd2a4da3f3.jpg", - "http://10.0.0.120:30003/file/public/public_20240110/file/7c9b33a8-5106-4982-9d58-a593ad8acbf6.jpg" - ] -} - -export default () => { - return ( - - ) -} -``` - -| 参数名 | 参数类型 | 参数说明 | -| ------ | -------- | ---- | -|label|string|左上角标题| -|url|string|链接| -|openRoll|boolean|是否支持鼠标滚动放大缩小| -|urls|string[]|链接数组| -|score|string|相似度| diff --git a/packages/meta/src/VideoPlayer/VideoPlayer.tsx b/packages/meta/src/VideoPlayer/VideoPlayer.tsx new file mode 100644 index 0000000..6571019 --- /dev/null +++ b/packages/meta/src/VideoPlayer/VideoPlayer.tsx @@ -0,0 +1,676 @@ +import React, { Dispatch, ReactElement, SetStateAction, forwardRef, useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react'; +import { + noop, + get, + addEventListenerWrapper, + dataURLToBlob, + nextTick, + toRealNumber, + getTransforms, + formatDurationTime +} from '@zhst/func'; +import Align from 'rc-align'; +import { Rect, IScreenshotButtonProp, AlignType } from '@zhst/types' +import { useLatest, useUpdateEffect, useFullscreen, useUnmount } from '@zhst/hooks'; +import classNames from 'classnames'; +import download from 'downloadjs'; +import { Button, message } from 'antd'; +import Icon from '../iconfont'; +import { + Cropper, + EVENT_CROP_START, + EVENT_CROP_END, +} from '../ImageEditor'; +import FlvPlayer, { FLV_EVENT } from './components/FlvPlayer'; +import Range from './components/Progress'; +import Loading from './components/Loading'; +import getScreenshotButtonRender from '../BigImagePreview/components/ScreenhotButtons'; +import { CROP_TYPE } from '../utils/constants'; +import { getShowStatus } from './videoPlayerHelper' +import './index.less' + +const componentName = `zhst-image__video-view`; + +export interface VideoViewProps { + /* 播放地址 */ + url: string; + /* 播放总时间 */ + maxDuration?: number; + /* 截图渲染 */ + screenshotButtonAlign?: AlignType; + screenshotButtonRender?: (screenshotButtonProp: IScreenshotButtonProp) => ReactElement; + /* 默认截图框 */ + defautlNormalizationRect?: Rect; + /* 截图回调 */ + onCropChange?: (showCrop: boolean, normalizationRect: null | Rect) => void; +} + +export interface VideoViewRef { + /* 当前图片模式 */ + cropAble: boolean; + setShowCrop: Dispatch>; + downloadVideoframe: () => void; +} + +const VideoPlayer = forwardRef((props, ref) => { + const { + url, + maxDuration, + screenshotButtonAlign = { + points: ['bl', 'br'], + offset: [6, 0], + overflow: { + adjustX: true, + adjustY: true, + }, + }, + screenshotButtonRender = getScreenshotButtonRender({ + onBigImageActionClick: () => {}, + disableBtn: [], + }), + onCropChange, + defautlNormalizationRect: defaultNormalizationRect, + } = props; + const videoType = useMemo(() => (url && url.startsWith('http') ? 'mp4' : 'flv'), [url]); + // ========================== 播放 ========================= + //实例参数 + const containerRef: any = useRef(null); //容器ref + const videoRef: any = useRef(null); //video 标签dom + const videoInsRef: any = useRef(null); //flv 实例 + const [playSeq, setPlaySeq] = useState(0); // 通过重置playid使FLV组件重新渲染 + const videoRemoveListener = useRef(noop); //移除dom监听的中间函数 + const loadingTimeRef = useRef(0); //最后一次加载时间 + const delayLoadingTimer: any = useRef(null); //算loading的定时器 + //状态参数 + const [isReady, setIsReady] = useState(false); // + const [isPlay, setIsPlay] = useState(false); //当前是否播放 + + const [isEnd, setIsEnd] = useState(false); //是否播放结束 + const [isError, setIsError] = useState(false); //播放出错 + const [isVideoLoadFinished, setIsVideoLoadFinish] = useState(false); //是否缓存加载完成 + const [playTime, setPlayTime] = useState(0); //当前播放时间 + const [isLoadingVideo, setIsLoadingVideo] = useState(true); //是否加载中 + const [isDelayLoading, setIsDelayLoading] = useState(false); //显示的转圈loading 延迟0.2s显示 + //设置延迟转圈圈 + const latestIsLoadingVideo = useLatest(isLoadingVideo); + const setIsLoadingVideoWrapper = (isLoading: boolean) => { + setIsLoadingVideo((preLoading) => { + if (!preLoading && isLoading) { + loadingTimeRef.current = new Date().getTime(); + } + if (!isLoading) { + loadingTimeRef.current = null; + } + //延迟0。2s相关 + if (!isLoading) { + setIsDelayLoading(false); + } + if (!delayLoadingTimer.current && preLoading) { + delayLoadingTimer.current = setTimeout(() => { + if (latestIsLoadingVideo.current) { + //0.2s后才显示 + setIsDelayLoading(true); + } + delayLoadingTimer.current = null; + }, 200); + } + return isLoading; + }); + }; + // 初始化loading 30s 直接显示错误 + // TODO :逻辑忘记了 不应该是每次init player吗? + useEffect(() => { + let timer = setInterval(() => { + if (loadingTimeRef.current) { + if (new Date().getTime() - loadingTimeRef.current > 1000 * 30) { + checkIsErr() + } + } + }, 1000); + return () => { + clearInterval(timer); + }; + }, []); + + //结束的时候暂停 保证不播了 + useUpdateEffect(() => { + if (isEnd) { + videoInsRef?.current?.pause?.(); + } + }, [isEnd]); + + // 捕捉视频播放报错 + const checkIsErr = () => { + setIsError(true) + try { + videoInsRef?.current?.destroy?.(); + } catch (error) { + console.error(error); + } + } + + // 初始化 + const latestMaxDuration = useLatest(maxDuration); + const initPlayer = useCallback((ins: any, dom: any) => { + videoRef.current = dom; + videoInsRef.current = ins; + const maxDuration = latestMaxDuration.current || 0; + //监听播放事件 + let video = dom; + let errorLister = (e: any) => { + checkIsErr(); + console.error('视频出错了', e, video.currentTime); + }; + let waitingListener = (e: any) => { + setIsLoadingVideoWrapper(true); + console.debug('视频加载等待', e, video.currentTime); + }; + let playingListener = (e: any) => { + setIsLoadingVideoWrapper(false); + setIsError(false) + console.debug('视频从等待中播放', e, video.currentTime); + }; + let playLister = (e: any) => { + setIsPlay(true); + setIsError(false) + console.debug('提示该视频正在播放中', e, video.currentTime); + }; + let pauseListener = (e: any) => { + setIsPlay(false); + console.debug('暂停播放', e, video.currentTime); + }; + let endedListner = (e: any) => { + setIsEnd(true); + setIsVideoLoadFinish(true); + console.debug('视频播放完了', e, video.currentTime); + }; + let timeupdateListner = (e: any) => { + console.debug( + '视频播放时间更新', + e, + video.currentTime, + videoRef.current?.duration, + maxDuration + ); + let nowTime = video.currentTime; + if (nowTime >= maxDuration) { + setIsEnd(true); + setIsVideoLoadFinish(true); + } + setPlayTime(nowTime); + }; + // see https://github.com/bilibili/flv.js/issues/337 + let windowErrorHandle = (errorEvent: any) => { + try { + if ( + errorEvent['message'] == + "Uncaught TypeError: Cannot read property 'flushStashedSamples' of null" + ) { + checkIsErr(); + console.error('视频出错了 window监听', errorEvent); + } + } catch (error) { + console.error(error); + } + }; + video.addEventListener('error', errorLister); + video.addEventListener('waiting', waitingListener); + video.addEventListener('playing', playingListener); + video.addEventListener('play', playLister); + video.addEventListener('pause', pauseListener); + video.addEventListener('ended', endedListner); + video.addEventListener('timeupdate', timeupdateListner); + window.addEventListener('error', windowErrorHandle); + + videoRemoveListener.current = () => { + video.removeEventListener('error', errorLister); + video.removeEventListener('waiting', waitingListener); + video.removeEventListener('playing', playingListener); + video.removeEventListener('play', playLister); + video.removeEventListener('pause', pauseListener); + video.removeEventListener('ended', endedListner); + video.removeEventListener('timeupdate', timeupdateListner); + window.removeEventListener('error', windowErrorHandle); + }; + + videoInsRef?.current.on(FLV_EVENT.ERROR, (type: any, errDetail: any, info: any) => { + checkIsErr(); + console.error('videoInsRef 错误', type, errDetail, info, video.currentTime); + }); + let playPromise = videoInsRef?.current.play(); + //先ready 遮挡会导致播放失败 + setIsReady(true); + playPromise + .then(() => { + setIsReady(true); + }) + .catch((...arg: any) => { + try { + } catch (error) {} + // setIsError(true); + console.error('playPromise视频出错了', arg); + }); + }, []); + + useUnmount(() => { + try { + videoRemoveListener.current(); + } catch (e) { + console.error(e); + } + }); + + const reload = async () => { + if (videoInsRef.current) { + let oldTime = videoInsRef.current.currentTime; + videoInsRef.current.currentTime = 0; + + //如果修改时间不成功,则走重新加载的逻辑 + if (oldTime === videoInsRef.current.currentTime) { + //重置状态 + setIsReady(false); + setIsPlay(false); + setIsLoadingVideoWrapper(false); + setIsReady(false); + setIsEnd(false); + setIsVideoLoadFinish(false); + setPlayTime(0); + + //清楚dom事件监听 + try { + videoRemoveListener.current(); + } catch (error) { + console.error(error); + } + setPlaySeq((pre) => pre + 1); + return; + } + videoInsRef.current.play(); + } + + setPlayTime(0); + setIsEnd(false); + }; + const seek = (v: number) => { + if (videoInsRef.current && isVideoLoadFinished) { + setPlayTime(parseFloat(v as any)); + videoInsRef.current.currentTime = parseFloat(v as any); + } else { + message.warning('待视频加载完,才可操作进度条') + } + }; + // ========================== 视频opt bar ========================= + const [isFullscreen, { toggleFullscreen }] = useFullscreen(containerRef, { + pageFullscreen: true, + }); + const showMaxDuration = !!maxDuration + ? maxDuration + : toRealNumber(get(videoRef, 'current.duration', 0)); + const showSlider = videoInsRef.current && isVideoLoadFinished; + const showStatus: any = getShowStatus(isDelayLoading, isEnd, isError); + + // ========================== 截图 ========================= + const corpContainerRef: any = useRef(); + const cropInsRef: any = useRef(null); + const [showCrop, setShowCrop] = useState(false); + + //回显默认框选 + const isFirstFlagRef = useRef(true); + useEffect(() => { + const isFirst = isFirstFlagRef.current; + if (!isLoadingVideo && isReady && isFirst && defaultNormalizationRect && !showStatus) { + nextTick(() => { + setShowCrop(true); + }); + } + }, [isLoadingVideo, showStatus]); + + //定位按钮相关参数 + const alginContainerRef: any = useRef(null); + const alignRef: any = useRef(null); + const [cropRect, setCropRect] = useState(null); + + useEffect(() => { + showCrop ? videoInsRef?.current?.pause() : videoInsRef?.current?.play(); + }, [showCrop]); + + useEffect(() => { + let handlerCropStart: { remove: () => void; }; + let handlerCropEnd: { remove: () => void; }; + setCropRect(null); + if (!isReady) return; + if (showCrop) { + handlerCropStart = addEventListenerWrapper(corpContainerRef.current, EVENT_CROP_START, () => { + setCropRect(null); + }); + handlerCropEnd = addEventListenerWrapper(corpContainerRef.current, EVENT_CROP_END, (event: { detail: any; }) => { + const data = event.detail; + setCropRect({ + x: data.left, + y: data.top, + w: data.width, + h: data.height, + }); + alignRef?.current?.forceAlign?.(); + }); + let video: any = videoRef.current; + //计算 limitcroppbox + let scale = Math.min( + video.offsetWidth / video.videoWidth, + video.offsetHeight / video.videoHeight + ); + let finalVideoWidth = video.videoWidth * scale; + let finalVideoHeight = video.videoHeight * scale; + let cropBoxLimited = { + width: finalVideoWidth, + height: finalVideoHeight, + top: (video.offsetHeight - finalVideoHeight) / 2, + left: (video.offsetWidth - finalVideoWidth) / 2, + }; + //获取视频图片 + let canvas = document.createElement('canvas'); + canvas.width = video.offsetWidth; + canvas.height = video.offsetHeight; + canvas.style.display = 'none'; + document.body.appendChild(canvas); + let ctx = canvas.getContext('2d'); + ctx?.drawImage( + video, + (video.offsetWidth - finalVideoWidth) / 2, + (video.offsetHeight - finalVideoHeight) / 2, + finalVideoWidth, + finalVideoHeight + ); + let imageData = canvas.toDataURL('image/png'); + canvas.parentNode?.removeChild(canvas); + //回显编辑框 + const isFirst = isFirstFlagRef.current; + let initialCropBoxData = null; + if (isFirst && defaultNormalizationRect) { + initialCropBoxData = { + left: defaultNormalizationRect.x * finalVideoWidth + cropBoxLimited.left, + top: defaultNormalizationRect.y * finalVideoHeight + cropBoxLimited.top, + width: defaultNormalizationRect.w * finalVideoWidth, + height: defaultNormalizationRect.h * finalVideoHeight, + }; + } + isFirstFlagRef.current = false; + + cropInsRef.current = new Cropper(corpContainerRef.current, { + showMask: true, + cropBoxLimited, + img: imageData, + initialCropBoxData, + }); + } + return () => { + handlerCropStart?.remove(); + handlerCropEnd?.remove(); + cropInsRef?.current?.destroy?.(); + cropInsRef.current = null; + }; + }, [showCrop, isReady]); + + const latestCropRect = useLatest(cropRect); + + const getCropInfo = async () => { + const cropRect = latestCropRect.current as any; + let video: any = videoRef.current; + if (!video) return + let rectList = []; + let extendRectList = []; + let selectIndex = 0; + //获取视频图片的url + let scale = Math.min( + video.offsetWidth / video.videoWidth, + video.offsetHeight / video.videoHeight + ); + let finalVideoWidth = video.videoWidth * scale; + let finalVideoHeight = video.videoHeight * scale; + let canvas = document.createElement('canvas'); + canvas.width = finalVideoWidth; + canvas.height = finalVideoHeight; + canvas.style.display = 'none'; + document.body.appendChild(canvas); + let ctx = canvas.getContext('2d') as CanvasRenderingContext2D; + ctx.drawImage( + video, + 0, + 0, + finalVideoWidth, + finalVideoHeight + ); + let base64 = canvas.toDataURL('image/jpeg'); + const blobData = dataURLToBlob(base64); + canvas.parentNode?.removeChild(canvas); + const file = new window.File([blobData], `${new Date().getTime()}`); + let newRect = { + w: cropRect.w / finalVideoWidth, + h: cropRect.h / finalVideoHeight, + x: (cropRect.x - (video.offsetWidth - finalVideoWidth) / 2) / finalVideoWidth, + y: (cropRect.y - (video.offsetHeight - finalVideoHeight) / 2) / finalVideoHeight + }; + rectList.push(newRect); + extendRectList.push(newRect); + //扩展框获取imgkey + extendRectList.forEach(async (rect, index) => { + extendRectList[index] = { + ...rect, + }; + }) + return { + rectList, + extendRectList, + selectIndex, + file + }; + }; + + //回调 + useEffect(() => { + //计算归一化crop rect + let normalizationRect = null; + if (showCrop && cropRect) { + let video: any = videoRef.current; + let scale = Math.min( + video.offsetWidth / video.videoWidth, + video.offsetHeight / video.videoHeight + ); + let finalVideoWidth = video.videoWidth * scale; + let finalVideoHeight = video.videoHeight * scale; + let cropBoxLimited = { + width: finalVideoWidth, + height: finalVideoHeight, + top: (video.offsetHeight - finalVideoHeight) / 2, + left: (video.offsetWidth - finalVideoWidth) / 2, + }; + normalizationRect = { + x: (cropRect.x - cropBoxLimited.left) / cropBoxLimited.width, + y: (cropRect.y - cropBoxLimited.top) / cropBoxLimited.height, + w: cropRect.w / cropBoxLimited.width, + h: cropRect.h / cropBoxLimited.height, + }; + } + + onCropChange?.(showCrop, normalizationRect); + }, [showCrop, cropRect]); + + // ========================== 截帧 ========================= + const downloadVideoframe = useCallback(async () => { + try { + videoInsRef?.current?.pause?.(); + let video: any = videoRef.current; + var canvas = document.createElement('canvas'); + const ctx = canvas.getContext('2d') + let base64; + //当视频处于还未加载出来时,截屏为黑色图片 + if (video.readyState === 0) { + ctx?.clearRect(0, 0, canvas.width, canvas.height); + canvas.width = video.offsetWidth; + canvas.height = video.offsetHeight; + // @ts-ignore + ctx.fillStyle = 'black'; + ctx?.fillRect(0, 0, canvas.width, canvas.height); + base64 = canvas.toDataURL(); + } else { + canvas.width = video.videoWidth; + canvas.height = video.videoHeight; + ctx?.drawImage(video, 0, 0, canvas.width, canvas.height); + base64 = canvas.toDataURL('image/png'); + } + download(base64); + } catch (error) { + console.error(error); + } + }, []); + + // ============================== 暴露出去的方法 =============================== + const latestIsReady = useLatest(isReady); + const cropAble = !showStatus && isReady; + useImperativeHandle(ref, () => ({ + cropAble, + setShowCrop: (dispatch) => { + const isReady = latestIsReady.current; + if (!isReady) return; + setShowCrop(dispatch); + }, + downloadVideoframe, + })); + + return ( +
    + {url && ( + <> + + {/* //截图 */} +
    + {/*
    */} +
    + {showCrop && cropRect && screenshotButtonRender && ( + <> +
    + + {screenshotButtonRender({ + model: 'IMAGE', + getCropInfo, + setShowCrop, + cropType: CROP_TYPE['CUSTOM'], + })} + + + )} + {/* 视频进度条 */} + {!showCrop && ( +
    +
    + +
    +
    { + e.stopPropagation(); + }} + > + +
    + {/* TODO: 删除扩展方法format */} + {formatDurationTime(playTime)}/{formatDurationTime(showMaxDuration)} +
    +
    +
    + +
    +
    + )} + {/* mask */} + {!!showStatus && ( + reload()} /> + )} + + )} +
    + ); +}); + +export default VideoPlayer; diff --git a/packages/meta/src/VideoPlayer/components/FlvPlayer/index.tsx b/packages/meta/src/VideoPlayer/components/FlvPlayer/index.tsx index edc23e5..b34b981 100644 --- a/packages/meta/src/VideoPlayer/components/FlvPlayer/index.tsx +++ b/packages/meta/src/VideoPlayer/components/FlvPlayer/index.tsx @@ -33,7 +33,7 @@ export default class VideoPlayer extends Component { curPlayUrl: '', shouldReinit: false, }; - flvPlayer = null; + flvPlayer: any = null; videoElement = null; static getDerivedStateFromProps = (nextProps: { url?: any; playId?: any; }, prevState: { curPlayUrl?: any; playId?: any; }) => { @@ -59,20 +59,40 @@ export default class VideoPlayer extends Component { if ($video) { - if (flvjs.isSupported() && this.props.url && this.props.url !== '') { + if (flvjs.isSupported() && this.props.url && this.props.url) { const reload = () => { if (this.flvPlayer && this.flvPlayer.destroy) { try { - this.flvPlayer?.destroy(); + this.flvPlayer.destroy() } catch (error) { console.error(error); } } - let flvPlayer = flvjs.createPlayer({ ...others }, config); + let flvPlayer = flvjs.createPlayer({ ...others }, { + deferLoadAfterSourceOpen: false, + ...config + }); flvPlayer.attachMediaElement($video); flvPlayer.load(); this.flvPlayer = flvPlayer; + // @ts-ignore + let controller = this.flvPlayer._transmuxer._controller + let wsLoader = controller._ioctl._loader + const oldWsOnCompleteFunc = wsLoader._onComplete + wsLoader._onComplete = function() { + if(!controller._remuxer) { + controller._remuxer = { + destroy: () => { + console.log('组件销毁') + }, + flushStashedSamples: () => { + console.log("flushStashedSamples") + } + } + } + oldWsOnCompleteFunc() + } this.flvPlayer.reload = reload; onCreat && onCreat(this.flvPlayer, $video); }; diff --git a/packages/meta/src/VideoPlayer/components/Loading/index.tsx b/packages/meta/src/VideoPlayer/components/Loading/index.tsx index b6cc17e..0da447c 100644 --- a/packages/meta/src/VideoPlayer/components/Loading/index.tsx +++ b/packages/meta/src/VideoPlayer/components/Loading/index.tsx @@ -7,7 +7,7 @@ import './index.less' const componentName = `zhst-image__video-view`; export interface ILoading { - status: 'LOADING' | 'COMPLETED' | 'END' | 'ERROR' + status: 'LOADING' | 'COMPLETED' | 'END' | 'ERROR' | null reload: () => void } diff --git a/packages/meta/src/VideoPlayer/components/Progress/index.tsx b/packages/meta/src/VideoPlayer/components/Progress/index.tsx index 1d3b821..9aea069 100644 --- a/packages/meta/src/VideoPlayer/components/Progress/index.tsx +++ b/packages/meta/src/VideoPlayer/components/Progress/index.tsx @@ -1,12 +1,15 @@ import React from 'react'; import classNames from 'classnames'; import { Slider } from 'antd'; +import type { SliderSingleProps } from 'antd' import './index.less'; const componentName = `zhst-image__range`; -export interface RangeWrapperProps extends React.HTMLAttributes { +export interface RangeWrapperProps extends SliderSingleProps { showSlider: boolean; + className?: string; + min: number; } export const Range: React.FC = (props) => { diff --git a/packages/meta/src/VideoPlayer/index.md b/packages/meta/src/VideoPlayer/index.md index e1abe8d..f879582 100644 --- a/packages/meta/src/VideoPlayer/index.md +++ b/packages/meta/src/VideoPlayer/index.md @@ -9,19 +9,31 @@ group: # VideoPlayer 视频播放 +:::warning{title=注意} +播放进度条操作还未完善,在播放结束和拖拽的过程中都有一定程度卡顿,目前逻辑待优化 +::: + ```jsx -import React from 'react'; +import React, { useRef, useState } from 'react'; +import { Space, Button } from 'antd' import { VideoPlayer } from '@zhst/meta' -const props = { - "flvUrl":"ws://10.0.0.120:9033/flv/HaikangNvr/45.flv?ip=10.0.2.103&stime=1705051970&etime=1705051990", - "maxDuration":20, - "showCrop$":false -} - export default () => { + const videoRef = useRef(null) + const [url, setUrl] = useState('ws://10.0.0.120:9033/flv/Sip/34020000001310000301.flv?ip=10.0.0.120&stime=1704815972&etime=1704815992') + return ( - + + + + + + ) } ``` + +| 参数名 | 参数类型 | 参数说明 | +| ------ | -------- | ---- | +| url | string(必填) | 当前视频链接 | +| maxDuration | number(必填) | 视频截取长度 | diff --git a/packages/meta/src/VideoPlayer/index.tsx b/packages/meta/src/VideoPlayer/index.tsx index 46e5703..57e073e 100644 --- a/packages/meta/src/VideoPlayer/index.tsx +++ b/packages/meta/src/VideoPlayer/index.tsx @@ -1,696 +1,5 @@ -import React, { Dispatch, ReactElement, SetStateAction, forwardRef, useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react'; -import { - noop, - get, - addEventListenerWrapper, - dataURLToBlob, - nextTick, - toRealNumber, - getTransforms, - formatDurationTime -} from '@zhst/func'; -import Align from 'rc-align'; -import { Rect, IScreenshotButtonProp, AlignType } from '@zhst/types' -import { useLatest, useUpdateEffect, useFullscreen, useUnmount } from '@zhst/hooks'; -import classNames from 'classnames'; -import download from 'downloadjs'; -import { Button, message } from 'antd'; -import Icon from '../iconfont'; -import { - Cropper, - EVENT_CROP_START, - EVENT_CROP_END, -} from '../ImageEditor'; -import FlvPlayer, { FLV_EVENT } from './components/FlvPlayer'; -import Range from './components/Progress'; -import Loading, { ILoading } from './components/Loading'; -import getScreenshotButtonRender from '../BigImagePreview/components/ScreenhotButtons'; -import './index.less' +import VideoPlayer from './VideoPlayer' -const componentName = `zhst-image__video-view`; +export type { VideoViewProps, VideoViewRef } from './VideoPlayer' -export const CROP_TYPE = { - CUSTOM: 'CSUTOM', - AUTO: 'AUTO', -}; - -export function getShowStatus(isLoadingVideo: boolean, isEnd: boolean, isError: boolean): ILoading['status'] { - let status = null; - if (isLoadingVideo) { - status = 'LOADING'; - } - if (isError) { - status = 'ERROR'; - } - if (isEnd) { - status = 'END'; - } - return status; -} - - -export interface VideoViewProps { - /* 播放地址 */ - flvUrl: string; - /* 播放总时间 */ - maxDuration?: number; - /* 截图渲染 */ - screenshotButtonAlign?: AlignType; - screenshotButtonRender?: (screenshotButtonProp: IScreenshotButtonProp) => ReactElement; - /* 默认截图框 */ - defautlNormalizationRect?: Rect; - /* 截图回调 */ - onCropChange?: (showCrop: boolean, normalizationRect: null | Rect) => void; -} - -export interface VideoViewRef { - /* 当前图片模式 */ - cropAble: boolean; - setShowCrop: Dispatch>; - downloadVideoframe: () => void; -} - -const VideoPlayer = forwardRef((props, ref) => { - const { - flvUrl, - maxDuration, - screenshotButtonAlign = { - points: ['bl', 'br'], - offset: [6, 0], - overflow: { - adjustX: true, - adjustY: true, - }, - }, - screenshotButtonRender = getScreenshotButtonRender({ - onBigImageActionClick: () => {}, - disableBtn: [], - }), - onCropChange, - defautlNormalizationRect: defaultNormalizationRect, - } = props; - const videoType = useMemo(() => (flvUrl && flvUrl.startsWith('http') ? 'mp4' : 'flv'), [flvUrl]); - // ========================== 播放 ========================= - //实例参数 - const containerRef = useRef(null); //容器ref - const videoRef = useRef(null); //video 标签dom - const videoInsRef: any = useRef(null); //flv 实例 - const [playSeq, setPlaySeq] = useState(0); // 通过重置playid使FLV组件重新渲染 - const videoRemoveListener = useRef(noop); //移除dom监听的中间函数 - const loadingTimeRef = useRef(0); //最后一次加载时间 - const delayLoadingTimer = useRef(null); //算loading的定时器 - //状态参数 - const [isReady, setIsReady] = useState(false); // - const [isPlay, setIsPlay] = useState(false); //当前是否播放 - - const [isEnd, setIsEnd] = useState(false); //是否播放结束 - const [isError, setIsError] = useState(false); //播放出错 - const [isVideoLoadFinished, setIsVideoLoadFinish] = useState(false); //是否缓存加载完成 - const [playTime, setPlayTime] = useState(0); //当前播放时间 - const [isLoadingVideo, setIsLoadingVideo] = useState(true); //是否加载中 - const [isDelayLoading, setIsDelayLoading] = useState(false); //显示的转圈loading 延迟0.2s显示 - //设置延迟转圈圈 - const latestIsLoadingVideo = useLatest(isLoadingVideo); - const setIsLoadingVideoWrapper = (isLoading: boolean) => { - setIsLoadingVideo((preLoading) => { - if (!preLoading && isLoading) { - loadingTimeRef.current = new Date().getTime(); - } - if (!isLoading) { - loadingTimeRef.current = null; - } - //延迟0。2s相关 - if (!isLoading) { - setIsDelayLoading(false); - } - if (!delayLoadingTimer.current && preLoading) { - delayLoadingTimer.current = setTimeout(() => { - if (latestIsLoadingVideo.current) { - //0.2s后才显示 - setIsDelayLoading(true); - } - delayLoadingTimer.current = null; - }, 200); - } - return isLoading; - }); - }; - // 初始化loading 30s 直接显示错误 - // TODO :逻辑忘记了 不应该是每次init player吗? - useEffect(() => { - let timer = setInterval(() => { - if (loadingTimeRef.current) { - if (new Date().getTime() - loadingTimeRef.current > 1000 * 30) { - checkIsErr() - } - } - }, 1000); - return () => { - clearInterval(timer); - }; - }, []); - - //结束的时候暂停 保证不播了 - useUpdateEffect(() => { - if (isEnd) { - videoInsRef?.current?.pause?.(); - } - }, [isEnd]); - - // 捕捉视频播放报错 - const checkIsErr = () => { - setIsError(true) - try { - videoInsRef?.current?.destroy?.(); - } catch (error) { - console.error(error); - } - } - - // 初始化 - const latestMaxDuration = useLatest(maxDuration); - const initPlayer = useCallback((ins: any, dom: any) => { - videoRef.current = dom; - videoInsRef.current = ins; - const maxDuration = latestMaxDuration.current || 0; - //监听播放事件 - let video = dom; - let errorLister = (e: any) => { - checkIsErr(); - console.error('视频出错了', e, video.currentTime); - }; - let waitingListener = (e: any) => { - setIsLoadingVideoWrapper(true); - console.debug('视频加载等待', e, video.currentTime); - }; - let playingListener = (e: any) => { - setIsLoadingVideoWrapper(false); - setIsError(false) - console.debug('视频从等待中播放', e, video.currentTime); - }; - let playLister = (e: any) => { - setIsPlay(true); - setIsError(false) - console.debug('提示该视频正在播放中', e, video.currentTime); - }; - let pauseListener = (e: any) => { - setIsPlay(false); - console.debug('暂停播放', e, video.currentTime); - }; - let endedListner = (e: any) => { - setIsEnd(true); - setIsVideoLoadFinish(true); - console.debug('视频播放完了', e, video.currentTime); - }; - let timeupdateListner = (e: any) => { - console.debug( - '视频播放时间更新', - e, - video.currentTime, - videoRef.current?.duration, - maxDuration - ); - let nowTime = video.currentTime; - if (nowTime >= maxDuration) { - setIsEnd(true); - setIsVideoLoadFinish(true); - } - setPlayTime(nowTime); - }; - // see https://github.com/bilibili/flv.js/issues/337 - let windowErrorHandle = (errorEvent: { [x: string]: string; }) => { - try { - if ( - errorEvent['message'] == - "Uncaught TypeError: Cannot read property 'flushStashedSamples' of null" - ) { - checkIsErr(); - console.error('视频出错了 window监听', errorEvent); - } - } catch (error) { - console.error(error); - } - }; - video.addEventListener('error', errorLister); - video.addEventListener('waiting', waitingListener); - video.addEventListener('playing', playingListener); - video.addEventListener('play', playLister); - video.addEventListener('pause', pauseListener); - video.addEventListener('ended', endedListner); - video.addEventListener('timeupdate', timeupdateListner); - window.addEventListener('error', windowErrorHandle); - - videoRemoveListener.current = () => { - video.removeEventListener('error', errorLister); - video.removeEventListener('waiting', waitingListener); - video.removeEventListener('playing', playingListener); - video.removeEventListener('play', playLister); - video.removeEventListener('pause', pauseListener); - video.removeEventListener('ended', endedListner); - video.removeEventListener('timeupdate', timeupdateListner); - window.removeEventListener('error', windowErrorHandle); - }; - - videoInsRef?.current.on(FLV_EVENT.ERROR, (type: any, errDetail: any, info: any) => { - checkIsErr(); - console.error('videoInsRef 错误', type, errDetail, info, video.currentTime); - }); - let playPromise = videoInsRef?.current.play(); - //先ready 遮挡会导致播放失败 - setIsReady(true); - playPromise - .then(() => { - setIsReady(true); - }) - .catch((...arg: any) => { - try { - } catch (error) {} - // setIsError(true); - console.error('playPromise视频出错了', arg); - }); - }, []); - - useUnmount(() => { - try { - videoRemoveListener.current(); - } catch (e) { - console.error(e); - } - }); - - const reload = async () => { - if (videoInsRef.current) { - let oldTime = videoInsRef.current.currentTime; - videoInsRef.current.currentTime = 0; - - //如果修改时间不成功,则走重新加载的逻辑 - if (oldTime === videoInsRef.current.currentTime) { - //重置状态 - setIsReady(false); - setIsPlay(false); - setIsLoadingVideoWrapper(false); - setIsReady(false); - setIsEnd(false); - setIsVideoLoadFinish(false); - setPlayTime(0); - - //清楚dom事件监听 - try { - videoRemoveListener.current(); - } catch (error) { - console.error(error); - } - setPlaySeq((pre) => pre + 1); - return; - } - videoInsRef.current.play(); - } - - setPlayTime(0); - setIsEnd(false); - }; - const seek = (v: string) => { - if (videoInsRef.current && isVideoLoadFinished) { - setPlayTime(parseFloat(v)); - videoInsRef.current.currentTime = parseFloat(v); - } else { - message.warning('待视频加载完,才可操作进度条') - } - }; - // ========================== 视频opt bar ========================= - const [isFullscreen, { toggleFullscreen }] = useFullscreen(containerRef, { - pageFullscreen: true, - }); - const showMaxDuration = !!maxDuration - ? maxDuration - : toRealNumber(get(videoRef, 'current.duration', 0)); - const showSlider = videoInsRef.current && isVideoLoadFinished; - const showStatus = getShowStatus(isDelayLoading, isEnd, isError); - - // ========================== 截图 ========================= - const corpContainerRef = useRef(); - const cropInsRef = useRef(null); - const [showCrop, setShowCrop] = useState(false); - - //回显默认框选 - const isFirstFlagRef = useRef(true); - useEffect(() => { - const isFirst = isFirstFlagRef.current; - if (!isLoadingVideo && isReady && isFirst && defaultNormalizationRect && !showStatus) { - nextTick(() => { - setShowCrop(true); - }); - } - }, [isLoadingVideo, showStatus]); - - //定位按钮相关参数 - const alginContainerRef = useRef(null); - const alignRef = useRef(null); - const [cropRect, setCropRect] = useState(null); - - useEffect(() => { - showCrop ? videoInsRef?.current?.pause() : videoInsRef?.current?.play(); - }, [showCrop]); - - useEffect(() => { - let handlerCropStart: { remove: () => void; }; - let handlerCropEnd: { remove: () => void; }; - setCropRect(null); - if (!isReady) return; - if (showCrop) { - handlerCropStart = addEventListenerWrapper(corpContainerRef.current, EVENT_CROP_START, (event) => { - setCropRect(null); - }); - handlerCropEnd = addEventListenerWrapper(corpContainerRef.current, EVENT_CROP_END, (event) => { - const data = event.detail; - setCropRect({ - x: data.left, - y: data.top, - w: data.width, - h: data.height, - }); - alignRef?.current?.forceAlign?.(); - }); - let video: any = videoRef.current; - //计算limitcroppbox - let scale = Math.min( - video.offsetWidth / video.videoWidth, - video.offsetHeight / video.videoHeight - ); - let finalVideoWidth = video.videoWidth * scale; - let finalVideoHeight = video.videoHeight * scale; - let cropBoxLimited = { - width: finalVideoWidth, - height: finalVideoHeight, - top: (video.offsetHeight - finalVideoHeight) / 2, - left: (video.offsetWidth - finalVideoWidth) / 2, - }; - //获取视频图片 - let canvas = document.createElement('canvas'); - canvas.width = video.offsetWidth; - canvas.height = video.offsetHeight; - canvas.style.display = 'none'; - document.body.appendChild(canvas); - let ctx = canvas.getContext('2d'); - ctx.drawImage( - video, - (video.offsetWidth - finalVideoWidth) / 2, - (video.offsetHeight - finalVideoHeight) / 2, - finalVideoWidth, - finalVideoHeight - ); - let imageData = canvas.toDataURL('image/png'); - canvas.parentNode?.removeChild(canvas); - //回显编辑框 - const isFirst = isFirstFlagRef.current; - let initialCropBoxData = null; - if (isFirst && defaultNormalizationRect) { - initialCropBoxData = { - left: defaultNormalizationRect.x * finalVideoWidth + cropBoxLimited.left, - top: defaultNormalizationRect.y * finalVideoHeight + cropBoxLimited.top, - width: defaultNormalizationRect.w * finalVideoWidth, - height: defaultNormalizationRect.h * finalVideoHeight, - }; - } - isFirstFlagRef.current = false; - - cropInsRef.current = new Cropper(corpContainerRef.current, { - showMask: true, - cropBoxLimited, - img: imageData, - initialCropBoxData, - }); - } - return () => { - handlerCropStart?.remove(); - handlerCropEnd?.remove(); - cropInsRef?.current?.destroy?.(); - cropInsRef.current = null; - }; - }, [showCrop, isReady]); - - const latestCropRect = useLatest(cropRect); - - const getCropInfo = async () => { - const cropRect = latestCropRect.current as any; - let video: any = videoRef.current; - if (!video) return - let rectList = []; - let extendRectList = []; - let selectIndex = 0; - //获取视频图片的url - let scale = Math.min( - video.offsetWidth / video.videoWidth, - video.offsetHeight / video.videoHeight - ); - let finalVideoWidth = video.videoWidth * scale; - let finalVideoHeight = video.videoHeight * scale; - let canvas = document.createElement('canvas'); - canvas.width = finalVideoWidth; - canvas.height = finalVideoHeight; - canvas.style.display = 'none'; - document.body.appendChild(canvas); - let ctx = canvas.getContext('2d') as CanvasRenderingContext2D; - ctx.drawImage( - video, - 0, - 0, - finalVideoWidth, - finalVideoHeight - ); - let base64 = canvas.toDataURL('image/jpeg'); - const blobData = dataURLToBlob(base64); - canvas.parentNode?.removeChild(canvas); - const file = new window.File([blobData], `${new Date().getTime()}`); - let newRect = { - w: cropRect.w / finalVideoWidth, - h: cropRect.h / finalVideoHeight, - x: (cropRect.x - (video.offsetWidth - finalVideoWidth) / 2) / finalVideoWidth, - y: (cropRect.y - (video.offsetHeight - finalVideoHeight) / 2) / finalVideoHeight - }; - rectList.push(newRect); - extendRectList.push(newRect); - //扩展框获取imgkey - extendRectList.forEach(async (rect, index) => { - extendRectList[index] = { - ...rect, - }; - }) - return { - rectList, - extendRectList, - selectIndex, - file - }; - }; - - //回调 - useEffect(() => { - //计算归一化crop rect - let normalizationRect = null; - if (showCrop && cropRect) { - let video: any = videoRef.current; - let scale = Math.min( - video.offsetWidth / video.videoWidth, - video.offsetHeight / video.videoHeight - ); - let finalVideoWidth = video.videoWidth * scale; - let finalVideoHeight = video.videoHeight * scale; - let cropBoxLimited = { - width: finalVideoWidth, - height: finalVideoHeight, - top: (video.offsetHeight - finalVideoHeight) / 2, - left: (video.offsetWidth - finalVideoWidth) / 2, - }; - normalizationRect = { - x: (cropRect.x - cropBoxLimited.left) / cropBoxLimited.width, - y: (cropRect.y - cropBoxLimited.top) / cropBoxLimited.height, - w: cropRect.w / cropBoxLimited.width, - h: cropRect.h / cropBoxLimited.height, - }; - } - - onCropChange?.(showCrop, normalizationRect); - }, [showCrop, cropRect]); - - // ========================== 截帧 ========================= - const downloadVideoframe = useCallback(async () => { - try { - videoInsRef?.current?.pause?.(); - let video: any = videoRef.current; - var canvas = document.createElement('canvas'); - const ctx = canvas.getContext('2d') - let base64; - //当视频处于还未加载出来时,截屏为黑色图片 - if (video.readyState === 0) { - ctx?.clearRect(0, 0, canvas.width, canvas.height); - canvas.width = video.offsetWidth; - canvas.height = video.offsetHeight; - // @ts-ignore - ctx.fillStyle = 'black'; - ctx?.fillRect(0, 0, canvas.width, canvas.height); - base64 = canvas.toDataURL(); - } else { - canvas.width = video.videoWidth; - canvas.height = video.videoHeight; - ctx?.drawImage(video, 0, 0, canvas.width, canvas.height); - base64 = canvas.toDataURL('image/png'); - } - download(base64); - } catch (error) { - console.error(error); - } - }, []); - - // ============================== 暴露出去的方法 =============================== - const latestIsReady = useLatest(isReady); - const cropAble = !showStatus && isReady; - useImperativeHandle(ref, () => ({ - cropAble, - setShowCrop: (dispatch) => { - const isReady = latestIsReady.current; - if (!isReady) return; - setShowCrop(dispatch); - }, - downloadVideoframe, - })); - - return ( -
    - {flvUrl && ( - <> - - {/* //截图 */} -
    - {/*
    */} -
    - {showCrop && cropRect && screenshotButtonRender && ( - <> -
    - - {screenshotButtonRender({ - model: 'IMAGE', - getCropInfo, - setShowCrop, - cropType: CROP_TYPE['CUSTOM'], - })} - - - )} - {/* 视频进度条 */} - {!showCrop && ( -
    -
    - -
    -
    { - e.stopPropagation(); - }} - > - -
    - {/* TODO: 删除扩展方法format */} - {formatDurationTime(playTime)}/{formatDurationTime(showMaxDuration)} -
    -
    -
    - -
    -
    - )} - {/* mask */} - {!!showStatus && ( - reload()} /> - )} - - )} -
    - ); -}); - -export default VideoPlayer; +export default VideoPlayer diff --git a/packages/meta/src/VideoPlayer/videoPlayerHelper.ts b/packages/meta/src/VideoPlayer/videoPlayerHelper.ts new file mode 100644 index 0000000..0ce9bf0 --- /dev/null +++ b/packages/meta/src/VideoPlayer/videoPlayerHelper.ts @@ -0,0 +1,14 @@ + +export function getShowStatus(isLoadingVideo: boolean, isEnd: boolean, isError: boolean) { + let status = null; + if (isLoadingVideo) { + status = 'LOADING'; + } + if (isError) { + status = 'ERROR'; + } + if (isEnd) { + status = 'END'; + } + return status; +} diff --git a/packages/meta/src/index.md b/packages/meta/src/index.md index b5316e0..c54cdfa 100644 --- a/packages/meta/src/index.md +++ b/packages/meta/src/index.md @@ -5,4 +5,61 @@ title: 快速上手 order: 1 --- +## 目录结构 + + +
      +
    • + src + 开发文件夹 +
        +
      • + Component1 + 组件目录 +
          +
        • + index.ts + 入口文件 +
        • +
        • + Component1.tsx + 组件1 +
        • +
        • + Component1Helper.ts + 组件函数 +
        • +
        • + index.less + 样式文件 +
        • +
        • + index.md + 说明文档 +
        • +
        +
      • +
      • + utils + 公共函数文件夹 +
      • +
      • + index.ts + 总入口文件 +
      • +
      +
    • +
    • + .dumirc.ts + 文档配置 +
    • +
    • + package.json + 这是 package.json +
    • +
    +
    + + + diff --git a/packages/meta/src/index.tsx b/packages/meta/src/index.tsx index 6d39fad..5582665 100644 --- a/packages/meta/src/index.tsx +++ b/packages/meta/src/index.tsx @@ -1,5 +1,5 @@ export { default as doubleClick } from './doubleClick'; export { default as Icon } from './iconfont'; -export { default as ImagePreview } from './ImagePreview' +export { default as CompareImage } from './CompareImage' export { default as BigImagePreview } from './BigImagePreview' export { default as VideoPlayer } from './VideoPlayer' diff --git a/packages/meta/src/utils/constants.ts b/packages/meta/src/utils/constants.ts new file mode 100644 index 0000000..3e90a79 --- /dev/null +++ b/packages/meta/src/utils/constants.ts @@ -0,0 +1,13 @@ +export const CROP_TYPE = { + CUSTOM: 'CSUTOM', + AUTO: 'AUTO', +}; + +export const defaultAlignOption = { + points: ['bl', 'br'], + offset: [6, 0], + overflow: { + adjustX: true, + adjustY: true, + }, +}; diff --git a/packages/request/CHANGELOG.md b/packages/request/CHANGELOG.md index 8ac9057..e1947d9 100644 --- a/packages/request/CHANGELOG.md +++ b/packages/request/CHANGELOG.md @@ -1,5 +1,11 @@ # @zhst/request +## 0.3.0 + +### Minor Changes + +- feat: 初始化项目包 + ## 0.2.4 ### Patch Changes diff --git a/packages/request/es/index.d.ts b/packages/request/es/index.d.ts new file mode 100644 index 0000000..746e3db --- /dev/null +++ b/packages/request/es/index.d.ts @@ -0,0 +1,32 @@ +import type { RequestOptionsInit } from 'umi-request'; +export declare class ResponseError extends Error { + name: string; + data: D; + response: Response; + request: { + url: string; + options: RequestOptionsInit; + }; + type: string; + constructor(response: Response, text: string, data: D, request: { + url: string; + options: RequestOptionsInit; + }, type?: string); +} +export declare const req: import("umi-request").RequestMethod; +export interface OPTION extends RequestOptionsInit { + toast?: boolean; +} +interface CGI { + method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH'; + url: string; + baseUrl?: string; + data?: { + [key: string]: any; + }; + useBaseUrl?: boolean; + originUrl?: boolean; + refererSuffix?: string; +} +export declare const doRequest: (cgi: CGI, option?: OPTION) => Promise; +export default doRequest; diff --git a/packages/request/es/index.js b/packages/request/es/index.js index e15cf6d..b0ed186 100644 --- a/packages/request/es/index.js +++ b/packages/request/es/index.js @@ -81,19 +81,25 @@ req.use( /*#__PURE__*/function () { return _context.abrupt("return"); case 14: isEmptyRes = d === ''; //有些后端接口成功会返回空 做下兼容 + if (res) { + _context.next = 17; + break; + } + return _context.abrupt("return"); + case 17: body = !isEmptyRes ? JSON.parse(d) : d; if (!(res.status >= 200 && res.status < 300)) { - _context.next = 20; + _context.next = 22; break; } ctx.res = body; - _context.next = 24; + _context.next = 26; break; - case 20: + case 22: // 先判断Grpc-Metadata-Errorx-Message errMsg = res.headers.get('Grpc-Metadata-Errorx-Message'); if (errMsg) { - errMsg = window.utf8.decode(base64.decode(errMsg)); + errMsg = base64.decode(errMsg); // 后判断 body中的message } else if (!errMsg && get(body, 'message')) { errMsg = "".concat(get(body, 'message')); @@ -103,21 +109,21 @@ req.use( /*#__PURE__*/function () { } toast && message.error(errMsg); throw new ResponseError(res, errMsg, d, req, 'CustomError'); - case 24: - _context.next = 30; - break; case 26: - _context.prev = 26; + _context.next = 32; + break; + case 28: + _context.prev = 28; _context.t0 = _context["catch"](2); if (get(_context.t0, 'type') !== 'CustomError') { toast && message.error('您的网络发生异常,无法连接服务器'); } throw _context.t0; - case 30: + case 32: case "end": return _context.stop(); } - }, _callee, null, [[2, 26]]); + }, _callee, null, [[2, 28]]); })); return function (_x, _x2) { return _ref.apply(this, arguments); @@ -172,7 +178,7 @@ export var doRequest = function doRequest(cgi, option) { } : { data: newData }; - return request(newUrl, _objectSpread(_objectSpread(_objectSpread({ + return req(newUrl, _objectSpread(_objectSpread(_objectSpread({ method: method }, paramObj), option), {}, { headers: _objectSpread({ diff --git a/packages/request/lib/index.d.ts b/packages/request/lib/index.d.ts new file mode 100644 index 0000000..746e3db --- /dev/null +++ b/packages/request/lib/index.d.ts @@ -0,0 +1,32 @@ +import type { RequestOptionsInit } from 'umi-request'; +export declare class ResponseError extends Error { + name: string; + data: D; + response: Response; + request: { + url: string; + options: RequestOptionsInit; + }; + type: string; + constructor(response: Response, text: string, data: D, request: { + url: string; + options: RequestOptionsInit; + }, type?: string); +} +export declare const req: import("umi-request").RequestMethod; +export interface OPTION extends RequestOptionsInit { + toast?: boolean; +} +interface CGI { + method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH'; + url: string; + baseUrl?: string; + data?: { + [key: string]: any; + }; + useBaseUrl?: boolean; + originUrl?: boolean; + refererSuffix?: string; +} +export declare const doRequest: (cgi: CGI, option?: OPTION) => Promise; +export default doRequest; diff --git a/packages/request/lib/index.js b/packages/request/lib/index.js new file mode 100644 index 0000000..9935c48 --- /dev/null +++ b/packages/request/lib/index.js @@ -0,0 +1,150 @@ +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// src/index.ts +var src_exports = {}; +__export(src_exports, { + ResponseError: () => ResponseError, + default: () => src_default, + doRequest: () => doRequest, + req: () => req +}); +module.exports = __toCommonJS(src_exports); +var import_umi_request = require("umi-request"); +var import_lodash_es = require("lodash-es"); +var import_antd = require("antd"); +var import_user = require("@zhst/types/user"); +var import_base_64 = __toESM(require("base-64")); +var ResponseError = class extends Error { + constructor(response, text, data, request, type = "ResponseError") { + super(text || response.statusText); + this.name = "ResponseError"; + this.data = data; + this.response = response; + this.request = request; + this.type = type; + } +}; +var req = (0, import_umi_request.extend)({ + getResponse: true, + // timeout: 1000, + parseResponse: false +}); +req.use(async (ctx, next) => { + const { req: req2 } = ctx; + const { toast = true } = (req2 == null ? void 0 : req2.options) || {}; + try { + await next(); + const { res } = ctx; + const d = await res.text(); + if (res.status === 401) { + localStorage.removeItem(import_user.User.TOKEN_KEY); + localStorage.removeItem(import_user.User.USER_KEY); + import_antd.message.warning("登录过期,请重新登录!"); + return; + } + const isEmptyRes = d === ""; + if (!res) + return; + const body = !isEmptyRes ? JSON.parse(d) : d; + if (res.status >= 200 && res.status < 300) { + ctx.res = body; + } else { + let errMsg = res.headers.get("Grpc-Metadata-Errorx-Message"); + if (errMsg) { + errMsg = import_base_64.default.decode(errMsg); + } else if (!errMsg && (0, import_lodash_es.get)(body, "message")) { + errMsg = `${(0, import_lodash_es.get)(body, "message")}`; + } else { + errMsg = "您的网络发生异常,无法连接服务器"; + } + toast && import_antd.message.error(errMsg); + throw new ResponseError(res, errMsg, d, req2, "CustomError"); + } + } catch (error) { + if ((0, import_lodash_es.get)(error, "type") !== "CustomError") { + toast && import_antd.message.error("您的网络发生异常,无法连接服务器"); + } + throw error; + } +}); +var doRequest = (cgi, option) => { + const { + method, + url, + baseUrl, + data = {}, + useBaseUrl = true, + originUrl = false, + refererSuffix = "" + } = cgi; + const token = localStorage.getItem(import_user.User.TOKEN_KEY); + const userInfo = localStorage.getItem(import_user.User.USER_KEY) ? JSON.parse(localStorage.getItem(import_user.User.USER_KEY)) : null; + let newUrl = ""; + if (useBaseUrl) { + newUrl = `${baseUrl}${url}`; + } else { + newUrl = `http://10.0.0.7:32223${url}`; + } + if (originUrl) { + newUrl = url; + } + const regex = /\/:(\w+)/g; + const params = []; + let matches; + while ((matches = regex.exec(newUrl)) != null) { + if (matches[1]) { + params.push(matches[1]); + } + } + params.forEach(function(name) { + let d = data == null ? void 0 : data[name]; + if (d == null) { + d = ""; + } + newUrl = newUrl.replace(`:${name}`, d); + }); + const newData = (0, import_lodash_es.omit)(data, params); + const paramObj = method.toLowerCase() === "get" ? { params: newData } : { data: newData }; + return req(newUrl, { + method, + ...paramObj, + ...option, + headers: { + authorization: token, + ...refererSuffix ? { zhst_referer: `${baseUrl}${refererSuffix}` } : {} + } + }); +}; +var src_default = doRequest; +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + ResponseError, + doRequest, + req +}); diff --git a/packages/request/package.json b/packages/request/package.json index 955c4d4..9f9b43b 100644 --- a/packages/request/package.json +++ b/packages/request/package.json @@ -1,6 +1,6 @@ { "name": "@zhst/request", - "version": "0.2.4", + "version": "0.3.0", "description": "请求库", "keywords": [ "request", diff --git a/packages/request/src/index.ts b/packages/request/src/index.ts index 5c40139..e981647 100644 --- a/packages/request/src/index.ts +++ b/packages/request/src/index.ts @@ -59,7 +59,7 @@ req.use(async (ctx, next) => { // 先判断Grpc-Metadata-Errorx-Message let errMsg = res.headers.get('Grpc-Metadata-Errorx-Message'); if (errMsg) { - errMsg = window?.utf8?.decode(base64.decode(errMsg)); + errMsg = base64.decode(errMsg) // 后判断 body中的message } else if (!errMsg && get(body, 'message')) { errMsg = `${get(body, 'message')}`; diff --git a/packages/types/CHANGELOG.md b/packages/types/CHANGELOG.md index 4b45684..0843b80 100644 --- a/packages/types/CHANGELOG.md +++ b/packages/types/CHANGELOG.md @@ -1,5 +1,11 @@ # @zhst/types +## 0.3.0 + +### Minor Changes + +- feat: 初始化项目包 + ## 0.2.4 ### Patch Changes diff --git a/packages/types/index.d.ts b/packages/types/index.d.ts index f04db81..890324e 100644 --- a/packages/types/index.d.ts +++ b/packages/types/index.d.ts @@ -141,7 +141,7 @@ export interface IScreenshotButtonProp { getCropInfo: () => Promise; setShowCrop: React.Dispatch>; cropType: typeof cropType[number]; - selectAlgorithmVersion: number | null; + selectAlgorithmVersion?: number | null; } export interface AlignType { @@ -275,4 +275,5 @@ export type IOdRectOrigin { featureString: any[] } subObjects: any[] + objects: any[] } diff --git a/packages/types/package.json b/packages/types/package.json index 42c5ff3..b04dddb 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,6 +1,6 @@ { "name": "@zhst/types", - "version": "0.2.4", + "version": "0.3.0", "description": "变量定义库", "keywords": [ "types", @@ -13,14 +13,14 @@ "main": "", "typings": "index.d.ts", "exports": { - ".": { - "types": { - "default": "./index.d.ts" - } - }, - "./user": "./user.d.ts", - "./BigImageModal": "./BigImageModal.d.ts", - "./package.json": "./package.json" + ".": { + "types": { + "default": "./index.d.ts" + } + }, + "./user": "./user.d.ts", + "./BigImageModal": "./BigImageModal.d.ts", + "./package.json": "./package.json" }, "scripts": { "build": "father build" @@ -29,6 +29,5 @@ "access": "public", "registry": "http://10.0.0.77:4874" }, - "dependencies": { - } + "dependencies": {} } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index adf155e..17d36c6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -80,18 +80,12 @@ importers: antd: specifier: ^5.12.5 version: 5.12.5(react-dom@18.2.0)(react@18.2.0) - base-64: - specifier: ^1.0.0 - version: 1.0.0 classnames: specifier: ^2.5.1 version: 2.5.1 rc-util: specifier: ^5.38.1 version: 5.38.1(react-dom@18.2.0)(react@18.2.0) - umi-request: - specifier: ^1.4.0 - version: 1.4.0 devDependencies: '@zhst/types': specifier: workspace:^