From eb58402034a0a38361758cdc88d83b84fd8bc29b Mon Sep 17 00:00:00 2001 From: qianmoQ Date: Wed, 22 May 2024 20:50:45 +0800 Subject: [PATCH 1/5] [Core] [User] Fixed the user profile picture repeatedly uploaded --- .../initializer/InitializerConfigure.java | 3 +- .../service/service/impl/UserServiceImpl.java | 8 +- core/datacap-ui/yarn.lock | 401 ++++++++++++++---- .../java/io/edurt/datacap/fs/IOUtils.java | 7 + 4 files changed, 326 insertions(+), 93 deletions(-) diff --git a/core/datacap-service/src/main/java/io/edurt/datacap/service/initializer/InitializerConfigure.java b/core/datacap-service/src/main/java/io/edurt/datacap/service/initializer/InitializerConfigure.java index 2217e1f2..30e176ea 100644 --- a/core/datacap-service/src/main/java/io/edurt/datacap/service/initializer/InitializerConfigure.java +++ b/core/datacap-service/src/main/java/io/edurt/datacap/service/initializer/InitializerConfigure.java @@ -10,6 +10,7 @@ import io.edurt.datacap.service.security.UserDetailsService; import lombok.Getter; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.ObjectUtils; +import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @@ -166,7 +167,7 @@ public class InitializerConfigure public String getAvatarPath() { - if (fsConfigure.getEndpoint() != null) { + if (StringUtils.isNotEmpty(fsConfigure.getEndpoint())) { return fsConfigure.getEndpoint(); } return avatarPath.replace("{username}", UserDetailsService.getUser().getUsername()); diff --git a/core/datacap-service/src/main/java/io/edurt/datacap/service/service/impl/UserServiceImpl.java b/core/datacap-service/src/main/java/io/edurt/datacap/service/service/impl/UserServiceImpl.java index 5e9e9869..1345865c 100644 --- a/core/datacap-service/src/main/java/io/edurt/datacap/service/service/impl/UserServiceImpl.java +++ b/core/datacap-service/src/main/java/io/edurt/datacap/service/service/impl/UserServiceImpl.java @@ -294,7 +294,7 @@ public class UserServiceImpl .endpoint(avatarPath) .bucket(initializerConfigure.getFsConfigure().getBucket()) .stream(file.getInputStream()) - .fileName(file.getOriginalFilename()) + .fileName(String.format("%s.png", user.getId())) .build(); FsResponse response = fs.writer(fsRequest); UserEntity entity = userRepository.findById(user.getId()).get(); @@ -320,6 +320,7 @@ public class UserServiceImpl } private String encodeImageToBase64(InputStream inputStream) + throws IOException { try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) { byte[] buffer = new byte[1024]; @@ -333,5 +334,10 @@ public class UserServiceImpl log.warn("Encode image to base64 exception", e); return null; } + finally { + if (inputStream != null) { + inputStream.close(); + } + } } } diff --git a/core/datacap-ui/yarn.lock b/core/datacap-ui/yarn.lock index 9a1d1ee8..7983d8ee 100644 --- a/core/datacap-ui/yarn.lock +++ b/core/datacap-ui/yarn.lock @@ -363,11 +363,121 @@ style-mod "^4.1.0" w3c-keyname "^2.2.4" +"@esbuild/aix-ppc64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz#a70f4ac11c6a1dfc18b8bbb13284155d933b9537" + integrity sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g== + +"@esbuild/android-arm64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz#db1c9202a5bc92ea04c7b6840f1bbe09ebf9e6b9" + integrity sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg== + +"@esbuild/android-arm@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.20.2.tgz#3b488c49aee9d491c2c8f98a909b785870d6e995" + integrity sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w== + +"@esbuild/android-x64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.20.2.tgz#3b1628029e5576249d2b2d766696e50768449f98" + integrity sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg== + "@esbuild/darwin-arm64@0.20.2": version "0.20.2" resolved "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz" integrity sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA== +"@esbuild/darwin-x64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz#90ed098e1f9dd8a9381695b207e1cff45540a0d0" + integrity sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA== + +"@esbuild/freebsd-arm64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz#d71502d1ee89a1130327e890364666c760a2a911" + integrity sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw== + +"@esbuild/freebsd-x64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz#aa5ea58d9c1dd9af688b8b6f63ef0d3d60cea53c" + integrity sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw== + +"@esbuild/linux-arm64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz#055b63725df678379b0f6db9d0fa85463755b2e5" + integrity sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A== + +"@esbuild/linux-arm@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz#76b3b98cb1f87936fbc37f073efabad49dcd889c" + integrity sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg== + +"@esbuild/linux-ia32@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz#c0e5e787c285264e5dfc7a79f04b8b4eefdad7fa" + integrity sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig== + +"@esbuild/linux-loong64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz#a6184e62bd7cdc63e0c0448b83801001653219c5" + integrity sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ== + +"@esbuild/linux-mips64el@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz#d08e39ce86f45ef8fc88549d29c62b8acf5649aa" + integrity sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA== + +"@esbuild/linux-ppc64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz#8d252f0b7756ffd6d1cbde5ea67ff8fd20437f20" + integrity sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg== + +"@esbuild/linux-riscv64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz#19f6dcdb14409dae607f66ca1181dd4e9db81300" + integrity sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg== + +"@esbuild/linux-s390x@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz#3c830c90f1a5d7dd1473d5595ea4ebb920988685" + integrity sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ== + +"@esbuild/linux-x64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz#86eca35203afc0d9de0694c64ec0ab0a378f6fff" + integrity sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw== + +"@esbuild/netbsd-x64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz#e771c8eb0e0f6e1877ffd4220036b98aed5915e6" + integrity sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ== + +"@esbuild/openbsd-x64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz#9a795ae4b4e37e674f0f4d716f3e226dd7c39baf" + integrity sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ== + +"@esbuild/sunos-x64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz#7df23b61a497b8ac189def6e25a95673caedb03f" + integrity sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w== + +"@esbuild/win32-arm64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz#f1ae5abf9ca052ae11c1bc806fb4c0f519bacf90" + integrity sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ== + +"@esbuild/win32-ia32@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz#241fe62c34d8e8461cd708277813e1d0ba55ce23" + integrity sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ== + +"@esbuild/win32-x64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz#9c907b21e30a52db959ba4f80bb01a0cc403d5cc" + integrity sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ== + "@floating-ui/core@^1.0.0": version "1.6.0" resolved "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.0.tgz" @@ -402,7 +512,7 @@ resolved "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.5.2.tgz" integrity sha512-gBxPg3aVO6J0kpfHNILc+NMhXnqHumFxOmjYCFfOiLZfwhnnfhtsdA2hfJlDnj+8PjAs6kKQPenOTKj3Rf7zHw== -"@fortawesome/fontawesome-svg-core@^6.5.1", "@fortawesome/fontawesome-svg-core@~1 || ~6": +"@fortawesome/fontawesome-svg-core@^6.5.1": version "6.5.2" resolved "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.5.2.tgz" integrity sha512-5CdaCBGl8Rh9ohNdxeeTMxIj8oc3KNBgIeLMvJosBMdslK/UnEB8rzyDRrbKdL1kDweqBPo4GT9wvnakHWucZw== @@ -442,7 +552,7 @@ optionalDependencies: "@interactjs/interact" "1.10.27" -"@interactjs/core@^1.10.17", "@interactjs/core@1.10.27": +"@interactjs/core@1.10.27", "@interactjs/core@^1.10.17": version "1.10.27" resolved "https://registry.npmjs.org/@interactjs/core/-/core-1.10.27.tgz" integrity sha512-SliUr/3ZbLAdED8LokzYzWHWMdCB5Cq+UnpXuRy+BIod1j97m4IUFf/D1iIKUBBjBcucgXbz28z96WnenVCB7Q== @@ -455,7 +565,7 @@ "@interactjs/interact" "1.10.27" vue "3" -"@interactjs/interact@^1.10.17", "@interactjs/interact@1.10.27": +"@interactjs/interact@1.10.27", "@interactjs/interact@^1.10.17": version "1.10.27" resolved "https://registry.npmjs.org/@interactjs/interact/-/interact-1.10.27.tgz" integrity sha512-XdH3A2UUzjEFGGJgFuJlhiz99tE8jB8xNh/DmnoMuL6uOQPxNA+sWRnzEVjG0+zY2P3/dbhEpi4Cn3FLPzydwA== @@ -463,7 +573,7 @@ "@interactjs/core" "1.10.27" "@interactjs/utils" "1.10.27" -"@interactjs/modifiers@^1.10.17", "@interactjs/modifiers@1.10.27": +"@interactjs/modifiers@^1.10.17": version "1.10.27" resolved "https://registry.npmjs.org/@interactjs/modifiers/-/modifiers-1.10.27.tgz" integrity sha512-ei/qfoQ+9/8k6WzNzdNqHI6cWkIV576N4Ap16r5CoqOWwhA6Xzj3OMHf1g0t1O4eSq2HdJsVJn3eLNfw9HsbeQ== @@ -484,7 +594,7 @@ resolved "https://registry.npmjs.org/@interactjs/types/-/types-1.10.27.tgz" integrity sha512-BUdv0cvs4H5ODuwft2Xp4eL8Vmi3LcihK42z0Ft/FbVJZoRioBsxH+LlsBdK4tAie7PqlKGy+1oyOncu1nQ6eA== -"@interactjs/utils@^1.10.17", "@interactjs/utils@1.10.27": +"@interactjs/utils@1.10.27", "@interactjs/utils@^1.10.17": version "1.10.27" resolved "https://registry.npmjs.org/@interactjs/utils/-/utils-1.10.27.tgz" integrity sha512-+qfLOio2OxQqg1cXSnRaCl+N8MQDQLDS9w+aOGxH8YLAhIMyt7Asxx/46//sT8orgsi16pmlBPtngPHT9s8zKw== @@ -713,7 +823,7 @@ "@nodelib/fs.stat" "2.0.5" run-parallel "^1.1.9" -"@nodelib/fs.stat@^2.0.2", "@nodelib/fs.stat@2.0.5": +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": version "2.0.5" resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz" integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== @@ -741,11 +851,66 @@ resolved "https://registry.npmjs.org/@radix-icons/vue/-/vue-1.0.0.tgz" integrity sha512-gKWWk9tTK/laDRRNe5KLLR8A0qUwx4q4+DN8Fq48hJ904u78R82ayAO3TrxbNLgyn2D0h6rRiGdLzQWj7rPcvA== +"@resvg/resvg-js-android-arm-eabi@2.4.1": + version "2.4.1" + resolved "https://registry.yarnpkg.com/@resvg/resvg-js-android-arm-eabi/-/resvg-js-android-arm-eabi-2.4.1.tgz#49dc9722f95096f8aff70186deae8e148d60dce5" + integrity sha512-AA6f7hS0FAPpvQMhBCf6f1oD1LdlqNXKCxAAPpKh6tR11kqV0YIB9zOlIYgITM14mq2YooLFl6XIbbvmY+jwUw== + +"@resvg/resvg-js-android-arm64@2.4.1": + version "2.4.1" + resolved "https://registry.yarnpkg.com/@resvg/resvg-js-android-arm64/-/resvg-js-android-arm64-2.4.1.tgz#fdb7c9362ea27a228831d047cfd1ea240daed780" + integrity sha512-/QleoRdPfsEuH9jUjilYcDtKK/BkmWcK+1LXM8L2nsnf/CI8EnFyv7ZzCj4xAIvZGAy9dTYr/5NZBcTwxG2HQg== + "@resvg/resvg-js-darwin-arm64@2.4.1": version "2.4.1" resolved "https://registry.npmjs.org/@resvg/resvg-js-darwin-arm64/-/resvg-js-darwin-arm64-2.4.1.tgz" integrity sha512-U1oMNhea+kAXgiEXgzo7EbFGCD1Edq5aSlQoe6LMly6UjHzgx2W3N5kEXCwU/CgN5FiQhZr7PlSJSlcr7mdhfg== +"@resvg/resvg-js-darwin-x64@2.4.1": + version "2.4.1" + resolved "https://registry.yarnpkg.com/@resvg/resvg-js-darwin-x64/-/resvg-js-darwin-x64-2.4.1.tgz#18dd758184f4877be1f6ac80d2f37999581c998c" + integrity sha512-avyVh6DpebBfHHtTQTZYSr6NG1Ur6TEilk1+H0n7V+g4F7x7WPOo8zL00ZhQCeRQ5H4f8WXNWIEKL8fwqcOkYw== + +"@resvg/resvg-js-linux-arm-gnueabihf@2.4.1": + version "2.4.1" + resolved "https://registry.yarnpkg.com/@resvg/resvg-js-linux-arm-gnueabihf/-/resvg-js-linux-arm-gnueabihf-2.4.1.tgz#eee8f8166763aacc935a53e223e7b9c31b10c94a" + integrity sha512-isY/mdKoBWH4VB5v621co+8l101jxxYjuTkwOLsbW+5RK9EbLciPlCB02M99ThAHzI2MYxIUjXNmNgOW8btXvw== + +"@resvg/resvg-js-linux-arm64-gnu@2.4.1": + version "2.4.1" + resolved "https://registry.yarnpkg.com/@resvg/resvg-js-linux-arm64-gnu/-/resvg-js-linux-arm64-gnu-2.4.1.tgz#826569e1ee08f07879ce32850822ede2ee1192ef" + integrity sha512-uY5voSCrFI8TH95vIYBm5blpkOtltLxLRODyhKJhGfskOI7XkRw5/t1u0sWAGYD8rRSNX+CA+np86otKjubrNg== + +"@resvg/resvg-js-linux-arm64-musl@2.4.1": + version "2.4.1" + resolved "https://registry.yarnpkg.com/@resvg/resvg-js-linux-arm64-musl/-/resvg-js-linux-arm64-musl-2.4.1.tgz#faf63d873666078ca74604454d40e4fecc22beb4" + integrity sha512-6mT0+JBCsermKMdi/O2mMk3m7SqOjwi9TKAwSngRZ/nQoL3Z0Z5zV+572ztgbWr0GODB422uD8e9R9zzz38dRQ== + +"@resvg/resvg-js-linux-x64-gnu@2.4.1": + version "2.4.1" + resolved "https://registry.yarnpkg.com/@resvg/resvg-js-linux-x64-gnu/-/resvg-js-linux-x64-gnu-2.4.1.tgz#37b4c16c488aac3834a069c3725f017285d94b1e" + integrity sha512-60KnrscLj6VGhkYOJEmmzPlqqfcw1keDh6U+vMcNDjPhV3B5vRSkpP/D/a8sfokyeh4VEacPSYkWGezvzS2/mg== + +"@resvg/resvg-js-linux-x64-musl@2.4.1": + version "2.4.1" + resolved "https://registry.yarnpkg.com/@resvg/resvg-js-linux-x64-musl/-/resvg-js-linux-x64-musl-2.4.1.tgz#6099cf57c958832549b0671991246e06bb44df27" + integrity sha512-0AMyZSICC1D7ge115cOZQW8Pcad6PjWuZkBFF3FJuSxC6Dgok0MQnLTs2MfMdKBlAcwO9dXsf3bv9tJZj8pATA== + +"@resvg/resvg-js-win32-arm64-msvc@2.4.1": + version "2.4.1" + resolved "https://registry.yarnpkg.com/@resvg/resvg-js-win32-arm64-msvc/-/resvg-js-win32-arm64-msvc-2.4.1.tgz#10c9472a20198a218d8c3b6d8fbb3fcba213b670" + integrity sha512-76XDFOFSa3d0QotmcNyChh2xHwk+JTFiEQBVxMlHpHMeq7hNrQJ1IpE1zcHSQvrckvkdfLboKRrlGB86B10Qjw== + +"@resvg/resvg-js-win32-ia32-msvc@2.4.1": + version "2.4.1" + resolved "https://registry.yarnpkg.com/@resvg/resvg-js-win32-ia32-msvc/-/resvg-js-win32-ia32-msvc-2.4.1.tgz#bfc1d37ed485d72ca5717138b99ba40788fa2720" + integrity sha512-odyVFGrEWZIzzJ89KdaFtiYWaIJh9hJRW/frcEcG3agJ464VXkN/2oEVF5ulD+5mpGlug9qJg7htzHcKxDN8sg== + +"@resvg/resvg-js-win32-x64-msvc@2.4.1": + version "2.4.1" + resolved "https://registry.yarnpkg.com/@resvg/resvg-js-win32-x64-msvc/-/resvg-js-win32-x64-msvc-2.4.1.tgz#83cae82dfe27121f85492eb4dc03f6fe33d8a703" + integrity sha512-vY4kTLH2S3bP+puU5x7hlAxHv+ulFgcK6Zn3efKSr0M0KnZ9A3qeAjZteIpkowEFfUeMPNg2dvvoFRJA9zqxSw== + "@resvg/resvg-js@2.4.1": version "2.4.1" resolved "https://registry.npmjs.org/@resvg/resvg-js/-/resvg-js-2.4.1.tgz" @@ -764,11 +929,81 @@ "@resvg/resvg-js-win32-ia32-msvc" "2.4.1" "@resvg/resvg-js-win32-x64-msvc" "2.4.1" +"@rollup/rollup-android-arm-eabi@4.14.2": + version "4.14.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.14.2.tgz#9047b5b1ec19f58c0fdf3a072bd977bcec056576" + integrity sha512-ahxSgCkAEk+P/AVO0vYr7DxOD3CwAQrT0Go9BJyGQ9Ef0QxVOfjDZMiF4Y2s3mLyPrjonchIMH/tbWHucJMykQ== + +"@rollup/rollup-android-arm64@4.14.2": + version "4.14.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.14.2.tgz#08a2d2705193ebb3054941994e152808beb5254e" + integrity sha512-lAarIdxZWbFSHFSDao9+I/F5jDaKyCqAPMq5HqnfpBw8dKDiCaaqM0lq5h1pQTLeIqueeay4PieGR5jGZMWprw== + "@rollup/rollup-darwin-arm64@4.14.2": version "4.14.2" resolved "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.14.2.tgz" integrity sha512-SWsr8zEUk82KSqquIMgZEg2GE5mCSfr9sE/thDROkX6pb3QQWPp8Vw8zOq2GyxZ2t0XoSIUlvHDkrf5Gmf7x3Q== +"@rollup/rollup-darwin-x64@4.14.2": + version "4.14.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.14.2.tgz#59ebe3b858a44680d5f87546ea2df1c7e3135f6a" + integrity sha512-o/HAIrQq0jIxJAhgtIvV5FWviYK4WB0WwV91SLUnsliw1lSAoLsmgEEgRWzDguAFeUEUUoIWXiJrPqU7vGiVkA== + +"@rollup/rollup-linux-arm-gnueabihf@4.14.2": + version "4.14.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.14.2.tgz#44cffc07d04d659cb635aec11bef530d5757ee6a" + integrity sha512-nwlJ65UY9eGq91cBi6VyDfArUJSKOYt5dJQBq8xyLhvS23qO+4Nr/RreibFHjP6t+5ap2ohZrUJcHv5zk5ju/g== + +"@rollup/rollup-linux-arm64-gnu@4.14.2": + version "4.14.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.14.2.tgz#9901e2288fb192b74a2f8428c507d43cc2739ceb" + integrity sha512-Pg5TxxO2IVlMj79+c/9G0LREC9SY3HM+pfAwX7zj5/cAuwrbfj2Wv9JbMHIdPCfQpYsI4g9mE+2Bw/3aeSs2rQ== + +"@rollup/rollup-linux-arm64-musl@4.14.2": + version "4.14.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.14.2.tgz#8a2c55a72e0c716a15d830fee3bf5a1a756f13ec" + integrity sha512-cAOTjGNm84gc6tS02D1EXtG7tDRsVSDTBVXOLbj31DkwfZwgTPYZ6aafSU7rD/4R2a34JOwlF9fQayuTSkoclA== + +"@rollup/rollup-linux-powerpc64le-gnu@4.14.2": + version "4.14.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.14.2.tgz#71bf99c8017476ac85b09d21b3fa2eacbad96100" + integrity sha512-4RyT6v1kXb7C0fn6zV33rvaX05P0zHoNzaXI/5oFHklfKm602j+N4mn2YvoezQViRLPnxP8M1NaY4s/5kXO5cw== + +"@rollup/rollup-linux-riscv64-gnu@4.14.2": + version "4.14.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.14.2.tgz#48ee7fe5fee7b6d0028b6dda4fab95238208a0cd" + integrity sha512-KNUH6jC/vRGAKSorySTyc/yRYlCwN/5pnMjXylfBniwtJx5O7X17KG/0efj8XM3TZU7raYRXJFFReOzNmL1n1w== + +"@rollup/rollup-linux-s390x-gnu@4.14.2": + version "4.14.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.14.2.tgz#65ad6f82729ef9d8634847189214e3205892f42f" + integrity sha512-xPV4y73IBEXToNPa3h5lbgXOi/v0NcvKxU0xejiFw6DtIYQqOTMhZ2DN18/HrrP0PmiL3rGtRG9gz1QE8vFKXQ== + +"@rollup/rollup-linux-x64-gnu@4.14.2": + version "4.14.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.14.2.tgz#2ab802ce25c0d0d44a0ea55b0068f79e462d22cd" + integrity sha512-QBhtr07iFGmF9egrPOWyO5wciwgtzKkYPNLVCFZTmr4TWmY0oY2Dm/bmhHjKRwZoGiaKdNcKhFtUMBKvlchH+Q== + +"@rollup/rollup-linux-x64-musl@4.14.2": + version "4.14.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.14.2.tgz#85dcd3f549c2fdbcf1cb1f1b5f501933ed590880" + integrity sha512-8zfsQRQGH23O6qazZSFY5jP5gt4cFvRuKTpuBsC1ZnSWxV8ZKQpPqOZIUtdfMOugCcBvFGRa1pDC/tkf19EgBw== + +"@rollup/rollup-win32-arm64-msvc@4.14.2": + version "4.14.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.14.2.tgz#10f608dfc1e5bb96aca18c7784cc4a94d890c03c" + integrity sha512-H4s8UjgkPnlChl6JF5empNvFHp77Jx+Wfy2EtmYPe9G22XV+PMuCinZVHurNe8ggtwoaohxARJZbaH/3xjB/FA== + +"@rollup/rollup-win32-ia32-msvc@4.14.2": + version "4.14.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.14.2.tgz#f27f9fb64b7e10b04121e0054d9145ee21589267" + integrity sha512-djqpAjm/i8erWYF0K6UY4kRO3X5+T4TypIqw60Q8MTqSBaQNpNXDhxdjpZ3ikgb+wn99svA7jxcXpiyg9MUsdw== + +"@rollup/rollup-win32-x64-msvc@4.14.2": + version "4.14.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.14.2.tgz#5d2d9dc96b436469dc74ef93de069b14fb12aace" + integrity sha512-teAqzLT0yTYZa8ZP7zhFKEx4cotS8Tkk5XiqNMJhD4CpaWB1BHARE4Qy+RzwnXvSAYv+Q3jAqCVBS+PS+Yee8Q== + "@swc/helpers@^0.5.0": version "0.5.8" resolved "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.8.tgz" @@ -886,7 +1121,7 @@ resolved "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.5.tgz" integrity sha512-6L6VymKTzYSrEf4Nev4Xa1LCHKrlTlYCBMTlQKFuddo1CvQcE52I0mwfOJayueUC7MJuXOeHTcIU683lzd0cUA== -"@types/node@^18.0.0 || >=20.0.0", "@types/node@^20.11.26": +"@types/node@^20.11.26": version "20.12.7" resolved "https://registry.npmjs.org/@types/node/-/node-20.12.7.tgz" integrity sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg== @@ -1157,16 +1392,6 @@ "@visactor/vutils-extension" "~1.8.5" cssfontparser "^1.2.1" -"@visactor/vutils-extension@~1.8.5": - version "1.8.11" - resolved "https://registry.npmjs.org/@visactor/vutils-extension/-/vutils-extension-1.8.11.tgz" - integrity sha512-Hknzpy3+xh4sdL0iSn5N93BHiMJF4FdwSwhHYEibRpriZmWKG6wBxsJ0Bll4d7oS4f+svxt8Sg2vRYKzQEcIxQ== - dependencies: - "@visactor/vrender-core" "0.17.17" - "@visactor/vrender-kits" "0.17.17" - "@visactor/vscale" "~0.17.3" - "@visactor/vutils" "~0.17.3" - "@visactor/vutils-extension@1.10.4": version "1.10.4" resolved "https://registry.npmjs.org/@visactor/vutils-extension/-/vutils-extension-1.10.4.tgz" @@ -1179,7 +1404,17 @@ "@visactor/vscale" "~0.18.1" "@visactor/vutils" "~0.18.1" -"@visactor/vutils@~0.17.3", "@visactor/vutils@0.17.5": +"@visactor/vutils-extension@~1.8.5": + version "1.8.11" + resolved "https://registry.npmjs.org/@visactor/vutils-extension/-/vutils-extension-1.8.11.tgz" + integrity sha512-Hknzpy3+xh4sdL0iSn5N93BHiMJF4FdwSwhHYEibRpriZmWKG6wBxsJ0Bll4d7oS4f+svxt8Sg2vRYKzQEcIxQ== + dependencies: + "@visactor/vrender-core" "0.17.17" + "@visactor/vrender-kits" "0.17.17" + "@visactor/vscale" "~0.17.3" + "@visactor/vutils" "~0.17.3" + +"@visactor/vutils@0.17.5", "@visactor/vutils@~0.17.3": version "0.17.5" resolved "https://registry.npmjs.org/@visactor/vutils/-/vutils-0.17.5.tgz" integrity sha512-HFN6Pk1Wc1RK842g02MeKOlvdri5L7/nqxMVTqxIvi0XMhHXpmoqN4+/9H+h8LmJpVohyrI/MT85TRBV/rManw== @@ -1188,7 +1423,7 @@ "@turf/invariant" "^6.5.0" eventemitter3 "^4.0.7" -"@visactor/vutils@~0.18.1", "@visactor/vutils@0.18.1": +"@visactor/vutils@0.18.1", "@visactor/vutils@~0.18.1": version "0.18.1" resolved "https://registry.npmjs.org/@visactor/vutils/-/vutils-0.18.1.tgz" integrity sha512-XGq9a85HrVP3Rbby1qO2/JS9GewJtZv6y35Xujcb2ZGLEjnpCK61Y1OXwSC5SZOKmtsH4SjYMf5czlnNhQ3GeA== @@ -1202,14 +1437,14 @@ resolved "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.0.4.tgz" integrity sha512-WS3hevEszI6CEVEx28F8RjTX97k3KsrcY6kvTg7+Whm5y3oYvcqzVeGCU3hxSAn4uY2CLCkeokkGKpoctccilQ== -"@volar/language-core@~1.11.1", "@volar/language-core@1.11.1": +"@volar/language-core@1.11.1", "@volar/language-core@~1.11.1": version "1.11.1" resolved "https://registry.npmjs.org/@volar/language-core/-/language-core-1.11.1.tgz" integrity sha512-dOcNn3i9GgZAcJt43wuaEykSluAuOkQgzni1cuxLxTV0nJKanQztp7FxyswdRILaKH+P2XZMPRp2S4MV/pElCw== dependencies: "@volar/source-map" "1.11.1" -"@volar/source-map@~1.11.1", "@volar/source-map@1.11.1": +"@volar/source-map@1.11.1", "@volar/source-map@~1.11.1": version "1.11.1" resolved "https://registry.npmjs.org/@volar/source-map/-/source-map-1.11.1.tgz" integrity sha512-hJnOnwZ4+WT5iupLRnuzbULZ42L7BWWPMmruzwtLhJfpDVoZLjNBxHDi2sY2bgZXCKlpU5XcsMFoYrsQmPhfZg== @@ -1234,7 +1469,7 @@ resolved "https://registry.npmjs.org/@vue-flow/controls/-/controls-1.1.1.tgz" integrity sha512-TCoRD5aYZQsM/N7QlPJcIILg1Gxm0O/zoUikxaeadcom1OlKFHutY72agsySJEWM6fTlyb7w8DYCbB4T8YbFoQ== -"@vue-flow/core@^1.23.0", "@vue-flow/core@^1.33.4": +"@vue-flow/core@^1.33.4": version "1.33.5" resolved "https://registry.npmjs.org/@vue-flow/core/-/core-1.33.5.tgz" integrity sha512-Obo+KHmcww/NYGARMqVH1dhd42QeFzV+TNwytrjVgYCoMVCNjs/blCh437TYTsNy4vgX1NKpNwTbQrS+keurgA== @@ -1263,7 +1498,7 @@ estree-walker "^2.0.2" source-map-js "^1.0.2" -"@vue/compiler-dom@^3.3.0", "@vue/compiler-dom@3.4.21": +"@vue/compiler-dom@3.4.21", "@vue/compiler-dom@^3.3.0": version "3.4.21" resolved "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.21.tgz" integrity sha512-IZC6FKowtT1sl0CR5DpXSiEB5ayw75oT2bma1BEhV7RRR1+cfwLrxc2Z8Zq/RGFzJ8w5r9QtCOvTjQgdn0IKmA== @@ -1346,7 +1581,7 @@ "@vue/compiler-ssr" "3.4.21" "@vue/shared" "3.4.21" -"@vue/shared@^3.3.0", "@vue/shared@3.4.21": +"@vue/shared@3.4.21", "@vue/shared@^3.3.0": version "3.4.21" resolved "https://registry.npmjs.org/@vue/shared/-/shared-3.4.21.tgz" integrity sha512-PuJe7vDIi6VYSinuEbUIQgMIRZGgM8e4R+G+/dQTk0X1NEdvgvvgv7m+rfmDH1gZzyA1OjjoWskvHlfRNfQf3g== @@ -1366,7 +1601,7 @@ resolved "https://registry.npmjs.org/@vueuse/metadata/-/metadata-10.9.0.tgz" integrity sha512-iddNbg3yZM0X7qFY2sAotomgdHK7YJ6sKUvQqbvwnf7TmaVPxS4EJydcNsVejNdS8iWCtDk+fYXr7E32nyTnGA== -"@vueuse/shared@^10.5.0", "@vueuse/shared@10.9.0": +"@vueuse/shared@10.9.0", "@vueuse/shared@^10.5.0": version "10.9.0" resolved "https://registry.npmjs.org/@vueuse/shared/-/shared-10.9.0.tgz" integrity sha512-Uud2IWncmAfJvRaFYzv5OHDli+FbOzxiVEQdLCKQKLyhz94PIyFC3CHcH7EDMwIn8NPtD06+PNbC/PiO0LGLtw== @@ -1378,12 +1613,12 @@ abs-svg-path@~0.1.1: resolved "https://registry.npmjs.org/abs-svg-path/-/abs-svg-path-0.1.1.tgz" integrity sha512-d8XPSGjfyzlXC3Xx891DJRyZfqk5JU0BJrDQcsWomFIV1/BIzPW5HDH5iDdWpqWaav0YVIEzT1RHTwWr0FFshA== -ace-builds@*, ace-builds@^1.32.7: +ace-builds@^1.32.7: version "1.32.9" resolved "https://registry.npmjs.org/ace-builds/-/ace-builds-1.32.9.tgz" integrity sha512-dqBLPj//Gq0b92YUtRIsdWsORf4J+4xW3r8/4Wr2Vqid7O1j7YBV/ZsVvWBjZFy+EnvMCRFCFOEIM1cbt4BQ/g== -ag-grid-community@^31.2.0, ag-grid-community@31.2.1: +ag-grid-community@31.2.1, ag-grid-community@^31.2.0: version "31.2.1" resolved "https://registry.npmjs.org/ag-grid-community/-/ag-grid-community-31.2.1.tgz" integrity sha512-D+gnUQ4dHZ/EQJmupQnDqcEKiCEeuK5ZxlsIpdPKgHg/23dmW+aEdivtB9nLpSc2IEK0RUpchcSxeUT37Boo5A== @@ -1396,11 +1631,6 @@ ag-grid-vue3@^31.2.0: ag-grid-community "31.2.1" vue "^3.0.0" -ansi_up@^6.0.2: - version "6.0.2" - resolved "https://registry.npmjs.org/ansi_up/-/ansi_up-6.0.2.tgz" - integrity sha512-3G3vKvl1ilEp7J1u6BmULpMA0xVoW/f4Ekqhl8RTrJrhEBkonKn5k3bUc5Xt+qDayA6iDX0jyUh3AbZjB/l0tw== - ansi-regex@^5.0.1: version "5.0.1" resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz" @@ -1423,6 +1653,11 @@ ansi-styles@^6.1.0: resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz" integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== +ansi_up@^6.0.2: + version "6.0.2" + resolved "https://registry.npmjs.org/ansi_up/-/ansi_up-6.0.2.tgz" + integrity sha512-3G3vKvl1ilEp7J1u6BmULpMA0xVoW/f4Ekqhl8RTrJrhEBkonKn5k3bUc5Xt+qDayA6iDX0jyUh3AbZjB/l0tw== + any-promise@^1.0.0: version "1.3.0" resolved "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz" @@ -1518,7 +1753,7 @@ braces@^3.0.2, braces@~3.0.2: dependencies: fill-range "^7.0.1" -browserslist@^4.23.0, "browserslist@>= 4.21.0": +browserslist@^4.23.0: version "4.23.0" resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz" integrity sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ== @@ -1574,16 +1809,16 @@ clipboard@^2.0.6: select "^1.1.2" tiny-emitter "^2.0.0" -clsx@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/clsx/-/clsx-2.1.0.tgz" - integrity sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg== - clsx@2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/clsx/-/clsx-2.0.0.tgz" integrity sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q== +clsx@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/clsx/-/clsx-2.1.0.tgz" + integrity sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg== + codemirror@^6.0.1: version "6.0.1" resolved "https://registry.npmjs.org/codemirror/-/codemirror-6.0.1.tgz" @@ -1597,7 +1832,7 @@ codemirror@^6.0.1: "@codemirror/state" "^6.0.0" "@codemirror/view" "^6.0.0" -color-convert@^2.0.1, color-convert@2.0.1: +color-convert@2.0.1, color-convert@^2.0.1: version "2.0.1" resolved "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz" integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== @@ -1616,7 +1851,7 @@ combined-stream@^1.0.8: dependencies: delayed-stream "~1.0.0" -commander@^2.20.3, commander@2: +commander@2, commander@^2.20.3: version "2.20.3" resolved "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== @@ -1716,7 +1951,7 @@ d3-array@1: resolved "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz" integrity sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg== -d3-drag@^3.0.0, "d3-drag@2 - 3": +"d3-drag@2 - 3", d3-drag@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz" integrity sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg== @@ -1762,7 +1997,7 @@ d3-hierarchy@^3.1.1: dependencies: d3-color "1 - 3" -d3-selection@^3.0.0, "d3-selection@2 - 3", d3-selection@3: +"d3-selection@2 - 3", d3-selection@3, d3-selection@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz" integrity sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ== @@ -1869,7 +2104,7 @@ embla-carousel-vue@^8.0.2: embla-carousel "8.0.2" embla-carousel-reactive-utils "8.0.2" -embla-carousel@^8.0.2, embla-carousel@8.0.2: +embla-carousel@8.0.2, embla-carousel@^8.0.2: version "8.0.2" resolved "https://registry.npmjs.org/embla-carousel/-/embla-carousel-8.0.2.tgz" integrity sha512-bogsDO8xosuh/l3PxIvA5AMl3+BnRVAse9sDW/60amzj4MbGS5re4WH5eVEXiuH8G1/3G7QUAX2QNr3Yx8z5rA== @@ -2154,7 +2389,7 @@ is-number@^7.0.0: resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== -isarray@~0.0.1, isarray@0.0.1: +isarray@0.0.1, isarray@~0.0.1: version "0.0.1" resolved "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz" integrity sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ== @@ -2266,7 +2501,7 @@ markdown-it-xss@^1.0.2: dependencies: xss "^1.0.6" -markdown-it@*, markdown-it@^14.0.0: +markdown-it@^14.0.0: version "14.1.0" resolved "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz" integrity sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg== @@ -2428,7 +2663,7 @@ path-browserify@^1.0.1: resolved "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz" integrity sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g== -path-data-parser@^0.1.0, path-data-parser@0.1.0: +path-data-parser@0.1.0, path-data-parser@^0.1.0: version "0.1.0" resolved "https://registry.npmjs.org/path-data-parser/-/path-data-parser-0.1.0.tgz" integrity sha512-NOnmBpt5Y2RWbuv0LMzsayp3lVylAHLPUTut412ZA3l+C4uw4ZVkQbjShYCQ8TCpUMdPapr4YjUqLYD6v68j+w== @@ -2496,7 +2731,7 @@ point-at-length@^1.1.0: isarray "~0.0.1" parse-svg-path "~0.1.1" -points-on-curve@^0.2.0, points-on-curve@0.2.0: +points-on-curve@0.2.0, points-on-curve@^0.2.0: version "0.2.0" resolved "https://registry.npmjs.org/points-on-curve/-/points-on-curve-0.2.0.tgz" integrity sha512-0mYKnYYe9ZcqMCWhUjItv/oHjvgEsfKvnUTg8sAtnHr3GVy7rGkXCb6d5cSyqrWqL4k81b9CPg3urd+T7aop3A== @@ -2558,7 +2793,7 @@ postcss-value-parser@^4.0.0, postcss-value-parser@^4.2.0: resolved "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz" integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== -postcss@^8.0.0, postcss@^8.1.0, postcss@^8.2.14, postcss@^8.4.21, postcss@^8.4.23, postcss@^8.4.35, postcss@^8.4.38, postcss@>=8.0.9: +postcss@^8.4.23, postcss@^8.4.35, postcss@^8.4.38: version "8.4.38" resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz" integrity sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A== @@ -2807,28 +3042,7 @@ stream-source@0.3: resolved "https://registry.npmjs.org/stream-source/-/stream-source-0.3.5.tgz" integrity sha512-ZuEDP9sgjiAwUVoDModftG0JtYiLUV8K4ljYD1VyUMRWtbVf92474o4kuuul43iZ8t/hRuiDAx1dIJSvirrK/g== -string_decoder@^1.1.1: - version "1.3.0" - resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz" - integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== - dependencies: - safe-buffer "~5.2.0" - -string_decoder@~0.10.x: - version "0.10.31" - resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz" - integrity sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ== - -"string-width-cjs@npm:string-width@^4.2.0": - version "4.2.3" - resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -string-width@^4.1.0: +"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0: version "4.2.3" resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -2846,14 +3060,19 @@ string-width@^5.0.1, string-width@^5.1.2: emoji-regex "^9.2.2" strip-ansi "^7.0.1" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1": - version "6.0.1" - resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== dependencies: - ansi-regex "^5.0.1" + safe-buffer "~5.2.0" -strip-ansi@^6.0.0, strip-ansi@^6.0.1: +string_decoder@~0.10.x: + version "0.10.31" + resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz" + integrity sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ== + +"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -2902,7 +3121,7 @@ tailwindcss-animate@^1.0.7: resolved "https://registry.npmjs.org/tailwindcss-animate/-/tailwindcss-animate-1.0.7.tgz" integrity sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA== -tailwindcss@^3.4.1, "tailwindcss@>=3.0.0 || insiders": +tailwindcss@^3.4.1: version "3.4.3" resolved "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.3.tgz" integrity sha512-U7sxQk/n397Bmx4JHbJx/iSOOv5G+II3f1kpLpY2QeUv5DcPdcTsYLlusZfq1NthHS1c1cZoyFmmkex1rzke0A== @@ -3017,7 +3236,7 @@ typedarray@~0.0.5: resolved "https://registry.npmjs.org/typedarray/-/typedarray-0.0.7.tgz" integrity sha512-ueeb9YybpjhivjbHP2LdFDAjbS948fGEPj+ACAMs4xCMmh72OCOMQWBQKlaN4ZNQ04yfLSDLSx1tGRIoWimObQ== -typescript@*, typescript@^5.2.2: +typescript@^5.2.2: version "5.4.5" resolved "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz" integrity sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ== @@ -3069,7 +3288,7 @@ vaul-vue@^0.1.0: radix-vue "^1.4.9" vue "^3.4.5" -vee-validate@^4.12.6, vee-validate@4.12.6: +vee-validate@4.12.6, vee-validate@^4.12.6: version "4.12.6" resolved "https://registry.npmjs.org/vee-validate/-/vee-validate-4.12.6.tgz" integrity sha512-EKM3YHy8t1miPh30d5X6xOrfG/Ctq0nbN4eMpCK7ezvI6T98/S66vswP+ihL4QqAK/k5KqreWOxof09+JG7N/A== @@ -3096,7 +3315,7 @@ view-ui-plus@^1.3.16: tinycolor2 "^1.4.1" v-click-outside-x "^3.7.1" -vite@^5.0.0, vite@^5.1.6: +vite@^5.1.6: version "5.2.8" resolved "https://registry.npmjs.org/vite/-/vite-5.2.8.tgz" integrity sha512-OyZR+c1CE8yeHw5V5t59aXsUPPVTHMDjEZz8MgguLL/Q7NblxhZUlTu9xSPqlsUO/y+X7dlU05jdhvyycD55DA== @@ -3152,17 +3371,6 @@ vue-tsc@^1.8.27: "@vue/language-core" "1.8.27" semver "^7.5.4" -"vue@^2.7.0 || ^3.0.0", vue@^3, vue@^3.0.0, "vue@^3.0.0-0 || ^2.6.0", vue@^3.0.1, vue@^3.2.0, vue@^3.2.25, vue@^3.2.29, vue@^3.2.37, vue@^3.2.47, vue@^3.3.0, vue@^3.3.11, vue@^3.4.21, vue@^3.4.5, "vue@>= 3", "vue@>= 3.0.0 < 4", "vue@>= 3.2.0", vue@>=3.0.1, vue@>=3.2, vue@3, vue@3.4.21: - version "3.4.21" - resolved "https://registry.npmjs.org/vue/-/vue-3.4.21.tgz" - integrity sha512-5hjyV/jLEIKD/jYl4cavMcnzKwjMKohureP8ejn3hhEjwhWIhWeuzL2kJAjzl/WyVsgPY56Sy4Z40C3lVshxXA== - dependencies: - "@vue/compiler-dom" "3.4.21" - "@vue/compiler-sfc" "3.4.21" - "@vue/runtime-dom" "3.4.21" - "@vue/server-renderer" "3.4.21" - "@vue/shared" "3.4.21" - vue3-ace-editor@^2.2.4: version "2.2.4" resolved "https://registry.npmjs.org/vue3-ace-editor/-/vue3-ace-editor-2.2.4.tgz" @@ -3192,6 +3400,17 @@ vue3-grid-layout-next@^1.0.6: interactjs "^1.10.17" mitt "^3.0.0" +vue@3, vue@^3.0.0, vue@^3.4.21, vue@^3.4.5: + version "3.4.21" + resolved "https://registry.npmjs.org/vue/-/vue-3.4.21.tgz" + integrity sha512-5hjyV/jLEIKD/jYl4cavMcnzKwjMKohureP8ejn3hhEjwhWIhWeuzL2kJAjzl/WyVsgPY56Sy4Z40C3lVshxXA== + dependencies: + "@vue/compiler-dom" "3.4.21" + "@vue/compiler-sfc" "3.4.21" + "@vue/runtime-dom" "3.4.21" + "@vue/server-renderer" "3.4.21" + "@vue/shared" "3.4.21" + vuedraggable@^4.1.0: version "4.1.0" resolved "https://registry.npmjs.org/vuedraggable/-/vuedraggable-4.1.0.tgz" diff --git a/fs/datacap-fs-local/src/main/java/io/edurt/datacap/fs/IOUtils.java b/fs/datacap-fs-local/src/main/java/io/edurt/datacap/fs/IOUtils.java index 73b79f21..39346180 100644 --- a/fs/datacap-fs-local/src/main/java/io/edurt/datacap/fs/IOUtils.java +++ b/fs/datacap-fs-local/src/main/java/io/edurt/datacap/fs/IOUtils.java @@ -1,5 +1,6 @@ package io.edurt.datacap.fs; +import java.io.IOException; import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; @@ -46,6 +47,7 @@ public class IOUtils * @return true if the contents were successfully copied, false otherwise */ public static boolean copy(InputStream stream, String target, boolean createdDir) + throws IOException { try { Path targetPath = Paths.get(target); @@ -59,6 +61,11 @@ public class IOUtils catch (Exception e) { throw new RuntimeException(e); } + finally { + if (stream != null) { + stream.close(); + } + } } /** From 2ecf43498c52464f12933502cbccb0771b555234 Mon Sep 17 00:00:00 2001 From: qianmoQ Date: Wed, 22 May 2024 21:46:20 +0800 Subject: [PATCH 2/5] [Core] [Role] Fixed setting multiple permissions will cause repetitive problems in menu display (close #766) --- .../controller/admin/RoleController.java | 54 ++++++++++--------- .../datacap/service/entity/MenuEntity.java | 2 + 2 files changed, 32 insertions(+), 24 deletions(-) diff --git a/core/datacap-server/src/main/java/io/edurt/datacap/server/controller/admin/RoleController.java b/core/datacap-server/src/main/java/io/edurt/datacap/server/controller/admin/RoleController.java index 5a9a9e38..0e8dbcf8 100644 --- a/core/datacap-server/src/main/java/io/edurt/datacap/server/controller/admin/RoleController.java +++ b/core/datacap-server/src/main/java/io/edurt/datacap/server/controller/admin/RoleController.java @@ -1,5 +1,6 @@ package io.edurt.datacap.server.controller.admin; +import com.google.common.collect.Sets; import io.edurt.datacap.common.response.CommonResponse; import io.edurt.datacap.service.body.FilterBody; import io.edurt.datacap.service.entity.MenuEntity; @@ -19,9 +20,7 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; -import java.util.HashSet; import java.util.List; -import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; @@ -64,31 +63,38 @@ public class RoleController return roleService.getMenusByRoleId(id); } else { - Optional optionalRole = this.roleRepository.findById(id); - RoleEntity role = optionalRole.get(); - Set menus = new HashSet<>(); - extractIds(nodes).forEach(nodeId -> { - MenuEntity entity = new MenuEntity(); - entity.setId(nodeId); - menus.add(entity); - }); - role.setMenus(menus); - return roleService.saveOrUpdate(roleRepository, role); + return this.roleRepository.findById(id) + .map(item -> { + Set menus = extractIds(nodes, Sets.newHashSet()).stream() + .map(value -> { + MenuEntity entity = new MenuEntity(); + entity.setId(value); + return entity; + }) + .collect(Collectors.toSet()); + item.setMenus(menus); + return roleService.saveOrUpdate(roleRepository, item); + }) + .orElse(CommonResponse.failure(String.format("Role [ %s ] not found", id))); } } - private static Set extractIds(List nodes) + /** + * Extracts the IDs from a list of TreeRecord objects and adds them to a set. + * + * @param nodes the list of TreeRecord objects to extract IDs from + * @param idSet the set to add the extracted IDs to + * @return the set of extracted IDs + */ + private static Set extractIds(List nodes, Set idSet) { - return nodes.stream() - .flatMap(node -> { - Set idSet = new HashSet<>(); - idSet.add(node.getId()); - List childrenList = node.getChildren(); - if (ObjectUtils.isNotEmpty(childrenList)) { - idSet.addAll(extractIds(childrenList)); - } - return idSet.stream(); - }) - .collect(Collectors.toSet()); + for (TreeRecord node : nodes) { + idSet.add(node.getId()); + List childrenList = node.getChildren(); + if (ObjectUtils.isNotEmpty(childrenList)) { + extractIds(childrenList, idSet); + } + } + return idSet; } } diff --git a/core/datacap-service/src/main/java/io/edurt/datacap/service/entity/MenuEntity.java b/core/datacap-service/src/main/java/io/edurt/datacap/service/entity/MenuEntity.java index 72628cca..1562f641 100644 --- a/core/datacap-service/src/main/java/io/edurt/datacap/service/entity/MenuEntity.java +++ b/core/datacap-service/src/main/java/io/edurt/datacap/service/entity/MenuEntity.java @@ -3,6 +3,7 @@ package io.edurt.datacap.service.entity; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import io.edurt.datacap.common.enums.MenuEnum; import lombok.Data; +import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import lombok.ToString; @@ -17,6 +18,7 @@ import javax.persistence.Table; @NoArgsConstructor @Entity @Table(name = "datacap_menu") +@EqualsAndHashCode(callSuper = true) @SuppressFBWarnings(value = {"EI_EXPOSE_REP", "RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE", "EQ_OVERRIDING_EQUALS_NOT_SYMMETRIC"}, justification = "I prefer to suppress these FindBugs warnings") public class MenuEntity From 91493d828653367e49844a655ceb42bdb9805613 Mon Sep 17 00:00:00 2001 From: qianmoQ Date: Wed, 22 May 2024 23:35:33 +0800 Subject: [PATCH 3/5] [Core] Support upload file --- configure/schema/2024.03.5/schema.sql | 9 ++ .../server/controller/UploadController.java | 27 +++++ .../datacap/service/body/UploadBody.java | 22 ++++ .../service/converter/AvatarConverter.java | 26 ++++ .../service/entity/DashboardEntity.java | 7 ++ .../service/entity/convert/AvatarEntity.java | 18 +++ .../datacap/service/enums/UploadMode.java | 6 + .../service/service/UploadService.java | 9 ++ .../service/impl/UploadServiceImpl.java | 112 ++++++++++++++++++ core/datacap-ui/src/services/upload.ts | 14 +++ 10 files changed, 250 insertions(+) create mode 100644 configure/schema/2024.03.5/schema.sql create mode 100644 core/datacap-server/src/main/java/io/edurt/datacap/server/controller/UploadController.java create mode 100644 core/datacap-service/src/main/java/io/edurt/datacap/service/body/UploadBody.java create mode 100644 core/datacap-service/src/main/java/io/edurt/datacap/service/converter/AvatarConverter.java create mode 100644 core/datacap-service/src/main/java/io/edurt/datacap/service/entity/convert/AvatarEntity.java create mode 100644 core/datacap-service/src/main/java/io/edurt/datacap/service/enums/UploadMode.java create mode 100644 core/datacap-service/src/main/java/io/edurt/datacap/service/service/UploadService.java create mode 100644 core/datacap-service/src/main/java/io/edurt/datacap/service/service/impl/UploadServiceImpl.java create mode 100644 core/datacap-ui/src/services/upload.ts diff --git a/configure/schema/2024.03.5/schema.sql b/configure/schema/2024.03.5/schema.sql new file mode 100644 index 00000000..0d933b99 --- /dev/null +++ b/configure/schema/2024.03.5/schema.sql @@ -0,0 +1,9 @@ +# +If you are upgrading to 2024.03.4 from a different version, execute the following SQL statement +# Если вы обновляетесь до версии 2024.03.4 с другой версии, выполните следующую инструкцию SQL +# 如果您是通过其他版本升级到 2024.03.4, 请执行以下 SQL 语句 + +USE `datacap`; + +ALTER TABLE `datacap_dashboard` + ADD COLUMN `avatar` TEXT DEFAULT NULL; diff --git a/core/datacap-server/src/main/java/io/edurt/datacap/server/controller/UploadController.java b/core/datacap-server/src/main/java/io/edurt/datacap/server/controller/UploadController.java new file mode 100644 index 00000000..9ff58ee0 --- /dev/null +++ b/core/datacap-server/src/main/java/io/edurt/datacap/server/controller/UploadController.java @@ -0,0 +1,27 @@ +package io.edurt.datacap.server.controller; + +import io.edurt.datacap.common.response.CommonResponse; +import io.edurt.datacap.service.body.UploadBody; +import io.edurt.datacap.service.service.UploadService; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController(value = "uploadController") +@RequestMapping(value = "/api/v1/upload") +public class UploadController +{ + private final UploadService service; + + public UploadController(UploadService service) + { + this.service = service; + } + + @PostMapping + public CommonResponse upload(@ModelAttribute UploadBody configure) + { + return service.upload(configure); + } +} diff --git a/core/datacap-service/src/main/java/io/edurt/datacap/service/body/UploadBody.java b/core/datacap-service/src/main/java/io/edurt/datacap/service/body/UploadBody.java new file mode 100644 index 00000000..b96071a1 --- /dev/null +++ b/core/datacap-service/src/main/java/io/edurt/datacap/service/body/UploadBody.java @@ -0,0 +1,22 @@ +package io.edurt.datacap.service.body; + +import io.edurt.datacap.service.enums.UploadMode; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.ToString; +import org.springframework.web.multipart.MultipartFile; + +@Data +@Builder +@ToString +@NoArgsConstructor +@AllArgsConstructor +public class UploadBody +{ + private Long id; + private String code; + private UploadMode mode; + private MultipartFile file; +} diff --git a/core/datacap-service/src/main/java/io/edurt/datacap/service/converter/AvatarConverter.java b/core/datacap-service/src/main/java/io/edurt/datacap/service/converter/AvatarConverter.java new file mode 100644 index 00000000..c9f2fed7 --- /dev/null +++ b/core/datacap-service/src/main/java/io/edurt/datacap/service/converter/AvatarConverter.java @@ -0,0 +1,26 @@ +package io.edurt.datacap.service.converter; + +import io.edurt.datacap.common.utils.JsonUtils; +import io.edurt.datacap.service.entity.convert.AvatarEntity; +import org.apache.commons.lang3.StringUtils; + +import javax.persistence.AttributeConverter; + +public class AvatarConverter + implements AttributeConverter +{ + @Override + public String convertToDatabaseColumn(AvatarEntity entity) + { + return JsonUtils.toJSON(entity); + } + + @Override + public AvatarEntity convertToEntityAttribute(String s) + { + if (StringUtils.isEmpty(s)) { + return null; + } + return JsonUtils.toObject(s, AvatarEntity.class); + } +} diff --git a/core/datacap-service/src/main/java/io/edurt/datacap/service/entity/DashboardEntity.java b/core/datacap-service/src/main/java/io/edurt/datacap/service/entity/DashboardEntity.java index 79217a78..c2a69bb6 100644 --- a/core/datacap-service/src/main/java/io/edurt/datacap/service/entity/DashboardEntity.java +++ b/core/datacap-service/src/main/java/io/edurt/datacap/service/entity/DashboardEntity.java @@ -2,6 +2,8 @@ package io.edurt.datacap.service.entity; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; +import io.edurt.datacap.service.converter.AvatarConverter; +import io.edurt.datacap.service.entity.convert.AvatarEntity; import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; @@ -11,6 +13,7 @@ import lombok.experimental.SuperBuilder; import org.springframework.data.jpa.domain.support.AuditingEntityListener; import javax.persistence.Column; +import javax.persistence.Convert; import javax.persistence.Entity; import javax.persistence.EntityListeners; import javax.persistence.JoinColumn; @@ -40,6 +43,10 @@ public class DashboardEntity @Column(name = "description") private String description; + @Column(name = "avatar") + @Convert(converter = AvatarConverter.class) + private AvatarEntity avatar; + @ManyToOne @JoinTable(name = "datacap_dashboard_user_relation", joinColumns = @JoinColumn(name = "dashboard_id"), diff --git a/core/datacap-service/src/main/java/io/edurt/datacap/service/entity/convert/AvatarEntity.java b/core/datacap-service/src/main/java/io/edurt/datacap/service/entity/convert/AvatarEntity.java new file mode 100644 index 00000000..6921e7b7 --- /dev/null +++ b/core/datacap-service/src/main/java/io/edurt/datacap/service/entity/convert/AvatarEntity.java @@ -0,0 +1,18 @@ +package io.edurt.datacap.service.entity.convert; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.ToString; + +@Data +@Builder +@ToString +@NoArgsConstructor +@AllArgsConstructor +public class AvatarEntity +{ + private String type; + private String path; +} diff --git a/core/datacap-service/src/main/java/io/edurt/datacap/service/enums/UploadMode.java b/core/datacap-service/src/main/java/io/edurt/datacap/service/enums/UploadMode.java new file mode 100644 index 00000000..beafec52 --- /dev/null +++ b/core/datacap-service/src/main/java/io/edurt/datacap/service/enums/UploadMode.java @@ -0,0 +1,6 @@ +package io.edurt.datacap.service.enums; + +public enum UploadMode +{ + DASHBOARD +} diff --git a/core/datacap-service/src/main/java/io/edurt/datacap/service/service/UploadService.java b/core/datacap-service/src/main/java/io/edurt/datacap/service/service/UploadService.java new file mode 100644 index 00000000..2ffb5157 --- /dev/null +++ b/core/datacap-service/src/main/java/io/edurt/datacap/service/service/UploadService.java @@ -0,0 +1,9 @@ +package io.edurt.datacap.service.service; + +import io.edurt.datacap.common.response.CommonResponse; +import io.edurt.datacap.service.body.UploadBody; + +public interface UploadService +{ + CommonResponse upload(UploadBody configure); +} diff --git a/core/datacap-service/src/main/java/io/edurt/datacap/service/service/impl/UploadServiceImpl.java b/core/datacap-service/src/main/java/io/edurt/datacap/service/service/impl/UploadServiceImpl.java new file mode 100644 index 00000000..bb1c43c1 --- /dev/null +++ b/core/datacap-service/src/main/java/io/edurt/datacap/service/service/impl/UploadServiceImpl.java @@ -0,0 +1,112 @@ +package io.edurt.datacap.service.service.impl; + +import com.google.inject.Injector; +import io.edurt.datacap.common.response.CommonResponse; +import io.edurt.datacap.common.utils.SpiUtils; +import io.edurt.datacap.fs.FsRequest; +import io.edurt.datacap.fs.FsResponse; +import io.edurt.datacap.service.body.UploadBody; +import io.edurt.datacap.service.entity.convert.AvatarEntity; +import io.edurt.datacap.service.enums.UploadMode; +import io.edurt.datacap.service.initializer.InitializerConfigure; +import io.edurt.datacap.service.repository.DashboardRepository; +import io.edurt.datacap.service.security.UserDetailsService; +import io.edurt.datacap.service.service.UploadService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import java.io.IOException; + +@Slf4j +@Service +public class UploadServiceImpl + implements UploadService +{ + private final Injector injector; + private final DashboardRepository dashboard; + private final InitializerConfigure initializer; + + public UploadServiceImpl(Injector injector, DashboardRepository dashboard, InitializerConfigure initializer) + { + this.injector = injector; + this.dashboard = dashboard; + this.initializer = initializer; + } + + @Override + public CommonResponse upload(UploadBody configure) + { + if (configure.getMode().equals(UploadMode.DASHBOARD)) { + return dashboard.findByCode(configure.getCode()) + .map(value -> { + try { + FsRequest fsRequest = getFsRequest(configure.getFile(), configure); + SpiUtils.findFs(injector, initializer.getFsConfigure().getType()) + .ifPresent(fs -> { + FsResponse response = fs.writer(fsRequest); + AvatarEntity entity = AvatarEntity.builder() + .path(response.getRemote()) + .type(initializer.getFsConfigure().getType()) + .build(); + value.setAvatar(entity); + dashboard.save(value); + }); + } + catch (IOException e) { + log.error("Failed to upload file [ {} ]", configure.getCode(), e); + return CommonResponse.failure(e.getMessage()); + } + finally { + try { + configure.getFile().getInputStream().close(); + } + catch (IOException e) { + log.warn("Failed to close input stream", e); + } + return CommonResponse.success(value); + } + }) + .orElseGet(() -> CommonResponse.failure(String.format("Dashboard [ %s ] not found", configure.getCode()))); + } + return CommonResponse.failure(String.format("Mode [ %s ] not supported", configure.getMode())); + } + + /** + * Generates a FsRequest object based on the given MultipartFile and UploadBody. + * + * @param file the MultipartFile object containing the file data + * @param configure the UploadBody object containing the configuration + * @return the generated FsRequest object + * @throws IOException if there is an error reading the file input stream + */ + private FsRequest getFsRequest(MultipartFile file, UploadBody configure) + throws IOException + { + return FsRequest.builder() + .access(initializer.getFsConfigure().getAccess()) + .secret(initializer.getFsConfigure().getSecret()) + .endpoint(getHome(configure)) + .bucket(initializer.getFsConfigure().getBucket()) + .stream(file.getInputStream()) + .fileName("avatar.png") + .build(); + } + + /** + * Returns the home directory path based on the given configuration. + * + * @param configure the upload configuration containing the mode and code + * @return the home directory path + */ + private String getHome(UploadBody configure) + { + if (!initializer.getFsConfigure().getType().equals("Local")) { + return initializer.getFsConfigure().getEndpoint(); + } + return String.join("/", initializer.getDataHome(), + UserDetailsService.getUser().getUsername(), + configure.getMode().toString().toLowerCase(), + configure.getCode()); + } +} diff --git a/core/datacap-ui/src/services/upload.ts b/core/datacap-ui/src/services/upload.ts new file mode 100644 index 00000000..652e4d1d --- /dev/null +++ b/core/datacap-ui/src/services/upload.ts @@ -0,0 +1,14 @@ +import { BaseService } from '@/services/base.ts' + +const DEFAULT_PATH = '/api/v1/upload' + +class UploadService + extends BaseService +{ + constructor() + { + super(DEFAULT_PATH) + } +} + +export default new UploadService() From b0cdc46433e90425e1460c23178a9a90737eced6 Mon Sep 17 00:00:00 2001 From: qianmoQ Date: Thu, 23 May 2024 00:15:48 +0800 Subject: [PATCH 4/5] [Core] Support preview images --- .../edurt/datacap/common/utils/UrlUtils.java | 19 ++++++++++++++ .../datacap/security/SecurityConfigure.java | 2 +- .../datacap/security/WebAppConfigure.java | 25 +++++++++++++++++++ .../service/impl/UploadServiceImpl.java | 24 +++++++++++++++++- core/datacap-ui/src/model/avatar.ts | 5 ++++ core/datacap-ui/src/model/dashboard.ts | 2 ++ .../pages/admin/dashboard/DashboardHome.vue | 2 +- 7 files changed, 76 insertions(+), 3 deletions(-) create mode 100644 core/datacap-common/src/main/java/io/edurt/datacap/common/utils/UrlUtils.java create mode 100644 core/datacap-security/src/main/java/io/edurt/datacap/security/WebAppConfigure.java create mode 100644 core/datacap-ui/src/model/avatar.ts diff --git a/core/datacap-common/src/main/java/io/edurt/datacap/common/utils/UrlUtils.java b/core/datacap-common/src/main/java/io/edurt/datacap/common/utils/UrlUtils.java new file mode 100644 index 00000000..74aee6d5 --- /dev/null +++ b/core/datacap-common/src/main/java/io/edurt/datacap/common/utils/UrlUtils.java @@ -0,0 +1,19 @@ +package io.edurt.datacap.common.utils; + +public class UrlUtils +{ + private UrlUtils() + { + } + + /** + * Replaces multiple consecutive slashes in the given URL with a single slash. + * + * @param url the URL to fix + * @return the fixed URL with single slashes + */ + public static String fixUrl(String url) + { + return url.replaceAll("/+", "/"); + } +} diff --git a/core/datacap-security/src/main/java/io/edurt/datacap/security/SecurityConfigure.java b/core/datacap-security/src/main/java/io/edurt/datacap/security/SecurityConfigure.java index af56e6a3..c2f457b5 100644 --- a/core/datacap-security/src/main/java/io/edurt/datacap/security/SecurityConfigure.java +++ b/core/datacap-security/src/main/java/io/edurt/datacap/security/SecurityConfigure.java @@ -68,7 +68,7 @@ public class SecurityConfigure .exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and() .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and() .authorizeRequests() - .antMatchers("/", "/**/*.js", "/**/*.css", "/api/auth/**", "/fonts/**", "/static/**", "/h2-console/**", "/api/v1/captcha", "/api/v1/table/dataDownload/**") + .antMatchers("/", "/**/*.js", "/**/*.css", "/api/auth/**", "/fonts/**", "/static/**", "/h2-console/**", "/api/v1/captcha", "/api/v1/table/dataDownload/**", "/upload/**") .permitAll() .anyRequest() .authenticated(); diff --git a/core/datacap-security/src/main/java/io/edurt/datacap/security/WebAppConfigure.java b/core/datacap-security/src/main/java/io/edurt/datacap/security/WebAppConfigure.java new file mode 100644 index 00000000..56dadc33 --- /dev/null +++ b/core/datacap-security/src/main/java/io/edurt/datacap/security/WebAppConfigure.java @@ -0,0 +1,25 @@ +package io.edurt.datacap.security; + +import io.edurt.datacap.service.initializer.InitializerConfigure; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +@Configuration +public class WebAppConfigure + implements WebMvcConfigurer +{ + private final InitializerConfigure initializer; + + public WebAppConfigure(InitializerConfigure initializer) + { + this.initializer = initializer; + } + + @Override + public void addResourceHandlers(ResourceHandlerRegistry registry) + { + registry.addResourceHandler("/upload/**") + .addResourceLocations("file:" + initializer.getDataHome() + "/"); + } +} diff --git a/core/datacap-service/src/main/java/io/edurt/datacap/service/service/impl/UploadServiceImpl.java b/core/datacap-service/src/main/java/io/edurt/datacap/service/service/impl/UploadServiceImpl.java index bb1c43c1..f0e74af7 100644 --- a/core/datacap-service/src/main/java/io/edurt/datacap/service/service/impl/UploadServiceImpl.java +++ b/core/datacap-service/src/main/java/io/edurt/datacap/service/service/impl/UploadServiceImpl.java @@ -3,6 +3,7 @@ package io.edurt.datacap.service.service.impl; import com.google.inject.Injector; import io.edurt.datacap.common.response.CommonResponse; import io.edurt.datacap.common.utils.SpiUtils; +import io.edurt.datacap.common.utils.UrlUtils; import io.edurt.datacap.fs.FsRequest; import io.edurt.datacap.fs.FsResponse; import io.edurt.datacap.service.body.UploadBody; @@ -16,6 +17,8 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; +import javax.servlet.http.HttpServletRequest; + import java.io.IOException; @Slf4j @@ -24,12 +27,14 @@ public class UploadServiceImpl implements UploadService { private final Injector injector; + private final HttpServletRequest request; private final DashboardRepository dashboard; private final InitializerConfigure initializer; - public UploadServiceImpl(Injector injector, DashboardRepository dashboard, InitializerConfigure initializer) + public UploadServiceImpl(Injector injector, HttpServletRequest request, DashboardRepository dashboard, InitializerConfigure initializer) { this.injector = injector; + this.request = request; this.dashboard = dashboard; this.initializer = initializer; } @@ -49,6 +54,9 @@ public class UploadServiceImpl .path(response.getRemote()) .type(initializer.getFsConfigure().getType()) .build(); + if (initializer.getFsConfigure().getType().equals("Local")) { + entity.setPath(getAccess(entity)); + } value.setAvatar(entity); dashboard.save(value); }); @@ -109,4 +117,18 @@ public class UploadServiceImpl configure.getMode().toString().toLowerCase(), configure.getCode()); } + + /** + * Returns the access URL for the given AvatarEntity. + * + * @param configure the AvatarEntity containing the path + * @return the access URL + */ + private String getAccess(AvatarEntity configure) + { + String protocol = request.getScheme(); + String host = request.getServerName(); + int port = request.getServerPort(); + return protocol + "://" + host + ":" + port + UrlUtils.fixUrl("/upload" + configure.getPath().replaceFirst(initializer.getDataHome(), "")); + } } diff --git a/core/datacap-ui/src/model/avatar.ts b/core/datacap-ui/src/model/avatar.ts new file mode 100644 index 00000000..843bce2c --- /dev/null +++ b/core/datacap-ui/src/model/avatar.ts @@ -0,0 +1,5 @@ +export interface AvatarModel +{ + type?: string + path?: string +} diff --git a/core/datacap-ui/src/model/dashboard.ts b/core/datacap-ui/src/model/dashboard.ts index 31feba61..607ba548 100644 --- a/core/datacap-ui/src/model/dashboard.ts +++ b/core/datacap-ui/src/model/dashboard.ts @@ -1,5 +1,6 @@ import { UserModel } from '@/model/user.ts' import { ReportModel } from '@/model/report.ts' +import { AvatarModel } from '@/model/avatar.ts' export interface DashboardModel { @@ -13,6 +14,7 @@ export interface DashboardModel user?: UserModel reports?: ReportModel[] code?: string + avatar?: AvatarModel } export class DashboardRequest diff --git a/core/datacap-ui/src/views/pages/admin/dashboard/DashboardHome.vue b/core/datacap-ui/src/views/pages/admin/dashboard/DashboardHome.vue index 3423e874..f400610b 100644 --- a/core/datacap-ui/src/views/pages/admin/dashboard/DashboardHome.vue +++ b/core/datacap-ui/src/views/pages/admin/dashboard/DashboardHome.vue @@ -45,7 +45,7 @@
- +