From 793efc312a281f2548226808a776e55fdab4f653 Mon Sep 17 00:00:00 2001 From: ulleo Date: Wed, 23 Aug 2023 16:45:25 +0800 Subject: [PATCH] =?UTF-8?q?=E5=90=88=E5=B9=B6=E6=89=A9=E5=B1=95=E6=8F=92?= =?UTF-8?q?=E4=BB=B6=E5=88=B0=E4=B8=BB=E5=B7=A5=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- extensions/.gitignore | 58 + extensions/README.md | 19 + .../dm/.gitignore | 35 + .../dm/build.sh | 6 + .../dm/dm-backend/pom.xml | 109 ++ .../datasource/dm/provider/DmConfig.java | 21 + .../datasource/dm/provider/DmDsProvider.java | 226 +++ .../datasource/dm/query/DmConstants.java | 61 + .../datasource/dm/query/DmQueryProvider.java | 1558 +++++++++++++++ .../datasource/dm/service/DmService.java | 59 + .../dm/dm-frontend/.babelrc | 12 + .../dm/dm-frontend/.gitignore | 14 + .../dm/dm-frontend/README.md | 21 + .../dm-frontend/build/build-async-plugins.js | 35 + .../dm/dm-frontend/build/build.js | 41 + .../dm/dm-frontend/build/check-versions.js | 54 + .../dm/dm-frontend/build/logo.png | Bin 0 -> 6849 bytes .../dm/dm-frontend/build/utils.js | 101 + .../dm/dm-frontend/build/vue-loader.conf.js | 22 + .../build/webpack.async-plugins.js | 91 + .../dm/dm-frontend/build/webpack.base.conf.js | 103 + .../dm/dm-frontend/build/webpack.dev.conf.js | 95 + .../dm/dm-frontend/build/webpack.prod.conf.js | 145 ++ .../dm/dm-frontend/config/dev.env.js | 7 + .../dm/dm-frontend/config/index.js | 69 + .../dm/dm-frontend/config/prod.env.js | 4 + .../dm/dm-frontend/index.html | 12 + .../dm/dm-frontend/package.json | 75 + .../dm/dm-frontend/pom.xml | 80 + .../dm/dm-frontend/src/App.vue | 23 + .../dm/dm-frontend/src/assets/logo.png | Bin 0 -> 6849 bytes .../dm-frontend/src/components/HelloWorld.vue | 113 ++ .../dm/dm-frontend/src/de-base/lang/en.js | 16 + .../dm/dm-frontend/src/de-base/lang/index.js | 49 + .../dm-frontend/src/de-base/lang/messages.js | 17 + .../dm/dm-frontend/src/de-base/lang/tw.js | 16 + .../dm/dm-frontend/src/de-base/lang/zh.js | 21 + .../dm/dm-frontend/src/icons/index.js | 9 + .../src/icons/svg/de_pwd_invisible.svg | 3 + .../src/icons/svg/de_pwd_visible.svg | 3 + .../dm-frontend/src/icons/svg/dm-backend.svg | 1 + .../dm/dm-frontend/src/icons/svg/dm.jpg | Bin 0 -> 52036 bytes .../dm/dm-frontend/src/icons/svgo.yml | 22 + .../dm/dm-frontend/src/main.js | 33 + .../dm/dm-frontend/src/router/index.js | 21 + .../dm/dm-frontend/src/utils/compare.js | 29 + .../dm/dm-frontend/src/utils/validate.js | 15 + .../dm/dm-frontend/src/views/dePwd.vue | 75 + .../dm/dm-frontend/src/views/dm.vue | 202 ++ .../dm/plugin.json | 13 + .../dataease-extensions-datasource/dm/pom.xml | 19 + .../kingbase/build.sh | 6 + .../kingbase/kingbase-backend/pom.xml | 109 ++ .../kingbase/provider/KingbaseConfig.java | 27 + .../kingbase/provider/KingbaseDsProvider.java | 264 +++ .../kingbase/query/KingbaseConstants.java | 60 + .../kingbase/query/KingbaseQueryProvider.java | 1707 +++++++++++++++++ .../kingbase/service/KingbaseService.java | 71 + .../kingbase/kingbase-frontend/.babelrc | 12 + .../kingbase/kingbase-frontend/.gitignore | 14 + .../kingbase/kingbase-frontend/README.md | 21 + .../build/build-async-plugins.js | 35 + .../kingbase/kingbase-frontend/build/build.js | 41 + .../kingbase-frontend/build/check-versions.js | 54 + .../kingbase/kingbase-frontend/build/logo.png | Bin 0 -> 6849 bytes .../kingbase/kingbase-frontend/build/utils.js | 101 + .../build/vue-loader.conf.js | 22 + .../build/webpack.async-plugins.js | 91 + .../build/webpack.base.conf.js | 103 + .../build/webpack.dev.conf.js | 95 + .../build/webpack.prod.conf.js | 145 ++ .../kingbase-frontend/config/dev.env.js | 7 + .../kingbase-frontend/config/index.js | 69 + .../kingbase-frontend/config/prod.env.js | 4 + .../kingbase/kingbase-frontend/index.html | 12 + .../kingbase/kingbase-frontend/package.json | 75 + .../kingbase/kingbase-frontend/pom.xml | 80 + .../kingbase-frontend/postcss.config.js | 5 + .../kingbase/kingbase-frontend/src/App.vue | 23 + .../kingbase-frontend/src/assets/logo.png | Bin 0 -> 6849 bytes .../src/components/HelloWorld.vue | 113 ++ .../kingbase-frontend/src/de-base/lang/en.js | 31 + .../src/de-base/lang/index.js | 49 + .../src/de-base/lang/messages.js | 17 + .../kingbase-frontend/src/de-base/lang/tw.js | 31 + .../kingbase-frontend/src/de-base/lang/zh.js | 31 + .../kingbase-frontend/src/icons/index.js | 9 + .../src/icons/svg/de_pwd_invisible.svg | 3 + .../src/icons/svg/de_pwd_visible.svg | 3 + .../src/icons/svg/kingbase-backend.svg | 1 + .../src/icons/svg/kingbase.jpg | Bin 0 -> 19509 bytes .../kingbase-frontend/src/icons/svgo.yml | 22 + .../kingbase/kingbase-frontend/src/main.js | 33 + .../kingbase-frontend/src/router/index.js | 21 + .../kingbase-frontend/src/utils/compare.js | 29 + .../kingbase-frontend/src/utils/validate.js | 15 + .../kingbase-frontend/src/views/dePwd.vue | 75 + .../kingbase-frontend/src/views/kingbase.vue | 202 ++ .../kingbase/plugin.json | 13 + .../kingbase/pom.xml | 19 + .../kylin/build.sh | 6 + .../kylin/kylin-backend/pom.xml | 108 ++ .../kylin/provider/KylinConfig.java | 19 + .../kylin/provider/KylinDsProvider.java | 189 ++ .../kylin/query/KylinConstants.java | 38 + .../kylin/query/KylinQueryProvider.java | 1256 ++++++++++++ .../kylin/service/KylinService.java | 54 + .../kylin/kylin-frontend/.babelrc | 12 + .../kylin/kylin-frontend/.gitignore | 14 + .../kylin/kylin-frontend/README.md | 21 + .../build/build-async-plugins.js | 35 + .../kylin/kylin-frontend/build/build.js | 41 + .../kylin-frontend/build/check-versions.js | 54 + .../kylin/kylin-frontend/build/logo.png | Bin 0 -> 6849 bytes .../kylin/kylin-frontend/build/utils.js | 101 + .../kylin-frontend/build/vue-loader.conf.js | 22 + .../build/webpack.async-plugins.js | 85 + .../kylin-frontend/build/webpack.base.conf.js | 103 + .../kylin-frontend/build/webpack.dev.conf.js | 95 + .../kylin-frontend/build/webpack.prod.conf.js | 145 ++ .../kylin/kylin-frontend/config/dev.env.js | 7 + .../kylin/kylin-frontend/config/index.js | 69 + .../kylin/kylin-frontend/config/prod.env.js | 4 + .../kylin/kylin-frontend/index.html | 12 + .../kylin/kylin-frontend/package.json | 75 + .../kylin/kylin-frontend/pom.xml | 80 + .../kylin/kylin-frontend/src/App.vue | 23 + .../kylin/kylin-frontend/src/assets/logo.png | Bin 0 -> 6849 bytes .../src/components/HelloWorld.vue | 113 ++ .../kylin-frontend/src/de-base/lang/en.js | 19 + .../kylin-frontend/src/de-base/lang/index.js | 49 + .../src/de-base/lang/messages.js | 17 + .../kylin-frontend/src/de-base/lang/tw.js | 19 + .../kylin-frontend/src/de-base/lang/zh.js | 19 + .../kylin/kylin-frontend/src/icons/index.js | 9 + .../src/icons/svg/de_pwd_invisible.svg | 3 + .../src/icons/svg/de_pwd_visible.svg | 3 + .../src/icons/svg/kylin-backend.svg | 1 + .../kylin-frontend/src/icons/svg/kylin.jpg | Bin 0 -> 18205 bytes .../kylin/kylin-frontend/src/icons/svgo.yml | 22 + .../kylin/kylin-frontend/src/main.js | 33 + .../kylin/kylin-frontend/src/router/index.js | 21 + .../kylin/kylin-frontend/src/utils/compare.js | 29 + .../kylin-frontend/src/utils/validate.js | 15 + .../kylin/kylin-frontend/src/views/dePwd.vue | 75 + .../kylin/kylin-frontend/src/views/kylin.vue | 163 ++ .../kylin/plugin.json | 13 + .../kylin/pom.xml | 19 + .../maxcompute/.gitignore | 35 + .../maxcompute/build.sh | 6 + .../maxcompute/maxcompute-backend/pom.xml | 109 ++ .../dm/provider/MaxcomputeConfig.java | 32 + .../dm/provider/MaxcomputeDsProvider.java | 104 + .../datasource/dm/query/MaxConstants.java | 45 + .../dm/query/MaxcomputeQueryProvider.java | 1285 +++++++++++++ .../dm/service/MaxcomputeService.java | 58 + .../maxcompute/maxcompute-frontend/.babelrc | 12 + .../maxcompute-frontend/.editorconfig | 9 + .../maxcompute/maxcompute-frontend/.gitignore | 14 + .../maxcompute-frontend/.postcssrc.js | 10 + .../maxcompute/maxcompute-frontend/README.md | 21 + .../build/build-async-plugins.js | 35 + .../maxcompute-frontend/build/build.js | 41 + .../build/check-versions.js | 54 + .../maxcompute-frontend/build/logo.png | Bin 0 -> 6849 bytes .../maxcompute-frontend/build/utils.js | 101 + .../build/vue-loader.conf.js | 22 + .../build/webpack.async-plugins.js | 91 + .../build/webpack.base.conf.js | 91 + .../build/webpack.dev.conf.js | 95 + .../build/webpack.prod.conf.js | 145 ++ .../maxcompute-frontend/config/dev.env.js | 7 + .../maxcompute-frontend/config/index.js | 69 + .../maxcompute-frontend/config/prod.env.js | 4 + .../maxcompute/maxcompute-frontend/index.html | 12 + .../maxcompute-frontend/package.json | 73 + .../maxcompute/maxcompute-frontend/pom.xml | 80 + .../maxcompute-frontend/src/App.vue | 23 + .../maxcompute-frontend/src/assets/logo.png | Bin 0 -> 6849 bytes .../src/components/HelloWorld.vue | 113 ++ .../src/de-base/lang/en.js | 15 + .../src/de-base/lang/index.js | 49 + .../src/de-base/lang/messages.js | 17 + .../src/de-base/lang/tw.js | 15 + .../src/de-base/lang/zh.js | 15 + .../maxcompute-frontend/src/icons/index.js | 9 + .../src/icons/svg/maxcompute-backend.svg | 1 + .../src/icons/svg/maxcompute.jpg | Bin 0 -> 6965 bytes .../maxcompute-frontend/src/icons/svgo.yml | 22 + .../maxcompute-frontend/src/main.js | 33 + .../maxcompute-frontend/src/router/index.js | 21 + .../maxcompute-frontend/src/utils/compare.js | 29 + .../maxcompute-frontend/src/utils/validate.js | 15 + .../src/views/maxcompute.vue | 164 ++ .../maxcompute/plugin.json | 13 + .../maxcompute/pom.xml | 19 + .../mongo/build.sh | 6 + .../mongo/mongo-backend/pom.xml | 109 ++ .../mongo/provider/MongoConfig.java | 23 + .../mongo/provider/MongobiDsProvider.java | 134 ++ .../mongo/query/MongoConstants.java | 51 + .../mongo/query/MongobiQueryProvider.java | 1331 +++++++++++++ .../mongo/service/MongoService.java | 58 + .../mongo/mongo-frontend/.babelrc | 12 + .../mongo/mongo-frontend/.gitignore | 14 + .../mongo/mongo-frontend/README.md | 21 + .../build/build-async-plugins.js | 35 + .../mongo/mongo-frontend/build/build.js | 41 + .../mongo-frontend/build/check-versions.js | 54 + .../mongo/mongo-frontend/build/logo.png | Bin 0 -> 6849 bytes .../mongo/mongo-frontend/build/utils.js | 101 + .../mongo-frontend/build/vue-loader.conf.js | 22 + .../build/webpack.async-plugins.js | 103 + .../mongo-frontend/build/webpack.base.conf.js | 91 + .../mongo-frontend/build/webpack.dev.conf.js | 95 + .../mongo-frontend/build/webpack.prod.conf.js | 145 ++ .../mongo/mongo-frontend/config/dev.env.js | 7 + .../mongo/mongo-frontend/config/index.js | 69 + .../mongo/mongo-frontend/config/prod.env.js | 4 + .../mongo/mongo-frontend/index.html | 12 + .../mongo/mongo-frontend/package.json | 75 + .../mongo/mongo-frontend/pom.xml | 80 + .../mongo/mongo-frontend/src/App.vue | 23 + .../mongo/mongo-frontend/src/assets/logo.png | Bin 0 -> 6849 bytes .../src/components/HelloWorld.vue | 113 ++ .../mongo-frontend/src/de-base/lang/en.js | 23 + .../mongo-frontend/src/de-base/lang/index.js | 49 + .../src/de-base/lang/messages.js | 17 + .../mongo-frontend/src/de-base/lang/tw.js | 23 + .../mongo-frontend/src/de-base/lang/zh.js | 23 + .../mongo/mongo-frontend/src/icons/index.js | 9 + .../src/icons/svg/mongo-backend.svg | 1 + .../mongo-frontend/src/icons/svg/mongobi.jpg | Bin 0 -> 9124 bytes .../mongo/mongo-frontend/src/icons/svgo.yml | 22 + .../mongo/mongo-frontend/src/main.js | 33 + .../mongo/mongo-frontend/src/router/index.js | 21 + .../mongo/mongo-frontend/src/utils/compare.js | 29 + .../mongo-frontend/src/utils/validate.js | 15 + .../mongo/mongo-frontend/src/views/dePwd.vue | 75 + .../mongo-frontend/src/views/mongobi.vue | 177 ++ .../mongo/plugin.json | 13 + .../mongo/pom.xml | 19 + .../dataease-extensions-datasource/pom.xml | 24 + .../presto/build.sh | 6 + .../presto/plugin.json | 13 + .../presto/pom.xml | 19 + .../presto/presto-backend/pom.xml | 109 ++ .../datasource/dm/provider/PrestoConfig.java | 22 + .../dm/provider/PrestoDsProvider.java | 154 ++ .../datasource/dm/query/PrestoConstants.java | 45 + .../dm/query/PrestoQueryProvider.java | 1287 +++++++++++++ .../datasource/dm/service/PrestoService.java | 54 + .../presto/presto-frontend/.babelrc | 12 + .../presto/presto-frontend/.editorconfig | 9 + .../presto/presto-frontend/.gitignore | 14 + .../presto/presto-frontend/.postcssrc.js | 10 + .../presto/presto-frontend/README.md | 21 + .../build/build-async-plugins.js | 35 + .../presto/presto-frontend/build/build.js | 41 + .../presto-frontend/build/check-versions.js | 54 + .../presto/presto-frontend/build/logo.png | Bin 0 -> 6849 bytes .../presto/presto-frontend/build/utils.js | 101 + .../presto-frontend/build/vue-loader.conf.js | 22 + .../build/webpack.async-plugins.js | 91 + .../build/webpack.base.conf.js | 103 + .../presto-frontend/build/webpack.dev.conf.js | 95 + .../build/webpack.prod.conf.js | 145 ++ .../presto/presto-frontend/config/dev.env.js | 7 + .../presto/presto-frontend/config/index.js | 69 + .../presto/presto-frontend/config/prod.env.js | 4 + .../presto/presto-frontend/index.html | 12 + .../presto/presto-frontend/package.json | 75 + .../presto/presto-frontend/pom.xml | 80 + .../presto/presto-frontend/src/App.vue | 23 + .../presto-frontend/src/assets/logo.png | Bin 0 -> 6849 bytes .../src/components/HelloWorld.vue | 113 ++ .../presto-frontend/src/de-base/lang/en.js | 20 + .../presto-frontend/src/de-base/lang/index.js | 49 + .../src/de-base/lang/messages.js | 17 + .../presto-frontend/src/de-base/lang/tw.js | 20 + .../presto-frontend/src/de-base/lang/zh.js | 20 + .../presto/presto-frontend/src/icons/index.js | 9 + .../src/icons/svg/de_pwd_invisible.svg | 3 + .../src/icons/svg/de_pwd_visible.svg | 3 + .../src/icons/svg/presto-backend.svg | 1 + .../presto-frontend/src/icons/svg/presto.jpg | Bin 0 -> 9532 bytes .../presto/presto-frontend/src/icons/svgo.yml | 22 + .../presto/presto-frontend/src/main.js | 33 + .../presto-frontend/src/router/index.js | 21 + .../presto-frontend/src/utils/compare.js | 29 + .../presto-frontend/src/utils/validate.js | 15 + .../presto-frontend/src/views/dePwd.vue | 75 + .../presto-frontend/src/views/presto.vue | 167 ++ extensions/dataease-extensions-view/pom.xml | 24 + .../view-3dpie/build.sh | 8 + .../view-3dpie/plugin.json | 13 + .../view-3dpie/pom.xml | 19 + .../view-3dpie/view-3dpie-backend/pom.xml | 109 ++ .../view/official/impl/Pie3DService.java | 88 + .../view-3dpie/view-3dpie-frontend/.babelrc | 12 + .../view-3dpie-frontend/.editorconfig | 9 + .../view-3dpie/view-3dpie-frontend/.gitignore | 14 + .../view-3dpie-frontend/.postcssrc.js | 10 + .../view-3dpie/view-3dpie-frontend/README.md | 21 + .../build/build-async-plugins.js | 35 + .../view-3dpie-frontend/build/build.js | 41 + .../build/check-versions.js | 54 + .../view-3dpie-frontend/build/logo.png | Bin 0 -> 6849 bytes .../view-3dpie-frontend/build/utils.js | 101 + .../build/vue-loader.conf.js | 22 + .../build/webpack.async-plugins.js | 97 + .../build/webpack.base.conf.js | 91 + .../build/webpack.dev.conf.js | 95 + .../build/webpack.prod.conf.js | 145 ++ .../view-3dpie-frontend/config/dev.env.js | 7 + .../view-3dpie-frontend/config/index.js | 69 + .../view-3dpie-frontend/config/prod.env.js | 4 + .../view-3dpie/view-3dpie-frontend/index.html | 12 + .../view-3dpie-frontend/package.json | 73 + .../view-3dpie/view-3dpie-frontend/pom.xml | 80 + .../view-3dpie-frontend/src/App.vue | 23 + .../view-3dpie-frontend/src/assets/logo.png | Bin 0 -> 6849 bytes .../src/components/HelloWorld.vue | 113 ++ .../src/components/SvgIcon/index.vue | 60 + .../selector/BackgroundColorSelector.vue | 102 + .../src/components/selector/ColorSelector.vue | 290 +++ .../src/components/selector/LabelSelector.vue | 165 ++ .../components/selector/LegendSelector.vue | 165 ++ .../src/components/selector/TitleSelector.vue | 164 ++ .../components/selector/TooltipSelector.vue | 144 ++ .../src/components/views/ChartDragItem.vue | 278 +++ .../src/components/views/DimensionExtItem.vue | 256 +++ .../src/components/views/DimensionItem.vue | 256 +++ .../src/components/views/DrillItem.vue | 146 ++ .../src/components/views/FieldErrorTips.vue | 21 + .../src/components/views/FilterItem.vue | 153 ++ .../src/components/views/QuotaExtItem.vue | 363 ++++ .../src/components/views/QuotaItem.vue | 344 ++++ .../src/components/views/ViewTrackBar.vue | 59 + .../src/components/views/utils.js | 34 + .../src/de-base/lang/en.js | 7 + .../src/de-base/lang/index.js | 49 + .../src/de-base/lang/messages.js | 17 + .../src/de-base/lang/tw.js | 7 + .../src/de-base/lang/zh.js | 7 + .../view-3dpie-frontend/src/icons/index.js | 9 + .../src/icons/svg/3d-pie.svg | 1 + .../src/icons/svg/view-3dpie-backend.svg | 1 + .../view-3dpie-frontend/src/icons/svgo.yml | 0 .../view-3dpie-frontend/src/main.js | 34 + .../view-3dpie-frontend/src/router/index.js | 21 + .../view-3dpie-frontend/src/utils/3dpie.js | 268 +++ .../view-3dpie-frontend/src/utils/compare.js | 29 + .../view-3dpie-frontend/src/utils/map.js | 350 ++++ .../view-3dpie-frontend/src/utils/validate.js | 15 + .../src/views/PluginDemo.vue | 55 + .../src/views/highcharts/3dpie/data.vue | 680 +++++++ .../src/views/highcharts/3dpie/index.vue | 244 +++ .../src/views/highcharts/3dpie/style.vue | 162 ++ .../src/views/highcharts/3dpie/type.vue | 63 + .../view-bubblemap/build.sh | 8 + .../view-bubblemap/plugin.json | 13 + .../view-bubblemap/pom.xml | 22 + .../view-bubblemap-backend/pom.xml | 161 ++ .../view/official/impl/BubbleMapService.java | 113 ++ .../src/main/resources/allatori/allatori.xml | 18 + .../src/main/resources/application.properties | 28 + .../view-bubblemap-frontend/.babelrc | 12 + .../view-bubblemap-frontend/.editorconfig | 9 + .../view-bubblemap-frontend/.gitignore | 14 + .../view-bubblemap-frontend/.postcssrc.js | 10 + .../view-bubblemap-frontend/README.md | 21 + .../build/build-async-plugins.js | 35 + .../view-bubblemap-frontend/build/build.js | 41 + .../build/check-versions.js | 54 + .../view-bubblemap-frontend/build/logo.png | Bin 0 -> 6849 bytes .../view-bubblemap-frontend/build/utils.js | 101 + .../build/vue-loader.conf.js | 22 + .../build/webpack.async-plugins.js | 97 + .../build/webpack.base.conf.js | 91 + .../build/webpack.dev.conf.js | 95 + .../build/webpack.prod.conf.js | 145 ++ .../view-bubblemap-frontend/config/dev.env.js | 7 + .../view-bubblemap-frontend/config/index.js | 69 + .../config/prod.env.js | 4 + .../view-bubblemap-frontend/index.html | 12 + .../view-bubblemap-frontend/package.json | 72 + .../view-bubblemap-frontend/pom.xml | 80 + .../view-bubblemap-frontend/src/App.vue | 23 + .../src/assets/logo.png | Bin 0 -> 6849 bytes .../src/components/HelloWorld.vue | 113 ++ .../src/components/SvgIcon/index.vue | 68 + .../selector/BackgroundColorSelector.vue | 102 + .../src/components/selector/ColorSelector.vue | 335 ++++ .../src/components/selector/LabelSelector.vue | 203 ++ .../selector/SuspensionSelector.vue | 116 ++ .../src/components/selector/TitleSelector.vue | 164 ++ .../components/selector/TooltipSelector.vue | 159 ++ .../src/components/views/ChartDragItem.vue | 278 +++ .../src/components/views/DimensionExtItem.vue | 256 +++ .../src/components/views/DimensionItem.vue | 256 +++ .../src/components/views/DrillItem.vue | 146 ++ .../src/components/views/FieldErrorTips.vue | 21 + .../src/components/views/FilterItem.vue | 154 ++ .../src/components/views/QuotaExtItem.vue | 363 ++++ .../src/components/views/QuotaItem.vue | 345 ++++ .../src/components/views/ViewTrackBar.vue | 59 + .../src/components/views/utils.js | 34 + .../src/de-base/lang/en.js | 8 + .../src/de-base/lang/index.js | 48 + .../src/de-base/lang/messages.js | 17 + .../src/de-base/lang/tw.js | 8 + .../src/de-base/lang/zh.js | 8 + .../src/icons/index.js | 9 + .../src/icons/svg/buddle-map.svg | 1 + .../src/icons/svg/view-bubblemap-backend.svg | 1 + .../src/icons/svgo.yml | 0 .../view-bubblemap-frontend/src/main.js | 34 + .../src/router/index.js | 27 + .../src/utils/compare.js | 29 + .../view-bubblemap-frontend/src/utils/map.js | 370 ++++ .../src/utils/nationalCenterPoint.js | 750 ++++++++ .../src/utils/validate.js | 16 + .../src/views/PluginDemo.vue | 55 + .../src/views/echarts/map/buddle/data.vue | 721 +++++++ .../src/views/echarts/map/buddle/format.js | 47 + .../src/views/echarts/map/buddle/index.vue | 442 +++++ .../src/views/echarts/map/buddle/style.vue | 160 ++ .../src/views/echarts/map/buddle/type.vue | 58 + .../src/views/echarts/map/test.vue | 21 + .../view-chartmix/build.sh | 8 + .../view-chartmix/plugin.json | 13 + .../view-chartmix/pom.xml | 20 + .../view-chartmix-backend/pom.xml | 109 ++ .../handler/DefaultViewStatHandler.java | 103 + .../view/official/impl/ChartMixService.java | 192 ++ .../view-chartmix-frontend/.babelrc | 12 + .../view-chartmix-frontend/.editorconfig | 9 + .../view-chartmix-frontend/.gitignore | 14 + .../view-chartmix-frontend/.postcssrc.js | 10 + .../view-chartmix-frontend/README.md | 21 + .../build/build-async-plugins.js | 35 + .../view-chartmix-frontend/build/build.js | 41 + .../build/check-versions.js | 54 + .../view-chartmix-frontend/build/logo.png | Bin 0 -> 6849 bytes .../view-chartmix-frontend/build/utils.js | 101 + .../build/vue-loader.conf.js | 22 + .../build/webpack.async-plugins.js | 97 + .../build/webpack.base.conf.js | 91 + .../build/webpack.dev.conf.js | 95 + .../build/webpack.prod.conf.js | 147 ++ .../view-chartmix-frontend/config/dev.env.js | 7 + .../view-chartmix-frontend/config/index.js | 69 + .../view-chartmix-frontend/config/prod.env.js | 4 + .../view-chartmix-frontend/index.html | 12 + .../view-chartmix-frontend/package.json | 75 + .../view-chartmix-frontend/pom.xml | 80 + .../view-chartmix-frontend/src/App.vue | 23 + .../src/assets/logo.png | Bin 0 -> 6849 bytes .../src/components/HelloWorld.vue | 113 ++ .../src/components/SvgIcon/index.vue | 60 + .../selector/BackgroundColorSelector.vue | 102 + .../src/components/selector/ColorSelector.vue | 306 +++ .../src/components/selector/LabelSelector.vue | 259 +++ .../components/selector/LegendSelector.vue | 165 ++ .../components/selector/SizeSelectorAntV.vue | 130 ++ .../src/components/selector/TitleSelector.vue | 269 +++ .../components/selector/TooltipSelector.vue | 144 ++ .../selector/TooltipSelectorAntV.vue | 228 +++ .../src/components/views/ChartDragItem.vue | 278 +++ .../src/components/views/ChartTitleUpdate.vue | 480 +++++ .../src/components/views/DimensionExtItem.vue | 256 +++ .../src/components/views/DrillItem.vue | 146 ++ .../src/components/views/FieldErrorTips.vue | 21 + .../src/components/views/FilterItem.vue | 154 ++ .../src/components/views/LocationLineItem.vue | 170 ++ .../src/components/views/QuotaExtItem.vue | 414 ++++ .../src/components/views/QuotaItem.vue | 414 ++++ .../components/views/SankeyDimensionItem.vue | 420 ++++ .../src/components/views/ViewTrackBar.vue | 80 + .../src/components/views/utils.js | 99 + .../src/de-base/lang/en.js | 22 + .../src/de-base/lang/index.js | 49 + .../src/de-base/lang/messages.js | 17 + .../src/de-base/lang/tw.js | 23 + .../src/de-base/lang/zh.js | 21 + .../view-chartmix-frontend/src/icons/index.js | 9 + .../src/icons/svg/chart-mix.svg | 1 + .../src/icons/svg/view-chart-mix-backend.svg | 1 + .../view-chartmix-frontend/src/icons/svgo.yml | 0 .../view-chartmix-frontend/src/main.js | 36 + .../src/router/index.js | 21 + .../src/utils/chartmix.js | 73 + .../src/utils/clickoutside.js | 68 + .../src/utils/compare.js | 29 + .../src/utils/formatter.js | 74 + .../view-chartmix-frontend/src/utils/map.js | 595 ++++++ .../src/utils/validate.js | 15 + .../src/views/PluginDemo.vue | 55 + .../src/views/antv/chartmix/data.vue | 663 +++++++ .../src/views/antv/chartmix/index.vue | 717 +++++++ .../src/views/antv/chartmix/style.vue | 175 ++ .../src/views/antv/chartmix/type.vue | 63 + .../view-racebar/build.sh | 8 + .../view-racebar/plugin.json | 13 + .../view-racebar/pom.xml | 20 + .../view-racebar/view-racebar-backend/pom.xml | 109 ++ .../handler/DefaultViewStatHandler.java | 107 ++ .../view/official/impl/RaceBarService.java | 186 ++ .../view-racebar-frontend/.babelrc | 12 + .../view-racebar-frontend/.editorconfig | 9 + .../view-racebar-frontend/.gitignore | 14 + .../view-racebar-frontend/.postcssrc.js | 10 + .../view-racebar-frontend/README.md | 21 + .../build/build-async-plugins.js | 35 + .../view-racebar-frontend/build/build.js | 41 + .../build/check-versions.js | 54 + .../view-racebar-frontend/build/logo.png | Bin 0 -> 6849 bytes .../view-racebar-frontend/build/utils.js | 101 + .../build/vue-loader.conf.js | 22 + .../build/webpack.async-plugins.js | 97 + .../build/webpack.base.conf.js | 91 + .../build/webpack.dev.conf.js | 95 + .../build/webpack.prod.conf.js | 147 ++ .../view-racebar-frontend/config/dev.env.js | 7 + .../view-racebar-frontend/config/index.js | 69 + .../view-racebar-frontend/config/prod.env.js | 4 + .../view-racebar-frontend/index.html | 12 + .../view-racebar-frontend/package.json | 74 + .../view-racebar-frontend/pom.xml | 80 + .../view-racebar-frontend/src/App.vue | 23 + .../view-racebar-frontend/src/assets/logo.png | Bin 0 -> 6849 bytes .../src/components/HelloWorld.vue | 113 ++ .../src/components/SvgIcon/index.vue | 60 + .../selector/BackgroundColorSelector.vue | 102 + .../src/components/selector/ColorSelector.vue | 306 +++ .../components/selector/GraphicSetting.vue | 177 ++ .../src/components/selector/LabelSelector.vue | 220 +++ .../components/selector/LegendSelector.vue | 165 ++ .../components/selector/MarginSelector.vue | 280 +++ .../components/selector/SizeSelectorAntV.vue | 130 ++ .../src/components/selector/SliderSetting.vue | 159 ++ .../src/components/selector/TitleSelector.vue | 319 +++ .../components/selector/TooltipSelector.vue | 152 ++ .../src/components/selector/XAxisSelector.vue | 493 +++++ .../src/components/selector/YAxisSelector.vue | 493 +++++ .../src/components/views/ChartDragItem.vue | 278 +++ .../src/components/views/ChartTitleUpdate.vue | 480 +++++ .../src/components/views/DimensionExtItem.vue | 371 ++++ .../src/components/views/DimensionItem.vue | 415 ++++ .../src/components/views/DrillItem.vue | 146 ++ .../src/components/views/FieldErrorTips.vue | 21 + .../src/components/views/FilterItem.vue | 154 ++ .../src/components/views/LocationLineItem.vue | 170 ++ .../src/components/views/QuotaExtItem.vue | 410 ++++ .../src/components/views/QuotaItem.vue | 395 ++++ .../src/components/views/ViewTrackBar.vue | 80 + .../src/components/views/utils.js | 99 + .../src/de-base/lang/en.js | 29 + .../src/de-base/lang/index.js | 49 + .../src/de-base/lang/messages.js | 17 + .../src/de-base/lang/tw.js | 30 + .../src/de-base/lang/zh.js | 28 + .../view-racebar-frontend/src/icons/index.js | 9 + .../src/icons/svg/race-bar.svg | 1 + .../src/icons/svg/view-race-bar-backend.svg | 1 + .../view-racebar-frontend/src/icons/svgo.yml | 0 .../view-racebar-frontend/src/main.js | 36 + .../view-racebar-frontend/src/router/index.js | 21 + .../src/utils/clickoutside.js | 68 + .../src/utils/compare.js | 29 + .../src/utils/formatter.js | 77 + .../view-racebar-frontend/src/utils/map.js | 849 ++++++++ .../src/utils/validate.js | 15 + .../src/views/PluginDemo.vue | 55 + .../src/views/antv/racebar/data.vue | 682 +++++++ .../src/views/antv/racebar/index.vue | 690 +++++++ .../src/views/antv/racebar/style.vue | 251 +++ .../src/views/antv/racebar/type.vue | 63 + .../view-sankey/build.sh | 8 + .../view-sankey/plugin.json | 13 + .../view-sankey/pom.xml | 20 + .../view-sankey/view-sankey-backend/pom.xml | 109 ++ .../view/official/impl/SankeyService.java | 122 ++ .../view-sankey/view-sankey-frontend/.babelrc | 12 + .../view-sankey-frontend/.editorconfig | 9 + .../view-sankey-frontend/.gitignore | 14 + .../view-sankey-frontend/.postcssrc.js | 10 + .../view-sankey-frontend/README.md | 21 + .../build/build-async-plugins.js | 35 + .../view-sankey-frontend/build/build.js | 41 + .../build/check-versions.js | 54 + .../view-sankey-frontend/build/logo.png | Bin 0 -> 6849 bytes .../view-sankey-frontend/build/utils.js | 101 + .../build/vue-loader.conf.js | 22 + .../build/webpack.async-plugins.js | 97 + .../build/webpack.base.conf.js | 91 + .../build/webpack.dev.conf.js | 95 + .../build/webpack.prod.conf.js | 147 ++ .../view-sankey-frontend/config/dev.env.js | 7 + .../view-sankey-frontend/config/index.js | 69 + .../view-sankey-frontend/config/prod.env.js | 4 + .../view-sankey-frontend/index.html | 12 + .../view-sankey-frontend/package.json | 75 + .../view-sankey/view-sankey-frontend/pom.xml | 80 + .../view-sankey-frontend/src/App.vue | 23 + .../view-sankey-frontend/src/assets/logo.png | Bin 0 -> 6849 bytes .../src/components/HelloWorld.vue | 113 ++ .../src/components/SvgIcon/index.vue | 60 + .../selector/BackgroundColorSelector.vue | 102 + .../src/components/selector/ColorSelector.vue | 306 +++ .../src/components/selector/LabelSelector.vue | 259 +++ .../components/selector/LegendSelector.vue | 165 ++ .../components/selector/SizeSelectorAntV.vue | 130 ++ .../src/components/selector/TitleSelector.vue | 269 +++ .../components/selector/TooltipSelector.vue | 144 ++ .../selector/TooltipSelectorAntV.vue | 228 +++ .../src/components/views/ChartDragItem.vue | 278 +++ .../src/components/views/ChartTitleUpdate.vue | 480 +++++ .../src/components/views/DimensionExtItem.vue | 256 +++ .../src/components/views/DrillItem.vue | 146 ++ .../src/components/views/FieldErrorTips.vue | 21 + .../src/components/views/FilterItem.vue | 154 ++ .../src/components/views/LocationLineItem.vue | 170 ++ .../src/components/views/QuotaExtItem.vue | 363 ++++ .../components/views/SankeyDimensionItem.vue | 342 ++++ .../src/components/views/SankeyQuotaItem.vue | 333 ++++ .../src/components/views/ViewTrackBar.vue | 80 + .../src/components/views/utils.js | 86 + .../src/de-base/lang/en.js | 22 + .../src/de-base/lang/index.js | 49 + .../src/de-base/lang/messages.js | 17 + .../src/de-base/lang/tw.js | 23 + .../src/de-base/lang/zh.js | 21 + .../view-sankey-frontend/src/icons/index.js | 9 + .../src/icons/svg/sankey.svg | 1 + .../src/icons/svg/view-sankey-backend.svg | 1 + .../view-sankey-frontend/src/icons/svgo.yml | 0 .../view-sankey-frontend/src/main.js | 36 + .../view-sankey-frontend/src/router/index.js | 21 + .../src/utils/clickoutside.js | 68 + .../view-sankey-frontend/src/utils/compare.js | 29 + .../view-sankey-frontend/src/utils/map.js | 469 +++++ .../view-sankey-frontend/src/utils/sankey.js | 73 + .../src/utils/validate.js | 15 + .../src/views/PluginDemo.vue | 55 + .../src/views/antv/sankey/data.vue | 717 +++++++ .../src/views/antv/sankey/index.vue | 527 +++++ .../src/views/antv/sankey/style.vue | 175 ++ .../src/views/antv/sankey/type.vue | 63 + .../view-symbolmap/build.sh | 8 + .../view-symbolmap/plugin.json | 13 + .../view-symbolmap/pom.xml | 20 + .../view-symbolmap-backend/pom.xml | 109 ++ .../view/official/dto/SymbolMapResultDTO.java | 18 + .../official/handler/SymbolMapRSHandler.java | 142 ++ .../handler/SymbolMapStatHandler.java | 101 + .../view/official/impl/SymbolMapService.java | 161 ++ .../view-symbolmap-frontend/.babelrc | 12 + .../view-symbolmap-frontend/.editorconfig | 9 + .../view-symbolmap-frontend/.gitignore | 14 + .../view-symbolmap-frontend/.postcssrc.js | 10 + .../view-symbolmap-frontend/README.md | 21 + .../build/build-async-plugins.js | 35 + .../view-symbolmap-frontend/build/build.js | 41 + .../build/check-versions.js | 54 + .../view-symbolmap-frontend/build/logo.png | Bin 0 -> 6849 bytes .../view-symbolmap-frontend/build/utils.js | 101 + .../build/vue-loader.conf.js | 22 + .../build/webpack.async-plugins.js | 97 + .../build/webpack.base.conf.js | 91 + .../build/webpack.dev.conf.js | 95 + .../build/webpack.prod.conf.js | 147 ++ .../view-symbolmap-frontend/config/dev.env.js | 7 + .../view-symbolmap-frontend/config/index.js | 69 + .../config/prod.env.js | 4 + .../view-symbolmap-frontend/index.html | 12 + .../view-symbolmap-frontend/package.json | 82 + .../view-symbolmap-frontend/pom.xml | 80 + .../view-symbolmap-frontend/src/App.vue | 23 + .../src/assets/logo.png | Bin 0 -> 6849 bytes .../src/components/HelloWorld.vue | 113 ++ .../src/components/SvgIcon/index.vue | 60 + .../selector/BackgroundColorSelector.vue | 102 + .../selector/BaseMapStyleSelector.vue | 99 + .../src/components/selector/ColorSelector.vue | 290 +++ .../src/components/selector/LabelSelector.vue | 244 +++ .../components/selector/LegendSelector.vue | 165 ++ .../components/selector/SizeSelectorAntV.vue | 130 ++ .../src/components/selector/TitleSelector.vue | 269 +++ .../components/selector/TooltipSelector.vue | 144 ++ .../selector/TooltipSelectorAntV.vue | 225 +++ .../src/components/views/ChartDragItem.vue | 278 +++ .../src/components/views/DimensionExtItem.vue | 256 +++ .../src/components/views/DrillItem.vue | 146 ++ .../src/components/views/FieldErrorTips.vue | 21 + .../src/components/views/FilterItem.vue | 154 ++ .../src/components/views/LocationLineItem.vue | 170 ++ .../src/components/views/LocationXItem.vue | 170 ++ .../src/components/views/LocationYItem.vue | 170 ++ .../src/components/views/QuotaExtItem.vue | 363 ++++ .../src/components/views/QuotaItem.vue | 310 +++ .../src/components/views/ViewTrackBar.vue | 59 + .../src/components/views/utils.js | 48 + .../src/de-base/lang/en.js | 23 + .../src/de-base/lang/index.js | 49 + .../src/de-base/lang/messages.js | 17 + .../src/de-base/lang/tw.js | 24 + .../src/de-base/lang/zh.js | 22 + .../src/icons/index.js | 9 + .../src/icons/svg/map-marker-old.svg | 1 + .../src/icons/svg/map-marker.png | Bin 0 -> 3072 bytes .../src/icons/svg/map-marker.svg | 3 + .../src/icons/svg/symbol-map.svg | 1 + .../src/icons/svg/view-symbolmap-backend.svg | 1 + .../src/icons/svgo.yml | 0 .../view-symbolmap-frontend/src/main.js | 36 + .../src/router/index.js | 21 + .../src/utils/compare.js | 29 + .../view-symbolmap-frontend/src/utils/map.js | 430 +++++ .../src/utils/symbolmap.js | 73 + .../src/utils/validate.js | 15 + .../src/views/PluginDemo.vue | 55 + .../src/views/antv/symbolmap/data.vue | 648 +++++++ .../src/views/antv/symbolmap/index.vue | 633 ++++++ .../src/views/antv/symbolmap/style.vue | 199 ++ .../src/views/antv/symbolmap/type.vue | 63 + extensions/pom.xml | 43 + pom.xml | 1 + 729 files changed, 70579 insertions(+) create mode 100644 extensions/.gitignore create mode 100644 extensions/README.md create mode 100644 extensions/dataease-extensions-datasource/dm/.gitignore create mode 100755 extensions/dataease-extensions-datasource/dm/build.sh create mode 100644 extensions/dataease-extensions-datasource/dm/dm-backend/pom.xml create mode 100644 extensions/dataease-extensions-datasource/dm/dm-backend/src/main/java/io/dataease/plugins/datasource/dm/provider/DmConfig.java create mode 100644 extensions/dataease-extensions-datasource/dm/dm-backend/src/main/java/io/dataease/plugins/datasource/dm/provider/DmDsProvider.java create mode 100644 extensions/dataease-extensions-datasource/dm/dm-backend/src/main/java/io/dataease/plugins/datasource/dm/query/DmConstants.java create mode 100644 extensions/dataease-extensions-datasource/dm/dm-backend/src/main/java/io/dataease/plugins/datasource/dm/query/DmQueryProvider.java create mode 100644 extensions/dataease-extensions-datasource/dm/dm-backend/src/main/java/io/dataease/plugins/datasource/dm/service/DmService.java create mode 100644 extensions/dataease-extensions-datasource/dm/dm-frontend/.babelrc create mode 100644 extensions/dataease-extensions-datasource/dm/dm-frontend/.gitignore create mode 100644 extensions/dataease-extensions-datasource/dm/dm-frontend/README.md create mode 100644 extensions/dataease-extensions-datasource/dm/dm-frontend/build/build-async-plugins.js create mode 100644 extensions/dataease-extensions-datasource/dm/dm-frontend/build/build.js create mode 100644 extensions/dataease-extensions-datasource/dm/dm-frontend/build/check-versions.js create mode 100644 extensions/dataease-extensions-datasource/dm/dm-frontend/build/logo.png create mode 100644 extensions/dataease-extensions-datasource/dm/dm-frontend/build/utils.js create mode 100644 extensions/dataease-extensions-datasource/dm/dm-frontend/build/vue-loader.conf.js create mode 100644 extensions/dataease-extensions-datasource/dm/dm-frontend/build/webpack.async-plugins.js create mode 100644 extensions/dataease-extensions-datasource/dm/dm-frontend/build/webpack.base.conf.js create mode 100755 extensions/dataease-extensions-datasource/dm/dm-frontend/build/webpack.dev.conf.js create mode 100644 extensions/dataease-extensions-datasource/dm/dm-frontend/build/webpack.prod.conf.js create mode 100644 extensions/dataease-extensions-datasource/dm/dm-frontend/config/dev.env.js create mode 100644 extensions/dataease-extensions-datasource/dm/dm-frontend/config/index.js create mode 100644 extensions/dataease-extensions-datasource/dm/dm-frontend/config/prod.env.js create mode 100644 extensions/dataease-extensions-datasource/dm/dm-frontend/index.html create mode 100644 extensions/dataease-extensions-datasource/dm/dm-frontend/package.json create mode 100644 extensions/dataease-extensions-datasource/dm/dm-frontend/pom.xml create mode 100644 extensions/dataease-extensions-datasource/dm/dm-frontend/src/App.vue create mode 100644 extensions/dataease-extensions-datasource/dm/dm-frontend/src/assets/logo.png create mode 100644 extensions/dataease-extensions-datasource/dm/dm-frontend/src/components/HelloWorld.vue create mode 100644 extensions/dataease-extensions-datasource/dm/dm-frontend/src/de-base/lang/en.js create mode 100644 extensions/dataease-extensions-datasource/dm/dm-frontend/src/de-base/lang/index.js create mode 100644 extensions/dataease-extensions-datasource/dm/dm-frontend/src/de-base/lang/messages.js create mode 100644 extensions/dataease-extensions-datasource/dm/dm-frontend/src/de-base/lang/tw.js create mode 100644 extensions/dataease-extensions-datasource/dm/dm-frontend/src/de-base/lang/zh.js create mode 100644 extensions/dataease-extensions-datasource/dm/dm-frontend/src/icons/index.js create mode 100644 extensions/dataease-extensions-datasource/dm/dm-frontend/src/icons/svg/de_pwd_invisible.svg create mode 100644 extensions/dataease-extensions-datasource/dm/dm-frontend/src/icons/svg/de_pwd_visible.svg create mode 100644 extensions/dataease-extensions-datasource/dm/dm-frontend/src/icons/svg/dm-backend.svg create mode 100644 extensions/dataease-extensions-datasource/dm/dm-frontend/src/icons/svg/dm.jpg create mode 100644 extensions/dataease-extensions-datasource/dm/dm-frontend/src/icons/svgo.yml create mode 100644 extensions/dataease-extensions-datasource/dm/dm-frontend/src/main.js create mode 100644 extensions/dataease-extensions-datasource/dm/dm-frontend/src/router/index.js create mode 100644 extensions/dataease-extensions-datasource/dm/dm-frontend/src/utils/compare.js create mode 100644 extensions/dataease-extensions-datasource/dm/dm-frontend/src/utils/validate.js create mode 100644 extensions/dataease-extensions-datasource/dm/dm-frontend/src/views/dePwd.vue create mode 100644 extensions/dataease-extensions-datasource/dm/dm-frontend/src/views/dm.vue create mode 100644 extensions/dataease-extensions-datasource/dm/plugin.json create mode 100644 extensions/dataease-extensions-datasource/dm/pom.xml create mode 100755 extensions/dataease-extensions-datasource/kingbase/build.sh create mode 100644 extensions/dataease-extensions-datasource/kingbase/kingbase-backend/pom.xml create mode 100644 extensions/dataease-extensions-datasource/kingbase/kingbase-backend/src/main/java/io/dataease/plugins/datasource/kingbase/provider/KingbaseConfig.java create mode 100644 extensions/dataease-extensions-datasource/kingbase/kingbase-backend/src/main/java/io/dataease/plugins/datasource/kingbase/provider/KingbaseDsProvider.java create mode 100644 extensions/dataease-extensions-datasource/kingbase/kingbase-backend/src/main/java/io/dataease/plugins/datasource/kingbase/query/KingbaseConstants.java create mode 100644 extensions/dataease-extensions-datasource/kingbase/kingbase-backend/src/main/java/io/dataease/plugins/datasource/kingbase/query/KingbaseQueryProvider.java create mode 100644 extensions/dataease-extensions-datasource/kingbase/kingbase-backend/src/main/java/io/dataease/plugins/datasource/kingbase/service/KingbaseService.java create mode 100644 extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/.babelrc create mode 100644 extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/.gitignore create mode 100644 extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/README.md create mode 100644 extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/build/build-async-plugins.js create mode 100644 extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/build/build.js create mode 100644 extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/build/check-versions.js create mode 100644 extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/build/logo.png create mode 100644 extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/build/utils.js create mode 100644 extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/build/vue-loader.conf.js create mode 100644 extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/build/webpack.async-plugins.js create mode 100644 extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/build/webpack.base.conf.js create mode 100755 extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/build/webpack.dev.conf.js create mode 100644 extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/build/webpack.prod.conf.js create mode 100644 extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/config/dev.env.js create mode 100644 extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/config/index.js create mode 100644 extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/config/prod.env.js create mode 100644 extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/index.html create mode 100644 extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/package.json create mode 100644 extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/pom.xml create mode 100644 extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/postcss.config.js create mode 100644 extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/src/App.vue create mode 100644 extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/src/assets/logo.png create mode 100644 extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/src/components/HelloWorld.vue create mode 100644 extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/src/de-base/lang/en.js create mode 100644 extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/src/de-base/lang/index.js create mode 100644 extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/src/de-base/lang/messages.js create mode 100644 extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/src/de-base/lang/tw.js create mode 100644 extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/src/de-base/lang/zh.js create mode 100644 extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/src/icons/index.js create mode 100644 extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/src/icons/svg/de_pwd_invisible.svg create mode 100644 extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/src/icons/svg/de_pwd_visible.svg create mode 100644 extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/src/icons/svg/kingbase-backend.svg create mode 100644 extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/src/icons/svg/kingbase.jpg create mode 100644 extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/src/icons/svgo.yml create mode 100644 extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/src/main.js create mode 100644 extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/src/router/index.js create mode 100644 extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/src/utils/compare.js create mode 100644 extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/src/utils/validate.js create mode 100644 extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/src/views/dePwd.vue create mode 100644 extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/src/views/kingbase.vue create mode 100644 extensions/dataease-extensions-datasource/kingbase/plugin.json create mode 100644 extensions/dataease-extensions-datasource/kingbase/pom.xml create mode 100755 extensions/dataease-extensions-datasource/kylin/build.sh create mode 100644 extensions/dataease-extensions-datasource/kylin/kylin-backend/pom.xml create mode 100644 extensions/dataease-extensions-datasource/kylin/kylin-backend/src/main/java/io/dataease/plugins/datasource/kylin/provider/KylinConfig.java create mode 100644 extensions/dataease-extensions-datasource/kylin/kylin-backend/src/main/java/io/dataease/plugins/datasource/kylin/provider/KylinDsProvider.java create mode 100644 extensions/dataease-extensions-datasource/kylin/kylin-backend/src/main/java/io/dataease/plugins/datasource/kylin/query/KylinConstants.java create mode 100644 extensions/dataease-extensions-datasource/kylin/kylin-backend/src/main/java/io/dataease/plugins/datasource/kylin/query/KylinQueryProvider.java create mode 100644 extensions/dataease-extensions-datasource/kylin/kylin-backend/src/main/java/io/dataease/plugins/datasource/kylin/service/KylinService.java create mode 100644 extensions/dataease-extensions-datasource/kylin/kylin-frontend/.babelrc create mode 100644 extensions/dataease-extensions-datasource/kylin/kylin-frontend/.gitignore create mode 100644 extensions/dataease-extensions-datasource/kylin/kylin-frontend/README.md create mode 100644 extensions/dataease-extensions-datasource/kylin/kylin-frontend/build/build-async-plugins.js create mode 100644 extensions/dataease-extensions-datasource/kylin/kylin-frontend/build/build.js create mode 100644 extensions/dataease-extensions-datasource/kylin/kylin-frontend/build/check-versions.js create mode 100644 extensions/dataease-extensions-datasource/kylin/kylin-frontend/build/logo.png create mode 100644 extensions/dataease-extensions-datasource/kylin/kylin-frontend/build/utils.js create mode 100644 extensions/dataease-extensions-datasource/kylin/kylin-frontend/build/vue-loader.conf.js create mode 100644 extensions/dataease-extensions-datasource/kylin/kylin-frontend/build/webpack.async-plugins.js create mode 100644 extensions/dataease-extensions-datasource/kylin/kylin-frontend/build/webpack.base.conf.js create mode 100755 extensions/dataease-extensions-datasource/kylin/kylin-frontend/build/webpack.dev.conf.js create mode 100644 extensions/dataease-extensions-datasource/kylin/kylin-frontend/build/webpack.prod.conf.js create mode 100644 extensions/dataease-extensions-datasource/kylin/kylin-frontend/config/dev.env.js create mode 100644 extensions/dataease-extensions-datasource/kylin/kylin-frontend/config/index.js create mode 100644 extensions/dataease-extensions-datasource/kylin/kylin-frontend/config/prod.env.js create mode 100644 extensions/dataease-extensions-datasource/kylin/kylin-frontend/index.html create mode 100644 extensions/dataease-extensions-datasource/kylin/kylin-frontend/package.json create mode 100644 extensions/dataease-extensions-datasource/kylin/kylin-frontend/pom.xml create mode 100644 extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/App.vue create mode 100644 extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/assets/logo.png create mode 100644 extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/components/HelloWorld.vue create mode 100644 extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/de-base/lang/en.js create mode 100644 extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/de-base/lang/index.js create mode 100644 extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/de-base/lang/messages.js create mode 100644 extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/de-base/lang/tw.js create mode 100644 extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/de-base/lang/zh.js create mode 100644 extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/icons/index.js create mode 100644 extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/icons/svg/de_pwd_invisible.svg create mode 100644 extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/icons/svg/de_pwd_visible.svg create mode 100644 extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/icons/svg/kylin-backend.svg create mode 100644 extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/icons/svg/kylin.jpg create mode 100644 extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/icons/svgo.yml create mode 100644 extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/main.js create mode 100644 extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/router/index.js create mode 100644 extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/utils/compare.js create mode 100644 extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/utils/validate.js create mode 100644 extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/views/dePwd.vue create mode 100644 extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/views/kylin.vue create mode 100644 extensions/dataease-extensions-datasource/kylin/plugin.json create mode 100644 extensions/dataease-extensions-datasource/kylin/pom.xml create mode 100644 extensions/dataease-extensions-datasource/maxcompute/.gitignore create mode 100755 extensions/dataease-extensions-datasource/maxcompute/build.sh create mode 100644 extensions/dataease-extensions-datasource/maxcompute/maxcompute-backend/pom.xml create mode 100644 extensions/dataease-extensions-datasource/maxcompute/maxcompute-backend/src/main/java/io/dataease/plugins/datasource/dm/provider/MaxcomputeConfig.java create mode 100644 extensions/dataease-extensions-datasource/maxcompute/maxcompute-backend/src/main/java/io/dataease/plugins/datasource/dm/provider/MaxcomputeDsProvider.java create mode 100644 extensions/dataease-extensions-datasource/maxcompute/maxcompute-backend/src/main/java/io/dataease/plugins/datasource/dm/query/MaxConstants.java create mode 100644 extensions/dataease-extensions-datasource/maxcompute/maxcompute-backend/src/main/java/io/dataease/plugins/datasource/dm/query/MaxcomputeQueryProvider.java create mode 100644 extensions/dataease-extensions-datasource/maxcompute/maxcompute-backend/src/main/java/io/dataease/plugins/datasource/dm/service/MaxcomputeService.java create mode 100644 extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/.babelrc create mode 100644 extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/.editorconfig create mode 100644 extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/.gitignore create mode 100644 extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/.postcssrc.js create mode 100644 extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/README.md create mode 100644 extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/build/build-async-plugins.js create mode 100644 extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/build/build.js create mode 100644 extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/build/check-versions.js create mode 100644 extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/build/logo.png create mode 100644 extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/build/utils.js create mode 100644 extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/build/vue-loader.conf.js create mode 100644 extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/build/webpack.async-plugins.js create mode 100644 extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/build/webpack.base.conf.js create mode 100755 extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/build/webpack.dev.conf.js create mode 100644 extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/build/webpack.prod.conf.js create mode 100644 extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/config/dev.env.js create mode 100644 extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/config/index.js create mode 100644 extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/config/prod.env.js create mode 100644 extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/index.html create mode 100644 extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/package.json create mode 100644 extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/pom.xml create mode 100644 extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/src/App.vue create mode 100644 extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/src/assets/logo.png create mode 100644 extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/src/components/HelloWorld.vue create mode 100644 extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/src/de-base/lang/en.js create mode 100644 extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/src/de-base/lang/index.js create mode 100644 extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/src/de-base/lang/messages.js create mode 100644 extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/src/de-base/lang/tw.js create mode 100644 extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/src/de-base/lang/zh.js create mode 100644 extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/src/icons/index.js create mode 100644 extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/src/icons/svg/maxcompute-backend.svg create mode 100644 extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/src/icons/svg/maxcompute.jpg create mode 100644 extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/src/icons/svgo.yml create mode 100644 extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/src/main.js create mode 100644 extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/src/router/index.js create mode 100644 extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/src/utils/compare.js create mode 100644 extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/src/utils/validate.js create mode 100644 extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/src/views/maxcompute.vue create mode 100644 extensions/dataease-extensions-datasource/maxcompute/plugin.json create mode 100644 extensions/dataease-extensions-datasource/maxcompute/pom.xml create mode 100755 extensions/dataease-extensions-datasource/mongo/build.sh create mode 100644 extensions/dataease-extensions-datasource/mongo/mongo-backend/pom.xml create mode 100644 extensions/dataease-extensions-datasource/mongo/mongo-backend/src/main/java/io/dataease/plugins/datasource/mongo/provider/MongoConfig.java create mode 100644 extensions/dataease-extensions-datasource/mongo/mongo-backend/src/main/java/io/dataease/plugins/datasource/mongo/provider/MongobiDsProvider.java create mode 100644 extensions/dataease-extensions-datasource/mongo/mongo-backend/src/main/java/io/dataease/plugins/datasource/mongo/query/MongoConstants.java create mode 100644 extensions/dataease-extensions-datasource/mongo/mongo-backend/src/main/java/io/dataease/plugins/datasource/mongo/query/MongobiQueryProvider.java create mode 100644 extensions/dataease-extensions-datasource/mongo/mongo-backend/src/main/java/io/dataease/plugins/datasource/mongo/service/MongoService.java create mode 100644 extensions/dataease-extensions-datasource/mongo/mongo-frontend/.babelrc create mode 100644 extensions/dataease-extensions-datasource/mongo/mongo-frontend/.gitignore create mode 100644 extensions/dataease-extensions-datasource/mongo/mongo-frontend/README.md create mode 100644 extensions/dataease-extensions-datasource/mongo/mongo-frontend/build/build-async-plugins.js create mode 100644 extensions/dataease-extensions-datasource/mongo/mongo-frontend/build/build.js create mode 100644 extensions/dataease-extensions-datasource/mongo/mongo-frontend/build/check-versions.js create mode 100644 extensions/dataease-extensions-datasource/mongo/mongo-frontend/build/logo.png create mode 100644 extensions/dataease-extensions-datasource/mongo/mongo-frontend/build/utils.js create mode 100644 extensions/dataease-extensions-datasource/mongo/mongo-frontend/build/vue-loader.conf.js create mode 100644 extensions/dataease-extensions-datasource/mongo/mongo-frontend/build/webpack.async-plugins.js create mode 100644 extensions/dataease-extensions-datasource/mongo/mongo-frontend/build/webpack.base.conf.js create mode 100755 extensions/dataease-extensions-datasource/mongo/mongo-frontend/build/webpack.dev.conf.js create mode 100644 extensions/dataease-extensions-datasource/mongo/mongo-frontend/build/webpack.prod.conf.js create mode 100644 extensions/dataease-extensions-datasource/mongo/mongo-frontend/config/dev.env.js create mode 100644 extensions/dataease-extensions-datasource/mongo/mongo-frontend/config/index.js create mode 100644 extensions/dataease-extensions-datasource/mongo/mongo-frontend/config/prod.env.js create mode 100644 extensions/dataease-extensions-datasource/mongo/mongo-frontend/index.html create mode 100644 extensions/dataease-extensions-datasource/mongo/mongo-frontend/package.json create mode 100644 extensions/dataease-extensions-datasource/mongo/mongo-frontend/pom.xml create mode 100644 extensions/dataease-extensions-datasource/mongo/mongo-frontend/src/App.vue create mode 100644 extensions/dataease-extensions-datasource/mongo/mongo-frontend/src/assets/logo.png create mode 100644 extensions/dataease-extensions-datasource/mongo/mongo-frontend/src/components/HelloWorld.vue create mode 100644 extensions/dataease-extensions-datasource/mongo/mongo-frontend/src/de-base/lang/en.js create mode 100644 extensions/dataease-extensions-datasource/mongo/mongo-frontend/src/de-base/lang/index.js create mode 100644 extensions/dataease-extensions-datasource/mongo/mongo-frontend/src/de-base/lang/messages.js create mode 100644 extensions/dataease-extensions-datasource/mongo/mongo-frontend/src/de-base/lang/tw.js create mode 100644 extensions/dataease-extensions-datasource/mongo/mongo-frontend/src/de-base/lang/zh.js create mode 100644 extensions/dataease-extensions-datasource/mongo/mongo-frontend/src/icons/index.js create mode 100644 extensions/dataease-extensions-datasource/mongo/mongo-frontend/src/icons/svg/mongo-backend.svg create mode 100644 extensions/dataease-extensions-datasource/mongo/mongo-frontend/src/icons/svg/mongobi.jpg create mode 100644 extensions/dataease-extensions-datasource/mongo/mongo-frontend/src/icons/svgo.yml create mode 100644 extensions/dataease-extensions-datasource/mongo/mongo-frontend/src/main.js create mode 100644 extensions/dataease-extensions-datasource/mongo/mongo-frontend/src/router/index.js create mode 100644 extensions/dataease-extensions-datasource/mongo/mongo-frontend/src/utils/compare.js create mode 100644 extensions/dataease-extensions-datasource/mongo/mongo-frontend/src/utils/validate.js create mode 100644 extensions/dataease-extensions-datasource/mongo/mongo-frontend/src/views/dePwd.vue create mode 100644 extensions/dataease-extensions-datasource/mongo/mongo-frontend/src/views/mongobi.vue create mode 100644 extensions/dataease-extensions-datasource/mongo/plugin.json create mode 100644 extensions/dataease-extensions-datasource/mongo/pom.xml create mode 100644 extensions/dataease-extensions-datasource/pom.xml create mode 100755 extensions/dataease-extensions-datasource/presto/build.sh create mode 100644 extensions/dataease-extensions-datasource/presto/plugin.json create mode 100644 extensions/dataease-extensions-datasource/presto/pom.xml create mode 100644 extensions/dataease-extensions-datasource/presto/presto-backend/pom.xml create mode 100644 extensions/dataease-extensions-datasource/presto/presto-backend/src/main/java/io/dataease/plugins/datasource/dm/provider/PrestoConfig.java create mode 100644 extensions/dataease-extensions-datasource/presto/presto-backend/src/main/java/io/dataease/plugins/datasource/dm/provider/PrestoDsProvider.java create mode 100644 extensions/dataease-extensions-datasource/presto/presto-backend/src/main/java/io/dataease/plugins/datasource/dm/query/PrestoConstants.java create mode 100644 extensions/dataease-extensions-datasource/presto/presto-backend/src/main/java/io/dataease/plugins/datasource/dm/query/PrestoQueryProvider.java create mode 100644 extensions/dataease-extensions-datasource/presto/presto-backend/src/main/java/io/dataease/plugins/datasource/dm/service/PrestoService.java create mode 100644 extensions/dataease-extensions-datasource/presto/presto-frontend/.babelrc create mode 100644 extensions/dataease-extensions-datasource/presto/presto-frontend/.editorconfig create mode 100644 extensions/dataease-extensions-datasource/presto/presto-frontend/.gitignore create mode 100644 extensions/dataease-extensions-datasource/presto/presto-frontend/.postcssrc.js create mode 100644 extensions/dataease-extensions-datasource/presto/presto-frontend/README.md create mode 100644 extensions/dataease-extensions-datasource/presto/presto-frontend/build/build-async-plugins.js create mode 100644 extensions/dataease-extensions-datasource/presto/presto-frontend/build/build.js create mode 100644 extensions/dataease-extensions-datasource/presto/presto-frontend/build/check-versions.js create mode 100644 extensions/dataease-extensions-datasource/presto/presto-frontend/build/logo.png create mode 100644 extensions/dataease-extensions-datasource/presto/presto-frontend/build/utils.js create mode 100644 extensions/dataease-extensions-datasource/presto/presto-frontend/build/vue-loader.conf.js create mode 100644 extensions/dataease-extensions-datasource/presto/presto-frontend/build/webpack.async-plugins.js create mode 100644 extensions/dataease-extensions-datasource/presto/presto-frontend/build/webpack.base.conf.js create mode 100755 extensions/dataease-extensions-datasource/presto/presto-frontend/build/webpack.dev.conf.js create mode 100644 extensions/dataease-extensions-datasource/presto/presto-frontend/build/webpack.prod.conf.js create mode 100644 extensions/dataease-extensions-datasource/presto/presto-frontend/config/dev.env.js create mode 100644 extensions/dataease-extensions-datasource/presto/presto-frontend/config/index.js create mode 100644 extensions/dataease-extensions-datasource/presto/presto-frontend/config/prod.env.js create mode 100644 extensions/dataease-extensions-datasource/presto/presto-frontend/index.html create mode 100644 extensions/dataease-extensions-datasource/presto/presto-frontend/package.json create mode 100644 extensions/dataease-extensions-datasource/presto/presto-frontend/pom.xml create mode 100644 extensions/dataease-extensions-datasource/presto/presto-frontend/src/App.vue create mode 100644 extensions/dataease-extensions-datasource/presto/presto-frontend/src/assets/logo.png create mode 100644 extensions/dataease-extensions-datasource/presto/presto-frontend/src/components/HelloWorld.vue create mode 100644 extensions/dataease-extensions-datasource/presto/presto-frontend/src/de-base/lang/en.js create mode 100644 extensions/dataease-extensions-datasource/presto/presto-frontend/src/de-base/lang/index.js create mode 100644 extensions/dataease-extensions-datasource/presto/presto-frontend/src/de-base/lang/messages.js create mode 100644 extensions/dataease-extensions-datasource/presto/presto-frontend/src/de-base/lang/tw.js create mode 100644 extensions/dataease-extensions-datasource/presto/presto-frontend/src/de-base/lang/zh.js create mode 100644 extensions/dataease-extensions-datasource/presto/presto-frontend/src/icons/index.js create mode 100644 extensions/dataease-extensions-datasource/presto/presto-frontend/src/icons/svg/de_pwd_invisible.svg create mode 100644 extensions/dataease-extensions-datasource/presto/presto-frontend/src/icons/svg/de_pwd_visible.svg create mode 100644 extensions/dataease-extensions-datasource/presto/presto-frontend/src/icons/svg/presto-backend.svg create mode 100644 extensions/dataease-extensions-datasource/presto/presto-frontend/src/icons/svg/presto.jpg create mode 100644 extensions/dataease-extensions-datasource/presto/presto-frontend/src/icons/svgo.yml create mode 100644 extensions/dataease-extensions-datasource/presto/presto-frontend/src/main.js create mode 100644 extensions/dataease-extensions-datasource/presto/presto-frontend/src/router/index.js create mode 100644 extensions/dataease-extensions-datasource/presto/presto-frontend/src/utils/compare.js create mode 100644 extensions/dataease-extensions-datasource/presto/presto-frontend/src/utils/validate.js create mode 100644 extensions/dataease-extensions-datasource/presto/presto-frontend/src/views/dePwd.vue create mode 100644 extensions/dataease-extensions-datasource/presto/presto-frontend/src/views/presto.vue create mode 100644 extensions/dataease-extensions-view/pom.xml create mode 100644 extensions/dataease-extensions-view/view-3dpie/build.sh create mode 100644 extensions/dataease-extensions-view/view-3dpie/plugin.json create mode 100644 extensions/dataease-extensions-view/view-3dpie/pom.xml create mode 100644 extensions/dataease-extensions-view/view-3dpie/view-3dpie-backend/pom.xml create mode 100644 extensions/dataease-extensions-view/view-3dpie/view-3dpie-backend/src/main/java/io/dataease/plugins/view/official/impl/Pie3DService.java create mode 100644 extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/.babelrc create mode 100644 extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/.editorconfig create mode 100644 extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/.gitignore create mode 100644 extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/.postcssrc.js create mode 100644 extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/README.md create mode 100644 extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/build/build-async-plugins.js create mode 100644 extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/build/build.js create mode 100644 extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/build/check-versions.js create mode 100644 extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/build/logo.png create mode 100644 extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/build/utils.js create mode 100644 extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/build/vue-loader.conf.js create mode 100644 extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/build/webpack.async-plugins.js create mode 100644 extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/build/webpack.base.conf.js create mode 100755 extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/build/webpack.dev.conf.js create mode 100644 extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/build/webpack.prod.conf.js create mode 100644 extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/config/dev.env.js create mode 100644 extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/config/index.js create mode 100644 extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/config/prod.env.js create mode 100644 extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/index.html create mode 100644 extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/package.json create mode 100644 extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/pom.xml create mode 100644 extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/App.vue create mode 100644 extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/assets/logo.png create mode 100644 extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/components/HelloWorld.vue create mode 100644 extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/components/SvgIcon/index.vue create mode 100644 extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/components/selector/BackgroundColorSelector.vue create mode 100644 extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/components/selector/ColorSelector.vue create mode 100644 extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/components/selector/LabelSelector.vue create mode 100644 extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/components/selector/LegendSelector.vue create mode 100644 extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/components/selector/TitleSelector.vue create mode 100644 extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/components/selector/TooltipSelector.vue create mode 100644 extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/components/views/ChartDragItem.vue create mode 100644 extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/components/views/DimensionExtItem.vue create mode 100644 extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/components/views/DimensionItem.vue create mode 100644 extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/components/views/DrillItem.vue create mode 100644 extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/components/views/FieldErrorTips.vue create mode 100644 extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/components/views/FilterItem.vue create mode 100644 extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/components/views/QuotaExtItem.vue create mode 100644 extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/components/views/QuotaItem.vue create mode 100644 extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/components/views/ViewTrackBar.vue create mode 100644 extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/components/views/utils.js create mode 100644 extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/de-base/lang/en.js create mode 100644 extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/de-base/lang/index.js create mode 100644 extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/de-base/lang/messages.js create mode 100644 extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/de-base/lang/tw.js create mode 100644 extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/de-base/lang/zh.js create mode 100644 extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/icons/index.js create mode 100644 extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/icons/svg/3d-pie.svg create mode 100644 extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/icons/svg/view-3dpie-backend.svg create mode 100644 extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/icons/svgo.yml create mode 100644 extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/main.js create mode 100644 extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/router/index.js create mode 100644 extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/utils/3dpie.js create mode 100644 extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/utils/compare.js create mode 100644 extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/utils/map.js create mode 100644 extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/utils/validate.js create mode 100644 extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/views/PluginDemo.vue create mode 100644 extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/views/highcharts/3dpie/data.vue create mode 100644 extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/views/highcharts/3dpie/index.vue create mode 100644 extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/views/highcharts/3dpie/style.vue create mode 100644 extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/views/highcharts/3dpie/type.vue create mode 100644 extensions/dataease-extensions-view/view-bubblemap/build.sh create mode 100644 extensions/dataease-extensions-view/view-bubblemap/plugin.json create mode 100644 extensions/dataease-extensions-view/view-bubblemap/pom.xml create mode 100644 extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-backend/pom.xml create mode 100644 extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-backend/src/main/java/io/dataease/plugins/view/official/impl/BubbleMapService.java create mode 100644 extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-backend/src/main/resources/allatori/allatori.xml create mode 100644 extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-backend/src/main/resources/application.properties create mode 100644 extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/.babelrc create mode 100644 extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/.editorconfig create mode 100644 extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/.gitignore create mode 100644 extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/.postcssrc.js create mode 100644 extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/README.md create mode 100644 extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/build/build-async-plugins.js create mode 100644 extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/build/build.js create mode 100644 extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/build/check-versions.js create mode 100644 extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/build/logo.png create mode 100644 extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/build/utils.js create mode 100644 extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/build/vue-loader.conf.js create mode 100644 extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/build/webpack.async-plugins.js create mode 100644 extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/build/webpack.base.conf.js create mode 100755 extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/build/webpack.dev.conf.js create mode 100644 extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/build/webpack.prod.conf.js create mode 100644 extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/config/dev.env.js create mode 100644 extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/config/index.js create mode 100644 extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/config/prod.env.js create mode 100644 extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/index.html create mode 100644 extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/package.json create mode 100644 extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/pom.xml create mode 100644 extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/App.vue create mode 100644 extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/assets/logo.png create mode 100644 extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/components/HelloWorld.vue create mode 100644 extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/components/SvgIcon/index.vue create mode 100644 extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/components/selector/BackgroundColorSelector.vue create mode 100644 extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/components/selector/ColorSelector.vue create mode 100644 extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/components/selector/LabelSelector.vue create mode 100644 extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/components/selector/SuspensionSelector.vue create mode 100644 extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/components/selector/TitleSelector.vue create mode 100644 extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/components/selector/TooltipSelector.vue create mode 100644 extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/components/views/ChartDragItem.vue create mode 100644 extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/components/views/DimensionExtItem.vue create mode 100644 extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/components/views/DimensionItem.vue create mode 100644 extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/components/views/DrillItem.vue create mode 100644 extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/components/views/FieldErrorTips.vue create mode 100644 extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/components/views/FilterItem.vue create mode 100644 extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/components/views/QuotaExtItem.vue create mode 100644 extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/components/views/QuotaItem.vue create mode 100644 extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/components/views/ViewTrackBar.vue create mode 100644 extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/components/views/utils.js create mode 100644 extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/de-base/lang/en.js create mode 100644 extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/de-base/lang/index.js create mode 100644 extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/de-base/lang/messages.js create mode 100644 extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/de-base/lang/tw.js create mode 100644 extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/de-base/lang/zh.js create mode 100644 extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/icons/index.js create mode 100644 extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/icons/svg/buddle-map.svg create mode 100644 extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/icons/svg/view-bubblemap-backend.svg create mode 100644 extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/icons/svgo.yml create mode 100644 extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/main.js create mode 100644 extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/router/index.js create mode 100644 extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/utils/compare.js create mode 100644 extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/utils/map.js create mode 100644 extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/utils/nationalCenterPoint.js create mode 100644 extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/utils/validate.js create mode 100644 extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/views/PluginDemo.vue create mode 100644 extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/views/echarts/map/buddle/data.vue create mode 100644 extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/views/echarts/map/buddle/format.js create mode 100644 extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/views/echarts/map/buddle/index.vue create mode 100644 extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/views/echarts/map/buddle/style.vue create mode 100644 extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/views/echarts/map/buddle/type.vue create mode 100644 extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/views/echarts/map/test.vue create mode 100644 extensions/dataease-extensions-view/view-chartmix/build.sh create mode 100644 extensions/dataease-extensions-view/view-chartmix/plugin.json create mode 100644 extensions/dataease-extensions-view/view-chartmix/pom.xml create mode 100644 extensions/dataease-extensions-view/view-chartmix/view-chartmix-backend/pom.xml create mode 100644 extensions/dataease-extensions-view/view-chartmix/view-chartmix-backend/src/main/java/io/dataease/plugins/view/official/handler/DefaultViewStatHandler.java create mode 100644 extensions/dataease-extensions-view/view-chartmix/view-chartmix-backend/src/main/java/io/dataease/plugins/view/official/impl/ChartMixService.java create mode 100644 extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/.babelrc create mode 100644 extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/.editorconfig create mode 100644 extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/.gitignore create mode 100644 extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/.postcssrc.js create mode 100644 extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/README.md create mode 100644 extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/build/build-async-plugins.js create mode 100644 extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/build/build.js create mode 100644 extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/build/check-versions.js create mode 100644 extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/build/logo.png create mode 100644 extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/build/utils.js create mode 100644 extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/build/vue-loader.conf.js create mode 100644 extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/build/webpack.async-plugins.js create mode 100644 extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/build/webpack.base.conf.js create mode 100755 extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/build/webpack.dev.conf.js create mode 100644 extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/build/webpack.prod.conf.js create mode 100644 extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/config/dev.env.js create mode 100644 extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/config/index.js create mode 100644 extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/config/prod.env.js create mode 100644 extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/index.html create mode 100644 extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/package.json create mode 100644 extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/pom.xml create mode 100644 extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/App.vue create mode 100644 extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/assets/logo.png create mode 100644 extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/HelloWorld.vue create mode 100644 extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/SvgIcon/index.vue create mode 100644 extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/selector/BackgroundColorSelector.vue create mode 100644 extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/selector/ColorSelector.vue create mode 100644 extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/selector/LabelSelector.vue create mode 100644 extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/selector/LegendSelector.vue create mode 100644 extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/selector/SizeSelectorAntV.vue create mode 100644 extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/selector/TitleSelector.vue create mode 100644 extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/selector/TooltipSelector.vue create mode 100644 extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/selector/TooltipSelectorAntV.vue create mode 100644 extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/views/ChartDragItem.vue create mode 100644 extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/views/ChartTitleUpdate.vue create mode 100644 extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/views/DimensionExtItem.vue create mode 100644 extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/views/DrillItem.vue create mode 100644 extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/views/FieldErrorTips.vue create mode 100644 extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/views/FilterItem.vue create mode 100644 extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/views/LocationLineItem.vue create mode 100644 extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/views/QuotaExtItem.vue create mode 100644 extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/views/QuotaItem.vue create mode 100644 extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/views/SankeyDimensionItem.vue create mode 100644 extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/views/ViewTrackBar.vue create mode 100644 extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/views/utils.js create mode 100644 extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/de-base/lang/en.js create mode 100644 extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/de-base/lang/index.js create mode 100644 extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/de-base/lang/messages.js create mode 100644 extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/de-base/lang/tw.js create mode 100644 extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/de-base/lang/zh.js create mode 100644 extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/icons/index.js create mode 100644 extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/icons/svg/chart-mix.svg create mode 100644 extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/icons/svg/view-chart-mix-backend.svg create mode 100644 extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/icons/svgo.yml create mode 100644 extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/main.js create mode 100644 extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/router/index.js create mode 100644 extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/utils/chartmix.js create mode 100644 extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/utils/clickoutside.js create mode 100644 extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/utils/compare.js create mode 100644 extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/utils/formatter.js create mode 100644 extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/utils/map.js create mode 100644 extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/utils/validate.js create mode 100644 extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/views/PluginDemo.vue create mode 100644 extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/views/antv/chartmix/data.vue create mode 100644 extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/views/antv/chartmix/index.vue create mode 100644 extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/views/antv/chartmix/style.vue create mode 100644 extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/views/antv/chartmix/type.vue create mode 100644 extensions/dataease-extensions-view/view-racebar/build.sh create mode 100644 extensions/dataease-extensions-view/view-racebar/plugin.json create mode 100644 extensions/dataease-extensions-view/view-racebar/pom.xml create mode 100644 extensions/dataease-extensions-view/view-racebar/view-racebar-backend/pom.xml create mode 100644 extensions/dataease-extensions-view/view-racebar/view-racebar-backend/src/main/java/io/dataease/plugins/view/official/handler/DefaultViewStatHandler.java create mode 100644 extensions/dataease-extensions-view/view-racebar/view-racebar-backend/src/main/java/io/dataease/plugins/view/official/impl/RaceBarService.java create mode 100644 extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/.babelrc create mode 100644 extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/.editorconfig create mode 100644 extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/.gitignore create mode 100644 extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/.postcssrc.js create mode 100644 extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/README.md create mode 100644 extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/build/build-async-plugins.js create mode 100644 extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/build/build.js create mode 100644 extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/build/check-versions.js create mode 100644 extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/build/logo.png create mode 100644 extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/build/utils.js create mode 100644 extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/build/vue-loader.conf.js create mode 100644 extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/build/webpack.async-plugins.js create mode 100644 extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/build/webpack.base.conf.js create mode 100755 extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/build/webpack.dev.conf.js create mode 100644 extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/build/webpack.prod.conf.js create mode 100644 extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/config/dev.env.js create mode 100644 extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/config/index.js create mode 100644 extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/config/prod.env.js create mode 100644 extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/index.html create mode 100644 extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/package.json create mode 100644 extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/pom.xml create mode 100644 extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/App.vue create mode 100644 extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/assets/logo.png create mode 100644 extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/HelloWorld.vue create mode 100644 extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/SvgIcon/index.vue create mode 100644 extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/selector/BackgroundColorSelector.vue create mode 100644 extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/selector/ColorSelector.vue create mode 100644 extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/selector/GraphicSetting.vue create mode 100644 extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/selector/LabelSelector.vue create mode 100644 extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/selector/LegendSelector.vue create mode 100644 extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/selector/MarginSelector.vue create mode 100644 extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/selector/SizeSelectorAntV.vue create mode 100644 extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/selector/SliderSetting.vue create mode 100644 extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/selector/TitleSelector.vue create mode 100644 extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/selector/TooltipSelector.vue create mode 100644 extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/selector/XAxisSelector.vue create mode 100644 extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/selector/YAxisSelector.vue create mode 100644 extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/views/ChartDragItem.vue create mode 100644 extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/views/ChartTitleUpdate.vue create mode 100644 extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/views/DimensionExtItem.vue create mode 100644 extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/views/DimensionItem.vue create mode 100644 extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/views/DrillItem.vue create mode 100644 extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/views/FieldErrorTips.vue create mode 100644 extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/views/FilterItem.vue create mode 100644 extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/views/LocationLineItem.vue create mode 100644 extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/views/QuotaExtItem.vue create mode 100644 extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/views/QuotaItem.vue create mode 100644 extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/views/ViewTrackBar.vue create mode 100644 extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/views/utils.js create mode 100644 extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/de-base/lang/en.js create mode 100644 extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/de-base/lang/index.js create mode 100644 extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/de-base/lang/messages.js create mode 100644 extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/de-base/lang/tw.js create mode 100644 extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/de-base/lang/zh.js create mode 100644 extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/icons/index.js create mode 100644 extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/icons/svg/race-bar.svg create mode 100644 extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/icons/svg/view-race-bar-backend.svg create mode 100644 extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/icons/svgo.yml create mode 100644 extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/main.js create mode 100644 extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/router/index.js create mode 100644 extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/utils/clickoutside.js create mode 100644 extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/utils/compare.js create mode 100644 extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/utils/formatter.js create mode 100644 extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/utils/map.js create mode 100644 extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/utils/validate.js create mode 100644 extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/views/PluginDemo.vue create mode 100644 extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/views/antv/racebar/data.vue create mode 100644 extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/views/antv/racebar/index.vue create mode 100644 extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/views/antv/racebar/style.vue create mode 100644 extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/views/antv/racebar/type.vue create mode 100644 extensions/dataease-extensions-view/view-sankey/build.sh create mode 100644 extensions/dataease-extensions-view/view-sankey/plugin.json create mode 100644 extensions/dataease-extensions-view/view-sankey/pom.xml create mode 100644 extensions/dataease-extensions-view/view-sankey/view-sankey-backend/pom.xml create mode 100644 extensions/dataease-extensions-view/view-sankey/view-sankey-backend/src/main/java/io/dataease/plugins/view/official/impl/SankeyService.java create mode 100644 extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/.babelrc create mode 100644 extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/.editorconfig create mode 100644 extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/.gitignore create mode 100644 extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/.postcssrc.js create mode 100644 extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/README.md create mode 100644 extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/build/build-async-plugins.js create mode 100644 extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/build/build.js create mode 100644 extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/build/check-versions.js create mode 100644 extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/build/logo.png create mode 100644 extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/build/utils.js create mode 100644 extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/build/vue-loader.conf.js create mode 100644 extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/build/webpack.async-plugins.js create mode 100644 extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/build/webpack.base.conf.js create mode 100755 extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/build/webpack.dev.conf.js create mode 100644 extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/build/webpack.prod.conf.js create mode 100644 extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/config/dev.env.js create mode 100644 extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/config/index.js create mode 100644 extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/config/prod.env.js create mode 100644 extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/index.html create mode 100644 extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/package.json create mode 100644 extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/pom.xml create mode 100644 extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/App.vue create mode 100644 extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/assets/logo.png create mode 100644 extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/HelloWorld.vue create mode 100644 extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/SvgIcon/index.vue create mode 100644 extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/selector/BackgroundColorSelector.vue create mode 100644 extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/selector/ColorSelector.vue create mode 100644 extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/selector/LabelSelector.vue create mode 100644 extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/selector/LegendSelector.vue create mode 100644 extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/selector/SizeSelectorAntV.vue create mode 100644 extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/selector/TitleSelector.vue create mode 100644 extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/selector/TooltipSelector.vue create mode 100644 extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/selector/TooltipSelectorAntV.vue create mode 100644 extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/views/ChartDragItem.vue create mode 100644 extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/views/ChartTitleUpdate.vue create mode 100644 extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/views/DimensionExtItem.vue create mode 100644 extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/views/DrillItem.vue create mode 100644 extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/views/FieldErrorTips.vue create mode 100644 extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/views/FilterItem.vue create mode 100644 extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/views/LocationLineItem.vue create mode 100644 extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/views/QuotaExtItem.vue create mode 100644 extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/views/SankeyDimensionItem.vue create mode 100644 extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/views/SankeyQuotaItem.vue create mode 100644 extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/views/ViewTrackBar.vue create mode 100644 extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/views/utils.js create mode 100644 extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/de-base/lang/en.js create mode 100644 extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/de-base/lang/index.js create mode 100644 extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/de-base/lang/messages.js create mode 100644 extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/de-base/lang/tw.js create mode 100644 extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/de-base/lang/zh.js create mode 100644 extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/icons/index.js create mode 100644 extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/icons/svg/sankey.svg create mode 100644 extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/icons/svg/view-sankey-backend.svg create mode 100644 extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/icons/svgo.yml create mode 100644 extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/main.js create mode 100644 extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/router/index.js create mode 100644 extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/utils/clickoutside.js create mode 100644 extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/utils/compare.js create mode 100644 extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/utils/map.js create mode 100644 extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/utils/sankey.js create mode 100644 extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/utils/validate.js create mode 100644 extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/views/PluginDemo.vue create mode 100644 extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/views/antv/sankey/data.vue create mode 100644 extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/views/antv/sankey/index.vue create mode 100644 extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/views/antv/sankey/style.vue create mode 100644 extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/views/antv/sankey/type.vue create mode 100644 extensions/dataease-extensions-view/view-symbolmap/build.sh create mode 100644 extensions/dataease-extensions-view/view-symbolmap/plugin.json create mode 100644 extensions/dataease-extensions-view/view-symbolmap/pom.xml create mode 100644 extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-backend/pom.xml create mode 100644 extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-backend/src/main/java/io/dataease/plugins/view/official/dto/SymbolMapResultDTO.java create mode 100644 extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-backend/src/main/java/io/dataease/plugins/view/official/handler/SymbolMapRSHandler.java create mode 100644 extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-backend/src/main/java/io/dataease/plugins/view/official/handler/SymbolMapStatHandler.java create mode 100644 extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-backend/src/main/java/io/dataease/plugins/view/official/impl/SymbolMapService.java create mode 100644 extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/.babelrc create mode 100644 extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/.editorconfig create mode 100644 extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/.gitignore create mode 100644 extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/.postcssrc.js create mode 100644 extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/README.md create mode 100644 extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/build/build-async-plugins.js create mode 100644 extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/build/build.js create mode 100644 extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/build/check-versions.js create mode 100644 extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/build/logo.png create mode 100644 extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/build/utils.js create mode 100644 extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/build/vue-loader.conf.js create mode 100644 extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/build/webpack.async-plugins.js create mode 100644 extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/build/webpack.base.conf.js create mode 100755 extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/build/webpack.dev.conf.js create mode 100644 extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/build/webpack.prod.conf.js create mode 100644 extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/config/dev.env.js create mode 100644 extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/config/index.js create mode 100644 extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/config/prod.env.js create mode 100644 extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/index.html create mode 100644 extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/package.json create mode 100644 extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/pom.xml create mode 100644 extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/App.vue create mode 100644 extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/assets/logo.png create mode 100644 extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/HelloWorld.vue create mode 100644 extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/SvgIcon/index.vue create mode 100644 extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/selector/BackgroundColorSelector.vue create mode 100644 extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/selector/BaseMapStyleSelector.vue create mode 100644 extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/selector/ColorSelector.vue create mode 100644 extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/selector/LabelSelector.vue create mode 100644 extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/selector/LegendSelector.vue create mode 100644 extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/selector/SizeSelectorAntV.vue create mode 100644 extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/selector/TitleSelector.vue create mode 100644 extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/selector/TooltipSelector.vue create mode 100644 extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/selector/TooltipSelectorAntV.vue create mode 100644 extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/views/ChartDragItem.vue create mode 100644 extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/views/DimensionExtItem.vue create mode 100644 extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/views/DrillItem.vue create mode 100644 extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/views/FieldErrorTips.vue create mode 100644 extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/views/FilterItem.vue create mode 100644 extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/views/LocationLineItem.vue create mode 100644 extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/views/LocationXItem.vue create mode 100644 extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/views/LocationYItem.vue create mode 100644 extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/views/QuotaExtItem.vue create mode 100644 extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/views/QuotaItem.vue create mode 100644 extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/views/ViewTrackBar.vue create mode 100644 extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/views/utils.js create mode 100644 extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/de-base/lang/en.js create mode 100644 extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/de-base/lang/index.js create mode 100644 extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/de-base/lang/messages.js create mode 100644 extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/de-base/lang/tw.js create mode 100644 extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/de-base/lang/zh.js create mode 100644 extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/icons/index.js create mode 100644 extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/icons/svg/map-marker-old.svg create mode 100644 extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/icons/svg/map-marker.png create mode 100644 extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/icons/svg/map-marker.svg create mode 100644 extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/icons/svg/symbol-map.svg create mode 100644 extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/icons/svg/view-symbolmap-backend.svg create mode 100644 extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/icons/svgo.yml create mode 100644 extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/main.js create mode 100644 extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/router/index.js create mode 100644 extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/utils/compare.js create mode 100644 extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/utils/map.js create mode 100644 extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/utils/symbolmap.js create mode 100644 extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/utils/validate.js create mode 100644 extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/views/PluginDemo.vue create mode 100644 extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/views/antv/symbolmap/data.vue create mode 100644 extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/views/antv/symbolmap/index.vue create mode 100644 extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/views/antv/symbolmap/style.vue create mode 100644 extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/views/antv/symbolmap/type.vue create mode 100644 extensions/pom.xml diff --git a/extensions/.gitignore b/extensions/.gitignore new file mode 100644 index 0000000000..30d79216dd --- /dev/null +++ b/extensions/.gitignore @@ -0,0 +1,58 @@ +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +#*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* +/.idea/ +target/ +*.iml +.DS_Store +node_modules +/dist +node/ +static/ +# local env files +.env.demo +.env.*.local + +# Log files +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* + +# Editor directories and files +.idea +.vscode +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? +*.lock +*.classpath +*.project +*.factorypath +.settings/ +.lh + + +package-lock.json diff --git a/extensions/README.md b/extensions/README.md new file mode 100644 index 0000000000..50b8e1189f --- /dev/null +++ b/extensions/README.md @@ -0,0 +1,19 @@ +# DateEase 官方插件 + +此仓库用于放置 DataEase 官方插件,插件分为两种类型:数据源插件和视图插件。 + +当前以插件方式支持的数据源包括: + + - 达梦数据库 + - Apache Kylin + - 阿里云 MaxCompute + - MongoDB + - Presto + +当前已插件方式支持的视图包括: + + - 3dpie + - bubblemap + - symbolmap + +更多插件持续开发中,敬请期待。 diff --git a/extensions/dataease-extensions-datasource/dm/.gitignore b/extensions/dataease-extensions-datasource/dm/.gitignore new file mode 100644 index 0000000000..a5a2b0c056 --- /dev/null +++ b/extensions/dataease-extensions-datasource/dm/.gitignore @@ -0,0 +1,35 @@ +# Created by .ignore support plugin (hsz.mobi) +.DS_Store +node_modules +node/ +/dist + +# local env files +.env.local +.env.*.local + +# Log files +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Editor directories and files +.idea +*.iml +.vscode +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? + + +src/main/resources/static +src/main/resources/templates +src/test/ +target +.settings +.project +.classpath +.factorypath +src/main/resources/jmeter/lib/ \ No newline at end of file diff --git a/extensions/dataease-extensions-datasource/dm/build.sh b/extensions/dataease-extensions-datasource/dm/build.sh new file mode 100755 index 0000000000..e77b784305 --- /dev/null +++ b/extensions/dataease-extensions-datasource/dm/build.sh @@ -0,0 +1,6 @@ +#!/bin/sh +mvn clean package -U -Dmaven.test.skip=true + +cp dm-backend/target/dm-backend-1.18.0.jar . + +zip -r dm.zip ./dm-backend-1.18.0.jar ./dmDriver ./plugin.json diff --git a/extensions/dataease-extensions-datasource/dm/dm-backend/pom.xml b/extensions/dataease-extensions-datasource/dm/dm-backend/pom.xml new file mode 100644 index 0000000000..b92b653718 --- /dev/null +++ b/extensions/dataease-extensions-datasource/dm/dm-backend/pom.xml @@ -0,0 +1,109 @@ + + + + dm + io.dataease + ${dataease.version} + + 4.0.0 + + dm-backend + + + + io.dataease + dataease-plugin-datasource + + + + + + + src/main/java + + **/*.properties + **/*.xml + + false + + + src/main/resources + + **/* + + false + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 11 + 11 + + + + + org.apache.maven.plugins + maven-jar-plugin + 2.4 + + + **/server/** + **/*.properties + **/Application* + + + + + + maven-clean-plugin + + + + src/main/resources/static + + ** + + false + + + + + + + + + org.apache.maven.plugins + maven-antrun-plugin + + + main-class-placement + generate-resources + + + + + + + + + + + + run + + + + + + + + + + + diff --git a/extensions/dataease-extensions-datasource/dm/dm-backend/src/main/java/io/dataease/plugins/datasource/dm/provider/DmConfig.java b/extensions/dataease-extensions-datasource/dm/dm-backend/src/main/java/io/dataease/plugins/datasource/dm/provider/DmConfig.java new file mode 100644 index 0000000000..e1d07a3167 --- /dev/null +++ b/extensions/dataease-extensions-datasource/dm/dm-backend/src/main/java/io/dataease/plugins/datasource/dm/provider/DmConfig.java @@ -0,0 +1,21 @@ +package io.dataease.plugins.datasource.dm.provider; + +import io.dataease.plugins.datasource.entity.JdbcConfiguration; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class DmConfig extends JdbcConfiguration { + + private String driver = "dm.jdbc.driver.DmDriver"; + private String extraParams; + + + public String getJdbc() { + return "jdbc:dm://HOST:PORT/DATABASE" + .replace("HOST", getHost().trim()) + .replace("PORT", getPort().toString()) + .replace("DATABASE", getDataBase().trim()); + } +} diff --git a/extensions/dataease-extensions-datasource/dm/dm-backend/src/main/java/io/dataease/plugins/datasource/dm/provider/DmDsProvider.java b/extensions/dataease-extensions-datasource/dm/dm-backend/src/main/java/io/dataease/plugins/datasource/dm/provider/DmDsProvider.java new file mode 100644 index 0000000000..35acaa981a --- /dev/null +++ b/extensions/dataease-extensions-datasource/dm/dm-backend/src/main/java/io/dataease/plugins/datasource/dm/provider/DmDsProvider.java @@ -0,0 +1,226 @@ +package io.dataease.plugins.datasource.dm.provider; + +import com.google.gson.Gson; +import io.dataease.plugins.common.base.domain.DeDriver; +import io.dataease.plugins.common.base.mapper.DeDriverMapper; +import io.dataease.plugins.common.constants.DatasourceTypes; +import io.dataease.plugins.common.dto.datasource.TableDesc; +import io.dataease.plugins.common.dto.datasource.TableField; +import io.dataease.plugins.common.exception.DataEaseException; +import io.dataease.plugins.common.request.datasource.DatasourceRequest; +import io.dataease.plugins.datasource.entity.JdbcConfiguration; +import io.dataease.plugins.datasource.provider.DefaultJdbcProvider; +import io.dataease.plugins.datasource.provider.ExtendedJdbcClassLoader; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.lang.reflect.Method; +import java.sql.*; +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.Properties; + + +@Component() +public class DmDsProvider extends DefaultJdbcProvider { + @Resource + private DeDriverMapper deDriverMapper; + + @Override + public String getType() { + return "dm"; + } + + @Override + public boolean isUseDatasourcePool() { + return false; + } + + @Override + public Connection getConnection(DatasourceRequest datasourceRequest) throws Exception { + DmConfig dmConfig = new Gson().fromJson(datasourceRequest.getDatasource().getConfiguration(), DmConfig.class); + + String defaultDriver = dmConfig.getDriver(); + String customDriver = dmConfig.getCustomDriver(); + + String url = dmConfig.getJdbc(); + Properties props = new Properties(); + DeDriver deDriver = null; + if (StringUtils.isNotEmpty(dmConfig.getAuthMethod()) && dmConfig.getAuthMethod().equalsIgnoreCase("kerberos")) { + System.setProperty("java.security.krb5.conf", "/opt/dataease/conf/krb5.conf"); + ExtendedJdbcClassLoader classLoader; + if (isDefaultClassLoader(customDriver)) { + classLoader = extendedJdbcClassLoader; + } else { + deDriver = deDriverMapper.selectByPrimaryKey(customDriver); + classLoader = getCustomJdbcClassLoader(deDriver); + } + Class ConfigurationClass = classLoader.loadClass("org.apache.hadoop.conf.Configuration"); + Method set = ConfigurationClass.getMethod("set", String.class, String.class); + Object obj = ConfigurationClass.newInstance(); + set.invoke(obj, "hadoop.security.authentication", "Kerberos"); + + Class UserGroupInformationClass = classLoader.loadClass("org.apache.hadoop.security.UserGroupInformation"); + Method setConfiguration = UserGroupInformationClass.getMethod("setConfiguration", ConfigurationClass); + Method loginUserFromKeytab = UserGroupInformationClass.getMethod("loginUserFromKeytab", String.class, String.class); + setConfiguration.invoke(null, obj); + loginUserFromKeytab.invoke(null, dmConfig.getUsername(), "/opt/dataease/conf/" + dmConfig.getPassword()); + } else { + if (StringUtils.isNotBlank(dmConfig.getUsername())) { + props.setProperty("user", dmConfig.getUsername()); + if (StringUtils.isNotBlank(dmConfig.getPassword())) { + props.setProperty("password", dmConfig.getPassword()); + } + } + } + + Connection conn; + String driverClassName; + ExtendedJdbcClassLoader jdbcClassLoader; + if (isDefaultClassLoader(customDriver)) { + driverClassName = defaultDriver; + jdbcClassLoader = extendedJdbcClassLoader; + } else { + if (deDriver == null) { + deDriver = deDriverMapper.selectByPrimaryKey(customDriver); + } + driverClassName = deDriver.getDriverClass(); + jdbcClassLoader = getCustomJdbcClassLoader(deDriver); + } + + Driver driverClass = (Driver) jdbcClassLoader.loadClass(driverClassName).newInstance(); + ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + try { + Thread.currentThread().setContextClassLoader(jdbcClassLoader); + conn = driverClass.connect(url, props); + } catch (Exception e) { + e.printStackTrace(); + throw e; + } finally { + Thread.currentThread().setContextClassLoader(classLoader); + } + return conn; + } + + @Override + public List getTables(DatasourceRequest datasourceRequest) throws Exception { + List tables = new ArrayList<>(); + String queryStr = getTablesSql(datasourceRequest); + JdbcConfiguration jdbcConfiguration = new Gson().fromJson(datasourceRequest.getDatasource().getConfiguration(), JdbcConfiguration.class); + int queryTimeout = jdbcConfiguration.getQueryTimeout() > 0 ? jdbcConfiguration.getQueryTimeout() : 0; + try (Connection con = getConnectionFromPool(datasourceRequest); Statement statement = getStatement(con, queryTimeout); ResultSet resultSet = statement.executeQuery(queryStr)) { + while (resultSet.next()) { + tables.add(getTableDesc(datasourceRequest, resultSet)); + } + } catch (Exception e) { + DataEaseException.throwException(e); + } + + return tables; + } + + private TableDesc getTableDesc(DatasourceRequest datasourceRequest, ResultSet resultSet) throws SQLException { + TableDesc tableDesc = new TableDesc(); + tableDesc.setName(resultSet.getString(1)); + return tableDesc; + } + + @Override + public List getTableFields(DatasourceRequest datasourceRequest) throws Exception { + List list = new LinkedList<>(); + try (Connection connection = getConnectionFromPool(datasourceRequest)) { + DatabaseMetaData databaseMetaData = connection.getMetaData(); + ResultSet resultSet = databaseMetaData.getColumns(null, "%", datasourceRequest.getTable(), "%"); + while (resultSet.next()) { + String tableName = resultSet.getString("TABLE_NAME"); + String database; + database = resultSet.getString("TABLE_CAT"); + if (database != null) { + if (tableName.equals(datasourceRequest.getTable()) && database.equalsIgnoreCase(getDatabase(datasourceRequest))) { + TableField tableField = getTableFiled(resultSet, datasourceRequest); + list.add(tableField); + } + } else { + if (tableName.equals(datasourceRequest.getTable())) { + TableField tableField = getTableFiled(resultSet, datasourceRequest); + list.add(tableField); + } + } + } + resultSet.close(); + } catch (SQLException e) { + DataEaseException.throwException(e); + } catch (Exception e) { + DataEaseException.throwException("Data source connection exception: " + e.getMessage()); + } + return list; + } + + private String getDatabase(DatasourceRequest datasourceRequest) { + JdbcConfiguration jdbcConfiguration = new Gson().fromJson(datasourceRequest.getDatasource().getConfiguration(), JdbcConfiguration.class); + return jdbcConfiguration.getDataBase(); + } + + + private TableField getTableFiled(ResultSet resultSet, DatasourceRequest datasourceRequest) throws SQLException { + TableField tableField = new TableField(); + String colName = resultSet.getString("COLUMN_NAME"); + tableField.setFieldName(colName); + String remarks = resultSet.getString("REMARKS"); + if (remarks == null || remarks.equals("")) { + remarks = colName; + } + tableField.setRemarks(remarks); + String dbType = resultSet.getString("TYPE_NAME").toUpperCase(); + tableField.setFieldType(dbType); + if (dbType.equalsIgnoreCase("LONG")) { + tableField.setFieldSize(65533); + } + if (StringUtils.isNotEmpty(dbType) && dbType.toLowerCase().contains("date") && tableField.getFieldSize() < 50) { + tableField.setFieldSize(50); + } + + if (datasourceRequest.getDatasource().getType().equalsIgnoreCase(DatasourceTypes.hive.name()) && tableField.getFieldType().equalsIgnoreCase("BOOLEAN")) { + tableField.setFieldSize(1); + } else { + String size = resultSet.getString("COLUMN_SIZE"); + if (size == null) { + tableField.setFieldSize(1); + } else { + tableField.setFieldSize(Integer.valueOf(size)); + } + } + return tableField; + } + + @Override + public String checkStatus(DatasourceRequest datasourceRequest) throws Exception { + String queryStr = getTablesSql(datasourceRequest); + JdbcConfiguration jdbcConfiguration = new Gson().fromJson(datasourceRequest.getDatasource().getConfiguration(), JdbcConfiguration.class); + int queryTimeout = jdbcConfiguration.getQueryTimeout() > 0 ? jdbcConfiguration.getQueryTimeout() : 0; + try (Connection con = getConnection(datasourceRequest); Statement statement = getStatement(con, queryTimeout); ResultSet resultSet = statement.executeQuery(queryStr)) { + } catch (Exception e) { + e.printStackTrace(); + DataEaseException.throwException(e.getMessage()); + } + return "Success"; + } + + + @Override + public String getTablesSql(DatasourceRequest datasourceRequest) throws Exception { + DmConfig dmConfig = new Gson().fromJson(datasourceRequest.getDatasource().getConfiguration(), DmConfig.class); + if (StringUtils.isEmpty(dmConfig.getSchema())) { + throw new Exception("Database schema is empty."); + } + return "select table_name from all_tab_comments where owner='OWNER' AND table_type = 'TABLE' ".replaceAll("OWNER", dmConfig.getSchema()); + } + + @Override + public String getSchemaSql(DatasourceRequest datasourceRequest) { + return "select OBJECT_NAME from dba_objects where object_type='SCH'"; + } + +} diff --git a/extensions/dataease-extensions-datasource/dm/dm-backend/src/main/java/io/dataease/plugins/datasource/dm/query/DmConstants.java b/extensions/dataease-extensions-datasource/dm/dm-backend/src/main/java/io/dataease/plugins/datasource/dm/query/DmConstants.java new file mode 100644 index 0000000000..d067905573 --- /dev/null +++ b/extensions/dataease-extensions-datasource/dm/dm-backend/src/main/java/io/dataease/plugins/datasource/dm/query/DmConstants.java @@ -0,0 +1,61 @@ +package io.dataease.plugins.datasource.dm.query; + + + +import io.dataease.plugins.common.constants.datasource.SQLConstants; + +import static io.dataease.plugins.common.constants.DatasourceTypes.oracle; + +public class DmConstants extends SQLConstants { + + public static final String KEYWORD_TABLE = oracle.getKeywordPrefix() + "%s" + oracle.getKeywordSuffix(); + + public static final String KEYWORD_FIX = "%s." + oracle.getKeywordPrefix() + "%s" + oracle.getKeywordSuffix(); + + public static final String ALIAS_FIX = oracle.getAliasPrefix() + "%s" + oracle.getAliasSuffix(); + + public static final String UNIX_TIMESTAMP = "UNIX_TIMESTAMP(%s)"; + + public static final String DATE_FORMAT = "to_timestamp(%s,'%s')"; + + public static final String FROM_UNIXTIME = "FROM_UNIXTIME(%s,'%s')"; + + public static final String CAST = "CAST(%s AS %s)"; + + public static final String DEFAULT_DATE_FORMAT = "YYYY-MM-DD HH24:MI:SS"; + + public static final String DEFAULT_INT_FORMAT = "DECIMAL(20,0)"; + + public static final String DEFAULT_FLOAT_FORMAT = "DECIMAL(20,8)"; + + public static final String WHERE_VALUE_NULL = "(NULL,'')"; + + public static final String WHERE_VALUE_VALUE = "'%s'"; + + public static final String AGG_COUNT = "COUNT(*)"; + + public static final String AGG_FIELD = "%s(%s)"; + + public static final String WHERE_BETWEEN = "'%s' AND '%s'"; + + public static final String BRACKETS = "(%s)"; + + public static final String TO_NUMBER = "TO_NUMBER(%s)"; + + public static final String TO_DATE = "TO_DATE(%s,'%s')"; + + public static final String TO_CHAR = "TO_CHAR(%s,'%s')"; + + public static final String DEFAULT_START_DATE = "'1970-01-01 8:0:0'"; + + public static final String TO_MS = " * 24 * 60 * 60 * 100"; + + public static final String CALC_SUB = "%s - %s"; + + // public static final String GROUP_CONCAT = "vm_concat(%s)"; + public static final String GROUP_CONCAT = "to_char(listagg(%s,',' ) within GROUP (order by (%s)))"; + + public static final String NAME = "oracle"; + + +} diff --git a/extensions/dataease-extensions-datasource/dm/dm-backend/src/main/java/io/dataease/plugins/datasource/dm/query/DmQueryProvider.java b/extensions/dataease-extensions-datasource/dm/dm-backend/src/main/java/io/dataease/plugins/datasource/dm/query/DmQueryProvider.java new file mode 100644 index 0000000000..e43bea7a80 --- /dev/null +++ b/extensions/dataease-extensions-datasource/dm/dm-backend/src/main/java/io/dataease/plugins/datasource/dm/query/DmQueryProvider.java @@ -0,0 +1,1558 @@ +package io.dataease.plugins.datasource.dm.query; + +import cn.hutool.json.JSONArray; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.gson.Gson; +import io.dataease.plugins.common.base.domain.ChartViewWithBLOBs; +import io.dataease.plugins.common.base.domain.DatasetTableField; +import io.dataease.plugins.common.base.domain.DatasetTableFieldExample; +import io.dataease.plugins.common.base.domain.Datasource; +import io.dataease.plugins.common.base.mapper.DatasetTableFieldMapper; +import io.dataease.plugins.common.constants.DeTypeConstants; +import io.dataease.plugins.common.constants.datasource.OracleConstants; +import io.dataease.plugins.common.constants.datasource.SQLConstants; +import io.dataease.plugins.common.dto.chart.ChartCustomFilterItemDTO; +import io.dataease.plugins.common.dto.chart.ChartFieldCustomFilterDTO; +import io.dataease.plugins.common.dto.chart.ChartViewFieldDTO; +import io.dataease.plugins.common.dto.datasource.DeSortField; +import io.dataease.plugins.common.dto.sqlObj.SQLObj; +import io.dataease.plugins.common.request.chart.ChartExtFilterRequest; +import io.dataease.plugins.common.request.permission.DataSetRowPermissionsTreeDTO; +import io.dataease.plugins.common.request.permission.DatasetRowPermissionsTreeItem; +import io.dataease.plugins.datasource.dm.provider.DmConfig; +import io.dataease.plugins.datasource.entity.Dateformat; +import io.dataease.plugins.datasource.entity.JdbcConfiguration; +import io.dataease.plugins.datasource.entity.PageInfo; +import io.dataease.plugins.datasource.query.QueryProvider; +import io.dataease.plugins.datasource.query.Utils; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.ObjectUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Component; +import org.stringtemplate.v4.ST; +import org.stringtemplate.v4.STGroup; +import org.stringtemplate.v4.STGroupFile; + +import javax.annotation.Resource; +import java.text.MessageFormat; +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +import static io.dataease.plugins.common.constants.datasource.SQLConstants.TABLE_ALIAS_PREFIX; + +/** + * @Author gin + * @Date 2021/5/17 2:43 下午 + */ +@Component() +public class DmQueryProvider extends QueryProvider { + + @Resource + private DatasetTableFieldMapper datasetTableFieldMapper; + + @Override + public Integer transFieldType(String field) { + switch (field) { + case "CHAR": + case "VARCHAR2": + case "VARCHAR": + case "TEXT": + case "TINYTEXT": + case "MEDIUMTEXT": + case "LONGTEXT": + case "ENUM": + case "LONG": + case "NVARCHAR2": + case "NCHAR": + return 0;// 文本 + case "DATE": + case "TIME": + case "YEAR": + case "DATETIME": + case "TIMESTAMP": + return 1;// 时间 + case "INT": + case "SMALLINT": + case "MEDIUMINT": + case "INTEGER": + case "BIGINT": + return 2;// 整型 + case "NUMBER": + case "FLOAT": + case "DOUBLE": + case "DECIMAL": + case "DEC": + case "NUMERIC": + return 3;// 浮点 + case "BIT": + case "TINYINT": + return 4;// 布尔 + default: + return 0; + } + } + + @Override + public String createSQLPreview(String sql, String orderBy) { + return "SELECT * FROM (" + sqlFix(sql) + ") DE_TMP " + " WHERE rownum <= 1000"; + } + + @Override + public String createQuerySQL(String table, List fields, boolean isGroup, Datasource ds, + List fieldCustomFilter, List rowPermissionsTree, List sortFields) { + SQLObj tableObj = SQLObj.builder() + .tableName((table.startsWith("(") && table.endsWith(")")) ? table + : String.format(OracleConstants.KEYWORD_TABLE, table)) + .tableAlias(String.format(OracleConstants.ALIAS_FIX, String.format(TABLE_ALIAS_PREFIX, 0))) + .build(); + + setSchema(tableObj, ds); + List xFields = xFields(table, fields); + + STGroup stg = new STGroupFile(SQLConstants.SQL_TEMPLATE); + ST st_sql = stg.getInstanceOf("previewSql"); + st_sql.add("isGroup", isGroup); + if (CollectionUtils.isNotEmpty(xFields)) + st_sql.add("groups", xFields); + if (ObjectUtils.isNotEmpty(tableObj)) + st_sql.add("table", tableObj); + String customWheres = transCustomFilterList(tableObj, fieldCustomFilter); + // row permissions tree + String whereTrees = transFilterTrees(tableObj, rowPermissionsTree); + List wheres = new ArrayList<>(); + if (customWheres != null) + wheres.add(customWheres); + if (whereTrees != null) + wheres.add(whereTrees); + if (CollectionUtils.isNotEmpty(wheres)) + st_sql.add("filters", wheres); + + List xOrders = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(sortFields)) { + int step = fields.size(); + for (int i = step; i < (step + sortFields.size()); i++) { + DeSortField deSortField = sortFields.get(i - step); + SQLObj order = buildSortField(deSortField, tableObj, i); + xOrders.add(order); + } + } + if (ObjectUtils.isNotEmpty(xOrders)) { + st_sql.add("orders", xOrders); + } + return st_sql.render(); + } + + @Override + public String createQuerySQL(String table, List fields, boolean isGroup, Datasource ds, + List fieldCustomFilter, List rowPermissionsTree) { + return createQuerySQL(table, fields, isGroup, ds, fieldCustomFilter, rowPermissionsTree, null); + } + + @Override + public String createQuerySQLAsTmp(String sql, List fields, boolean isGroup, + List fieldCustomFilter, List rowPermissionsTree, List sortFields) { + return createQuerySQL("(" + sqlFix(sql) + ")", fields, isGroup, null, fieldCustomFilter, rowPermissionsTree, sortFields); + } + + public void setSchema(SQLObj tableObj, Datasource ds) { + if (ds != null && !tableObj.getTableName().startsWith("(") && !tableObj.getTableName().endsWith(")")) { + String schema = new Gson().fromJson(ds.getConfiguration(), JdbcConfiguration.class).getSchema(); + schema = String.format(OracleConstants.KEYWORD_TABLE, schema); + tableObj.setTableName(schema + "." + tableObj.getTableName()); + } + } + + private SQLObj buildSortField(DeSortField f, SQLObj tableObj, int index) { + String originField; + if (ObjectUtils.isNotEmpty(f.getExtField()) && f.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originField = calcFieldRegex(f.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(f.getExtField()) && f.getExtField() == 1) { + originField = String.format(OracleConstants.KEYWORD_FIX, tableObj.getTableAlias(), f.getOriginName()); + } else { + originField = String.format(OracleConstants.KEYWORD_FIX, tableObj.getTableAlias(), f.getOriginName()); + } + String fieldAlias = String.format(OracleConstants.ALIAS_FIX, + String.format(SQLConstants.FIELD_ALIAS_X_PREFIX, index)); + String fieldName = ""; + // 处理横轴字段 + if (f.getDeExtractType() == 1) { + if (f.getDeType() == 2 || f.getDeType() == 3) { + fieldName = String.format(OracleConstants.UNIX_TIMESTAMP, originField) + "*1000"; + } else { + fieldName = originField; + } + } else if (f.getDeExtractType() == 0) { + if (f.getDeType() == 2) { + fieldName = String.format(OracleConstants.CAST, originField, OracleConstants.DEFAULT_INT_FORMAT); + } else if (f.getDeType() == 3) { + fieldName = String.format(OracleConstants.CAST, originField, OracleConstants.DEFAULT_FLOAT_FORMAT); + } else if (f.getDeType() == 1) { + fieldName = String.format(OracleConstants.DATE_FORMAT, originField, OracleConstants.DEFAULT_DATE_FORMAT); + } else { + fieldName = originField; + } + } else { + if (f.getDeType() == 1) { + String cast = String.format(OracleConstants.CAST, originField, OracleConstants.DEFAULT_INT_FORMAT) + + "/1000"; + fieldName = String.format(OracleConstants.FROM_UNIXTIME, cast, OracleConstants.DEFAULT_DATE_FORMAT); + } else if (f.getDeType() == 2) { + fieldName = String.format(OracleConstants.CAST, originField, OracleConstants.DEFAULT_INT_FORMAT); + } else { + fieldName = originField; + } + } + SQLObj result = SQLObj.builder().orderField(originField).orderAlias(originField) + .orderDirection(f.getOrderDirection()).build(); + return result; + } + + private List xFields(String table, List fields) { + SQLObj tableObj = SQLObj.builder() + .tableName((table.startsWith("(") && table.endsWith(")")) ? table + : String.format(OracleConstants.KEYWORD_TABLE, table)) + .tableAlias(String.format(OracleConstants.ALIAS_FIX, String.format(TABLE_ALIAS_PREFIX, 0))) + .build(); + List xFields = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(fields)) { + for (int i = 0; i < fields.size(); i++) { + DatasetTableField f = fields.get(i); + String originField; + if (ObjectUtils.isNotEmpty(f.getExtField()) && f.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originField = calcFieldRegex(f.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(f.getExtField()) && f.getExtField() == 1) { + originField = String.format(OracleConstants.KEYWORD_FIX, tableObj.getTableAlias(), + f.getOriginName()); + } else { + originField = String.format(OracleConstants.KEYWORD_FIX, tableObj.getTableAlias(), + f.getOriginName()); + } + String fieldAlias = String.format(OracleConstants.ALIAS_FIX, + String.format(SQLConstants.FIELD_ALIAS_X_PREFIX, i)); + String fieldName = ""; + // 处理横轴字段 + if (f.getDeExtractType() == 1) { + if (f.getDeType() == 2 || f.getDeType() == 3) { + fieldName = String.format(OracleConstants.UNIX_TIMESTAMP, originField) + "*1000"; + } else { + fieldName = originField; + } + } else if (f.getDeExtractType() == 0) { + if (f.getDeType() == 2) { + fieldName = String.format(OracleConstants.CAST, originField, + OracleConstants.DEFAULT_INT_FORMAT); + } else if (f.getDeType() == 3) { + fieldName = String.format(OracleConstants.CAST, originField, + OracleConstants.DEFAULT_FLOAT_FORMAT); + } else if (f.getDeType() == 1) { + fieldName = String.format(OracleConstants.DATE_FORMAT, originField, + OracleConstants.DEFAULT_DATE_FORMAT); + } else { + fieldName = originField; + } + } else { + if (f.getDeType() == 1) { + String cast = String.format(OracleConstants.CAST, originField, + OracleConstants.DEFAULT_INT_FORMAT) + "/1000"; + fieldName = String.format(OracleConstants.FROM_UNIXTIME, cast, + OracleConstants.DEFAULT_DATE_FORMAT); + } else if (f.getDeType() == 2) { + fieldName = String.format(OracleConstants.CAST, originField, + OracleConstants.DEFAULT_INT_FORMAT); + } else { + fieldName = originField; + } + } + xFields.add(SQLObj.builder() + .fieldName(fieldName) + .fieldAlias(fieldAlias) + .build()); + } + } + return xFields; + } + + private String sqlColumn(List xFields) { + String[] array = xFields.stream().map(f -> { + return f.getFieldAlias(); + }).toArray(String[]::new); + return StringUtils.join(array, ","); + } + + @Override + public String createQuerySQLAsTmp(String sql, List fields, boolean isGroup, + List fieldCustomFilter, List rowPermissionsTree) { + return createQuerySQL("(" + sqlFix(sql) + ")", fields, isGroup, null, fieldCustomFilter, rowPermissionsTree); + } + + @Override + public String createQueryTableWithPage(String table, List fields, Integer page, Integer pageSize, + Integer realSize, boolean isGroup, Datasource ds, List fieldCustomFilter, List rowPermissionsTree) { + List xFields = xFields(table, fields); + + return MessageFormat.format( + "SELECT {0} FROM ( SELECT DE_TMP.*, rownum r FROM ( {1} ) DE_TMP WHERE rownum <= {2} ) WHERE r > {3} ", + sqlColumn(xFields), createQuerySQL(table, fields, isGroup, ds, fieldCustomFilter, rowPermissionsTree), + Integer.valueOf(page * realSize).toString(), Integer.valueOf((page - 1) * pageSize).toString()); + } + + @Override + public String createQuerySQLWithPage(String sql, List fields, Integer page, Integer pageSize, + Integer realSize, boolean isGroup, List fieldCustomFilter, List rowPermissionsTree) { + List xFields = xFields("(" + sqlFix(sql) + ")", fields); + return MessageFormat.format( + "SELECT {0} FROM ( SELECT DE_TMP.*, rownum r FROM ( {1} ) DE_TMP WHERE rownum <= {2} ) WHERE r > {3} ", + sqlColumn(xFields), createQuerySQLAsTmp(sql, fields, isGroup, fieldCustomFilter, rowPermissionsTree), + Integer.valueOf(page * realSize).toString(), Integer.valueOf((page - 1) * pageSize).toString()); + } + + @Override + public String createQueryTableWithLimit(String table, List fields, Integer limit, + boolean isGroup, Datasource ds, List fieldCustomFilter, List rowPermissionsTree) { + String schema = new Gson().fromJson(ds.getConfiguration(), JdbcConfiguration.class).getSchema(); + return String.format("SELECT * from %s WHERE rownum <= %s ", + schema + "." + String.format(OracleConstants.KEYWORD_TABLE, table), limit.toString()); + } + + @Override + public String createQuerySqlWithLimit(String sql, List fields, Integer limit, boolean isGroup, + List fieldCustomFilter, List rowPermissionsTree) { + return String.format("SELECT * from %s WHERE rownum <= %s ", "(" + sqlFix(sql) + ")", limit.toString()); + } + + @Override + public String getSQL(String table, List xAxis, List yAxis, + List fieldCustomFilter, List rowPermissionsTree, List extFilterRequestList, + Datasource ds, ChartViewWithBLOBs view) { + SQLObj tableObj = SQLObj.builder() + .tableName((table.startsWith("(") && table.endsWith(")")) ? table + : String.format(OracleConstants.KEYWORD_TABLE, table)) + .tableAlias(String.format(OracleConstants.ALIAS_FIX, String.format(TABLE_ALIAS_PREFIX, 0))) + .build(); + setSchema(tableObj, ds); + List xFields = new ArrayList<>(); + List xOrders = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(xAxis)) { + for (int i = 0; i < xAxis.size(); i++) { + ChartViewFieldDTO x = xAxis.get(i); + String originField; + if (ObjectUtils.isNotEmpty(x.getExtField()) && x.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originField = calcFieldRegex(x.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(x.getExtField()) && x.getExtField() == 1) { + originField = String.format(OracleConstants.KEYWORD_FIX, tableObj.getTableAlias(), + x.getOriginName()); + } else { + originField = String.format(OracleConstants.KEYWORD_FIX, tableObj.getTableAlias(), + x.getOriginName()); + } + String fieldAlias = String.format(OracleConstants.ALIAS_FIX, + String.format(SQLConstants.FIELD_ALIAS_X_PREFIX, i)); + // 处理横轴字段 + xFields.add(getXFields(x, originField, fieldAlias)); + // 处理横轴排序 + if (StringUtils.isNotEmpty(x.getSort()) && Utils.joinSort(x.getSort())) { + xOrders.add(SQLObj.builder() + .orderField(originField) + .orderAlias(fieldAlias) + .orderDirection(x.getSort()) + .build()); + } + } + } + List yFields = new ArrayList<>(); + List yWheres = new ArrayList<>(); + List yOrders = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(yAxis)) { + for (int i = 0; i < yAxis.size(); i++) { + ChartViewFieldDTO y = yAxis.get(i); + String originField; + if (ObjectUtils.isNotEmpty(y.getExtField()) && y.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originField = calcFieldRegex(y.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(y.getExtField()) && y.getExtField() == 1) { + originField = String.format(OracleConstants.KEYWORD_FIX, tableObj.getTableAlias(), + y.getOriginName()); + } else { + originField = String.format(OracleConstants.KEYWORD_FIX, tableObj.getTableAlias(), + y.getOriginName()); + } + String fieldAlias = String.format(OracleConstants.ALIAS_FIX, + String.format(SQLConstants.FIELD_ALIAS_Y_PREFIX, i)); + // 处理纵轴字段 + yFields.add(getYFields(y, originField, fieldAlias)); + // 处理纵轴过滤 + yWheres.add(getYWheres(y, originField, fieldAlias)); + // 处理纵轴排序 + if (StringUtils.isNotEmpty(y.getSort()) && Utils.joinSort(y.getSort())) { + yOrders.add(SQLObj.builder() + .orderField(originField) + .orderAlias(fieldAlias) + .orderDirection(y.getSort()) + .build()); + } + } + } + // 处理视图中字段过滤 + String customWheres = transCustomFilterList(tableObj, fieldCustomFilter); + // 处理仪表板字段过滤 + String extWheres = transExtFilterList(tableObj, extFilterRequestList); + // row permissions tree + String whereTrees = transFilterTrees(tableObj, rowPermissionsTree); + // 构建sql所有参数 + List fields = new ArrayList<>(); + fields.addAll(xFields); + fields.addAll(yFields); + List wheres = new ArrayList<>(); + if (customWheres != null) + wheres.add(customWheres); + if (extWheres != null) + wheres.add(extWheres); + if (whereTrees != null) + wheres.add(whereTrees); + List groups = new ArrayList<>(); + groups.addAll(xFields); + // 外层再次套sql + List orders = new ArrayList<>(); + orders.addAll(xOrders); + orders.addAll(yOrders); + List aggWheres = new ArrayList<>(); + aggWheres.addAll(yWheres.stream().filter(ObjectUtils::isNotEmpty).collect(Collectors.toList())); + + STGroup stg = new STGroupFile(SQLConstants.SQL_TEMPLATE); + ST st_sql = stg.getInstanceOf("querySql"); + if (CollectionUtils.isNotEmpty(xFields)) + st_sql.add("groups", xFields); + if (CollectionUtils.isNotEmpty(yFields)) + st_sql.add("aggregators", yFields); + if (CollectionUtils.isNotEmpty(wheres)) + st_sql.add("filters", wheres); + if (ObjectUtils.isNotEmpty(tableObj)) + st_sql.add("table", tableObj); + String sql = st_sql.render(); + + ST st = stg.getInstanceOf("querySql"); + SQLObj tableSQL = SQLObj.builder() + .tableName(String.format(OracleConstants.BRACKETS, sql)) + .tableAlias(String.format(TABLE_ALIAS_PREFIX, 1)) + .build(); + if (CollectionUtils.isNotEmpty(aggWheres)) + st.add("filters", aggWheres); + if (CollectionUtils.isNotEmpty(orders)) + st.add("orders", orders); + if (ObjectUtils.isNotEmpty(tableSQL)) + st.add("table", tableSQL); + return sqlLimit(st.render(), view); + } + + private String originalTableInfo(String table, List xAxis, List fieldCustomFilter, List rowPermissionsTree, List extFilterRequestList, Datasource ds, ChartViewWithBLOBs view) { + SQLObj tableObj = SQLObj.builder() + .tableName((table.startsWith("(") && table.endsWith(")")) ? table + : String.format(OracleConstants.KEYWORD_TABLE, table)) + .tableAlias(String.format(OracleConstants.ALIAS_FIX, String.format(TABLE_ALIAS_PREFIX, 0))) + .build(); + setSchema(tableObj, ds); + List xFields = new ArrayList<>(); + List xOrders = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(xAxis)) { + for (int i = 0; i < xAxis.size(); i++) { + ChartViewFieldDTO x = xAxis.get(i); + String originField; + if (ObjectUtils.isNotEmpty(x.getExtField()) && x.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originField = calcFieldRegex(x.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(x.getExtField()) && x.getExtField() == 1) { + originField = String.format(OracleConstants.KEYWORD_FIX, tableObj.getTableAlias(), + x.getOriginName()); + } else { + if (x.getDeType() == 2 || x.getDeType() == 3) { + originField = String.format(OracleConstants.CAST, + String.format(OracleConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getOriginName()), + OracleConstants.DEFAULT_FLOAT_FORMAT); + } else { + originField = String.format(OracleConstants.KEYWORD_FIX, tableObj.getTableAlias(), + x.getOriginName()); + } + } + String fieldAlias = String.format(OracleConstants.ALIAS_FIX, + String.format(SQLConstants.FIELD_ALIAS_X_PREFIX, i)); + // 处理横轴字段 + xFields.add(getXFields(x, originField, fieldAlias)); + // 处理横轴排序 + if (StringUtils.isNotEmpty(x.getSort()) && Utils.joinSort(x.getSort())) { + xOrders.add(SQLObj.builder() + .orderField(originField) + .orderAlias(fieldAlias) + .orderDirection(x.getSort()) + .build()); + } + } + } + // 处理视图中字段过滤 + String customWheres = transCustomFilterList(tableObj, fieldCustomFilter); + // 处理仪表板字段过滤 + String extWheres = transExtFilterList(tableObj, extFilterRequestList); + // row permissions tree + String whereTrees = transFilterTrees(tableObj, rowPermissionsTree); + // 构建sql所有参数 + List fields = new ArrayList<>(); + fields.addAll(xFields); + List wheres = new ArrayList<>(); + if (customWheres != null) + wheres.add(customWheres); + if (extWheres != null) + wheres.add(extWheres); + if (whereTrees != null) + wheres.add(whereTrees); + List groups = new ArrayList<>(); + groups.addAll(xFields); + // 外层再次套sql + List orders = new ArrayList<>(); + orders.addAll(xOrders); + + STGroup stg = new STGroupFile(SQLConstants.SQL_TEMPLATE); + ST st_sql = stg.getInstanceOf("previewSql"); + st_sql.add("isGroup", false); + if (CollectionUtils.isNotEmpty(xFields)) + st_sql.add("groups", xFields); + if (CollectionUtils.isNotEmpty(wheres)) + st_sql.add("filters", wheres); + if (ObjectUtils.isNotEmpty(tableObj)) + st_sql.add("table", tableObj); + String sql = st_sql.render(); + + ST st = stg.getInstanceOf("previewSql"); + st.add("isGroup", false); + SQLObj tableSQL = SQLObj.builder() + .tableName(String.format(OracleConstants.BRACKETS, sql)) + .tableAlias(String.format(TABLE_ALIAS_PREFIX, 1)) + .build(); + if (CollectionUtils.isNotEmpty(orders)) + st.add("orders", orders); + if (ObjectUtils.isNotEmpty(tableSQL)) + st.add("table", tableSQL); + return st.render(); + } + @Override + public String getSQLTableInfo(String table, List xAxis, List fieldCustomFilter, List rowPermissionsTree, List extFilterRequestList, Datasource ds, ChartViewWithBLOBs view) { + return sqlLimit(originalTableInfo(table, xAxis, fieldCustomFilter, rowPermissionsTree, extFilterRequestList, ds, view), view); + } + + @Override + public String getSQLWithPage(boolean isTable, String table, List xAxis, List fieldCustomFilter, List rowPermissionsTree, List extFilterRequestList, Datasource ds, ChartViewWithBLOBs view, PageInfo pageInfo) { + String limit = ((pageInfo.getGoPage() != null && pageInfo.getPageSize() != null) ? " LIMIT " + (pageInfo.getGoPage() - 1) * pageInfo.getPageSize() + "," + pageInfo.getPageSize() : ""); + if (isTable) { + return originalTableInfo(table, xAxis, fieldCustomFilter, rowPermissionsTree, extFilterRequestList, ds, view) + limit; + } else { + return originalTableInfo("(" + sqlFix(table) + ")", xAxis, fieldCustomFilter, rowPermissionsTree, extFilterRequestList, ds, view) + limit; + } + } + + @Override + public String getSQLAsTmpTableInfo(String sql, List xAxis, List fieldCustomFilter, List rowPermissionsTree, List extFilterRequestList, Datasource ds, ChartViewWithBLOBs view) { + return getSQLTableInfo("(" + sqlFix(sql) + ")", xAxis, fieldCustomFilter, rowPermissionsTree, extFilterRequestList, null, view); + } + + @Override + public String getSQLAsTmp(String sql, List xAxis, List yAxis, List fieldCustomFilter, List rowPermissionsTree, List extFilterRequestList, ChartViewWithBLOBs view) { + return getSQL("(" + sqlFix(sql) + ")", xAxis, yAxis, fieldCustomFilter, rowPermissionsTree, extFilterRequestList, null, view); + } + + @Override + public String getSQLStack(String table, List xAxis, List yAxis, List fieldCustomFilter, List rowPermissionsTree, List extFilterRequestList, List extStack, Datasource ds, ChartViewWithBLOBs view) { + SQLObj tableObj = SQLObj.builder() + .tableName((table.startsWith("(") && table.endsWith(")")) ? table + : String.format(OracleConstants.KEYWORD_TABLE, table)) + .tableAlias(String.format(OracleConstants.ALIAS_FIX, String.format(TABLE_ALIAS_PREFIX, 0))) + .build(); + setSchema(tableObj, ds); + List xFields = new ArrayList<>(); + List xOrders = new ArrayList<>(); + List xList = new ArrayList<>(); + xList.addAll(xAxis); + xList.addAll(extStack); + if (CollectionUtils.isNotEmpty(xList)) { + for (int i = 0; i < xList.size(); i++) { + ChartViewFieldDTO x = xList.get(i); + String originField; + if (ObjectUtils.isNotEmpty(x.getExtField()) && x.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originField = calcFieldRegex(x.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(x.getExtField()) && x.getExtField() == 1) { + originField = String.format(OracleConstants.KEYWORD_FIX, tableObj.getTableAlias(), + x.getOriginName()); + } else { + originField = String.format(OracleConstants.KEYWORD_FIX, tableObj.getTableAlias(), + x.getOriginName()); + } + String fieldAlias = String.format(OracleConstants.ALIAS_FIX, + String.format(SQLConstants.FIELD_ALIAS_X_PREFIX, i)); + // 处理横轴字段 + xFields.add(getXFields(x, originField, fieldAlias)); + // 处理横轴排序 + if (StringUtils.isNotEmpty(x.getSort()) && Utils.joinSort(x.getSort())) { + xOrders.add(SQLObj.builder() + .orderField(originField) + .orderAlias(fieldAlias) + .orderDirection(x.getSort()) + .build()); + } + } + } + List yFields = new ArrayList<>(); + List yWheres = new ArrayList<>(); + List yOrders = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(yAxis)) { + for (int i = 0; i < yAxis.size(); i++) { + ChartViewFieldDTO y = yAxis.get(i); + String originField; + if (ObjectUtils.isNotEmpty(y.getExtField()) && y.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originField = calcFieldRegex(y.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(y.getExtField()) && y.getExtField() == 1) { + originField = String.format(OracleConstants.KEYWORD_FIX, tableObj.getTableAlias(), + y.getOriginName()); + } else { + originField = String.format(OracleConstants.KEYWORD_FIX, tableObj.getTableAlias(), + y.getOriginName()); + } + String fieldAlias = String.format(OracleConstants.ALIAS_FIX, + String.format(SQLConstants.FIELD_ALIAS_Y_PREFIX, i)); + // 处理纵轴字段 + yFields.add(getYFields(y, originField, fieldAlias)); + // 处理纵轴过滤 + yWheres.add(getYWheres(y, originField, fieldAlias)); + // 处理纵轴排序 + if (StringUtils.isNotEmpty(y.getSort()) && Utils.joinSort(y.getSort())) { + yOrders.add(SQLObj.builder() + .orderField(originField) + .orderAlias(fieldAlias) + .orderDirection(y.getSort()) + .build()); + } + } + } + // 处理视图中字段过滤 + String customWheres = transCustomFilterList(tableObj, fieldCustomFilter); + // 处理仪表板字段过滤 + String extWheres = transExtFilterList(tableObj, extFilterRequestList); + // row permissions tree + String whereTrees = transFilterTrees(tableObj, rowPermissionsTree); + // 构建sql所有参数 + List fields = new ArrayList<>(); + fields.addAll(xFields); + fields.addAll(yFields); + List wheres = new ArrayList<>(); + if (customWheres != null) + wheres.add(customWheres); + if (extWheres != null) + wheres.add(extWheres); + if (whereTrees != null) + wheres.add(whereTrees); + List groups = new ArrayList<>(); + groups.addAll(xFields); + // 外层再次套sql + List orders = new ArrayList<>(); + orders.addAll(xOrders); + orders.addAll(yOrders); + List aggWheres = new ArrayList<>(); + aggWheres.addAll(yWheres.stream().filter(ObjectUtils::isNotEmpty).collect(Collectors.toList())); + + STGroup stg = new STGroupFile(SQLConstants.SQL_TEMPLATE); + ST st_sql = stg.getInstanceOf("querySql"); + if (CollectionUtils.isNotEmpty(xFields)) + st_sql.add("groups", xFields); + if (CollectionUtils.isNotEmpty(yFields)) + st_sql.add("aggregators", yFields); + if (CollectionUtils.isNotEmpty(wheres)) + st_sql.add("filters", wheres); + if (ObjectUtils.isNotEmpty(tableObj)) + st_sql.add("table", tableObj); + String sql = st_sql.render(); + + ST st = stg.getInstanceOf("querySql"); + SQLObj tableSQL = SQLObj.builder() + .tableName(String.format(OracleConstants.BRACKETS, sql)) + .tableAlias(String.format(TABLE_ALIAS_PREFIX, 1)) + .build(); + if (CollectionUtils.isNotEmpty(aggWheres)) + st.add("filters", aggWheres); + if (CollectionUtils.isNotEmpty(orders)) + st.add("orders", orders); + if (ObjectUtils.isNotEmpty(tableSQL)) + st.add("table", tableSQL); + return sqlLimit(st.render(), view); + } + + @Override + public String getSQLAsTmpStack(String table, List xAxis, List yAxis, + List fieldCustomFilter, List rowPermissionsTree, List extFilterRequestList, + List extStack, ChartViewWithBLOBs view) { + return getSQLStack("(" + sqlFix(table) + ")", xAxis, yAxis, fieldCustomFilter, rowPermissionsTree, extFilterRequestList, extStack, + null, view); + } + + @Override + public String getSQLScatter(String table, List xAxis, List yAxis, + List fieldCustomFilter, List rowPermissionsTree, List extFilterRequestList, + List extBubble, Datasource ds, ChartViewWithBLOBs view) { + SQLObj tableObj = SQLObj.builder() + .tableName((table.startsWith("(") && table.endsWith(")")) ? table + : String.format(OracleConstants.KEYWORD_TABLE, table)) + .tableAlias(String.format(OracleConstants.ALIAS_FIX, String.format(TABLE_ALIAS_PREFIX, 0))) + .build(); + setSchema(tableObj, ds); + List xFields = new ArrayList<>(); + List xOrders = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(xAxis)) { + for (int i = 0; i < xAxis.size(); i++) { + ChartViewFieldDTO x = xAxis.get(i); + String originField; + if (ObjectUtils.isNotEmpty(x.getExtField()) && x.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originField = calcFieldRegex(x.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(x.getExtField()) && x.getExtField() == 1) { + originField = String.format(OracleConstants.KEYWORD_FIX, tableObj.getTableAlias(), + x.getOriginName()); + } else { + originField = String.format(OracleConstants.KEYWORD_FIX, tableObj.getTableAlias(), + x.getOriginName()); + } + String fieldAlias = String.format(OracleConstants.ALIAS_FIX, + String.format(SQLConstants.FIELD_ALIAS_X_PREFIX, i)); + // 处理横轴字段 + xFields.add(getXFields(x, originField, fieldAlias)); + // 处理横轴排序 + if (StringUtils.isNotEmpty(x.getSort()) && Utils.joinSort(x.getSort())) { + xOrders.add(SQLObj.builder() + .orderField(originField) + .orderAlias(fieldAlias) + .orderDirection(x.getSort()) + .build()); + } + } + } + List yFields = new ArrayList<>(); + List yWheres = new ArrayList<>(); + List yOrders = new ArrayList<>(); + List yList = new ArrayList<>(); + yList.addAll(yAxis); + yList.addAll(extBubble); + if (CollectionUtils.isNotEmpty(yList)) { + for (int i = 0; i < yList.size(); i++) { + ChartViewFieldDTO y = yList.get(i); + String originField; + if (ObjectUtils.isNotEmpty(y.getExtField()) && y.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originField = calcFieldRegex(y.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(y.getExtField()) && y.getExtField() == 1) { + originField = String.format(OracleConstants.KEYWORD_FIX, tableObj.getTableAlias(), + y.getOriginName()); + } else { + originField = String.format(OracleConstants.KEYWORD_FIX, tableObj.getTableAlias(), + y.getOriginName()); + } + String fieldAlias = String.format(OracleConstants.ALIAS_FIX, + String.format(SQLConstants.FIELD_ALIAS_Y_PREFIX, i)); + // 处理纵轴字段 + yFields.add(getYFields(y, originField, fieldAlias)); + // 处理纵轴过滤 + yWheres.add(getYWheres(y, originField, fieldAlias)); + // 处理纵轴排序 + if (StringUtils.isNotEmpty(y.getSort()) && Utils.joinSort(y.getSort())) { + yOrders.add(SQLObj.builder() + .orderField(originField) + .orderAlias(fieldAlias) + .orderDirection(y.getSort()) + .build()); + } + } + } + // 处理视图中字段过滤 + String customWheres = transCustomFilterList(tableObj, fieldCustomFilter); + // 处理仪表板字段过滤 + String extWheres = transExtFilterList(tableObj, extFilterRequestList); + // row permissions tree + String whereTrees = transFilterTrees(tableObj, rowPermissionsTree); + // 构建sql所有参数 + List fields = new ArrayList<>(); + fields.addAll(xFields); + fields.addAll(yFields); + List wheres = new ArrayList<>(); + if (customWheres != null) + wheres.add(customWheres); + if (extWheres != null) + wheres.add(extWheres); + if (whereTrees != null) + wheres.add(whereTrees); + List groups = new ArrayList<>(); + groups.addAll(xFields); + // 外层再次套sql + List orders = new ArrayList<>(); + orders.addAll(xOrders); + orders.addAll(yOrders); + List aggWheres = new ArrayList<>(); + aggWheres.addAll(yWheres.stream().filter(ObjectUtils::isNotEmpty).collect(Collectors.toList())); + + STGroup stg = new STGroupFile(SQLConstants.SQL_TEMPLATE); + ST st_sql = stg.getInstanceOf("querySql"); + if (CollectionUtils.isNotEmpty(xFields)) + st_sql.add("groups", xFields); + if (CollectionUtils.isNotEmpty(yFields)) + st_sql.add("aggregators", yFields); + if (CollectionUtils.isNotEmpty(wheres)) + st_sql.add("filters", wheres); + if (ObjectUtils.isNotEmpty(tableObj)) + st_sql.add("table", tableObj); + String sql = st_sql.render(); + + ST st = stg.getInstanceOf("querySql"); + SQLObj tableSQL = SQLObj.builder() + .tableName(String.format(OracleConstants.BRACKETS, sql)) + .tableAlias(String.format(TABLE_ALIAS_PREFIX, 1)) + .build(); + if (CollectionUtils.isNotEmpty(aggWheres)) + st.add("filters", aggWheres); + if (CollectionUtils.isNotEmpty(orders)) + st.add("orders", orders); + if (ObjectUtils.isNotEmpty(tableSQL)) + st.add("table", tableSQL); + return sqlLimit(st.render(), view); + } + + @Override + public String getSQLAsTmpScatter(String table, List xAxis, List yAxis, + List fieldCustomFilter, List rowPermissionsTree, List extFilterRequestList, + List extBubble, ChartViewWithBLOBs view) { + return getSQLScatter("(" + sqlFix(table) + ")", xAxis, yAxis, fieldCustomFilter, rowPermissionsTree, extFilterRequestList, + extBubble, null, view); + } + + @Override + public String searchTable(String table) { + return "SELECT table_name FROM information_schema.TABLES WHERE table_name ='" + table + "'"; + } + + @Override + public String getSQLSummary(String table, List yAxis, + List fieldCustomFilter, List rowPermissionsTree, List extFilterRequestList, + ChartViewWithBLOBs view, Datasource ds) { + // 字段汇总 排序等 + SQLObj tableObj = SQLObj.builder() + .tableName((table.startsWith("(") && table.endsWith(")")) ? table + : String.format(OracleConstants.KEYWORD_TABLE, table)) + .tableAlias(String.format(OracleConstants.ALIAS_FIX, String.format(TABLE_ALIAS_PREFIX, 0))) + .build(); + setSchema(tableObj, ds); + List yFields = new ArrayList<>(); + List yWheres = new ArrayList<>(); + List yOrders = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(yAxis)) { + for (int i = 0; i < yAxis.size(); i++) { + ChartViewFieldDTO y = yAxis.get(i); + String originField; + if (ObjectUtils.isNotEmpty(y.getExtField()) && y.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originField = calcFieldRegex(y.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(y.getExtField()) && y.getExtField() == 1) { + originField = String.format(OracleConstants.KEYWORD_FIX, tableObj.getTableAlias(), + y.getOriginName()); + } else { + originField = String.format(OracleConstants.KEYWORD_FIX, tableObj.getTableAlias(), + y.getOriginName()); + } + String fieldAlias = String.format(SQLConstants.FIELD_ALIAS_Y_PREFIX, i); + // 处理纵轴字段 + yFields.add(getYFields(y, originField, fieldAlias)); + // 处理纵轴过滤 + yWheres.add(getYWheres(y, originField, fieldAlias)); + // 处理纵轴排序 + if (StringUtils.isNotEmpty(y.getSort()) && Utils.joinSort(y.getSort())) { + yOrders.add(SQLObj.builder() + .orderField(originField) + .orderAlias(fieldAlias) + .orderDirection(y.getSort()) + .build()); + } + } + } + // 处理视图中字段过滤 + String customWheres = transCustomFilterList(tableObj, fieldCustomFilter); + // 处理仪表板字段过滤 + String extWheres = transExtFilterList(tableObj, extFilterRequestList); + // row permissions tree + String whereTrees = transFilterTrees(tableObj, rowPermissionsTree); + // 构建sql所有参数 + List fields = new ArrayList<>(); + fields.addAll(yFields); + List wheres = new ArrayList<>(); + if (customWheres != null) + wheres.add(customWheres); + if (extWheres != null) + wheres.add(extWheres); + if (whereTrees != null) + wheres.add(whereTrees); + // 外层再次套sql + List orders = new ArrayList<>(); + orders.addAll(yOrders); + List aggWheres = new ArrayList<>(); + aggWheres.addAll(yWheres.stream().filter(ObjectUtils::isNotEmpty).collect(Collectors.toList())); + + STGroup stg = new STGroupFile(SQLConstants.SQL_TEMPLATE); + ST st_sql = stg.getInstanceOf("querySql"); + if (CollectionUtils.isNotEmpty(yFields)) + st_sql.add("aggregators", yFields); + if (CollectionUtils.isNotEmpty(wheres)) + st_sql.add("filters", wheres); + if (ObjectUtils.isNotEmpty(tableObj)) + st_sql.add("table", tableObj); + String sql = st_sql.render(); + + ST st = stg.getInstanceOf("querySql"); + SQLObj tableSQL = SQLObj.builder() + .tableName(String.format(OracleConstants.BRACKETS, sql)) + .tableAlias(String.format(TABLE_ALIAS_PREFIX, 1)) + .build(); + if (CollectionUtils.isNotEmpty(aggWheres)) + st.add("filters", aggWheres); + if (CollectionUtils.isNotEmpty(orders)) + st.add("orders", orders); + if (ObjectUtils.isNotEmpty(tableSQL)) + st.add("table", tableSQL); + return sqlLimit(st.render(), view); + } + + @Override + public String getSQLSummaryAsTmp(String sql, List yAxis, + List fieldCustomFilter, List rowPermissionsTree, List extFilterRequestList, + ChartViewWithBLOBs view) { + return getSQLSummary("(" + sqlFix(sql) + ")", yAxis, fieldCustomFilter, rowPermissionsTree, extFilterRequestList, view, null); + } + + @Override + public String wrapSql(String sql) { + sql = sql.trim(); + if (sql.lastIndexOf(";") == (sql.length() - 1)) { + sql = sql.substring(0, sql.length() - 1); + } + String tmpSql = "SELECT * FROM (" + sql + ") DE_TMP " + " where rownum <= 0"; + return tmpSql; + } + + @Override + public String createRawQuerySQL(String table, List fields, Datasource ds) { + String[] array = fields.stream().map(f -> { + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.append(" \"").append(f.getOriginName()).append("\""); + return stringBuilder.toString(); + }).toArray(String[]::new); + DmConfig dmConfig = new Gson().fromJson(ds.getConfiguration(), DmConfig.class); + return MessageFormat.format("SELECT {0} FROM {1}", StringUtils.join(array, ","), + dmConfig.getSchema() + ".\"" + table + "\""); + } + + @Override + public String createRawQuerySQLAsTmp(String sql, List fields) { + String[] array = fields.stream().map(f -> { + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.append(" \"").append(f.getOriginName()).append("\""); + return stringBuilder.toString(); + }).toArray(String[]::new); + return MessageFormat.format("SELECT {0} FROM {1}", StringUtils.join(array, ","), + " (" + sqlFix(sql) + ") DE_TMP "); + } + + @Override + public String transTreeItem(SQLObj tableObj, DatasetRowPermissionsTreeItem item) { + String res = null; + DatasetTableField field = item.getField(); + if (ObjectUtils.isEmpty(field)) { + return null; + } + String whereName = ""; + String originName; + if (ObjectUtils.isNotEmpty(field.getExtField()) && field.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originName = calcFieldRegex(field.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(field.getExtField()) && field.getExtField() == 1) { + originName = String.format(OracleConstants.KEYWORD_FIX, tableObj.getTableAlias(), + field.getOriginName()); + } else { + originName = String.format(OracleConstants.KEYWORD_FIX, tableObj.getTableAlias(), + field.getOriginName()); + } + + if (field.getDeType() == 1) { + if (field.getDeExtractType() == 0 || field.getDeExtractType() == 5) { + whereName = String.format(OracleConstants.TO_DATE, originName, StringUtils.isNotEmpty(field.getDateFormat()) ? field.getDateFormat() : OracleConstants.DEFAULT_DATE_FORMAT); + } + if (field.getDeExtractType() == 2 || field.getDeExtractType() == 3 || field.getDeExtractType() == 4) { + String cast = String.format(OracleConstants.CAST, originName, OracleConstants.DEFAULT_INT_FORMAT) + + "/1000"; + whereName = String.format(OracleConstants.FROM_UNIXTIME, cast, OracleConstants.DEFAULT_DATE_FORMAT); + } + if (field.getDeExtractType() == 1) { + whereName = originName; + } + } else if (field.getDeType() == 2 || field.getDeType() == 3) { + if (field.getDeExtractType() == 0 || field.getDeExtractType() == 5) { + whereName = String.format(OracleConstants.CAST, originName, OracleConstants.DEFAULT_FLOAT_FORMAT); + } + if (field.getDeExtractType() == 1) { + whereName = String.format(OracleConstants.UNIX_TIMESTAMP, originName) + "*1000"; + } + if (field.getDeExtractType() == 2 || field.getDeExtractType() == 3 || field.getDeExtractType() == 4) { + whereName = originName; + } + } else { + whereName = originName; + } + + if (StringUtils.equalsIgnoreCase(item.getFilterType(), "enum")) { + if (CollectionUtils.isNotEmpty(item.getEnumValue())) { + res = "(" + whereName + " IN ('" + String.join("','", item.getEnumValue()) + "'))"; + } + } else { + String value = item.getValue(); + String whereTerm = transMysqlFilterTerm(item.getTerm()); + String whereValue = ""; + + if (StringUtils.equalsIgnoreCase(item.getTerm(), "null")) { + whereValue = ""; + } else if (StringUtils.equalsIgnoreCase(item.getTerm(), "not_null")) { + whereValue = ""; + } else if (StringUtils.equalsIgnoreCase(item.getTerm(), "empty")) { + whereValue = "''"; + } else if (StringUtils.equalsIgnoreCase(item.getTerm(), "not_empty")) { + whereValue = "''"; + } else if (StringUtils.containsIgnoreCase(item.getTerm(), "in") + || StringUtils.containsIgnoreCase(item.getTerm(), "not in")) { + whereValue = "('" + String.join("','", value.split(",")) + "')"; + } else if (StringUtils.containsIgnoreCase(item.getTerm(), "like")) { + whereValue = "'%" + value + "%'"; + } else { + if (field.getDeType() == 1) { + whereValue = String.format(OracleConstants.TO_DATE, "'" + value + "'", OracleConstants.DEFAULT_DATE_FORMAT); + } else { + whereValue = String.format(OracleConstants.WHERE_VALUE_VALUE, value); + } + } + SQLObj build = SQLObj.builder() + .whereField(whereName) + .whereTermAndValue(whereTerm + whereValue) + .build(); + res = build.getWhereField() + " " + build.getWhereTermAndValue(); + } + return res; + } + + @Override + public String convertTableToSql(String tableName, Datasource ds) { + String schema = new Gson().fromJson(ds.getConfiguration(), JdbcConfiguration.class).getSchema(); + schema = String.format(OracleConstants.KEYWORD_TABLE, schema); + return createSQLPreview( + "SELECT * FROM " + schema + "." + String.format(OracleConstants.KEYWORD_TABLE, tableName), null); + } + + public String transMysqlFilterTerm(String term) { + switch (term) { + case "eq": + return " = "; + case "not_eq": + return " <> "; + case "lt": + return " < "; + case "le": + return " <= "; + case "gt": + return " > "; + case "ge": + return " >= "; + case "in": + return " IN "; + case "not in": + return " NOT IN "; + case "like": + return " LIKE "; + case "not like": + return " NOT LIKE "; + case "null": + return " IS NULL "; + case "not_null": + return " IS NOT NULL "; + case "empty": + return " = "; + case "not_empty": + return " <> "; + case "between": + return " BETWEEN "; + default: + return ""; + } + } + + public String transCustomFilterList(SQLObj tableObj, List requestList) { + if (CollectionUtils.isEmpty(requestList)) { + return null; + } + List res = new ArrayList<>(); + for (ChartFieldCustomFilterDTO request : requestList) { + List list = new ArrayList<>(); + DatasetTableField field = request.getField(); + + if (ObjectUtils.isEmpty(field)) { + continue; + } + String whereName = ""; + String originName; + if (ObjectUtils.isNotEmpty(field.getExtField()) && field.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originName = calcFieldRegex(field.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(field.getExtField()) && field.getExtField() == 1) { + originName = String.format(OracleConstants.KEYWORD_FIX, tableObj.getTableAlias(), + field.getOriginName()); + } else { + originName = String.format(OracleConstants.KEYWORD_FIX, tableObj.getTableAlias(), + field.getOriginName()); + } + + if (field.getDeType() == 1) { + if (field.getDeExtractType() == 0 || field.getDeExtractType() == 5) { + whereName = String.format(OracleConstants.TO_DATE, originName, StringUtils.isNotEmpty(field.getDateFormat()) ? field.getDateFormat() : OracleConstants.DEFAULT_DATE_FORMAT); + } + if (field.getDeExtractType() == 2 || field.getDeExtractType() == 3 || field.getDeExtractType() == 4) { + String cast = String.format(OracleConstants.CAST, originName, OracleConstants.DEFAULT_INT_FORMAT) + + "/1000"; + whereName = String.format(OracleConstants.FROM_UNIXTIME, cast, OracleConstants.DEFAULT_DATE_FORMAT); + } + if (field.getDeExtractType() == 1) { + whereName = originName; + } + } else if (field.getDeType() == 2 || field.getDeType() == 3) { + if (field.getDeExtractType() == 0 || field.getDeExtractType() == 5) { + whereName = String.format(OracleConstants.CAST, originName, OracleConstants.DEFAULT_FLOAT_FORMAT); + } + if (field.getDeExtractType() == 1) { + whereName = String.format(OracleConstants.UNIX_TIMESTAMP, originName) + "*1000"; + } + if (field.getDeExtractType() == 2 || field.getDeExtractType() == 3 || field.getDeExtractType() == 4) { + whereName = originName; + } + } else { + whereName = originName; + } + + if (StringUtils.equalsIgnoreCase(request.getFilterType(), "enum")) { + if (CollectionUtils.isNotEmpty(request.getEnumCheckField())) { + res.add("(" + whereName + " IN ('" + String.join("','", request.getEnumCheckField()) + "'))"); + } + } else { + List filter = request.getFilter(); + for (ChartCustomFilterItemDTO filterItemDTO : filter) { + String value = filterItemDTO.getValue(); + String whereTerm = transMysqlFilterTerm(filterItemDTO.getTerm()); + String whereValue = ""; + + if (StringUtils.equalsIgnoreCase(filterItemDTO.getTerm(), "null")) { + whereValue = ""; + } else if (StringUtils.equalsIgnoreCase(filterItemDTO.getTerm(), "not_null")) { + whereValue = ""; + } else if (StringUtils.equalsIgnoreCase(filterItemDTO.getTerm(), "empty")) { + whereValue = "''"; + } else if (StringUtils.equalsIgnoreCase(filterItemDTO.getTerm(), "not_empty")) { + whereValue = "''"; + } else if (StringUtils.containsIgnoreCase(filterItemDTO.getTerm(), "in") + || StringUtils.containsIgnoreCase(filterItemDTO.getTerm(), "not in")) { + whereValue = "('" + String.join("','", value.split(",")) + "')"; + } else if (StringUtils.containsIgnoreCase(filterItemDTO.getTerm(), "like")) { + whereValue = "'%" + value + "%'"; + } else { + if (field.getDeType() == 1) { + whereValue = String.format(OracleConstants.TO_DATE, "'" + value + "'", StringUtils.isNotEmpty(field.getDateFormat()) ? field.getDateFormat() : OracleConstants.DEFAULT_DATE_FORMAT); + } else { + whereValue = String.format(OracleConstants.WHERE_VALUE_VALUE, value); + } + } + list.add(SQLObj.builder() + .whereField(whereName) + .whereTermAndValue(whereTerm + whereValue) + .build()); + } + + List strList = new ArrayList<>(); + list.forEach(ele -> strList.add(ele.getWhereField() + " " + ele.getWhereTermAndValue())); + if (CollectionUtils.isNotEmpty(list)) { + res.add("(" + String.join(" " + getLogic(request.getLogic()) + " ", strList) + ")"); + } + } + } + return CollectionUtils.isNotEmpty(res) ? "(" + String.join(" AND ", res) + ")" : null; + } + + public String transExtFilterList(SQLObj tableObj, List requestList) { + if (CollectionUtils.isEmpty(requestList)) { + return null; + } + List list = new ArrayList<>(); + for (ChartExtFilterRequest request : requestList) { + List value = request.getValue(); + + List whereNameList = new ArrayList<>(); + List fieldList = new ArrayList<>(); + if (request.getIsTree()) { + fieldList.addAll(request.getDatasetTableFieldList()); + } else { + fieldList.add(request.getDatasetTableField()); + } + + for (DatasetTableField field : fieldList) { + if (CollectionUtils.isEmpty(value) || ObjectUtils.isEmpty(field)) { + continue; + } + String whereName = ""; + + String originName; + if (ObjectUtils.isNotEmpty(field.getExtField()) && field.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originName = calcFieldRegex(field.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(field.getExtField()) && field.getExtField() == 1) { + originName = String.format(OracleConstants.KEYWORD_FIX, tableObj.getTableAlias(), + field.getOriginName()); + } else { + originName = String.format(OracleConstants.KEYWORD_FIX, tableObj.getTableAlias(), + field.getOriginName()); + } + + if (field.getDeType() == 1) { + if (field.getDeExtractType() == 0 || field.getDeExtractType() == 5) { + whereName = String.format(OracleConstants.TO_DATE, originName, StringUtils.isNotEmpty(field.getDateFormat()) ? field.getDateFormat() : OracleConstants.DEFAULT_DATE_FORMAT); + } + if (field.getDeExtractType() == 2 || field.getDeExtractType() == 3 + || field.getDeExtractType() == 4) { + String cast = String.format(OracleConstants.CAST, originName, + OracleConstants.DEFAULT_INT_FORMAT) + "/1000"; + whereName = String.format(OracleConstants.FROM_UNIXTIME, cast, + OracleConstants.DEFAULT_DATE_FORMAT); + } + if (field.getDeExtractType() == 1) { + whereName = originName; + } + } else if (field.getDeType() == 2 || field.getDeType() == 3) { + if (field.getDeExtractType() == 0 || field.getDeExtractType() == 5) { + whereName = String.format(OracleConstants.CAST, originName, + OracleConstants.DEFAULT_FLOAT_FORMAT); + } + if (field.getDeExtractType() == 1) { + whereName = String.format(OracleConstants.UNIX_TIMESTAMP, originName) + "*1000"; + } + if (field.getDeExtractType() == 2 || field.getDeExtractType() == 3 + || field.getDeExtractType() == 4) { + whereName = originName; + } + } else { + whereName = originName; + } + whereNameList.add(whereName); + } + + String whereName = ""; + if (request.getIsTree()) { + whereName = StringUtils.join(whereNameList, "||','||"); + } else { + whereName = whereNameList.get(0); + } + String whereTerm = transMysqlFilterTerm(request.getOperator()); + String whereValue = ""; + + if (StringUtils.containsIgnoreCase(request.getOperator(), "in")) { + whereValue = "('" + StringUtils.join(value, "','") + "')"; + } else if (StringUtils.containsIgnoreCase(request.getOperator(), "like")) { + String keyword = value.get(0).toUpperCase(); + whereValue = "'%" + keyword + "%'"; + whereName = "upper(" + whereName + ")"; + } else if (StringUtils.containsIgnoreCase(request.getOperator(), "between")) { + if (request.getDatasetTableField().getDeType() == 1) { + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + String startTime = simpleDateFormat.format(new Date(Long.parseLong(value.get(0)))); + String endTime = simpleDateFormat.format(new Date(Long.parseLong(value.get(1)))); + String st = String.format(OracleConstants.TO_DATE, "'" + startTime + "'", + OracleConstants.DEFAULT_DATE_FORMAT); + String et = String.format(OracleConstants.TO_DATE, "'" + endTime + "'", + OracleConstants.DEFAULT_DATE_FORMAT); + whereValue = st + " AND " + et; + } else { + whereValue = String.format(OracleConstants.WHERE_BETWEEN, value.get(0), value.get(1)); + } + } else { + whereValue = String.format(OracleConstants.WHERE_VALUE_VALUE, value.get(0)); + } + list.add(SQLObj.builder() + .whereField(whereName) + .whereTermAndValue(whereTerm + whereValue) + .build()); + } + List strList = new ArrayList<>(); + list.forEach(ele -> strList.add(ele.getWhereField() + " " + ele.getWhereTermAndValue())); + return CollectionUtils.isNotEmpty(list) ? "(" + String.join(" AND ", strList) + ")" : null; + } + + private String sqlFix(String sql) { + if (sql.lastIndexOf(";") == (sql.length() - 1)) { + sql = sql.substring(0, sql.length() - 1); + } + return sql; + } + + private String transDateFormat(String dateStyle, String datePattern) { + String split = "-"; + if (StringUtils.equalsIgnoreCase(datePattern, "date_sub")) { + split = "-"; + } else if (StringUtils.equalsIgnoreCase(datePattern, "date_split")) { + split = "/"; + } else { + split = "-"; + } + + if (StringUtils.isEmpty(dateStyle)) { + return OracleConstants.DEFAULT_DATE_FORMAT; + } + + switch (dateStyle) { + case "y": + return "YYYY"; + case "y_M": + return "YYYY" + split + "MM"; + case "y_M_d": + return "YYYY" + split + "MM" + split + "DD"; + case "H_m_s": + return "HH24:MI:SS"; + case "y_M_d_H_m": + return "YYYY" + split + "MM" + split + "DD" + " HH24:MI"; + case "y_M_d_H_m_s": + return "YYYY" + split + "MM" + split + "DD" + " HH24:MI:SS"; + default: + return OracleConstants.DEFAULT_DATE_FORMAT; + } + } + + private SQLObj getXFields(ChartViewFieldDTO x, String originField, String fieldAlias) { + String fieldName = ""; + if (x.getDeExtractType() == DeTypeConstants.DE_TIME) { + if (x.getDeType() == DeTypeConstants.DE_INT || x.getDeType() == DeTypeConstants.DE_FLOAT) { // 时间转数值 + if (x.getType().equalsIgnoreCase("DATE")) { + String date = String.format(OracleConstants.CALC_SUB, originField, + String.format(OracleConstants.TO_DATE, OracleConstants.DEFAULT_START_DATE, + OracleConstants.DEFAULT_DATE_FORMAT)); + fieldName = String.format(OracleConstants.TO_NUMBER, date) + OracleConstants.TO_MS; + } else { + String toChar = String.format(OracleConstants.TO_CHAR, originField, + OracleConstants.DEFAULT_DATE_FORMAT); + String toDate = String.format(OracleConstants.TO_DATE, toChar, OracleConstants.DEFAULT_DATE_FORMAT); + String toDate1 = String.format(OracleConstants.TO_DATE, OracleConstants.DEFAULT_START_DATE, + OracleConstants.DEFAULT_DATE_FORMAT); + fieldName = String.format(OracleConstants.TO_NUMBER, + String.format(OracleConstants.CALC_SUB, toDate, toDate1)) + OracleConstants.TO_MS; + } + } else if (x.getDeType() == DeTypeConstants.DE_TIME) { // 格式化显示时间 + String format = transDateFormat(x.getDateStyle(), x.getDatePattern()); + if (x.getType().equalsIgnoreCase("DATE")) { + fieldName = String.format(OracleConstants.TO_CHAR, originField, format); + } else { + String toChar = String.format(OracleConstants.TO_CHAR, originField, + OracleConstants.DEFAULT_DATE_FORMAT); + String toDate = String.format(OracleConstants.TO_DATE, toChar, OracleConstants.DEFAULT_DATE_FORMAT); + fieldName = String.format(OracleConstants.TO_CHAR, toDate, format); + } + } else { + fieldName = originField; + } + } else { + if (x.getDeType() == DeTypeConstants.DE_TIME) { + String format = transDateFormat(x.getDateStyle(), x.getDatePattern()); + if (x.getDeExtractType() == DeTypeConstants.DE_STRING) { // 字符串转时间 + String toDate = String.format(OracleConstants.TO_DATE, originField, StringUtils.isNotEmpty(x.getDateFormat()) ? x.getDateFormat() : OracleConstants.DEFAULT_DATE_FORMAT); + fieldName = String.format(OracleConstants.TO_CHAR, toDate, format); + } else { // 数值转时间 + String date = originField + "/(1000 * 60 * 60 * 24)+" + String.format(OracleConstants.TO_DATE, + OracleConstants.DEFAULT_START_DATE, OracleConstants.DEFAULT_DATE_FORMAT); + fieldName = String.format(OracleConstants.TO_CHAR, date, format); + } + } else { + if (x.getDeType() == DeTypeConstants.DE_INT) { + fieldName = String.format(OracleConstants.CAST, originField, OracleConstants.DEFAULT_INT_FORMAT); + } else if (x.getDeType() == DeTypeConstants.DE_FLOAT) { + fieldName = String.format(OracleConstants.CAST, originField, OracleConstants.DEFAULT_FLOAT_FORMAT); + } else { + fieldName = originField; + } + } + } + return SQLObj.builder() + .fieldName(fieldName) + .fieldAlias(fieldAlias) + .build(); + } + + private List getXWheres(ChartViewFieldDTO x, String originField, String fieldAlias) { + List list = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(x.getFilter()) && x.getFilter().size() > 0) { + x.getFilter().forEach(f -> { + String whereName = ""; + String whereTerm = transMysqlFilterTerm(f.getTerm()); + String whereValue = ""; + if (x.getDeType() == 1 && x.getDeExtractType() != 1) { + String cast = String.format(OracleConstants.CAST, originField, OracleConstants.DEFAULT_INT_FORMAT) + + "/1000"; + whereName = String.format(OracleConstants.FROM_UNIXTIME, cast, OracleConstants.DEFAULT_DATE_FORMAT); + } else { + whereName = originField; + } + if (StringUtils.equalsIgnoreCase(f.getTerm(), "null")) { + whereValue = ""; + } else if (StringUtils.equalsIgnoreCase(f.getTerm(), "not_null")) { + whereValue = ""; + } else if (StringUtils.equalsIgnoreCase(f.getTerm(), "empty")) { + whereValue = "''"; + } else if (StringUtils.equalsIgnoreCase(f.getTerm(), "not_empty")) { + whereValue = "''"; + } else if (StringUtils.containsIgnoreCase(f.getTerm(), "in")) { + whereValue = "('" + StringUtils.join(f.getValue(), "','") + "')"; + } else if (StringUtils.containsIgnoreCase(f.getTerm(), "like")) { + whereValue = "'%" + f.getValue() + "%'"; + } else { + whereValue = String.format(OracleConstants.WHERE_VALUE_VALUE, f.getValue()); + } + list.add(SQLObj.builder() + .whereField(whereName) + .whereAlias(fieldAlias) + .whereTermAndValue(whereTerm + whereValue) + .build()); + }); + } + return list; + } + + private SQLObj getYFields(ChartViewFieldDTO y, String originField, String fieldAlias) { + String fieldName = ""; + if (StringUtils.equalsIgnoreCase(y.getOriginName(), "*")) { + fieldName = OracleConstants.AGG_COUNT; + } else if (SQLConstants.DIMENSION_TYPE.contains(y.getDeType())) { + if (StringUtils.equalsIgnoreCase(y.getSummary(), "count_distinct")) { + fieldName = String.format(OracleConstants.AGG_FIELD, "COUNT", "DISTINCT " + originField); + } else if (StringUtils.equalsIgnoreCase(y.getSummary(), "group_concat")) { + fieldName = String.format(OracleConstants.GROUP_CONCAT, originField, originField); + } else { + fieldName = String.format(OracleConstants.AGG_FIELD, y.getSummary(), originField); + } + } else { + if (StringUtils.equalsIgnoreCase(y.getSummary(), "avg") + || StringUtils.containsIgnoreCase(y.getSummary(), "pop")) { + String cast = String.format(OracleConstants.CAST, originField, + y.getDeType() == 2 ? OracleConstants.DEFAULT_INT_FORMAT : OracleConstants.DEFAULT_FLOAT_FORMAT); + String agg = String.format(OracleConstants.AGG_FIELD, y.getSummary(), cast); + fieldName = String.format(OracleConstants.CAST, agg, OracleConstants.DEFAULT_FLOAT_FORMAT); + } else { + String cast = String.format(OracleConstants.CAST, originField, + y.getDeType() == 2 ? OracleConstants.DEFAULT_INT_FORMAT : OracleConstants.DEFAULT_FLOAT_FORMAT); + if (StringUtils.equalsIgnoreCase(y.getSummary(), "count_distinct")) { + fieldName = String.format(OracleConstants.AGG_FIELD, "COUNT", "DISTINCT " + cast); + } else { + fieldName = String.format(OracleConstants.AGG_FIELD, y.getSummary(), cast); + } + } + } + return SQLObj.builder() + .fieldName(fieldName) + .fieldAlias(fieldAlias) + .build(); + } + + private String getYWheres(ChartViewFieldDTO y, String originField, String fieldAlias) { + List list = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(y.getFilter()) && y.getFilter().size() > 0) { + y.getFilter().forEach(f -> { + String whereTerm = transMysqlFilterTerm(f.getTerm()); + String whereValue = ""; + // 原始类型不是时间,在de中被转成时间的字段做处理 + if (StringUtils.equalsIgnoreCase(f.getTerm(), "null")) { + whereValue = ""; + } else if (StringUtils.equalsIgnoreCase(f.getTerm(), "not_null")) { + whereValue = ""; + } else if (StringUtils.equalsIgnoreCase(f.getTerm(), "empty")) { + whereValue = "''"; + } else if (StringUtils.equalsIgnoreCase(f.getTerm(), "not_empty")) { + whereValue = "''"; + } else if (StringUtils.containsIgnoreCase(f.getTerm(), "in")) { + whereValue = "('" + StringUtils.join(f.getValue(), "','") + "')"; + } else if (StringUtils.containsIgnoreCase(f.getTerm(), "like")) { + whereValue = "'%" + f.getValue() + "%'"; + } else { + whereValue = String.format(OracleConstants.WHERE_VALUE_VALUE, f.getValue()); + } + list.add(SQLObj.builder() + .whereField(fieldAlias) + .whereAlias(fieldAlias) + .whereTermAndValue(whereTerm + whereValue) + .build()); + }); + } + List strList = new ArrayList<>(); + list.forEach(ele -> strList.add(ele.getWhereField() + " " + ele.getWhereTermAndValue())); + return CollectionUtils.isNotEmpty(list) ? "(" + String.join(" " + getLogic(y.getLogic()) + " ", strList) + ")" + : null; + } + + private String calcFieldRegex(String originField, SQLObj tableObj) { + originField = originField.replaceAll("[\\t\\n\\r]]", ""); + // 正则提取[xxx] + String regex = "\\[(.*?)]"; + Pattern pattern = Pattern.compile(regex); + Matcher matcher = pattern.matcher(originField); + Set ids = new HashSet<>(); + while (matcher.find()) { + String id = matcher.group(1); + ids.add(id); + } + if (CollectionUtils.isEmpty(ids)) { + return originField; + } + DatasetTableFieldExample datasetTableFieldExample = new DatasetTableFieldExample(); + datasetTableFieldExample.createCriteria().andIdIn(new ArrayList<>(ids)); + List calcFields = datasetTableFieldMapper.selectByExample(datasetTableFieldExample); + for (DatasetTableField ele : calcFields) { + originField = originField.replaceAll("\\[" + ele.getId() + "]", + String.format(OracleConstants.KEYWORD_FIX, tableObj.getTableAlias(), ele.getOriginName())); + } + return originField; + } + + private String sqlLimit(String sql, ChartViewWithBLOBs view) { + if (StringUtils.equalsIgnoreCase(view.getResultMode(), "custom")) { + return "SELECT * FROM (" + sqlFix(sql) + ") DE_RESULT_TMP " + " WHERE rownum <= " + view.getResultCount(); + } else { + return sql; + } + } + + public List dateformat() { + ObjectMapper objectMapper = new ObjectMapper(); + List dateformats = new ArrayList<>(); + try{ + dateformats = objectMapper.readValue("[\n" + + "{\"dateformat\": \"YYYY-MM-DD\"},\n" + + "{\"dateformat\": \"YYYY/MM/DD\"},\n" + + "{\"dateformat\": \"YYYYMMDD\"},\n" + + "{\"dateformat\": \"YYYY-MM-DD HH24:MI:SS\"},\n" + + "{\"dateformat\": \"YYYY/MM/DD HH24:MI:SS\"},\n" + + "{\"dateformat\": \"YYYYMMDD HH24:MI:SS\"}\n" + + "]", new TypeReference>() {} ); + }catch (Exception e){} + return dateformats; + } +} diff --git a/extensions/dataease-extensions-datasource/dm/dm-backend/src/main/java/io/dataease/plugins/datasource/dm/service/DmService.java b/extensions/dataease-extensions-datasource/dm/dm-backend/src/main/java/io/dataease/plugins/datasource/dm/service/DmService.java new file mode 100644 index 0000000000..b259396354 --- /dev/null +++ b/extensions/dataease-extensions-datasource/dm/dm-backend/src/main/java/io/dataease/plugins/datasource/dm/service/DmService.java @@ -0,0 +1,59 @@ +package io.dataease.plugins.datasource.dm.service; + +import io.dataease.plugins.common.constants.DatabaseClassification; +import io.dataease.plugins.common.constants.DatasourceCalculationMode; +import io.dataease.plugins.common.dto.StaticResource; +import io.dataease.plugins.common.dto.datasource.DataSourceType; +import io.dataease.plugins.datasource.service.DatasourceService; +import org.springframework.stereotype.Service; + +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + +@Service +public class DmService extends DatasourceService { + + + @Override + public List components() { + List result = new ArrayList<>(); + result.add("dm"); + return result; + } + @Override + protected InputStream readContent(String s) { + InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream("static/" + s); + return resourceAsStream; + } + + + @Override + public List staticResources() { + List results = new ArrayList<>(); + StaticResource staticResource = new StaticResource(); + staticResource.setName("dm"); + staticResource.setSuffix("jpg"); + results.add(staticResource); + results.add(pluginSvg()); + return results; + } + + @Override + public DataSourceType getDataSourceType() { + DataSourceType dataSourceType = new DataSourceType("dm", "DM" , true , "", DatasourceCalculationMode.DIRECT, true); + dataSourceType.setKeywordPrefix("\""); + dataSourceType.setKeywordSuffix("\""); + dataSourceType.setAliasPrefix("\""); + dataSourceType.setAliasSuffix("\""); + dataSourceType.setDatabaseClassification(DatabaseClassification.OLTP); + return dataSourceType; + } + + private StaticResource pluginSvg() { + StaticResource staticResource = new StaticResource(); + staticResource.setName("dm-backend"); + staticResource.setSuffix("svg"); + return staticResource; + } +} diff --git a/extensions/dataease-extensions-datasource/dm/dm-frontend/.babelrc b/extensions/dataease-extensions-datasource/dm/dm-frontend/.babelrc new file mode 100644 index 0000000000..3a280ba34b --- /dev/null +++ b/extensions/dataease-extensions-datasource/dm/dm-frontend/.babelrc @@ -0,0 +1,12 @@ +{ + "presets": [ + ["env", { + "modules": false, + "targets": { + "browsers": ["> 1%", "last 2 versions", "not ie <= 8"] + } + }], + "stage-2" + ], + "plugins": ["transform-vue-jsx", "transform-runtime"] +} diff --git a/extensions/dataease-extensions-datasource/dm/dm-frontend/.gitignore b/extensions/dataease-extensions-datasource/dm/dm-frontend/.gitignore new file mode 100644 index 0000000000..541a820f6c --- /dev/null +++ b/extensions/dataease-extensions-datasource/dm/dm-frontend/.gitignore @@ -0,0 +1,14 @@ +.DS_Store +node_modules/ +/dist/ +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Editor directories and files +.idea +.vscode +*.suo +*.ntvs* +*.njsproj +*.sln diff --git a/extensions/dataease-extensions-datasource/dm/dm-frontend/README.md b/extensions/dataease-extensions-datasource/dm/dm-frontend/README.md new file mode 100644 index 0000000000..c1e4be95e0 --- /dev/null +++ b/extensions/dataease-extensions-datasource/dm/dm-frontend/README.md @@ -0,0 +1,21 @@ +# deplugin-view-frontend + +> A Vue.js project + +## Build Setup + +``` bash +# install dependencies +npm install + +# serve with hot reload at localhost:8080 +npm run dev + +# build for production with minification +npm run build + +# build for production and view the bundle analyzer report +npm run build --report +``` + +For a detailed explanation on how things work, check out the [guide](http://vuejs-templates.github.io/webpack/) and [docs for vue-loader](http://vuejs.github.io/vue-loader). diff --git a/extensions/dataease-extensions-datasource/dm/dm-frontend/build/build-async-plugins.js b/extensions/dataease-extensions-datasource/dm/dm-frontend/build/build-async-plugins.js new file mode 100644 index 0000000000..2303854531 --- /dev/null +++ b/extensions/dataease-extensions-datasource/dm/dm-frontend/build/build-async-plugins.js @@ -0,0 +1,35 @@ +'use strict' +require('./check-versions')() + +process.env.NODE_ENV = 'production' + +const ora = require('ora') +const chalk = require('chalk') +const webpack = require('webpack') +const webpackConfig = require('./webpack.async-plugins') + +const spinner = ora('building for sync-plugins...') +spinner.start() + +webpack(webpackConfig, function (err, stats) { + spinner.stop() + if (err) throw err + process.stdout.write(stats.toString({ + colors: true, + modules: false, + children: false, + chunks: false, + chunkModules: false + }) + '\n\n') + + if (stats.hasErrors()) { + console.log(chalk.red(' Build failed with errors.\n')) + process.exit(1) + } + + console.log(chalk.cyan(' Build complete.\n')) + console.log(chalk.yellow( + ' Tip: built files are meant to be served over an HTTP server.\n' + + ' Opening index.html over file:// won\'t work.\n' + )) +}) diff --git a/extensions/dataease-extensions-datasource/dm/dm-frontend/build/build.js b/extensions/dataease-extensions-datasource/dm/dm-frontend/build/build.js new file mode 100644 index 0000000000..8f2ad8ad49 --- /dev/null +++ b/extensions/dataease-extensions-datasource/dm/dm-frontend/build/build.js @@ -0,0 +1,41 @@ +'use strict' +require('./check-versions')() + +process.env.NODE_ENV = 'production' + +const ora = require('ora') +const rm = require('rimraf') +const path = require('path') +const chalk = require('chalk') +const webpack = require('webpack') +const config = require('../config') +const webpackConfig = require('./webpack.prod.conf') + +const spinner = ora('building for production...') +spinner.start() + +rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => { + if (err) throw err + webpack(webpackConfig, (err, stats) => { + spinner.stop() + if (err) throw err + process.stdout.write(stats.toString({ + colors: true, + modules: false, + children: false, // If you are using ts-loader, setting this to true will make TypeScript errors show up during build. + chunks: false, + chunkModules: false + }) + '\n\n') + + if (stats.hasErrors()) { + console.log(chalk.red(' Build failed with errors.\n')) + process.exit(1) + } + + console.log(chalk.cyan(' Build complete.\n')) + console.log(chalk.yellow( + ' Tip: built files are meant to be served over an HTTP server.\n' + + ' Opening index.html over file:// won\'t work.\n' + )) + }) +}) diff --git a/extensions/dataease-extensions-datasource/dm/dm-frontend/build/check-versions.js b/extensions/dataease-extensions-datasource/dm/dm-frontend/build/check-versions.js new file mode 100644 index 0000000000..3ef972a08d --- /dev/null +++ b/extensions/dataease-extensions-datasource/dm/dm-frontend/build/check-versions.js @@ -0,0 +1,54 @@ +'use strict' +const chalk = require('chalk') +const semver = require('semver') +const packageConfig = require('../package.json') +const shell = require('shelljs') + +function exec (cmd) { + return require('child_process').execSync(cmd).toString().trim() +} + +const versionRequirements = [ + { + name: 'node', + currentVersion: semver.clean(process.version), + versionRequirement: packageConfig.engines.node + } +] + +if (shell.which('npm')) { + versionRequirements.push({ + name: 'npm', + currentVersion: exec('npm --version'), + versionRequirement: packageConfig.engines.npm + }) +} + +module.exports = function () { + const warnings = [] + + for (let i = 0; i < versionRequirements.length; i++) { + const mod = versionRequirements[i] + + if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) { + warnings.push(mod.name + ': ' + + chalk.red(mod.currentVersion) + ' should be ' + + chalk.green(mod.versionRequirement) + ) + } + } + + if (warnings.length) { + console.log('') + console.log(chalk.yellow('To use this template, you must update following to modules:')) + console.log() + + for (let i = 0; i < warnings.length; i++) { + const warning = warnings[i] + console.log(' ' + warning) + } + + console.log() + process.exit(1) + } +} diff --git a/extensions/dataease-extensions-datasource/dm/dm-frontend/build/logo.png b/extensions/dataease-extensions-datasource/dm/dm-frontend/build/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..f3d2503fc2a44b5053b0837ebea6e87a2d339a43 GIT binary patch literal 6849 zcmaKRcUV(fvo}bjDT-7nLI_nlK}sT_69H+`qzVWDA|yaU?}j417wLi^B1KB1SLsC& zL0ag7$U(XW5YR7p&Ux?sP$d4lvMt8C^+TcQu4F zQqv!UF!I+kw)c0jhd6+g6oCr9P?7)?!qX1ui*iL{p}sKCAGuJ{{W)0z1pLF|=>h}& zt(2Lr0Z`2ig8<5i%Zk}cO5Fm=LByqGWaS`oqChZdEFmc`0hSb#gg|Aap^{+WKOYcj zHjINK)KDG%&s?Mt4CL(T=?;~U@bU2x_mLKN!#GJuK_CzbNw5SMEJorG!}_5;?R>@1 zSl)jns3WlU7^J%=(hUtfmuUCU&C3%8B5C^f5>W2Cy8jW3#{Od{lF1}|?c61##3dzA zsPlFG;l_FzBK}8>|H_Ru_H#!_7$UH4UKo3lKOA}g1(R&|e@}GINYVzX?q=_WLZCgh z)L|eJMce`D0EIwgRaNETDsr+?vQknSGAi=7H00r`QnI%oQnFxm`G2umXso9l+8*&Q z7WqF|$p49js$mdzo^BXpH#gURy=UO;=IMrYc5?@+sR4y_?d*~0^YP7d+y0{}0)zBM zIKVM(DBvICK#~7N0a+PY6)7;u=dutmNqK3AlsrUU9U`d;msiucB_|8|2kY=(7XA;G zwDA8AR)VCA#JOkxm#6oHNS^YVuOU;8p$N)2{`;oF|rQ?B~K$%rHDxXs+_G zF5|-uqHZvSzq}L;5Kcy_P+x0${33}Ofb6+TX&=y;;PkEOpz%+_bCw_{<&~ zeLV|!bP%l1qxywfVr9Z9JI+++EO^x>ZuCK);=$VIG1`kxK8F2M8AdC$iOe3cj1fo(ce4l-9 z7*zKy3={MixvUk=enQE;ED~7tv%qh&3lR<0m??@w{ILF|e#QOyPkFYK!&Up7xWNtL zOW%1QMC<3o;G9_S1;NkPB6bqbCOjeztEc6TsBM<(q9((JKiH{01+Ud=uw9B@{;(JJ z-DxI2*{pMq`q1RQc;V8@gYAY44Z!%#W~M9pRxI(R?SJ7sy7em=Z5DbuDlr@*q|25V)($-f}9c#?D%dU^RS<(wz?{P zFFHtCab*!rl(~j@0(Nadvwg8q|4!}L^>d?0al6}Rrv9$0M#^&@zjbfJy_n!%mVHK4 z6pLRIQ^Uq~dnyy$`ay51Us6WaP%&O;@49m&{G3z7xV3dLtt1VTOMYl3UW~Rm{Eq4m zF?Zl_v;?7EFx1_+#WFUXxcK78IV)FO>42@cm@}2I%pVbZqQ}3;p;sDIm&knay03a^ zn$5}Q$G!@fTwD$e(x-~aWP0h+4NRz$KlnO_H2c< z(XX#lPuW_%H#Q+c&(nRyX1-IadKR-%$4FYC0fsCmL9ky3 zKpxyjd^JFR+vg2!=HWf}2Z?@Td`0EG`kU?{8zKrvtsm)|7>pPk9nu@2^z96aU2<#` z2QhvH5w&V;wER?mopu+nqu*n8p~(%QkwSs&*0eJwa zMXR05`OSFpfyRb!Y_+H@O%Y z0=K^y6B8Gcbl?SA)qMP3Z+=C(?8zL@=74R=EVnE?vY!1BQy2@q*RUgRx4yJ$k}MnL zs!?74QciNb-LcG*&o<9=DSL>1n}ZNd)w1z3-0Pd^4ED1{qd=9|!!N?xnXjM!EuylY z5=!H>&hSofh8V?Jofyd!h`xDI1fYAuV(sZwwN~{$a}MX^=+0TH*SFp$vyxmUv7C*W zv^3Gl0+eTFgBi3FVD;$nhcp)ka*4gSskYIqQ&+M}xP9yLAkWzBI^I%zR^l1e?bW_6 zIn{mo{dD=)9@V?s^fa55jh78rP*Ze<3`tRCN4*mpO$@7a^*2B*7N_|A(Ve2VB|)_o z$=#_=aBkhe(ifX}MLT()@5?OV+~7cXC3r!%{QJxriXo9I%*3q4KT4Xxzyd{ z9;_%=W%q!Vw$Z7F3lUnY+1HZ*lO;4;VR2+i4+D(m#01OYq|L_fbnT;KN<^dkkCwtd zF7n+O7KvAw8c`JUh6LmeIrk4`F3o|AagKSMK3))_5Cv~y2Bb2!Ibg9BO7Vkz?pAYX zoI=B}+$R22&IL`NCYUYjrdhwjnMx_v=-Qcx-jmtN>!Zqf|n1^SWrHy zK|MwJ?Z#^>)rfT5YSY{qjZ&`Fjd;^vv&gF-Yj6$9-Dy$<6zeP4s+78gS2|t%Z309b z0^fp~ue_}i`U9j!<|qF92_3oB09NqgAoehQ`)<)dSfKoJl_A6Ec#*Mx9Cpd-p#$Ez z={AM*r-bQs6*z$!*VA4|QE7bf@-4vb?Q+pPKLkY2{yKsw{&udv_2v8{Dbd zm~8VAv!G~s)`O3|Q6vFUV%8%+?ZSVUa(;fhPNg#vab@J*9XE4#D%)$UU-T5`fwjz! z6&gA^`OGu6aUk{l*h9eB?opVdrHK>Q@U>&JQ_2pR%}TyOXGq_6s56_`U(WoOaAb+K zXQr#6H}>a-GYs9^bGP2Y&hSP5gEtW+GVC4=wy0wQk=~%CSXj=GH6q z-T#s!BV`xZVxm{~jr_ezYRpqqIcXC=Oq`b{lu`Rt(IYr4B91hhVC?yg{ol4WUr3v9 zOAk2LG>CIECZ-WIs0$N}F#eoIUEtZudc7DPYIjzGqDLWk_A4#(LgacooD z2K4IWs@N`Bddm-{%oy}!k0^i6Yh)uJ1S*90>|bm3TOZxcV|ywHUb(+CeX-o1|LTZM zwU>dY3R&U)T(}5#Neh?-CWT~@{6Ke@sI)uSuzoah8COy)w)B)aslJmp`WUcjdia-0 zl2Y}&L~XfA`uYQboAJ1;J{XLhYjH){cObH3FDva+^8ioOQy%Z=xyjGLmWMrzfFoH; zEi3AG`_v+%)&lDJE;iJWJDI@-X9K5O)LD~j*PBe(wu+|%ar~C+LK1+-+lK=t# z+Xc+J7qp~5q=B~rD!x78)?1+KUIbYr^5rcl&tB-cTtj+e%{gpZZ4G~6r15+d|J(ky zjg@@UzMW0k9@S#W(1H{u;Nq(7llJbq;;4t$awM;l&(2s+$l!Ay9^Ge|34CVhr7|BG z?dAR83smef^frq9V(OH+a+ki#q&-7TkWfFM=5bsGbU(8mC;>QTCWL5ydz9s6k@?+V zcjiH`VI=59P-(-DWXZ~5DH>B^_H~;4$)KUhnmGo*G!Tq8^LjfUDO)lASN*=#AY_yS zqW9UX(VOCO&p@kHdUUgsBO0KhXxn1sprK5h8}+>IhX(nSXZKwlNsjk^M|RAaqmCZB zHBolOHYBas@&{PT=R+?d8pZu zUHfyucQ`(umXSW7o?HQ3H21M`ZJal+%*)SH1B1j6rxTlG3hx1IGJN^M7{$j(9V;MZ zRKybgVuxKo#XVM+?*yTy{W+XHaU5Jbt-UG33x{u(N-2wmw;zzPH&4DE103HV@ER86 z|FZEmQb|&1s5#`$4!Cm}&`^{(4V}OP$bk`}v6q6rm;P!H)W|2i^e{7lTk2W@jo_9q z*aw|U7#+g59Fv(5qI`#O-qPj#@_P>PC#I(GSp3DLv7x-dmYK=C7lPF8a)bxb=@)B1 zUZ`EqpXV2dR}B&r`uM}N(TS99ZT0UB%IN|0H%DcVO#T%L_chrgn#m6%x4KE*IMfjX zJ%4veCEqbXZ`H`F_+fELMC@wuy_ch%t*+Z+1I}wN#C+dRrf2X{1C8=yZ_%Pt6wL_~ zZ2NN-hXOT4P4n$QFO7yYHS-4wF1Xfr-meG9Pn;uK51?hfel`d38k{W)F*|gJLT2#T z<~>spMu4(mul-8Q3*pf=N4DcI)zzjqAgbE2eOT7~&f1W3VsdD44Ffe;3mJp-V@8UC z)|qnPc12o~$X-+U@L_lWqv-RtvB~%hLF($%Ew5w>^NR82qC_0FB z)=hP1-OEx?lLi#jnLzH}a;Nvr@JDO-zQWd}#k^an$Kwml;MrD&)sC5b`s0ZkVyPkb zt}-jOq^%_9>YZe7Y}PhW{a)c39G`kg(P4@kxjcYfgB4XOOcmezdUI7j-!gs7oAo2o zx(Ph{G+YZ`a%~kzK!HTAA5NXE-7vOFRr5oqY$rH>WI6SFvWmahFav!CfRMM3%8J&c z*p+%|-fNS_@QrFr(at!JY9jCg9F-%5{nb5Bo~z@Y9m&SHYV`49GAJjA5h~h4(G!Se zZmK{Bo7ivCfvl}@A-ptkFGcWXAzj3xfl{evi-OG(TaCn1FAHxRc{}B|x+Ua1D=I6M z!C^ZIvK6aS_c&(=OQDZfm>O`Nxsw{ta&yiYPA~@e#c%N>>#rq)k6Aru-qD4(D^v)y z*>Rs;YUbD1S8^D(ps6Jbj0K3wJw>L4m)0e(6Pee3Y?gy9i0^bZO?$*sv+xKV?WBlh zAp*;v6w!a8;A7sLB*g-^<$Z4L7|5jXxxP1}hQZ<55f9<^KJ>^mKlWSGaLcO0=$jem zWyZkRwe~u{{tU63DlCaS9$Y4CP4f?+wwa(&1ou)b>72ydrFvm`Rj-0`kBJgK@nd(*Eh!(NC{F-@=FnF&Y!q`7){YsLLHf0_B6aHc# z>WIuHTyJwIH{BJ4)2RtEauC7Yq7Cytc|S)4^*t8Va3HR zg=~sN^tp9re@w=GTx$;zOWMjcg-7X3Wk^N$n;&Kf1RgVG2}2L-(0o)54C509C&77i zrjSi{X*WV=%C17((N^6R4Ya*4#6s_L99RtQ>m(%#nQ#wrRC8Y%yxkH;d!MdY+Tw@r zjpSnK`;C-U{ATcgaxoEpP0Gf+tx);buOMlK=01D|J+ROu37qc*rD(w`#O=3*O*w9?biwNoq3WN1`&Wp8TvKj3C z3HR9ssH7a&Vr<6waJrU zdLg!ieYz%U^bmpn%;(V%%ugMk92&?_XX1K@mwnVSE6!&%P%Wdi7_h`CpScvspMx?N zQUR>oadnG17#hNc$pkTp+9lW+MBKHRZ~74XWUryd)4yd zj98$%XmIL4(9OnoeO5Fnyn&fpQ9b0h4e6EHHw*l68j;>(ya`g^S&y2{O8U>1*>4zR zq*WSI_2o$CHQ?x0!wl9bpx|Cm2+kFMR)oMud1%n2=qn5nE&t@Fgr#=Zv2?}wtEz^T z9rrj=?IH*qI5{G@Rn&}^Z{+TW}mQeb9=8b<_a`&Cm#n%n~ zU47MvCBsdXFB1+adOO)03+nczfWa#vwk#r{o{dF)QWya9v2nv43Zp3%Ps}($lA02*_g25t;|T{A5snSY?3A zrRQ~(Ygh_ebltHo1VCbJb*eOAr;4cnlXLvI>*$-#AVsGg6B1r7@;g^L zFlJ_th0vxO7;-opU@WAFe;<}?!2q?RBrFK5U{*ai@NLKZ^};Ul}beukveh?TQn;$%9=R+DX07m82gP$=}Uo_%&ngV`}Hyv8g{u z3SWzTGV|cwQuFIs7ZDOqO_fGf8Q`8MwL}eUp>q?4eqCmOTcwQuXtQckPy|4F1on8l zP*h>d+cH#XQf|+6c|S{7SF(Lg>bR~l(0uY?O{OEVlaxa5@e%T&xju=o1`=OD#qc16 zSvyH*my(dcp6~VqR;o(#@m44Lug@~_qw+HA=mS#Z^4reBy8iV?H~I;{LQWk3aKK8$bLRyt$g?- { + const notifier = require('node-notifier') + + return (severity, errors) => { + if (severity !== 'error') return + + const error = errors[0] + const filename = error.file && error.file.split('!').pop() + + notifier.notify({ + title: packageConfig.name, + message: severity + ': ' + error.name, + subtitle: filename || '', + icon: path.join(__dirname, 'logo.png') + }) + } +} diff --git a/extensions/dataease-extensions-datasource/dm/dm-frontend/build/vue-loader.conf.js b/extensions/dataease-extensions-datasource/dm/dm-frontend/build/vue-loader.conf.js new file mode 100644 index 0000000000..33ed58bc0a --- /dev/null +++ b/extensions/dataease-extensions-datasource/dm/dm-frontend/build/vue-loader.conf.js @@ -0,0 +1,22 @@ +'use strict' +const utils = require('./utils') +const config = require('../config') +const isProduction = process.env.NODE_ENV === 'production' +const sourceMapEnabled = isProduction + ? config.build.productionSourceMap + : config.dev.cssSourceMap + +module.exports = { + loaders: utils.cssLoaders({ + sourceMap: sourceMapEnabled, + extract: isProduction + }), + cssSourceMap: sourceMapEnabled, + cacheBusting: config.dev.cacheBusting, + transformToRequire: { + video: ['src', 'poster'], + source: 'src', + img: 'src', + image: 'xlink:href' + } +} diff --git a/extensions/dataease-extensions-datasource/dm/dm-frontend/build/webpack.async-plugins.js b/extensions/dataease-extensions-datasource/dm/dm-frontend/build/webpack.async-plugins.js new file mode 100644 index 0000000000..a1587e3ce0 --- /dev/null +++ b/extensions/dataease-extensions-datasource/dm/dm-frontend/build/webpack.async-plugins.js @@ -0,0 +1,91 @@ +const webpack = require('webpack') +const path = require('path') +const utils = require('./utils') +const CopyPlugin = require("copy-webpack-plugin"); +const VueLoaderPlugin = require('vue-loader/lib/plugin'); +function resolve (dir) { + return path.join(__dirname, '..', dir) +} + +module.exports = { + mode: 'development', + entry: { + 'dm': resolve('/src/views/dm.vue') + }, + output: { + path: resolve('/static/'), + filename: '[name].js' + }, + resolve: { + extensions: ['.js', '.vue', '.json'], + alias: { + 'vue$': 'vue/dist/vue.esm.js', + '@': resolve('src') + } + }, + externals: { + vue: 'vue' + }, + module: { + rules: [ + { + test: /\.vue$/, + loader: 'vue-loader', + options: { + transformAssetUrls: { + video: 'src', + source: 'src', + img: 'src', + image: 'xlink:href' + } + } + }, + { + test: /.(sa|sc|c)ss$/, + use: [ + {loader: 'vue-style-loader'}, + 'css-loader', + 'sass-loader' + ] + }, + { + test: /\.js$/, + loader: 'babel-loader', + include: [resolve('src'), resolve('test')] + }, + { + test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: utils.assetsPath('img/[name].[hash:7].[ext]') + } + }, + { + test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: utils.assetsPath('media/[name].[hash:7].[ext]') + } + }, + { + test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: utils.assetsPath('fonts/[name].[hash:7].[ext]') + } + } + ] + }, + plugins: [ + new VueLoaderPlugin(), + new webpack.DefinePlugin({ + 'process.env.NODE_ENV': '"production"' + }), + new CopyPlugin([ + {from: 'src/icons/svg/'} + ]), + ] +} diff --git a/extensions/dataease-extensions-datasource/dm/dm-frontend/build/webpack.base.conf.js b/extensions/dataease-extensions-datasource/dm/dm-frontend/build/webpack.base.conf.js new file mode 100644 index 0000000000..7ef785a39e --- /dev/null +++ b/extensions/dataease-extensions-datasource/dm/dm-frontend/build/webpack.base.conf.js @@ -0,0 +1,103 @@ +'use strict' +const path = require('path') +const utils = require('./utils') +const config = require('../config') +const vueLoaderConfig = require('./vue-loader.conf') + +function resolve (dir) { + return path.join(__dirname, '..', dir) +} + + + +module.exports = { + context: path.resolve(__dirname, '../'), + entry: { + app: './src/main.js' + }, + output: { + path: config.build.assetsRoot, + filename: '[name].js', + publicPath: process.env.NODE_ENV === 'production' + ? config.build.assetsPublicPath + : config.dev.assetsPublicPath + }, + resolve: { + extensions: ['.js', '.vue', '.json'], + alias: { + 'vue$': 'vue/dist/vue.esm.js', + '@': resolve('src'), + } + }, + module: { + rules: [ + { + test: /\.vue$/, + loader: 'vue-loader', + options: vueLoaderConfig + }, + { + test: /\.js$/, + loader: 'babel-loader', + include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')] + }, + { + test: /\.svg$/, + loader: 'svg-sprite-loader', + include: [resolve('src/icons')], + options: { + symbolId: 'icon-[name]' + } + }, + { + test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, + loader: 'url-loader', + exclude: [resolve('src/icons')], + options: { + limit: 10000, + name: utils.assetsPath('img/[name].[hash:7].[ext]') + } + }, + { + test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: utils.assetsPath('media/[name].[hash:7].[ext]') + } + }, + { + test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: utils.assetsPath('fonts/[name].[hash:7].[ext]') + } + }, + { + test: /\.svg$/, + include: [path.resolve('src/icons')], + use: [ + { + loader: 'svg-sprite-loader', + options: { + symbolId: 'icon-[name]', + }, + } + ], + } + ] + }, + node: { + // prevent webpack from injecting useless setImmediate polyfill because Vue + // source contains it (although only uses it if it's native). + setImmediate: false, + // prevent webpack from injecting mocks to Node native modules + // that does not make sense for the client + dgram: 'empty', + fs: 'empty', + net: 'empty', + tls: 'empty', + child_process: 'empty' + } +} diff --git a/extensions/dataease-extensions-datasource/dm/dm-frontend/build/webpack.dev.conf.js b/extensions/dataease-extensions-datasource/dm/dm-frontend/build/webpack.dev.conf.js new file mode 100755 index 0000000000..070ae221f3 --- /dev/null +++ b/extensions/dataease-extensions-datasource/dm/dm-frontend/build/webpack.dev.conf.js @@ -0,0 +1,95 @@ +'use strict' +const utils = require('./utils') +const webpack = require('webpack') +const config = require('../config') +const merge = require('webpack-merge') +const path = require('path') +const baseWebpackConfig = require('./webpack.base.conf') +const CopyWebpackPlugin = require('copy-webpack-plugin') +const HtmlWebpackPlugin = require('html-webpack-plugin') +const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin') +const portfinder = require('portfinder') + +const HOST = process.env.HOST +const PORT = process.env.PORT && Number(process.env.PORT) + +const devWebpackConfig = merge(baseWebpackConfig, { + module: { + rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true }) + }, + // cheap-module-eval-source-map is faster for development + devtool: config.dev.devtool, + + // these devServer options should be customized in /config/index.js + devServer: { + clientLogLevel: 'warning', + historyApiFallback: { + rewrites: [ + { from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') }, + ], + }, + hot: true, + contentBase: false, // since we use CopyWebpackPlugin. + compress: true, + host: HOST || config.dev.host, + port: PORT || config.dev.port, + open: config.dev.autoOpenBrowser, + overlay: config.dev.errorOverlay + ? { warnings: false, errors: true } + : false, + publicPath: config.dev.assetsPublicPath, + proxy: config.dev.proxyTable, + quiet: true, // necessary for FriendlyErrorsPlugin + watchOptions: { + poll: config.dev.poll, + } + }, + plugins: [ + new webpack.DefinePlugin({ + 'process.env': require('../config/dev.env') + }), + new webpack.HotModuleReplacementPlugin(), + new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update. + new webpack.NoEmitOnErrorsPlugin(), + // https://github.com/ampedandwired/html-webpack-plugin + new HtmlWebpackPlugin({ + filename: 'index.html', + template: 'index.html', + inject: true + }), + // copy custom static assets + new CopyWebpackPlugin([ + { + from: path.resolve(__dirname, '../static'), + to: config.dev.assetsSubDirectory, + ignore: ['.*'] + } + ]) + ] +}) + +module.exports = new Promise((resolve, reject) => { + portfinder.basePort = process.env.PORT || config.dev.port + portfinder.getPort((err, port) => { + if (err) { + reject(err) + } else { + // publish the new Port, necessary for e2e tests + process.env.PORT = port + // add port to devServer config + devWebpackConfig.devServer.port = port + + // Add FriendlyErrorsPlugin + devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({ + compilationSuccessInfo: { + messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`], + }, + onErrors: config.dev.notifyOnErrors + ? utils.createNotifierCallback() + : undefined + })) + + resolve(devWebpackConfig) + } + }) +}) diff --git a/extensions/dataease-extensions-datasource/dm/dm-frontend/build/webpack.prod.conf.js b/extensions/dataease-extensions-datasource/dm/dm-frontend/build/webpack.prod.conf.js new file mode 100644 index 0000000000..3e25238ef6 --- /dev/null +++ b/extensions/dataease-extensions-datasource/dm/dm-frontend/build/webpack.prod.conf.js @@ -0,0 +1,145 @@ +'use strict' +const path = require('path') +const utils = require('./utils') +const webpack = require('webpack') +const config = require('../config') +const merge = require('webpack-merge') +const baseWebpackConfig = require('./webpack.base.conf') +const CopyWebpackPlugin = require('copy-webpack-plugin') +const HtmlWebpackPlugin = require('html-webpack-plugin') +const ExtractTextPlugin = require('extract-text-webpack-plugin') +const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin') +const UglifyJsPlugin = require('uglifyjs-webpack-plugin') + +const env = require('../config/prod.env') + +const webpackConfig = merge(baseWebpackConfig, { + module: { + rules: utils.styleLoaders({ + sourceMap: config.build.productionSourceMap, + extract: true, + usePostCSS: true + }) + }, + devtool: config.build.productionSourceMap ? config.build.devtool : false, + output: { + path: config.build.assetsRoot, + filename: utils.assetsPath('js/[name].[chunkhash].js'), + chunkFilename: utils.assetsPath('js/[id].[chunkhash].js') + }, + plugins: [ + // http://vuejs.github.io/vue-loader/en/workflow/production.html + new webpack.DefinePlugin({ + 'process.env': env + }), + new UglifyJsPlugin({ + uglifyOptions: { + compress: { + warnings: false + } + }, + sourceMap: config.build.productionSourceMap, + parallel: true + }), + // extract css into its own file + new ExtractTextPlugin({ + filename: utils.assetsPath('css/[name].[contenthash].css'), + // Setting the following option to `false` will not extract CSS from codesplit chunks. + // Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack. + // It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`, + // increasing file size: https://github.com/vuejs-templates/webpack/issues/1110 + allChunks: true, + }), + // Compress extracted CSS. We are using this plugin so that possible + // duplicated CSS from different components can be deduped. + new OptimizeCSSPlugin({ + cssProcessorOptions: config.build.productionSourceMap + ? { safe: true, map: { inline: false } } + : { safe: true } + }), + // generate dist index.html with correct asset hash for caching. + // you can customize output by editing /index.html + // see https://github.com/ampedandwired/html-webpack-plugin + new HtmlWebpackPlugin({ + filename: config.build.index, + template: 'index.html', + inject: true, + minify: { + removeComments: true, + collapseWhitespace: true, + removeAttributeQuotes: true + // more options: + // https://github.com/kangax/html-minifier#options-quick-reference + }, + // necessary to consistently work with multiple chunks via CommonsChunkPlugin + chunksSortMode: 'dependency' + }), + // keep module.id stable when vendor modules does not change + new webpack.HashedModuleIdsPlugin(), + // enable scope hoisting + new webpack.optimize.ModuleConcatenationPlugin(), + // split vendor js into its own file + new webpack.optimize.CommonsChunkPlugin({ + name: 'vendor', + minChunks (module) { + // any required modules inside node_modules are extracted to vendor + return ( + module.resource && + /\.js$/.test(module.resource) && + module.resource.indexOf( + path.join(__dirname, '../node_modules') + ) === 0 + ) + } + }), + // extract webpack runtime and module manifest to its own file in order to + // prevent vendor hash from being updated whenever app bundle is updated + new webpack.optimize.CommonsChunkPlugin({ + name: 'manifest', + minChunks: Infinity + }), + // This instance extracts shared chunks from code split chunks and bundles them + // in a separate chunk, similar to the vendor chunk + // see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk + new webpack.optimize.CommonsChunkPlugin({ + name: 'app', + async: 'vendor-async', + children: true, + minChunks: 3 + }), + + // copy custom static assets + new CopyWebpackPlugin([ + { + from: path.resolve(__dirname, '../static'), + to: config.build.assetsSubDirectory, + ignore: ['.*'] + } + ]) + ] +}) + +if (config.build.productionGzip) { + const CompressionWebpackPlugin = require('compression-webpack-plugin') + + webpackConfig.plugins.push( + new CompressionWebpackPlugin({ + asset: '[path].gz[query]', + algorithm: 'gzip', + test: new RegExp( + '\\.(' + + config.build.productionGzipExtensions.join('|') + + ')$' + ), + threshold: 10240, + minRatio: 0.8 + }) + ) +} + +if (config.build.bundleAnalyzerReport) { + const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin + webpackConfig.plugins.push(new BundleAnalyzerPlugin()) +} + +module.exports = webpackConfig diff --git a/extensions/dataease-extensions-datasource/dm/dm-frontend/config/dev.env.js b/extensions/dataease-extensions-datasource/dm/dm-frontend/config/dev.env.js new file mode 100644 index 0000000000..1e22973ae7 --- /dev/null +++ b/extensions/dataease-extensions-datasource/dm/dm-frontend/config/dev.env.js @@ -0,0 +1,7 @@ +'use strict' +const merge = require('webpack-merge') +const prodEnv = require('./prod.env') + +module.exports = merge(prodEnv, { + NODE_ENV: '"development"' +}) diff --git a/extensions/dataease-extensions-datasource/dm/dm-frontend/config/index.js b/extensions/dataease-extensions-datasource/dm/dm-frontend/config/index.js new file mode 100644 index 0000000000..c5eded7f81 --- /dev/null +++ b/extensions/dataease-extensions-datasource/dm/dm-frontend/config/index.js @@ -0,0 +1,69 @@ +'use strict' +// Template version: 1.3.1 +// see http://vuejs-templates.github.io/webpack for documentation. + +const path = require('path') + +module.exports = { + dev: { + + // Paths + assetsSubDirectory: 'static', + assetsPublicPath: '/', + proxyTable: {}, + + // Various Dev Server settings + host: 'localhost', // can be overwritten by process.env.HOST + port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined + autoOpenBrowser: false, + errorOverlay: true, + notifyOnErrors: true, + poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions- + + + /** + * Source Maps + */ + + // https://webpack.js.org/configuration/devtool/#development + devtool: 'cheap-module-eval-source-map', + + // If you have problems debugging vue-files in devtools, + // set this to false - it *may* help + // https://vue-loader.vuejs.org/en/options.html#cachebusting + cacheBusting: true, + + cssSourceMap: true + }, + + build: { + // Template for index.html + index: path.resolve(__dirname, '../dist/index.html'), + + // Paths + assetsRoot: path.resolve(__dirname, '../dist'), + assetsSubDirectory: 'static', + assetsPublicPath: '/', + + /** + * Source Maps + */ + + productionSourceMap: true, + // https://webpack.js.org/configuration/devtool/#production + devtool: '#source-map', + + // Gzip off by default as many popular static hosts such as + // Surge or Netlify already gzip all static assets for you. + // Before setting to `true`, make sure to: + // npm install --save-dev compression-webpack-plugin + productionGzip: false, + productionGzipExtensions: ['js', 'css'], + + // Run the build command with an extra argument to + // View the bundle analyzer report after build finishes: + // `npm run build --report` + // Set to `true` or `false` to always turn it on or off + bundleAnalyzerReport: process.env.npm_config_report + } +} diff --git a/extensions/dataease-extensions-datasource/dm/dm-frontend/config/prod.env.js b/extensions/dataease-extensions-datasource/dm/dm-frontend/config/prod.env.js new file mode 100644 index 0000000000..a6f997616e --- /dev/null +++ b/extensions/dataease-extensions-datasource/dm/dm-frontend/config/prod.env.js @@ -0,0 +1,4 @@ +'use strict' +module.exports = { + NODE_ENV: '"production"' +} diff --git a/extensions/dataease-extensions-datasource/dm/dm-frontend/index.html b/extensions/dataease-extensions-datasource/dm/dm-frontend/index.html new file mode 100644 index 0000000000..03ce3fdf27 --- /dev/null +++ b/extensions/dataease-extensions-datasource/dm/dm-frontend/index.html @@ -0,0 +1,12 @@ + + + + + + deplugin-view-frontend + + +
+ + + diff --git a/extensions/dataease-extensions-datasource/dm/dm-frontend/package.json b/extensions/dataease-extensions-datasource/dm/dm-frontend/package.json new file mode 100644 index 0000000000..64a3ce7ad6 --- /dev/null +++ b/extensions/dataease-extensions-datasource/dm/dm-frontend/package.json @@ -0,0 +1,75 @@ +{ + "name": "deplugin-datasource-frontend", + "version": "1.0.0", + "description": "A Vue.js project", + "author": "", + "private": true, + "scripts": { + "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js", + "start": "npm run dev", + "build": "node build/build.js", + "buildPlugin": "node build/build-async-plugins.js" + }, + "dependencies": { + "@riophae/vue-treeselect": "0.4.0", + "highcharts": "^10.0.0", + "svg-sprite-loader": "^6.0.11", + "svgo": "1.2.2", + "svgo-loader": "^3.0.1", + "vue": "^2.5.2", + "vue-i18n": "7.3.2", + "vue-router": "^3.0.1", + "vue-uuid": "2.0.2", + "vuedraggable": "^2.24.3" + }, + "devDependencies": { + "autoprefixer": "^7.1.2", + "babel-core": "^6.22.1", + "babel-helper-vue-jsx-merge-props": "^2.0.3", + "babel-loader": "^7.1.1", + "babel-plugin-syntax-jsx": "^6.18.0", + "babel-plugin-transform-runtime": "^6.22.0", + "babel-plugin-transform-vue-jsx": "^3.5.0", + "babel-preset-env": "^1.3.2", + "babel-preset-stage-2": "^6.22.0", + "chalk": "^2.0.1", + "copy-webpack-plugin": "^4.6.0", + "css-loader": "^0.28.0", + "element-ui": "2.15.7", + "extract-text-webpack-plugin": "^4.0.0-beta.0", + "file-loader": "^1.1.4", + "friendly-errors-webpack-plugin": "^1.6.1", + "html-webpack-plugin": "^3.2.0", + "js-cookie": "2.2.0", + "node-notifier": "^8.0.1", + "optimize-css-assets-webpack-plugin": "^3.2.0", + "ora": "^1.2.0", + "portfinder": "^1.0.13", + "postcss-import": "^11.0.0", + "postcss-loader": "^2.0.8", + "postcss-url": "^7.2.1", + "rimraf": "^2.6.0", + "sass": "^1.33.0", + "sass-loader": "^7.3.1", + "semver": "^5.3.0", + "shelljs": "^0.8.5", + "uglifyjs-webpack-plugin": "^1.1.1", + "url-loader": "^0.5.8", + "vue-loader": "^15.6.4", + "vue-style-loader": "^4.1.2", + "vue-template-compiler": "^2.5.2", + "webpack": "^4.8.1", + "webpack-bundle-analyzer": "^3.3.2", + "webpack-dev-server": "^3.1.11", + "webpack-merge": "^4.1.0" + }, + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + }, + "browserslist": [ + "> 1%", + "last 2 versions", + "not ie <= 8" + ] +} diff --git a/extensions/dataease-extensions-datasource/dm/dm-frontend/pom.xml b/extensions/dataease-extensions-datasource/dm/dm-frontend/pom.xml new file mode 100644 index 0000000000..eae8cd7ea0 --- /dev/null +++ b/extensions/dataease-extensions-datasource/dm/dm-frontend/pom.xml @@ -0,0 +1,80 @@ + + + + + io.dataease + dm + ${dataease.version} + + + 4.0.0 + dm-frontend + + + UTF-8 + UTF-8 + 1.9.1 + + + + + + maven-clean-plugin + + + + static + + ** + + false + + + + + + + + com.github.eirslett + frontend-maven-plugin + ${frontend-maven-plugin.version} + + + install node and npm + + install-node-and-npm + + + + v16.20.2 + 7.6.3 + + + + + npm install + + npm + + + + install --force + + + + + npm run buildPlugin + + npm + + + run buildPlugin + + + + + + + diff --git a/extensions/dataease-extensions-datasource/dm/dm-frontend/src/App.vue b/extensions/dataease-extensions-datasource/dm/dm-frontend/src/App.vue new file mode 100644 index 0000000000..8542e07722 --- /dev/null +++ b/extensions/dataease-extensions-datasource/dm/dm-frontend/src/App.vue @@ -0,0 +1,23 @@ + + + + + diff --git a/extensions/dataease-extensions-datasource/dm/dm-frontend/src/assets/logo.png b/extensions/dataease-extensions-datasource/dm/dm-frontend/src/assets/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..f3d2503fc2a44b5053b0837ebea6e87a2d339a43 GIT binary patch literal 6849 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 +
+

{{ msg }}

+

Essential Links

+ +

Ecosystem

+ +
+ + + + + + diff --git a/extensions/dataease-extensions-datasource/dm/dm-frontend/src/de-base/lang/en.js b/extensions/dataease-extensions-datasource/dm/dm-frontend/src/de-base/lang/en.js new file mode 100644 index 0000000000..3f7c408e8a --- /dev/null +++ b/extensions/dataease-extensions-datasource/dm/dm-frontend/src/de-base/lang/en.js @@ -0,0 +1,16 @@ +export default { + plugin_view_3d_pie: { + type_title: '3D-PIE', + label: 'Label', + angle: 'Angle' + }, + host: 'Host', + port: 'Port', + dataBase: 'Catalog', + schema: 'Schema', + username: 'User', + password: 'Password', + get_schema: 'Get Schema', + please_choose_schema: 'Please select Schema', + query_timeout: 'Query timeout (seconds)' +} diff --git a/extensions/dataease-extensions-datasource/dm/dm-frontend/src/de-base/lang/index.js b/extensions/dataease-extensions-datasource/dm/dm-frontend/src/de-base/lang/index.js new file mode 100644 index 0000000000..e50d0478e6 --- /dev/null +++ b/extensions/dataease-extensions-datasource/dm/dm-frontend/src/de-base/lang/index.js @@ -0,0 +1,49 @@ +import Vue from 'vue' +import VueI18n from 'vue-i18n' +import Cookies from 'js-cookie' +import elementEnLocale from 'element-ui/lib/locale/lang/en' // element-ui lang +import elementZhLocale from 'element-ui/lib/locale/lang/zh-CN'// element-ui lang +import elementTWLocale from 'element-ui/lib/locale/lang/zh-TW'// element-ui lang + +import localMessages from './messages' + + +Vue.use(VueI18n) + +const messages = { + en_US: { + ...localMessages['en_US'], + ...elementEnLocale + }, + zh_CN: { + ...localMessages['zh_CN'], + ...elementZhLocale + }, + zh_TW: { + ...localMessages['zh_TW'], + ...elementTWLocale + } +} +export function getLanguage () { + const chooseLanguage = Cookies.get('language') + if (chooseLanguage) return chooseLanguage + + // if has not choose language + const language = (navigator.language || navigator.browserLanguage).toLowerCase() + const locales = Object.keys(messages) + for (const locale of locales) { + if (language.indexOf(locale) > -1) { + return locale + } + } + return 'zh_CN' +} +const i18n = new VueI18n({ + // set locale + // options: en | zh | es + locale: getLanguage(), + // set locale messages + messages +}) + +export default i18n diff --git a/extensions/dataease-extensions-datasource/dm/dm-frontend/src/de-base/lang/messages.js b/extensions/dataease-extensions-datasource/dm/dm-frontend/src/de-base/lang/messages.js new file mode 100644 index 0000000000..844f8c0673 --- /dev/null +++ b/extensions/dataease-extensions-datasource/dm/dm-frontend/src/de-base/lang/messages.js @@ -0,0 +1,17 @@ +import enLocale from './en' +import zhLocale from './zh' +import twLocale from './tw' + +const messages = { + en_US: { + ...enLocale + }, + zh_CN: { + ...zhLocale + }, + zh_TW: { + ...twLocale + } +} + +export default messages \ No newline at end of file diff --git a/extensions/dataease-extensions-datasource/dm/dm-frontend/src/de-base/lang/tw.js b/extensions/dataease-extensions-datasource/dm/dm-frontend/src/de-base/lang/tw.js new file mode 100644 index 0000000000..745a3cd2eb --- /dev/null +++ b/extensions/dataease-extensions-datasource/dm/dm-frontend/src/de-base/lang/tw.js @@ -0,0 +1,16 @@ +export default { + plugin_view_3d_pie: { + type_title: '3D餅圖', + label: '標籤', + angle: '角度' + }, + host: '主機名', + port: '端口', + dataBase: '數據庫', + schema: 'Schema', + username: '用戶名', + password: '密碼', + get_schema: '获取 Schema', + please_choose_schema: '请选择 Schema', + query_timeout: '査詢超時(秒)' +} diff --git a/extensions/dataease-extensions-datasource/dm/dm-frontend/src/de-base/lang/zh.js b/extensions/dataease-extensions-datasource/dm/dm-frontend/src/de-base/lang/zh.js new file mode 100644 index 0000000000..ff8c95c1f1 --- /dev/null +++ b/extensions/dataease-extensions-datasource/dm/dm-frontend/src/de-base/lang/zh.js @@ -0,0 +1,21 @@ +export default { + plugin_view_3d_pie: { + type_title: '3D饼图', + label: '标签', + angle: '角度' + }, + host: '主机名', + port: '端口', + dataBase: '数据库', + schema: 'Schema', + username: '用户名', + password: '密码', + get_schema: '获取 Schema', + please_choose_schema: '请选择 Schema', + second: '秒', + enter_the_port: '请输入端口', + one_user_name: '请输入用户名', + input_a_password: '请输入密码', + please_select: '请选择', + query_timeout: '查询超时' +} diff --git a/extensions/dataease-extensions-datasource/dm/dm-frontend/src/icons/index.js b/extensions/dataease-extensions-datasource/dm/dm-frontend/src/icons/index.js new file mode 100644 index 0000000000..2c6b309c96 --- /dev/null +++ b/extensions/dataease-extensions-datasource/dm/dm-frontend/src/icons/index.js @@ -0,0 +1,9 @@ +import Vue from 'vue' +import SvgIcon from '@/components/SvgIcon'// svg component + +// register globally +Vue.component('svg-icon', SvgIcon) + +const req = require.context('./svg', false, /\.svg$/) +const requireAll = requireContext => requireContext.keys().map(requireContext) +requireAll(req) diff --git a/extensions/dataease-extensions-datasource/dm/dm-frontend/src/icons/svg/de_pwd_invisible.svg b/extensions/dataease-extensions-datasource/dm/dm-frontend/src/icons/svg/de_pwd_invisible.svg new file mode 100644 index 0000000000..661ebba33e --- /dev/null +++ b/extensions/dataease-extensions-datasource/dm/dm-frontend/src/icons/svg/de_pwd_invisible.svg @@ -0,0 +1,3 @@ + + + diff --git a/extensions/dataease-extensions-datasource/dm/dm-frontend/src/icons/svg/de_pwd_visible.svg b/extensions/dataease-extensions-datasource/dm/dm-frontend/src/icons/svg/de_pwd_visible.svg new file mode 100644 index 0000000000..4e7ba5e799 --- /dev/null +++ b/extensions/dataease-extensions-datasource/dm/dm-frontend/src/icons/svg/de_pwd_visible.svg @@ -0,0 +1,3 @@ + + + diff --git a/extensions/dataease-extensions-datasource/dm/dm-frontend/src/icons/svg/dm-backend.svg b/extensions/dataease-extensions-datasource/dm/dm-frontend/src/icons/svg/dm-backend.svg new file mode 100644 index 0000000000..5b3c9135fe --- /dev/null +++ b/extensions/dataease-extensions-datasource/dm/dm-frontend/src/icons/svg/dm-backend.svg @@ -0,0 +1 @@ +【icon】插件管理-导出 diff --git a/extensions/dataease-extensions-datasource/dm/dm-frontend/src/icons/svg/dm.jpg b/extensions/dataease-extensions-datasource/dm/dm-frontend/src/icons/svg/dm.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2d770a439dae535979786d98c234946de143640d GIT binary patch literal 52036 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 rR{ZJ4;lIfg|CPh#KV7l;f3% i18n.t(key, value) +}) +Vue.component('Treeselect', Treeselect) +Vue.component('draggable', draggable) +Vue.prototype.hasDataPermission = function(pTarget, pSource) { + + if (pSource && pTarget) { + return pSource.indexOf(pTarget) > -1 + } + return false +} +/* eslint-disable no-new */ +new Vue({ + el: '#app', + router, + i18n, + components: { App }, + template: '' +}) diff --git a/extensions/dataease-extensions-datasource/dm/dm-frontend/src/router/index.js b/extensions/dataease-extensions-datasource/dm/dm-frontend/src/router/index.js new file mode 100644 index 0000000000..b5b55fa1fc --- /dev/null +++ b/extensions/dataease-extensions-datasource/dm/dm-frontend/src/router/index.js @@ -0,0 +1,21 @@ +import Vue from 'vue' +import Router from 'vue-router' +import HelloWorld from '@/components/HelloWorld' +import maxcompute from '@/views/maxcompute' + +Vue.use(Router) + +export default new Router({ + routes: [ + { + path: '/', + name: 'HelloWorld', + component: HelloWorld + }, + { + path: '/maxcompute', + name: 'maxcompute', + component: maxcompute + } + ] +}) diff --git a/extensions/dataease-extensions-datasource/dm/dm-frontend/src/utils/compare.js b/extensions/dataease-extensions-datasource/dm/dm-frontend/src/utils/compare.js new file mode 100644 index 0000000000..b06a104a10 --- /dev/null +++ b/extensions/dataease-extensions-datasource/dm/dm-frontend/src/utils/compare.js @@ -0,0 +1,29 @@ +export const compareItem = { + type: 'none', // year-yoy/month-yoy等 + resultData: 'percent', // 对比差sub,百分比percent等 + field: '', + custom: { + field: '', + calcType: '0', // 0-增长值,1-增长率 + timeType: '0', // 0-固定日期,1-日期区间 + currentTime: '', + compareTime: '', + currentTimeRange: [], + compareTimeRange: [] + } +} + +export const compareYearList = [ + { name: 'year_mom', value: 'year_mom' } +] + +export const compareMonthList = [ + { name: 'month_mom', value: 'month_mom' }, + { name: 'year_yoy', value: 'year_yoy' } +] + +export const compareDayList = [ + { name: 'day_mom', value: 'day_mom' }, + { name: 'month_yoy', value: 'month_yoy' }, + { name: 'year_yoy', value: 'year_yoy' } +] diff --git a/extensions/dataease-extensions-datasource/dm/dm-frontend/src/utils/validate.js b/extensions/dataease-extensions-datasource/dm/dm-frontend/src/utils/validate.js new file mode 100644 index 0000000000..3e8ffa9448 --- /dev/null +++ b/extensions/dataease-extensions-datasource/dm/dm-frontend/src/utils/validate.js @@ -0,0 +1,15 @@ +/** + * Created by PanJiaChen on 16/11/18. + */ + +/** + * @param {string} path + * @returns {Boolean} + */ +export function isExternal(path) { + return /^(https?:|mailto:|tel:)/.test(path) || /^(http?:|mailto:|tel:)/.test(path) || path.startsWith('/api/pluginCommon/staticInfo') +} + + + + diff --git a/extensions/dataease-extensions-datasource/dm/dm-frontend/src/views/dePwd.vue b/extensions/dataease-extensions-datasource/dm/dm-frontend/src/views/dePwd.vue new file mode 100644 index 0000000000..61bf3e88ee --- /dev/null +++ b/extensions/dataease-extensions-datasource/dm/dm-frontend/src/views/dePwd.vue @@ -0,0 +1,75 @@ + + + + \ No newline at end of file diff --git a/extensions/dataease-extensions-datasource/dm/dm-frontend/src/views/dm.vue b/extensions/dataease-extensions-datasource/dm/dm-frontend/src/views/dm.vue new file mode 100644 index 0000000000..35dc3badef --- /dev/null +++ b/extensions/dataease-extensions-datasource/dm/dm-frontend/src/views/dm.vue @@ -0,0 +1,202 @@ + + + + + diff --git a/extensions/dataease-extensions-datasource/dm/plugin.json b/extensions/dataease-extensions-datasource/dm/plugin.json new file mode 100644 index 0000000000..137eaef7b9 --- /dev/null +++ b/extensions/dataease-extensions-datasource/dm/plugin.json @@ -0,0 +1,13 @@ +{ + "name":"达梦数据源插件", + "free":0, + "store":"default", + "cost":0, + "category":"datasource", + "descript":"达梦插件,值得拥有", + "version":"1.18.0", + "creator":"DATAEASE", + "moduleName":"dm-backend", + "require":"1.12.0", + "dsType":"dm" +} diff --git a/extensions/dataease-extensions-datasource/dm/pom.xml b/extensions/dataease-extensions-datasource/dm/pom.xml new file mode 100644 index 0000000000..0b467c4e29 --- /dev/null +++ b/extensions/dataease-extensions-datasource/dm/pom.xml @@ -0,0 +1,19 @@ + + + + dataease-extensions-datasource + io.dataease + ${dataease.version} + + 4.0.0 + + dm + pom + + dm-frontend + dm-backend + + + diff --git a/extensions/dataease-extensions-datasource/kingbase/build.sh b/extensions/dataease-extensions-datasource/kingbase/build.sh new file mode 100755 index 0000000000..b37400980a --- /dev/null +++ b/extensions/dataease-extensions-datasource/kingbase/build.sh @@ -0,0 +1,6 @@ +#!/bin/sh +mvn clean package -U -Dmaven.test.skip=true + +cp kingbase-backend/target/kingbase-backend-1.18.0.jar . + +zip -r kingbase.zip ./kingbase-backend-1.18.0.jar ./kingbaseDriver ./plugin.json diff --git a/extensions/dataease-extensions-datasource/kingbase/kingbase-backend/pom.xml b/extensions/dataease-extensions-datasource/kingbase/kingbase-backend/pom.xml new file mode 100644 index 0000000000..4544d15cc9 --- /dev/null +++ b/extensions/dataease-extensions-datasource/kingbase/kingbase-backend/pom.xml @@ -0,0 +1,109 @@ + + + + kingbase + io.dataease + ${dataease.version} + + 4.0.0 + + kingbase-backend + + + + io.dataease + dataease-plugin-datasource + + + + + + + src/main/java + + **/*.properties + **/*.xml + + false + + + src/main/resources + + **/* + + false + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 11 + 11 + + + + + org.apache.maven.plugins + maven-jar-plugin + 2.4 + + + **/server/** + **/*.properties + **/Application* + + + + + + maven-clean-plugin + + + + src/main/resources/static + + ** + + false + + + + + + + + + org.apache.maven.plugins + maven-antrun-plugin + + + main-class-placement + generate-resources + + + + + + + + + + + + run + + + + + + + + + + + diff --git a/extensions/dataease-extensions-datasource/kingbase/kingbase-backend/src/main/java/io/dataease/plugins/datasource/kingbase/provider/KingbaseConfig.java b/extensions/dataease-extensions-datasource/kingbase/kingbase-backend/src/main/java/io/dataease/plugins/datasource/kingbase/provider/KingbaseConfig.java new file mode 100644 index 0000000000..b83467e5e4 --- /dev/null +++ b/extensions/dataease-extensions-datasource/kingbase/kingbase-backend/src/main/java/io/dataease/plugins/datasource/kingbase/provider/KingbaseConfig.java @@ -0,0 +1,27 @@ +package io.dataease.plugins.datasource.kingbase.provider; + +import io.dataease.plugins.datasource.entity.JdbcConfiguration; +import lombok.Getter; +import lombok.Setter; + +/** + * 连接配置信息 + */ +@Getter +@Setter +public class KingbaseConfig extends JdbcConfiguration { + + private String driver = "com.kingbase8.Driver";//驱动类名 + private String extraParams; + + + /** + * JDBC 拼接 + */ + public String getJdbc() { + return "jdbc:kingbase8://HOST:PORT/DATABASE" + .replace("HOST", getHost().trim()) + .replace("PORT", getPort().toString()) + .replace("DATABASE", getDataBase().trim()); + } +} diff --git a/extensions/dataease-extensions-datasource/kingbase/kingbase-backend/src/main/java/io/dataease/plugins/datasource/kingbase/provider/KingbaseDsProvider.java b/extensions/dataease-extensions-datasource/kingbase/kingbase-backend/src/main/java/io/dataease/plugins/datasource/kingbase/provider/KingbaseDsProvider.java new file mode 100644 index 0000000000..d3f2b843cb --- /dev/null +++ b/extensions/dataease-extensions-datasource/kingbase/kingbase-backend/src/main/java/io/dataease/plugins/datasource/kingbase/provider/KingbaseDsProvider.java @@ -0,0 +1,264 @@ +package io.dataease.plugins.datasource.kingbase.provider; + +import com.google.gson.Gson; +import io.dataease.plugins.common.base.domain.DeDriver; +import io.dataease.plugins.common.base.mapper.DeDriverMapper; +import io.dataease.plugins.common.constants.DatasourceTypes; +import io.dataease.plugins.common.dto.datasource.TableDesc; +import io.dataease.plugins.common.dto.datasource.TableField; +import io.dataease.plugins.common.exception.DataEaseException; +import io.dataease.plugins.common.request.datasource.DatasourceRequest; +import io.dataease.plugins.datasource.entity.JdbcConfiguration; +import io.dataease.plugins.datasource.provider.DefaultJdbcProvider; +import io.dataease.plugins.datasource.provider.ExtendedJdbcClassLoader; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.lang.reflect.Method; +import java.sql.*; +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.Properties; + + +@Component() +public class KingbaseDsProvider extends DefaultJdbcProvider { + @Resource + private DeDriverMapper deDriverMapper; + + @Override + public String getType() { + return "kingbase"; + } + + @Override + public boolean isUseDatasourcePool() { + return false; + } + + /** + * 连接数据源 + */ + @Override + public Connection getConnection(DatasourceRequest datasourceRequest) throws Exception { + KingbaseConfig kingbaseConfig = new Gson().fromJson(datasourceRequest.getDatasource().getConfiguration(), + KingbaseConfig.class); + + String defaultDriver = kingbaseConfig.getDriver(); + String customDriver = kingbaseConfig.getCustomDriver(); + + String url = kingbaseConfig.getJdbc(); + Properties props = new Properties(); + DeDriver deDriver = null; + if (StringUtils.isNotEmpty(kingbaseConfig.getAuthMethod()) && kingbaseConfig.getAuthMethod().equalsIgnoreCase("kerberos")) { + System.setProperty("java.security.krb5.conf", "/opt/dataease/conf/krb5.conf"); + ExtendedJdbcClassLoader classLoader; + if (isDefaultClassLoader(customDriver)) { + classLoader = extendedJdbcClassLoader; + } else { + deDriver = deDriverMapper.selectByPrimaryKey(customDriver); + classLoader = getCustomJdbcClassLoader(deDriver); + } + Class ConfigurationClass = classLoader.loadClass("org.apache.hadoop.conf.Configuration"); + Method set = ConfigurationClass.getMethod("set", String.class, String.class); + Object obj = ConfigurationClass.newInstance(); + set.invoke(obj, "hadoop.security.authentication", "Kerberos"); + + Class UserGroupInformationClass = classLoader.loadClass("org.apache.hadoop.security" + + ".UserGroupInformation"); + Method setConfiguration = UserGroupInformationClass.getMethod("setConfiguration", ConfigurationClass); + Method loginUserFromKeytab = UserGroupInformationClass.getMethod("loginUserFromKeytab", String.class, + String.class); + setConfiguration.invoke(null, obj); + loginUserFromKeytab.invoke(null, kingbaseConfig.getUsername(), + "/opt/dataease/conf/" + kingbaseConfig.getPassword()); + } else { + if (StringUtils.isNotBlank(kingbaseConfig.getUsername())) { + props.setProperty("user", kingbaseConfig.getUsername()); + if (StringUtils.isNotBlank(kingbaseConfig.getPassword())) { + props.setProperty("password", kingbaseConfig.getPassword()); + } + } + } + + Connection conn; + String driverClassName; + ExtendedJdbcClassLoader jdbcClassLoader; + if (isDefaultClassLoader(customDriver)) { + driverClassName = defaultDriver; + jdbcClassLoader = extendedJdbcClassLoader; + } else { + if (deDriver == null) { + deDriver = deDriverMapper.selectByPrimaryKey(customDriver); + } + driverClassName = deDriver.getDriverClass(); + jdbcClassLoader = getCustomJdbcClassLoader(deDriver); + } + + Driver driverClass = (Driver) jdbcClassLoader.loadClass(driverClassName).newInstance(); + ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + try { + Thread.currentThread().setContextClassLoader(jdbcClassLoader); + conn = driverClass.connect(url, props); + } catch (Exception e) { + e.printStackTrace(); + throw e; + } finally { + Thread.currentThread().setContextClassLoader(classLoader); + } + return conn; + } + + /** + * 获取表名称 + */ + @Override + public List getTables(DatasourceRequest datasourceRequest) throws Exception { + List tables = new ArrayList<>(); + String queryStr = getTablesSql(datasourceRequest); + JdbcConfiguration jdbcConfiguration = + new Gson().fromJson(datasourceRequest.getDatasource().getConfiguration(), JdbcConfiguration.class); + int queryTimeout = Math.max(jdbcConfiguration.getQueryTimeout(), 0); + try (Connection con = getConnectionFromPool(datasourceRequest); Statement statement = getStatement(con, + queryTimeout); ResultSet resultSet = statement.executeQuery(queryStr)) { + while (resultSet.next()) { + tables.add(getTableDesc(datasourceRequest, resultSet)); + } + } catch (Exception e) { + DataEaseException.throwException(e); + } + + return tables; + } + + /** + * 获取表名称 + */ + private TableDesc getTableDesc(DatasourceRequest datasourceRequest, ResultSet resultSet) throws SQLException { + TableDesc tableDesc = new TableDesc(); + tableDesc.setName(resultSet.getString(1)); + return tableDesc; + } + + /** + * 获取表字段信息 + */ + @Override + public List getTableFields(DatasourceRequest datasourceRequest) throws Exception { + List list = new LinkedList<>(); + try (Connection connection = getConnectionFromPool(datasourceRequest)) { + DatabaseMetaData databaseMetaData = connection.getMetaData(); + ResultSet resultSet = databaseMetaData.getColumns(null, null, datasourceRequest.getTable(), "%"); + while (resultSet.next()) { + String tableName = resultSet.getString("TABLE_NAME").toUpperCase(); + String database; + database = resultSet.getString("TABLE_CAT"); + if (database != null) { + if (tableName.equals(datasourceRequest.getTable()) && database.equalsIgnoreCase(getDatabase(datasourceRequest))) { + TableField tableField = getTableFiled(resultSet, datasourceRequest); + list.add(tableField); + } + } else { + if (tableName.equals(datasourceRequest.getTable())) { + TableField tableField = getTableFiled(resultSet, datasourceRequest); + list.add(tableField); + } + } + } + resultSet.close(); + } catch (SQLException e) { + DataEaseException.throwException(e); + } catch (Exception e) { + DataEaseException.throwException("Data source connection exception: " + e.getMessage()); + } + return list; + } + + /** + * 获取数据源 + */ + private String getDatabase(DatasourceRequest datasourceRequest) { + JdbcConfiguration jdbcConfiguration = + new Gson().fromJson(datasourceRequest.getDatasource().getConfiguration(), JdbcConfiguration.class); + return jdbcConfiguration.getDataBase(); + } + + /** + * 获取表字段 + */ + private TableField getTableFiled(ResultSet resultSet, DatasourceRequest datasourceRequest) throws SQLException { + TableField tableField = new TableField(); + String colName = resultSet.getString("COLUMN_NAME"); + tableField.setFieldName(colName); + String remarks = resultSet.getString("REMARKS"); + if (remarks == null || remarks.equals("")) { + remarks = colName; + } + tableField.setRemarks(remarks); + String dbType = resultSet.getString("TYPE_NAME").toUpperCase(); + tableField.setFieldType(dbType); + if (dbType.equalsIgnoreCase("LONG")) { + tableField.setFieldSize(65533); + } + if (StringUtils.isNotEmpty(dbType) && dbType.toLowerCase().contains("date") && tableField.getFieldSize() < 50) { + tableField.setFieldSize(50); + } + + if (datasourceRequest.getDatasource().getType().equalsIgnoreCase(DatasourceTypes.hive.name()) && tableField.getFieldType().equalsIgnoreCase("BOOLEAN")) { + tableField.setFieldSize(1); + } else { + String size = resultSet.getString("COLUMN_SIZE"); + if (size == null) { + tableField.setFieldSize(1); + } else { + tableField.setFieldSize(Integer.valueOf(size)); + } + } + return tableField; + } + + /** + * 检验数据源状态 + */ + @Override + public String checkStatus(DatasourceRequest datasourceRequest) throws Exception { + String queryStr = getTablesSql(datasourceRequest); + JdbcConfiguration jdbcConfiguration = + new Gson().fromJson(datasourceRequest.getDatasource().getConfiguration(), JdbcConfiguration.class); + int queryTimeout = Math.max(jdbcConfiguration.getQueryTimeout(), 0); + try (Connection con = getConnection(datasourceRequest); Statement statement = getStatement(con, queryTimeout); ResultSet resultSet = statement.executeQuery(queryStr)) { + } catch (Exception e) { + e.printStackTrace(); + DataEaseException.throwException(e.getMessage()); + } + return "Success"; + } + + /** + * 显示对应的表的 SQL 语句 + */ + @Override + public String getTablesSql(DatasourceRequest datasourceRequest) throws Exception { + KingbaseConfig kingbaseConfig = new Gson().fromJson(datasourceRequest.getDatasource().getConfiguration(), + KingbaseConfig.class); + if (StringUtils.isEmpty(kingbaseConfig.getSchema())) { + throw new Exception("Database schema is empty."); + } + /*return "select a.table_name, b.comments from all_tables a, user_tab_comments b where a.table_name = b + .table_name and owner=upper('OWNER') ".replaceAll("OWNER", + kingbaseConfig.getSchema());*/ + return ("select table_name from all_tables where owner=upper('OWNER') ").replaceAll("OWNER", + kingbaseConfig.getSchema()); + } + + /** + * 获取所有的用户 + */ + @Override + public String getSchemaSql(DatasourceRequest datasourceRequest) { + return "select * from all_users"; + } + +} diff --git a/extensions/dataease-extensions-datasource/kingbase/kingbase-backend/src/main/java/io/dataease/plugins/datasource/kingbase/query/KingbaseConstants.java b/extensions/dataease-extensions-datasource/kingbase/kingbase-backend/src/main/java/io/dataease/plugins/datasource/kingbase/query/KingbaseConstants.java new file mode 100644 index 0000000000..911924b8a2 --- /dev/null +++ b/extensions/dataease-extensions-datasource/kingbase/kingbase-backend/src/main/java/io/dataease/plugins/datasource/kingbase/query/KingbaseConstants.java @@ -0,0 +1,60 @@ +package io.dataease.plugins.datasource.kingbase.query; + + +import io.dataease.plugins.common.constants.datasource.SQLConstants; + +import static io.dataease.plugins.common.constants.DatasourceTypes.oracle; + +public class KingbaseConstants extends SQLConstants { + + public static final String KEYWORD_TABLE = oracle.getKeywordPrefix() + "%s" + oracle.getKeywordSuffix(); + + public static final String KEYWORD_FIX = "%s." + oracle.getKeywordPrefix() + "%s" + oracle.getKeywordSuffix(); + + public static final String ALIAS_FIX = oracle.getAliasPrefix() + "%s" + oracle.getAliasSuffix(); + + public static final String UNIX_TIMESTAMP = "UNIX_TIMESTAMP(%s)"; + + public static final String DATE_FORMAT = "to_timestamp(%s,'%s')"; + + public static final String FROM_UNIXTIME = "FROM_UNIXTIME(%s,'%s')"; + + public static final String CAST = "CAST(%s AS %s)"; + + public static final String DEFAULT_DATE_FORMAT = "YYYY-MM-DD HH24:MI:SS"; + + public static final String DEFAULT_INT_FORMAT = "DECIMAL(20,0)"; + + public static final String DEFAULT_FLOAT_FORMAT = "DECIMAL(20,8)"; + + public static final String WHERE_VALUE_NULL = "(NULL,'')"; + + public static final String WHERE_VALUE_VALUE = "'%s'"; + + public static final String AGG_COUNT = "COUNT(*)"; + + public static final String AGG_FIELD = "%s(%s)"; + + public static final String WHERE_BETWEEN = "'%s' AND '%s'"; + + public static final String BRACKETS = "(%s)"; + + public static final String TO_NUMBER = "TO_NUMBER(%s)"; + + public static final String TO_DATE = "TO_DATE(%s,'%s')"; + + public static final String TO_CHAR = "TO_CHAR(%s,'%s')"; + + public static final String DEFAULT_START_DATE = "'1970-01-01 8:0:0'"; + + public static final String TO_MS = " * 24 * 60 * 60 * 100"; + + public static final String CALC_SUB = "%s - %s"; + + // public static final String GROUP_CONCAT = "vm_concat(%s)"; + public static final String GROUP_CONCAT = "to_char(listagg(%s,',' ) within GROUP (order by (%s)))"; + + public static final String NAME = "oracle"; + + +} diff --git a/extensions/dataease-extensions-datasource/kingbase/kingbase-backend/src/main/java/io/dataease/plugins/datasource/kingbase/query/KingbaseQueryProvider.java b/extensions/dataease-extensions-datasource/kingbase/kingbase-backend/src/main/java/io/dataease/plugins/datasource/kingbase/query/KingbaseQueryProvider.java new file mode 100644 index 0000000000..7a35f8895e --- /dev/null +++ b/extensions/dataease-extensions-datasource/kingbase/kingbase-backend/src/main/java/io/dataease/plugins/datasource/kingbase/query/KingbaseQueryProvider.java @@ -0,0 +1,1707 @@ +package io.dataease.plugins.datasource.kingbase.query; + +import cn.hutool.json.JSONArray; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.gson.Gson; +import io.dataease.plugins.common.base.domain.ChartViewWithBLOBs; +import io.dataease.plugins.common.base.domain.DatasetTableField; +import io.dataease.plugins.common.base.domain.DatasetTableFieldExample; +import io.dataease.plugins.common.base.domain.Datasource; +import io.dataease.plugins.common.base.mapper.DatasetTableFieldMapper; +import io.dataease.plugins.common.constants.DeTypeConstants; +import io.dataease.plugins.common.constants.datasource.OracleConstants; +import io.dataease.plugins.common.constants.datasource.SQLConstants; +import io.dataease.plugins.common.dto.chart.ChartCustomFilterItemDTO; +import io.dataease.plugins.common.dto.chart.ChartFieldCustomFilterDTO; +import io.dataease.plugins.common.dto.chart.ChartViewFieldDTO; +import io.dataease.plugins.common.dto.datasource.DeSortField; +import io.dataease.plugins.common.dto.sqlObj.SQLObj; +import io.dataease.plugins.common.request.chart.ChartExtFilterRequest; +import io.dataease.plugins.common.request.permission.DataSetRowPermissionsTreeDTO; +import io.dataease.plugins.common.request.permission.DatasetRowPermissionsTreeItem; +import io.dataease.plugins.datasource.kingbase.provider.KingbaseConfig; +import io.dataease.plugins.datasource.entity.Dateformat; +import io.dataease.plugins.datasource.entity.JdbcConfiguration; +import io.dataease.plugins.datasource.entity.PageInfo; +import io.dataease.plugins.datasource.query.QueryProvider; +import io.dataease.plugins.datasource.query.Utils; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.ObjectUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Component; +import org.stringtemplate.v4.ST; +import org.stringtemplate.v4.STGroup; +import org.stringtemplate.v4.STGroupFile; + +import javax.annotation.Resource; +import java.text.MessageFormat; +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +import static io.dataease.plugins.common.constants.datasource.SQLConstants.TABLE_ALIAS_PREFIX; + +@Component() +public class KingbaseQueryProvider extends QueryProvider { + + @Resource + private DatasetTableFieldMapper datasetTableFieldMapper; + + /** + * 字段类型 + */ + @Override + public Integer transFieldType(String field) { + switch (field) { + case "CHAR": + case "VARCHAR2": + case "VARCHAR": + case "TEXT": + case "TINYTEXT": + case "MEDIUMTEXT": + case "LONGTEXT": + case "ENUM": + case "LONG": + case "NVARCHAR2": + case "NCHAR": + return 0;// 文本 + case "DATE": + case "TIME": + case "YEAR": + case "DATETIME": + case "TIMESTAMP": + return 1;// 时间 + case "INT": + case "INT2": + case "INT4": + case "INT8": + case "SMALLINT": + case "MEDIUMINT": + case "INTEGER": + case "BIGINT": + return 2;// 整型 + case "NUMBER": + case "FLOAT": + case "FLOAT4": + case "FLOAT8": + case "DOUBLE": + case "DECIMAL": + case "DEC": + case "NUMERIC": + return 3;// 浮点 + case "BIT": + case "TINYINT": + return 4;// 布尔 + default: + return 0; + } + } + + /** + * 查询一千行数据 + * + * @param sql + * @param orderBy + * @return + */ + @Override + public String createSQLPreview(String sql, String orderBy) { + return "SELECT * FROM (" + sqlFix(sql) + ") DE_TMP " + " WHERE rownum <= 1000"; + } + + /** + * 创建查询 SQL + * + * @param table + * @param fields + * @param isGroup + * @param ds + * @param fieldCustomFilter + * @param rowPermissionsTree + * @param sortFields + * @return + */ + @Override + public String createQuerySQL(String table, List fields, boolean isGroup, Datasource ds, + List fieldCustomFilter, + List rowPermissionsTree, List sortFields) { + SQLObj tableObj = SQLObj.builder() + .tableName((table.startsWith("(") && table.endsWith(")")) ? table + : String.format(OracleConstants.KEYWORD_TABLE, table)) + .tableAlias(String.format(OracleConstants.ALIAS_FIX, String.format(TABLE_ALIAS_PREFIX, 0))) + .build(); + + //setSchema(tableObj, ds); + List xFields = xFields(table, fields); + + STGroup stg = new STGroupFile(SQLConstants.SQL_TEMPLATE); + ST st_sql = stg.getInstanceOf("previewSql"); + st_sql.add("isGroup", isGroup); + if (CollectionUtils.isNotEmpty(xFields)) + st_sql.add("groups", xFields); + if (ObjectUtils.isNotEmpty(tableObj)) + st_sql.add("table", tableObj); + String customWheres = transCustomFilterList(tableObj, fieldCustomFilter); + // row permissions tree + String whereTrees = transFilterTrees(tableObj, rowPermissionsTree); + List wheres = new ArrayList<>(); + if (customWheres != null) + wheres.add(customWheres); + if (whereTrees != null) + wheres.add(whereTrees); + if (CollectionUtils.isNotEmpty(wheres)) + st_sql.add("filters", wheres); + + List xOrders = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(sortFields)) { + int step = fields.size(); + for (int i = step; i < (step + sortFields.size()); i++) { + DeSortField deSortField = sortFields.get(i - step); + SQLObj order = buildSortField(deSortField, tableObj, i); + xOrders.add(order); + } + } + if (ObjectUtils.isNotEmpty(xOrders)) { + st_sql.add("orders", xOrders); + } + return st_sql.render(); + } + + @Override + public String createQuerySQL(String table, List fields, boolean isGroup, Datasource ds, + List fieldCustomFilter, + List rowPermissionsTree) { + + return createQuerySQL(table, fields, isGroup, ds, fieldCustomFilter, rowPermissionsTree, null); + } + + /** + * 以临时表的方式创建查询 SQL + * + * @param sql + * @param fields + * @param isGroup + * @param fieldCustomFilter + * @param rowPermissionsTree + * @param sortFields + * @return + */ + @Override + public String createQuerySQLAsTmp(String sql, List fields, boolean isGroup, + List fieldCustomFilter, + List rowPermissionsTree, + List sortFields) { + return createQuerySQL("(" + sqlFix(sql) + ")", fields, isGroup, null, fieldCustomFilter, rowPermissionsTree, + sortFields); + } + + /** + * 获取表名 schema + ".表名" + * + * @param tableObj + * @param ds + */ + public void setSchema(SQLObj tableObj, Datasource ds) { + if (ds != null && !tableObj.getTableName().startsWith("(") && !tableObj.getTableName().endsWith(")")) { + String schema = new Gson().fromJson(ds.getConfiguration(), JdbcConfiguration.class).getSchema(); + schema = String.format(OracleConstants.KEYWORD_TABLE, schema); + tableObj.setTableName(schema + "." + tableObj.getTableName()); + } + } + + private SQLObj buildSortField(DeSortField f, SQLObj tableObj, int index) { + String originField; + if (ObjectUtils.isNotEmpty(f.getExtField()) && f.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originField = calcFieldRegex(f.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(f.getExtField()) && f.getExtField() == 1) { + originField = String.format(OracleConstants.KEYWORD_FIX, tableObj.getTableAlias(), f.getOriginName()); + } else { + originField = String.format(OracleConstants.KEYWORD_FIX, tableObj.getTableAlias(), f.getOriginName()); + } + String fieldAlias = String.format(OracleConstants.ALIAS_FIX, + String.format(SQLConstants.FIELD_ALIAS_X_PREFIX, index)); + String fieldName = ""; + // 处理横轴字段 + if (f.getDeExtractType() == 1) { + if (f.getDeType() == 2 || f.getDeType() == 3) { + fieldName = String.format(OracleConstants.UNIX_TIMESTAMP, originField) + "*1000"; + } else { + fieldName = originField; + } + } else if (f.getDeExtractType() == 0) { + if (f.getDeType() == 2) { + fieldName = String.format(OracleConstants.CAST, originField, OracleConstants.DEFAULT_INT_FORMAT); + } else if (f.getDeType() == 3) { + fieldName = String.format(OracleConstants.CAST, originField, OracleConstants.DEFAULT_FLOAT_FORMAT); + } else if (f.getDeType() == 1) { + fieldName = String.format(OracleConstants.DATE_FORMAT, originField, + OracleConstants.DEFAULT_DATE_FORMAT); + } else { + fieldName = originField; + } + } else { + if (f.getDeType() == 1) { + String cast = String.format(OracleConstants.CAST, originField, OracleConstants.DEFAULT_INT_FORMAT) + + "/1000"; + fieldName = String.format(OracleConstants.FROM_UNIXTIME, cast, OracleConstants.DEFAULT_DATE_FORMAT); + } else if (f.getDeType() == 2) { + fieldName = String.format(OracleConstants.CAST, originField, OracleConstants.DEFAULT_INT_FORMAT); + } else { + fieldName = originField; + } + } + SQLObj result = SQLObj.builder().orderField(originField).orderAlias(originField) + .orderDirection(f.getOrderDirection()).build(); + return result; + } + + private List xFields(String table, List fields) { + SQLObj tableObj = SQLObj.builder() + .tableName((table.startsWith("(") && table.endsWith(")")) ? table + : String.format(OracleConstants.KEYWORD_TABLE, table)) + .tableAlias(String.format(OracleConstants.ALIAS_FIX, String.format(TABLE_ALIAS_PREFIX, 0))) + .build(); + List xFields = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(fields)) { + for (int i = 0; i < fields.size(); i++) { + DatasetTableField f = fields.get(i); + String originField; + if (ObjectUtils.isNotEmpty(f.getExtField()) && f.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originField = calcFieldRegex(f.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(f.getExtField()) && f.getExtField() == 1) { + originField = String.format(OracleConstants.KEYWORD_FIX, tableObj.getTableAlias(), + f.getOriginName()); + } else { + originField = String.format(OracleConstants.KEYWORD_FIX, tableObj.getTableAlias(), + f.getOriginName()); + } + String fieldAlias = String.format(OracleConstants.ALIAS_FIX, + String.format(SQLConstants.FIELD_ALIAS_X_PREFIX, i)); + String fieldName = ""; + // 处理横轴字段 + if (f.getDeExtractType() == 1) { + if (f.getDeType() == 2 || f.getDeType() == 3) { + fieldName = String.format(OracleConstants.UNIX_TIMESTAMP, originField) + "*1000"; + } else { + fieldName = originField; + } + } else if (f.getDeExtractType() == 0) { + if (f.getDeType() == 2) { + fieldName = String.format(OracleConstants.CAST, originField, + OracleConstants.DEFAULT_INT_FORMAT); + } else if (f.getDeType() == 3) { + fieldName = String.format(OracleConstants.CAST, originField, + OracleConstants.DEFAULT_FLOAT_FORMAT); + } else if (f.getDeType() == 1) { + fieldName = String.format(OracleConstants.DATE_FORMAT, originField, + OracleConstants.DEFAULT_DATE_FORMAT); + } else { + fieldName = originField; + } + } else { + if (f.getDeType() == 1) { + String cast = String.format(OracleConstants.CAST, originField, + OracleConstants.DEFAULT_INT_FORMAT) + "/1000"; + fieldName = String.format(OracleConstants.FROM_UNIXTIME, cast, + OracleConstants.DEFAULT_DATE_FORMAT); + } else if (f.getDeType() == 2) { + fieldName = String.format(OracleConstants.CAST, originField, + OracleConstants.DEFAULT_INT_FORMAT); + } else { + fieldName = originField; + } + } + xFields.add(SQLObj.builder() + .fieldName(fieldName) + .fieldAlias(fieldAlias) + .build()); + } + } + return xFields; + } + + private String sqlColumn(List xFields) { + String[] array = xFields.stream().map(f -> { + return f.getFieldAlias(); + }).toArray(String[]::new); + return StringUtils.join(array, ","); + } + + @Override + public String createQuerySQLAsTmp(String sql, List fields, boolean isGroup, + List fieldCustomFilter, + List rowPermissionsTree) { + return createQuerySQL("(" + sqlFix(sql) + ")", fields, isGroup, null, fieldCustomFilter, rowPermissionsTree); + } + + @Override + public String createQueryTableWithPage(String table, List fields, Integer page, Integer pageSize, + Integer realSize, boolean isGroup, Datasource ds, + List fieldCustomFilter, + List rowPermissionsTree) { + List xFields = xFields(table, fields); + + return MessageFormat.format( + "SELECT {0} FROM ( SELECT DE_TMP.*, rownum r FROM ( {1} ) DE_TMP WHERE rownum <= {2} ) WHERE r > {3} ", + sqlColumn(xFields), createQuerySQL(table, fields, isGroup, ds, fieldCustomFilter, rowPermissionsTree), + Integer.valueOf(page * realSize).toString(), Integer.valueOf((page - 1) * pageSize).toString()); + } + + @Override + public String createQuerySQLWithPage(String sql, List fields, Integer page, Integer pageSize, + Integer realSize, boolean isGroup, + List fieldCustomFilter, + List rowPermissionsTree) { + List xFields = xFields("(" + sqlFix(sql) + ")", fields); + return MessageFormat.format( + "SELECT {0} FROM ( SELECT DE_TMP.*, rownum r FROM ( {1} ) DE_TMP WHERE rownum <= {2} ) WHERE r > {3} ", + sqlColumn(xFields), createQuerySQLAsTmp(sql, fields, isGroup, fieldCustomFilter, rowPermissionsTree), + Integer.valueOf(page * realSize).toString(), Integer.valueOf((page - 1) * pageSize).toString()); + } + + @Override + public String createQueryTableWithLimit(String table, List fields, Integer limit, + boolean isGroup, Datasource ds, + List fieldCustomFilter, + List rowPermissionsTree) { + /*String schema = new Gson().fromJson(ds.getConfiguration(), JdbcConfiguration.class).getSchema(); + return String.format("SELECT * from %s WHERE rownum <= %s ", + schema + "." + String.format(OracleConstants.KEYWORD_TABLE, table), limit.toString());*/ + return String.format("SELECT * from %s WHERE rownum <= %s ", + String.format(OracleConstants.KEYWORD_TABLE, table), limit.toString()); + } + + @Override + public String createQuerySqlWithLimit(String sql, List fields, Integer limit, boolean isGroup, + List fieldCustomFilter, + List rowPermissionsTree) { + return String.format("SELECT * from %s WHERE rownum <= %s ", "(" + sqlFix(sql) + ")", limit.toString()); + } + + @Override + public String getSQL(String table, List xAxis, List yAxis, + List fieldCustomFilter, + List rowPermissionsTree, + List extFilterRequestList, + Datasource ds, ChartViewWithBLOBs view) { + SQLObj tableObj = SQLObj.builder() + .tableName((table.startsWith("(") && table.endsWith(")")) ? table + : String.format(OracleConstants.KEYWORD_TABLE, table)) + .tableAlias(String.format(OracleConstants.ALIAS_FIX, String.format(TABLE_ALIAS_PREFIX, 0))) + .build(); + //setSchema(tableObj, ds); + List xFields = new ArrayList<>(); + List xOrders = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(xAxis)) { + for (int i = 0; i < xAxis.size(); i++) { + ChartViewFieldDTO x = xAxis.get(i); + String originField; + if (ObjectUtils.isNotEmpty(x.getExtField()) && x.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originField = calcFieldRegex(x.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(x.getExtField()) && x.getExtField() == 1) { + originField = String.format(OracleConstants.KEYWORD_FIX, tableObj.getTableAlias(), + x.getOriginName()); + } else { + originField = String.format(OracleConstants.KEYWORD_FIX, tableObj.getTableAlias(), + x.getOriginName()); + } + String fieldAlias = String.format(OracleConstants.ALIAS_FIX, + String.format(SQLConstants.FIELD_ALIAS_X_PREFIX, i)); + // 处理横轴字段 + xFields.add(getXFields(x, originField, fieldAlias)); + // 处理横轴排序 + if (StringUtils.isNotEmpty(x.getSort()) && Utils.joinSort(x.getSort())) { + xOrders.add(SQLObj.builder() + .orderField(originField) + .orderAlias(fieldAlias) + .orderDirection(x.getSort()) + .build()); + } + } + } + List yFields = new ArrayList<>(); + List yWheres = new ArrayList<>(); + List yOrders = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(yAxis)) { + for (int i = 0; i < yAxis.size(); i++) { + ChartViewFieldDTO y = yAxis.get(i); + String originField; + if (ObjectUtils.isNotEmpty(y.getExtField()) && y.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originField = calcFieldRegex(y.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(y.getExtField()) && y.getExtField() == 1) { + originField = String.format(OracleConstants.KEYWORD_FIX, tableObj.getTableAlias(), + y.getOriginName()); + } else { + originField = String.format(OracleConstants.KEYWORD_FIX, tableObj.getTableAlias(), + y.getOriginName()); + } + String fieldAlias = String.format(OracleConstants.ALIAS_FIX, + String.format(SQLConstants.FIELD_ALIAS_Y_PREFIX, i)); + // 处理纵轴字段 + yFields.add(getYFields(y, originField, fieldAlias)); + // 处理纵轴过滤 + yWheres.add(getYWheres(y, originField, fieldAlias)); + // 处理纵轴排序 + if (StringUtils.isNotEmpty(y.getSort()) && Utils.joinSort(y.getSort())) { + yOrders.add(SQLObj.builder() + .orderField(originField) + .orderAlias(fieldAlias) + .orderDirection(y.getSort()) + .build()); + } + } + } + // 处理视图中字段过滤 + String customWheres = transCustomFilterList(tableObj, fieldCustomFilter); + // 处理仪表板字段过滤 + String extWheres = transExtFilterList(tableObj, extFilterRequestList); + // row permissions tree + String whereTrees = transFilterTrees(tableObj, rowPermissionsTree); + // 构建sql所有参数 + List fields = new ArrayList<>(); + fields.addAll(xFields); + fields.addAll(yFields); + List wheres = new ArrayList<>(); + if (customWheres != null) + wheres.add(customWheres); + if (extWheres != null) + wheres.add(extWheres); + if (whereTrees != null) + wheres.add(whereTrees); + List groups = new ArrayList<>(); + groups.addAll(xFields); + // 外层再次套sql + List orders = new ArrayList<>(); + orders.addAll(xOrders); + orders.addAll(yOrders); + List aggWheres = new ArrayList<>(); + aggWheres.addAll(yWheres.stream().filter(ObjectUtils::isNotEmpty).collect(Collectors.toList())); + + STGroup stg = new STGroupFile(SQLConstants.SQL_TEMPLATE); + ST st_sql = stg.getInstanceOf("querySql"); + if (CollectionUtils.isNotEmpty(xFields)) + st_sql.add("groups", xFields); + if (CollectionUtils.isNotEmpty(yFields)) + st_sql.add("aggregators", yFields); + if (CollectionUtils.isNotEmpty(wheres)) + st_sql.add("filters", wheres); + if (ObjectUtils.isNotEmpty(tableObj)) + st_sql.add("table", tableObj); + String sql = st_sql.render(); + + ST st = stg.getInstanceOf("querySql"); + SQLObj tableSQL = SQLObj.builder() + .tableName(String.format(OracleConstants.BRACKETS, sql)) + .tableAlias(String.format(TABLE_ALIAS_PREFIX, 1)) + .build(); + if (CollectionUtils.isNotEmpty(aggWheres)) + st.add("filters", aggWheres); + if (CollectionUtils.isNotEmpty(orders)) + st.add("orders", orders); + if (ObjectUtils.isNotEmpty(tableSQL)) + st.add("table", tableSQL); + return sqlLimit(st.render(), view); + } + + private String originalTableInfo(String table, List xAxis, + List fieldCustomFilter, + List rowPermissionsTree, + List extFilterRequestList, Datasource ds, + ChartViewWithBLOBs view) { + SQLObj tableObj = SQLObj.builder() + .tableName((table.startsWith("(") && table.endsWith(")")) ? table + : String.format(OracleConstants.KEYWORD_TABLE, table)) + .tableAlias(String.format(OracleConstants.ALIAS_FIX, String.format(TABLE_ALIAS_PREFIX, 0))) + .build(); + //setSchema(tableObj, ds); + List xFields = new ArrayList<>(); + List xOrders = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(xAxis)) { + for (int i = 0; i < xAxis.size(); i++) { + ChartViewFieldDTO x = xAxis.get(i); + String originField; + if (ObjectUtils.isNotEmpty(x.getExtField()) && x.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originField = calcFieldRegex(x.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(x.getExtField()) && x.getExtField() == 1) { + originField = String.format(OracleConstants.KEYWORD_FIX, tableObj.getTableAlias(), + x.getOriginName()); + } else { + if (x.getDeType() == 2 || x.getDeType() == 3) { + originField = String.format(OracleConstants.CAST, + String.format(OracleConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getOriginName()), + OracleConstants.DEFAULT_FLOAT_FORMAT); + } else { + originField = String.format(OracleConstants.KEYWORD_FIX, tableObj.getTableAlias(), + x.getOriginName()); + } + } + String fieldAlias = String.format(OracleConstants.ALIAS_FIX, + String.format(SQLConstants.FIELD_ALIAS_X_PREFIX, i)); + // 处理横轴字段 + xFields.add(getXFields(x, originField, fieldAlias)); + // 处理横轴排序 + if (StringUtils.isNotEmpty(x.getSort()) && Utils.joinSort(x.getSort())) { + xOrders.add(SQLObj.builder() + .orderField(originField) + .orderAlias(fieldAlias) + .orderDirection(x.getSort()) + .build()); + } + } + } + // 处理视图中字段过滤 + String customWheres = transCustomFilterList(tableObj, fieldCustomFilter); + // 处理仪表板字段过滤 + String extWheres = transExtFilterList(tableObj, extFilterRequestList); + // row permissions tree + String whereTrees = transFilterTrees(tableObj, rowPermissionsTree); + // 构建sql所有参数 + List fields = new ArrayList<>(); + fields.addAll(xFields); + List wheres = new ArrayList<>(); + if (customWheres != null) + wheres.add(customWheres); + if (extWheres != null) + wheres.add(extWheres); + if (whereTrees != null) + wheres.add(whereTrees); + List groups = new ArrayList<>(); + groups.addAll(xFields); + // 外层再次套sql + List orders = new ArrayList<>(); + orders.addAll(xOrders); + + STGroup stg = new STGroupFile(SQLConstants.SQL_TEMPLATE); + ST st_sql = stg.getInstanceOf("previewSql"); + st_sql.add("isGroup", false); + if (CollectionUtils.isNotEmpty(xFields)) + st_sql.add("groups", xFields); + if (CollectionUtils.isNotEmpty(wheres)) + st_sql.add("filters", wheres); + if (ObjectUtils.isNotEmpty(tableObj)) + st_sql.add("table", tableObj); + String sql = st_sql.render(); + + ST st = stg.getInstanceOf("previewSql"); + st.add("isGroup", false); + SQLObj tableSQL = SQLObj.builder() + .tableName(String.format(OracleConstants.BRACKETS, sql)) + .tableAlias(String.format(TABLE_ALIAS_PREFIX, 1)) + .build(); + if (CollectionUtils.isNotEmpty(orders)) + st.add("orders", orders); + if (ObjectUtils.isNotEmpty(tableSQL)) + st.add("table", tableSQL); + return st.render(); + } + + @Override + public String getSQLTableInfo(String table, List xAxis, + List fieldCustomFilter, + List rowPermissionsTree, + List extFilterRequestList, Datasource ds, + ChartViewWithBLOBs view) { + return sqlLimit(originalTableInfo(table, xAxis, fieldCustomFilter, rowPermissionsTree, extFilterRequestList, + ds, view), view); + } + + @Override + public String getSQLWithPage(boolean isTable, String table, List xAxis, + List fieldCustomFilter, + List rowPermissionsTree, + List extFilterRequestList, Datasource ds, + ChartViewWithBLOBs view, PageInfo pageInfo) { + String limit = ((pageInfo.getGoPage() != null && pageInfo.getPageSize() != null) ? + " LIMIT " + (pageInfo.getGoPage() - 1) * pageInfo.getPageSize() + "," + pageInfo.getPageSize() : ""); + if (isTable) { + return originalTableInfo(table, xAxis, fieldCustomFilter, rowPermissionsTree, extFilterRequestList, ds, + view) + limit; + } else { + return originalTableInfo("(" + sqlFix(table) + ")", xAxis, fieldCustomFilter, rowPermissionsTree, + extFilterRequestList, ds, view) + limit; + } + } + + @Override + public String getSQLAsTmpTableInfo(String sql, List xAxis, + List fieldCustomFilter, + List rowPermissionsTree, + List extFilterRequestList, Datasource ds, + ChartViewWithBLOBs view) { + return getSQLTableInfo("(" + sqlFix(sql) + ")", xAxis, fieldCustomFilter, rowPermissionsTree, + extFilterRequestList, null, view); + } + + @Override + public String getSQLAsTmp(String sql, List xAxis, List yAxis, + List fieldCustomFilter, + List rowPermissionsTree, + List extFilterRequestList, ChartViewWithBLOBs view) { + return getSQL("(" + sqlFix(sql) + ")", xAxis, yAxis, fieldCustomFilter, rowPermissionsTree, + extFilterRequestList, null, view); + } + + @Override + public String getSQLStack(String table, List xAxis, List yAxis, + List fieldCustomFilter, + List rowPermissionsTree, + List extFilterRequestList, + List extStack, Datasource ds, ChartViewWithBLOBs view) { + SQLObj tableObj = SQLObj.builder() + .tableName((table.startsWith("(") && table.endsWith(")")) ? table + : String.format(OracleConstants.KEYWORD_TABLE, table)) + .tableAlias(String.format(OracleConstants.ALIAS_FIX, String.format(TABLE_ALIAS_PREFIX, 0))) + .build(); + //setSchema(tableObj, ds); + List xFields = new ArrayList<>(); + List xOrders = new ArrayList<>(); + List xList = new ArrayList<>(); + xList.addAll(xAxis); + xList.addAll(extStack); + if (CollectionUtils.isNotEmpty(xList)) { + for (int i = 0; i < xList.size(); i++) { + ChartViewFieldDTO x = xList.get(i); + String originField; + if (ObjectUtils.isNotEmpty(x.getExtField()) && x.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originField = calcFieldRegex(x.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(x.getExtField()) && x.getExtField() == 1) { + originField = String.format(OracleConstants.KEYWORD_FIX, tableObj.getTableAlias(), + x.getOriginName()); + } else { + originField = String.format(OracleConstants.KEYWORD_FIX, tableObj.getTableAlias(), + x.getOriginName()); + } + String fieldAlias = String.format(OracleConstants.ALIAS_FIX, + String.format(SQLConstants.FIELD_ALIAS_X_PREFIX, i)); + // 处理横轴字段 + xFields.add(getXFields(x, originField, fieldAlias)); + // 处理横轴排序 + if (StringUtils.isNotEmpty(x.getSort()) && Utils.joinSort(x.getSort())) { + xOrders.add(SQLObj.builder() + .orderField(originField) + .orderAlias(fieldAlias) + .orderDirection(x.getSort()) + .build()); + } + } + } + List yFields = new ArrayList<>(); + List yWheres = new ArrayList<>(); + List yOrders = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(yAxis)) { + for (int i = 0; i < yAxis.size(); i++) { + ChartViewFieldDTO y = yAxis.get(i); + String originField; + if (ObjectUtils.isNotEmpty(y.getExtField()) && y.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originField = calcFieldRegex(y.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(y.getExtField()) && y.getExtField() == 1) { + originField = String.format(OracleConstants.KEYWORD_FIX, tableObj.getTableAlias(), + y.getOriginName()); + } else { + originField = String.format(OracleConstants.KEYWORD_FIX, tableObj.getTableAlias(), + y.getOriginName()); + } + String fieldAlias = String.format(OracleConstants.ALIAS_FIX, + String.format(SQLConstants.FIELD_ALIAS_Y_PREFIX, i)); + // 处理纵轴字段 + yFields.add(getYFields(y, originField, fieldAlias)); + // 处理纵轴过滤 + yWheres.add(getYWheres(y, originField, fieldAlias)); + // 处理纵轴排序 + if (StringUtils.isNotEmpty(y.getSort()) && Utils.joinSort(y.getSort())) { + yOrders.add(SQLObj.builder() + .orderField(originField) + .orderAlias(fieldAlias) + .orderDirection(y.getSort()) + .build()); + } + } + } + // 处理视图中字段过滤 + String customWheres = transCustomFilterList(tableObj, fieldCustomFilter); + // 处理仪表板字段过滤 + String extWheres = transExtFilterList(tableObj, extFilterRequestList); + // row permissions tree + String whereTrees = transFilterTrees(tableObj, rowPermissionsTree); + // 构建sql所有参数 + List fields = new ArrayList<>(); + fields.addAll(xFields); + fields.addAll(yFields); + List wheres = new ArrayList<>(); + if (customWheres != null) + wheres.add(customWheres); + if (extWheres != null) + wheres.add(extWheres); + if (whereTrees != null) + wheres.add(whereTrees); + List groups = new ArrayList<>(); + groups.addAll(xFields); + // 外层再次套sql + List orders = new ArrayList<>(); + orders.addAll(xOrders); + orders.addAll(yOrders); + List aggWheres = new ArrayList<>(); + aggWheres.addAll(yWheres.stream().filter(ObjectUtils::isNotEmpty).collect(Collectors.toList())); + + STGroup stg = new STGroupFile(SQLConstants.SQL_TEMPLATE); + ST st_sql = stg.getInstanceOf("querySql"); + if (CollectionUtils.isNotEmpty(xFields)) + st_sql.add("groups", xFields); + if (CollectionUtils.isNotEmpty(yFields)) + st_sql.add("aggregators", yFields); + if (CollectionUtils.isNotEmpty(wheres)) + st_sql.add("filters", wheres); + if (ObjectUtils.isNotEmpty(tableObj)) + st_sql.add("table", tableObj); + String sql = st_sql.render(); + + ST st = stg.getInstanceOf("querySql"); + SQLObj tableSQL = SQLObj.builder() + .tableName(String.format(OracleConstants.BRACKETS, sql)) + .tableAlias(String.format(TABLE_ALIAS_PREFIX, 1)) + .build(); + if (CollectionUtils.isNotEmpty(aggWheres)) + st.add("filters", aggWheres); + if (CollectionUtils.isNotEmpty(orders)) + st.add("orders", orders); + if (ObjectUtils.isNotEmpty(tableSQL)) + st.add("table", tableSQL); + return sqlLimit(st.render(), view); + } + + @Override + public String getSQLAsTmpStack(String table, List xAxis, List yAxis, + List fieldCustomFilter, + List rowPermissionsTree, + List extFilterRequestList, + List extStack, ChartViewWithBLOBs view) { + return getSQLStack("(" + sqlFix(table) + ")", xAxis, yAxis, fieldCustomFilter, rowPermissionsTree, + extFilterRequestList, extStack, + null, view); + } + + /** + * 获取 SQL 函数 + * + * @param table + * @param xAxis + * @param yAxis + * @param fieldCustomFilter + * @param rowPermissionsTree + * @param extFilterRequestList + * @param extBubble + * @param ds + * @param view + * @return + */ + @Override + public String getSQLScatter(String table, List xAxis, List yAxis, + List fieldCustomFilter, + List rowPermissionsTree, + List extFilterRequestList, + List extBubble, Datasource ds, ChartViewWithBLOBs view) { + SQLObj tableObj = SQLObj.builder() + .tableName((table.startsWith("(") && table.endsWith(")")) ? table + : String.format(OracleConstants.KEYWORD_TABLE, table)) + .tableAlias(String.format(OracleConstants.ALIAS_FIX, String.format(TABLE_ALIAS_PREFIX, 0))) + .build(); + //setSchema(tableObj, ds); + List xFields = new ArrayList<>(); + List xOrders = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(xAxis)) { + for (int i = 0; i < xAxis.size(); i++) { + ChartViewFieldDTO x = xAxis.get(i); + String originField; + if (ObjectUtils.isNotEmpty(x.getExtField()) && x.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originField = calcFieldRegex(x.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(x.getExtField()) && x.getExtField() == 1) { + originField = String.format(OracleConstants.KEYWORD_FIX, tableObj.getTableAlias(), + x.getOriginName()); + } else { + originField = String.format(OracleConstants.KEYWORD_FIX, tableObj.getTableAlias(), + x.getOriginName()); + } + String fieldAlias = String.format(OracleConstants.ALIAS_FIX, + String.format(SQLConstants.FIELD_ALIAS_X_PREFIX, i)); + // 处理横轴字段 + xFields.add(getXFields(x, originField, fieldAlias)); + // 处理横轴排序 + if (StringUtils.isNotEmpty(x.getSort()) && Utils.joinSort(x.getSort())) { + xOrders.add(SQLObj.builder() + .orderField(originField) + .orderAlias(fieldAlias) + .orderDirection(x.getSort()) + .build()); + } + } + } + List yFields = new ArrayList<>(); + List yWheres = new ArrayList<>(); + List yOrders = new ArrayList<>(); + List yList = new ArrayList<>(); + yList.addAll(yAxis); + yList.addAll(extBubble); + if (CollectionUtils.isNotEmpty(yList)) { + for (int i = 0; i < yList.size(); i++) { + ChartViewFieldDTO y = yList.get(i); + String originField; + if (ObjectUtils.isNotEmpty(y.getExtField()) && y.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originField = calcFieldRegex(y.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(y.getExtField()) && y.getExtField() == 1) { + originField = String.format(OracleConstants.KEYWORD_FIX, tableObj.getTableAlias(), + y.getOriginName()); + } else { + originField = String.format(OracleConstants.KEYWORD_FIX, tableObj.getTableAlias(), + y.getOriginName()); + } + String fieldAlias = String.format(OracleConstants.ALIAS_FIX, + String.format(SQLConstants.FIELD_ALIAS_Y_PREFIX, i)); + // 处理纵轴字段 + yFields.add(getYFields(y, originField, fieldAlias)); + // 处理纵轴过滤 + yWheres.add(getYWheres(y, originField, fieldAlias)); + // 处理纵轴排序 + if (StringUtils.isNotEmpty(y.getSort()) && Utils.joinSort(y.getSort())) { + yOrders.add(SQLObj.builder() + .orderField(originField) + .orderAlias(fieldAlias) + .orderDirection(y.getSort()) + .build()); + } + } + } + // 处理视图中字段过滤 + String customWheres = transCustomFilterList(tableObj, fieldCustomFilter); + // 处理仪表板字段过滤 + String extWheres = transExtFilterList(tableObj, extFilterRequestList); + // row permissions tree + String whereTrees = transFilterTrees(tableObj, rowPermissionsTree); + // 构建sql所有参数 + List fields = new ArrayList<>(); + fields.addAll(xFields); + fields.addAll(yFields); + List wheres = new ArrayList<>(); + if (customWheres != null) + wheres.add(customWheres); + if (extWheres != null) + wheres.add(extWheres); + if (whereTrees != null) + wheres.add(whereTrees); + List groups = new ArrayList<>(); + groups.addAll(xFields); + // 外层再次套sql + List orders = new ArrayList<>(); + orders.addAll(xOrders); + orders.addAll(yOrders); + List aggWheres = new ArrayList<>(); + aggWheres.addAll(yWheres.stream().filter(ObjectUtils::isNotEmpty).collect(Collectors.toList())); + + STGroup stg = new STGroupFile(SQLConstants.SQL_TEMPLATE); + ST st_sql = stg.getInstanceOf("querySql"); + if (CollectionUtils.isNotEmpty(xFields)) + st_sql.add("groups", xFields); + if (CollectionUtils.isNotEmpty(yFields)) + st_sql.add("aggregators", yFields); + if (CollectionUtils.isNotEmpty(wheres)) + st_sql.add("filters", wheres); + if (ObjectUtils.isNotEmpty(tableObj)) + st_sql.add("table", tableObj); + String sql = st_sql.render(); + + ST st = stg.getInstanceOf("querySql"); + SQLObj tableSQL = SQLObj.builder() + .tableName(String.format(OracleConstants.BRACKETS, sql)) + .tableAlias(String.format(TABLE_ALIAS_PREFIX, 1)) + .build(); + if (CollectionUtils.isNotEmpty(aggWheres)) + st.add("filters", aggWheres); + if (CollectionUtils.isNotEmpty(orders)) + st.add("orders", orders); + if (ObjectUtils.isNotEmpty(tableSQL)) + st.add("table", tableSQL); + return sqlLimit(st.render(), view); + } + + @Override + public String getSQLAsTmpScatter(String table, List xAxis, List yAxis, + List fieldCustomFilter, + List rowPermissionsTree, + List extFilterRequestList, + List extBubble, ChartViewWithBLOBs view) { + return getSQLScatter("(" + sqlFix(table) + ")", xAxis, yAxis, fieldCustomFilter, rowPermissionsTree, + extFilterRequestList, + extBubble, null, view); + } + + /** + * 查询表 + * + * @param table + * @return + */ + @Override + public String searchTable(String table) { + return "SELECT table_name FROM information_schema.TABLES WHERE table_name ='" + table + "'"; + } + + @Override + public String getSQLSummary(String table, List yAxis, + List fieldCustomFilter, + List rowPermissionsTree, + List extFilterRequestList, + ChartViewWithBLOBs view, Datasource ds) { + // 字段汇总 排序等 + SQLObj tableObj = SQLObj.builder() + .tableName((table.startsWith("(") && table.endsWith(")")) ? table + : String.format(OracleConstants.KEYWORD_TABLE, table)) + .tableAlias(String.format(OracleConstants.ALIAS_FIX, String.format(TABLE_ALIAS_PREFIX, 0))) + .build(); + //setSchema(tableObj, ds); + List yFields = new ArrayList<>(); + List yWheres = new ArrayList<>(); + List yOrders = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(yAxis)) { + for (int i = 0; i < yAxis.size(); i++) { + ChartViewFieldDTO y = yAxis.get(i); + String originField; + if (ObjectUtils.isNotEmpty(y.getExtField()) && y.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originField = calcFieldRegex(y.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(y.getExtField()) && y.getExtField() == 1) { + originField = String.format(OracleConstants.KEYWORD_FIX, tableObj.getTableAlias(), + y.getOriginName()); + } else { + originField = String.format(OracleConstants.KEYWORD_FIX, tableObj.getTableAlias(), + y.getOriginName()); + } + String fieldAlias = String.format(SQLConstants.FIELD_ALIAS_Y_PREFIX, i); + // 处理纵轴字段 + yFields.add(getYFields(y, originField, fieldAlias)); + // 处理纵轴过滤 + yWheres.add(getYWheres(y, originField, fieldAlias)); + // 处理纵轴排序 + if (StringUtils.isNotEmpty(y.getSort()) && Utils.joinSort(y.getSort())) { + yOrders.add(SQLObj.builder() + .orderField(originField) + .orderAlias(fieldAlias) + .orderDirection(y.getSort()) + .build()); + } + } + } + // 处理视图中字段过滤 + String customWheres = transCustomFilterList(tableObj, fieldCustomFilter); + // 处理仪表板字段过滤 + String extWheres = transExtFilterList(tableObj, extFilterRequestList); + // row permissions tree + String whereTrees = transFilterTrees(tableObj, rowPermissionsTree); + // 构建sql所有参数 + List fields = new ArrayList<>(); + fields.addAll(yFields); + List wheres = new ArrayList<>(); + if (customWheres != null) + wheres.add(customWheres); + if (extWheres != null) + wheres.add(extWheres); + if (whereTrees != null) + wheres.add(whereTrees); + // 外层再次套sql + List orders = new ArrayList<>(); + orders.addAll(yOrders); + List aggWheres = new ArrayList<>(); + aggWheres.addAll(yWheres.stream().filter(ObjectUtils::isNotEmpty).collect(Collectors.toList())); + + STGroup stg = new STGroupFile(SQLConstants.SQL_TEMPLATE); + ST st_sql = stg.getInstanceOf("querySql"); + if (CollectionUtils.isNotEmpty(yFields)) + st_sql.add("aggregators", yFields); + if (CollectionUtils.isNotEmpty(wheres)) + st_sql.add("filters", wheres); + if (ObjectUtils.isNotEmpty(tableObj)) + st_sql.add("table", tableObj); + String sql = st_sql.render(); + + ST st = stg.getInstanceOf("querySql"); + SQLObj tableSQL = SQLObj.builder() + .tableName(String.format(OracleConstants.BRACKETS, sql)) + .tableAlias(String.format(TABLE_ALIAS_PREFIX, 1)) + .build(); + if (CollectionUtils.isNotEmpty(aggWheres)) + st.add("filters", aggWheres); + if (CollectionUtils.isNotEmpty(orders)) + st.add("orders", orders); + if (ObjectUtils.isNotEmpty(tableSQL)) + st.add("table", tableSQL); + return sqlLimit(st.render(), view); + } + + @Override + public String getSQLSummaryAsTmp(String sql, List yAxis, + List fieldCustomFilter, + List rowPermissionsTree, + List extFilterRequestList, + ChartViewWithBLOBs view) { + return getSQLSummary("(" + sqlFix(sql) + ")", yAxis, fieldCustomFilter, rowPermissionsTree, + extFilterRequestList, view, null); + } + + @Override + public String wrapSql(String sql) { + sql = sql.trim(); + if (sql.lastIndexOf(";") == (sql.length() - 1)) { + sql = sql.substring(0, sql.length() - 1); + } + String tmpSql = "SELECT * FROM (" + sql + ") DE_TMP " + " where rownum <= 0"; + return tmpSql; + } + + @Override + public String createRawQuerySQL(String table, List fields, Datasource ds) { + String[] array = fields.stream().map(f -> { + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.append("\"").append(f.getOriginName()).append("\""); + return stringBuilder.toString(); + }).toArray(String[]::new); + KingbaseConfig kingbaseConfig = new Gson().fromJson(ds.getConfiguration(), KingbaseConfig.class); + /*return MessageFormat.format("SELECT {0} FROM {1}", StringUtils.join(array, ","), + kingbaseConfig.getSchema() + ".\"" + table + "\"");*/ + return MessageFormat.format("SELECT {0} FROM {1}", StringUtils.join(array, ","), + table + "\""); + } + + @Override + public String createRawQuerySQLAsTmp(String sql, List fields) { + String[] array = fields.stream().map(f -> { + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.append(" \"").append(f.getOriginName()).append("\""); + return stringBuilder.toString(); + }).toArray(String[]::new); + return MessageFormat.format("SELECT {0} FROM {1}", StringUtils.join(array, ","), + " (" + sqlFix(sql) + ") DE_TMP "); + } + + @Override + public String transTreeItem(SQLObj tableObj, DatasetRowPermissionsTreeItem item) { + String res = null; + DatasetTableField field = item.getField(); + if (ObjectUtils.isEmpty(field)) { + return null; + } + String whereName = ""; + String originName; + if (ObjectUtils.isNotEmpty(field.getExtField()) && field.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originName = calcFieldRegex(field.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(field.getExtField()) && field.getExtField() == 1) { + originName = String.format(OracleConstants.KEYWORD_FIX, tableObj.getTableAlias(), + field.getOriginName()); + } else { + originName = String.format(OracleConstants.KEYWORD_FIX, tableObj.getTableAlias(), + field.getOriginName()); + } + + if (field.getDeType() == 1) { + if (field.getDeExtractType() == 0 || field.getDeExtractType() == 5) { + whereName = String.format(OracleConstants.TO_DATE, originName, + StringUtils.isNotEmpty(field.getDateFormat()) ? field.getDateFormat() : + OracleConstants.DEFAULT_DATE_FORMAT); + } + if (field.getDeExtractType() == 2 || field.getDeExtractType() == 3 || field.getDeExtractType() == 4) { + String cast = String.format(OracleConstants.CAST, originName, OracleConstants.DEFAULT_INT_FORMAT) + + "/1000"; + whereName = String.format(OracleConstants.FROM_UNIXTIME, cast, OracleConstants.DEFAULT_DATE_FORMAT); + } + if (field.getDeExtractType() == 1) { + whereName = originName; + } + } else if (field.getDeType() == 2 || field.getDeType() == 3) { + if (field.getDeExtractType() == 0 || field.getDeExtractType() == 5) { + whereName = String.format(OracleConstants.CAST, originName, OracleConstants.DEFAULT_FLOAT_FORMAT); + } + if (field.getDeExtractType() == 1) { + whereName = String.format(OracleConstants.UNIX_TIMESTAMP, originName) + "*1000"; + } + if (field.getDeExtractType() == 2 || field.getDeExtractType() == 3 || field.getDeExtractType() == 4) { + whereName = originName; + } + } else { + whereName = originName; + } + + if (StringUtils.equalsIgnoreCase(item.getFilterType(), "enum")) { + if (CollectionUtils.isNotEmpty(item.getEnumValue())) { + res = "(" + whereName + " IN ('" + String.join("','", item.getEnumValue()) + "'))"; + } + } else { + String value = item.getValue(); + String whereTerm = transMysqlFilterTerm(item.getTerm()); + String whereValue = ""; + + if (StringUtils.equalsIgnoreCase(item.getTerm(), "null")) { + whereValue = ""; + } else if (StringUtils.equalsIgnoreCase(item.getTerm(), "not_null")) { + whereValue = ""; + } else if (StringUtils.equalsIgnoreCase(item.getTerm(), "empty")) { + whereValue = "''"; + } else if (StringUtils.equalsIgnoreCase(item.getTerm(), "not_empty")) { + whereValue = "''"; + } else if (StringUtils.containsIgnoreCase(item.getTerm(), "in") + || StringUtils.containsIgnoreCase(item.getTerm(), "not in")) { + whereValue = "('" + String.join("','", value.split(",")) + "')"; + } else if (StringUtils.containsIgnoreCase(item.getTerm(), "like")) { + whereValue = "'%" + value + "%'"; + } else { + if (field.getDeType() == 1) { + whereValue = String.format(OracleConstants.TO_DATE, "'" + value + "'", + OracleConstants.DEFAULT_DATE_FORMAT); + } else { + whereValue = String.format(OracleConstants.WHERE_VALUE_VALUE, value); + } + } + SQLObj build = SQLObj.builder() + .whereField(whereName) + .whereTermAndValue(whereTerm + whereValue) + .build(); + res = build.getWhereField() + " " + build.getWhereTermAndValue(); + } + return res; + } + + @Override + public String convertTableToSql(String tableName, Datasource ds) { + /*String schema = new Gson().fromJson(ds.getConfiguration(), JdbcConfiguration.class).getSchema(); + schema = String.format(OracleConstants.KEYWORD_TABLE, schema); + return createSQLPreview( + "SELECT * FROM " + schema + "." + String.format(OracleConstants.KEYWORD_TABLE, tableName), null);*/ + return createSQLPreview( + "SELECT * FROM " + String.format(OracleConstants.KEYWORD_TABLE, tableName), null); + } + + public String transMysqlFilterTerm(String term) { + switch (term) { + case "eq": + return " = "; + case "not_eq": + return " <> "; + case "lt": + return " < "; + case "le": + return " <= "; + case "gt": + return " > "; + case "ge": + return " >= "; + case "in": + return " IN "; + case "not in": + return " NOT IN "; + case "like": + return " LIKE "; + case "not like": + return " NOT LIKE "; + case "null": + return " IS NULL "; + case "not_null": + return " IS NOT NULL "; + case "empty": + return " = "; + case "not_empty": + return " <> "; + case "between": + return " BETWEEN "; + default: + return ""; + } + } + + public String transCustomFilterList(SQLObj tableObj, List requestList) { + if (CollectionUtils.isEmpty(requestList)) { + return null; + } + List res = new ArrayList<>(); + for (ChartFieldCustomFilterDTO request : requestList) { + List list = new ArrayList<>(); + DatasetTableField field = request.getField(); + + if (ObjectUtils.isEmpty(field)) { + continue; + } + String whereName = ""; + String originName; + if (ObjectUtils.isNotEmpty(field.getExtField()) && field.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originName = calcFieldRegex(field.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(field.getExtField()) && field.getExtField() == 1) { + originName = String.format(OracleConstants.KEYWORD_FIX, tableObj.getTableAlias(), + field.getOriginName()); + } else { + originName = String.format(OracleConstants.KEYWORD_FIX, tableObj.getTableAlias(), + field.getOriginName()); + } + + if (field.getDeType() == 1) { + if (field.getDeExtractType() == 0 || field.getDeExtractType() == 5) { + whereName = String.format(OracleConstants.TO_DATE, originName, + StringUtils.isNotEmpty(field.getDateFormat()) ? field.getDateFormat() : + OracleConstants.DEFAULT_DATE_FORMAT); + } + if (field.getDeExtractType() == 2 || field.getDeExtractType() == 3 || field.getDeExtractType() == 4) { + String cast = String.format(OracleConstants.CAST, originName, OracleConstants.DEFAULT_INT_FORMAT) + + "/1000"; + whereName = String.format(OracleConstants.FROM_UNIXTIME, cast, OracleConstants.DEFAULT_DATE_FORMAT); + } + if (field.getDeExtractType() == 1) { + whereName = originName; + } + } else if (field.getDeType() == 2 || field.getDeType() == 3) { + if (field.getDeExtractType() == 0 || field.getDeExtractType() == 5) { + whereName = String.format(OracleConstants.CAST, originName, OracleConstants.DEFAULT_FLOAT_FORMAT); + } + if (field.getDeExtractType() == 1) { + whereName = String.format(OracleConstants.UNIX_TIMESTAMP, originName) + "*1000"; + } + if (field.getDeExtractType() == 2 || field.getDeExtractType() == 3 || field.getDeExtractType() == 4) { + whereName = originName; + } + } else { + whereName = originName; + } + + if (StringUtils.equalsIgnoreCase(request.getFilterType(), "enum")) { + if (CollectionUtils.isNotEmpty(request.getEnumCheckField())) { + res.add("(" + whereName + " IN ('" + String.join("','", request.getEnumCheckField()) + "'))"); + } + } else { + List filter = request.getFilter(); + for (ChartCustomFilterItemDTO filterItemDTO : filter) { + String value = filterItemDTO.getValue(); + String whereTerm = transMysqlFilterTerm(filterItemDTO.getTerm()); + String whereValue = ""; + + if (StringUtils.equalsIgnoreCase(filterItemDTO.getTerm(), "null")) { + whereValue = ""; + } else if (StringUtils.equalsIgnoreCase(filterItemDTO.getTerm(), "not_null")) { + whereValue = ""; + } else if (StringUtils.equalsIgnoreCase(filterItemDTO.getTerm(), "empty")) { + whereValue = "''"; + } else if (StringUtils.equalsIgnoreCase(filterItemDTO.getTerm(), "not_empty")) { + whereValue = "''"; + } else if (StringUtils.containsIgnoreCase(filterItemDTO.getTerm(), "in") + || StringUtils.containsIgnoreCase(filterItemDTO.getTerm(), "not in")) { + whereValue = "('" + String.join("','", value.split(",")) + "')"; + } else if (StringUtils.containsIgnoreCase(filterItemDTO.getTerm(), "like")) { + whereValue = "'%" + value + "%'"; + } else { + if (field.getDeType() == 1) { + whereValue = String.format(OracleConstants.TO_DATE, "'" + value + "'", + OracleConstants.DEFAULT_DATE_FORMAT); + } else { + whereValue = String.format(OracleConstants.WHERE_VALUE_VALUE, value); + } + } + list.add(SQLObj.builder() + .whereField(whereName) + .whereTermAndValue(whereTerm + whereValue) + .build()); + } + + List strList = new ArrayList<>(); + list.forEach(ele -> strList.add(ele.getWhereField() + " " + ele.getWhereTermAndValue())); + if (CollectionUtils.isNotEmpty(list)) { + res.add("(" + String.join(" " + getLogic(request.getLogic()) + " ", strList) + ")"); + } + } + } + return CollectionUtils.isNotEmpty(res) ? "(" + String.join(" AND ", res) + ")" : null; + } + + public String transExtFilterList(SQLObj tableObj, List requestList) { + if (CollectionUtils.isEmpty(requestList)) { + return null; + } + List list = new ArrayList<>(); + for (ChartExtFilterRequest request : requestList) { + List value = request.getValue(); + + List whereNameList = new ArrayList<>(); + List fieldList = new ArrayList<>(); + if (request.getIsTree()) { + fieldList.addAll(request.getDatasetTableFieldList()); + } else { + fieldList.add(request.getDatasetTableField()); + } + + for (DatasetTableField field : fieldList) { + if (CollectionUtils.isEmpty(value) || ObjectUtils.isEmpty(field)) { + continue; + } + String whereName = ""; + + String originName; + if (ObjectUtils.isNotEmpty(field.getExtField()) && field.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originName = calcFieldRegex(field.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(field.getExtField()) && field.getExtField() == 1) { + originName = String.format(OracleConstants.KEYWORD_FIX, tableObj.getTableAlias(), + field.getOriginName()); + } else { + originName = String.format(OracleConstants.KEYWORD_FIX, tableObj.getTableAlias(), + field.getOriginName()); + } + + if (field.getDeType() == 1) { + if (field.getDeExtractType() == 0 || field.getDeExtractType() == 5) { + whereName = String.format(OracleConstants.TO_DATE, originName, + OracleConstants.DEFAULT_DATE_FORMAT); + } + if (field.getDeExtractType() == 2 || field.getDeExtractType() == 3 + || field.getDeExtractType() == 4) { + String cast = String.format(OracleConstants.CAST, originName, + OracleConstants.DEFAULT_INT_FORMAT) + "/1000"; + whereName = String.format(OracleConstants.FROM_UNIXTIME, cast, + OracleConstants.DEFAULT_DATE_FORMAT); + } + if (field.getDeExtractType() == 1) { + whereName = originName; + } + } else if (field.getDeType() == 2 || field.getDeType() == 3) { + if (field.getDeExtractType() == 0 || field.getDeExtractType() == 5) { + whereName = String.format(OracleConstants.CAST, originName, + OracleConstants.DEFAULT_FLOAT_FORMAT); + } + if (field.getDeExtractType() == 1) { + whereName = String.format(OracleConstants.UNIX_TIMESTAMP, originName) + "*1000"; + } + if (field.getDeExtractType() == 2 || field.getDeExtractType() == 3 + || field.getDeExtractType() == 4) { + whereName = originName; + } + } else { + whereName = originName; + } + whereNameList.add(whereName); + } + + String whereName = ""; + if (request.getIsTree()) { + whereName = StringUtils.join(whereNameList, "||','||"); + } else { + whereName = whereNameList.get(0); + } + String whereTerm = transMysqlFilterTerm(request.getOperator()); + String whereValue = ""; + + if (StringUtils.containsIgnoreCase(request.getOperator(), "in")) { + whereValue = "('" + StringUtils.join(value, "','") + "')"; + } else if (StringUtils.containsIgnoreCase(request.getOperator(), "like")) { + String keyword = value.get(0).toUpperCase(); + whereValue = "'%" + keyword + "%'"; + whereName = "upper(" + whereName + ")"; + } else if (StringUtils.containsIgnoreCase(request.getOperator(), "between")) { + if (request.getDatasetTableField().getDeType() == 1) { + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + String startTime = simpleDateFormat.format(new Date(Long.parseLong(value.get(0)))); + String endTime = simpleDateFormat.format(new Date(Long.parseLong(value.get(1)))); + String st = String.format(OracleConstants.TO_DATE, "'" + startTime + "'", + OracleConstants.DEFAULT_DATE_FORMAT); + String et = String.format(OracleConstants.TO_DATE, "'" + endTime + "'", + OracleConstants.DEFAULT_DATE_FORMAT); + whereValue = st + " AND " + et; + } else { + whereValue = String.format(OracleConstants.WHERE_BETWEEN, value.get(0), value.get(1)); + } + } else { + whereValue = String.format(OracleConstants.WHERE_VALUE_VALUE, value.get(0)); + } + list.add(SQLObj.builder() + .whereField(whereName) + .whereTermAndValue(whereTerm + whereValue) + .build()); + } + List strList = new ArrayList<>(); + list.forEach(ele -> strList.add(ele.getWhereField() + " " + ele.getWhereTermAndValue())); + return CollectionUtils.isNotEmpty(list) ? "(" + String.join(" AND ", strList) + ")" : null; + } + + /** + * 去除 SQL 语句的 ";" + * + * @param sql + * @return + */ + private String sqlFix(String sql) { + if (sql.lastIndexOf(";") == (sql.length() - 1)) { + sql = sql.substring(0, sql.length() - 1); + } + return sql; + } + + private String transDateFormat(String dateStyle, String datePattern) { + String split = "-"; + if (StringUtils.equalsIgnoreCase(datePattern, "date_sub")) { + split = "-"; + } else if (StringUtils.equalsIgnoreCase(datePattern, "date_split")) { + split = "/"; + } else { + split = "-"; + } + + if (StringUtils.isEmpty(dateStyle)) { + return OracleConstants.DEFAULT_DATE_FORMAT; + } + + switch (dateStyle) { + case "y": + return "YYYY"; + case "y_M": + return "YYYY" + split + "MM"; + case "y_M_d": + return "YYYY" + split + "MM" + split + "DD"; + case "H_m_s": + return "HH24:MI:SS"; + case "y_M_d_H_m": + return "YYYY" + split + "MM" + split + "DD" + " HH24:MI"; + case "y_M_d_H_m_s": + return "YYYY" + split + "MM" + split + "DD" + " HH24:MI:SS"; + default: + return OracleConstants.DEFAULT_DATE_FORMAT; + } + } + + private SQLObj getXFields(ChartViewFieldDTO x, String originField, String fieldAlias) { + String fieldName = ""; + if (x.getDeExtractType() == DeTypeConstants.DE_TIME) { + if (x.getDeType() == DeTypeConstants.DE_INT || x.getDeType() == DeTypeConstants.DE_FLOAT) { // 时间转数值 + if (x.getType().equalsIgnoreCase("DATE")) { + String date = String.format(OracleConstants.CALC_SUB, originField, + String.format(OracleConstants.TO_DATE, OracleConstants.DEFAULT_START_DATE, + OracleConstants.DEFAULT_DATE_FORMAT)); + fieldName = String.format(OracleConstants.TO_NUMBER, date) + OracleConstants.TO_MS; + } else { + String toChar = String.format(OracleConstants.TO_CHAR, originField, + OracleConstants.DEFAULT_DATE_FORMAT); + String toDate = String.format(OracleConstants.TO_DATE, toChar, OracleConstants.DEFAULT_DATE_FORMAT); + String toDate1 = String.format(OracleConstants.TO_DATE, OracleConstants.DEFAULT_START_DATE, + OracleConstants.DEFAULT_DATE_FORMAT); + fieldName = String.format(OracleConstants.TO_NUMBER, + String.format(OracleConstants.CALC_SUB, toDate, toDate1)) + OracleConstants.TO_MS; + } + } else if (x.getDeType() == DeTypeConstants.DE_TIME) { // 格式化显示时间 + String format = transDateFormat(x.getDateStyle(), x.getDatePattern()); + if (x.getType().equalsIgnoreCase("DATE")) { + fieldName = String.format(OracleConstants.TO_CHAR, originField, format); + } else { + String toChar = String.format(OracleConstants.TO_CHAR, originField, + OracleConstants.DEFAULT_DATE_FORMAT); + String toDate = String.format(OracleConstants.TO_DATE, toChar, OracleConstants.DEFAULT_DATE_FORMAT); + fieldName = String.format(OracleConstants.TO_CHAR, toDate, format); + } + } else { + fieldName = originField; + } + } else { + if (x.getDeType() == DeTypeConstants.DE_TIME) { + String format = transDateFormat(x.getDateStyle(), x.getDatePattern()); + if (x.getDeExtractType() == DeTypeConstants.DE_STRING) { // 字符串转时间 + String toDate = String.format(OracleConstants.TO_DATE, originField, + OracleConstants.DEFAULT_DATE_FORMAT); + fieldName = String.format(OracleConstants.TO_CHAR, toDate, format); + } else { // 数值转时间 + String date = originField + "/(1000 * 60 * 60 * 24)+" + String.format(OracleConstants.TO_DATE, + OracleConstants.DEFAULT_START_DATE, OracleConstants.DEFAULT_DATE_FORMAT); + fieldName = String.format(OracleConstants.TO_CHAR, date, format); + } + } else { + if (x.getDeType() == DeTypeConstants.DE_INT) { + fieldName = String.format(OracleConstants.CAST, originField, OracleConstants.DEFAULT_INT_FORMAT); + } else if (x.getDeType() == DeTypeConstants.DE_FLOAT) { + fieldName = String.format(OracleConstants.CAST, originField, OracleConstants.DEFAULT_FLOAT_FORMAT); + } else { + fieldName = originField; + } + } + } + return SQLObj.builder() + .fieldName(fieldName) + .fieldAlias(fieldAlias) + .build(); + } + + private List getXWheres(ChartViewFieldDTO x, String originField, String fieldAlias) { + List list = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(x.getFilter()) && x.getFilter().size() > 0) { + x.getFilter().forEach(f -> { + String whereName = ""; + String whereTerm = transMysqlFilterTerm(f.getTerm()); + String whereValue = ""; + if (x.getDeType() == 1 && x.getDeExtractType() != 1) { + String cast = String.format(OracleConstants.CAST, originField, OracleConstants.DEFAULT_INT_FORMAT) + + "/1000"; + whereName = String.format(OracleConstants.FROM_UNIXTIME, cast, OracleConstants.DEFAULT_DATE_FORMAT); + } else { + whereName = originField; + } + if (StringUtils.equalsIgnoreCase(f.getTerm(), "null")) { + whereValue = ""; + } else if (StringUtils.equalsIgnoreCase(f.getTerm(), "not_null")) { + whereValue = ""; + } else if (StringUtils.equalsIgnoreCase(f.getTerm(), "empty")) { + whereValue = "''"; + } else if (StringUtils.equalsIgnoreCase(f.getTerm(), "not_empty")) { + whereValue = "''"; + } else if (StringUtils.containsIgnoreCase(f.getTerm(), "in")) { + whereValue = "('" + StringUtils.join(f.getValue(), "','") + "')"; + } else if (StringUtils.containsIgnoreCase(f.getTerm(), "like")) { + whereValue = "'%" + f.getValue() + "%'"; + } else { + whereValue = String.format(OracleConstants.WHERE_VALUE_VALUE, f.getValue()); + } + list.add(SQLObj.builder() + .whereField(whereName) + .whereAlias(fieldAlias) + .whereTermAndValue(whereTerm + whereValue) + .build()); + }); + } + return list; + } + + private SQLObj getYFields(ChartViewFieldDTO y, String originField, String fieldAlias) { + String fieldName = ""; + if (StringUtils.equalsIgnoreCase(y.getOriginName(), "*")) { + fieldName = OracleConstants.AGG_COUNT; + } else if (SQLConstants.DIMENSION_TYPE.contains(y.getDeType())) { + if (StringUtils.equalsIgnoreCase(y.getSummary(), "count_distinct")) { + fieldName = String.format(OracleConstants.AGG_FIELD, "COUNT", "DISTINCT " + originField); + } else if (StringUtils.equalsIgnoreCase(y.getSummary(), "group_concat")) { + fieldName = String.format(OracleConstants.GROUP_CONCAT, originField, originField); + } else { + fieldName = String.format(OracleConstants.AGG_FIELD, y.getSummary(), originField); + } + } else { + if (StringUtils.equalsIgnoreCase(y.getSummary(), "avg") + || StringUtils.containsIgnoreCase(y.getSummary(), "pop")) { + String cast = String.format(OracleConstants.CAST, originField, + y.getDeType() == 2 ? OracleConstants.DEFAULT_INT_FORMAT : OracleConstants.DEFAULT_FLOAT_FORMAT); + String agg = String.format(OracleConstants.AGG_FIELD, y.getSummary(), cast); + fieldName = String.format(OracleConstants.CAST, agg, OracleConstants.DEFAULT_FLOAT_FORMAT); + } else { + String cast = String.format(OracleConstants.CAST, originField, + y.getDeType() == 2 ? OracleConstants.DEFAULT_INT_FORMAT : OracleConstants.DEFAULT_FLOAT_FORMAT); + if (StringUtils.equalsIgnoreCase(y.getSummary(), "count_distinct")) { + fieldName = String.format(OracleConstants.AGG_FIELD, "COUNT", "DISTINCT " + cast); + } else { + fieldName = String.format(OracleConstants.AGG_FIELD, y.getSummary(), cast); + } + } + } + return SQLObj.builder() + .fieldName(fieldName) + .fieldAlias(fieldAlias) + .build(); + } + + private String getYWheres(ChartViewFieldDTO y, String originField, String fieldAlias) { + List list = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(y.getFilter()) && y.getFilter().size() > 0) { + y.getFilter().forEach(f -> { + String whereTerm = transMysqlFilterTerm(f.getTerm()); + String whereValue = ""; + // 原始类型不是时间,在de中被转成时间的字段做处理 + if (StringUtils.equalsIgnoreCase(f.getTerm(), "null")) { + whereValue = ""; + } else if (StringUtils.equalsIgnoreCase(f.getTerm(), "not_null")) { + whereValue = ""; + } else if (StringUtils.equalsIgnoreCase(f.getTerm(), "empty")) { + whereValue = "''"; + } else if (StringUtils.equalsIgnoreCase(f.getTerm(), "not_empty")) { + whereValue = "''"; + } else if (StringUtils.containsIgnoreCase(f.getTerm(), "in")) { + whereValue = "('" + StringUtils.join(f.getValue(), "','") + "')"; + } else if (StringUtils.containsIgnoreCase(f.getTerm(), "like")) { + whereValue = "'%" + f.getValue() + "%'"; + } else { + whereValue = String.format(OracleConstants.WHERE_VALUE_VALUE, f.getValue()); + } + list.add(SQLObj.builder() + .whereField(fieldAlias) + .whereAlias(fieldAlias) + .whereTermAndValue(whereTerm + whereValue) + .build()); + }); + } + List strList = new ArrayList<>(); + list.forEach(ele -> strList.add(ele.getWhereField() + " " + ele.getWhereTermAndValue())); + return CollectionUtils.isNotEmpty(list) ? "(" + String.join(" " + getLogic(y.getLogic()) + " ", strList) + ")" + : null; + } + + private String calcFieldRegex(String originField, SQLObj tableObj) { + originField = originField.replaceAll("[\\t\\n\\r]]", ""); + // 正则提取[xxx] + String regex = "\\[(.*?)]"; + Pattern pattern = Pattern.compile(regex); + Matcher matcher = pattern.matcher(originField); + Set ids = new HashSet<>(); + while (matcher.find()) { + String id = matcher.group(1); + ids.add(id); + } + if (CollectionUtils.isEmpty(ids)) { + return originField; + } + DatasetTableFieldExample datasetTableFieldExample = new DatasetTableFieldExample(); + datasetTableFieldExample.createCriteria().andIdIn(new ArrayList<>(ids)); + List calcFields = datasetTableFieldMapper.selectByExample(datasetTableFieldExample); + for (DatasetTableField ele : calcFields) { + originField = originField.replaceAll("\\[" + ele.getId() + "]", + String.format(OracleConstants.KEYWORD_FIX, tableObj.getTableAlias(), ele.getOriginName())); + } + return originField; + } + + /** + * 数据条数限制 + * + * @param sql + * @param view + * @return + */ + private String sqlLimit(String sql, ChartViewWithBLOBs view) { + if (StringUtils.equalsIgnoreCase(view.getResultMode(), "custom")) { + return "SELECT * FROM (" + sqlFix(sql) + ") DE_RESULT_TMP " + " WHERE rownum <= " + view.getResultCount(); + } else { + return sql; + } + } + + public List dateformat() { + ObjectMapper objectMapper = new ObjectMapper(); + List dateformats = new ArrayList<>(); + try { + dateformats = objectMapper.readValue("[\n" + + "{\"dateformat\": \"YYYY-MM-DD\"},\n" + + "{\"dateformat\": \"YYYY/MM/DD\"},\n" + + "{\"dateformat\": \"YYYYMMDD\"},\n" + + "{\"dateformat\": \"YYYY-MM-DD HH24:MI:SS\"},\n" + + "{\"dateformat\": \"YYYY/MM/DD HH24:MI:SS\"},\n" + + "{\"dateformat\": \"YYYYMMDD HH24:MI:SS\"}\n" + + "]", new TypeReference>() { + }); + } catch (Exception e) { + } + return dateformats; + } +} diff --git a/extensions/dataease-extensions-datasource/kingbase/kingbase-backend/src/main/java/io/dataease/plugins/datasource/kingbase/service/KingbaseService.java b/extensions/dataease-extensions-datasource/kingbase/kingbase-backend/src/main/java/io/dataease/plugins/datasource/kingbase/service/KingbaseService.java new file mode 100644 index 0000000000..e5f546a68e --- /dev/null +++ b/extensions/dataease-extensions-datasource/kingbase/kingbase-backend/src/main/java/io/dataease/plugins/datasource/kingbase/service/KingbaseService.java @@ -0,0 +1,71 @@ +package io.dataease.plugins.datasource.kingbase.service; + +import io.dataease.plugins.common.constants.DatabaseClassification; +import io.dataease.plugins.common.constants.DatasourceCalculationMode; +import io.dataease.plugins.common.dto.StaticResource; +import io.dataease.plugins.common.dto.datasource.DataSourceType; +import io.dataease.plugins.datasource.service.DatasourceService; +import org.springframework.stereotype.Service; + +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + +@Service +public class KingbaseService extends DatasourceService { + + + /** + * 添加数据源类型 + */ + @Override + public List components() { + List result = new ArrayList<>(); + result.add("kingbase"); + return result; + } + + /** + * 读取静态资源 + */ + @Override + protected InputStream readContent(String s) { + return this.getClass().getClassLoader().getResourceAsStream("static/" + s); + } + + /** + * 映射 Logo 资源 + */ + @Override + public List staticResources() { + List results = new ArrayList<>(); + StaticResource staticResource = new StaticResource(); + staticResource.setName("kingbase"); + staticResource.setSuffix("jpg"); + results.add(staticResource); + results.add(pluginSvg()); + return results; + } + + /** + * 用户填写的数据源信息 + */ + @Override + public DataSourceType getDataSourceType() { + DataSourceType dataSourceType = new DataSourceType("kingbase", "KingBase", true, "", + DatasourceCalculationMode.DIRECT_AND_SYNC, true); + dataSourceType.setKeywordPrefix("\""); + dataSourceType.setKeywordSuffix("\""); + dataSourceType.setAliasPrefix("\""); + dataSourceType.setAliasSuffix("\""); + dataSourceType.setDatabaseClassification(DatabaseClassification.OLTP); + return dataSourceType; + } + + private StaticResource pluginSvg() { + StaticResource staticResource = new StaticResource(); + staticResource.setName("kingbase-backend"); + staticResource.setSuffix("svg"); + return staticResource; + } +} diff --git a/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/.babelrc b/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/.babelrc new file mode 100644 index 0000000000..3a280ba34b --- /dev/null +++ b/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/.babelrc @@ -0,0 +1,12 @@ +{ + "presets": [ + ["env", { + "modules": false, + "targets": { + "browsers": ["> 1%", "last 2 versions", "not ie <= 8"] + } + }], + "stage-2" + ], + "plugins": ["transform-vue-jsx", "transform-runtime"] +} diff --git a/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/.gitignore b/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/.gitignore new file mode 100644 index 0000000000..541a820f6c --- /dev/null +++ b/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/.gitignore @@ -0,0 +1,14 @@ +.DS_Store +node_modules/ +/dist/ +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Editor directories and files +.idea +.vscode +*.suo +*.ntvs* +*.njsproj +*.sln diff --git a/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/README.md b/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/README.md new file mode 100644 index 0000000000..c1e4be95e0 --- /dev/null +++ b/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/README.md @@ -0,0 +1,21 @@ +# deplugin-view-frontend + +> A Vue.js project + +## Build Setup + +``` bash +# install dependencies +npm install + +# serve with hot reload at localhost:8080 +npm run dev + +# build for production with minification +npm run build + +# build for production and view the bundle analyzer report +npm run build --report +``` + +For a detailed explanation on how things work, check out the [guide](http://vuejs-templates.github.io/webpack/) and [docs for vue-loader](http://vuejs.github.io/vue-loader). diff --git a/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/build/build-async-plugins.js b/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/build/build-async-plugins.js new file mode 100644 index 0000000000..2303854531 --- /dev/null +++ b/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/build/build-async-plugins.js @@ -0,0 +1,35 @@ +'use strict' +require('./check-versions')() + +process.env.NODE_ENV = 'production' + +const ora = require('ora') +const chalk = require('chalk') +const webpack = require('webpack') +const webpackConfig = require('./webpack.async-plugins') + +const spinner = ora('building for sync-plugins...') +spinner.start() + +webpack(webpackConfig, function (err, stats) { + spinner.stop() + if (err) throw err + process.stdout.write(stats.toString({ + colors: true, + modules: false, + children: false, + chunks: false, + chunkModules: false + }) + '\n\n') + + if (stats.hasErrors()) { + console.log(chalk.red(' Build failed with errors.\n')) + process.exit(1) + } + + console.log(chalk.cyan(' Build complete.\n')) + console.log(chalk.yellow( + ' Tip: built files are meant to be served over an HTTP server.\n' + + ' Opening index.html over file:// won\'t work.\n' + )) +}) diff --git a/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/build/build.js b/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/build/build.js new file mode 100644 index 0000000000..8f2ad8ad49 --- /dev/null +++ b/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/build/build.js @@ -0,0 +1,41 @@ +'use strict' +require('./check-versions')() + +process.env.NODE_ENV = 'production' + +const ora = require('ora') +const rm = require('rimraf') +const path = require('path') +const chalk = require('chalk') +const webpack = require('webpack') +const config = require('../config') +const webpackConfig = require('./webpack.prod.conf') + +const spinner = ora('building for production...') +spinner.start() + +rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => { + if (err) throw err + webpack(webpackConfig, (err, stats) => { + spinner.stop() + if (err) throw err + process.stdout.write(stats.toString({ + colors: true, + modules: false, + children: false, // If you are using ts-loader, setting this to true will make TypeScript errors show up during build. + chunks: false, + chunkModules: false + }) + '\n\n') + + if (stats.hasErrors()) { + console.log(chalk.red(' Build failed with errors.\n')) + process.exit(1) + } + + console.log(chalk.cyan(' Build complete.\n')) + console.log(chalk.yellow( + ' Tip: built files are meant to be served over an HTTP server.\n' + + ' Opening index.html over file:// won\'t work.\n' + )) + }) +}) diff --git a/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/build/check-versions.js b/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/build/check-versions.js new file mode 100644 index 0000000000..3ef972a08d --- /dev/null +++ b/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/build/check-versions.js @@ -0,0 +1,54 @@ +'use strict' +const chalk = require('chalk') +const semver = require('semver') +const packageConfig = require('../package.json') +const shell = require('shelljs') + +function exec (cmd) { + return require('child_process').execSync(cmd).toString().trim() +} + +const versionRequirements = [ + { + name: 'node', + currentVersion: semver.clean(process.version), + versionRequirement: packageConfig.engines.node + } +] + +if (shell.which('npm')) { + versionRequirements.push({ + name: 'npm', + currentVersion: exec('npm --version'), + versionRequirement: packageConfig.engines.npm + }) +} + +module.exports = function () { + const warnings = [] + + for (let i = 0; i < versionRequirements.length; i++) { + const mod = versionRequirements[i] + + if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) { + warnings.push(mod.name + ': ' + + chalk.red(mod.currentVersion) + ' should be ' + + chalk.green(mod.versionRequirement) + ) + } + } + + if (warnings.length) { + console.log('') + console.log(chalk.yellow('To use this template, you must update following to modules:')) + console.log() + + for (let i = 0; i < warnings.length; i++) { + const warning = warnings[i] + console.log(' ' + warning) + } + + console.log() + process.exit(1) + } +} diff --git a/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/build/logo.png b/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/build/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..f3d2503fc2a44b5053b0837ebea6e87a2d339a43 GIT binary patch literal 6849 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 { + const notifier = require('node-notifier') + + return (severity, errors) => { + if (severity !== 'error') return + + const error = errors[0] + const filename = error.file && error.file.split('!').pop() + + notifier.notify({ + title: packageConfig.name, + message: severity + ': ' + error.name, + subtitle: filename || '', + icon: path.join(__dirname, 'logo.png') + }) + } +} diff --git a/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/build/vue-loader.conf.js b/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/build/vue-loader.conf.js new file mode 100644 index 0000000000..33ed58bc0a --- /dev/null +++ b/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/build/vue-loader.conf.js @@ -0,0 +1,22 @@ +'use strict' +const utils = require('./utils') +const config = require('../config') +const isProduction = process.env.NODE_ENV === 'production' +const sourceMapEnabled = isProduction + ? config.build.productionSourceMap + : config.dev.cssSourceMap + +module.exports = { + loaders: utils.cssLoaders({ + sourceMap: sourceMapEnabled, + extract: isProduction + }), + cssSourceMap: sourceMapEnabled, + cacheBusting: config.dev.cacheBusting, + transformToRequire: { + video: ['src', 'poster'], + source: 'src', + img: 'src', + image: 'xlink:href' + } +} diff --git a/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/build/webpack.async-plugins.js b/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/build/webpack.async-plugins.js new file mode 100644 index 0000000000..a037511cbe --- /dev/null +++ b/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/build/webpack.async-plugins.js @@ -0,0 +1,91 @@ +const webpack = require('webpack') +const path = require('path') +const utils = require('./utils') +const CopyPlugin = require("copy-webpack-plugin"); +const VueLoaderPlugin = require('vue-loader/lib/plugin'); +function resolve (dir) { + return path.join(__dirname, '..', dir) +} + +module.exports = { + mode: 'development', + entry: { + 'kingbase': resolve('/src/views/kingbase.vue') + }, + output: { + path: resolve('/static/'), + filename: '[name].js' + }, + resolve: { + extensions: ['.js', '.vue', '.json'], + alias: { + 'vue$': 'vue/dist/vue.esm.js', + '@': resolve('src') + } + }, + externals: { + vue: 'vue' + }, + module: { + rules: [ + { + test: /\.vue$/, + loader: 'vue-loader', + options: { + transformAssetUrls: { + video: 'src', + source: 'src', + img: 'src', + image: 'xlink:href' + } + } + }, + { + test: /.(sa|sc|c)ss$/, + use: [ + {loader: 'vue-style-loader'}, + 'css-loader', + 'sass-loader' + ] + }, + { + test: /\.js$/, + loader: 'babel-loader', + include: [resolve('src'), resolve('test')] + }, + { + test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: utils.assetsPath('img/[name].[hash:7].[ext]') + } + }, + { + test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: utils.assetsPath('media/[name].[hash:7].[ext]') + } + }, + { + test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: utils.assetsPath('fonts/[name].[hash:7].[ext]') + } + } + ] + }, + plugins: [ + new VueLoaderPlugin(), + new webpack.DefinePlugin({ + 'process.env.NODE_ENV': '"production"' + }), + new CopyPlugin([ + {from: 'src/icons/svg/'} + ]), + ] +} diff --git a/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/build/webpack.base.conf.js b/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/build/webpack.base.conf.js new file mode 100644 index 0000000000..7ef785a39e --- /dev/null +++ b/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/build/webpack.base.conf.js @@ -0,0 +1,103 @@ +'use strict' +const path = require('path') +const utils = require('./utils') +const config = require('../config') +const vueLoaderConfig = require('./vue-loader.conf') + +function resolve (dir) { + return path.join(__dirname, '..', dir) +} + + + +module.exports = { + context: path.resolve(__dirname, '../'), + entry: { + app: './src/main.js' + }, + output: { + path: config.build.assetsRoot, + filename: '[name].js', + publicPath: process.env.NODE_ENV === 'production' + ? config.build.assetsPublicPath + : config.dev.assetsPublicPath + }, + resolve: { + extensions: ['.js', '.vue', '.json'], + alias: { + 'vue$': 'vue/dist/vue.esm.js', + '@': resolve('src'), + } + }, + module: { + rules: [ + { + test: /\.vue$/, + loader: 'vue-loader', + options: vueLoaderConfig + }, + { + test: /\.js$/, + loader: 'babel-loader', + include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')] + }, + { + test: /\.svg$/, + loader: 'svg-sprite-loader', + include: [resolve('src/icons')], + options: { + symbolId: 'icon-[name]' + } + }, + { + test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, + loader: 'url-loader', + exclude: [resolve('src/icons')], + options: { + limit: 10000, + name: utils.assetsPath('img/[name].[hash:7].[ext]') + } + }, + { + test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: utils.assetsPath('media/[name].[hash:7].[ext]') + } + }, + { + test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: utils.assetsPath('fonts/[name].[hash:7].[ext]') + } + }, + { + test: /\.svg$/, + include: [path.resolve('src/icons')], + use: [ + { + loader: 'svg-sprite-loader', + options: { + symbolId: 'icon-[name]', + }, + } + ], + } + ] + }, + node: { + // prevent webpack from injecting useless setImmediate polyfill because Vue + // source contains it (although only uses it if it's native). + setImmediate: false, + // prevent webpack from injecting mocks to Node native modules + // that does not make sense for the client + dgram: 'empty', + fs: 'empty', + net: 'empty', + tls: 'empty', + child_process: 'empty' + } +} diff --git a/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/build/webpack.dev.conf.js b/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/build/webpack.dev.conf.js new file mode 100755 index 0000000000..070ae221f3 --- /dev/null +++ b/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/build/webpack.dev.conf.js @@ -0,0 +1,95 @@ +'use strict' +const utils = require('./utils') +const webpack = require('webpack') +const config = require('../config') +const merge = require('webpack-merge') +const path = require('path') +const baseWebpackConfig = require('./webpack.base.conf') +const CopyWebpackPlugin = require('copy-webpack-plugin') +const HtmlWebpackPlugin = require('html-webpack-plugin') +const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin') +const portfinder = require('portfinder') + +const HOST = process.env.HOST +const PORT = process.env.PORT && Number(process.env.PORT) + +const devWebpackConfig = merge(baseWebpackConfig, { + module: { + rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true }) + }, + // cheap-module-eval-source-map is faster for development + devtool: config.dev.devtool, + + // these devServer options should be customized in /config/index.js + devServer: { + clientLogLevel: 'warning', + historyApiFallback: { + rewrites: [ + { from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') }, + ], + }, + hot: true, + contentBase: false, // since we use CopyWebpackPlugin. + compress: true, + host: HOST || config.dev.host, + port: PORT || config.dev.port, + open: config.dev.autoOpenBrowser, + overlay: config.dev.errorOverlay + ? { warnings: false, errors: true } + : false, + publicPath: config.dev.assetsPublicPath, + proxy: config.dev.proxyTable, + quiet: true, // necessary for FriendlyErrorsPlugin + watchOptions: { + poll: config.dev.poll, + } + }, + plugins: [ + new webpack.DefinePlugin({ + 'process.env': require('../config/dev.env') + }), + new webpack.HotModuleReplacementPlugin(), + new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update. + new webpack.NoEmitOnErrorsPlugin(), + // https://github.com/ampedandwired/html-webpack-plugin + new HtmlWebpackPlugin({ + filename: 'index.html', + template: 'index.html', + inject: true + }), + // copy custom static assets + new CopyWebpackPlugin([ + { + from: path.resolve(__dirname, '../static'), + to: config.dev.assetsSubDirectory, + ignore: ['.*'] + } + ]) + ] +}) + +module.exports = new Promise((resolve, reject) => { + portfinder.basePort = process.env.PORT || config.dev.port + portfinder.getPort((err, port) => { + if (err) { + reject(err) + } else { + // publish the new Port, necessary for e2e tests + process.env.PORT = port + // add port to devServer config + devWebpackConfig.devServer.port = port + + // Add FriendlyErrorsPlugin + devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({ + compilationSuccessInfo: { + messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`], + }, + onErrors: config.dev.notifyOnErrors + ? utils.createNotifierCallback() + : undefined + })) + + resolve(devWebpackConfig) + } + }) +}) diff --git a/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/build/webpack.prod.conf.js b/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/build/webpack.prod.conf.js new file mode 100644 index 0000000000..3e25238ef6 --- /dev/null +++ b/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/build/webpack.prod.conf.js @@ -0,0 +1,145 @@ +'use strict' +const path = require('path') +const utils = require('./utils') +const webpack = require('webpack') +const config = require('../config') +const merge = require('webpack-merge') +const baseWebpackConfig = require('./webpack.base.conf') +const CopyWebpackPlugin = require('copy-webpack-plugin') +const HtmlWebpackPlugin = require('html-webpack-plugin') +const ExtractTextPlugin = require('extract-text-webpack-plugin') +const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin') +const UglifyJsPlugin = require('uglifyjs-webpack-plugin') + +const env = require('../config/prod.env') + +const webpackConfig = merge(baseWebpackConfig, { + module: { + rules: utils.styleLoaders({ + sourceMap: config.build.productionSourceMap, + extract: true, + usePostCSS: true + }) + }, + devtool: config.build.productionSourceMap ? config.build.devtool : false, + output: { + path: config.build.assetsRoot, + filename: utils.assetsPath('js/[name].[chunkhash].js'), + chunkFilename: utils.assetsPath('js/[id].[chunkhash].js') + }, + plugins: [ + // http://vuejs.github.io/vue-loader/en/workflow/production.html + new webpack.DefinePlugin({ + 'process.env': env + }), + new UglifyJsPlugin({ + uglifyOptions: { + compress: { + warnings: false + } + }, + sourceMap: config.build.productionSourceMap, + parallel: true + }), + // extract css into its own file + new ExtractTextPlugin({ + filename: utils.assetsPath('css/[name].[contenthash].css'), + // Setting the following option to `false` will not extract CSS from codesplit chunks. + // Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack. + // It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`, + // increasing file size: https://github.com/vuejs-templates/webpack/issues/1110 + allChunks: true, + }), + // Compress extracted CSS. We are using this plugin so that possible + // duplicated CSS from different components can be deduped. + new OptimizeCSSPlugin({ + cssProcessorOptions: config.build.productionSourceMap + ? { safe: true, map: { inline: false } } + : { safe: true } + }), + // generate dist index.html with correct asset hash for caching. + // you can customize output by editing /index.html + // see https://github.com/ampedandwired/html-webpack-plugin + new HtmlWebpackPlugin({ + filename: config.build.index, + template: 'index.html', + inject: true, + minify: { + removeComments: true, + collapseWhitespace: true, + removeAttributeQuotes: true + // more options: + // https://github.com/kangax/html-minifier#options-quick-reference + }, + // necessary to consistently work with multiple chunks via CommonsChunkPlugin + chunksSortMode: 'dependency' + }), + // keep module.id stable when vendor modules does not change + new webpack.HashedModuleIdsPlugin(), + // enable scope hoisting + new webpack.optimize.ModuleConcatenationPlugin(), + // split vendor js into its own file + new webpack.optimize.CommonsChunkPlugin({ + name: 'vendor', + minChunks (module) { + // any required modules inside node_modules are extracted to vendor + return ( + module.resource && + /\.js$/.test(module.resource) && + module.resource.indexOf( + path.join(__dirname, '../node_modules') + ) === 0 + ) + } + }), + // extract webpack runtime and module manifest to its own file in order to + // prevent vendor hash from being updated whenever app bundle is updated + new webpack.optimize.CommonsChunkPlugin({ + name: 'manifest', + minChunks: Infinity + }), + // This instance extracts shared chunks from code split chunks and bundles them + // in a separate chunk, similar to the vendor chunk + // see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk + new webpack.optimize.CommonsChunkPlugin({ + name: 'app', + async: 'vendor-async', + children: true, + minChunks: 3 + }), + + // copy custom static assets + new CopyWebpackPlugin([ + { + from: path.resolve(__dirname, '../static'), + to: config.build.assetsSubDirectory, + ignore: ['.*'] + } + ]) + ] +}) + +if (config.build.productionGzip) { + const CompressionWebpackPlugin = require('compression-webpack-plugin') + + webpackConfig.plugins.push( + new CompressionWebpackPlugin({ + asset: '[path].gz[query]', + algorithm: 'gzip', + test: new RegExp( + '\\.(' + + config.build.productionGzipExtensions.join('|') + + ')$' + ), + threshold: 10240, + minRatio: 0.8 + }) + ) +} + +if (config.build.bundleAnalyzerReport) { + const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin + webpackConfig.plugins.push(new BundleAnalyzerPlugin()) +} + +module.exports = webpackConfig diff --git a/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/config/dev.env.js b/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/config/dev.env.js new file mode 100644 index 0000000000..1e22973ae7 --- /dev/null +++ b/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/config/dev.env.js @@ -0,0 +1,7 @@ +'use strict' +const merge = require('webpack-merge') +const prodEnv = require('./prod.env') + +module.exports = merge(prodEnv, { + NODE_ENV: '"development"' +}) diff --git a/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/config/index.js b/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/config/index.js new file mode 100644 index 0000000000..c5eded7f81 --- /dev/null +++ b/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/config/index.js @@ -0,0 +1,69 @@ +'use strict' +// Template version: 1.3.1 +// see http://vuejs-templates.github.io/webpack for documentation. + +const path = require('path') + +module.exports = { + dev: { + + // Paths + assetsSubDirectory: 'static', + assetsPublicPath: '/', + proxyTable: {}, + + // Various Dev Server settings + host: 'localhost', // can be overwritten by process.env.HOST + port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined + autoOpenBrowser: false, + errorOverlay: true, + notifyOnErrors: true, + poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions- + + + /** + * Source Maps + */ + + // https://webpack.js.org/configuration/devtool/#development + devtool: 'cheap-module-eval-source-map', + + // If you have problems debugging vue-files in devtools, + // set this to false - it *may* help + // https://vue-loader.vuejs.org/en/options.html#cachebusting + cacheBusting: true, + + cssSourceMap: true + }, + + build: { + // Template for index.html + index: path.resolve(__dirname, '../dist/index.html'), + + // Paths + assetsRoot: path.resolve(__dirname, '../dist'), + assetsSubDirectory: 'static', + assetsPublicPath: '/', + + /** + * Source Maps + */ + + productionSourceMap: true, + // https://webpack.js.org/configuration/devtool/#production + devtool: '#source-map', + + // Gzip off by default as many popular static hosts such as + // Surge or Netlify already gzip all static assets for you. + // Before setting to `true`, make sure to: + // npm install --save-dev compression-webpack-plugin + productionGzip: false, + productionGzipExtensions: ['js', 'css'], + + // Run the build command with an extra argument to + // View the bundle analyzer report after build finishes: + // `npm run build --report` + // Set to `true` or `false` to always turn it on or off + bundleAnalyzerReport: process.env.npm_config_report + } +} diff --git a/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/config/prod.env.js b/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/config/prod.env.js new file mode 100644 index 0000000000..a6f997616e --- /dev/null +++ b/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/config/prod.env.js @@ -0,0 +1,4 @@ +'use strict' +module.exports = { + NODE_ENV: '"production"' +} diff --git a/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/index.html b/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/index.html new file mode 100644 index 0000000000..03ce3fdf27 --- /dev/null +++ b/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/index.html @@ -0,0 +1,12 @@ + + + + + + deplugin-view-frontend + + +
+ + + diff --git a/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/package.json b/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/package.json new file mode 100644 index 0000000000..64a3ce7ad6 --- /dev/null +++ b/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/package.json @@ -0,0 +1,75 @@ +{ + "name": "deplugin-datasource-frontend", + "version": "1.0.0", + "description": "A Vue.js project", + "author": "", + "private": true, + "scripts": { + "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js", + "start": "npm run dev", + "build": "node build/build.js", + "buildPlugin": "node build/build-async-plugins.js" + }, + "dependencies": { + "@riophae/vue-treeselect": "0.4.0", + "highcharts": "^10.0.0", + "svg-sprite-loader": "^6.0.11", + "svgo": "1.2.2", + "svgo-loader": "^3.0.1", + "vue": "^2.5.2", + "vue-i18n": "7.3.2", + "vue-router": "^3.0.1", + "vue-uuid": "2.0.2", + "vuedraggable": "^2.24.3" + }, + "devDependencies": { + "autoprefixer": "^7.1.2", + "babel-core": "^6.22.1", + "babel-helper-vue-jsx-merge-props": "^2.0.3", + "babel-loader": "^7.1.1", + "babel-plugin-syntax-jsx": "^6.18.0", + "babel-plugin-transform-runtime": "^6.22.0", + "babel-plugin-transform-vue-jsx": "^3.5.0", + "babel-preset-env": "^1.3.2", + "babel-preset-stage-2": "^6.22.0", + "chalk": "^2.0.1", + "copy-webpack-plugin": "^4.6.0", + "css-loader": "^0.28.0", + "element-ui": "2.15.7", + "extract-text-webpack-plugin": "^4.0.0-beta.0", + "file-loader": "^1.1.4", + "friendly-errors-webpack-plugin": "^1.6.1", + "html-webpack-plugin": "^3.2.0", + "js-cookie": "2.2.0", + "node-notifier": "^8.0.1", + "optimize-css-assets-webpack-plugin": "^3.2.0", + "ora": "^1.2.0", + "portfinder": "^1.0.13", + "postcss-import": "^11.0.0", + "postcss-loader": "^2.0.8", + "postcss-url": "^7.2.1", + "rimraf": "^2.6.0", + "sass": "^1.33.0", + "sass-loader": "^7.3.1", + "semver": "^5.3.0", + "shelljs": "^0.8.5", + "uglifyjs-webpack-plugin": "^1.1.1", + "url-loader": "^0.5.8", + "vue-loader": "^15.6.4", + "vue-style-loader": "^4.1.2", + "vue-template-compiler": "^2.5.2", + "webpack": "^4.8.1", + "webpack-bundle-analyzer": "^3.3.2", + "webpack-dev-server": "^3.1.11", + "webpack-merge": "^4.1.0" + }, + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + }, + "browserslist": [ + "> 1%", + "last 2 versions", + "not ie <= 8" + ] +} diff --git a/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/pom.xml b/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/pom.xml new file mode 100644 index 0000000000..899a5b0d25 --- /dev/null +++ b/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/pom.xml @@ -0,0 +1,80 @@ + + + + + io.dataease + kingbase + ${dataease.version} + + + 4.0.0 + kingbase-frontend + + + UTF-8 + UTF-8 + 1.9.1 + + + + + + maven-clean-plugin + + + + static + + ** + + false + + + + + + + + com.github.eirslett + frontend-maven-plugin + ${frontend-maven-plugin.version} + + + install node and npm + + install-node-and-npm + + + + v16.20.2 + 7.6.3 + + + + + npm install + + npm + + + + install --force + + + + + npm run buildPlugin + + npm + + + run buildPlugin + + + + + + + diff --git a/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/postcss.config.js b/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/postcss.config.js new file mode 100644 index 0000000000..ccd0905482 --- /dev/null +++ b/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/postcss.config.js @@ -0,0 +1,5 @@ +module.exports = { + plugins: { + 'autoprefixer': { browsers: 'last 5 version' } + } +} \ No newline at end of file diff --git a/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/src/App.vue b/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/src/App.vue new file mode 100644 index 0000000000..8542e07722 --- /dev/null +++ b/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/src/App.vue @@ -0,0 +1,23 @@ + + + + + diff --git a/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/src/assets/logo.png b/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/src/assets/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..f3d2503fc2a44b5053b0837ebea6e87a2d339a43 GIT binary patch literal 6849 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 +
+

{{ msg }}

+

Essential Links

+ +

Ecosystem

+ +
+ + + + + + diff --git a/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/src/de-base/lang/en.js b/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/src/de-base/lang/en.js new file mode 100644 index 0000000000..e5084e7ed1 --- /dev/null +++ b/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/src/de-base/lang/en.js @@ -0,0 +1,31 @@ +export default { + host: 'Host name/IP address', + dataBase: 'Database name', + connection_mode: 'Connection mode', + oracle_sid: 'SID', + oracle_service_name: 'Service name', + username: 'User name', + password: 'Password', + port: 'Port', + schema: 'Schema', + get_schema: 'Get Schema', + charset: 'Character set', + targetCharset: 'Target character set', + priority: 'Advanced settings', + initial_pool_size: 'Initial connections', + min_pool_size: 'Minimum connections', + max_pool_size: 'Maximum connections', + query_timeout: 'Query timeout', + one_user_name: 'Please enter the user name', + input_a_password: 'Please enter the password', + enter_the_port: 'Please enter the port', + please_choose_schema: 'Please select Schema', + please_choose_charset: 'Please select the database character set', + please_choose_targetCharset: 'Please select the target character set', + please_input_initial_pool_size: 'Please enter the initial number of connections', + please_input_min_pool_size: 'Please enter the minimum number of connections', + please_input_max_pool_size: 'Please enter the maximum number of connections', + please_input_query_timeout: 'Please enter the query timeout', + second: 'Second', + please_select: 'Please select' +} diff --git a/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/src/de-base/lang/index.js b/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/src/de-base/lang/index.js new file mode 100644 index 0000000000..e50d0478e6 --- /dev/null +++ b/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/src/de-base/lang/index.js @@ -0,0 +1,49 @@ +import Vue from 'vue' +import VueI18n from 'vue-i18n' +import Cookies from 'js-cookie' +import elementEnLocale from 'element-ui/lib/locale/lang/en' // element-ui lang +import elementZhLocale from 'element-ui/lib/locale/lang/zh-CN'// element-ui lang +import elementTWLocale from 'element-ui/lib/locale/lang/zh-TW'// element-ui lang + +import localMessages from './messages' + + +Vue.use(VueI18n) + +const messages = { + en_US: { + ...localMessages['en_US'], + ...elementEnLocale + }, + zh_CN: { + ...localMessages['zh_CN'], + ...elementZhLocale + }, + zh_TW: { + ...localMessages['zh_TW'], + ...elementTWLocale + } +} +export function getLanguage () { + const chooseLanguage = Cookies.get('language') + if (chooseLanguage) return chooseLanguage + + // if has not choose language + const language = (navigator.language || navigator.browserLanguage).toLowerCase() + const locales = Object.keys(messages) + for (const locale of locales) { + if (language.indexOf(locale) > -1) { + return locale + } + } + return 'zh_CN' +} +const i18n = new VueI18n({ + // set locale + // options: en | zh | es + locale: getLanguage(), + // set locale messages + messages +}) + +export default i18n diff --git a/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/src/de-base/lang/messages.js b/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/src/de-base/lang/messages.js new file mode 100644 index 0000000000..844f8c0673 --- /dev/null +++ b/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/src/de-base/lang/messages.js @@ -0,0 +1,17 @@ +import enLocale from './en' +import zhLocale from './zh' +import twLocale from './tw' + +const messages = { + en_US: { + ...enLocale + }, + zh_CN: { + ...zhLocale + }, + zh_TW: { + ...twLocale + } +} + +export default messages \ No newline at end of file diff --git a/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/src/de-base/lang/tw.js b/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/src/de-base/lang/tw.js new file mode 100644 index 0000000000..96ddbd7a11 --- /dev/null +++ b/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/src/de-base/lang/tw.js @@ -0,0 +1,31 @@ +export default { + host: '主機名/IP地址', + dataBase: '數據庫名稱', + connection_mode: '連接方式', + oracle_sid: 'SID', + oracle_service_name: '服務名', + username: '用戶名', + password: '密碼', + port: '端口', + schema: 'Schema', + get_schema: '獲取 Schema', + charset: '字符集', + targetCharset: '目標字符集', + priority: '高級設置', + initial_pool_size: '初始連接數', + min_pool_size: '最小連接數', + max_pool_size: '最大連接數', + query_timeout: '查詢超時', + one_user_name: '請輸入用戶名', + input_a_password: '請輸入密碼', + enter_the_port: '請輸入端口', + please_choose_schema: '請選擇 Schema', + please_choose_charset: '請選擇數據庫字符集', + please_choose_targetCharset: '請選擇目標字符集', + please_input_initial_pool_size: '請輸入初始連接數', + please_input_min_pool_size: '請輸入最小連接數', + please_input_max_pool_size: '請輸入最大連接數', + please_input_query_timeout: '請輸入查詢超時', + second: '秒', + please_select: '請選擇' +} diff --git a/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/src/de-base/lang/zh.js b/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/src/de-base/lang/zh.js new file mode 100644 index 0000000000..46aaa52af8 --- /dev/null +++ b/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/src/de-base/lang/zh.js @@ -0,0 +1,31 @@ +export default { + host: '主机名/IP地址', + dataBase: '数据库名称', + connection_mode: '连接方式', + oracle_sid: 'SID', + oracle_service_name: '服务名', + username: '用户名', + password: '密码', + port: '端口', + schema: 'Schema', + get_schema: '获取 Schema', + charset: '字符集', + targetCharset: '目标字符集', + priority: '高级设置', + initial_pool_size: '初始连接数', + min_pool_size: '最小连接数', + max_pool_size: '最大连接数', + query_timeout: '查询超时', + one_user_name: '请输入用户名', + input_a_password: '请输入密码', + enter_the_port: '请输入端口', + please_choose_schema: '请选择 Schema', + please_choose_charset: '请选择数据库字符集', + please_choose_targetCharset: '请选择目标字符集', + please_input_initial_pool_size: '请输入初始连接数', + please_input_min_pool_size: '请输入最小连接数', + please_input_max_pool_size: '请输入最大连接数', + please_input_query_timeout: '请输入查询超时', + second: '秒', + please_select: '请选择' +} diff --git a/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/src/icons/index.js b/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/src/icons/index.js new file mode 100644 index 0000000000..2c6b309c96 --- /dev/null +++ b/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/src/icons/index.js @@ -0,0 +1,9 @@ +import Vue from 'vue' +import SvgIcon from '@/components/SvgIcon'// svg component + +// register globally +Vue.component('svg-icon', SvgIcon) + +const req = require.context('./svg', false, /\.svg$/) +const requireAll = requireContext => requireContext.keys().map(requireContext) +requireAll(req) diff --git a/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/src/icons/svg/de_pwd_invisible.svg b/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/src/icons/svg/de_pwd_invisible.svg new file mode 100644 index 0000000000..661ebba33e --- /dev/null +++ b/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/src/icons/svg/de_pwd_invisible.svg @@ -0,0 +1,3 @@ + + + diff --git a/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/src/icons/svg/de_pwd_visible.svg b/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/src/icons/svg/de_pwd_visible.svg new file mode 100644 index 0000000000..4e7ba5e799 --- /dev/null +++ b/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/src/icons/svg/de_pwd_visible.svg @@ -0,0 +1,3 @@ + + + diff --git a/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/src/icons/svg/kingbase-backend.svg b/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/src/icons/svg/kingbase-backend.svg new file mode 100644 index 0000000000..15b98f1f23 --- /dev/null +++ b/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/src/icons/svg/kingbase-backend.svg @@ -0,0 +1 @@ +【icon】人大金仓 \ No newline at end of file diff --git a/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/src/icons/svg/kingbase.jpg b/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/src/icons/svg/kingbase.jpg new file mode 100644 index 0000000000000000000000000000000000000000..3ba452f5936fcd4927aa4c4127dd7a88b81958be GIT binary patch literal 19509 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 i18n.t(key, value) +}) +Vue.component('Treeselect', Treeselect) +Vue.component('draggable', draggable) +Vue.prototype.hasDataPermission = function(pTarget, pSource) { + + if (pSource && pTarget) { + return pSource.indexOf(pTarget) > -1 + } + return false +} +/* eslint-disable no-new */ +new Vue({ + el: '#app', + router, + i18n, + components: { App }, + template: '' +}) diff --git a/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/src/router/index.js b/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/src/router/index.js new file mode 100644 index 0000000000..78245d2d42 --- /dev/null +++ b/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/src/router/index.js @@ -0,0 +1,21 @@ +import Vue from 'vue' +import Router from 'vue-router' +import HelloWorld from '@/components/HelloWorld' +import kingbase from '@/views/kingbase' + +Vue.use(Router) + +export default new Router({ + routes: [ + { + path: '/', + name: 'HelloWorld', + component: HelloWorld + }, + { + path: '/kingbase', + name: 'kingbase', + component: kingbase + } + ] +}) diff --git a/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/src/utils/compare.js b/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/src/utils/compare.js new file mode 100644 index 0000000000..b06a104a10 --- /dev/null +++ b/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/src/utils/compare.js @@ -0,0 +1,29 @@ +export const compareItem = { + type: 'none', // year-yoy/month-yoy等 + resultData: 'percent', // 对比差sub,百分比percent等 + field: '', + custom: { + field: '', + calcType: '0', // 0-增长值,1-增长率 + timeType: '0', // 0-固定日期,1-日期区间 + currentTime: '', + compareTime: '', + currentTimeRange: [], + compareTimeRange: [] + } +} + +export const compareYearList = [ + { name: 'year_mom', value: 'year_mom' } +] + +export const compareMonthList = [ + { name: 'month_mom', value: 'month_mom' }, + { name: 'year_yoy', value: 'year_yoy' } +] + +export const compareDayList = [ + { name: 'day_mom', value: 'day_mom' }, + { name: 'month_yoy', value: 'month_yoy' }, + { name: 'year_yoy', value: 'year_yoy' } +] diff --git a/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/src/utils/validate.js b/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/src/utils/validate.js new file mode 100644 index 0000000000..3e8ffa9448 --- /dev/null +++ b/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/src/utils/validate.js @@ -0,0 +1,15 @@ +/** + * Created by PanJiaChen on 16/11/18. + */ + +/** + * @param {string} path + * @returns {Boolean} + */ +export function isExternal(path) { + return /^(https?:|mailto:|tel:)/.test(path) || /^(http?:|mailto:|tel:)/.test(path) || path.startsWith('/api/pluginCommon/staticInfo') +} + + + + diff --git a/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/src/views/dePwd.vue b/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/src/views/dePwd.vue new file mode 100644 index 0000000000..61bf3e88ee --- /dev/null +++ b/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/src/views/dePwd.vue @@ -0,0 +1,75 @@ + + + + \ No newline at end of file diff --git a/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/src/views/kingbase.vue b/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/src/views/kingbase.vue new file mode 100644 index 0000000000..4058b3b40a --- /dev/null +++ b/extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/src/views/kingbase.vue @@ -0,0 +1,202 @@ + + + + + diff --git a/extensions/dataease-extensions-datasource/kingbase/plugin.json b/extensions/dataease-extensions-datasource/kingbase/plugin.json new file mode 100644 index 0000000000..9da57b4c99 --- /dev/null +++ b/extensions/dataease-extensions-datasource/kingbase/plugin.json @@ -0,0 +1,13 @@ +{ + "name":"kingbase-ora 数据源插件", + "free":0, + "store":"default", + "cost":0, + "category":"datasource", + "descript":"人大金仓插件,值得拥有", + "version":"1.18.0", + "creator":"DATAEASE", + "moduleName":"kingbase-backend", + "require":"1.17.0", + "dsType":"kingbase" +} diff --git a/extensions/dataease-extensions-datasource/kingbase/pom.xml b/extensions/dataease-extensions-datasource/kingbase/pom.xml new file mode 100644 index 0000000000..28bcdb261d --- /dev/null +++ b/extensions/dataease-extensions-datasource/kingbase/pom.xml @@ -0,0 +1,19 @@ + + + + dataease-extensions-datasource + io.dataease + ${dataease.version} + + 4.0.0 + + kingbase + pom + + kingbase-frontend + kingbase-backend + + + diff --git a/extensions/dataease-extensions-datasource/kylin/build.sh b/extensions/dataease-extensions-datasource/kylin/build.sh new file mode 100755 index 0000000000..6c0f20b902 --- /dev/null +++ b/extensions/dataease-extensions-datasource/kylin/build.sh @@ -0,0 +1,6 @@ +#!/bin/sh + mvn clean package -U -Dmaven.test.skip=true + +cp kylin-backend/target/kylin-backend-1.18.0.jar . + +zip -r kylin.zip ./kylin-backend-1.18.0.jar ./kylinDriver ./plugin.json diff --git a/extensions/dataease-extensions-datasource/kylin/kylin-backend/pom.xml b/extensions/dataease-extensions-datasource/kylin/kylin-backend/pom.xml new file mode 100644 index 0000000000..5380575ba1 --- /dev/null +++ b/extensions/dataease-extensions-datasource/kylin/kylin-backend/pom.xml @@ -0,0 +1,108 @@ + + + + kylin + io.dataease + ${dataease.version} + + 4.0.0 + + kylin-backend + + + + io.dataease + dataease-plugin-datasource + + + + + + src/main/java + + **/*.properties + **/*.xml + + false + + + src/main/resources + + **/* + + false + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 11 + 11 + + + + + org.apache.maven.plugins + maven-jar-plugin + 2.4 + + + **/server/** + **/*.properties + **/Application* + + + + + + maven-clean-plugin + + + + src/main/resources/static + + ** + + false + + + + + + + + + org.apache.maven.plugins + maven-antrun-plugin + + + main-class-placement + generate-resources + + + + + + + + + + + + run + + + + + + + + + + + diff --git a/extensions/dataease-extensions-datasource/kylin/kylin-backend/src/main/java/io/dataease/plugins/datasource/kylin/provider/KylinConfig.java b/extensions/dataease-extensions-datasource/kylin/kylin-backend/src/main/java/io/dataease/plugins/datasource/kylin/provider/KylinConfig.java new file mode 100644 index 0000000000..77e434d4f7 --- /dev/null +++ b/extensions/dataease-extensions-datasource/kylin/kylin-backend/src/main/java/io/dataease/plugins/datasource/kylin/provider/KylinConfig.java @@ -0,0 +1,19 @@ +package io.dataease.plugins.datasource.kylin.provider; + +import io.dataease.plugins.datasource.entity.JdbcConfiguration; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class KylinConfig extends JdbcConfiguration { + + private String driver = "org.apache.kylin.jdbc.Driver"; + + public String getJdbc() { + return "jdbc:kylin://HOSTNAME:PORT/DATABASE" + .replace("HOSTNAME", getHost().trim()) + .replace("PORT", getPort().toString().trim()) + .replace("DATABASE", getDataBase().trim()); + } +} diff --git a/extensions/dataease-extensions-datasource/kylin/kylin-backend/src/main/java/io/dataease/plugins/datasource/kylin/provider/KylinDsProvider.java b/extensions/dataease-extensions-datasource/kylin/kylin-backend/src/main/java/io/dataease/plugins/datasource/kylin/provider/KylinDsProvider.java new file mode 100644 index 0000000000..81862855a3 --- /dev/null +++ b/extensions/dataease-extensions-datasource/kylin/kylin-backend/src/main/java/io/dataease/plugins/datasource/kylin/provider/KylinDsProvider.java @@ -0,0 +1,189 @@ +package io.dataease.plugins.datasource.kylin.provider; + +import com.alibaba.druid.pool.DruidPooledConnection; +import com.google.gson.Gson; +import io.dataease.plugins.common.base.domain.DeDriver; +import io.dataease.plugins.common.base.mapper.DeDriverMapper; +import io.dataease.plugins.common.constants.DatasourceTypes; +import io.dataease.plugins.common.dto.datasource.TableDesc; +import io.dataease.plugins.common.dto.datasource.TableField; +import io.dataease.plugins.common.exception.DataEaseException; +import io.dataease.plugins.common.request.datasource.DatasourceRequest; +import io.dataease.plugins.datasource.entity.JdbcConfiguration; +import io.dataease.plugins.datasource.provider.DefaultJdbcProvider; +import io.dataease.plugins.datasource.provider.ExtendedJdbcClassLoader; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.sql.*; +import java.util.*; + + +@Component() +public class KylinDsProvider extends DefaultJdbcProvider { + @Resource + private DeDriverMapper deDriverMapper; + + @Override + public String getType() { + return "kylin"; + } + + @Override + public boolean isUseDatasourcePool() { + return false; + } + + @Override + public Connection getConnection(DatasourceRequest datasourceRequest) throws Exception { + io.dataease.plugins.datasource.kylin.provider.KylinConfig prestoConfig = new Gson().fromJson(datasourceRequest.getDatasource().getConfiguration(), KylinConfig.class); + + String defaultDriver = prestoConfig.getDriver(); + String customDriver = prestoConfig.getCustomDriver(); + + String url = prestoConfig.getJdbc(); + Properties props = new Properties(); + DeDriver deDriver = null; + if (StringUtils.isNotBlank(prestoConfig.getUsername())) { + props.setProperty("user", prestoConfig.getUsername()); + if (StringUtils.isNotBlank(prestoConfig.getPassword())) { + props.setProperty("password", prestoConfig.getPassword()); + } + } + + Connection conn; + String driverClassName ; + ExtendedJdbcClassLoader jdbcClassLoader; + if(isDefaultClassLoader(customDriver)){ + driverClassName = defaultDriver; + jdbcClassLoader = extendedJdbcClassLoader; + }else { + if(deDriver == null){ + deDriver = deDriverMapper.selectByPrimaryKey(customDriver); + } + driverClassName = deDriver.getDriverClass(); + jdbcClassLoader = getCustomJdbcClassLoader(deDriver); + } + ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + try { + Thread.currentThread().setContextClassLoader(jdbcClassLoader); + Driver driverClass = (Driver) jdbcClassLoader.loadClass(driverClassName).newInstance(); + conn= driverClass.connect(url, props); + }catch (Exception e){ + e.printStackTrace(); + throw e; + }finally { + Thread.currentThread().setContextClassLoader(classLoader); + } + return conn; + } + + @Override + public List getTables(DatasourceRequest datasourceRequest) throws Exception { + List tables = new ArrayList<>(); + + List tableNames = new ArrayList<>(); + try (Connection con = getConnectionFromPool(datasourceRequest)) { + DatabaseMetaData databaseMetaData = con.getMetaData(); + ResultSet resultSet = databaseMetaData.getColumns(null, "%", "%", "%"); + while (resultSet.next()) { + String tableName = resultSet.getString("TABLE_NAME"); + if(!tableNames.contains(tableName)){ + tableNames.add(tableName); + TableDesc tableDesc = new TableDesc(); + tableDesc.setName(tableName); + tables.add(tableDesc); + } + } + } catch (Exception e) { + DataEaseException.throwException(e); + } + + return tables; + } + + + @Override + public List getTableFields(DatasourceRequest datasourceRequest) throws Exception { + List list = new LinkedList<>(); + try (Connection connection = getConnectionFromPool(datasourceRequest)) { + DatabaseMetaData databaseMetaData = connection.getMetaData(); + String tableNamePattern = datasourceRequest.getTable(); + ResultSet resultSet = databaseMetaData.getColumns(null, "%", tableNamePattern, "%"); + while (resultSet.next()) { + String tableName = resultSet.getString("TABLE_NAME"); + String database; + if (datasourceRequest.getDatasource().getType().equalsIgnoreCase(DatasourceTypes.pg.name()) || datasourceRequest.getDatasource().getType().equalsIgnoreCase(DatasourceTypes.ck.name()) || datasourceRequest.getDatasource().getType().equalsIgnoreCase(DatasourceTypes.impala.name())) { + database = resultSet.getString("TABLE_SCHEM"); + } else { + database = resultSet.getString("TABLE_CAT"); + } + if (tableName.equals(datasourceRequest.getTable())) { + TableField tableField = getTableFiled(resultSet, datasourceRequest); + list.add(tableField); + } + + } + resultSet.close(); + } catch (SQLException e) { + DataEaseException.throwException(e); + } catch (Exception e) { + } + return list; + } + + private TableField getTableFiled(ResultSet resultSet, DatasourceRequest datasourceRequest) throws SQLException { + TableField tableField = new TableField(); + String colName = resultSet.getString("COLUMN_NAME"); + tableField.setFieldName(colName); + String remarks = resultSet.getString("REMARKS"); + if (remarks == null || remarks.equals("")) { + remarks = colName; + } + tableField.setRemarks(remarks); + String dbType = resultSet.getString("TYPE_NAME").toUpperCase(); + tableField.setFieldType(dbType); + if (dbType.equalsIgnoreCase("LONG")) { + tableField.setFieldSize(65533); + } + if (StringUtils.isNotEmpty(dbType) && dbType.toLowerCase().contains("date") && tableField.getFieldSize() < 50) { + tableField.setFieldSize(50); + } + + String size = resultSet.getString("COLUMN_SIZE"); + if (size == null) { + tableField.setFieldSize(1); + } else { + tableField.setFieldSize(Integer.valueOf(size)); + } + + if (StringUtils.isNotEmpty(tableField.getFieldType()) && tableField.getFieldType().equalsIgnoreCase("DECIMAL")) { + tableField.setAccuracy(Integer.valueOf(resultSet.getString("DECIMAL_DIGITS"))); + } + return tableField; + } + + @Override + public String checkStatus(DatasourceRequest datasourceRequest) throws Exception { + try (Connection con = getConnection(datasourceRequest)) { + List tables = new ArrayList<>(); + List tableNames = new ArrayList<>(); + ResultSet resultSet = con.getMetaData().getColumns(null, "%", "%", "%"); + while (resultSet.next()) { + String tableName = resultSet.getString("TABLE_NAME"); + if(!tableNames.contains(tableName)){ + tableNames.add(tableName); + TableDesc tableDesc = new TableDesc(); + tableDesc.setName(tableName); + tables.add(tableDesc); + } + } + } catch (Exception e) { + DataEaseException.throwException(e.getMessage()); + } + return "Success"; + } + + +} diff --git a/extensions/dataease-extensions-datasource/kylin/kylin-backend/src/main/java/io/dataease/plugins/datasource/kylin/query/KylinConstants.java b/extensions/dataease-extensions-datasource/kylin/kylin-backend/src/main/java/io/dataease/plugins/datasource/kylin/query/KylinConstants.java new file mode 100644 index 0000000000..51ab017a64 --- /dev/null +++ b/extensions/dataease-extensions-datasource/kylin/kylin-backend/src/main/java/io/dataease/plugins/datasource/kylin/query/KylinConstants.java @@ -0,0 +1,38 @@ +package io.dataease.plugins.datasource.kylin.query; + +import io.dataease.plugins.common.constants.datasource.SQLConstants; + + +public class KylinConstants extends SQLConstants { + + public static final String KEYWORD_TABLE = "%s" ; + + public static final String KEYWORD_FIX = "%s." + "%s"; + + + public static final String CAST = "CAST(%s AS %s)"; + + public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss"; + + public static final String DEFAULT_DATE_TYPE = "TIMESTAMP"; + + public static final String DEFAULT_INT_FORMAT = "BIGINT"; + + public static final String DEFAULT_FLOAT_FORMAT = "DOUBLE"; + + public static final String WHERE_VALUE_NULL = "(NULL,'')"; + + public static final String WHERE_VALUE_VALUE = "'%s'"; + + public static final String AGG_COUNT = "COUNT(*)"; + + public static final String AGG_FIELD = "%s(%s)"; + + public static final String WHERE_BETWEEN = "'%s' AND '%s'"; + + public static final String BRACKETS = "(%s)"; + + public static final String NAME = "pg"; + + +} diff --git a/extensions/dataease-extensions-datasource/kylin/kylin-backend/src/main/java/io/dataease/plugins/datasource/kylin/query/KylinQueryProvider.java b/extensions/dataease-extensions-datasource/kylin/kylin-backend/src/main/java/io/dataease/plugins/datasource/kylin/query/KylinQueryProvider.java new file mode 100644 index 0000000000..d7b455cb0d --- /dev/null +++ b/extensions/dataease-extensions-datasource/kylin/kylin-backend/src/main/java/io/dataease/plugins/datasource/kylin/query/KylinQueryProvider.java @@ -0,0 +1,1256 @@ +package io.dataease.plugins.datasource.kylin.query; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.gson.Gson; +import io.dataease.plugins.common.base.domain.ChartViewWithBLOBs; +import io.dataease.plugins.common.base.domain.DatasetTableField; +import io.dataease.plugins.common.base.domain.DatasetTableFieldExample; +import io.dataease.plugins.common.base.domain.Datasource; +import io.dataease.plugins.common.base.mapper.DatasetTableFieldMapper; +import io.dataease.plugins.common.constants.DeTypeConstants; +import io.dataease.plugins.common.constants.datasource.SQLConstants; +import io.dataease.plugins.common.constants.datasource.SqlServerSQLConstants; +import io.dataease.plugins.common.dto.chart.ChartCustomFilterItemDTO; +import io.dataease.plugins.common.dto.chart.ChartFieldCustomFilterDTO; +import io.dataease.plugins.common.dto.chart.ChartViewFieldDTO; +import io.dataease.plugins.common.dto.datasource.DeSortField; +import io.dataease.plugins.common.dto.sqlObj.SQLObj; +import io.dataease.plugins.common.request.chart.ChartExtFilterRequest; +import io.dataease.plugins.common.request.permission.DataSetRowPermissionsTreeDTO; +import io.dataease.plugins.common.request.permission.DatasetRowPermissionsTreeItem; +import io.dataease.plugins.datasource.entity.Dateformat; +import io.dataease.plugins.datasource.entity.JdbcConfiguration; +import io.dataease.plugins.datasource.query.QueryProvider; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.ObjectUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Component; +import org.stringtemplate.v4.ST; +import org.stringtemplate.v4.STGroup; +import org.stringtemplate.v4.STGroupFile; + +import javax.annotation.Resource; +import java.text.MessageFormat; +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +import static io.dataease.plugins.common.constants.datasource.SQLConstants.TABLE_ALIAS_PREFIX; + + +@Component() +public class KylinQueryProvider extends QueryProvider { + @Resource + private DatasetTableFieldMapper datasetTableFieldMapper; + + private static final Gson json = new Gson(); + + @Override + public Integer transFieldType(String field) { + field = field.contains("(") ? field.split("\\(")[0] : field; + field = field.toUpperCase(); + switch (field) { + case "DATE": + case "DATETIME": + case "TIMESTAMP": + case "TIME": + return DeTypeConstants.DE_TIME;// 时间 + case "TINYINT": + case "SMALLINT": + case "INT": + case "BIGINT": + case "INTEGER": + return DeTypeConstants.DE_INT;// 整型 + case "FLOAT": + case "DOUBLE": + case "DECIMAL": + case "NUMERIC": + return DeTypeConstants.DE_FLOAT;// 浮点 + case "BOOLEAN": + return DeTypeConstants.DE_BOOL;// 布尔 + case "BINARY": + return DeTypeConstants.DE_BINARY;// 二进制 + default: + return DeTypeConstants.DE_STRING; + } + } + + @Override + public String createSQLPreview(String sql, String orderBy) { + return "SELECT * FROM (" + sqlFix(sql) + ") AS DE_TMP " + " LIMIT 1000"; + } + + @Override + public String createQuerySQL(String table, List fields, boolean isGroup, Datasource ds, List fieldCustomFilter, List rowPermissionsTree) { + return createQuerySQL(table, fields, isGroup, ds, fieldCustomFilter, rowPermissionsTree, null); + } + + @Override + public String createQuerySQL(String table, List fields, boolean isGroup, Datasource ds, List fieldCustomFilter, List rowPermissionsTree, List sortFields) { + SQLObj tableObj = SQLObj.builder() + .tableName((table.startsWith("(") && table.endsWith(")")) ? table : String.format(KylinConstants.KEYWORD_TABLE, table)) + .tableAlias(String.format(TABLE_ALIAS_PREFIX, 0)) + .build(); + List xFields = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(fields)) { + for (int i = 0; i < fields.size(); i++) { + DatasetTableField f = fields.get(i); + String originField; + if (ObjectUtils.isNotEmpty(f.getExtField()) && f.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originField = calcFieldRegex(f.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(f.getExtField()) && f.getExtField() == 1) { + originField = String.format(KylinConstants.KEYWORD_FIX, tableObj.getTableAlias(), f.getOriginName()); + } else { + originField = String.format(KylinConstants.KEYWORD_FIX, tableObj.getTableAlias(), f.getOriginName()); + } + String fieldAlias = String.format(SQLConstants.FIELD_ALIAS_X_PREFIX, i); + String fieldName = ""; + // 处理横轴字段 + if (f.getDeExtractType() == DeTypeConstants.DE_TIME) { +// if (f.getDeType() == DeTypeConstants.DE_INT || f.getDeType() == DeTypeConstants.DE_FLOAT) { +// fieldName = String.format(KylinConstants.UNIX_TIMESTAMP, originField); +// } else { +// fieldName = originField; +// } + fieldName = originField; + } else if (f.getDeExtractType() == DeTypeConstants.DE_STRING) { + if (f.getDeType() == DeTypeConstants.DE_INT) { + fieldName = String.format(KylinConstants.CAST, originField, KylinConstants.DEFAULT_INT_FORMAT); + } else if (f.getDeType() == DeTypeConstants.DE_FLOAT) { + fieldName = String.format(KylinConstants.CAST, originField, KylinConstants.DEFAULT_FLOAT_FORMAT); + } else if (f.getDeType() == DeTypeConstants.DE_TIME) { + fieldName = String.format(KylinConstants.CAST, originField, KylinConstants.DEFAULT_DATE_TYPE); +// fieldName = String.format(KylinConstants.date_parse, originField, StringUtils.isNotEmpty(f.getDateFormat()) ? f.getDateFormat() : KylinConstants.DEFAULT_DATE_FORMAT); + } else { + fieldName = originField; + } + } else { + fieldName = originField; +// if (f.getDeType() == DeTypeConstants.DE_TIME) { +// fieldName = String.format(KylinConstants.FORMAT_DATETIME, String.format(KylinConstants.FROM_UNIXTIME, originField + "/1000"), KylinConstants.DEFAULT_DATE_FORMAT); +// } else if (f.getDeType() == DeTypeConstants.DE_INT) { +// fieldName = String.format(KylinConstants.CAST, originField, KylinConstants.DEFAULT_INT_FORMAT); +// } else { +// fieldName = originField; +// } + } + xFields.add(SQLObj.builder() + .fieldName(fieldName) + .fieldAlias(fieldAlias) + .build()); + } + } + + STGroup stg = new STGroupFile(SQLConstants.SQL_TEMPLATE); + ST st_sql = stg.getInstanceOf("previewSql"); + st_sql.add("isGroup", isGroup); + if (CollectionUtils.isNotEmpty(xFields)) st_sql.add("groups", xFields); + if (ObjectUtils.isNotEmpty(tableObj)) st_sql.add("table", tableObj); + String customWheres = transCustomFilterList(tableObj, fieldCustomFilter); + // row permissions tree + String whereTrees = transFilterTrees(tableObj, rowPermissionsTree); + List wheres = new ArrayList<>(); + if (customWheres != null) wheres.add(customWheres); + if (whereTrees != null) wheres.add(whereTrees); + if (CollectionUtils.isNotEmpty(wheres)) st_sql.add("filters", wheres); + + List xOrders = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(sortFields)) { + int step = fields.size(); + for (int i = step; i < (step + sortFields.size()); i++) { + DeSortField deSortField = sortFields.get(i - step); + SQLObj order = buildSortField(deSortField, tableObj, i); + xOrders.add(order); + } + } + if (ObjectUtils.isNotEmpty(xOrders)) { + st_sql.add("orders", xOrders); + } + + return st_sql.render(); + } + + private SQLObj buildSortField(DeSortField f, SQLObj tableObj, int i) { + String originField; + if (ObjectUtils.isNotEmpty(f.getExtField()) && f.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originField = calcFieldRegex(f.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(f.getExtField()) && f.getExtField() == 1) { + originField = String.format(KylinConstants.KEYWORD_FIX, tableObj.getTableAlias(), f.getOriginName()); + } else { + originField = String.format(KylinConstants.KEYWORD_FIX, tableObj.getTableAlias(), f.getOriginName()); + } + String fieldAlias = String.format(SQLConstants.FIELD_ALIAS_X_PREFIX, i); + String fieldName = ""; + // 处理横轴字段 + if (f.getDeExtractType() == DeTypeConstants.DE_TIME) { + if (f.getDeType() == DeTypeConstants.DE_INT || f.getDeType() == DeTypeConstants.DE_FLOAT) { + fieldName = String.format(KylinConstants.CAST, originField, KylinConstants.DEFAULT_INT_FORMAT); + } else { + fieldName = originField; + } + } else if (f.getDeExtractType() == DeTypeConstants.DE_STRING) { + if (f.getDeType() == DeTypeConstants.DE_INT) { + fieldName = String.format(KylinConstants.CAST, originField, KylinConstants.DEFAULT_INT_FORMAT); + } else if (f.getDeType() == DeTypeConstants.DE_FLOAT) { + fieldName = String.format(KylinConstants.CAST, originField, KylinConstants.DEFAULT_FLOAT_FORMAT); + } else if (f.getDeType() == DeTypeConstants.DE_TIME) { + fieldName = String.format(KylinConstants.CAST, originField, KylinConstants.DEFAULT_DATE_TYPE); + } else { + fieldName = originField; + } + } else { + if (f.getDeType() == DeTypeConstants.DE_TIME) { + fieldName = String.format(KylinConstants.CAST, originField, KylinConstants.DEFAULT_DATE_TYPE); + } else if (f.getDeType() == DeTypeConstants.DE_INT) { + fieldName = String.format(KylinConstants.CAST, originField, KylinConstants.DEFAULT_INT_FORMAT); + } else { + fieldName = originField; + } + } + SQLObj result = SQLObj.builder().orderField(originField).orderAlias(originField).orderDirection(f.getOrderDirection()).build(); + return result; + } + + @Override + public String createQuerySQLAsTmp(String sql, List fields, boolean isGroup, List fieldCustomFilter, List rowPermissionsTree, List sortFields) { + return createQuerySQL("(" + sqlFix(sql) + ")", fields, isGroup, null, fieldCustomFilter, rowPermissionsTree, sortFields); + } + + @Override + public String createQuerySQLAsTmp(String sql, List fields, boolean isGroup, List fieldCustomFilter, List rowPermissionsTree) { + return createQuerySQL("(" + sqlFix(sql) + ")", fields, isGroup, null, fieldCustomFilter, rowPermissionsTree); + } + + @Override + public String createQueryTableWithPage(String table, List fields, Integer page, Integer pageSize, Integer realSize, boolean isGroup, Datasource ds, List fieldCustomFilter, List rowPermissionsTree) { + return createQuerySQL(table, fields, isGroup, ds, fieldCustomFilter, rowPermissionsTree) + " LIMIT " + realSize; + } + + @Override + public String createQuerySQLWithPage(String sql, List fields, Integer page, Integer pageSize, Integer realSize, boolean isGroup, List fieldCustomFilter, List rowPermissionsTree) { + return createQuerySQLAsTmp(sql, fields, isGroup, fieldCustomFilter, rowPermissionsTree) + " LIMIT " + realSize; + } + + @Override + public String createQueryTableWithLimit(String table, List fields, Integer limit, boolean isGroup, Datasource ds, List fieldCustomFilter, List rowPermissionsTree) { + return createQuerySQL(table, fields, isGroup, ds, fieldCustomFilter, rowPermissionsTree) + " LIMIT " + limit; + } + + @Override + public String createQuerySqlWithLimit(String sql, List fields, Integer limit, boolean isGroup, List fieldCustomFilter, List rowPermissionsTree) { + return createQuerySQLAsTmp(sql, fields, isGroup, fieldCustomFilter, rowPermissionsTree) + " LIMIT " + limit; + } + + @Override + public String getSQL(String table, List xAxis, List yAxis, List fieldCustomFilter, List rowPermissionsTree, List extFilterRequestList, Datasource ds, ChartViewWithBLOBs view) { + SQLObj tableObj = SQLObj.builder() + .tableName((table.startsWith("(") && table.endsWith(")")) ? table : String.format(KylinConstants.KEYWORD_TABLE, table)) + .tableAlias(String.format(TABLE_ALIAS_PREFIX, 0)) + .build(); + setSchema(tableObj, ds); + List xFields = new ArrayList<>(); + List xOrders = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(xAxis)) { + for (int i = 0; i < xAxis.size(); i++) { + ChartViewFieldDTO x = xAxis.get(i); + String originField; + if (ObjectUtils.isNotEmpty(x.getExtField()) && x.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originField = calcFieldRegex(x.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(x.getExtField()) && x.getExtField() == 1) { + originField = String.format(KylinConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getOriginName()); + } else { + originField = String.format(KylinConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getOriginName()); + } + String fieldAlias = String.format(SQLConstants.FIELD_ALIAS_X_PREFIX, i); + // 处理横轴字段 + xFields.add(getXFields(x, originField, fieldAlias)); + // 处理横轴排序 + if (StringUtils.isNotEmpty(x.getSort()) && !StringUtils.equalsIgnoreCase(x.getSort(), "none")) { + xOrders.add(SQLObj.builder() + .orderField(originField) + .orderAlias(fieldAlias) + .orderDirection(x.getSort()) + .build()); + } + } + } + List yFields = new ArrayList<>(); + List yWheres = new ArrayList<>(); + List yOrders = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(yAxis)) { + for (int i = 0; i < yAxis.size(); i++) { + ChartViewFieldDTO y = yAxis.get(i); + String originField; + if (ObjectUtils.isNotEmpty(y.getExtField()) && y.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originField = calcFieldRegex(y.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(y.getExtField()) && y.getExtField() == 1) { + originField = String.format(KylinConstants.KEYWORD_FIX, tableObj.getTableAlias(), y.getOriginName()); + } else { + originField = String.format(KylinConstants.KEYWORD_FIX, tableObj.getTableAlias(), y.getOriginName()); + } + String fieldAlias = String.format(SQLConstants.FIELD_ALIAS_Y_PREFIX, i); + // 处理纵轴字段 + yFields.add(getYFields(y, originField, fieldAlias)); + // 处理纵轴过滤 + yWheres.add(getYWheres(y, originField, fieldAlias)); + // 处理纵轴排序 + if (StringUtils.isNotEmpty(y.getSort()) && !StringUtils.equalsIgnoreCase(y.getSort(), "none")) { + yOrders.add(SQLObj.builder() + .orderField(originField) + .orderAlias(fieldAlias) + .orderDirection(y.getSort()) + .build()); + } + } + } + // 处理视图中字段过滤 + String customWheres = transCustomFilterList(tableObj, fieldCustomFilter); + // 处理仪表板字段过滤 + String extWheres = transExtFilterList(tableObj, extFilterRequestList); + // row permissions tree + String whereTrees = transFilterTrees(tableObj, rowPermissionsTree); + // 构建sql所有参数 + List fields = new ArrayList<>(); + fields.addAll(xFields); + fields.addAll(yFields); + List wheres = new ArrayList<>(); + if (customWheres != null) wheres.add(customWheres); + if (extWheres != null) wheres.add(extWheres); + if (whereTrees != null) wheres.add(whereTrees); + List groups = new ArrayList<>(); + groups.addAll(xFields); + // 外层再次套sql + List orders = new ArrayList<>(); + orders.addAll(xOrders); + orders.addAll(yOrders); + List aggWheres = new ArrayList<>(); + aggWheres.addAll(yWheres.stream().filter(ObjectUtils::isNotEmpty).collect(Collectors.toList())); + + STGroup stg = new STGroupFile(SQLConstants.SQL_TEMPLATE); + ST st_sql = stg.getInstanceOf("querySql"); + if (CollectionUtils.isNotEmpty(xFields)) st_sql.add("groups", xFields); + if (CollectionUtils.isNotEmpty(yFields)) st_sql.add("aggregators", yFields); + if (CollectionUtils.isNotEmpty(wheres)) st_sql.add("filters", wheres); + if (ObjectUtils.isNotEmpty(tableObj)) st_sql.add("table", tableObj); + String sql = st_sql.render(); + + ST st = stg.getInstanceOf("querySql"); + SQLObj tableSQL = SQLObj.builder() + .tableName(String.format(KylinConstants.BRACKETS, sql)) + .tableAlias(String.format(TABLE_ALIAS_PREFIX, 1)) + .build(); + if (CollectionUtils.isNotEmpty(aggWheres)) st.add("filters", aggWheres); + if (CollectionUtils.isNotEmpty(orders)) st.add("orders", orders); + if (ObjectUtils.isNotEmpty(tableSQL)) st.add("table", tableSQL); + return sqlLimit(st.render(), view); + } + + @Override + public String getSQLTableInfo(String table, List xAxis, List fieldCustomFilter, List rowPermissionsTree, List extFilterRequestList, Datasource ds, ChartViewWithBLOBs view) { + SQLObj tableObj = SQLObj.builder() + .tableName((table.startsWith("(") && table.endsWith(")")) ? table : String.format(KylinConstants.KEYWORD_TABLE, table)) + .tableAlias(String.format(TABLE_ALIAS_PREFIX, 0)) + .build(); + setSchema(tableObj, ds); + List xFields = new ArrayList<>(); + List xOrders = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(xAxis)) { + for (int i = 0; i < xAxis.size(); i++) { + ChartViewFieldDTO x = xAxis.get(i); + String originField; + if (ObjectUtils.isNotEmpty(x.getExtField()) && x.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originField = calcFieldRegex(x.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(x.getExtField()) && x.getExtField() == 1) { + originField = String.format(KylinConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getOriginName()); + } else { + if (x.getDeType() == 2 || x.getDeType() == 3) { + originField = String.format(KylinConstants.CAST, String.format(KylinConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getOriginName()), KylinConstants.DEFAULT_FLOAT_FORMAT); + } else { + originField = String.format(KylinConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getOriginName()); + } + } + String fieldAlias = String.format(SQLConstants.FIELD_ALIAS_X_PREFIX, i); + // 处理横轴字段 + xFields.add(getXFields(x, originField, fieldAlias)); + // 处理横轴排序 + if (StringUtils.isNotEmpty(x.getSort()) && !StringUtils.equalsIgnoreCase(x.getSort(), "none")) { + xOrders.add(SQLObj.builder() + .orderField(originField) + .orderAlias(fieldAlias) + .orderDirection(x.getSort()) + .build()); + } + } + } + // 处理视图中字段过滤 + String customWheres = transCustomFilterList(tableObj, fieldCustomFilter); + // 处理仪表板字段过滤 + String extWheres = transExtFilterList(tableObj, extFilterRequestList); + // row permissions tree + String whereTrees = transFilterTrees(tableObj, rowPermissionsTree); + // 构建sql所有参数 + List fields = new ArrayList<>(); + fields.addAll(xFields); + List wheres = new ArrayList<>(); + if (customWheres != null) wheres.add(customWheres); + if (extWheres != null) wheres.add(extWheres); + if (whereTrees != null) wheres.add(whereTrees); + List groups = new ArrayList<>(); + groups.addAll(xFields); + // 外层再次套sql + List orders = new ArrayList<>(); + orders.addAll(xOrders); + + STGroup stg = new STGroupFile(SQLConstants.SQL_TEMPLATE); + ST st_sql = stg.getInstanceOf("previewSql"); + st_sql.add("isGroup", false); + if (CollectionUtils.isNotEmpty(xFields)) st_sql.add("groups", xFields); + if (CollectionUtils.isNotEmpty(wheres)) st_sql.add("filters", wheres); + if (ObjectUtils.isNotEmpty(tableObj)) st_sql.add("table", tableObj); + String sql = st_sql.render(); + + ST st = stg.getInstanceOf("previewSql"); + st.add("isGroup", false); + SQLObj tableSQL = SQLObj.builder() + .tableName(String.format(KylinConstants.BRACKETS, sql)) + .tableAlias(String.format(TABLE_ALIAS_PREFIX, 1)) + .build(); + if (CollectionUtils.isNotEmpty(orders)) st.add("orders", orders); + if (ObjectUtils.isNotEmpty(tableSQL)) st.add("table", tableSQL); + return sqlLimit(st.render(), view); + } + + @Override + public String getSQLAsTmpTableInfo(String sql, List xAxis, List fieldCustomFilter, List rowPermissionsTree, List extFilterRequestList, Datasource ds, ChartViewWithBLOBs view) { + return getSQLTableInfo("(" + sqlFix(sql) + ")", xAxis, fieldCustomFilter, rowPermissionsTree, extFilterRequestList, ds, view); + } + + + @Override + public String getSQLAsTmp(String sql, List xAxis, List yAxis, List fieldCustomFilter, List rowPermissionsTree, List extFilterRequestList, ChartViewWithBLOBs view) { + return getSQL("(" + sqlFix(sql) + ")", xAxis, yAxis, fieldCustomFilter, rowPermissionsTree, extFilterRequestList, null, view); + } + + @Override + public String getSQLStack(String table, List xAxis, List yAxis, List fieldCustomFilter, List rowPermissionsTree, List extFilterRequestList, List extStack, Datasource ds, ChartViewWithBLOBs view) { + SQLObj tableObj = SQLObj.builder() + .tableName((table.startsWith("(") && table.endsWith(")")) ? table : String.format(KylinConstants.KEYWORD_TABLE, table)) + .tableAlias(String.format(TABLE_ALIAS_PREFIX, 0)) + .build(); + setSchema(tableObj, ds); + List xFields = new ArrayList<>(); + List xOrders = new ArrayList<>(); + List xList = new ArrayList<>(); + xList.addAll(xAxis); + xList.addAll(extStack); + if (CollectionUtils.isNotEmpty(xList)) { + for (int i = 0; i < xList.size(); i++) { + ChartViewFieldDTO x = xList.get(i); + String originField; + if (ObjectUtils.isNotEmpty(x.getExtField()) && x.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originField = calcFieldRegex(x.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(x.getExtField()) && x.getExtField() == 1) { + originField = String.format(KylinConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getOriginName()); + } else { + originField = String.format(KylinConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getOriginName()); + } + String fieldAlias = String.format(SQLConstants.FIELD_ALIAS_X_PREFIX, i); + // 处理横轴字段 + xFields.add(getXFields(x, originField, fieldAlias)); + // 处理横轴排序 + if (StringUtils.isNotEmpty(x.getSort()) && !StringUtils.equalsIgnoreCase(x.getSort(), "none")) { + xOrders.add(SQLObj.builder() + .orderField(originField) + .orderAlias(fieldAlias) + .orderDirection(x.getSort()) + .build()); + } + } + } + List yFields = new ArrayList<>(); + List yWheres = new ArrayList<>(); + List yOrders = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(yAxis)) { + for (int i = 0; i < yAxis.size(); i++) { + ChartViewFieldDTO y = yAxis.get(i); + String originField; + if (ObjectUtils.isNotEmpty(y.getExtField()) && y.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originField = calcFieldRegex(y.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(y.getExtField()) && y.getExtField() == 1) { + originField = String.format(KylinConstants.KEYWORD_FIX, tableObj.getTableAlias(), y.getOriginName()); + } else { + originField = String.format(KylinConstants.KEYWORD_FIX, tableObj.getTableAlias(), y.getOriginName()); + } + String fieldAlias = String.format(SQLConstants.FIELD_ALIAS_Y_PREFIX, i); + // 处理纵轴字段 + yFields.add(getYFields(y, originField, fieldAlias)); + // 处理纵轴过滤 + yWheres.add(getYWheres(y, originField, fieldAlias)); + // 处理纵轴排序 + if (StringUtils.isNotEmpty(y.getSort()) && !StringUtils.equalsIgnoreCase(y.getSort(), "none")) { + yOrders.add(SQLObj.builder() + .orderField(originField) + .orderAlias(fieldAlias) + .orderDirection(y.getSort()) + .build()); + } + } + } + // 处理视图中字段过滤 + String customWheres = transCustomFilterList(tableObj, fieldCustomFilter); + // 处理仪表板字段过滤 + String extWheres = transExtFilterList(tableObj, extFilterRequestList); + // row permissions tree + String whereTrees = transFilterTrees(tableObj, rowPermissionsTree); + // 构建sql所有参数 + List fields = new ArrayList<>(); + fields.addAll(xFields); + fields.addAll(yFields); + List wheres = new ArrayList<>(); + if (customWheres != null) wheres.add(customWheres); + if (extWheres != null) wheres.add(extWheres); + if (whereTrees != null) wheres.add(whereTrees); + List groups = new ArrayList<>(); + groups.addAll(xFields); + // 外层再次套sql + List orders = new ArrayList<>(); + orders.addAll(xOrders); + orders.addAll(yOrders); + List aggWheres = new ArrayList<>(); + aggWheres.addAll(yWheres.stream().filter(ObjectUtils::isNotEmpty).collect(Collectors.toList())); + + STGroup stg = new STGroupFile(SQLConstants.SQL_TEMPLATE); + ST st_sql = stg.getInstanceOf("querySql"); + if (CollectionUtils.isNotEmpty(xFields)) st_sql.add("groups", xFields); + if (CollectionUtils.isNotEmpty(yFields)) st_sql.add("aggregators", yFields); + if (CollectionUtils.isNotEmpty(wheres)) st_sql.add("filters", wheres); + if (ObjectUtils.isNotEmpty(tableObj)) st_sql.add("table", tableObj); + String sql = st_sql.render(); + + ST st = stg.getInstanceOf("querySql"); + SQLObj tableSQL = SQLObj.builder() + .tableName(String.format(KylinConstants.BRACKETS, sql)) + .tableAlias(String.format(TABLE_ALIAS_PREFIX, 1)) + .build(); + if (CollectionUtils.isNotEmpty(aggWheres)) st.add("filters", aggWheres); + if (CollectionUtils.isNotEmpty(orders)) st.add("orders", orders); + if (ObjectUtils.isNotEmpty(tableSQL)) st.add("table", tableSQL); + return sqlLimit(st.render(), view); + } + + @Override + public String getSQLAsTmpStack(String table, List xAxis, List yAxis, List fieldCustomFilter, List rowPermissionsTree, List extFilterRequestList, List extStack, ChartViewWithBLOBs view) { + return getSQLStack("(" + sqlFix(table) + ")", xAxis, yAxis, fieldCustomFilter, rowPermissionsTree, extFilterRequestList, extStack, null, view); + } + + @Override + public String getSQLScatter(String table, List xAxis, List yAxis, List fieldCustomFilter, List rowPermissionsTree, List extFilterRequestList, List extBubble, Datasource ds, ChartViewWithBLOBs view) { + SQLObj tableObj = SQLObj.builder() + .tableName((table.startsWith("(") && table.endsWith(")")) ? table : String.format(KylinConstants.KEYWORD_TABLE, table)) + .tableAlias(String.format(TABLE_ALIAS_PREFIX, 0)) + .build(); + setSchema(tableObj, ds); + List xFields = new ArrayList<>(); + List xOrders = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(xAxis)) { + for (int i = 0; i < xAxis.size(); i++) { + ChartViewFieldDTO x = xAxis.get(i); + String originField; + if (ObjectUtils.isNotEmpty(x.getExtField()) && x.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originField = calcFieldRegex(x.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(x.getExtField()) && x.getExtField() == 1) { + originField = String.format(KylinConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getOriginName()); + } else { + originField = String.format(KylinConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getOriginName()); + } + String fieldAlias = String.format(SQLConstants.FIELD_ALIAS_X_PREFIX, i); + // 处理横轴字段 + xFields.add(getXFields(x, originField, fieldAlias)); + // 处理横轴排序 + if (StringUtils.isNotEmpty(x.getSort()) && !StringUtils.equalsIgnoreCase(x.getSort(), "none")) { + xOrders.add(SQLObj.builder() + .orderField(originField) + .orderAlias(fieldAlias) + .orderDirection(x.getSort()) + .build()); + } + } + } + List yFields = new ArrayList<>(); + List yWheres = new ArrayList<>(); + List yOrders = new ArrayList<>(); + List yList = new ArrayList<>(); + yList.addAll(yAxis); + yList.addAll(extBubble); + if (CollectionUtils.isNotEmpty(yList)) { + for (int i = 0; i < yList.size(); i++) { + ChartViewFieldDTO y = yList.get(i); + String originField; + if (ObjectUtils.isNotEmpty(y.getExtField()) && y.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originField = calcFieldRegex(y.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(y.getExtField()) && y.getExtField() == 1) { + originField = String.format(KylinConstants.KEYWORD_FIX, tableObj.getTableAlias(), y.getOriginName()); + } else { + originField = String.format(KylinConstants.KEYWORD_FIX, tableObj.getTableAlias(), y.getOriginName()); + } + String fieldAlias = String.format(SQLConstants.FIELD_ALIAS_Y_PREFIX, i); + // 处理纵轴字段 + yFields.add(getYFields(y, originField, fieldAlias)); + // 处理纵轴过滤 + yWheres.add(getYWheres(y, originField, fieldAlias)); + // 处理纵轴排序 + if (StringUtils.isNotEmpty(y.getSort()) && !StringUtils.equalsIgnoreCase(y.getSort(), "none")) { + yOrders.add(SQLObj.builder() + .orderField(originField) + .orderAlias(fieldAlias) + .orderDirection(y.getSort()) + .build()); + } + } + } + // 处理视图中字段过滤 + String customWheres = transCustomFilterList(tableObj, fieldCustomFilter); + // 处理仪表板字段过滤 + String extWheres = transExtFilterList(tableObj, extFilterRequestList); + // row permissions tree + String whereTrees = transFilterTrees(tableObj, rowPermissionsTree); + // 构建sql所有参数 + List fields = new ArrayList<>(); + fields.addAll(xFields); + fields.addAll(yFields); + List wheres = new ArrayList<>(); + if (customWheres != null) wheres.add(customWheres); + if (extWheres != null) wheres.add(extWheres); + if (whereTrees != null) wheres.add(whereTrees); + List groups = new ArrayList<>(); + groups.addAll(xFields); + // 外层再次套sql + List orders = new ArrayList<>(); + orders.addAll(xOrders); + orders.addAll(yOrders); + List aggWheres = new ArrayList<>(); + aggWheres.addAll(yWheres.stream().filter(ObjectUtils::isNotEmpty).collect(Collectors.toList())); + + STGroup stg = new STGroupFile(SQLConstants.SQL_TEMPLATE); + ST st_sql = stg.getInstanceOf("querySql"); + if (CollectionUtils.isNotEmpty(xFields)) st_sql.add("groups", xFields); + if (CollectionUtils.isNotEmpty(yFields)) st_sql.add("aggregators", yFields); + if (CollectionUtils.isNotEmpty(wheres)) st_sql.add("filters", wheres); + if (ObjectUtils.isNotEmpty(tableObj)) st_sql.add("table", tableObj); + String sql = st_sql.render(); + + ST st = stg.getInstanceOf("querySql"); + SQLObj tableSQL = SQLObj.builder() + .tableName(String.format(KylinConstants.BRACKETS, sql)) + .tableAlias(String.format(TABLE_ALIAS_PREFIX, 1)) + .build(); + if (CollectionUtils.isNotEmpty(aggWheres)) st.add("filters", aggWheres); + if (CollectionUtils.isNotEmpty(orders)) st.add("orders", orders); + if (ObjectUtils.isNotEmpty(tableSQL)) st.add("table", tableSQL); + return sqlLimit(st.render(), view); + } + + @Override + public String getSQLAsTmpScatter(String table, List xAxis, List yAxis, List fieldCustomFilter, List rowPermissionsTree, List extFilterRequestList, List extBubble, ChartViewWithBLOBs view) { + return getSQLScatter("(" + sqlFix(table) + ")", xAxis, yAxis, fieldCustomFilter, rowPermissionsTree, extFilterRequestList, extBubble, null, view); + } + + @Override + public String searchTable(String table) { + return "SELECT table_name FROM information_schema.TABLES WHERE table_name ='" + table + "'"; + } + + @Override + public String getSQLSummary(String table, List yAxis, List fieldCustomFilter, List rowPermissionsTree, List extFilterRequestList, ChartViewWithBLOBs view, Datasource ds) { + // 字段汇总 排序等 + SQLObj tableObj = SQLObj.builder() + .tableName((table.startsWith("(") && table.endsWith(")")) ? table : String.format(KylinConstants.KEYWORD_TABLE, table)) + .tableAlias(String.format(TABLE_ALIAS_PREFIX, 0)) + .build(); + setSchema(tableObj, ds); + List yFields = new ArrayList<>(); + List yWheres = new ArrayList<>(); + List yOrders = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(yAxis)) { + for (int i = 0; i < yAxis.size(); i++) { + ChartViewFieldDTO y = yAxis.get(i); + String originField; + if (ObjectUtils.isNotEmpty(y.getExtField()) && y.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originField = calcFieldRegex(y.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(y.getExtField()) && y.getExtField() == 1) { + originField = String.format(KylinConstants.KEYWORD_FIX, tableObj.getTableAlias(), y.getOriginName()); + } else { + originField = String.format(KylinConstants.KEYWORD_FIX, tableObj.getTableAlias(), y.getOriginName()); + } + String fieldAlias = String.format(SQLConstants.FIELD_ALIAS_Y_PREFIX, i); + // 处理纵轴字段 + yFields.add(getYFields(y, originField, fieldAlias)); + // 处理纵轴过滤 + yWheres.add(getYWheres(y, originField, fieldAlias)); + // 处理纵轴排序 + if (StringUtils.isNotEmpty(y.getSort()) && !StringUtils.equalsIgnoreCase(y.getSort(), "none")) { + yOrders.add(SQLObj.builder() + .orderField(originField) + .orderAlias(fieldAlias) + .orderDirection(y.getSort()) + .build()); + } + } + } + // 处理视图中字段过滤 + String customWheres = transCustomFilterList(tableObj, fieldCustomFilter); + // 处理仪表板字段过滤 + String extWheres = transExtFilterList(tableObj, extFilterRequestList); + // row permissions tree + String whereTrees = transFilterTrees(tableObj, rowPermissionsTree); + // 构建sql所有参数 + List fields = new ArrayList<>(); + fields.addAll(yFields); + List wheres = new ArrayList<>(); + if (customWheres != null) wheres.add(customWheres); + if (extWheres != null) wheres.add(extWheres); + if (whereTrees != null) wheres.add(whereTrees); + List groups = new ArrayList<>(); + // 外层再次套sql + List orders = new ArrayList<>(); + orders.addAll(yOrders); + List aggWheres = new ArrayList<>(); + aggWheres.addAll(yWheres.stream().filter(ObjectUtils::isNotEmpty).collect(Collectors.toList())); + + STGroup stg = new STGroupFile(SQLConstants.SQL_TEMPLATE); + ST st_sql = stg.getInstanceOf("querySql"); + if (CollectionUtils.isNotEmpty(yFields)) st_sql.add("aggregators", yFields); + if (CollectionUtils.isNotEmpty(wheres)) st_sql.add("filters", wheres); + if (ObjectUtils.isNotEmpty(tableObj)) st_sql.add("table", tableObj); + String sql = st_sql.render(); + + ST st = stg.getInstanceOf("querySql"); + SQLObj tableSQL = SQLObj.builder() + .tableName(String.format(KylinConstants.BRACKETS, sql)) + .tableAlias(String.format(TABLE_ALIAS_PREFIX, 1)) + .build(); + if (CollectionUtils.isNotEmpty(aggWheres)) st.add("filters", aggWheres); + if (CollectionUtils.isNotEmpty(orders)) st.add("orders", orders); + if (ObjectUtils.isNotEmpty(tableSQL)) st.add("table", tableSQL); + return sqlLimit(st.render(), view); + } + + @Override + public String getSQLSummaryAsTmp(String sql, List yAxis, List fieldCustomFilter, List rowPermissionsTree, List extFilterRequestList, ChartViewWithBLOBs view) { + return getSQLSummary("(" + sqlFix(sql) + ")", yAxis, fieldCustomFilter, rowPermissionsTree, extFilterRequestList, view, null); + } + + @Override + public String wrapSql(String sql) { + sql = sql.trim(); + if (sql.lastIndexOf(";") == (sql.length() - 1)) { + sql = sql.substring(0, sql.length() - 1); + } + String tmpSql = "SELECT * FROM (" + sql + ") AS tmp " + " LIMIT 0 "; + return tmpSql; + } + + @Override + public String createRawQuerySQL(String table, List fields, Datasource ds) { + String[] array = fields.stream().map(f -> { + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.append("\"").append(f.getOriginName()).append("\" AS ").append(f.getDataeaseName()); + return stringBuilder.toString(); + }).toArray(String[]::new); + if (ds != null) { + String schema = new Gson().fromJson(ds.getConfiguration(), JdbcConfiguration.class).getSchema(); + String tableWithSchema = String.format(SqlServerSQLConstants.KEYWORD_TABLE, schema) + "." + String.format(SqlServerSQLConstants.KEYWORD_TABLE, table); + return MessageFormat.format("SELECT {0} FROM {1} ", StringUtils.join(array, ","), tableWithSchema); + } else { + return MessageFormat.format("SELECT {0} FROM {1} ", StringUtils.join(array, ","), table); + } + } + + @Override + public String createRawQuerySQLAsTmp(String sql, List fields) { + return createRawQuerySQL(" (" + sqlFix(sql) + ") AS tmp ", fields, null); + } + + @Override + public String transTreeItem(SQLObj tableObj, DatasetRowPermissionsTreeItem item) { + String res = null; + DatasetTableField field = item.getField(); + if (ObjectUtils.isEmpty(field)) { + return null; + } + String whereName = ""; + String originName; + if (ObjectUtils.isNotEmpty(field.getExtField()) && field.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originName = calcFieldRegex(field.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(field.getExtField()) && field.getExtField() == 1) { + originName = String.format(KylinConstants.KEYWORD_FIX, tableObj.getTableAlias(), field.getOriginName()); + } else { + originName = String.format(KylinConstants.KEYWORD_FIX, tableObj.getTableAlias(), field.getOriginName()); + } + if (field.getDeType() == DeTypeConstants.DE_TIME) { + if (field.getDeExtractType() == DeTypeConstants.DE_STRING || field.getDeExtractType() == 5) { + whereName = String.format(KylinConstants.CAST, originName, KylinConstants.DEFAULT_DATE_TYPE); + } + if (field.getDeExtractType() == DeTypeConstants.DE_INT || field.getDeExtractType() == DeTypeConstants.DE_FLOAT || field.getDeExtractType() == 4) { + String cast = String.format(KylinConstants.CAST, originName, KylinConstants.DEFAULT_INT_FORMAT); + whereName = String.format(KylinConstants.CAST, originName, KylinConstants.DEFAULT_DATE_TYPE); + } + if (field.getDeExtractType() == DeTypeConstants.DE_STRING) { + whereName = originName; + } + } else if (field.getDeType() == DeTypeConstants.DE_INT || field.getDeType() == DeTypeConstants.DE_FLOAT) { + if (field.getDeExtractType() == DeTypeConstants.DE_STRING || field.getDeExtractType() == 5) { + whereName = String.format(KylinConstants.CAST, originName, KylinConstants.DEFAULT_FLOAT_FORMAT); + } + if (field.getDeExtractType() == DeTypeConstants.DE_TIME) { + whereName = String.format(KylinConstants.CAST, originName, KylinConstants.DEFAULT_DATE_TYPE); + } + if (field.getDeExtractType() == DeTypeConstants.DE_INT || field.getDeExtractType() == DeTypeConstants.DE_FLOAT || field.getDeExtractType() == 4) { + whereName = originName; + } + } else { + whereName = originName; + } + + if (StringUtils.equalsIgnoreCase(item.getFilterType(), "enum")) { + if (CollectionUtils.isNotEmpty(item.getEnumValue())) { + res = "(" + whereName + " IN ('" + String.join("','", item.getEnumValue()) + "'))"; + } + } else { + String value = item.getValue(); + String whereTerm = transMysqlFilterTerm(item.getTerm()); + String whereValue = ""; + + if (StringUtils.equalsIgnoreCase(item.getTerm(), "null")) { + whereValue = ""; + } else if (StringUtils.equalsIgnoreCase(item.getTerm(), "not_null")) { + whereValue = ""; + } else if (StringUtils.equalsIgnoreCase(item.getTerm(), "empty")) { + whereValue = "''"; + } else if (StringUtils.equalsIgnoreCase(item.getTerm(), "not_empty")) { + whereValue = "''"; + } else if (StringUtils.containsIgnoreCase(item.getTerm(), "in") || StringUtils.containsIgnoreCase(item.getTerm(), "not in")) { + whereValue = "('" + String.join("','", value.split(",")) + "')"; + } else if (StringUtils.containsIgnoreCase(item.getTerm(), "like")) { + whereValue = "'%" + value + "%'"; + } else { + whereValue = String.format(KylinConstants.WHERE_VALUE_VALUE, value); + } + SQLObj build = SQLObj.builder() + .whereField(whereName) + .whereTermAndValue(whereTerm + whereValue) + .build(); + res = build.getWhereField() + " " + build.getWhereTermAndValue(); + } + return res; + } + + @Override + public String convertTableToSql(String tableName, Datasource ds) { + String schema = new Gson().fromJson(ds.getConfiguration(), JdbcConfiguration.class).getSchema(); + schema = String.format(KylinConstants.KEYWORD_TABLE, schema); + return createSQLPreview("SELECT * FROM " + schema + "." + String.format(KylinConstants.KEYWORD_TABLE, tableName), null); + } + + public String transMysqlFilterTerm(String term) { + switch (term) { + case "eq": + return " = "; + case "not_eq": + return " <> "; + case "lt": + return " < "; + case "le": + return " <= "; + case "gt": + return " > "; + case "ge": + return " >= "; + case "in": + return " IN "; + case "not in": + return " NOT IN "; + case "like": + return " LIKE "; + case "not like": + return " NOT LIKE "; + case "null": + return " IS NULL "; + case "not_null": + return " IS NOT NULL "; + case "empty": + return " = "; + case "not_empty": + return " <> "; + case "between": + return " BETWEEN "; + default: + return ""; + } + } + + public String transCustomFilterList(SQLObj tableObj, List requestList) { + if (CollectionUtils.isEmpty(requestList)) { + return null; + } + List res = new ArrayList<>(); + for (ChartFieldCustomFilterDTO request : requestList) { + List list = new ArrayList<>(); + DatasetTableField field = request.getField(); + + if (ObjectUtils.isEmpty(field)) { + continue; + } + String whereName = ""; + String originName; + if (ObjectUtils.isNotEmpty(field.getExtField()) && field.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originName = calcFieldRegex(field.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(field.getExtField()) && field.getExtField() == 1) { + originName = String.format(KylinConstants.KEYWORD_FIX, tableObj.getTableAlias(), field.getOriginName()); + } else { + originName = String.format(KylinConstants.KEYWORD_FIX, tableObj.getTableAlias(), field.getOriginName()); + } + if (field.getDeType() == DeTypeConstants.DE_TIME) { + if (field.getDeExtractType() == DeTypeConstants.DE_STRING || field.getDeExtractType() == 5) { + whereName = String.format(KylinConstants.CAST, originName, KylinConstants.DEFAULT_DATE_TYPE); + } + if (field.getDeExtractType() == DeTypeConstants.DE_INT || field.getDeExtractType() == DeTypeConstants.DE_FLOAT || field.getDeExtractType() == DeTypeConstants.DE_BOOL) { + whereName = String.format(KylinConstants.CAST, originName, KylinConstants.DEFAULT_DATE_TYPE); + } + if (field.getDeExtractType() == DeTypeConstants.DE_STRING) { + whereName = originName; + } + } else if (field.getDeType() == DeTypeConstants.DE_INT || field.getDeType() == DeTypeConstants.DE_FLOAT) { + if (field.getDeExtractType() == DeTypeConstants.DE_STRING || field.getDeExtractType() == 5) { + whereName = String.format(KylinConstants.CAST, originName, KylinConstants.DEFAULT_FLOAT_FORMAT); + } + if (field.getDeExtractType() == DeTypeConstants.DE_TIME) { + whereName = String.format(KylinConstants.CAST, originName, KylinConstants.DEFAULT_INT_FORMAT); + } + if (field.getDeExtractType() == DeTypeConstants.DE_INT || field.getDeExtractType() == DeTypeConstants.DE_FLOAT || field.getDeExtractType() == 4) { + whereName = originName; + } + } else { + whereName = originName; + } + + if (StringUtils.equalsIgnoreCase(request.getFilterType(), "enum")) { + if (CollectionUtils.isNotEmpty(request.getEnumCheckField())) { + res.add("(" + whereName + " IN ('" + String.join("','", request.getEnumCheckField()) + "'))"); + } + } else { + List filter = request.getFilter(); + for (ChartCustomFilterItemDTO filterItemDTO : filter) { + String value = filterItemDTO.getValue(); + String whereTerm = transMysqlFilterTerm(filterItemDTO.getTerm()); + String whereValue = ""; + + if (StringUtils.equalsIgnoreCase(filterItemDTO.getTerm(), "null")) { + whereValue = ""; + } else if (StringUtils.equalsIgnoreCase(filterItemDTO.getTerm(), "not_null")) { + whereValue = ""; + } else if (StringUtils.equalsIgnoreCase(filterItemDTO.getTerm(), "empty")) { + whereValue = "''"; + } else if (StringUtils.equalsIgnoreCase(filterItemDTO.getTerm(), "not_empty")) { + whereValue = "''"; + } else if (StringUtils.containsIgnoreCase(filterItemDTO.getTerm(), "in") || StringUtils.containsIgnoreCase(filterItemDTO.getTerm(), "not in")) { + whereValue = "('" + String.join("','", value.split(",")) + "')"; + } else if (StringUtils.containsIgnoreCase(filterItemDTO.getTerm(), "like")) { + whereValue = "'%" + value + "%'"; + } else { + whereValue = String.format(KylinConstants.WHERE_VALUE_VALUE, value); + } + list.add(SQLObj.builder() + .whereField(whereName) + .whereTermAndValue(whereTerm + whereValue) + .build()); + } + + List strList = new ArrayList<>(); + list.forEach(ele -> strList.add(ele.getWhereField() + " " + ele.getWhereTermAndValue())); + if (CollectionUtils.isNotEmpty(list)) { + res.add("(" + String.join(" " + getLogic(request.getLogic()) + " ", strList) + ")"); + } + } + } + return CollectionUtils.isNotEmpty(res) ? "(" + String.join(" AND ", res) + ")" : null; + } + + public String transExtFilterList(SQLObj tableObj, List requestList) { + if (CollectionUtils.isEmpty(requestList)) { + return null; + } + List list = new ArrayList<>(); + for (ChartExtFilterRequest request : requestList) { + List value = request.getValue(); + + List whereNameList = new ArrayList<>(); + List fieldList = new ArrayList<>(); + if (request.getIsTree()) { + fieldList.addAll(request.getDatasetTableFieldList()); + } else { + fieldList.add(request.getDatasetTableField()); + } + + for (DatasetTableField field : fieldList) { + if (CollectionUtils.isEmpty(value) || ObjectUtils.isEmpty(field)) { + continue; + } + String whereName = ""; + + String originName; + if (ObjectUtils.isNotEmpty(field.getExtField()) && field.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originName = calcFieldRegex(field.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(field.getExtField()) && field.getExtField() == 1) { + originName = String.format(KylinConstants.KEYWORD_FIX, tableObj.getTableAlias(), field.getOriginName()); + } else { + originName = String.format(KylinConstants.KEYWORD_FIX, tableObj.getTableAlias(), field.getOriginName()); + } + + if (field.getDeType() == DeTypeConstants.DE_TIME) { + if (field.getDeExtractType() == DeTypeConstants.DE_STRING || field.getDeExtractType() == 5) { + whereName = String.format(KylinConstants.CAST, originName, KylinConstants.DEFAULT_DATE_TYPE); + } + if (field.getDeExtractType() == DeTypeConstants.DE_INT || field.getDeExtractType() == DeTypeConstants.DE_FLOAT || field.getDeExtractType() == 4) { + whereName = String.format(KylinConstants.CAST, originName, KylinConstants.DEFAULT_DATE_TYPE); + } + if (field.getDeExtractType() == 1) { + whereName = originName; + } + } else if (field.getDeType() == DeTypeConstants.DE_INT || field.getDeType() == DeTypeConstants.DE_FLOAT) { + if (field.getDeExtractType() == 0 || field.getDeExtractType() == 5) { + whereName = String.format(KylinConstants.CAST, originName, KylinConstants.DEFAULT_FLOAT_FORMAT); + } + if (field.getDeExtractType() == DeTypeConstants.DE_TIME) { + whereName = String.format(KylinConstants.CAST, originName, KylinConstants.DEFAULT_FLOAT_FORMAT); + } + if (field.getDeExtractType() == 2 || field.getDeExtractType() == 3 || field.getDeExtractType() == 4) { + whereName = originName; + } + } else { + whereName = originName; + } + whereNameList.add(whereName); + } + + String whereName = ""; + if (request.getIsTree()) { + whereName = "CONCAT(" + StringUtils.join(whereNameList, ",',',") + ")"; + } else { + whereName = whereNameList.get(0); + } + String whereTerm = transMysqlFilterTerm(request.getOperator()); + String whereValue = ""; + + if (StringUtils.containsIgnoreCase(request.getOperator(), "in")) { + whereValue = "('" + StringUtils.join(value, "','") + "')"; + } else if (StringUtils.containsIgnoreCase(request.getOperator(), "like")) { + String keyword = value.get(0).toUpperCase(); + whereValue = "'%" + keyword + "%'"; + whereName = "upper(" + whereName + ")"; + } else if (StringUtils.containsIgnoreCase(request.getOperator(), "between")) { + if (request.getDatasetTableField().getDeType() == 1) { + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + String startTime = simpleDateFormat.format(new Date(Long.parseLong(value.get(0)))); + String endTime = simpleDateFormat.format(new Date(Long.parseLong(value.get(1)))); + whereValue = String.format(KylinConstants.WHERE_BETWEEN, startTime, endTime); + } else { + whereValue = String.format(KylinConstants.WHERE_BETWEEN, value.get(0), value.get(1)); + } + } else { + whereValue = String.format(KylinConstants.WHERE_VALUE_VALUE, value.get(0)); + } + list.add(SQLObj.builder() + .whereField(whereName) + .whereTermAndValue(whereTerm + whereValue) + .build()); + } + List strList = new ArrayList<>(); + list.forEach(ele -> strList.add(ele.getWhereField() + " " + ele.getWhereTermAndValue())); + return CollectionUtils.isNotEmpty(list) ? "(" + String.join(" AND ", strList) + ")" : null; + } + + private String sqlFix(String sql) { + if (sql.lastIndexOf(";") == (sql.length() - 1)) { + sql = sql.substring(0, sql.length() - 1); + } + return sql; + } + + private String transDateFormat(String dateStyle, String datePattern) { + String split = "-"; + if (StringUtils.equalsIgnoreCase(datePattern, "date_sub")) { + split = "-"; + } else if (StringUtils.equalsIgnoreCase(datePattern, "date_split")) { + split = "/"; + } else { + split = "-"; + } + + if (StringUtils.isEmpty(dateStyle)) { + return "yyyy-MM-dd HH:mm:ss"; + } + + switch (dateStyle) { + case "y": + return "yyyy"; + case "y_M": + return "yyyy" + split + "MM"; + case "y_M_d": + return "yyyy" + split + "MM" + split + "dd"; + case "H_m_s": + return "hh:mi:ss"; + case "y_M_d_H_m": + return "yyyy" + split + "MM" + split + "dd" + " HH:mm"; + case "y_M_d_H_m_s": + return "yyyy" + split + "MM" + split + "dd" + " HH:mm:ss"; + default: + return "yyyy-MM-dd HH:mm:s"; + } + } + + private SQLObj getXFields(ChartViewFieldDTO x, String originField, String fieldAlias) { + String fieldName = ""; + if (x.getDeExtractType() == DeTypeConstants.DE_TIME) { +// if (x.getDeType() == DeTypeConstants.DE_INT || x.getDeType() == DeTypeConstants.DE_FLOAT) { +// fieldName = String.format(KylinConstants.UNIX_TIMESTAMP, originField); +// } else if (x.getDeType() == DeTypeConstants.DE_TIME) { +// String format = transDateFormat(x.getDateStyle(), x.getDatePattern()); +// fieldName = String.format(KylinConstants.FORMAT_DATETIME, originField, format); +// } else { +// fieldName = originField; +// } + fieldName = originField; + } else { + if (x.getDeType() == DeTypeConstants.DE_TIME) { + String format = transDateFormat(x.getDateStyle(), x.getDatePattern()); + if (x.getDeExtractType() == DeTypeConstants.DE_STRING) { + fieldName = String.format(KylinConstants.CAST, originField, KylinConstants.DEFAULT_DATE_TYPE); + } else { + fieldName = originField; + } + } else { + if (x.getDeType() == DeTypeConstants.DE_INT) { + fieldName = String.format(KylinConstants.CAST, originField, KylinConstants.DEFAULT_INT_FORMAT); + } else if (x.getDeType() == DeTypeConstants.DE_FLOAT) { + fieldName = String.format(KylinConstants.CAST, originField, KylinConstants.DEFAULT_FLOAT_FORMAT); + } else { + fieldName = originField; + } + } + } + return SQLObj.builder() + .fieldName(fieldName) + .fieldAlias(fieldAlias) + .build(); + } + + private SQLObj getYFields(ChartViewFieldDTO y, String originField, String fieldAlias) { + String fieldName = ""; + if (StringUtils.equalsIgnoreCase(y.getOriginName(), "*")) { + fieldName = KylinConstants.AGG_COUNT; + } else if (SQLConstants.DIMENSION_TYPE.contains(y.getDeType())) { + fieldName = String.format(KylinConstants.AGG_FIELD, y.getSummary(), originField); + } else { + if (StringUtils.equalsIgnoreCase(y.getSummary(), "avg") || StringUtils.containsIgnoreCase(y.getSummary(), "pop")) { + String cast = String.format(KylinConstants.CAST, originField, y.getDeType() == DeTypeConstants.DE_INT ? KylinConstants.DEFAULT_INT_FORMAT : KylinConstants.DEFAULT_FLOAT_FORMAT); + String agg = String.format(KylinConstants.AGG_FIELD, y.getSummary(), cast); + fieldName = String.format(KylinConstants.CAST, agg, KylinConstants.DEFAULT_FLOAT_FORMAT); + } else { + String cast = String.format(KylinConstants.CAST, originField, y.getDeType() == DeTypeConstants.DE_INT ? KylinConstants.DEFAULT_INT_FORMAT : KylinConstants.DEFAULT_FLOAT_FORMAT); + fieldName = String.format(KylinConstants.AGG_FIELD, y.getSummary(), cast); + } + } + return SQLObj.builder() + .fieldName(fieldName) + .fieldAlias(fieldAlias) + .build(); + } + + private String getYWheres(ChartViewFieldDTO y, String originField, String fieldAlias) { + List list = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(y.getFilter()) && y.getFilter().size() > 0) { + y.getFilter().forEach(f -> { + String whereTerm = transMysqlFilterTerm(f.getTerm()); + String whereValue = ""; + // 原始类型不是时间,在de中被转成时间的字段做处理 + if (StringUtils.equalsIgnoreCase(f.getTerm(), "null")) { + whereValue = ""; + } else if (StringUtils.equalsIgnoreCase(f.getTerm(), "not_null")) { + whereValue = ""; + } else if (StringUtils.equalsIgnoreCase(f.getTerm(), "empty")) { + whereValue = "''"; + } else if (StringUtils.equalsIgnoreCase(f.getTerm(), "not_empty")) { + whereValue = "''"; + } else if (StringUtils.containsIgnoreCase(f.getTerm(), "in")) { + whereValue = "('" + StringUtils.join(f.getValue(), "','") + "')"; + } else if (StringUtils.containsIgnoreCase(f.getTerm(), "like")) { + whereValue = "'%" + f.getValue() + "%'"; + } else { + whereValue = String.format(KylinConstants.WHERE_VALUE_VALUE, f.getValue()); + } + list.add(SQLObj.builder() + .whereField(fieldAlias) + .whereAlias(fieldAlias) + .whereTermAndValue(whereTerm + whereValue) + .build()); + }); + } + List strList = new ArrayList<>(); + list.forEach(ele -> strList.add(ele.getWhereField() + " " + ele.getWhereTermAndValue())); + return CollectionUtils.isNotEmpty(list) ? "(" + String.join(" " + getLogic(y.getLogic()) + " ", strList) + ")" : null; + } + + private String calcFieldRegex(String originField, SQLObj tableObj) { + originField = originField.replaceAll("[\\t\\n\\r]]", ""); + // 正则提取[xxx] + String regex = "\\[(.*?)]"; + Pattern pattern = Pattern.compile(regex); + Matcher matcher = pattern.matcher(originField); + Set ids = new HashSet<>(); + while (matcher.find()) { + String id = matcher.group(1); + ids.add(id); + } + if (CollectionUtils.isEmpty(ids)) { + return originField; + } + DatasetTableFieldExample datasetTableFieldExample = new DatasetTableFieldExample(); + datasetTableFieldExample.createCriteria().andIdIn(new ArrayList<>(ids)); + List calcFields = datasetTableFieldMapper.selectByExample(datasetTableFieldExample); + for (DatasetTableField ele : calcFields) { + originField = originField.replaceAll("\\[" + ele.getId() + "]", + String.format(KylinConstants.KEYWORD_FIX, tableObj.getTableAlias(), ele.getOriginName())); + } + return originField; + } + + private String sqlLimit(String sql, ChartViewWithBLOBs view) { + if (StringUtils.equalsIgnoreCase(view.getResultMode(), "custom")) { + return sql + " LIMIT " + view.getResultCount(); + } else { + return sql; + } + } + + public String getResultCount(boolean isTable, String sql, List xAxis, List fieldCustomFilter, List rowPermissionsTree, List extFilterRequestList, Datasource ds, ChartViewWithBLOBs view) { + return null; + } + +} diff --git a/extensions/dataease-extensions-datasource/kylin/kylin-backend/src/main/java/io/dataease/plugins/datasource/kylin/service/KylinService.java b/extensions/dataease-extensions-datasource/kylin/kylin-backend/src/main/java/io/dataease/plugins/datasource/kylin/service/KylinService.java new file mode 100644 index 0000000000..a54757342f --- /dev/null +++ b/extensions/dataease-extensions-datasource/kylin/kylin-backend/src/main/java/io/dataease/plugins/datasource/kylin/service/KylinService.java @@ -0,0 +1,54 @@ +package io.dataease.plugins.datasource.kylin.service; + +import io.dataease.plugins.common.constants.DatabaseClassification; +import io.dataease.plugins.common.constants.DatasourceCalculationMode; +import io.dataease.plugins.common.dto.StaticResource; +import io.dataease.plugins.common.dto.datasource.DataSourceType; +import io.dataease.plugins.datasource.service.DatasourceService; +import org.springframework.stereotype.Service; + +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + +@Service +public class KylinService extends DatasourceService { + + + @Override + public List components() { + List result = new ArrayList<>(); + result.add("kylin"); + return result; + } + @Override + protected InputStream readContent(String s) { + InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream("static/" + s); + return resourceAsStream; + } + + @Override + public List staticResources() { + List results = new ArrayList<>(); + StaticResource staticResource = new StaticResource(); + staticResource.setName("kylin"); + staticResource.setSuffix("jpg"); + results.add(staticResource); + results.add(pluginSvg()); + return results; + } + + @Override + public DataSourceType getDataSourceType() { + DataSourceType dataSourceType = new DataSourceType("kylin", "Kylin" , true , "", DatasourceCalculationMode.DIRECT, true); + dataSourceType.setDatabaseClassification(DatabaseClassification.DL); + return dataSourceType; + } + + private StaticResource pluginSvg() { + StaticResource staticResource = new StaticResource(); + staticResource.setName("kylin-backend"); + staticResource.setSuffix("svg"); + return staticResource; + } +} diff --git a/extensions/dataease-extensions-datasource/kylin/kylin-frontend/.babelrc b/extensions/dataease-extensions-datasource/kylin/kylin-frontend/.babelrc new file mode 100644 index 0000000000..3a280ba34b --- /dev/null +++ b/extensions/dataease-extensions-datasource/kylin/kylin-frontend/.babelrc @@ -0,0 +1,12 @@ +{ + "presets": [ + ["env", { + "modules": false, + "targets": { + "browsers": ["> 1%", "last 2 versions", "not ie <= 8"] + } + }], + "stage-2" + ], + "plugins": ["transform-vue-jsx", "transform-runtime"] +} diff --git a/extensions/dataease-extensions-datasource/kylin/kylin-frontend/.gitignore b/extensions/dataease-extensions-datasource/kylin/kylin-frontend/.gitignore new file mode 100644 index 0000000000..541a820f6c --- /dev/null +++ b/extensions/dataease-extensions-datasource/kylin/kylin-frontend/.gitignore @@ -0,0 +1,14 @@ +.DS_Store +node_modules/ +/dist/ +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Editor directories and files +.idea +.vscode +*.suo +*.ntvs* +*.njsproj +*.sln diff --git a/extensions/dataease-extensions-datasource/kylin/kylin-frontend/README.md b/extensions/dataease-extensions-datasource/kylin/kylin-frontend/README.md new file mode 100644 index 0000000000..c1e4be95e0 --- /dev/null +++ b/extensions/dataease-extensions-datasource/kylin/kylin-frontend/README.md @@ -0,0 +1,21 @@ +# deplugin-view-frontend + +> A Vue.js project + +## Build Setup + +``` bash +# install dependencies +npm install + +# serve with hot reload at localhost:8080 +npm run dev + +# build for production with minification +npm run build + +# build for production and view the bundle analyzer report +npm run build --report +``` + +For a detailed explanation on how things work, check out the [guide](http://vuejs-templates.github.io/webpack/) and [docs for vue-loader](http://vuejs.github.io/vue-loader). diff --git a/extensions/dataease-extensions-datasource/kylin/kylin-frontend/build/build-async-plugins.js b/extensions/dataease-extensions-datasource/kylin/kylin-frontend/build/build-async-plugins.js new file mode 100644 index 0000000000..2303854531 --- /dev/null +++ b/extensions/dataease-extensions-datasource/kylin/kylin-frontend/build/build-async-plugins.js @@ -0,0 +1,35 @@ +'use strict' +require('./check-versions')() + +process.env.NODE_ENV = 'production' + +const ora = require('ora') +const chalk = require('chalk') +const webpack = require('webpack') +const webpackConfig = require('./webpack.async-plugins') + +const spinner = ora('building for sync-plugins...') +spinner.start() + +webpack(webpackConfig, function (err, stats) { + spinner.stop() + if (err) throw err + process.stdout.write(stats.toString({ + colors: true, + modules: false, + children: false, + chunks: false, + chunkModules: false + }) + '\n\n') + + if (stats.hasErrors()) { + console.log(chalk.red(' Build failed with errors.\n')) + process.exit(1) + } + + console.log(chalk.cyan(' Build complete.\n')) + console.log(chalk.yellow( + ' Tip: built files are meant to be served over an HTTP server.\n' + + ' Opening index.html over file:// won\'t work.\n' + )) +}) diff --git a/extensions/dataease-extensions-datasource/kylin/kylin-frontend/build/build.js b/extensions/dataease-extensions-datasource/kylin/kylin-frontend/build/build.js new file mode 100644 index 0000000000..8f2ad8ad49 --- /dev/null +++ b/extensions/dataease-extensions-datasource/kylin/kylin-frontend/build/build.js @@ -0,0 +1,41 @@ +'use strict' +require('./check-versions')() + +process.env.NODE_ENV = 'production' + +const ora = require('ora') +const rm = require('rimraf') +const path = require('path') +const chalk = require('chalk') +const webpack = require('webpack') +const config = require('../config') +const webpackConfig = require('./webpack.prod.conf') + +const spinner = ora('building for production...') +spinner.start() + +rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => { + if (err) throw err + webpack(webpackConfig, (err, stats) => { + spinner.stop() + if (err) throw err + process.stdout.write(stats.toString({ + colors: true, + modules: false, + children: false, // If you are using ts-loader, setting this to true will make TypeScript errors show up during build. + chunks: false, + chunkModules: false + }) + '\n\n') + + if (stats.hasErrors()) { + console.log(chalk.red(' Build failed with errors.\n')) + process.exit(1) + } + + console.log(chalk.cyan(' Build complete.\n')) + console.log(chalk.yellow( + ' Tip: built files are meant to be served over an HTTP server.\n' + + ' Opening index.html over file:// won\'t work.\n' + )) + }) +}) diff --git a/extensions/dataease-extensions-datasource/kylin/kylin-frontend/build/check-versions.js b/extensions/dataease-extensions-datasource/kylin/kylin-frontend/build/check-versions.js new file mode 100644 index 0000000000..3ef972a08d --- /dev/null +++ b/extensions/dataease-extensions-datasource/kylin/kylin-frontend/build/check-versions.js @@ -0,0 +1,54 @@ +'use strict' +const chalk = require('chalk') +const semver = require('semver') +const packageConfig = require('../package.json') +const shell = require('shelljs') + +function exec (cmd) { + return require('child_process').execSync(cmd).toString().trim() +} + +const versionRequirements = [ + { + name: 'node', + currentVersion: semver.clean(process.version), + versionRequirement: packageConfig.engines.node + } +] + +if (shell.which('npm')) { + versionRequirements.push({ + name: 'npm', + currentVersion: exec('npm --version'), + versionRequirement: packageConfig.engines.npm + }) +} + +module.exports = function () { + const warnings = [] + + for (let i = 0; i < versionRequirements.length; i++) { + const mod = versionRequirements[i] + + if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) { + warnings.push(mod.name + ': ' + + chalk.red(mod.currentVersion) + ' should be ' + + chalk.green(mod.versionRequirement) + ) + } + } + + if (warnings.length) { + console.log('') + console.log(chalk.yellow('To use this template, you must update following to modules:')) + console.log() + + for (let i = 0; i < warnings.length; i++) { + const warning = warnings[i] + console.log(' ' + warning) + } + + console.log() + process.exit(1) + } +} diff --git a/extensions/dataease-extensions-datasource/kylin/kylin-frontend/build/logo.png b/extensions/dataease-extensions-datasource/kylin/kylin-frontend/build/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..f3d2503fc2a44b5053b0837ebea6e87a2d339a43 GIT binary patch literal 6849 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 { + const notifier = require('node-notifier') + + return (severity, errors) => { + if (severity !== 'error') return + + const error = errors[0] + const filename = error.file && error.file.split('!').pop() + + notifier.notify({ + title: packageConfig.name, + message: severity + ': ' + error.name, + subtitle: filename || '', + icon: path.join(__dirname, 'logo.png') + }) + } +} diff --git a/extensions/dataease-extensions-datasource/kylin/kylin-frontend/build/vue-loader.conf.js b/extensions/dataease-extensions-datasource/kylin/kylin-frontend/build/vue-loader.conf.js new file mode 100644 index 0000000000..33ed58bc0a --- /dev/null +++ b/extensions/dataease-extensions-datasource/kylin/kylin-frontend/build/vue-loader.conf.js @@ -0,0 +1,22 @@ +'use strict' +const utils = require('./utils') +const config = require('../config') +const isProduction = process.env.NODE_ENV === 'production' +const sourceMapEnabled = isProduction + ? config.build.productionSourceMap + : config.dev.cssSourceMap + +module.exports = { + loaders: utils.cssLoaders({ + sourceMap: sourceMapEnabled, + extract: isProduction + }), + cssSourceMap: sourceMapEnabled, + cacheBusting: config.dev.cacheBusting, + transformToRequire: { + video: ['src', 'poster'], + source: 'src', + img: 'src', + image: 'xlink:href' + } +} diff --git a/extensions/dataease-extensions-datasource/kylin/kylin-frontend/build/webpack.async-plugins.js b/extensions/dataease-extensions-datasource/kylin/kylin-frontend/build/webpack.async-plugins.js new file mode 100644 index 0000000000..43dfa8b1b0 --- /dev/null +++ b/extensions/dataease-extensions-datasource/kylin/kylin-frontend/build/webpack.async-plugins.js @@ -0,0 +1,85 @@ +const webpack = require('webpack') +const path = require('path') +const utils = require('./utils') +const CopyPlugin = require("copy-webpack-plugin"); +function resolve (dir) { + return path.join(__dirname, '..', dir) +} + +module.exports = { + entry: { + 'kylin': resolve('/src/views/kylin.vue') + }, + output: { + path: resolve('/static/'), + filename: '[name].js' + }, + resolve: { + extensions: ['.js', '.vue', '.json'], + alias: { + 'vue$': 'vue/dist/vue.esm.js', + '@': resolve('src') + } + }, + externals: { + vue: 'vue' + }, + module: { + rules: [ + { + test: /\.vue$/, + loader: 'vue-loader', + options: { + esModule: false, // vue-loader v13 更新 默认值为 true v12及之前版本为 false, 此项配置影响 vue 自身异步组件写法以及 webpack 打包结果 + loaders: utils.cssLoaders({ + sourceMap: true, + extract: false // css 不做提取 + }), + transformToRequire: { + video: 'src', + source: 'src', + img: 'src', + image: 'xlink:href' + } + } + }, + { + test: /\.js$/, + loader: 'babel-loader', + include: [resolve('src'), resolve('test')] + }, + { + test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: utils.assetsPath('img/[name].[hash:7].[ext]') + } + }, + { + test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: utils.assetsPath('media/[name].[hash:7].[ext]') + } + }, + { + test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: utils.assetsPath('fonts/[name].[hash:7].[ext]') + } + } + ] + }, + plugins: [ + new webpack.DefinePlugin({ + 'process.env.NODE_ENV': '"production"' + }), + new CopyPlugin([ + {from: 'src/icons/svg/'} + ]), + ] +} diff --git a/extensions/dataease-extensions-datasource/kylin/kylin-frontend/build/webpack.base.conf.js b/extensions/dataease-extensions-datasource/kylin/kylin-frontend/build/webpack.base.conf.js new file mode 100644 index 0000000000..7ef785a39e --- /dev/null +++ b/extensions/dataease-extensions-datasource/kylin/kylin-frontend/build/webpack.base.conf.js @@ -0,0 +1,103 @@ +'use strict' +const path = require('path') +const utils = require('./utils') +const config = require('../config') +const vueLoaderConfig = require('./vue-loader.conf') + +function resolve (dir) { + return path.join(__dirname, '..', dir) +} + + + +module.exports = { + context: path.resolve(__dirname, '../'), + entry: { + app: './src/main.js' + }, + output: { + path: config.build.assetsRoot, + filename: '[name].js', + publicPath: process.env.NODE_ENV === 'production' + ? config.build.assetsPublicPath + : config.dev.assetsPublicPath + }, + resolve: { + extensions: ['.js', '.vue', '.json'], + alias: { + 'vue$': 'vue/dist/vue.esm.js', + '@': resolve('src'), + } + }, + module: { + rules: [ + { + test: /\.vue$/, + loader: 'vue-loader', + options: vueLoaderConfig + }, + { + test: /\.js$/, + loader: 'babel-loader', + include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')] + }, + { + test: /\.svg$/, + loader: 'svg-sprite-loader', + include: [resolve('src/icons')], + options: { + symbolId: 'icon-[name]' + } + }, + { + test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, + loader: 'url-loader', + exclude: [resolve('src/icons')], + options: { + limit: 10000, + name: utils.assetsPath('img/[name].[hash:7].[ext]') + } + }, + { + test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: utils.assetsPath('media/[name].[hash:7].[ext]') + } + }, + { + test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: utils.assetsPath('fonts/[name].[hash:7].[ext]') + } + }, + { + test: /\.svg$/, + include: [path.resolve('src/icons')], + use: [ + { + loader: 'svg-sprite-loader', + options: { + symbolId: 'icon-[name]', + }, + } + ], + } + ] + }, + node: { + // prevent webpack from injecting useless setImmediate polyfill because Vue + // source contains it (although only uses it if it's native). + setImmediate: false, + // prevent webpack from injecting mocks to Node native modules + // that does not make sense for the client + dgram: 'empty', + fs: 'empty', + net: 'empty', + tls: 'empty', + child_process: 'empty' + } +} diff --git a/extensions/dataease-extensions-datasource/kylin/kylin-frontend/build/webpack.dev.conf.js b/extensions/dataease-extensions-datasource/kylin/kylin-frontend/build/webpack.dev.conf.js new file mode 100755 index 0000000000..070ae221f3 --- /dev/null +++ b/extensions/dataease-extensions-datasource/kylin/kylin-frontend/build/webpack.dev.conf.js @@ -0,0 +1,95 @@ +'use strict' +const utils = require('./utils') +const webpack = require('webpack') +const config = require('../config') +const merge = require('webpack-merge') +const path = require('path') +const baseWebpackConfig = require('./webpack.base.conf') +const CopyWebpackPlugin = require('copy-webpack-plugin') +const HtmlWebpackPlugin = require('html-webpack-plugin') +const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin') +const portfinder = require('portfinder') + +const HOST = process.env.HOST +const PORT = process.env.PORT && Number(process.env.PORT) + +const devWebpackConfig = merge(baseWebpackConfig, { + module: { + rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true }) + }, + // cheap-module-eval-source-map is faster for development + devtool: config.dev.devtool, + + // these devServer options should be customized in /config/index.js + devServer: { + clientLogLevel: 'warning', + historyApiFallback: { + rewrites: [ + { from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') }, + ], + }, + hot: true, + contentBase: false, // since we use CopyWebpackPlugin. + compress: true, + host: HOST || config.dev.host, + port: PORT || config.dev.port, + open: config.dev.autoOpenBrowser, + overlay: config.dev.errorOverlay + ? { warnings: false, errors: true } + : false, + publicPath: config.dev.assetsPublicPath, + proxy: config.dev.proxyTable, + quiet: true, // necessary for FriendlyErrorsPlugin + watchOptions: { + poll: config.dev.poll, + } + }, + plugins: [ + new webpack.DefinePlugin({ + 'process.env': require('../config/dev.env') + }), + new webpack.HotModuleReplacementPlugin(), + new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update. + new webpack.NoEmitOnErrorsPlugin(), + // https://github.com/ampedandwired/html-webpack-plugin + new HtmlWebpackPlugin({ + filename: 'index.html', + template: 'index.html', + inject: true + }), + // copy custom static assets + new CopyWebpackPlugin([ + { + from: path.resolve(__dirname, '../static'), + to: config.dev.assetsSubDirectory, + ignore: ['.*'] + } + ]) + ] +}) + +module.exports = new Promise((resolve, reject) => { + portfinder.basePort = process.env.PORT || config.dev.port + portfinder.getPort((err, port) => { + if (err) { + reject(err) + } else { + // publish the new Port, necessary for e2e tests + process.env.PORT = port + // add port to devServer config + devWebpackConfig.devServer.port = port + + // Add FriendlyErrorsPlugin + devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({ + compilationSuccessInfo: { + messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`], + }, + onErrors: config.dev.notifyOnErrors + ? utils.createNotifierCallback() + : undefined + })) + + resolve(devWebpackConfig) + } + }) +}) diff --git a/extensions/dataease-extensions-datasource/kylin/kylin-frontend/build/webpack.prod.conf.js b/extensions/dataease-extensions-datasource/kylin/kylin-frontend/build/webpack.prod.conf.js new file mode 100644 index 0000000000..3e25238ef6 --- /dev/null +++ b/extensions/dataease-extensions-datasource/kylin/kylin-frontend/build/webpack.prod.conf.js @@ -0,0 +1,145 @@ +'use strict' +const path = require('path') +const utils = require('./utils') +const webpack = require('webpack') +const config = require('../config') +const merge = require('webpack-merge') +const baseWebpackConfig = require('./webpack.base.conf') +const CopyWebpackPlugin = require('copy-webpack-plugin') +const HtmlWebpackPlugin = require('html-webpack-plugin') +const ExtractTextPlugin = require('extract-text-webpack-plugin') +const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin') +const UglifyJsPlugin = require('uglifyjs-webpack-plugin') + +const env = require('../config/prod.env') + +const webpackConfig = merge(baseWebpackConfig, { + module: { + rules: utils.styleLoaders({ + sourceMap: config.build.productionSourceMap, + extract: true, + usePostCSS: true + }) + }, + devtool: config.build.productionSourceMap ? config.build.devtool : false, + output: { + path: config.build.assetsRoot, + filename: utils.assetsPath('js/[name].[chunkhash].js'), + chunkFilename: utils.assetsPath('js/[id].[chunkhash].js') + }, + plugins: [ + // http://vuejs.github.io/vue-loader/en/workflow/production.html + new webpack.DefinePlugin({ + 'process.env': env + }), + new UglifyJsPlugin({ + uglifyOptions: { + compress: { + warnings: false + } + }, + sourceMap: config.build.productionSourceMap, + parallel: true + }), + // extract css into its own file + new ExtractTextPlugin({ + filename: utils.assetsPath('css/[name].[contenthash].css'), + // Setting the following option to `false` will not extract CSS from codesplit chunks. + // Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack. + // It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`, + // increasing file size: https://github.com/vuejs-templates/webpack/issues/1110 + allChunks: true, + }), + // Compress extracted CSS. We are using this plugin so that possible + // duplicated CSS from different components can be deduped. + new OptimizeCSSPlugin({ + cssProcessorOptions: config.build.productionSourceMap + ? { safe: true, map: { inline: false } } + : { safe: true } + }), + // generate dist index.html with correct asset hash for caching. + // you can customize output by editing /index.html + // see https://github.com/ampedandwired/html-webpack-plugin + new HtmlWebpackPlugin({ + filename: config.build.index, + template: 'index.html', + inject: true, + minify: { + removeComments: true, + collapseWhitespace: true, + removeAttributeQuotes: true + // more options: + // https://github.com/kangax/html-minifier#options-quick-reference + }, + // necessary to consistently work with multiple chunks via CommonsChunkPlugin + chunksSortMode: 'dependency' + }), + // keep module.id stable when vendor modules does not change + new webpack.HashedModuleIdsPlugin(), + // enable scope hoisting + new webpack.optimize.ModuleConcatenationPlugin(), + // split vendor js into its own file + new webpack.optimize.CommonsChunkPlugin({ + name: 'vendor', + minChunks (module) { + // any required modules inside node_modules are extracted to vendor + return ( + module.resource && + /\.js$/.test(module.resource) && + module.resource.indexOf( + path.join(__dirname, '../node_modules') + ) === 0 + ) + } + }), + // extract webpack runtime and module manifest to its own file in order to + // prevent vendor hash from being updated whenever app bundle is updated + new webpack.optimize.CommonsChunkPlugin({ + name: 'manifest', + minChunks: Infinity + }), + // This instance extracts shared chunks from code split chunks and bundles them + // in a separate chunk, similar to the vendor chunk + // see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk + new webpack.optimize.CommonsChunkPlugin({ + name: 'app', + async: 'vendor-async', + children: true, + minChunks: 3 + }), + + // copy custom static assets + new CopyWebpackPlugin([ + { + from: path.resolve(__dirname, '../static'), + to: config.build.assetsSubDirectory, + ignore: ['.*'] + } + ]) + ] +}) + +if (config.build.productionGzip) { + const CompressionWebpackPlugin = require('compression-webpack-plugin') + + webpackConfig.plugins.push( + new CompressionWebpackPlugin({ + asset: '[path].gz[query]', + algorithm: 'gzip', + test: new RegExp( + '\\.(' + + config.build.productionGzipExtensions.join('|') + + ')$' + ), + threshold: 10240, + minRatio: 0.8 + }) + ) +} + +if (config.build.bundleAnalyzerReport) { + const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin + webpackConfig.plugins.push(new BundleAnalyzerPlugin()) +} + +module.exports = webpackConfig diff --git a/extensions/dataease-extensions-datasource/kylin/kylin-frontend/config/dev.env.js b/extensions/dataease-extensions-datasource/kylin/kylin-frontend/config/dev.env.js new file mode 100644 index 0000000000..1e22973ae7 --- /dev/null +++ b/extensions/dataease-extensions-datasource/kylin/kylin-frontend/config/dev.env.js @@ -0,0 +1,7 @@ +'use strict' +const merge = require('webpack-merge') +const prodEnv = require('./prod.env') + +module.exports = merge(prodEnv, { + NODE_ENV: '"development"' +}) diff --git a/extensions/dataease-extensions-datasource/kylin/kylin-frontend/config/index.js b/extensions/dataease-extensions-datasource/kylin/kylin-frontend/config/index.js new file mode 100644 index 0000000000..c5eded7f81 --- /dev/null +++ b/extensions/dataease-extensions-datasource/kylin/kylin-frontend/config/index.js @@ -0,0 +1,69 @@ +'use strict' +// Template version: 1.3.1 +// see http://vuejs-templates.github.io/webpack for documentation. + +const path = require('path') + +module.exports = { + dev: { + + // Paths + assetsSubDirectory: 'static', + assetsPublicPath: '/', + proxyTable: {}, + + // Various Dev Server settings + host: 'localhost', // can be overwritten by process.env.HOST + port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined + autoOpenBrowser: false, + errorOverlay: true, + notifyOnErrors: true, + poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions- + + + /** + * Source Maps + */ + + // https://webpack.js.org/configuration/devtool/#development + devtool: 'cheap-module-eval-source-map', + + // If you have problems debugging vue-files in devtools, + // set this to false - it *may* help + // https://vue-loader.vuejs.org/en/options.html#cachebusting + cacheBusting: true, + + cssSourceMap: true + }, + + build: { + // Template for index.html + index: path.resolve(__dirname, '../dist/index.html'), + + // Paths + assetsRoot: path.resolve(__dirname, '../dist'), + assetsSubDirectory: 'static', + assetsPublicPath: '/', + + /** + * Source Maps + */ + + productionSourceMap: true, + // https://webpack.js.org/configuration/devtool/#production + devtool: '#source-map', + + // Gzip off by default as many popular static hosts such as + // Surge or Netlify already gzip all static assets for you. + // Before setting to `true`, make sure to: + // npm install --save-dev compression-webpack-plugin + productionGzip: false, + productionGzipExtensions: ['js', 'css'], + + // Run the build command with an extra argument to + // View the bundle analyzer report after build finishes: + // `npm run build --report` + // Set to `true` or `false` to always turn it on or off + bundleAnalyzerReport: process.env.npm_config_report + } +} diff --git a/extensions/dataease-extensions-datasource/kylin/kylin-frontend/config/prod.env.js b/extensions/dataease-extensions-datasource/kylin/kylin-frontend/config/prod.env.js new file mode 100644 index 0000000000..a6f997616e --- /dev/null +++ b/extensions/dataease-extensions-datasource/kylin/kylin-frontend/config/prod.env.js @@ -0,0 +1,4 @@ +'use strict' +module.exports = { + NODE_ENV: '"production"' +} diff --git a/extensions/dataease-extensions-datasource/kylin/kylin-frontend/index.html b/extensions/dataease-extensions-datasource/kylin/kylin-frontend/index.html new file mode 100644 index 0000000000..03ce3fdf27 --- /dev/null +++ b/extensions/dataease-extensions-datasource/kylin/kylin-frontend/index.html @@ -0,0 +1,12 @@ + + + + + + deplugin-view-frontend + + +
+ + + diff --git a/extensions/dataease-extensions-datasource/kylin/kylin-frontend/package.json b/extensions/dataease-extensions-datasource/kylin/kylin-frontend/package.json new file mode 100644 index 0000000000..d75d0e3c44 --- /dev/null +++ b/extensions/dataease-extensions-datasource/kylin/kylin-frontend/package.json @@ -0,0 +1,75 @@ +{ + "name": "deplugin-datasource-frontend", + "version": "1.0.0", + "description": "A Vue.js project", + "author": "", + "private": true, + "scripts": { + "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js", + "start": "npm run dev", + "build": "node build/build.js", + "buildPlugin": "node build/build-async-plugins.js" + }, + "dependencies": { + "@riophae/vue-treeselect": "0.4.0", + "highcharts": "^10.0.0", + "svg-sprite-loader": "^6.0.11", + "svgo": "1.2.2", + "svgo-loader": "^3.0.1", + "vue": "^2.5.2", + "vue-i18n": "7.3.2", + "vue-router": "^3.0.1", + "vue-uuid": "2.0.2", + "vuedraggable": "^2.24.3" + }, + "devDependencies": { + "autoprefixer": "^7.1.2", + "babel-core": "^6.22.1", + "babel-helper-vue-jsx-merge-props": "^2.0.3", + "babel-loader": "^7.1.1", + "babel-plugin-syntax-jsx": "^6.18.0", + "babel-plugin-transform-runtime": "^6.22.0", + "babel-plugin-transform-vue-jsx": "^3.5.0", + "babel-preset-env": "^1.3.2", + "babel-preset-stage-2": "^6.22.0", + "chalk": "^2.0.1", + "copy-webpack-plugin": "^4.6.0", + "css-loader": "^0.28.0", + "element-ui": "2.15.7", + "extract-text-webpack-plugin": "^3.0.0", + "file-loader": "^1.1.4", + "friendly-errors-webpack-plugin": "^1.6.1", + "html-webpack-plugin": "^2.30.1", + "js-cookie": "2.2.0", + "node-notifier": "^8.0.1", + "optimize-css-assets-webpack-plugin": "^3.2.0", + "ora": "^1.2.0", + "portfinder": "^1.0.13", + "postcss-import": "^11.0.0", + "postcss-loader": "^2.0.8", + "postcss-url": "^7.2.1", + "rimraf": "^2.6.0", + "sass": "^1.33.0", + "sass-loader": "^7.3.1", + "semver": "^5.3.0", + "shelljs": "^0.8.5", + "uglifyjs-webpack-plugin": "^1.1.1", + "url-loader": "^0.5.8", + "vue-loader": "^13.3.0", + "vue-style-loader": "^3.0.1", + "vue-template-compiler": "^2.5.2", + "webpack": "^3.6.0", + "webpack-bundle-analyzer": "^3.3.2", + "webpack-dev-server": "^3.1.11", + "webpack-merge": "^4.1.0" + }, + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + }, + "browserslist": [ + "> 1%", + "last 2 versions", + "not ie <= 8" + ] +} diff --git a/extensions/dataease-extensions-datasource/kylin/kylin-frontend/pom.xml b/extensions/dataease-extensions-datasource/kylin/kylin-frontend/pom.xml new file mode 100644 index 0000000000..c2f2313802 --- /dev/null +++ b/extensions/dataease-extensions-datasource/kylin/kylin-frontend/pom.xml @@ -0,0 +1,80 @@ + + + + + io.dataease + kylin + ${dataease.version} + + + 4.0.0 + kylin-frontend + + + UTF-8 + UTF-8 + 1.9.1 + + + + + + maven-clean-plugin + + + + static + + ** + + false + + + + + + + + com.github.eirslett + frontend-maven-plugin + ${frontend-maven-plugin.version} + + + install node and npm + + install-node-and-npm + + + + v16.20.2 + 7.6.3 + + + + + npm install + + npm + + + + install --force + + + + + npm run buildPlugin + + npm + + + run buildPlugin + + + + + + + diff --git a/extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/App.vue b/extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/App.vue new file mode 100644 index 0000000000..8542e07722 --- /dev/null +++ b/extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/App.vue @@ -0,0 +1,23 @@ + + + + + diff --git a/extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/assets/logo.png b/extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/assets/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..f3d2503fc2a44b5053b0837ebea6e87a2d339a43 GIT binary patch literal 6849 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 +
+

{{ msg }}

+

Essential Links

+ +

Ecosystem

+ +
+ + + + + + diff --git a/extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/de-base/lang/en.js b/extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/de-base/lang/en.js new file mode 100644 index 0000000000..0fcfd86f22 --- /dev/null +++ b/extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/de-base/lang/en.js @@ -0,0 +1,19 @@ +export default { + plugin_view_3d_pie: { + type_title: '3D-PIE', + label: 'Label', + angle: 'Angle' + }, + host: 'Host', + port: 'Port', + dataBase: 'Catalog', + schema: 'Schema', + username: 'User', + password: 'Password', + query_timeout: 'Query timeout (seconds)', + second: 'second', + please_select: 'Please select', + enter_the_port: 'Please enter the port', + one_user_name: 'enter one user name', + input_a_password: 'Please input a password' +} diff --git a/extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/de-base/lang/index.js b/extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/de-base/lang/index.js new file mode 100644 index 0000000000..e50d0478e6 --- /dev/null +++ b/extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/de-base/lang/index.js @@ -0,0 +1,49 @@ +import Vue from 'vue' +import VueI18n from 'vue-i18n' +import Cookies from 'js-cookie' +import elementEnLocale from 'element-ui/lib/locale/lang/en' // element-ui lang +import elementZhLocale from 'element-ui/lib/locale/lang/zh-CN'// element-ui lang +import elementTWLocale from 'element-ui/lib/locale/lang/zh-TW'// element-ui lang + +import localMessages from './messages' + + +Vue.use(VueI18n) + +const messages = { + en_US: { + ...localMessages['en_US'], + ...elementEnLocale + }, + zh_CN: { + ...localMessages['zh_CN'], + ...elementZhLocale + }, + zh_TW: { + ...localMessages['zh_TW'], + ...elementTWLocale + } +} +export function getLanguage () { + const chooseLanguage = Cookies.get('language') + if (chooseLanguage) return chooseLanguage + + // if has not choose language + const language = (navigator.language || navigator.browserLanguage).toLowerCase() + const locales = Object.keys(messages) + for (const locale of locales) { + if (language.indexOf(locale) > -1) { + return locale + } + } + return 'zh_CN' +} +const i18n = new VueI18n({ + // set locale + // options: en | zh | es + locale: getLanguage(), + // set locale messages + messages +}) + +export default i18n diff --git a/extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/de-base/lang/messages.js b/extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/de-base/lang/messages.js new file mode 100644 index 0000000000..844f8c0673 --- /dev/null +++ b/extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/de-base/lang/messages.js @@ -0,0 +1,17 @@ +import enLocale from './en' +import zhLocale from './zh' +import twLocale from './tw' + +const messages = { + en_US: { + ...enLocale + }, + zh_CN: { + ...zhLocale + }, + zh_TW: { + ...twLocale + } +} + +export default messages \ No newline at end of file diff --git a/extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/de-base/lang/tw.js b/extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/de-base/lang/tw.js new file mode 100644 index 0000000000..c4dc7d0b2a --- /dev/null +++ b/extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/de-base/lang/tw.js @@ -0,0 +1,19 @@ +export default { + plugin_view_3d_pie: { + type_title: '3D餅圖', + label: '標籤', + angle: '角度' + }, + host: '主機名', + port: '端口', + dataBase: '數據庫', + schema: 'Schema', + username: '用戶名', + password: '密碼', + query_timeout: '査詢超時(秒)', + second: '秒', + please_select: '請選擇', + enter_the_port: '請輸入埠', + one_user_name: '請輸入用戶名', + input_a_password: '請輸入密碼' +} diff --git a/extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/de-base/lang/zh.js b/extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/de-base/lang/zh.js new file mode 100644 index 0000000000..165700b887 --- /dev/null +++ b/extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/de-base/lang/zh.js @@ -0,0 +1,19 @@ +export default { + plugin_view_3d_pie: { + type_title: '3D饼图', + label: '标签', + angle: '角度' + }, + host: '主机名', + port: '端口', + dataBase: '数据库', + schema: 'Schema', + username: '用户名', + password: '密码', + query_timeout: '查询超时(秒)', + second: '秒', + please_select: '请选择', + enter_the_port: '请输入端口', + one_user_name: '请输入用户名', + input_a_password: '请输入密码' +} diff --git a/extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/icons/index.js b/extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/icons/index.js new file mode 100644 index 0000000000..2c6b309c96 --- /dev/null +++ b/extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/icons/index.js @@ -0,0 +1,9 @@ +import Vue from 'vue' +import SvgIcon from '@/components/SvgIcon'// svg component + +// register globally +Vue.component('svg-icon', SvgIcon) + +const req = require.context('./svg', false, /\.svg$/) +const requireAll = requireContext => requireContext.keys().map(requireContext) +requireAll(req) diff --git a/extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/icons/svg/de_pwd_invisible.svg b/extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/icons/svg/de_pwd_invisible.svg new file mode 100644 index 0000000000..661ebba33e --- /dev/null +++ b/extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/icons/svg/de_pwd_invisible.svg @@ -0,0 +1,3 @@ + + + diff --git a/extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/icons/svg/de_pwd_visible.svg b/extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/icons/svg/de_pwd_visible.svg new file mode 100644 index 0000000000..4e7ba5e799 --- /dev/null +++ b/extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/icons/svg/de_pwd_visible.svg @@ -0,0 +1,3 @@ + + + diff --git a/extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/icons/svg/kylin-backend.svg b/extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/icons/svg/kylin-backend.svg new file mode 100644 index 0000000000..a8de85ce6e --- /dev/null +++ b/extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/icons/svg/kylin-backend.svg @@ -0,0 +1 @@ +【icon】插件管理-导出 \ No newline at end of file diff --git a/extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/icons/svg/kylin.jpg b/extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/icons/svg/kylin.jpg new file mode 100644 index 0000000000000000000000000000000000000000..299e0af8e8f0f5b972993b721194bb415b9a246c GIT binary patch literal 18205 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 b#@pW~`4)e^8J9)j5fHGF4;(vF|K9`v8!4Wl literal 0 HcmV?d00001 diff --git a/extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/icons/svgo.yml b/extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/icons/svgo.yml new file mode 100644 index 0000000000..d11906aec2 --- /dev/null +++ b/extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/icons/svgo.yml @@ -0,0 +1,22 @@ +# replace default config + +# multipass: true +# full: true + +plugins: + + # - name + # + # or: + # - name: false + # - name: true + # + # or: + # - name: + # param1: 1 + # param2: 2 + +- removeAttrs: + attrs: + - 'fill' + - 'fill-rule' diff --git a/extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/main.js b/extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/main.js new file mode 100644 index 0000000000..99c5626590 --- /dev/null +++ b/extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/main.js @@ -0,0 +1,33 @@ +// The Vue build version to load with the `import` command +// (runtime-only or standalone) has been set in webpack.base.conf with an alias. +import Vue from 'vue' +import App from './App' +import router from './router' +import ElementUI from 'element-ui' +import Cookies from 'js-cookie' +import i18n from './de-base/lang' +import draggable from 'vuedraggable' +import Treeselect from '@riophae/vue-treeselect' +import '@riophae/vue-treeselect/dist/vue-treeselect.css' +Vue.config.productionTip = false +Vue.use(ElementUI, { + size: Cookies.get('size') || 'medium', + i18n: (key, value) => i18n.t(key, value) +}) +Vue.component('Treeselect', Treeselect) +Vue.component('draggable', draggable) +Vue.prototype.hasDataPermission = function(pTarget, pSource) { + + if (pSource && pTarget) { + return pSource.indexOf(pTarget) > -1 + } + return false +} +/* eslint-disable no-new */ +new Vue({ + el: '#app', + router, + i18n, + components: { App }, + template: '' +}) diff --git a/extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/router/index.js b/extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/router/index.js new file mode 100644 index 0000000000..b5b55fa1fc --- /dev/null +++ b/extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/router/index.js @@ -0,0 +1,21 @@ +import Vue from 'vue' +import Router from 'vue-router' +import HelloWorld from '@/components/HelloWorld' +import maxcompute from '@/views/maxcompute' + +Vue.use(Router) + +export default new Router({ + routes: [ + { + path: '/', + name: 'HelloWorld', + component: HelloWorld + }, + { + path: '/maxcompute', + name: 'maxcompute', + component: maxcompute + } + ] +}) diff --git a/extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/utils/compare.js b/extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/utils/compare.js new file mode 100644 index 0000000000..b06a104a10 --- /dev/null +++ b/extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/utils/compare.js @@ -0,0 +1,29 @@ +export const compareItem = { + type: 'none', // year-yoy/month-yoy等 + resultData: 'percent', // 对比差sub,百分比percent等 + field: '', + custom: { + field: '', + calcType: '0', // 0-增长值,1-增长率 + timeType: '0', // 0-固定日期,1-日期区间 + currentTime: '', + compareTime: '', + currentTimeRange: [], + compareTimeRange: [] + } +} + +export const compareYearList = [ + { name: 'year_mom', value: 'year_mom' } +] + +export const compareMonthList = [ + { name: 'month_mom', value: 'month_mom' }, + { name: 'year_yoy', value: 'year_yoy' } +] + +export const compareDayList = [ + { name: 'day_mom', value: 'day_mom' }, + { name: 'month_yoy', value: 'month_yoy' }, + { name: 'year_yoy', value: 'year_yoy' } +] diff --git a/extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/utils/validate.js b/extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/utils/validate.js new file mode 100644 index 0000000000..3e8ffa9448 --- /dev/null +++ b/extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/utils/validate.js @@ -0,0 +1,15 @@ +/** + * Created by PanJiaChen on 16/11/18. + */ + +/** + * @param {string} path + * @returns {Boolean} + */ +export function isExternal(path) { + return /^(https?:|mailto:|tel:)/.test(path) || /^(http?:|mailto:|tel:)/.test(path) || path.startsWith('/api/pluginCommon/staticInfo') +} + + + + diff --git a/extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/views/dePwd.vue b/extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/views/dePwd.vue new file mode 100644 index 0000000000..61bf3e88ee --- /dev/null +++ b/extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/views/dePwd.vue @@ -0,0 +1,75 @@ + + + + \ No newline at end of file diff --git a/extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/views/kylin.vue b/extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/views/kylin.vue new file mode 100644 index 0000000000..c327be8d96 --- /dev/null +++ b/extensions/dataease-extensions-datasource/kylin/kylin-frontend/src/views/kylin.vue @@ -0,0 +1,163 @@ + + + + + diff --git a/extensions/dataease-extensions-datasource/kylin/plugin.json b/extensions/dataease-extensions-datasource/kylin/plugin.json new file mode 100644 index 0000000000..f8258694ad --- /dev/null +++ b/extensions/dataease-extensions-datasource/kylin/plugin.json @@ -0,0 +1,13 @@ +{ + "name":"Kylin 数据源插件", + "free":0, + "store":"default", + "cost":0, + "category":"datasource", + "descript":"Kylin 插件,值得拥有", + "version":"1.18.0", + "creator":"DATAEASE", + "moduleName":"kylin-backend", + "require":"1.16.0", + "dsType":"kylin" +} diff --git a/extensions/dataease-extensions-datasource/kylin/pom.xml b/extensions/dataease-extensions-datasource/kylin/pom.xml new file mode 100644 index 0000000000..57779a138e --- /dev/null +++ b/extensions/dataease-extensions-datasource/kylin/pom.xml @@ -0,0 +1,19 @@ + + + + dataease-extensions-datasource + io.dataease + ${dataease.version} + + 4.0.0 + + kylin + pom + + kylin-frontend + kylin-backend + + + diff --git a/extensions/dataease-extensions-datasource/maxcompute/.gitignore b/extensions/dataease-extensions-datasource/maxcompute/.gitignore new file mode 100644 index 0000000000..a5a2b0c056 --- /dev/null +++ b/extensions/dataease-extensions-datasource/maxcompute/.gitignore @@ -0,0 +1,35 @@ +# Created by .ignore support plugin (hsz.mobi) +.DS_Store +node_modules +node/ +/dist + +# local env files +.env.local +.env.*.local + +# Log files +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Editor directories and files +.idea +*.iml +.vscode +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? + + +src/main/resources/static +src/main/resources/templates +src/test/ +target +.settings +.project +.classpath +.factorypath +src/main/resources/jmeter/lib/ \ No newline at end of file diff --git a/extensions/dataease-extensions-datasource/maxcompute/build.sh b/extensions/dataease-extensions-datasource/maxcompute/build.sh new file mode 100755 index 0000000000..a765c3b02b --- /dev/null +++ b/extensions/dataease-extensions-datasource/maxcompute/build.sh @@ -0,0 +1,6 @@ +#!/bin/sh +mvn clean package + +cp maxcompute-backend/target/maxcompute-backend-1.18.0.jar . + +zip -r maxcompute.zip ./maxcompute-backend-1.18.0.jar ./maxcomputeDriver ./plugin.json diff --git a/extensions/dataease-extensions-datasource/maxcompute/maxcompute-backend/pom.xml b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-backend/pom.xml new file mode 100644 index 0000000000..be472e9f84 --- /dev/null +++ b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-backend/pom.xml @@ -0,0 +1,109 @@ + + + + maxcompute + io.dataease + ${dataease.version} + + 4.0.0 + + maxcompute-backend + + + + io.dataease + dataease-plugin-datasource + + + + + + + src/main/java + + **/*.properties + **/*.xml + + false + + + src/main/resources + + **/* + + false + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 11 + 11 + + + + + org.apache.maven.plugins + maven-jar-plugin + 2.4 + + + **/server/** + **/*.properties + **/Application* + + + + + + maven-clean-plugin + + + + src/main/resources/static + + ** + + false + + + + + + + + + org.apache.maven.plugins + maven-antrun-plugin + + + main-class-placement + generate-resources + + + + + + + + + + + + run + + + + + + + + + + + diff --git a/extensions/dataease-extensions-datasource/maxcompute/maxcompute-backend/src/main/java/io/dataease/plugins/datasource/dm/provider/MaxcomputeConfig.java b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-backend/src/main/java/io/dataease/plugins/datasource/dm/provider/MaxcomputeConfig.java new file mode 100644 index 0000000000..16d3a7ffab --- /dev/null +++ b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-backend/src/main/java/io/dataease/plugins/datasource/dm/provider/MaxcomputeConfig.java @@ -0,0 +1,32 @@ +package io.dataease.plugins.datasource.dm.provider; + +import io.dataease.plugins.datasource.entity.JdbcConfiguration; +import lombok.Getter; +import lombok.Setter; +import org.apache.commons.lang3.StringUtils; + +@Getter +@Setter +public class MaxcomputeConfig extends JdbcConfiguration { + + private String driver = "com.aliyun.odps.jdbc.OdpsDriver"; + private String projectName; + private String access_id; + private String access_key; + private String end_point; + private String extraParams; + + + public String getJdbc() { + if(StringUtils.isEmpty(getExtraParams())){ + return "jdbc:odps:END_POINT?project=PROJECT_NAME" + .replace("END_POINT", getEnd_point().trim()) + .replace("PROJECT_NAME", getProjectName().trim()); + }else { + return "jdbc:odps:END_POINT?project=PROJECT_NAME&EXTRA_PARAMS" + .replace("END_POINT", getEnd_point().trim()) + .replace("PROJECT_NAME", getProjectName().trim()) + .replace("EXTRA_PARAMS", getExtraParams().trim()); + } + } +} diff --git a/extensions/dataease-extensions-datasource/maxcompute/maxcompute-backend/src/main/java/io/dataease/plugins/datasource/dm/provider/MaxcomputeDsProvider.java b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-backend/src/main/java/io/dataease/plugins/datasource/dm/provider/MaxcomputeDsProvider.java new file mode 100644 index 0000000000..9f0b324390 --- /dev/null +++ b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-backend/src/main/java/io/dataease/plugins/datasource/dm/provider/MaxcomputeDsProvider.java @@ -0,0 +1,104 @@ +package io.dataease.plugins.datasource.dm.provider; + +import com.google.gson.Gson; +import io.dataease.plugins.common.base.domain.DeDriver; +import io.dataease.plugins.common.base.mapper.DeDriverMapper; +import io.dataease.plugins.common.dto.datasource.TableDesc; +import io.dataease.plugins.common.dto.datasource.TableField; +import io.dataease.plugins.common.exception.DataEaseException; +import io.dataease.plugins.common.request.datasource.DatasourceRequest; +import io.dataease.plugins.datasource.entity.JdbcConfiguration; +import io.dataease.plugins.datasource.provider.DefaultJdbcProvider; +import io.dataease.plugins.datasource.provider.ExtendedJdbcClassLoader; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.sql.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; + + +@Component() +public class MaxcomputeDsProvider extends DefaultJdbcProvider { + + @Resource + private DeDriverMapper deDriverMapper; + + @Override + public String getType() { + return "maxcompute"; + } + + @Override + public boolean isUseDatasourcePool() { + return false; + } + + @Override + public Connection getConnection(DatasourceRequest datasourceRequest) throws Exception { + + MaxcomputeConfig maxcomputeConfig = new Gson().fromJson(datasourceRequest.getDatasource().getConfiguration(), MaxcomputeConfig.class); + String username = maxcomputeConfig.getAccess_id(); + String password = maxcomputeConfig.getAccess_key(); + + Properties props = new Properties(); + if (StringUtils.isNotBlank(username)) { + props.setProperty("user", username); + if (StringUtils.isNotBlank(password)) { + props.setProperty("password", password); + } + } + + String defaultDriver = maxcomputeConfig.getDriver(); + String customDriver = maxcomputeConfig.getCustomDriver(); + String url = maxcomputeConfig.getJdbc(); + + DeDriver deDriver; + String driverClassName ; + ExtendedJdbcClassLoader jdbcClassLoader; + if(!isDefaultClassLoader(customDriver)){ + deDriver = deDriverMapper.selectByPrimaryKey(customDriver); + driverClassName = deDriver.getDriverClass(); + jdbcClassLoader = getCustomJdbcClassLoader(deDriver); + }else { + driverClassName = defaultDriver; + jdbcClassLoader = extendedJdbcClassLoader; + } + + Driver driverClass = (Driver) jdbcClassLoader.loadClass(driverClassName).newInstance(); + Connection conn = driverClass.connect(url, props); + return conn; + } + + @Override + public List getTables(DatasourceRequest datasourceRequest) throws Exception { + List tables = new ArrayList<>(); + String queryStr = getTablesSql(datasourceRequest); + JdbcConfiguration jdbcConfiguration = new Gson().fromJson(datasourceRequest.getDatasource().getConfiguration(), JdbcConfiguration.class); + int queryTimeout = jdbcConfiguration.getQueryTimeout() > 0 ? jdbcConfiguration.getQueryTimeout() : 0; + try (Connection con = getConnectionFromPool(datasourceRequest); Statement statement = getStatement(con, queryTimeout); ResultSet resultSet = statement.executeQuery(queryStr)) { + while (resultSet.next()) { + tables.add(getTableDesc(datasourceRequest, resultSet)); + } + } catch (Exception e) { + DataEaseException.throwException(e); + } + + return tables; + } + + private TableDesc getTableDesc(DatasourceRequest datasourceRequest, ResultSet resultSet) throws SQLException { + TableDesc tableDesc = new TableDesc(); + tableDesc.setName(resultSet.getString(1)); + return tableDesc; + } + + @Override + public List getTableFields(DatasourceRequest datasourceRequest) throws Exception { + datasourceRequest.setQuery("select * from " + datasourceRequest.getTable() + " limit 0"); + return fetchResultField(datasourceRequest); + } + +} diff --git a/extensions/dataease-extensions-datasource/maxcompute/maxcompute-backend/src/main/java/io/dataease/plugins/datasource/dm/query/MaxConstants.java b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-backend/src/main/java/io/dataease/plugins/datasource/dm/query/MaxConstants.java new file mode 100644 index 0000000000..b7b80fdf69 --- /dev/null +++ b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-backend/src/main/java/io/dataease/plugins/datasource/dm/query/MaxConstants.java @@ -0,0 +1,45 @@ +package io.dataease.plugins.datasource.dm.query; + + + +import io.dataease.plugins.common.constants.datasource.SQLConstants; + + +public class MaxConstants extends SQLConstants { + + public static final String KEYWORD_TABLE = "%s" ; + + public static final String KEYWORD_FIX = "%s." + "%s"; + + public static final String UNIX_TIMESTAMP = "TO_MILLIS(%s)"; + + public static final String DATE_FORMAT = "to_char(%s, '%s')"; + + public static final String FROM_UNIXTIME = "from_unixtime(%s)"; + + public static final String CAST = "CAST(%s AS %s)"; + + public static final String TO_DATE = "to_date(%s, '%s')"; + + public static final String DEFAULT_DATE_FORMAT = "YYYY-MM-DD HH24:MI:SS"; + + public static final String DEFAULT_INT_FORMAT = "bigint"; + + public static final String DEFAULT_FLOAT_FORMAT = "DOUBLE"; + + public static final String WHERE_VALUE_NULL = "(NULL,'')"; + + public static final String WHERE_VALUE_VALUE = "'%s'"; + + public static final String AGG_COUNT = "COUNT(*)"; + + public static final String AGG_FIELD = "%s(%s)"; + + public static final String WHERE_BETWEEN = "'%s' AND '%s'"; + + public static final String BRACKETS = "(%s)"; + + public static final String NAME = "pg"; + + +} diff --git a/extensions/dataease-extensions-datasource/maxcompute/maxcompute-backend/src/main/java/io/dataease/plugins/datasource/dm/query/MaxcomputeQueryProvider.java b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-backend/src/main/java/io/dataease/plugins/datasource/dm/query/MaxcomputeQueryProvider.java new file mode 100644 index 0000000000..a7e7fe14fa --- /dev/null +++ b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-backend/src/main/java/io/dataease/plugins/datasource/dm/query/MaxcomputeQueryProvider.java @@ -0,0 +1,1285 @@ +package io.dataease.plugins.datasource.dm.query; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.gson.Gson; +import io.dataease.plugins.common.base.domain.ChartViewWithBLOBs; +import io.dataease.plugins.common.base.domain.DatasetTableField; +import io.dataease.plugins.common.base.domain.DatasetTableFieldExample; +import io.dataease.plugins.common.base.domain.Datasource; +import io.dataease.plugins.common.base.mapper.DatasetTableFieldMapper; +import io.dataease.plugins.common.constants.DeTypeConstants; +import io.dataease.plugins.common.constants.datasource.SQLConstants; +import io.dataease.plugins.common.constants.datasource.SqlServerSQLConstants; +import io.dataease.plugins.common.dto.chart.ChartCustomFilterItemDTO; +import io.dataease.plugins.common.dto.chart.ChartFieldCustomFilterDTO; +import io.dataease.plugins.common.dto.chart.ChartViewFieldDTO; +import io.dataease.plugins.common.dto.datasource.DeSortField; +import io.dataease.plugins.common.dto.sqlObj.SQLObj; +import io.dataease.plugins.common.request.chart.ChartExtFilterRequest; +import io.dataease.plugins.common.request.permission.DataSetRowPermissionsTreeDTO; +import io.dataease.plugins.common.request.permission.DatasetRowPermissionsTreeItem; +import io.dataease.plugins.datasource.entity.Dateformat; +import io.dataease.plugins.datasource.entity.JdbcConfiguration; +import io.dataease.plugins.datasource.entity.PageInfo; +import io.dataease.plugins.datasource.query.QueryProvider; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.ObjectUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Component; +import org.stringtemplate.v4.ST; +import org.stringtemplate.v4.STGroup; +import org.stringtemplate.v4.STGroupFile; + +import javax.annotation.Resource; +import java.text.MessageFormat; +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +import static io.dataease.plugins.common.constants.datasource.SQLConstants.TABLE_ALIAS_PREFIX; + + +@Component() +public class MaxcomputeQueryProvider extends QueryProvider { + @Resource + private DatasetTableFieldMapper datasetTableFieldMapper; + + @Override + public Integer transFieldType(String field) { + field = field.contains("(") ? field.split("\\(")[0] : field; + switch (field) { + // 文本 + case "DATE": + case "DATETIME": + case "TIMESTAMP": + return DeTypeConstants.DE_TIME;// 时间 + case "TINYINT": + case "SMALLINT": + case "INT": + case "BIGINT": + return DeTypeConstants.DE_INT;// 整型 + case "FLOAT": + case "DOUBLE": + case "DECIMAL": + return DeTypeConstants.DE_FLOAT;// 浮点 + case "BOOLEAN": + return DeTypeConstants.DE_BOOL;// 布尔 + case "BINARY": + return DeTypeConstants.DE_BINARY;// 二进制 + default: + return DeTypeConstants.DE_STRING; + } + } + + @Override + public String createSQLPreview(String sql, String orderBy) { + return "SELECT * FROM (" + sqlFix(sql) + ") AS tmp " + " LIMIT 1000 offset 0"; + } + + @Override + public String createQuerySQL(String table, List fields, boolean isGroup, Datasource ds, List fieldCustomFilter, List rowPermissionsTree) { + return createQuerySQL(table, fields, isGroup, ds, fieldCustomFilter, rowPermissionsTree, null); + } + + @Override + public String createQuerySQL(String table, List fields, boolean isGroup, Datasource ds, List fieldCustomFilter, List rowPermissionsTree, List sortFields) { + SQLObj tableObj = SQLObj.builder() + .tableName((table.startsWith("(") && table.endsWith(")")) ? table : String.format(MaxConstants.KEYWORD_TABLE, table)) + .tableAlias(String.format(TABLE_ALIAS_PREFIX, 0)) + .build(); + + + List xFields = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(fields)) { + for (int i = 0; i < fields.size(); i++) { + DatasetTableField f = fields.get(i); + String originField; + if (ObjectUtils.isNotEmpty(f.getExtField()) && f.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originField = calcFieldRegex(f.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(f.getExtField()) && f.getExtField() == 1) { + originField = String.format(MaxConstants.KEYWORD_FIX, tableObj.getTableAlias(), f.getOriginName()); + } else { + originField = String.format(MaxConstants.KEYWORD_FIX, tableObj.getTableAlias(), f.getOriginName()); + } + String fieldAlias = String.format(SQLConstants.FIELD_ALIAS_X_PREFIX, i); + String fieldName = ""; + // 处理横轴字段 + if (f.getDeExtractType() == DeTypeConstants.DE_TIME) { + if (f.getDeType() == DeTypeConstants.DE_INT || f.getDeType() == DeTypeConstants.DE_FLOAT) { + fieldName = String.format(MaxConstants.UNIX_TIMESTAMP, originField); + } else { + fieldName = originField; + } + } else if (f.getDeExtractType() == DeTypeConstants.DE_STRING) { + if (f.getDeType() == DeTypeConstants.DE_INT) { + fieldName = String.format(MaxConstants.CAST, originField, MaxConstants.DEFAULT_INT_FORMAT); + } else if (f.getDeType() == DeTypeConstants.DE_FLOAT) { + fieldName = String.format(MaxConstants.CAST, originField, MaxConstants.DEFAULT_FLOAT_FORMAT); + } else if (f.getDeType() == DeTypeConstants.DE_TIME) { + fieldName = String.format(MaxConstants.TO_DATE, originField, StringUtils.isNotEmpty(f.getDateFormat()) ? f.getDateFormat() : MaxConstants.DEFAULT_DATE_FORMAT); + } else { + fieldName = originField; + } + } else { + if (f.getDeType() == DeTypeConstants.DE_TIME) { + String cast = String.format(MaxConstants.CAST, originField, "bigint"); + fieldName = String.format(MaxConstants.FROM_UNIXTIME, cast); + } else if (f.getDeType() == DeTypeConstants.DE_INT) { + fieldName = String.format(MaxConstants.CAST, originField, MaxConstants.DEFAULT_INT_FORMAT); + } else { + fieldName = originField; + } + } + xFields.add(SQLObj.builder() + .fieldName(fieldName) + .fieldAlias(fieldAlias) + .build()); + } + } + + STGroup stg = new STGroupFile(SQLConstants.SQL_TEMPLATE); + ST st_sql = stg.getInstanceOf("previewSql"); + st_sql.add("isGroup", isGroup); + if (CollectionUtils.isNotEmpty(xFields)) st_sql.add("groups", xFields); + if (ObjectUtils.isNotEmpty(tableObj)) st_sql.add("table", tableObj); + String customWheres = transCustomFilterList(tableObj, fieldCustomFilter); + // row permissions tree + String whereTrees = transFilterTrees(tableObj, rowPermissionsTree); + List wheres = new ArrayList<>(); + if (customWheres != null) wheres.add(customWheres); + if (whereTrees != null) wheres.add(whereTrees); + if (CollectionUtils.isNotEmpty(wheres)) st_sql.add("filters", wheres); + + List xOrders = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(sortFields)) { + int step = fields.size(); + for (int i = step; i < (step + sortFields.size()); i++) { + DeSortField deSortField = sortFields.get(i - step); + SQLObj order = buildSortField(deSortField, tableObj, i); + xOrders.add(order); + } + } + if (ObjectUtils.isNotEmpty(xOrders)) { + st_sql.add("orders", xOrders); + String sql = st_sql.render(); + if (!StringUtils.containsIgnoreCase(sql, "LIMIT") && !StringUtils.containsIgnoreCase(sql, "offset")) { + sql += "LIMIT 1000000 offset 0"; + } + return sql; + } + return st_sql.render(); + } + + private SQLObj buildSortField(DeSortField f, SQLObj tableObj, int i) { + String originField; + if (ObjectUtils.isNotEmpty(f.getExtField()) && f.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originField = calcFieldRegex(f.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(f.getExtField()) && f.getExtField() == 1) { + originField = String.format(MaxConstants.KEYWORD_FIX, tableObj.getTableAlias(), f.getOriginName()); + } else { + originField = String.format(MaxConstants.KEYWORD_FIX, tableObj.getTableAlias(), f.getOriginName()); + } + String fieldAlias = String.format(SQLConstants.FIELD_ALIAS_X_PREFIX, i); + String fieldName = ""; + // 处理横轴字段 + if (f.getDeExtractType() == DeTypeConstants.DE_TIME) { + if (f.getDeType() == DeTypeConstants.DE_INT || f.getDeType() == DeTypeConstants.DE_FLOAT) { + fieldName = String.format(MaxConstants.UNIX_TIMESTAMP, originField); + } else { + fieldName = originField; + } + } else if (f.getDeExtractType() == DeTypeConstants.DE_STRING) { + if (f.getDeType() == DeTypeConstants.DE_INT) { + fieldName = String.format(MaxConstants.CAST, originField, MaxConstants.DEFAULT_INT_FORMAT); + } else if (f.getDeType() == DeTypeConstants.DE_FLOAT) { + fieldName = String.format(MaxConstants.CAST, originField, MaxConstants.DEFAULT_FLOAT_FORMAT); + } else if (f.getDeType() == DeTypeConstants.DE_TIME) { + fieldName = String.format(MaxConstants.TO_DATE, originField, StringUtils.isNotEmpty(f.getDateFormat()) ? f.getDateFormat() : MaxConstants.DEFAULT_DATE_FORMAT); + } else { + fieldName = originField; + } + } else { + if (f.getDeType() == DeTypeConstants.DE_TIME) { + String cast = String.format(MaxConstants.CAST, originField, "bigint"); + fieldName = String.format(MaxConstants.FROM_UNIXTIME, cast); + } else if (f.getDeType() == DeTypeConstants.DE_INT) { + fieldName = String.format(MaxConstants.CAST, originField, MaxConstants.DEFAULT_INT_FORMAT); + } else { + fieldName = originField; + } + } + SQLObj result = SQLObj.builder().orderField(originField).orderAlias(originField).orderDirection(f.getOrderDirection()).build(); + return result; + } + + @Override + public String createQuerySQLAsTmp(String sql, List fields, boolean isGroup, List fieldCustomFilter, List rowPermissionsTree, List sortFields) { + return createQuerySQL("(" + sqlFix(sql) + ")", fields, isGroup, null, fieldCustomFilter, rowPermissionsTree, sortFields); + } + + @Override + public String createQuerySQLAsTmp(String sql, List fields, boolean isGroup, List fieldCustomFilter, List rowPermissionsTree) { + return createQuerySQL("(" + sqlFix(sql) + ")", fields, isGroup, null, fieldCustomFilter, rowPermissionsTree); + } + + @Override + public String createQueryTableWithPage(String table, List fields, Integer page, Integer pageSize, Integer realSize, boolean isGroup, Datasource ds, List fieldCustomFilter, List rowPermissionsTree) { + return createQuerySQL(table, fields, isGroup, ds, fieldCustomFilter, rowPermissionsTree) + " LIMIT " + realSize + " offset " + (page - 1) * pageSize; + } + + @Override + public String createQuerySQLWithPage(String sql, List fields, Integer page, Integer pageSize, Integer realSize, boolean isGroup, List fieldCustomFilter, List rowPermissionsTree) { + return createQuerySQLAsTmp(sql, fields, isGroup, fieldCustomFilter, rowPermissionsTree) + " LIMIT " + realSize + " offset " + (page - 1) * pageSize; + } + + @Override + public String createQueryTableWithLimit(String table, List fields, Integer limit, boolean isGroup, Datasource ds, List fieldCustomFilter, List rowPermissionsTree) { + return createQuerySQL(table, fields, isGroup, ds, fieldCustomFilter, rowPermissionsTree) + " LIMIT " + limit + " offset 0"; + } + + @Override + public String createQuerySqlWithLimit(String sql, List fields, Integer limit, boolean isGroup, List fieldCustomFilter, List rowPermissionsTree) { + return createQuerySQLAsTmp(sql, fields, isGroup, fieldCustomFilter, rowPermissionsTree) + " LIMIT " + limit + " offset 0"; + } + + @Override + public String getSQL(String table, List xAxis, List yAxis, List fieldCustomFilter, List rowPermissionsTree, List extFilterRequestList, Datasource ds, ChartViewWithBLOBs view) { + SQLObj tableObj = SQLObj.builder() + .tableName((table.startsWith("(") && table.endsWith(")")) ? table : String.format(MaxConstants.KEYWORD_TABLE, table)) + .tableAlias(String.format(TABLE_ALIAS_PREFIX, 0)) + .build(); + + List xFields = new ArrayList<>(); + List xOrders = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(xAxis)) { + for (int i = 0; i < xAxis.size(); i++) { + ChartViewFieldDTO x = xAxis.get(i); + String originField; + if (ObjectUtils.isNotEmpty(x.getExtField()) && x.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originField = calcFieldRegex(x.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(x.getExtField()) && x.getExtField() == 1) { + originField = String.format(MaxConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getOriginName()); + } else { + originField = String.format(MaxConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getOriginName()); + } + String fieldAlias = String.format(SQLConstants.FIELD_ALIAS_X_PREFIX, i); + // 处理横轴字段 + xFields.add(getXFields(x, originField, fieldAlias)); + // 处理横轴排序 + if (StringUtils.isNotEmpty(x.getSort()) && !StringUtils.equalsIgnoreCase(x.getSort(), "none")) { + xOrders.add(SQLObj.builder() + .orderField(originField) + .orderAlias(fieldAlias) + .orderDirection(x.getSort()) + .build()); + } + } + } + List yFields = new ArrayList<>(); + List yWheres = new ArrayList<>(); + List yOrders = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(yAxis)) { + for (int i = 0; i < yAxis.size(); i++) { + ChartViewFieldDTO y = yAxis.get(i); + String originField; + if (ObjectUtils.isNotEmpty(y.getExtField()) && y.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originField = calcFieldRegex(y.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(y.getExtField()) && y.getExtField() == 1) { + originField = String.format(MaxConstants.KEYWORD_FIX, tableObj.getTableAlias(), y.getOriginName()); + } else { + originField = String.format(MaxConstants.KEYWORD_FIX, tableObj.getTableAlias(), y.getOriginName()); + } + String fieldAlias = String.format(SQLConstants.FIELD_ALIAS_Y_PREFIX, i); + // 处理纵轴字段 + yFields.add(getYFields(y, originField, fieldAlias)); + // 处理纵轴过滤 + yWheres.add(getYWheres(y, originField, fieldAlias)); + // 处理纵轴排序 + if (StringUtils.isNotEmpty(y.getSort()) && !StringUtils.equalsIgnoreCase(y.getSort(), "none")) { + yOrders.add(SQLObj.builder() + .orderField(originField) + .orderAlias(fieldAlias) + .orderDirection(y.getSort()) + .build()); + } + } + } + // 处理视图中字段过滤 + String customWheres = transCustomFilterList(tableObj, fieldCustomFilter); + // 处理仪表板字段过滤 + String extWheres = transExtFilterList(tableObj, extFilterRequestList); + // row permissions tree + String whereTrees = transFilterTrees(tableObj, rowPermissionsTree); + // 构建sql所有参数 + List fields = new ArrayList<>(); + fields.addAll(xFields); + fields.addAll(yFields); + List wheres = new ArrayList<>(); + if (customWheres != null) wheres.add(customWheres); + if (extWheres != null) wheres.add(extWheres); + if (whereTrees != null) wheres.add(whereTrees); + List groups = new ArrayList<>(); + groups.addAll(xFields); + // 外层再次套sql + List orders = new ArrayList<>(); + orders.addAll(xOrders); + orders.addAll(yOrders); + List aggWheres = new ArrayList<>(); + aggWheres.addAll(yWheres.stream().filter(ObjectUtils::isNotEmpty).collect(Collectors.toList())); + + STGroup stg = new STGroupFile(SQLConstants.SQL_TEMPLATE); + ST st_sql = stg.getInstanceOf("querySql"); + if (CollectionUtils.isNotEmpty(xFields)) st_sql.add("groups", xFields); + if (CollectionUtils.isNotEmpty(yFields)) st_sql.add("aggregators", yFields); + if (CollectionUtils.isNotEmpty(wheres)) st_sql.add("filters", wheres); + if (ObjectUtils.isNotEmpty(tableObj)) st_sql.add("table", tableObj); + String sql = st_sql.render(); + + ST st = stg.getInstanceOf("querySql"); + SQLObj tableSQL = SQLObj.builder() + .tableName(String.format(MaxConstants.BRACKETS, sql)) + .tableAlias(String.format(TABLE_ALIAS_PREFIX, 1)) + .build(); + if (CollectionUtils.isNotEmpty(aggWheres)) st.add("filters", aggWheres); + if (CollectionUtils.isNotEmpty(orders)) st.add("orders", orders); + if (ObjectUtils.isNotEmpty(tableSQL)) st.add("table", tableSQL); + return sqlLimit(st.render(), view); + } + + @Override + public String getSQLWithPage(boolean isTable, String table, List xAxis, List fieldCustomFilter, List rowPermissionsTree, List extFilterRequestList, Datasource ds, ChartViewWithBLOBs view, PageInfo pageInfo) { + String limit = ((pageInfo.getGoPage() != null && pageInfo.getPageSize() != null) ? " LIMIT " + pageInfo.getPageSize() + " offset " + (pageInfo.getGoPage() - 1) * pageInfo.getPageSize() : ""); + if (isTable) { + return originalTableInfo(table, xAxis, fieldCustomFilter, rowPermissionsTree, extFilterRequestList, ds, view) + limit; + } else { + return originalTableInfo("(" + sqlFix(table) + ")", xAxis, fieldCustomFilter, rowPermissionsTree, extFilterRequestList, ds, view) + limit; + } + } + + private String originalTableInfo(String table, List xAxis, List fieldCustomFilter, List rowPermissionsTree, List extFilterRequestList, Datasource ds, ChartViewWithBLOBs view) { + SQLObj tableObj = SQLObj.builder() + .tableName((table.startsWith("(") && table.endsWith(")")) ? table : String.format(MaxConstants.KEYWORD_TABLE, table)) + .tableAlias(String.format(TABLE_ALIAS_PREFIX, 0)) + .build(); + + List xFields = new ArrayList<>(); + List xOrders = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(xAxis)) { + for (int i = 0; i < xAxis.size(); i++) { + ChartViewFieldDTO x = xAxis.get(i); + String originField; + if (ObjectUtils.isNotEmpty(x.getExtField()) && x.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originField = calcFieldRegex(x.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(x.getExtField()) && x.getExtField() == 1) { + originField = String.format(MaxConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getOriginName()); + } else { + if (x.getDeType() == 2 || x.getDeType() == 3) { + originField = String.format(MaxConstants.CAST, String.format(MaxConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getOriginName()), MaxConstants.DEFAULT_FLOAT_FORMAT); + } else { + originField = String.format(MaxConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getOriginName()); + } + } + String fieldAlias = String.format(SQLConstants.FIELD_ALIAS_X_PREFIX, i); + // 处理横轴字段 + xFields.add(getXFields(x, originField, fieldAlias)); + // 处理横轴排序 + if (StringUtils.isNotEmpty(x.getSort()) && !StringUtils.equalsIgnoreCase(x.getSort(), "none")) { + xOrders.add(SQLObj.builder() + .orderField(originField) + .orderAlias(fieldAlias) + .orderDirection(x.getSort()) + .build()); + } + } + } + // 处理视图中字段过滤 + String customWheres = transCustomFilterList(tableObj, fieldCustomFilter); + // 处理仪表板字段过滤 + String extWheres = transExtFilterList(tableObj, extFilterRequestList); + // row permissions tree + String whereTrees = transFilterTrees(tableObj, rowPermissionsTree); + // 构建sql所有参数 + List fields = new ArrayList<>(); + fields.addAll(xFields); + List wheres = new ArrayList<>(); + if (customWheres != null) wheres.add(customWheres); + if (extWheres != null) wheres.add(extWheres); + if (whereTrees != null) wheres.add(whereTrees); + List groups = new ArrayList<>(); + groups.addAll(xFields); + // 外层再次套sql + List orders = new ArrayList<>(); + orders.addAll(xOrders); + + STGroup stg = new STGroupFile(SQLConstants.SQL_TEMPLATE); + ST st_sql = stg.getInstanceOf("previewSql"); + st_sql.add("isGroup", false); + if (CollectionUtils.isNotEmpty(xFields)) st_sql.add("groups", xFields); + if (CollectionUtils.isNotEmpty(wheres)) st_sql.add("filters", wheres); + if (ObjectUtils.isNotEmpty(tableObj)) st_sql.add("table", tableObj); + String sql = st_sql.render(); + + ST st = stg.getInstanceOf("previewSql"); + st.add("isGroup", false); + SQLObj tableSQL = SQLObj.builder() + .tableName(String.format(MaxConstants.BRACKETS, sql)) + .tableAlias(String.format(TABLE_ALIAS_PREFIX, 1)) + .build(); + if (CollectionUtils.isNotEmpty(orders)) st.add("orders", orders); + if (ObjectUtils.isNotEmpty(tableSQL)) st.add("table", tableSQL); + return st.render(); + } + + @Override + public String getSQLTableInfo(String table, List xAxis, List fieldCustomFilter, List rowPermissionsTree, List extFilterRequestList, Datasource ds, ChartViewWithBLOBs view) { + return sqlLimit(originalTableInfo(table, xAxis, fieldCustomFilter, rowPermissionsTree, extFilterRequestList, ds, view), view); + } + + @Override + public String getSQLAsTmpTableInfo(String sql, List xAxis, List fieldCustomFilter, List rowPermissionsTree, List extFilterRequestList, Datasource ds, ChartViewWithBLOBs view) { + return getSQLTableInfo("(" + sqlFix(sql) + ")", xAxis, fieldCustomFilter, rowPermissionsTree, extFilterRequestList, ds, view); + } + + + @Override + public String getSQLAsTmp(String sql, List xAxis, List yAxis, List fieldCustomFilter, List rowPermissionsTree, List extFilterRequestList, ChartViewWithBLOBs view) { + return getSQL("(" + sqlFix(sql) + ")", xAxis, yAxis, fieldCustomFilter, rowPermissionsTree, extFilterRequestList, null, view); + } + + @Override + public String getSQLStack(String table, List xAxis, List yAxis, List fieldCustomFilter, List rowPermissionsTree, List extFilterRequestList, List extStack, Datasource ds, ChartViewWithBLOBs view) { + SQLObj tableObj = SQLObj.builder() + .tableName((table.startsWith("(") && table.endsWith(")")) ? table : String.format(MaxConstants.KEYWORD_TABLE, table)) + .tableAlias(String.format(TABLE_ALIAS_PREFIX, 0)) + .build(); + + List xFields = new ArrayList<>(); + List xOrders = new ArrayList<>(); + List xList = new ArrayList<>(); + xList.addAll(xAxis); + xList.addAll(extStack); + if (CollectionUtils.isNotEmpty(xList)) { + for (int i = 0; i < xList.size(); i++) { + ChartViewFieldDTO x = xList.get(i); + String originField; + if (ObjectUtils.isNotEmpty(x.getExtField()) && x.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originField = calcFieldRegex(x.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(x.getExtField()) && x.getExtField() == 1) { + originField = String.format(MaxConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getOriginName()); + } else { + originField = String.format(MaxConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getOriginName()); + } + String fieldAlias = String.format(SQLConstants.FIELD_ALIAS_X_PREFIX, i); + // 处理横轴字段 + xFields.add(getXFields(x, originField, fieldAlias)); + // 处理横轴排序 + if (StringUtils.isNotEmpty(x.getSort()) && !StringUtils.equalsIgnoreCase(x.getSort(), "none")) { + xOrders.add(SQLObj.builder() + .orderField(originField) + .orderAlias(fieldAlias) + .orderDirection(x.getSort()) + .build()); + } + } + } + List yFields = new ArrayList<>(); + List yWheres = new ArrayList<>(); + List yOrders = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(yAxis)) { + for (int i = 0; i < yAxis.size(); i++) { + ChartViewFieldDTO y = yAxis.get(i); + String originField; + if (ObjectUtils.isNotEmpty(y.getExtField()) && y.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originField = calcFieldRegex(y.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(y.getExtField()) && y.getExtField() == 1) { + originField = String.format(MaxConstants.KEYWORD_FIX, tableObj.getTableAlias(), y.getOriginName()); + } else { + originField = String.format(MaxConstants.KEYWORD_FIX, tableObj.getTableAlias(), y.getOriginName()); + } + String fieldAlias = String.format(SQLConstants.FIELD_ALIAS_Y_PREFIX, i); + // 处理纵轴字段 + yFields.add(getYFields(y, originField, fieldAlias)); + // 处理纵轴过滤 + yWheres.add(getYWheres(y, originField, fieldAlias)); + // 处理纵轴排序 + if (StringUtils.isNotEmpty(y.getSort()) && !StringUtils.equalsIgnoreCase(y.getSort(), "none")) { + yOrders.add(SQLObj.builder() + .orderField(originField) + .orderAlias(fieldAlias) + .orderDirection(y.getSort()) + .build()); + } + } + } + // 处理视图中字段过滤 + String customWheres = transCustomFilterList(tableObj, fieldCustomFilter); + // 处理仪表板字段过滤 + String extWheres = transExtFilterList(tableObj, extFilterRequestList); + // row permissions tree + String whereTrees = transFilterTrees(tableObj, rowPermissionsTree); + // 构建sql所有参数 + List fields = new ArrayList<>(); + fields.addAll(xFields); + fields.addAll(yFields); + List wheres = new ArrayList<>(); + if (customWheres != null) wheres.add(customWheres); + if (extWheres != null) wheres.add(extWheres); + if (whereTrees != null) wheres.add(whereTrees); + List groups = new ArrayList<>(); + groups.addAll(xFields); + // 外层再次套sql + List orders = new ArrayList<>(); + orders.addAll(xOrders); + orders.addAll(yOrders); + List aggWheres = new ArrayList<>(); + aggWheres.addAll(yWheres.stream().filter(ObjectUtils::isNotEmpty).collect(Collectors.toList())); + + STGroup stg = new STGroupFile(SQLConstants.SQL_TEMPLATE); + ST st_sql = stg.getInstanceOf("querySql"); + if (CollectionUtils.isNotEmpty(xFields)) st_sql.add("groups", xFields); + if (CollectionUtils.isNotEmpty(yFields)) st_sql.add("aggregators", yFields); + if (CollectionUtils.isNotEmpty(wheres)) st_sql.add("filters", wheres); + if (ObjectUtils.isNotEmpty(tableObj)) st_sql.add("table", tableObj); + String sql = st_sql.render(); + + ST st = stg.getInstanceOf("querySql"); + SQLObj tableSQL = SQLObj.builder() + .tableName(String.format(MaxConstants.BRACKETS, sql)) + .tableAlias(String.format(TABLE_ALIAS_PREFIX, 1)) + .build(); + if (CollectionUtils.isNotEmpty(aggWheres)) st.add("filters", aggWheres); + if (CollectionUtils.isNotEmpty(orders)) st.add("orders", orders); + if (ObjectUtils.isNotEmpty(tableSQL)) st.add("table", tableSQL); + return sqlLimit(st.render(), view); + } + + @Override + public String getSQLAsTmpStack(String table, List xAxis, List yAxis, List fieldCustomFilter, List rowPermissionsTree, List extFilterRequestList, List extStack, ChartViewWithBLOBs view) { + return getSQLStack("(" + sqlFix(table) + ")", xAxis, yAxis, fieldCustomFilter, rowPermissionsTree, extFilterRequestList, extStack, null, view); + } + + @Override + public String getSQLScatter(String table, List xAxis, List yAxis, List fieldCustomFilter, List rowPermissionsTree, List extFilterRequestList, List extBubble, Datasource ds, ChartViewWithBLOBs view) { + SQLObj tableObj = SQLObj.builder() + .tableName((table.startsWith("(") && table.endsWith(")")) ? table : String.format(MaxConstants.KEYWORD_TABLE, table)) + .tableAlias(String.format(TABLE_ALIAS_PREFIX, 0)) + .build(); + + List xFields = new ArrayList<>(); + List xOrders = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(xAxis)) { + for (int i = 0; i < xAxis.size(); i++) { + ChartViewFieldDTO x = xAxis.get(i); + String originField; + if (ObjectUtils.isNotEmpty(x.getExtField()) && x.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originField = calcFieldRegex(x.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(x.getExtField()) && x.getExtField() == 1) { + originField = String.format(MaxConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getOriginName()); + } else { + originField = String.format(MaxConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getOriginName()); + } + String fieldAlias = String.format(SQLConstants.FIELD_ALIAS_X_PREFIX, i); + // 处理横轴字段 + xFields.add(getXFields(x, originField, fieldAlias)); + // 处理横轴排序 + if (StringUtils.isNotEmpty(x.getSort()) && !StringUtils.equalsIgnoreCase(x.getSort(), "none")) { + xOrders.add(SQLObj.builder() + .orderField(originField) + .orderAlias(fieldAlias) + .orderDirection(x.getSort()) + .build()); + } + } + } + List yFields = new ArrayList<>(); + List yWheres = new ArrayList<>(); + List yOrders = new ArrayList<>(); + List yList = new ArrayList<>(); + yList.addAll(yAxis); + yList.addAll(extBubble); + if (CollectionUtils.isNotEmpty(yList)) { + for (int i = 0; i < yList.size(); i++) { + ChartViewFieldDTO y = yList.get(i); + String originField; + if (ObjectUtils.isNotEmpty(y.getExtField()) && y.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originField = calcFieldRegex(y.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(y.getExtField()) && y.getExtField() == 1) { + originField = String.format(MaxConstants.KEYWORD_FIX, tableObj.getTableAlias(), y.getOriginName()); + } else { + originField = String.format(MaxConstants.KEYWORD_FIX, tableObj.getTableAlias(), y.getOriginName()); + } + String fieldAlias = String.format(SQLConstants.FIELD_ALIAS_Y_PREFIX, i); + // 处理纵轴字段 + yFields.add(getYFields(y, originField, fieldAlias)); + // 处理纵轴过滤 + yWheres.add(getYWheres(y, originField, fieldAlias)); + // 处理纵轴排序 + if (StringUtils.isNotEmpty(y.getSort()) && !StringUtils.equalsIgnoreCase(y.getSort(), "none")) { + yOrders.add(SQLObj.builder() + .orderField(originField) + .orderAlias(fieldAlias) + .orderDirection(y.getSort()) + .build()); + } + } + } + // 处理视图中字段过滤 + String customWheres = transCustomFilterList(tableObj, fieldCustomFilter); + // 处理仪表板字段过滤 + String extWheres = transExtFilterList(tableObj, extFilterRequestList); + // row permissions tree + String whereTrees = transFilterTrees(tableObj, rowPermissionsTree); + // 构建sql所有参数 + List fields = new ArrayList<>(); + fields.addAll(xFields); + fields.addAll(yFields); + List wheres = new ArrayList<>(); + if (customWheres != null) wheres.add(customWheres); + if (extWheres != null) wheres.add(extWheres); + if (whereTrees != null) wheres.add(whereTrees); + List groups = new ArrayList<>(); + groups.addAll(xFields); + // 外层再次套sql + List orders = new ArrayList<>(); + orders.addAll(xOrders); + orders.addAll(yOrders); + List aggWheres = new ArrayList<>(); + aggWheres.addAll(yWheres.stream().filter(ObjectUtils::isNotEmpty).collect(Collectors.toList())); + + STGroup stg = new STGroupFile(SQLConstants.SQL_TEMPLATE); + ST st_sql = stg.getInstanceOf("querySql"); + if (CollectionUtils.isNotEmpty(xFields)) st_sql.add("groups", xFields); + if (CollectionUtils.isNotEmpty(yFields)) st_sql.add("aggregators", yFields); + if (CollectionUtils.isNotEmpty(wheres)) st_sql.add("filters", wheres); + if (ObjectUtils.isNotEmpty(tableObj)) st_sql.add("table", tableObj); + String sql = st_sql.render(); + + ST st = stg.getInstanceOf("querySql"); + SQLObj tableSQL = SQLObj.builder() + .tableName(String.format(MaxConstants.BRACKETS, sql)) + .tableAlias(String.format(TABLE_ALIAS_PREFIX, 1)) + .build(); + if (CollectionUtils.isNotEmpty(aggWheres)) st.add("filters", aggWheres); + if (CollectionUtils.isNotEmpty(orders)) st.add("orders", orders); + if (ObjectUtils.isNotEmpty(tableSQL)) st.add("table", tableSQL); + return sqlLimit(st.render(), view); + } + + @Override + public String getSQLAsTmpScatter(String table, List xAxis, List yAxis, List fieldCustomFilter, List rowPermissionsTree, List extFilterRequestList, List extBubble, ChartViewWithBLOBs view) { + return getSQLScatter("(" + sqlFix(table) + ")", xAxis, yAxis, fieldCustomFilter, rowPermissionsTree, extFilterRequestList, extBubble, null, view); + } + + @Override + public String searchTable(String table) { + return "SELECT table_name FROM information_schema.TABLES WHERE table_name ='" + table + "'"; + } + + @Override + public String getSQLSummary(String table, List yAxis, List fieldCustomFilter, List rowPermissionsTree, List extFilterRequestList, ChartViewWithBLOBs view, Datasource ds) { + // 字段汇总 排序等 + SQLObj tableObj = SQLObj.builder() + .tableName((table.startsWith("(") && table.endsWith(")")) ? table : String.format(MaxConstants.KEYWORD_TABLE, table)) + .tableAlias(String.format(TABLE_ALIAS_PREFIX, 0)) + .build(); + + List yFields = new ArrayList<>(); + List yWheres = new ArrayList<>(); + List yOrders = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(yAxis)) { + for (int i = 0; i < yAxis.size(); i++) { + ChartViewFieldDTO y = yAxis.get(i); + String originField; + if (ObjectUtils.isNotEmpty(y.getExtField()) && y.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originField = calcFieldRegex(y.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(y.getExtField()) && y.getExtField() == 1) { + originField = String.format(MaxConstants.KEYWORD_FIX, tableObj.getTableAlias(), y.getOriginName()); + } else { + originField = String.format(MaxConstants.KEYWORD_FIX, tableObj.getTableAlias(), y.getOriginName()); + } + String fieldAlias = String.format(SQLConstants.FIELD_ALIAS_Y_PREFIX, i); + // 处理纵轴字段 + yFields.add(getYFields(y, originField, fieldAlias)); + // 处理纵轴过滤 + yWheres.add(getYWheres(y, originField, fieldAlias)); + // 处理纵轴排序 + if (StringUtils.isNotEmpty(y.getSort()) && !StringUtils.equalsIgnoreCase(y.getSort(), "none")) { + yOrders.add(SQLObj.builder() + .orderField(originField) + .orderAlias(fieldAlias) + .orderDirection(y.getSort()) + .build()); + } + } + } + // 处理视图中字段过滤 + String customWheres = transCustomFilterList(tableObj, fieldCustomFilter); + // 处理仪表板字段过滤 + String extWheres = transExtFilterList(tableObj, extFilterRequestList); + // row permissions tree + String whereTrees = transFilterTrees(tableObj, rowPermissionsTree); + // 构建sql所有参数 + List fields = new ArrayList<>(); + fields.addAll(yFields); + List wheres = new ArrayList<>(); + if (customWheres != null) wheres.add(customWheres); + if (extWheres != null) wheres.add(extWheres); + if (whereTrees != null) wheres.add(whereTrees); + List groups = new ArrayList<>(); + // 外层再次套sql + List orders = new ArrayList<>(); + orders.addAll(yOrders); + List aggWheres = new ArrayList<>(); + aggWheres.addAll(yWheres.stream().filter(ObjectUtils::isNotEmpty).collect(Collectors.toList())); + + STGroup stg = new STGroupFile(SQLConstants.SQL_TEMPLATE); + ST st_sql = stg.getInstanceOf("querySql"); + if (CollectionUtils.isNotEmpty(yFields)) st_sql.add("aggregators", yFields); + if (CollectionUtils.isNotEmpty(wheres)) st_sql.add("filters", wheres); + if (ObjectUtils.isNotEmpty(tableObj)) st_sql.add("table", tableObj); + String sql = st_sql.render(); + + ST st = stg.getInstanceOf("querySql"); + SQLObj tableSQL = SQLObj.builder() + .tableName(String.format(MaxConstants.BRACKETS, sql)) + .tableAlias(String.format(TABLE_ALIAS_PREFIX, 1)) + .build(); + if (CollectionUtils.isNotEmpty(aggWheres)) st.add("filters", aggWheres); + if (CollectionUtils.isNotEmpty(orders)) st.add("orders", orders); + if (ObjectUtils.isNotEmpty(tableSQL)) st.add("table", tableSQL); + return sqlLimit(st.render(), view); + } + + @Override + public String getSQLSummaryAsTmp(String sql, List yAxis, List fieldCustomFilter, List rowPermissionsTree, List extFilterRequestList, ChartViewWithBLOBs view) { + return getSQLSummary("(" + sqlFix(sql) + ")", yAxis, fieldCustomFilter, rowPermissionsTree, extFilterRequestList, view, null); + } + + @Override + public String wrapSql(String sql) { + sql = sql.trim(); + if (sql.lastIndexOf(";") == (sql.length() - 1)) { + sql = sql.substring(0, sql.length() - 1); + } + String tmpSql = "SELECT * FROM (" + sql + ") AS tmp " + " LIMIT 0 "; + return tmpSql; + } + + @Override + public String createRawQuerySQL(String table, List fields, Datasource ds) { + String[] array = fields.stream().map(f -> { + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.append("\"").append(f.getOriginName()).append("\" AS ").append(f.getDataeaseName()); + return stringBuilder.toString(); + }).toArray(String[]::new); + if (ds != null) { + String schema = new Gson().fromJson(ds.getConfiguration(), JdbcConfiguration.class).getSchema(); + String tableWithSchema = String.format(SqlServerSQLConstants.KEYWORD_TABLE, schema) + "." + String.format(SqlServerSQLConstants.KEYWORD_TABLE, table); + return MessageFormat.format("SELECT {0} FROM {1} ", StringUtils.join(array, ","), tableWithSchema); + } else { + return MessageFormat.format("SELECT {0} FROM {1} ", StringUtils.join(array, ","), table); + } + } + + @Override + public String createRawQuerySQLAsTmp(String sql, List fields) { + return createRawQuerySQL(" (" + sqlFix(sql) + ") AS tmp ", fields, null); + } + + @Override + public String transTreeItem(SQLObj tableObj, DatasetRowPermissionsTreeItem item) { + String res = null; + DatasetTableField field = item.getField(); + if (ObjectUtils.isEmpty(field)) { + return null; + } + String whereName = ""; + String originName; + if (ObjectUtils.isNotEmpty(field.getExtField()) && field.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originName = calcFieldRegex(field.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(field.getExtField()) && field.getExtField() == 1) { + originName = String.format(MaxConstants.KEYWORD_FIX, tableObj.getTableAlias(), field.getOriginName()); + } else { + originName = String.format(MaxConstants.KEYWORD_FIX, tableObj.getTableAlias(), field.getOriginName()); + } + if (field.getDeType() == 1) { + if (field.getDeExtractType() == 0 || field.getDeExtractType() == 5) { + whereName = String.format(MaxConstants.TO_DATE, originName, StringUtils.isNotEmpty(field.getDateFormat()) ? field.getDateFormat() : MaxConstants.DEFAULT_DATE_FORMAT); + } + if (field.getDeExtractType() == 2 || field.getDeExtractType() == 3 || field.getDeExtractType() == 4) { + String cast = String.format(MaxConstants.CAST, originName, "bigint"); + whereName = String.format(MaxConstants.FROM_UNIXTIME, cast); + } + if (field.getDeExtractType() == 1) { + whereName = originName; + } + } else if (field.getDeType() == 2 || field.getDeType() == 3) { + if (field.getDeExtractType() == 0 || field.getDeExtractType() == 5) { + whereName = String.format(MaxConstants.CAST, originName, MaxConstants.DEFAULT_FLOAT_FORMAT); + } + if (field.getDeExtractType() == 1) { + whereName = String.format(MaxConstants.UNIX_TIMESTAMP, originName); + } + if (field.getDeExtractType() == 2 || field.getDeExtractType() == 3 || field.getDeExtractType() == 4) { + whereName = originName; + } + } else { + whereName = originName; + } + + if (StringUtils.equalsIgnoreCase(item.getFilterType(), "enum")) { + if (CollectionUtils.isNotEmpty(item.getEnumValue())) { + res = "(" + whereName + " IN ('" + String.join("','", item.getEnumValue()) + "'))"; + } + } else { + String value = item.getValue(); + String whereTerm = transMysqlFilterTerm(item.getTerm()); + String whereValue = ""; + + if (StringUtils.equalsIgnoreCase(item.getTerm(), "null")) { + whereValue = ""; + } else if (StringUtils.equalsIgnoreCase(item.getTerm(), "not_null")) { + whereValue = ""; + } else if (StringUtils.equalsIgnoreCase(item.getTerm(), "empty")) { + whereValue = "''"; + } else if (StringUtils.equalsIgnoreCase(item.getTerm(), "not_empty")) { + whereValue = "''"; + } else if (StringUtils.containsIgnoreCase(item.getTerm(), "in") || StringUtils.containsIgnoreCase(item.getTerm(), "not in")) { + whereValue = "('" + String.join("','", value.split(",")) + "')"; + } else if (StringUtils.containsIgnoreCase(item.getTerm(), "like")) { + whereValue = "'%" + value + "%'"; + } else { + whereValue = String.format(MaxConstants.WHERE_VALUE_VALUE, value); + } + SQLObj build = SQLObj.builder() + .whereField(whereName) + .whereTermAndValue(whereTerm + whereValue) + .build(); + res = build.getWhereField() + " " + build.getWhereTermAndValue(); + } + return res; + } + + @Override + public String convertTableToSql(String tableName, Datasource ds) { + String schema = new Gson().fromJson(ds.getConfiguration(), JdbcConfiguration.class).getSchema(); + schema = String.format(MaxConstants.KEYWORD_TABLE, schema); + return createSQLPreview("SELECT * FROM " + schema + "." + String.format(MaxConstants.KEYWORD_TABLE, tableName), null); + } + + public String transMysqlFilterTerm(String term) { + switch (term) { + case "eq": + return " = "; + case "not_eq": + return " <> "; + case "lt": + return " < "; + case "le": + return " <= "; + case "gt": + return " > "; + case "ge": + return " >= "; + case "in": + return " IN "; + case "not in": + return " NOT IN "; + case "like": + return " LIKE "; + case "not like": + return " NOT LIKE "; + case "null": + return " IS NULL "; + case "not_null": + return " IS NOT NULL "; + case "empty": + return " = "; + case "not_empty": + return " <> "; + case "between": + return " BETWEEN "; + default: + return ""; + } + } + + public String transCustomFilterList(SQLObj tableObj, List requestList) { + if (CollectionUtils.isEmpty(requestList)) { + return null; + } + List res = new ArrayList<>(); + for (ChartFieldCustomFilterDTO request : requestList) { + List list = new ArrayList<>(); + DatasetTableField field = request.getField(); + + if (ObjectUtils.isEmpty(field)) { + continue; + } + String whereName = ""; + String originName; + if (ObjectUtils.isNotEmpty(field.getExtField()) && field.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originName = calcFieldRegex(field.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(field.getExtField()) && field.getExtField() == 1) { + originName = String.format(MaxConstants.KEYWORD_FIX, tableObj.getTableAlias(), field.getOriginName()); + } else { + originName = String.format(MaxConstants.KEYWORD_FIX, tableObj.getTableAlias(), field.getOriginName()); + } + if (field.getDeType() == 1) { + if (field.getDeExtractType() == 0 || field.getDeExtractType() == 5) { + whereName = String.format(MaxConstants.TO_DATE, originName, StringUtils.isNotEmpty(field.getDateFormat()) ? field.getDateFormat() : MaxConstants.DEFAULT_DATE_FORMAT); + } + if (field.getDeExtractType() == 2 || field.getDeExtractType() == 3 || field.getDeExtractType() == 4) { + String cast = String.format(MaxConstants.CAST, originName, "bigint"); + whereName = String.format(MaxConstants.FROM_UNIXTIME, cast); + } + if (field.getDeExtractType() == 1) { + whereName = originName; + } + } else if (field.getDeType() == 2 || field.getDeType() == 3) { + if (field.getDeExtractType() == 0 || field.getDeExtractType() == 5) { + whereName = String.format(MaxConstants.CAST, originName, MaxConstants.DEFAULT_FLOAT_FORMAT); + } + if (field.getDeExtractType() == 1) { + whereName = String.format(MaxConstants.UNIX_TIMESTAMP, originName); + } + if (field.getDeExtractType() == 2 || field.getDeExtractType() == 3 || field.getDeExtractType() == 4) { + whereName = originName; + } + } else { + whereName = originName; + } + + if (StringUtils.equalsIgnoreCase(request.getFilterType(), "enum")) { + if (CollectionUtils.isNotEmpty(request.getEnumCheckField())) { + res.add("(" + whereName + " IN ('" + String.join("','", request.getEnumCheckField()) + "'))"); + } + } else { + List filter = request.getFilter(); + for (ChartCustomFilterItemDTO filterItemDTO : filter) { + String value = filterItemDTO.getValue(); + String whereTerm = transMysqlFilterTerm(filterItemDTO.getTerm()); + String whereValue = ""; + + if (StringUtils.equalsIgnoreCase(filterItemDTO.getTerm(), "null")) { + whereValue = ""; + } else if (StringUtils.equalsIgnoreCase(filterItemDTO.getTerm(), "not_null")) { + whereValue = ""; + } else if (StringUtils.equalsIgnoreCase(filterItemDTO.getTerm(), "empty")) { + whereValue = "''"; + } else if (StringUtils.equalsIgnoreCase(filterItemDTO.getTerm(), "not_empty")) { + whereValue = "''"; + } else if (StringUtils.containsIgnoreCase(filterItemDTO.getTerm(), "in") || StringUtils.containsIgnoreCase(filterItemDTO.getTerm(), "not in")) { + whereValue = "('" + String.join("','", value.split(",")) + "')"; + } else if (StringUtils.containsIgnoreCase(filterItemDTO.getTerm(), "like")) { + whereValue = "'%" + value + "%'"; + } else { + whereValue = String.format(MaxConstants.WHERE_VALUE_VALUE, value); + } + list.add(SQLObj.builder() + .whereField(whereName) + .whereTermAndValue(whereTerm + whereValue) + .build()); + } + + List strList = new ArrayList<>(); + list.forEach(ele -> strList.add(ele.getWhereField() + " " + ele.getWhereTermAndValue())); + if (CollectionUtils.isNotEmpty(list)) { + res.add("(" + String.join(" " + getLogic(request.getLogic()) + " ", strList) + ")"); + } + } + } + return CollectionUtils.isNotEmpty(res) ? "(" + String.join(" AND ", res) + ")" : null; + } + + public String transExtFilterList(SQLObj tableObj, List requestList) { + if (CollectionUtils.isEmpty(requestList)) { + return null; + } + List list = new ArrayList<>(); + for (ChartExtFilterRequest request : requestList) { + List value = request.getValue(); + + List whereNameList = new ArrayList<>(); + List fieldList = new ArrayList<>(); + if (request.getIsTree()) { + fieldList.addAll(request.getDatasetTableFieldList()); + } else { + fieldList.add(request.getDatasetTableField()); + } + + for (DatasetTableField field : fieldList) { + if (CollectionUtils.isEmpty(value) || ObjectUtils.isEmpty(field)) { + continue; + } + String whereName = ""; + + String originName; + if (ObjectUtils.isNotEmpty(field.getExtField()) && field.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originName = calcFieldRegex(field.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(field.getExtField()) && field.getExtField() == 1) { + originName = String.format(MaxConstants.KEYWORD_FIX, tableObj.getTableAlias(), field.getOriginName()); + } else { + originName = String.format(MaxConstants.KEYWORD_FIX, tableObj.getTableAlias(), field.getOriginName()); + } + + if (field.getDeType() == 1) { + if (field.getDeExtractType() == 0 || field.getDeExtractType() == 5) { + whereName = String.format(MaxConstants.TO_DATE, originName, StringUtils.isNotEmpty(field.getDateFormat()) ? field.getDateFormat() : MaxConstants.DEFAULT_DATE_FORMAT); + } + if (field.getDeExtractType() == 2 || field.getDeExtractType() == 3 || field.getDeExtractType() == 4) { + String cast = String.format(MaxConstants.CAST, originName, "bigint"); + whereName = String.format(MaxConstants.FROM_UNIXTIME, cast); + } + if (field.getDeExtractType() == 1) { + whereName = originName; + } + } else if (field.getDeType() == 2 || field.getDeType() == 3) { + if (field.getDeExtractType() == 0 || field.getDeExtractType() == 5) { + whereName = String.format(MaxConstants.CAST, originName, MaxConstants.DEFAULT_FLOAT_FORMAT); + } + if (field.getDeExtractType() == 1) { + whereName = String.format(MaxConstants.UNIX_TIMESTAMP, originName); + } + if (field.getDeExtractType() == 2 || field.getDeExtractType() == 3 || field.getDeExtractType() == 4) { + whereName = originName; + } + } else { + whereName = originName; + } + whereNameList.add(whereName); + } + + String whereName = ""; + if (request.getIsTree()) { + whereName = "CONCAT(" + StringUtils.join(whereNameList, ",',',") + ")"; + } else { + whereName = whereNameList.get(0); + } + String whereTerm = transMysqlFilterTerm(request.getOperator()); + String whereValue = ""; + + if (StringUtils.containsIgnoreCase(request.getOperator(), "in")) { + whereValue = "('" + StringUtils.join(value, "','") + "')"; + } else if (StringUtils.containsIgnoreCase(request.getOperator(), "like")) { + String keyword = value.get(0).toUpperCase(); + whereValue = "'%" + keyword + "%'"; + whereName = "upper(" + whereName + ")"; + } else if (StringUtils.containsIgnoreCase(request.getOperator(), "between")) { + if (request.getDatasetTableField().getDeType() == 1) { + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + String startTime = simpleDateFormat.format(new Date(Long.parseLong(value.get(0)))); + String endTime = simpleDateFormat.format(new Date(Long.parseLong(value.get(1)))); + whereValue = String.format(MaxConstants.WHERE_BETWEEN, startTime, endTime); + } else { + whereValue = String.format(MaxConstants.WHERE_BETWEEN, value.get(0), value.get(1)); + } + } else { + whereValue = String.format(MaxConstants.WHERE_VALUE_VALUE, value.get(0)); + } + list.add(SQLObj.builder() + .whereField(whereName) + .whereTermAndValue(whereTerm + whereValue) + .build()); + } + List strList = new ArrayList<>(); + list.forEach(ele -> strList.add(ele.getWhereField() + " " + ele.getWhereTermAndValue())); + return CollectionUtils.isNotEmpty(list) ? "(" + String.join(" AND ", strList) + ")" : null; + } + + private String sqlFix(String sql) { + if (sql.lastIndexOf(";") == (sql.length() - 1)) { + sql = sql.substring(0, sql.length() - 1); + } + return sql; + } + + private String transDateFormat(String dateStyle, String datePattern) { + String split = "-"; + if (StringUtils.equalsIgnoreCase(datePattern, "date_sub")) { + split = "-"; + } else if (StringUtils.equalsIgnoreCase(datePattern, "date_split")) { + split = "/"; + } else { + split = "-"; + } + + if (StringUtils.isEmpty(dateStyle)) { + return "yyyy-mm-dd hh:mi:ss"; + } + + switch (dateStyle) { + case "y": + return "yyyy"; + case "y_M": + return "yyyy" + split + "mm"; + case "y_M_d": + return "yyyy" + split + "mm" + split + "dd"; + case "H_m_s": + return "hh:mi:ss"; + case "y_M_d_H_m": + return "yyyy" + split + "mm" + split + "dd" + " hh:mi"; + case "y_M_d_H_m_s": + return "yyyy" + split + "mm" + split + "dd" + " hh:mi:ss"; + default: + return "yyyy-mm-dd hh:mi:s"; + } + } + + private SQLObj getXFields(ChartViewFieldDTO x, String originField, String fieldAlias) { + String fieldName = ""; + if (x.getDeExtractType() == DeTypeConstants.DE_TIME) { + if (x.getDeType() == 2 || x.getDeType() == 3) { + fieldName = String.format(MaxConstants.UNIX_TIMESTAMP, originField); + } else if (x.getDeType() == DeTypeConstants.DE_TIME) { + String format = transDateFormat(x.getDateStyle(), x.getDatePattern()); + fieldName = String.format(MaxConstants.DATE_FORMAT, originField, format); + } else { + fieldName = originField; + } + } else { + if (x.getDeType() == DeTypeConstants.DE_TIME) { + String format = transDateFormat(x.getDateStyle(), x.getDatePattern()); + if (x.getDeExtractType() == DeTypeConstants.DE_STRING) { + fieldName = String.format(MaxConstants.TO_DATE, originField, StringUtils.isNotEmpty(x.getDateFormat()) ? x.getDateFormat() : MaxConstants.DEFAULT_DATE_FORMAT); + } else { + String cast = String.format(MaxConstants.CAST, originField, "bigint"); + String from_unixtime = String.format(MaxConstants.FROM_UNIXTIME, cast); + fieldName = String.format(MaxConstants.DATE_FORMAT, from_unixtime, format); + } + } else { + if (x.getDeType() == DeTypeConstants.DE_INT) { + fieldName = String.format(MaxConstants.CAST, originField, MaxConstants.DEFAULT_INT_FORMAT); + } else if (x.getDeType() == DeTypeConstants.DE_FLOAT) { + fieldName = String.format(MaxConstants.CAST, originField, MaxConstants.DEFAULT_FLOAT_FORMAT); + } else { + fieldName = originField; + } + } + } + return SQLObj.builder() + .fieldName(fieldName) + .fieldAlias(fieldAlias) + .build(); + } + + private SQLObj getYFields(ChartViewFieldDTO y, String originField, String fieldAlias) { + String fieldName = ""; + if (StringUtils.equalsIgnoreCase(y.getOriginName(), "*")) { + fieldName = MaxConstants.AGG_COUNT; + } else if (SQLConstants.DIMENSION_TYPE.contains(y.getDeType())) { + fieldName = String.format(MaxConstants.AGG_FIELD, y.getSummary(), originField); + } else { + if (StringUtils.equalsIgnoreCase(y.getSummary(), "avg") || StringUtils.containsIgnoreCase(y.getSummary(), "pop")) { + String cast = String.format(MaxConstants.CAST, originField, y.getDeType() == DeTypeConstants.DE_INT ? MaxConstants.DEFAULT_INT_FORMAT : MaxConstants.DEFAULT_FLOAT_FORMAT); + String agg = String.format(MaxConstants.AGG_FIELD, y.getSummary(), cast); + fieldName = String.format(MaxConstants.CAST, agg, MaxConstants.DEFAULT_FLOAT_FORMAT); + } else { + String cast = String.format(MaxConstants.CAST, originField, y.getDeType() == DeTypeConstants.DE_INT ? MaxConstants.DEFAULT_INT_FORMAT : MaxConstants.DEFAULT_FLOAT_FORMAT); + fieldName = String.format(MaxConstants.AGG_FIELD, y.getSummary(), cast); + } + } + return SQLObj.builder() + .fieldName(fieldName) + .fieldAlias(fieldAlias) + .build(); + } + + private String getYWheres(ChartViewFieldDTO y, String originField, String fieldAlias) { + List list = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(y.getFilter()) && y.getFilter().size() > 0) { + y.getFilter().forEach(f -> { + String whereTerm = transMysqlFilterTerm(f.getTerm()); + String whereValue = ""; + // 原始类型不是时间,在de中被转成时间的字段做处理 + if (StringUtils.equalsIgnoreCase(f.getTerm(), "null")) { + whereValue = ""; + } else if (StringUtils.equalsIgnoreCase(f.getTerm(), "not_null")) { + whereValue = ""; + } else if (StringUtils.equalsIgnoreCase(f.getTerm(), "empty")) { + whereValue = "''"; + } else if (StringUtils.equalsIgnoreCase(f.getTerm(), "not_empty")) { + whereValue = "''"; + } else if (StringUtils.containsIgnoreCase(f.getTerm(), "in")) { + whereValue = "('" + StringUtils.join(f.getValue(), "','") + "')"; + } else if (StringUtils.containsIgnoreCase(f.getTerm(), "like")) { + whereValue = "'%" + f.getValue() + "%'"; + } else { + whereValue = String.format(MaxConstants.WHERE_VALUE_VALUE, f.getValue()); + } + list.add(SQLObj.builder() + .whereField(fieldAlias) + .whereAlias(fieldAlias) + .whereTermAndValue(whereTerm + whereValue) + .build()); + }); + } + List strList = new ArrayList<>(); + list.forEach(ele -> strList.add(ele.getWhereField() + " " + ele.getWhereTermAndValue())); + return CollectionUtils.isNotEmpty(list) ? "(" + String.join(" " + getLogic(y.getLogic()) + " ", strList) + ")" : null; + } + + private String calcFieldRegex(String originField, SQLObj tableObj) { + originField = originField.replaceAll("[\\t\\n\\r]]", ""); + // 正则提取[xxx] + String regex = "\\[(.*?)]"; + Pattern pattern = Pattern.compile(regex); + Matcher matcher = pattern.matcher(originField); + Set ids = new HashSet<>(); + while (matcher.find()) { + String id = matcher.group(1); + ids.add(id); + } + if (CollectionUtils.isEmpty(ids)) { + return originField; + } + DatasetTableFieldExample datasetTableFieldExample = new DatasetTableFieldExample(); + datasetTableFieldExample.createCriteria().andIdIn(new ArrayList<>(ids)); + List calcFields = datasetTableFieldMapper.selectByExample(datasetTableFieldExample); + for (DatasetTableField ele : calcFields) { + originField = originField.replaceAll("\\[" + ele.getId() + "]", + String.format(MaxConstants.KEYWORD_FIX, tableObj.getTableAlias(), ele.getOriginName())); + } + return originField; + } + + private String sqlLimit(String sql, ChartViewWithBLOBs view) { + if (StringUtils.equalsIgnoreCase(view.getResultMode(), "custom")) { + return sql + " LIMIT " + view.getResultCount() + " offset 0"; + } else { + return sql; + } + } + + public List dateformat() { + ObjectMapper objectMapper = new ObjectMapper(); + List dateformats = new ArrayList<>(); + try{ + dateformats = objectMapper.readValue("[\n" + + "{\"dateformat\": \"yyyymmdd\"},\n" + + "{\"dateformat\": \"yyyy/mm/dd\"},\n" + + "{\"dateformat\": \"yyyy-mm-dd\"},\n" + + "{\"dateformat\": \"yyyymmdd hh:mi:s\"},\n" + + "{\"dateformat\": \"yyyy/mm/dd hh:mi:s\"},\n" + + "{\"dateformat\": \"yyyy-mm-dd hh:mi:s\"}\n" + + "]", new TypeReference>() {} ); + }catch (Exception e){} + return dateformats; + } +} diff --git a/extensions/dataease-extensions-datasource/maxcompute/maxcompute-backend/src/main/java/io/dataease/plugins/datasource/dm/service/MaxcomputeService.java b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-backend/src/main/java/io/dataease/plugins/datasource/dm/service/MaxcomputeService.java new file mode 100644 index 0000000000..a6217a4f1d --- /dev/null +++ b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-backend/src/main/java/io/dataease/plugins/datasource/dm/service/MaxcomputeService.java @@ -0,0 +1,58 @@ +package io.dataease.plugins.datasource.dm.service; + +import io.dataease.plugins.common.constants.DatabaseClassification; +import io.dataease.plugins.common.constants.DatasourceCalculationMode; +import io.dataease.plugins.common.dto.StaticResource; +import io.dataease.plugins.common.dto.datasource.DataSourceType; +import io.dataease.plugins.datasource.service.DatasourceService; +import org.springframework.stereotype.Service; + +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + +@Service +public class MaxcomputeService extends DatasourceService { + + + @Override + public List components() { + List result = new ArrayList<>(); + result.add("maxcompute"); + return result; + } + @Override + protected InputStream readContent(String s) { + InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream("static/" + s); + return resourceAsStream; + } + + @Override + public List staticResources() { + List results = new ArrayList<>(); + StaticResource staticResource = new StaticResource(); + staticResource.setName("maxcompute"); + staticResource.setSuffix("jpg"); + results.add(staticResource); + results.add(pluginSvg()); + return results; + } + + @Override + public DataSourceType getDataSourceType() { + DataSourceType dataSourceType = new DataSourceType("maxcompute", "Maxcompute" , true , "", DatasourceCalculationMode.DIRECT, true); + dataSourceType.setKeywordPrefix("\""); + dataSourceType.setKeywordSuffix("\""); + dataSourceType.setAliasPrefix("\""); + dataSourceType.setAliasSuffix("\""); + dataSourceType.setDatabaseClassification(DatabaseClassification.DL); + return dataSourceType; + } + + private StaticResource pluginSvg() { + StaticResource staticResource = new StaticResource(); + staticResource.setName("maxcompute-backend"); + staticResource.setSuffix("svg"); + return staticResource; + } +} diff --git a/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/.babelrc b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/.babelrc new file mode 100644 index 0000000000..3a280ba34b --- /dev/null +++ b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/.babelrc @@ -0,0 +1,12 @@ +{ + "presets": [ + ["env", { + "modules": false, + "targets": { + "browsers": ["> 1%", "last 2 versions", "not ie <= 8"] + } + }], + "stage-2" + ], + "plugins": ["transform-vue-jsx", "transform-runtime"] +} diff --git a/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/.editorconfig b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/.editorconfig new file mode 100644 index 0000000000..9d08a1a828 --- /dev/null +++ b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/.editorconfig @@ -0,0 +1,9 @@ +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true diff --git a/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/.gitignore b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/.gitignore new file mode 100644 index 0000000000..541a820f6c --- /dev/null +++ b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/.gitignore @@ -0,0 +1,14 @@ +.DS_Store +node_modules/ +/dist/ +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Editor directories and files +.idea +.vscode +*.suo +*.ntvs* +*.njsproj +*.sln diff --git a/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/.postcssrc.js b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/.postcssrc.js new file mode 100644 index 0000000000..eee3e92d7f --- /dev/null +++ b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/.postcssrc.js @@ -0,0 +1,10 @@ +// https://github.com/michael-ciniawsky/postcss-load-config + +module.exports = { + "plugins": { + "postcss-import": {}, + "postcss-url": {}, + // to edit target browsers: use "browserslist" field in package.json + "autoprefixer": {} + } +} diff --git a/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/README.md b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/README.md new file mode 100644 index 0000000000..c1e4be95e0 --- /dev/null +++ b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/README.md @@ -0,0 +1,21 @@ +# deplugin-view-frontend + +> A Vue.js project + +## Build Setup + +``` bash +# install dependencies +npm install + +# serve with hot reload at localhost:8080 +npm run dev + +# build for production with minification +npm run build + +# build for production and view the bundle analyzer report +npm run build --report +``` + +For a detailed explanation on how things work, check out the [guide](http://vuejs-templates.github.io/webpack/) and [docs for vue-loader](http://vuejs.github.io/vue-loader). diff --git a/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/build/build-async-plugins.js b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/build/build-async-plugins.js new file mode 100644 index 0000000000..2303854531 --- /dev/null +++ b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/build/build-async-plugins.js @@ -0,0 +1,35 @@ +'use strict' +require('./check-versions')() + +process.env.NODE_ENV = 'production' + +const ora = require('ora') +const chalk = require('chalk') +const webpack = require('webpack') +const webpackConfig = require('./webpack.async-plugins') + +const spinner = ora('building for sync-plugins...') +spinner.start() + +webpack(webpackConfig, function (err, stats) { + spinner.stop() + if (err) throw err + process.stdout.write(stats.toString({ + colors: true, + modules: false, + children: false, + chunks: false, + chunkModules: false + }) + '\n\n') + + if (stats.hasErrors()) { + console.log(chalk.red(' Build failed with errors.\n')) + process.exit(1) + } + + console.log(chalk.cyan(' Build complete.\n')) + console.log(chalk.yellow( + ' Tip: built files are meant to be served over an HTTP server.\n' + + ' Opening index.html over file:// won\'t work.\n' + )) +}) diff --git a/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/build/build.js b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/build/build.js new file mode 100644 index 0000000000..8f2ad8ad49 --- /dev/null +++ b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/build/build.js @@ -0,0 +1,41 @@ +'use strict' +require('./check-versions')() + +process.env.NODE_ENV = 'production' + +const ora = require('ora') +const rm = require('rimraf') +const path = require('path') +const chalk = require('chalk') +const webpack = require('webpack') +const config = require('../config') +const webpackConfig = require('./webpack.prod.conf') + +const spinner = ora('building for production...') +spinner.start() + +rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => { + if (err) throw err + webpack(webpackConfig, (err, stats) => { + spinner.stop() + if (err) throw err + process.stdout.write(stats.toString({ + colors: true, + modules: false, + children: false, // If you are using ts-loader, setting this to true will make TypeScript errors show up during build. + chunks: false, + chunkModules: false + }) + '\n\n') + + if (stats.hasErrors()) { + console.log(chalk.red(' Build failed with errors.\n')) + process.exit(1) + } + + console.log(chalk.cyan(' Build complete.\n')) + console.log(chalk.yellow( + ' Tip: built files are meant to be served over an HTTP server.\n' + + ' Opening index.html over file:// won\'t work.\n' + )) + }) +}) diff --git a/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/build/check-versions.js b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/build/check-versions.js new file mode 100644 index 0000000000..3ef972a08d --- /dev/null +++ b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/build/check-versions.js @@ -0,0 +1,54 @@ +'use strict' +const chalk = require('chalk') +const semver = require('semver') +const packageConfig = require('../package.json') +const shell = require('shelljs') + +function exec (cmd) { + return require('child_process').execSync(cmd).toString().trim() +} + +const versionRequirements = [ + { + name: 'node', + currentVersion: semver.clean(process.version), + versionRequirement: packageConfig.engines.node + } +] + +if (shell.which('npm')) { + versionRequirements.push({ + name: 'npm', + currentVersion: exec('npm --version'), + versionRequirement: packageConfig.engines.npm + }) +} + +module.exports = function () { + const warnings = [] + + for (let i = 0; i < versionRequirements.length; i++) { + const mod = versionRequirements[i] + + if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) { + warnings.push(mod.name + ': ' + + chalk.red(mod.currentVersion) + ' should be ' + + chalk.green(mod.versionRequirement) + ) + } + } + + if (warnings.length) { + console.log('') + console.log(chalk.yellow('To use this template, you must update following to modules:')) + console.log() + + for (let i = 0; i < warnings.length; i++) { + const warning = warnings[i] + console.log(' ' + warning) + } + + console.log() + process.exit(1) + } +} diff --git a/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/build/logo.png b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/build/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..f3d2503fc2a44b5053b0837ebea6e87a2d339a43 GIT binary patch literal 6849 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 { + const notifier = require('node-notifier') + + return (severity, errors) => { + if (severity !== 'error') return + + const error = errors[0] + const filename = error.file && error.file.split('!').pop() + + notifier.notify({ + title: packageConfig.name, + message: severity + ': ' + error.name, + subtitle: filename || '', + icon: path.join(__dirname, 'logo.png') + }) + } +} diff --git a/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/build/vue-loader.conf.js b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/build/vue-loader.conf.js new file mode 100644 index 0000000000..33ed58bc0a --- /dev/null +++ b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/build/vue-loader.conf.js @@ -0,0 +1,22 @@ +'use strict' +const utils = require('./utils') +const config = require('../config') +const isProduction = process.env.NODE_ENV === 'production' +const sourceMapEnabled = isProduction + ? config.build.productionSourceMap + : config.dev.cssSourceMap + +module.exports = { + loaders: utils.cssLoaders({ + sourceMap: sourceMapEnabled, + extract: isProduction + }), + cssSourceMap: sourceMapEnabled, + cacheBusting: config.dev.cacheBusting, + transformToRequire: { + video: ['src', 'poster'], + source: 'src', + img: 'src', + image: 'xlink:href' + } +} diff --git a/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/build/webpack.async-plugins.js b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/build/webpack.async-plugins.js new file mode 100644 index 0000000000..437ebaccdc --- /dev/null +++ b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/build/webpack.async-plugins.js @@ -0,0 +1,91 @@ +const webpack = require('webpack') +const path = require('path') +const utils = require('./utils') +const CopyPlugin = require("copy-webpack-plugin"); +const VueLoaderPlugin = require('vue-loader/lib/plugin'); +function resolve (dir) { + return path.join(__dirname, '..', dir) +} + +module.exports = { + mode: 'development', + entry: { + 'maxcompute': resolve('/src/views/maxcompute.vue') + }, + output: { + path: resolve('/static/'), + filename: '[name].js' + }, + resolve: { + extensions: ['.js', '.vue', '.json'], + alias: { + 'vue$': 'vue/dist/vue.esm.js', + '@': resolve('src') + } + }, + externals: { + vue: 'vue' + }, + module: { + rules: [ + { + test: /\.vue$/, + loader: 'vue-loader', + options: { + transformAssetUrls: { + video: 'src', + source: 'src', + img: 'src', + image: 'xlink:href' + } + } + }, + { + test: /.(sa|sc|c)ss$/, + use: [ + {loader: 'vue-style-loader'}, + 'css-loader', + 'sass-loader' + ] + }, + { + test: /\.js$/, + loader: 'babel-loader', + include: [resolve('src'), resolve('test')] + }, + { + test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: utils.assetsPath('img/[name].[hash:7].[ext]') + } + }, + { + test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: utils.assetsPath('media/[name].[hash:7].[ext]') + } + }, + { + test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: utils.assetsPath('fonts/[name].[hash:7].[ext]') + } + } + ] + }, + plugins: [ + new VueLoaderPlugin(), + new webpack.DefinePlugin({ + 'process.env.NODE_ENV': '"production"' + }), + new CopyPlugin([ + {from: 'src/icons/svg/'} + ]), + ] +} diff --git a/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/build/webpack.base.conf.js b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/build/webpack.base.conf.js new file mode 100644 index 0000000000..6ccc02dab4 --- /dev/null +++ b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/build/webpack.base.conf.js @@ -0,0 +1,91 @@ +'use strict' +const path = require('path') +const utils = require('./utils') +const config = require('../config') +const vueLoaderConfig = require('./vue-loader.conf') + +function resolve (dir) { + return path.join(__dirname, '..', dir) +} + + + +module.exports = { + context: path.resolve(__dirname, '../'), + entry: { + app: './src/main.js' + }, + output: { + path: config.build.assetsRoot, + filename: '[name].js', + publicPath: process.env.NODE_ENV === 'production' + ? config.build.assetsPublicPath + : config.dev.assetsPublicPath + }, + resolve: { + extensions: ['.js', '.vue', '.json'], + alias: { + 'vue$': 'vue/dist/vue.esm.js', + '@': resolve('src'), + } + }, + module: { + rules: [ + { + test: /\.vue$/, + loader: 'vue-loader', + options: vueLoaderConfig + }, + { + test: /\.js$/, + loader: 'babel-loader', + include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')] + }, + { + test: /\.svg$/, + loader: 'svg-sprite-loader', + include: [resolve('src/icons')], + options: { + symbolId: 'icon-[name]' + } + }, + { + test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, + loader: 'url-loader', + exclude: [resolve('src/icons')], + options: { + limit: 10000, + name: utils.assetsPath('img/[name].[hash:7].[ext]') + } + }, + { + test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: utils.assetsPath('media/[name].[hash:7].[ext]') + } + }, + { + test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: utils.assetsPath('fonts/[name].[hash:7].[ext]') + } + } + ] + }, + node: { + // prevent webpack from injecting useless setImmediate polyfill because Vue + // source contains it (although only uses it if it's native). + setImmediate: false, + // prevent webpack from injecting mocks to Node native modules + // that does not make sense for the client + dgram: 'empty', + fs: 'empty', + net: 'empty', + tls: 'empty', + child_process: 'empty' + } +} diff --git a/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/build/webpack.dev.conf.js b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/build/webpack.dev.conf.js new file mode 100755 index 0000000000..070ae221f3 --- /dev/null +++ b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/build/webpack.dev.conf.js @@ -0,0 +1,95 @@ +'use strict' +const utils = require('./utils') +const webpack = require('webpack') +const config = require('../config') +const merge = require('webpack-merge') +const path = require('path') +const baseWebpackConfig = require('./webpack.base.conf') +const CopyWebpackPlugin = require('copy-webpack-plugin') +const HtmlWebpackPlugin = require('html-webpack-plugin') +const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin') +const portfinder = require('portfinder') + +const HOST = process.env.HOST +const PORT = process.env.PORT && Number(process.env.PORT) + +const devWebpackConfig = merge(baseWebpackConfig, { + module: { + rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true }) + }, + // cheap-module-eval-source-map is faster for development + devtool: config.dev.devtool, + + // these devServer options should be customized in /config/index.js + devServer: { + clientLogLevel: 'warning', + historyApiFallback: { + rewrites: [ + { from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') }, + ], + }, + hot: true, + contentBase: false, // since we use CopyWebpackPlugin. + compress: true, + host: HOST || config.dev.host, + port: PORT || config.dev.port, + open: config.dev.autoOpenBrowser, + overlay: config.dev.errorOverlay + ? { warnings: false, errors: true } + : false, + publicPath: config.dev.assetsPublicPath, + proxy: config.dev.proxyTable, + quiet: true, // necessary for FriendlyErrorsPlugin + watchOptions: { + poll: config.dev.poll, + } + }, + plugins: [ + new webpack.DefinePlugin({ + 'process.env': require('../config/dev.env') + }), + new webpack.HotModuleReplacementPlugin(), + new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update. + new webpack.NoEmitOnErrorsPlugin(), + // https://github.com/ampedandwired/html-webpack-plugin + new HtmlWebpackPlugin({ + filename: 'index.html', + template: 'index.html', + inject: true + }), + // copy custom static assets + new CopyWebpackPlugin([ + { + from: path.resolve(__dirname, '../static'), + to: config.dev.assetsSubDirectory, + ignore: ['.*'] + } + ]) + ] +}) + +module.exports = new Promise((resolve, reject) => { + portfinder.basePort = process.env.PORT || config.dev.port + portfinder.getPort((err, port) => { + if (err) { + reject(err) + } else { + // publish the new Port, necessary for e2e tests + process.env.PORT = port + // add port to devServer config + devWebpackConfig.devServer.port = port + + // Add FriendlyErrorsPlugin + devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({ + compilationSuccessInfo: { + messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`], + }, + onErrors: config.dev.notifyOnErrors + ? utils.createNotifierCallback() + : undefined + })) + + resolve(devWebpackConfig) + } + }) +}) diff --git a/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/build/webpack.prod.conf.js b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/build/webpack.prod.conf.js new file mode 100644 index 0000000000..3e25238ef6 --- /dev/null +++ b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/build/webpack.prod.conf.js @@ -0,0 +1,145 @@ +'use strict' +const path = require('path') +const utils = require('./utils') +const webpack = require('webpack') +const config = require('../config') +const merge = require('webpack-merge') +const baseWebpackConfig = require('./webpack.base.conf') +const CopyWebpackPlugin = require('copy-webpack-plugin') +const HtmlWebpackPlugin = require('html-webpack-plugin') +const ExtractTextPlugin = require('extract-text-webpack-plugin') +const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin') +const UglifyJsPlugin = require('uglifyjs-webpack-plugin') + +const env = require('../config/prod.env') + +const webpackConfig = merge(baseWebpackConfig, { + module: { + rules: utils.styleLoaders({ + sourceMap: config.build.productionSourceMap, + extract: true, + usePostCSS: true + }) + }, + devtool: config.build.productionSourceMap ? config.build.devtool : false, + output: { + path: config.build.assetsRoot, + filename: utils.assetsPath('js/[name].[chunkhash].js'), + chunkFilename: utils.assetsPath('js/[id].[chunkhash].js') + }, + plugins: [ + // http://vuejs.github.io/vue-loader/en/workflow/production.html + new webpack.DefinePlugin({ + 'process.env': env + }), + new UglifyJsPlugin({ + uglifyOptions: { + compress: { + warnings: false + } + }, + sourceMap: config.build.productionSourceMap, + parallel: true + }), + // extract css into its own file + new ExtractTextPlugin({ + filename: utils.assetsPath('css/[name].[contenthash].css'), + // Setting the following option to `false` will not extract CSS from codesplit chunks. + // Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack. + // It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`, + // increasing file size: https://github.com/vuejs-templates/webpack/issues/1110 + allChunks: true, + }), + // Compress extracted CSS. We are using this plugin so that possible + // duplicated CSS from different components can be deduped. + new OptimizeCSSPlugin({ + cssProcessorOptions: config.build.productionSourceMap + ? { safe: true, map: { inline: false } } + : { safe: true } + }), + // generate dist index.html with correct asset hash for caching. + // you can customize output by editing /index.html + // see https://github.com/ampedandwired/html-webpack-plugin + new HtmlWebpackPlugin({ + filename: config.build.index, + template: 'index.html', + inject: true, + minify: { + removeComments: true, + collapseWhitespace: true, + removeAttributeQuotes: true + // more options: + // https://github.com/kangax/html-minifier#options-quick-reference + }, + // necessary to consistently work with multiple chunks via CommonsChunkPlugin + chunksSortMode: 'dependency' + }), + // keep module.id stable when vendor modules does not change + new webpack.HashedModuleIdsPlugin(), + // enable scope hoisting + new webpack.optimize.ModuleConcatenationPlugin(), + // split vendor js into its own file + new webpack.optimize.CommonsChunkPlugin({ + name: 'vendor', + minChunks (module) { + // any required modules inside node_modules are extracted to vendor + return ( + module.resource && + /\.js$/.test(module.resource) && + module.resource.indexOf( + path.join(__dirname, '../node_modules') + ) === 0 + ) + } + }), + // extract webpack runtime and module manifest to its own file in order to + // prevent vendor hash from being updated whenever app bundle is updated + new webpack.optimize.CommonsChunkPlugin({ + name: 'manifest', + minChunks: Infinity + }), + // This instance extracts shared chunks from code split chunks and bundles them + // in a separate chunk, similar to the vendor chunk + // see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk + new webpack.optimize.CommonsChunkPlugin({ + name: 'app', + async: 'vendor-async', + children: true, + minChunks: 3 + }), + + // copy custom static assets + new CopyWebpackPlugin([ + { + from: path.resolve(__dirname, '../static'), + to: config.build.assetsSubDirectory, + ignore: ['.*'] + } + ]) + ] +}) + +if (config.build.productionGzip) { + const CompressionWebpackPlugin = require('compression-webpack-plugin') + + webpackConfig.plugins.push( + new CompressionWebpackPlugin({ + asset: '[path].gz[query]', + algorithm: 'gzip', + test: new RegExp( + '\\.(' + + config.build.productionGzipExtensions.join('|') + + ')$' + ), + threshold: 10240, + minRatio: 0.8 + }) + ) +} + +if (config.build.bundleAnalyzerReport) { + const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin + webpackConfig.plugins.push(new BundleAnalyzerPlugin()) +} + +module.exports = webpackConfig diff --git a/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/config/dev.env.js b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/config/dev.env.js new file mode 100644 index 0000000000..1e22973ae7 --- /dev/null +++ b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/config/dev.env.js @@ -0,0 +1,7 @@ +'use strict' +const merge = require('webpack-merge') +const prodEnv = require('./prod.env') + +module.exports = merge(prodEnv, { + NODE_ENV: '"development"' +}) diff --git a/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/config/index.js b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/config/index.js new file mode 100644 index 0000000000..c5eded7f81 --- /dev/null +++ b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/config/index.js @@ -0,0 +1,69 @@ +'use strict' +// Template version: 1.3.1 +// see http://vuejs-templates.github.io/webpack for documentation. + +const path = require('path') + +module.exports = { + dev: { + + // Paths + assetsSubDirectory: 'static', + assetsPublicPath: '/', + proxyTable: {}, + + // Various Dev Server settings + host: 'localhost', // can be overwritten by process.env.HOST + port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined + autoOpenBrowser: false, + errorOverlay: true, + notifyOnErrors: true, + poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions- + + + /** + * Source Maps + */ + + // https://webpack.js.org/configuration/devtool/#development + devtool: 'cheap-module-eval-source-map', + + // If you have problems debugging vue-files in devtools, + // set this to false - it *may* help + // https://vue-loader.vuejs.org/en/options.html#cachebusting + cacheBusting: true, + + cssSourceMap: true + }, + + build: { + // Template for index.html + index: path.resolve(__dirname, '../dist/index.html'), + + // Paths + assetsRoot: path.resolve(__dirname, '../dist'), + assetsSubDirectory: 'static', + assetsPublicPath: '/', + + /** + * Source Maps + */ + + productionSourceMap: true, + // https://webpack.js.org/configuration/devtool/#production + devtool: '#source-map', + + // Gzip off by default as many popular static hosts such as + // Surge or Netlify already gzip all static assets for you. + // Before setting to `true`, make sure to: + // npm install --save-dev compression-webpack-plugin + productionGzip: false, + productionGzipExtensions: ['js', 'css'], + + // Run the build command with an extra argument to + // View the bundle analyzer report after build finishes: + // `npm run build --report` + // Set to `true` or `false` to always turn it on or off + bundleAnalyzerReport: process.env.npm_config_report + } +} diff --git a/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/config/prod.env.js b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/config/prod.env.js new file mode 100644 index 0000000000..a6f997616e --- /dev/null +++ b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/config/prod.env.js @@ -0,0 +1,4 @@ +'use strict' +module.exports = { + NODE_ENV: '"production"' +} diff --git a/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/index.html b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/index.html new file mode 100644 index 0000000000..03ce3fdf27 --- /dev/null +++ b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/index.html @@ -0,0 +1,12 @@ + + + + + + deplugin-view-frontend + + +

+ + + diff --git a/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/package.json b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/package.json new file mode 100644 index 0000000000..c7e40d6f1b --- /dev/null +++ b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/package.json @@ -0,0 +1,73 @@ +{ + "name": "deplugin-datasource-frontend", + "version": "1.0.0", + "description": "A Vue.js project", + "author": "", + "private": true, + "scripts": { + "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js", + "start": "npm run dev", + "build": "node build/build.js", + "buildPlugin": "node build/build-async-plugins.js" + }, + "dependencies": { + "@riophae/vue-treeselect": "0.4.0", + "highcharts": "^10.0.0", + "vue": "^2.5.2", + "vue-i18n": "7.3.2", + "vue-router": "^3.0.1", + "vue-uuid": "2.0.2", + "vuedraggable": "^2.24.3" + }, + "devDependencies": { + "autoprefixer": "^7.1.2", + "babel-core": "^6.22.1", + "babel-helper-vue-jsx-merge-props": "^2.0.3", + "babel-loader": "^7.1.1", + "babel-plugin-syntax-jsx": "^6.18.0", + "babel-plugin-transform-runtime": "^6.22.0", + "babel-plugin-transform-vue-jsx": "^3.5.0", + "babel-preset-env": "^1.3.2", + "babel-preset-stage-2": "^6.22.0", + "chalk": "^2.0.1", + "copy-webpack-plugin": "^4.6.0", + "css-loader": "^0.28.0", + "element-ui": "2.15.7", + "extract-text-webpack-plugin": "^4.0.0-beta.0", + "file-loader": "^1.1.4", + "friendly-errors-webpack-plugin": "^1.6.1", + "html-webpack-plugin": "^3.2.0", + "js-cookie": "2.2.0", + "node-notifier": "^8.0.1", + "optimize-css-assets-webpack-plugin": "^3.2.0", + "ora": "^1.2.0", + "portfinder": "^1.0.13", + "postcss-import": "^11.0.0", + "postcss-loader": "^2.0.8", + "postcss-url": "^7.2.1", + "rimraf": "^2.6.0", + "sass": "^1.33.0", + "sass-loader": "^7.3.1", + "semver": "^5.3.0", + "shelljs": "^0.8.5", + "svg-sprite-loader": "4.1.3", + "uglifyjs-webpack-plugin": "^1.1.1", + "url-loader": "^0.5.8", + "vue-loader": "^15.6.4", + "vue-style-loader": "^4.1.2", + "vue-template-compiler": "^2.5.2", + "webpack": "^4.8.1", + "webpack-bundle-analyzer": "^3.3.2", + "webpack-dev-server": "^3.1.11", + "webpack-merge": "^4.1.0" + }, + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + }, + "browserslist": [ + "> 1%", + "last 2 versions", + "not ie <= 8" + ] +} diff --git a/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/pom.xml b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/pom.xml new file mode 100644 index 0000000000..80e4c1305f --- /dev/null +++ b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/pom.xml @@ -0,0 +1,80 @@ + + + + + io.dataease + maxcompute + ${dataease.version} + + + 4.0.0 + maxcompute-frontend + + + UTF-8 + UTF-8 + 1.9.1 + + + + + + maven-clean-plugin + + + + static + + ** + + false + + + + + + + + com.github.eirslett + frontend-maven-plugin + ${frontend-maven-plugin.version} + + + install node and npm + + install-node-and-npm + + + + v16.20.2 + 7.6.3 + + + + + npm install + + npm + + + + install --force + + + + + npm run buildPlugin + + npm + + + run buildPlugin + + + + + + + diff --git a/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/src/App.vue b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/src/App.vue new file mode 100644 index 0000000000..8542e07722 --- /dev/null +++ b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/src/App.vue @@ -0,0 +1,23 @@ + + + + + diff --git a/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/src/assets/logo.png b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/src/assets/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..f3d2503fc2a44b5053b0837ebea6e87a2d339a43 GIT binary patch literal 6849 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 +
+

{{ msg }}

+

Essential Links

+ +

Ecosystem

+ +
+ + + + + + diff --git a/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/src/de-base/lang/en.js b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/src/de-base/lang/en.js new file mode 100644 index 0000000000..f8e5328b3d --- /dev/null +++ b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/src/de-base/lang/en.js @@ -0,0 +1,15 @@ +export default { + plugin_view_3d_pie: { + type_title: '3D-PIE', + label: 'Label', + angle: 'Angle' + }, + end_point: 'End Point', + projectName: 'Project Name', + access_id: 'Access ID', + access_key: 'Access Key', + query_timeout: 'Query timeout (seconds)', + second: 'second', + please_select: 'Please select', + query_timeout: 'query timeout', +} diff --git a/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/src/de-base/lang/index.js b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/src/de-base/lang/index.js new file mode 100644 index 0000000000..e50d0478e6 --- /dev/null +++ b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/src/de-base/lang/index.js @@ -0,0 +1,49 @@ +import Vue from 'vue' +import VueI18n from 'vue-i18n' +import Cookies from 'js-cookie' +import elementEnLocale from 'element-ui/lib/locale/lang/en' // element-ui lang +import elementZhLocale from 'element-ui/lib/locale/lang/zh-CN'// element-ui lang +import elementTWLocale from 'element-ui/lib/locale/lang/zh-TW'// element-ui lang + +import localMessages from './messages' + + +Vue.use(VueI18n) + +const messages = { + en_US: { + ...localMessages['en_US'], + ...elementEnLocale + }, + zh_CN: { + ...localMessages['zh_CN'], + ...elementZhLocale + }, + zh_TW: { + ...localMessages['zh_TW'], + ...elementTWLocale + } +} +export function getLanguage () { + const chooseLanguage = Cookies.get('language') + if (chooseLanguage) return chooseLanguage + + // if has not choose language + const language = (navigator.language || navigator.browserLanguage).toLowerCase() + const locales = Object.keys(messages) + for (const locale of locales) { + if (language.indexOf(locale) > -1) { + return locale + } + } + return 'zh_CN' +} +const i18n = new VueI18n({ + // set locale + // options: en | zh | es + locale: getLanguage(), + // set locale messages + messages +}) + +export default i18n diff --git a/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/src/de-base/lang/messages.js b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/src/de-base/lang/messages.js new file mode 100644 index 0000000000..844f8c0673 --- /dev/null +++ b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/src/de-base/lang/messages.js @@ -0,0 +1,17 @@ +import enLocale from './en' +import zhLocale from './zh' +import twLocale from './tw' + +const messages = { + en_US: { + ...enLocale + }, + zh_CN: { + ...zhLocale + }, + zh_TW: { + ...twLocale + } +} + +export default messages \ No newline at end of file diff --git a/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/src/de-base/lang/tw.js b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/src/de-base/lang/tw.js new file mode 100644 index 0000000000..5f64c42884 --- /dev/null +++ b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/src/de-base/lang/tw.js @@ -0,0 +1,15 @@ +export default { + plugin_view_3d_pie: { + type_title: '3D餅圖', + label: '標籤', + angle: '角度' + }, + end_point: 'End Point', + projectName: '項目名稱', + access_id: 'Access ID', + access_key: 'Access Key', + query_timeout: '査詢超時(秒)', + second: '秒', + please_select: '請選擇', + query_timeout: '査詢超時', +} diff --git a/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/src/de-base/lang/zh.js b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/src/de-base/lang/zh.js new file mode 100644 index 0000000000..901bfe2881 --- /dev/null +++ b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/src/de-base/lang/zh.js @@ -0,0 +1,15 @@ +export default { + plugin_view_3d_pie: { + type_title: '3D饼图', + label: '标签', + angle: '角度' + }, + end_point: 'End Point', + projectName: '项目名称', + access_id: 'Access ID', + access_key: 'Access Key', + query_timeout: '查询超时(秒)', + second: '秒', + please_select: '请选择', + query_timeout: '查询超时' +} diff --git a/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/src/icons/index.js b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/src/icons/index.js new file mode 100644 index 0000000000..2c6b309c96 --- /dev/null +++ b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/src/icons/index.js @@ -0,0 +1,9 @@ +import Vue from 'vue' +import SvgIcon from '@/components/SvgIcon'// svg component + +// register globally +Vue.component('svg-icon', SvgIcon) + +const req = require.context('./svg', false, /\.svg$/) +const requireAll = requireContext => requireContext.keys().map(requireContext) +requireAll(req) diff --git a/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/src/icons/svg/maxcompute-backend.svg b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/src/icons/svg/maxcompute-backend.svg new file mode 100644 index 0000000000..0075728ce5 --- /dev/null +++ b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/src/icons/svg/maxcompute-backend.svg @@ -0,0 +1 @@ +【icon】插件管理-导出 diff --git a/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/src/icons/svg/maxcompute.jpg b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/src/icons/svg/maxcompute.jpg new file mode 100644 index 0000000000000000000000000000000000000000..679e0fea021ce66c6a93780d6fb238e573d203ba GIT binary patch literal 6965 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 V;E6lZ~ueCXP&dE{{l4=)-eD8 literal 0 HcmV?d00001 diff --git a/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/src/icons/svgo.yml b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/src/icons/svgo.yml new file mode 100644 index 0000000000..d11906aec2 --- /dev/null +++ b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/src/icons/svgo.yml @@ -0,0 +1,22 @@ +# replace default config + +# multipass: true +# full: true + +plugins: + + # - name + # + # or: + # - name: false + # - name: true + # + # or: + # - name: + # param1: 1 + # param2: 2 + +- removeAttrs: + attrs: + - 'fill' + - 'fill-rule' diff --git a/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/src/main.js b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/src/main.js new file mode 100644 index 0000000000..99c5626590 --- /dev/null +++ b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/src/main.js @@ -0,0 +1,33 @@ +// The Vue build version to load with the `import` command +// (runtime-only or standalone) has been set in webpack.base.conf with an alias. +import Vue from 'vue' +import App from './App' +import router from './router' +import ElementUI from 'element-ui' +import Cookies from 'js-cookie' +import i18n from './de-base/lang' +import draggable from 'vuedraggable' +import Treeselect from '@riophae/vue-treeselect' +import '@riophae/vue-treeselect/dist/vue-treeselect.css' +Vue.config.productionTip = false +Vue.use(ElementUI, { + size: Cookies.get('size') || 'medium', + i18n: (key, value) => i18n.t(key, value) +}) +Vue.component('Treeselect', Treeselect) +Vue.component('draggable', draggable) +Vue.prototype.hasDataPermission = function(pTarget, pSource) { + + if (pSource && pTarget) { + return pSource.indexOf(pTarget) > -1 + } + return false +} +/* eslint-disable no-new */ +new Vue({ + el: '#app', + router, + i18n, + components: { App }, + template: '' +}) diff --git a/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/src/router/index.js b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/src/router/index.js new file mode 100644 index 0000000000..b5b55fa1fc --- /dev/null +++ b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/src/router/index.js @@ -0,0 +1,21 @@ +import Vue from 'vue' +import Router from 'vue-router' +import HelloWorld from '@/components/HelloWorld' +import maxcompute from '@/views/maxcompute' + +Vue.use(Router) + +export default new Router({ + routes: [ + { + path: '/', + name: 'HelloWorld', + component: HelloWorld + }, + { + path: '/maxcompute', + name: 'maxcompute', + component: maxcompute + } + ] +}) diff --git a/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/src/utils/compare.js b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/src/utils/compare.js new file mode 100644 index 0000000000..b06a104a10 --- /dev/null +++ b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/src/utils/compare.js @@ -0,0 +1,29 @@ +export const compareItem = { + type: 'none', // year-yoy/month-yoy等 + resultData: 'percent', // 对比差sub,百分比percent等 + field: '', + custom: { + field: '', + calcType: '0', // 0-增长值,1-增长率 + timeType: '0', // 0-固定日期,1-日期区间 + currentTime: '', + compareTime: '', + currentTimeRange: [], + compareTimeRange: [] + } +} + +export const compareYearList = [ + { name: 'year_mom', value: 'year_mom' } +] + +export const compareMonthList = [ + { name: 'month_mom', value: 'month_mom' }, + { name: 'year_yoy', value: 'year_yoy' } +] + +export const compareDayList = [ + { name: 'day_mom', value: 'day_mom' }, + { name: 'month_yoy', value: 'month_yoy' }, + { name: 'year_yoy', value: 'year_yoy' } +] diff --git a/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/src/utils/validate.js b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/src/utils/validate.js new file mode 100644 index 0000000000..3e8ffa9448 --- /dev/null +++ b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/src/utils/validate.js @@ -0,0 +1,15 @@ +/** + * Created by PanJiaChen on 16/11/18. + */ + +/** + * @param {string} path + * @returns {Boolean} + */ +export function isExternal(path) { + return /^(https?:|mailto:|tel:)/.test(path) || /^(http?:|mailto:|tel:)/.test(path) || path.startsWith('/api/pluginCommon/staticInfo') +} + + + + diff --git a/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/src/views/maxcompute.vue b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/src/views/maxcompute.vue new file mode 100644 index 0000000000..a155689f5a --- /dev/null +++ b/extensions/dataease-extensions-datasource/maxcompute/maxcompute-frontend/src/views/maxcompute.vue @@ -0,0 +1,164 @@ + + + + + diff --git a/extensions/dataease-extensions-datasource/maxcompute/plugin.json b/extensions/dataease-extensions-datasource/maxcompute/plugin.json new file mode 100644 index 0000000000..e7ea9b7ab2 --- /dev/null +++ b/extensions/dataease-extensions-datasource/maxcompute/plugin.json @@ -0,0 +1,13 @@ +{ + "name":"Maxcompute 数据源插件", + "free":0, + "store":"default", + "cost":0, + "category":"datasource", + "descript":"Maxcompute 插件,值得拥有", + "version":"1.18.0", + "creator":"DATAEASE", + "moduleName":"maxcompute-backend", + "require":"1.10.0", + "dsType":"maxcompute" +} diff --git a/extensions/dataease-extensions-datasource/maxcompute/pom.xml b/extensions/dataease-extensions-datasource/maxcompute/pom.xml new file mode 100644 index 0000000000..5b6a677dbc --- /dev/null +++ b/extensions/dataease-extensions-datasource/maxcompute/pom.xml @@ -0,0 +1,19 @@ + + + + dataease-extensions-datasource + io.dataease + ${dataease.version} + + 4.0.0 + + maxcompute + pom + + maxcompute-frontend + maxcompute-backend + + + diff --git a/extensions/dataease-extensions-datasource/mongo/build.sh b/extensions/dataease-extensions-datasource/mongo/build.sh new file mode 100755 index 0000000000..99feee776d --- /dev/null +++ b/extensions/dataease-extensions-datasource/mongo/build.sh @@ -0,0 +1,6 @@ +#!/bin/sh +mvn clean package -U -Dmaven.test.skip=true + +cp mongo-backend/target/mongo-backend-1.18.0.jar . + +zip -r mongo.zip ./mongo-backend-1.18.0.jar ./mongobiDriver ./plugin.json diff --git a/extensions/dataease-extensions-datasource/mongo/mongo-backend/pom.xml b/extensions/dataease-extensions-datasource/mongo/mongo-backend/pom.xml new file mode 100644 index 0000000000..e52800fdb0 --- /dev/null +++ b/extensions/dataease-extensions-datasource/mongo/mongo-backend/pom.xml @@ -0,0 +1,109 @@ + + + + mongo + io.dataease + ${dataease.version} + + 4.0.0 + + mongo-backend + + + + io.dataease + dataease-plugin-datasource + + + + + + + src/main/java + + **/*.properties + **/*.xml + + false + + + src/main/resources + + **/* + + false + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 11 + 11 + + + + + org.apache.maven.plugins + maven-jar-plugin + 2.4 + + + **/server/** + **/*.properties + **/Application* + + + + + + maven-clean-plugin + + + + src/main/resources/static + + ** + + false + + + + + + + + + org.apache.maven.plugins + maven-antrun-plugin + + + main-class-placement + generate-resources + + + + + + + + + + + + run + + + + + + + + + + + diff --git a/extensions/dataease-extensions-datasource/mongo/mongo-backend/src/main/java/io/dataease/plugins/datasource/mongo/provider/MongoConfig.java b/extensions/dataease-extensions-datasource/mongo/mongo-backend/src/main/java/io/dataease/plugins/datasource/mongo/provider/MongoConfig.java new file mode 100644 index 0000000000..d6ef05151a --- /dev/null +++ b/extensions/dataease-extensions-datasource/mongo/mongo-backend/src/main/java/io/dataease/plugins/datasource/mongo/provider/MongoConfig.java @@ -0,0 +1,23 @@ +package io.dataease.plugins.datasource.mongo.provider; + +import io.dataease.plugins.datasource.entity.JdbcConfiguration; +import lombok.Getter; +import lombok.Setter; +import org.apache.commons.lang3.StringUtils; + +@Getter +@Setter +public class MongoConfig extends JdbcConfiguration { + + private String driver = "com.mysql.jdbc.Driver"; + + private String extraParams; + + public String getJdbc() { + return "jdbc:mysql://HOSTNAME:PORT/DATABASE?EXTRA_PARAMS" + .replace("HOSTNAME", getHost().trim()) + .replace("PORT", getPort().toString().trim()) + .replace("DATABASE", getDataBase().trim()) + .replace("EXTRA_PARAMS", getExtraParams().trim()); + } +} diff --git a/extensions/dataease-extensions-datasource/mongo/mongo-backend/src/main/java/io/dataease/plugins/datasource/mongo/provider/MongobiDsProvider.java b/extensions/dataease-extensions-datasource/mongo/mongo-backend/src/main/java/io/dataease/plugins/datasource/mongo/provider/MongobiDsProvider.java new file mode 100644 index 0000000000..979ee476d2 --- /dev/null +++ b/extensions/dataease-extensions-datasource/mongo/mongo-backend/src/main/java/io/dataease/plugins/datasource/mongo/provider/MongobiDsProvider.java @@ -0,0 +1,134 @@ +package io.dataease.plugins.datasource.mongo.provider; + +import com.google.gson.Gson; +import io.dataease.plugins.common.base.domain.DeDriver; +import io.dataease.plugins.common.base.mapper.DeDriverMapper; +import io.dataease.plugins.common.dto.datasource.TableDesc; +import io.dataease.plugins.common.dto.datasource.TableField; +import io.dataease.plugins.common.exception.DataEaseException; +import io.dataease.plugins.common.request.datasource.DatasourceRequest; +import io.dataease.plugins.datasource.entity.JdbcConfiguration; +import io.dataease.plugins.datasource.mongo.query.MongoConstants; +import io.dataease.plugins.datasource.provider.DefaultJdbcProvider; +import io.dataease.plugins.datasource.provider.ExtendedJdbcClassLoader; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.lang.reflect.Method; +import java.sql.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; + + +@Component() +public class MongobiDsProvider extends DefaultJdbcProvider { + @Resource + private DeDriverMapper deDriverMapper; + + @Override + public String getType() { + return "mongobi"; + } + + @Override + public boolean isUseDatasourcePool() { + return false; + } + + @Override + public Connection getConnection(DatasourceRequest datasourceRequest) throws Exception { + MongoConfig mongoConfig = new Gson().fromJson(datasourceRequest.getDatasource().getConfiguration(), MongoConfig.class); + + String defaultDriver = mongoConfig.getDriver(); + String customDriver = mongoConfig.getCustomDriver(); + + String url = mongoConfig.getJdbc(); + Properties props = new Properties(); + DeDriver deDriver = null; + if (StringUtils.isNotBlank(mongoConfig.getUsername())) { + props.setProperty("user", mongoConfig.getUsername()); + if (StringUtils.isNotBlank(mongoConfig.getPassword())) { + props.setProperty("password", mongoConfig.getPassword()); + } + } + + Connection conn; + String driverClassName ; + ExtendedJdbcClassLoader jdbcClassLoader; + if(isDefaultClassLoader(customDriver)){ + driverClassName = defaultDriver; + jdbcClassLoader = extendedJdbcClassLoader; + }else { + if(deDriver == null){ + deDriver = deDriverMapper.selectByPrimaryKey(customDriver); + } + driverClassName = deDriver.getDriverClass(); + jdbcClassLoader = getCustomJdbcClassLoader(deDriver); + } + + Driver driverClass = (Driver) jdbcClassLoader.loadClass(driverClassName).newInstance(); + ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + try { + Thread.currentThread().setContextClassLoader(jdbcClassLoader); + conn= driverClass.connect(url, props); + }catch (Exception e){ + e.printStackTrace(); + throw e; + }finally { + Thread.currentThread().setContextClassLoader(classLoader); + } + return conn; + } + + @Override + public List getTables(DatasourceRequest datasourceRequest) throws Exception { + List tables = new ArrayList<>(); + String queryStr = getTablesSql(datasourceRequest); + JdbcConfiguration jdbcConfiguration = new Gson().fromJson(datasourceRequest.getDatasource().getConfiguration(), JdbcConfiguration.class); + int queryTimeout = jdbcConfiguration.getQueryTimeout() > 0 ? jdbcConfiguration.getQueryTimeout() : 0; + try (Connection con = getConnectionFromPool(datasourceRequest); Statement statement = getStatement(con, queryTimeout); ResultSet resultSet = statement.executeQuery(queryStr)) { + while (resultSet.next()) { + tables.add(getTableDesc(datasourceRequest, resultSet)); + } + } catch (Exception e) { + DataEaseException.throwException(e); + } + + return tables; + } + + private TableDesc getTableDesc(DatasourceRequest datasourceRequest, ResultSet resultSet) throws SQLException { + TableDesc tableDesc = new TableDesc(); + tableDesc.setName(resultSet.getString(1)); + return tableDesc; + } + + @Override + public List getTableFields(DatasourceRequest datasourceRequest) throws Exception { + + datasourceRequest.setQuery("select * from " + String.format(MongoConstants.KEYWORD_TABLE, datasourceRequest.getTable()) + " limit 0"); + return fetchResultField(datasourceRequest); + } + + @Override + public String checkStatus(DatasourceRequest datasourceRequest) throws Exception { + String queryStr = getTablesSql(datasourceRequest); + JdbcConfiguration jdbcConfiguration = new Gson().fromJson(datasourceRequest.getDatasource().getConfiguration(), JdbcConfiguration.class); + int queryTimeout = jdbcConfiguration.getQueryTimeout() > 0 ? jdbcConfiguration.getQueryTimeout() : 0; + try (Connection con = getConnection(datasourceRequest); Statement statement = getStatement(con, queryTimeout); ResultSet resultSet = statement.executeQuery(queryStr)) { + } catch (Exception e) { + e.printStackTrace(); + DataEaseException.throwException(e.getMessage()); + } + return "Success"; + } + + + @Override + public String getTablesSql(DatasourceRequest datasourceRequest) throws Exception { + return "show tables"; + } + +} diff --git a/extensions/dataease-extensions-datasource/mongo/mongo-backend/src/main/java/io/dataease/plugins/datasource/mongo/query/MongoConstants.java b/extensions/dataease-extensions-datasource/mongo/mongo-backend/src/main/java/io/dataease/plugins/datasource/mongo/query/MongoConstants.java new file mode 100644 index 0000000000..a6610fad69 --- /dev/null +++ b/extensions/dataease-extensions-datasource/mongo/mongo-backend/src/main/java/io/dataease/plugins/datasource/mongo/query/MongoConstants.java @@ -0,0 +1,51 @@ +package io.dataease.plugins.datasource.mongo.query; + + + +import io.dataease.plugins.common.constants.datasource.SQLConstants; + +import static io.dataease.plugins.common.constants.DatasourceTypes.mysql; + +public class MongoConstants extends SQLConstants { + + public static final String KEYWORD_TABLE = mysql.getKeywordPrefix() + "%s" + mysql.getKeywordSuffix(); + + public static final String KEYWORD_FIX = "%s." + mysql.getKeywordPrefix() + "%s" + mysql.getKeywordSuffix(); + + public static final String ALIAS_FIX = mysql.getAliasPrefix() + "%s" + mysql.getAliasSuffix(); + + public static final String UNIX_TIMESTAMP = "UNIX_TIMESTAMP(%s)"; + + public static final String DATE_FORMAT = "DATE_FORMAT(%s,'%s')"; + + public static final String FROM_UNIXTIME = "FROM_UNIXTIME(%s,'%s')"; + + public static final String STR_TO_DATE = "STR_TO_DATE(%s,'%s')"; + + public static final String CAST = "CAST(%s AS %s)"; + + public static final String DEFAULT_DATE_FORMAT = "%Y-%m-%d %H:%i:%S"; + + public static final String DEFAULT_INT_FORMAT = "DECIMAL(20,0)"; + + public static final String DEFAULT_FLOAT_FORMAT = "DECIMAL(20,8)"; + + public static final String WHERE_VALUE_NULL = "(NULL,'')"; + + public static final String WHERE_VALUE_VALUE = "'%s'"; + + public static final String AGG_COUNT = "COUNT(*)"; + + public static final String AGG_FIELD = "%s(%s)"; + + public static final String WHERE_BETWEEN = "'%s' AND '%s'"; + + public static final String BRACKETS = "(%s)"; + + public static final String NAME = "mysql"; + + public static final String GROUP_CONCAT = "group_concat(%s)"; + + + +} diff --git a/extensions/dataease-extensions-datasource/mongo/mongo-backend/src/main/java/io/dataease/plugins/datasource/mongo/query/MongobiQueryProvider.java b/extensions/dataease-extensions-datasource/mongo/mongo-backend/src/main/java/io/dataease/plugins/datasource/mongo/query/MongobiQueryProvider.java new file mode 100644 index 0000000000..f79e43bafa --- /dev/null +++ b/extensions/dataease-extensions-datasource/mongo/mongo-backend/src/main/java/io/dataease/plugins/datasource/mongo/query/MongobiQueryProvider.java @@ -0,0 +1,1331 @@ +package io.dataease.plugins.datasource.mongo.query; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import io.dataease.plugins.common.base.domain.ChartViewWithBLOBs; +import io.dataease.plugins.common.base.domain.DatasetTableField; +import io.dataease.plugins.common.base.domain.DatasetTableFieldExample; +import io.dataease.plugins.common.base.domain.Datasource; +import io.dataease.plugins.common.base.mapper.DatasetTableFieldMapper; +import io.dataease.plugins.common.constants.DeTypeConstants; +import io.dataease.plugins.common.constants.datasource.SQLConstants; +import io.dataease.plugins.common.dto.chart.ChartCustomFilterItemDTO; +import io.dataease.plugins.common.dto.chart.ChartFieldCustomFilterDTO; +import io.dataease.plugins.common.dto.chart.ChartViewFieldDTO; +import io.dataease.plugins.common.dto.datasource.DeSortField; +import io.dataease.plugins.common.dto.sqlObj.SQLObj; +import io.dataease.plugins.common.request.chart.ChartExtFilterRequest; +import io.dataease.plugins.common.request.permission.DataSetRowPermissionsTreeDTO; +import io.dataease.plugins.common.request.permission.DatasetRowPermissionsTreeItem; +import io.dataease.plugins.datasource.entity.Dateformat; +import io.dataease.plugins.datasource.entity.PageInfo; +import io.dataease.plugins.datasource.query.QueryProvider; +import io.dataease.plugins.datasource.query.Utils; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.ObjectUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Component; +import org.stringtemplate.v4.ST; +import org.stringtemplate.v4.STGroup; +import org.stringtemplate.v4.STGroupFile; + +import javax.annotation.Resource; +import java.text.MessageFormat; +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +import static io.dataease.plugins.common.constants.datasource.SQLConstants.TABLE_ALIAS_PREFIX; + + +@Component() +public class MongobiQueryProvider extends QueryProvider { + @Resource + private DatasetTableFieldMapper datasetTableFieldMapper; + + @Override + public Integer transFieldType(String field) { + switch (field) { + case "CHAR": + case "VARCHAR": + case "TEXT": + case "TINYTEXT": + case "MEDIUMTEXT": + case "LONGTEXT": + case "ENUM": + return 0;// 文本 + case "DATE": + case "TIME": + case "YEAR": + case "DATETIME": + case "TIMESTAMP": + return 1;// 时间 + case "INT": + case "SMALLINT": + case "MEDIUMINT": + case "INTEGER": + case "BIGINT": + case "LONG": //增加了LONG类型 + return 2;// 整型 + case "FLOAT": + case "DOUBLE": + case "DECIMAL": + return 3;// 浮点 + case "BIT": + case "TINYINT": + return 4;// 布尔 + default: + return 0; + } + } + + @Override + public String createSQLPreview(String sql, String orderBy) { + return "SELECT * FROM (" + sqlFix(sql) + ") AS tmp " + " LIMIT 0,1000"; + } + + @Override + public String createQuerySQL(String table, List fields, boolean isGroup, Datasource ds, List fieldCustomFilter, List rowPermissionsTree) { + return createQuerySQL(table, fields, isGroup, ds, fieldCustomFilter, rowPermissionsTree, null); + } + + @Override + public String createQuerySQLAsTmp(String sql, List fields, boolean isGroup, List fieldCustomFilter, List rowPermissionsTree) { + return createQuerySQL("(" + sqlFix(sql) + ")", fields, isGroup, null, fieldCustomFilter, rowPermissionsTree, null); + } + + private SQLObj buildSortField(DeSortField f, SQLObj tableObj, int index) { + String originField; + if (ObjectUtils.isNotEmpty(f.getExtField()) && f.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originField = calcFieldRegex(f.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(f.getExtField()) && f.getExtField() == 1) { + originField = String.format(MongoConstants.KEYWORD_FIX, tableObj.getTableAlias(), f.getOriginName()); + } else { + originField = String.format(MongoConstants.KEYWORD_FIX, tableObj.getTableAlias(), f.getOriginName()); + } + String fieldAlias = String.format(SQLConstants.FIELD_ALIAS_X_PREFIX, index); + String fieldName = ""; + // 处理横轴字段 + if (f.getDeExtractType() == 1) { + if (f.getDeType() == 2 || f.getDeType() == 3) { + fieldName = String.format(MongoConstants.UNIX_TIMESTAMP, originField) + "*1000"; + } else { + fieldName = String.format(MongoConstants.DATE_FORMAT, originField, MongoConstants.DEFAULT_DATE_FORMAT); + } + } else if (f.getDeExtractType() == 0) { + if (f.getDeType() == 2) { + fieldName = String.format(MongoConstants.CAST, originField, MongoConstants.DEFAULT_INT_FORMAT); + } else if (f.getDeType() == 3) { + fieldName = String.format(MongoConstants.CAST, originField, MongoConstants.DEFAULT_FLOAT_FORMAT); + } else if (f.getDeType() == 1) { + fieldName = String.format(MongoConstants.STR_TO_DATE, originField, StringUtils.isNotEmpty(f.getDateFormat()) ? f.getDateFormat() : MongoConstants.DEFAULT_DATE_FORMAT); + } else { + fieldName = originField; + } + } else { + if (f.getDeType() == 1) { + String cast = String.format(MongoConstants.CAST, originField, MongoConstants.DEFAULT_INT_FORMAT) + "/1000"; + fieldName = String.format(MongoConstants.FROM_UNIXTIME, cast, MongoConstants.DEFAULT_DATE_FORMAT); + } else if (f.getDeType() == 2) { + fieldName = String.format(MongoConstants.CAST, originField, MongoConstants.DEFAULT_INT_FORMAT); + } else { + fieldName = originField; + } + } + SQLObj result = SQLObj.builder().orderField(originField).orderAlias(originField).orderDirection(f.getOrderDirection()).build(); + return result; + + } + + @Override + public String createQuerySQL(String table, List fields, boolean isGroup, Datasource ds, List fieldCustomFilter, List rowPermissionsTree, List sortFields) { + SQLObj tableObj = SQLObj.builder() + .tableName((table.startsWith("(") && table.endsWith(")")) ? table : String.format(MongoConstants.KEYWORD_TABLE, table)) + .tableAlias(String.format(TABLE_ALIAS_PREFIX, 0)) + .build(); + List xFields = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(fields)) { + for (int i = 0; i < fields.size(); i++) { + DatasetTableField f = fields.get(i); + String originField; + if (ObjectUtils.isNotEmpty(f.getExtField()) && f.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originField = calcFieldRegex(f.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(f.getExtField()) && f.getExtField() == 1) { + originField = String.format(MongoConstants.KEYWORD_FIX, tableObj.getTableAlias(), f.getOriginName()); + } else { + originField = String.format(MongoConstants.KEYWORD_FIX, tableObj.getTableAlias(), f.getOriginName()); + } + String fieldAlias = String.format(SQLConstants.FIELD_ALIAS_X_PREFIX, i); + String fieldName = ""; + // 处理横轴字段 + if (f.getDeExtractType() == 1) { + if (f.getDeType() == 2 || f.getDeType() == 3) { + fieldName = String.format(MongoConstants.UNIX_TIMESTAMP, originField) + "*1000"; + } else { + fieldName = String.format(MongoConstants.DATE_FORMAT, originField, MongoConstants.DEFAULT_DATE_FORMAT); + } + } else if (f.getDeExtractType() == 0) { + if (f.getDeType() == 2) { + fieldName = String.format(MongoConstants.CAST, originField, MongoConstants.DEFAULT_INT_FORMAT); + } else if (f.getDeType() == 3) { + fieldName = String.format(MongoConstants.CAST, originField, MongoConstants.DEFAULT_FLOAT_FORMAT); + } else if (f.getDeType() == 1) { + fieldName = String.format(MongoConstants.STR_TO_DATE, originField, StringUtils.isNotEmpty(f.getDateFormat()) ? f.getDateFormat() : MongoConstants.DEFAULT_DATE_FORMAT); + } else { + fieldName = originField; + } + } else { + if (f.getDeType() == 1) { + String cast = String.format(MongoConstants.CAST, originField, MongoConstants.DEFAULT_INT_FORMAT) + "/1000"; + fieldName = String.format(MongoConstants.FROM_UNIXTIME, cast, MongoConstants.DEFAULT_DATE_FORMAT); + } else if (f.getDeType() == 2) { + fieldName = String.format(MongoConstants.CAST, originField, MongoConstants.DEFAULT_INT_FORMAT); + } else { + fieldName = originField; + } + } + xFields.add(SQLObj.builder() + .fieldName(fieldName) + .fieldAlias(fieldAlias) + .build()); + } + } + + + STGroup stg = new STGroupFile(SQLConstants.SQL_TEMPLATE); + ST st_sql = stg.getInstanceOf("previewSql"); + st_sql.add("isGroup", isGroup); + if (CollectionUtils.isNotEmpty(xFields)) st_sql.add("groups", xFields); + if (ObjectUtils.isNotEmpty(tableObj)) st_sql.add("table", tableObj); + + String customWheres = transCustomFilterList(tableObj, fieldCustomFilter); + // row permissions tree + String whereTrees = transFilterTrees(tableObj, rowPermissionsTree); + List wheres = new ArrayList<>(); + if (customWheres != null) wheres.add(customWheres); + if (whereTrees != null) wheres.add(whereTrees); + if (CollectionUtils.isNotEmpty(wheres)) st_sql.add("filters", wheres); + + List xOrders = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(sortFields)) { + int step = fields.size(); + for (int i = step; i < (step + sortFields.size()); i++) { + DeSortField deSortField = sortFields.get(i - step); + SQLObj order = buildSortField(deSortField, tableObj, i); + xOrders.add(order); + } + } + if (ObjectUtils.isNotEmpty(xOrders)) { + st_sql.add("orders", xOrders); + } + + return st_sql.render(); + } + + @Override + public String createQuerySQLAsTmp(String sql, List fields, boolean isGroup, List fieldCustomFilter, List rowPermissionsTree, List sortFields) { + return createQuerySQL("(" + sqlFix(sql) + ")", fields, isGroup, null, fieldCustomFilter, rowPermissionsTree, sortFields); + } + + @Override + public String createQueryTableWithPage(String table, List fields, Integer page, Integer pageSize, Integer realSize, boolean isGroup, Datasource ds, List fieldCustomFilter, List rowPermissionsTree) { + return createQuerySQL(table, fields, isGroup, null, fieldCustomFilter, rowPermissionsTree) + " LIMIT " + (page - 1) * pageSize + "," + realSize; + } + + @Override + public String createQueryTableWithLimit(String table, List fields, Integer limit, boolean isGroup, Datasource ds, List fieldCustomFilter, List rowPermissionsTree) { + return createQuerySQL(table, fields, isGroup, null, fieldCustomFilter, rowPermissionsTree) + " LIMIT 0," + limit; + } + + @Override + public String createQuerySqlWithLimit(String sql, List fields, Integer limit, boolean isGroup, List fieldCustomFilter, List rowPermissionsTree) { + return createQuerySQLAsTmp(sql, fields, isGroup, fieldCustomFilter, rowPermissionsTree) + " LIMIT 0," + limit; + } + + @Override + public String createQuerySQLWithPage(String sql, List fields, Integer page, Integer pageSize, Integer realSize, boolean isGroup, List fieldCustomFilter, List rowPermissionsTree) { + return createQuerySQLAsTmp(sql, fields, isGroup, fieldCustomFilter, rowPermissionsTree) + " LIMIT " + (page - 1) * pageSize + "," + realSize; + } + + @Override + public String getSQL(String table, List xAxis, List yAxis, List fieldCustomFilter, List rowPermissionsTree, List extFilterRequestList, Datasource ds, ChartViewWithBLOBs view) { + SQLObj tableObj = SQLObj.builder() + .tableName((table.startsWith("(") && table.endsWith(")")) ? table : String.format(MongoConstants.KEYWORD_TABLE, table)) + .tableAlias(String.format(TABLE_ALIAS_PREFIX, 0)) + .build(); + List xFields = new ArrayList<>(); + List xOrders = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(xAxis)) { + for (int i = 0; i < xAxis.size(); i++) { + ChartViewFieldDTO x = xAxis.get(i); + String originField; + if (ObjectUtils.isNotEmpty(x.getExtField()) && x.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originField = calcFieldRegex(x.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(x.getExtField()) && x.getExtField() == 1) { + originField = String.format(MongoConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getOriginName()); + } else { + originField = String.format(MongoConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getOriginName()); + } + String fieldAlias = String.format(SQLConstants.FIELD_ALIAS_X_PREFIX, i); + // 处理横轴字段 + xFields.add(getXFields(x, originField, fieldAlias)); + // 处理横轴排序 + if (StringUtils.isNotEmpty(x.getSort()) && Utils.joinSort(x.getSort())) { + xOrders.add(SQLObj.builder() + .orderField(originField) + .orderAlias(fieldAlias) + .orderDirection(x.getSort()) + .build()); + } + } + } + List yFields = new ArrayList<>(); + List yWheres = new ArrayList<>(); + List yOrders = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(yAxis)) { + for (int i = 0; i < yAxis.size(); i++) { + ChartViewFieldDTO y = yAxis.get(i); + String originField; + if (ObjectUtils.isNotEmpty(y.getExtField()) && y.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originField = calcFieldRegex(y.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(y.getExtField()) && y.getExtField() == 1) { + originField = String.format(MongoConstants.KEYWORD_FIX, tableObj.getTableAlias(), y.getOriginName()); + } else { + originField = String.format(MongoConstants.KEYWORD_FIX, tableObj.getTableAlias(), y.getOriginName()); + } + String fieldAlias = String.format(SQLConstants.FIELD_ALIAS_Y_PREFIX, i); + // 处理纵轴字段 + yFields.add(getYFields(y, originField, fieldAlias)); + // 处理纵轴过滤 + yWheres.add(getYWheres(y, originField, fieldAlias)); + // 处理纵轴排序 + if (StringUtils.isNotEmpty(y.getSort()) && Utils.joinSort(y.getSort())) { + yOrders.add(SQLObj.builder() + .orderField(originField) + .orderAlias(fieldAlias) + .orderDirection(y.getSort()) + .build()); + } + } + } + // 处理视图中字段过滤 + String customWheres = transCustomFilterList(tableObj, fieldCustomFilter); + // 处理仪表板字段过滤 + String extWheres = transExtFilterList(tableObj, extFilterRequestList); + // row permissions tree + String whereTrees = transFilterTrees(tableObj, rowPermissionsTree); + // 构建sql所有参数 + List fields = new ArrayList<>(); + fields.addAll(xFields); + fields.addAll(yFields); + List wheres = new ArrayList<>(); + if (customWheres != null) wheres.add(customWheres); + if (extWheres != null) wheres.add(extWheres); + if (whereTrees != null) wheres.add(whereTrees); + List groups = new ArrayList<>(); + groups.addAll(xFields); + // 外层再次套sql + List orders = new ArrayList<>(); + orders.addAll(xOrders); + orders.addAll(yOrders); + List aggWheres = new ArrayList<>(); + aggWheres.addAll(yWheres.stream().filter(ObjectUtils::isNotEmpty).collect(Collectors.toList())); + + STGroup stg = new STGroupFile(SQLConstants.SQL_TEMPLATE); + ST st_sql = stg.getInstanceOf("querySql"); + if (CollectionUtils.isNotEmpty(xFields)) st_sql.add("groups", xFields); + if (CollectionUtils.isNotEmpty(yFields)) st_sql.add("aggregators", yFields); + if (CollectionUtils.isNotEmpty(wheres)) st_sql.add("filters", wheres); + if (ObjectUtils.isNotEmpty(tableObj)) st_sql.add("table", tableObj); + String sql = st_sql.render(); + + ST st = stg.getInstanceOf("querySql"); + SQLObj tableSQL = SQLObj.builder() + .tableName(String.format(MongoConstants.BRACKETS, sql)) + .tableAlias(String.format(TABLE_ALIAS_PREFIX, 1)) + .build(); + if (CollectionUtils.isNotEmpty(aggWheres)) st.add("filters", aggWheres); + if (CollectionUtils.isNotEmpty(orders)) st.add("orders", orders); + if (ObjectUtils.isNotEmpty(tableSQL)) st.add("table", tableSQL); + return sqlLimit(st.render(), view); + } + + @Override + public String getSQLWithPage(boolean isTable, String table, List xAxis, List fieldCustomFilter, List rowPermissionsTree, List extFilterRequestList, Datasource ds, ChartViewWithBLOBs view, PageInfo pageInfo) { + String limit = ((pageInfo.getGoPage() != null && pageInfo.getPageSize() != null) ? " LIMIT " + (pageInfo.getGoPage() - 1) * pageInfo.getPageSize() + "," + pageInfo.getPageSize() : ""); + if (isTable) { + return originalTableInfo(table, xAxis, fieldCustomFilter, rowPermissionsTree, extFilterRequestList, ds, view) + limit; + } else { + return originalTableInfo("(" + sqlFix(table) + ")", xAxis, fieldCustomFilter, rowPermissionsTree, extFilterRequestList, ds, view) + limit; + } + } + + private String originalTableInfo(String table, List xAxis, List fieldCustomFilter, List rowPermissionsTree, List extFilterRequestList, Datasource ds, ChartViewWithBLOBs view) { + SQLObj tableObj = SQLObj.builder() + .tableName((table.startsWith("(") && table.endsWith(")")) ? table : String.format(MongoConstants.KEYWORD_TABLE, table)) + .tableAlias(String.format(TABLE_ALIAS_PREFIX, 0)) + .build(); + List xFields = new ArrayList<>(); + List xOrders = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(xAxis)) { + for (int i = 0; i < xAxis.size(); i++) { + ChartViewFieldDTO x = xAxis.get(i); + String originField; + if (ObjectUtils.isNotEmpty(x.getExtField()) && x.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originField = calcFieldRegex(x.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(x.getExtField()) && x.getExtField() == 1) { + originField = String.format(MongoConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getOriginName()); + } else { + if (x.getDeType() == 2 || x.getDeType() == 3) { + originField = String.format(MongoConstants.CAST, String.format(MongoConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getOriginName()), MongoConstants.DEFAULT_FLOAT_FORMAT); + } else { + originField = String.format(MongoConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getOriginName()); + } + } + String fieldAlias = String.format(SQLConstants.FIELD_ALIAS_X_PREFIX, i); + // 处理横轴字段 + xFields.add(getXFields(x, originField, fieldAlias)); + // 处理横轴排序 + if (StringUtils.isNotEmpty(x.getSort()) && Utils.joinSort(x.getSort())) { + xOrders.add(SQLObj.builder() + .orderField(originField) + .orderAlias(fieldAlias) + .orderDirection(x.getSort()) + .build()); + } + } + } + // 处理视图中字段过滤 + String customWheres = transCustomFilterList(tableObj, fieldCustomFilter); + // 处理仪表板字段过滤 + String extWheres = transExtFilterList(tableObj, extFilterRequestList); + // row permissions tree + String whereTrees = transFilterTrees(tableObj, rowPermissionsTree); + // 构建sql所有参数 + List fields = new ArrayList<>(); + fields.addAll(xFields); + List wheres = new ArrayList<>(); + if (customWheres != null) wheres.add(customWheres); + if (extWheres != null) wheres.add(extWheres); + if (whereTrees != null) wheres.add(whereTrees); + List groups = new ArrayList<>(); + groups.addAll(xFields); + // 外层再次套sql + List orders = new ArrayList<>(); + orders.addAll(xOrders); + + STGroup stg = new STGroupFile(SQLConstants.SQL_TEMPLATE); + ST st_sql = stg.getInstanceOf("previewSql"); + st_sql.add("isGroup", false); + if (CollectionUtils.isNotEmpty(xFields)) st_sql.add("groups", xFields); + if (CollectionUtils.isNotEmpty(wheres)) st_sql.add("filters", wheres); + if (ObjectUtils.isNotEmpty(tableObj)) st_sql.add("table", tableObj); + String sql = st_sql.render(); + + ST st = stg.getInstanceOf("previewSql"); + st.add("isGroup", false); + SQLObj tableSQL = SQLObj.builder() + .tableName(String.format(MongoConstants.BRACKETS, sql)) + .tableAlias(String.format(TABLE_ALIAS_PREFIX, 1)) + .build(); + if (CollectionUtils.isNotEmpty(orders)) st.add("orders", orders); + if (ObjectUtils.isNotEmpty(tableSQL)) st.add("table", tableSQL); + return st.render(); + } + @Override + public String getSQLTableInfo(String table, List xAxis, List fieldCustomFilter, List rowPermissionsTree, List extFilterRequestList, Datasource ds, ChartViewWithBLOBs view) { + return sqlLimit(originalTableInfo(table, xAxis, fieldCustomFilter, rowPermissionsTree, extFilterRequestList, ds, view), view); + } + + @Override + public String getSQLAsTmpTableInfo(String sql, List xAxis, List fieldCustomFilter, List rowPermissionsTree, List extFilterRequestList, Datasource ds, ChartViewWithBLOBs view) { + return getSQLTableInfo("(" + sqlFix(sql) + ")", xAxis, fieldCustomFilter, rowPermissionsTree, extFilterRequestList, null, view); + } + + + @Override + public String getSQLAsTmp(String sql, List xAxis, List yAxis, List fieldCustomFilter, List rowPermissionsTree, List extFilterRequestList, ChartViewWithBLOBs view) { + return getSQL("(" + sqlFix(sql) + ")", xAxis, yAxis, fieldCustomFilter, rowPermissionsTree, extFilterRequestList, null, view); + } + + @Override + public String getSQLStack(String table, List xAxis, List yAxis, List fieldCustomFilter, List rowPermissionsTree, List extFilterRequestList, List extStack, Datasource ds, ChartViewWithBLOBs view) { + SQLObj tableObj = SQLObj.builder() + .tableName((table.startsWith("(") && table.endsWith(")")) ? table : String.format(MongoConstants.KEYWORD_TABLE, table)) + .tableAlias(String.format(TABLE_ALIAS_PREFIX, 0)) + .build(); + List xFields = new ArrayList<>(); + List xOrders = new ArrayList<>(); + List xList = new ArrayList<>(); + xList.addAll(xAxis); + xList.addAll(extStack); + if (CollectionUtils.isNotEmpty(xList)) { + for (int i = 0; i < xList.size(); i++) { + ChartViewFieldDTO x = xList.get(i); + String originField; + if (ObjectUtils.isNotEmpty(x.getExtField()) && x.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originField = calcFieldRegex(x.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(x.getExtField()) && x.getExtField() == 1) { + originField = String.format(MongoConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getOriginName()); + } else { + originField = String.format(MongoConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getOriginName()); + } + String fieldAlias = String.format(SQLConstants.FIELD_ALIAS_X_PREFIX, i); + // 处理横轴字段 + xFields.add(getXFields(x, originField, fieldAlias)); + // 处理横轴排序 + if (StringUtils.isNotEmpty(x.getSort()) && Utils.joinSort(x.getSort())) { + xOrders.add(SQLObj.builder() + .orderField(originField) + .orderAlias(fieldAlias) + .orderDirection(x.getSort()) + .build()); + } + } + } + List yFields = new ArrayList<>(); + List yWheres = new ArrayList<>(); + List yOrders = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(yAxis)) { + for (int i = 0; i < yAxis.size(); i++) { + ChartViewFieldDTO y = yAxis.get(i); + String originField; + if (ObjectUtils.isNotEmpty(y.getExtField()) && y.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originField = calcFieldRegex(y.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(y.getExtField()) && y.getExtField() == 1) { + originField = String.format(MongoConstants.KEYWORD_FIX, tableObj.getTableAlias(), y.getOriginName()); + } else { + originField = String.format(MongoConstants.KEYWORD_FIX, tableObj.getTableAlias(), y.getOriginName()); + } + String fieldAlias = String.format(SQLConstants.FIELD_ALIAS_Y_PREFIX, i); + // 处理纵轴字段 + yFields.add(getYFields(y, originField, fieldAlias)); + // 处理纵轴过滤 + yWheres.add(getYWheres(y, originField, fieldAlias)); + // 处理纵轴排序 + if (StringUtils.isNotEmpty(y.getSort()) && Utils.joinSort(y.getSort())) { + yOrders.add(SQLObj.builder() + .orderField(originField) + .orderAlias(fieldAlias) + .orderDirection(y.getSort()) + .build()); + } + } + } + // 处理视图中字段过滤 + String customWheres = transCustomFilterList(tableObj, fieldCustomFilter); + // 处理仪表板字段过滤 + String extWheres = transExtFilterList(tableObj, extFilterRequestList); + // row permissions tree + String whereTrees = transFilterTrees(tableObj, rowPermissionsTree); + // 构建sql所有参数 + List fields = new ArrayList<>(); + fields.addAll(xFields); + fields.addAll(yFields); + List wheres = new ArrayList<>(); + if (customWheres != null) wheres.add(customWheres); + if (extWheres != null) wheres.add(extWheres); + if (whereTrees != null) wheres.add(whereTrees); + List groups = new ArrayList<>(); + groups.addAll(xFields); + // 外层再次套sql + List orders = new ArrayList<>(); + orders.addAll(xOrders); + orders.addAll(yOrders); + List aggWheres = new ArrayList<>(); + aggWheres.addAll(yWheres.stream().filter(ObjectUtils::isNotEmpty).collect(Collectors.toList())); + + STGroup stg = new STGroupFile(SQLConstants.SQL_TEMPLATE); + ST st_sql = stg.getInstanceOf("querySql"); + if (CollectionUtils.isNotEmpty(xFields)) st_sql.add("groups", xFields); + if (CollectionUtils.isNotEmpty(yFields)) st_sql.add("aggregators", yFields); + if (CollectionUtils.isNotEmpty(wheres)) st_sql.add("filters", wheres); + if (ObjectUtils.isNotEmpty(tableObj)) st_sql.add("table", tableObj); + String sql = st_sql.render(); + + ST st = stg.getInstanceOf("querySql"); + SQLObj tableSQL = SQLObj.builder() + .tableName(String.format(MongoConstants.BRACKETS, sql)) + .tableAlias(String.format(TABLE_ALIAS_PREFIX, 1)) + .build(); + if (CollectionUtils.isNotEmpty(aggWheres)) st.add("filters", aggWheres); + if (CollectionUtils.isNotEmpty(orders)) st.add("orders", orders); + if (ObjectUtils.isNotEmpty(tableSQL)) st.add("table", tableSQL); + return sqlLimit(st.render(), view); + } + + @Override + public String getSQLAsTmpStack(String table, List xAxis, List yAxis, List fieldCustomFilter, List rowPermissionsTree, List extFilterRequestList, List extStack, ChartViewWithBLOBs view) { + return getSQLStack("(" + sqlFix(table) + ")", xAxis, yAxis, fieldCustomFilter, rowPermissionsTree, extFilterRequestList, extStack, null, view); + } + + @Override + public String getSQLScatter(String table, List xAxis, List yAxis, List fieldCustomFilter, List rowPermissionsTree, List extFilterRequestList, List extBubble, Datasource ds, ChartViewWithBLOBs view) { + SQLObj tableObj = SQLObj.builder() + .tableName((table.startsWith("(") && table.endsWith(")")) ? table : String.format(MongoConstants.KEYWORD_TABLE, table)) + .tableAlias(String.format(TABLE_ALIAS_PREFIX, 0)) + .build(); + List xFields = new ArrayList<>(); + List xOrders = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(xAxis)) { + for (int i = 0; i < xAxis.size(); i++) { + ChartViewFieldDTO x = xAxis.get(i); + String originField; + if (ObjectUtils.isNotEmpty(x.getExtField()) && x.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originField = calcFieldRegex(x.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(x.getExtField()) && x.getExtField() == 1) { + originField = String.format(MongoConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getOriginName()); + } else { + originField = String.format(MongoConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getOriginName()); + } + String fieldAlias = String.format(SQLConstants.FIELD_ALIAS_X_PREFIX, i); + // 处理横轴字段 + xFields.add(getXFields(x, originField, fieldAlias)); + // 处理横轴排序 + if (StringUtils.isNotEmpty(x.getSort()) && Utils.joinSort(x.getSort())) { + xOrders.add(SQLObj.builder() + .orderField(originField) + .orderAlias(fieldAlias) + .orderDirection(x.getSort()) + .build()); + } + } + } + List yFields = new ArrayList<>(); + List yWheres = new ArrayList<>(); + List yOrders = new ArrayList<>(); + List yList = new ArrayList<>(); + yList.addAll(yAxis); + yList.addAll(extBubble); + if (CollectionUtils.isNotEmpty(yList)) { + for (int i = 0; i < yList.size(); i++) { + ChartViewFieldDTO y = yList.get(i); + String originField; + if (ObjectUtils.isNotEmpty(y.getExtField()) && y.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originField = calcFieldRegex(y.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(y.getExtField()) && y.getExtField() == 1) { + originField = String.format(MongoConstants.KEYWORD_FIX, tableObj.getTableAlias(), y.getOriginName()); + } else { + originField = String.format(MongoConstants.KEYWORD_FIX, tableObj.getTableAlias(), y.getOriginName()); + } + String fieldAlias = String.format(SQLConstants.FIELD_ALIAS_Y_PREFIX, i); + // 处理纵轴字段 + yFields.add(getYFields(y, originField, fieldAlias)); + // 处理纵轴过滤 + yWheres.add(getYWheres(y, originField, fieldAlias)); + // 处理纵轴排序 + if (StringUtils.isNotEmpty(y.getSort()) && Utils.joinSort(y.getSort())) { + yOrders.add(SQLObj.builder() + .orderField(originField) + .orderAlias(fieldAlias) + .orderDirection(y.getSort()) + .build()); + } + } + } + // 处理视图中字段过滤 + String customWheres = transCustomFilterList(tableObj, fieldCustomFilter); + // 处理仪表板字段过滤 + String extWheres = transExtFilterList(tableObj, extFilterRequestList); + // row permissions tree + String whereTrees = transFilterTrees(tableObj, rowPermissionsTree); + // 构建sql所有参数 + List fields = new ArrayList<>(); + fields.addAll(xFields); + fields.addAll(yFields); + List wheres = new ArrayList<>(); + if (customWheres != null) wheres.add(customWheres); + if (extWheres != null) wheres.add(extWheres); + if (whereTrees != null) wheres.add(whereTrees); + List groups = new ArrayList<>(); + groups.addAll(xFields); + // 外层再次套sql + List orders = new ArrayList<>(); + orders.addAll(xOrders); + orders.addAll(yOrders); + List aggWheres = new ArrayList<>(); + aggWheres.addAll(yWheres.stream().filter(ObjectUtils::isNotEmpty).collect(Collectors.toList())); + + STGroup stg = new STGroupFile(SQLConstants.SQL_TEMPLATE); + ST st_sql = stg.getInstanceOf("querySql"); + if (CollectionUtils.isNotEmpty(xFields)) st_sql.add("groups", xFields); + if (CollectionUtils.isNotEmpty(yFields)) st_sql.add("aggregators", yFields); + if (CollectionUtils.isNotEmpty(wheres)) st_sql.add("filters", wheres); + if (ObjectUtils.isNotEmpty(tableObj)) st_sql.add("table", tableObj); + String sql = st_sql.render(); + + ST st = stg.getInstanceOf("querySql"); + SQLObj tableSQL = SQLObj.builder() + .tableName(String.format(MongoConstants.BRACKETS, sql)) + .tableAlias(String.format(TABLE_ALIAS_PREFIX, 1)) + .build(); + if (CollectionUtils.isNotEmpty(aggWheres)) st.add("filters", aggWheres); + if (CollectionUtils.isNotEmpty(orders)) st.add("orders", orders); + if (ObjectUtils.isNotEmpty(tableSQL)) st.add("table", tableSQL); + return sqlLimit(st.render(), view); + } + + @Override + public String getSQLAsTmpScatter(String table, List xAxis, List yAxis, List fieldCustomFilter, List rowPermissionsTree, List extFilterRequestList, List extBubble, ChartViewWithBLOBs view) { + return getSQLScatter("(" + sqlFix(table) + ")", xAxis, yAxis, fieldCustomFilter, rowPermissionsTree, extFilterRequestList, extBubble, null, view); + } + + @Override + public String searchTable(String table) { + return "SELECT table_name FROM information_schema.TABLES WHERE table_name ='" + table + "'"; + } + + @Override + public String getSQLSummary(String table, List yAxis, List fieldCustomFilter, List rowPermissionsTree, List extFilterRequestList, ChartViewWithBLOBs view, Datasource ds) { + // 字段汇总 排序等 + SQLObj tableObj = SQLObj.builder() + .tableName((table.startsWith("(") && table.endsWith(")")) ? table : String.format(MongoConstants.KEYWORD_TABLE, table)) + .tableAlias(String.format(TABLE_ALIAS_PREFIX, 0)) + .build(); + List yFields = new ArrayList<>(); + List yWheres = new ArrayList<>(); + List yOrders = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(yAxis)) { + for (int i = 0; i < yAxis.size(); i++) { + ChartViewFieldDTO y = yAxis.get(i); + String originField; + if (ObjectUtils.isNotEmpty(y.getExtField()) && y.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originField = calcFieldRegex(y.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(y.getExtField()) && y.getExtField() == 1) { + originField = String.format(MongoConstants.KEYWORD_FIX, tableObj.getTableAlias(), y.getOriginName()); + } else { + originField = String.format(MongoConstants.KEYWORD_FIX, tableObj.getTableAlias(), y.getOriginName()); + } + String fieldAlias = String.format(SQLConstants.FIELD_ALIAS_Y_PREFIX, i); + // 处理纵轴字段 + yFields.add(getYFields(y, originField, fieldAlias)); + // 处理纵轴过滤 + yWheres.add(getYWheres(y, originField, fieldAlias)); + // 处理纵轴排序 + if (StringUtils.isNotEmpty(y.getSort()) && Utils.joinSort(y.getSort())) { + yOrders.add(SQLObj.builder() + .orderField(originField) + .orderAlias(fieldAlias) + .orderDirection(y.getSort()) + .build()); + } + } + } + // 处理视图中字段过滤 + String customWheres = transCustomFilterList(tableObj, fieldCustomFilter); + // 处理仪表板字段过滤 + String extWheres = transExtFilterList(tableObj, extFilterRequestList); + // row permissions tree + String whereTrees = transFilterTrees(tableObj, rowPermissionsTree); + // 构建sql所有参数 + List fields = new ArrayList<>(); + fields.addAll(yFields); + List wheres = new ArrayList<>(); + if (customWheres != null) wheres.add(customWheres); + if (extWheres != null) wheres.add(extWheres); + if (whereTrees != null) wheres.add(whereTrees); + List groups = new ArrayList<>(); + // 外层再次套sql + List orders = new ArrayList<>(); + orders.addAll(yOrders); + List aggWheres = new ArrayList<>(); + aggWheres.addAll(yWheres.stream().filter(ObjectUtils::isNotEmpty).collect(Collectors.toList())); + + STGroup stg = new STGroupFile(SQLConstants.SQL_TEMPLATE); + ST st_sql = stg.getInstanceOf("querySql"); + if (CollectionUtils.isNotEmpty(yFields)) st_sql.add("aggregators", yFields); + if (CollectionUtils.isNotEmpty(wheres)) st_sql.add("filters", wheres); + if (ObjectUtils.isNotEmpty(tableObj)) st_sql.add("table", tableObj); + String sql = st_sql.render(); + + ST st = stg.getInstanceOf("querySql"); + SQLObj tableSQL = SQLObj.builder() + .tableName(String.format(MongoConstants.BRACKETS, sql)) + .tableAlias(String.format(TABLE_ALIAS_PREFIX, 1)) + .build(); + if (CollectionUtils.isNotEmpty(aggWheres)) st.add("filters", aggWheres); + if (CollectionUtils.isNotEmpty(orders)) st.add("orders", orders); + if (ObjectUtils.isNotEmpty(tableSQL)) st.add("table", tableSQL); + return sqlLimit(st.render(), view); + } + + @Override + public String getSQLSummaryAsTmp(String sql, List yAxis, List fieldCustomFilter, List rowPermissionsTree, List extFilterRequestList, ChartViewWithBLOBs view) { + return getSQLSummary("(" + sqlFix(sql) + ")", yAxis, fieldCustomFilter, rowPermissionsTree, extFilterRequestList, view, null); + } + + @Override + public String wrapSql(String sql) { + sql = sql.trim(); + if (sql.lastIndexOf(";") == (sql.length() - 1)) { + sql = sql.substring(0, sql.length() - 1); + } + String tmpSql = "SELECT * FROM (" + sql + ") AS tmp " + " LIMIT 0"; + return tmpSql; + } + + @Override + public String createRawQuerySQL(String table, List fields, Datasource ds) { + String[] array = fields.stream().map(f -> { + StringBuilder stringBuilder = new StringBuilder(); + if (f.getDeExtractType() == 4) { // 处理 tinyint + stringBuilder.append("concat(`").append(f.getOriginName()).append("`,'') AS ").append(f.getDataeaseName()); + } else { + stringBuilder.append("`").append(f.getOriginName()).append("` AS ").append(f.getDataeaseName()); + } + return stringBuilder.toString(); + }).toArray(String[]::new); + return MessageFormat.format("SELECT {0} FROM {1}", StringUtils.join(array, ","), table); + } + + @Override + public String createRawQuerySQLAsTmp(String sql, List fields) { + return createRawQuerySQL(" (" + sqlFix(sql) + ") AS tmp ", fields, null); + } + + @Override + public String transTreeItem(SQLObj tableObj, DatasetRowPermissionsTreeItem item) { + String res = null; + DatasetTableField field = item.getField(); + if (ObjectUtils.isEmpty(field)) { + return null; + } + String whereName = ""; + String originName; + if (ObjectUtils.isNotEmpty(field.getExtField()) && field.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originName = calcFieldRegex(field.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(field.getExtField()) && field.getExtField() == 1) { + originName = String.format(MongoConstants.KEYWORD_FIX, tableObj.getTableAlias(), field.getOriginName()); + } else { + originName = String.format(MongoConstants.KEYWORD_FIX, tableObj.getTableAlias(), field.getOriginName()); + } + if (field.getDeType() == 1) { + if (field.getDeExtractType() == 0 || field.getDeExtractType() == 5) { + whereName = String.format(MongoConstants.STR_TO_DATE, originName, StringUtils.isNotEmpty(field.getDateFormat()) ? field.getDateFormat() : MongoConstants.DEFAULT_DATE_FORMAT); + } + if (field.getDeExtractType() == 2 || field.getDeExtractType() == 3 || field.getDeExtractType() == 4) { + String cast = String.format(MongoConstants.CAST, originName, MongoConstants.DEFAULT_INT_FORMAT) + "/1000"; + whereName = String.format(MongoConstants.FROM_UNIXTIME, cast, MongoConstants.DEFAULT_DATE_FORMAT); + } + if (field.getDeExtractType() == 1) { + whereName = originName; + } + } else if (field.getDeType() == 2 || field.getDeType() == 3) { + if (field.getDeExtractType() == 0 || field.getDeExtractType() == 5) { + whereName = String.format(MongoConstants.CAST, originName, MongoConstants.DEFAULT_FLOAT_FORMAT); + } + if (field.getDeExtractType() == 1) { + whereName = String.format(MongoConstants.UNIX_TIMESTAMP, originName); + } + if (field.getDeExtractType() == 2 || field.getDeExtractType() == 3 || field.getDeExtractType() == 4) { + whereName = originName; + } + } else { + whereName = originName; + } + + if (StringUtils.equalsIgnoreCase(item.getFilterType(), "enum")) { + if (CollectionUtils.isNotEmpty(item.getEnumValue())) { + res = "(" + whereName + " IN ('" + String.join("','", item.getEnumValue()) + "'))"; + } + } else { + String value = item.getValue(); + String whereTerm = transMysqlFilterTerm(item.getTerm()); + String whereValue = ""; + + if (StringUtils.equalsIgnoreCase(item.getTerm(), "null")) { + whereValue = ""; + } else if (StringUtils.equalsIgnoreCase(item.getTerm(), "not_null")) { + whereValue = ""; + } else if (StringUtils.equalsIgnoreCase(item.getTerm(), "empty")) { + whereValue = "''"; + } else if (StringUtils.equalsIgnoreCase(item.getTerm(), "not_empty")) { + whereValue = "''"; + } else if (StringUtils.containsIgnoreCase(item.getTerm(), "in") || StringUtils.containsIgnoreCase(item.getTerm(), "not in")) { + whereValue = "('" + String.join("','", value.split(",")) + "')"; + } else if (StringUtils.containsIgnoreCase(item.getTerm(), "like")) { + whereValue = "'%" + value + "%'"; + } else { + whereValue = String.format(MongoConstants.WHERE_VALUE_VALUE, value); + } + SQLObj build = SQLObj.builder() + .whereField(whereName) + .whereTermAndValue(whereTerm + whereValue) + .build(); + res = build.getWhereField() + " " + build.getWhereTermAndValue(); + } + return res; + } + + @Override + public String convertTableToSql(String tableName, Datasource ds) { + return createSQLPreview("SELECT * FROM " + String.format(MongoConstants.KEYWORD_TABLE, tableName), null); + } + + public String transMysqlFilterTerm(String term) { + switch (term) { + case "eq": + return " = "; + case "not_eq": + return " <> "; + case "lt": + return " < "; + case "le": + return " <= "; + case "gt": + return " > "; + case "ge": + return " >= "; + case "in": + return " IN "; + case "not in": + return " NOT IN "; + case "like": + return " LIKE "; + case "not like": + return " NOT LIKE "; + case "null": + return " IS NULL "; + case "not_null": + return " IS NOT NULL "; + case "empty": + return " = "; + case "not_empty": + return " <> "; + case "between": + return " BETWEEN "; + default: + return ""; + } + } + + public String transCustomFilterList(SQLObj tableObj, List requestList) { + if (CollectionUtils.isEmpty(requestList)) { + return null; + } + List res = new ArrayList<>(); + for (ChartFieldCustomFilterDTO request : requestList) { + List list = new ArrayList<>(); + DatasetTableField field = request.getField(); + + if (ObjectUtils.isEmpty(field)) { + continue; + } + String whereName = ""; + String originName; + if (ObjectUtils.isNotEmpty(field.getExtField()) && field.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originName = calcFieldRegex(field.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(field.getExtField()) && field.getExtField() == 1) { + originName = String.format(MongoConstants.KEYWORD_FIX, tableObj.getTableAlias(), field.getOriginName()); + } else { + originName = String.format(MongoConstants.KEYWORD_FIX, tableObj.getTableAlias(), field.getOriginName()); + } + if (field.getDeType() == 1) { + if (field.getDeExtractType() == 0 || field.getDeExtractType() == 5) { + whereName = String.format(MongoConstants.STR_TO_DATE, originName, StringUtils.isNotEmpty(field.getDateFormat()) ? field.getDateFormat() : MongoConstants.DEFAULT_DATE_FORMAT); + } + if (field.getDeExtractType() == 2 || field.getDeExtractType() == 3 || field.getDeExtractType() == 4) { + String cast = String.format(MongoConstants.CAST, originName, MongoConstants.DEFAULT_INT_FORMAT) + "/1000"; + whereName = String.format(MongoConstants.FROM_UNIXTIME, cast, MongoConstants.DEFAULT_DATE_FORMAT); + } + if (field.getDeExtractType() == 1) { + whereName = originName; + } + } else if (field.getDeType() == 2 || field.getDeType() == 3) { + if (field.getDeExtractType() == 0 || field.getDeExtractType() == 5) { + whereName = String.format(MongoConstants.CAST, originName, MongoConstants.DEFAULT_FLOAT_FORMAT); + } + if (field.getDeExtractType() == 1) { + whereName = String.format(MongoConstants.UNIX_TIMESTAMP, originName); + } + if (field.getDeExtractType() == 2 || field.getDeExtractType() == 3 || field.getDeExtractType() == 4) { + whereName = originName; + } + } else { + whereName = originName; + } + + if (StringUtils.equalsIgnoreCase(request.getFilterType(), "enum")) { + if (CollectionUtils.isNotEmpty(request.getEnumCheckField())) { + res.add("(" + whereName + " IN ('" + String.join("','", request.getEnumCheckField()) + "'))"); + } + } else { + List filter = request.getFilter(); + for (ChartCustomFilterItemDTO filterItemDTO : filter) { + String value = filterItemDTO.getValue(); + String whereTerm = transMysqlFilterTerm(filterItemDTO.getTerm()); + String whereValue = ""; + + if (StringUtils.equalsIgnoreCase(filterItemDTO.getTerm(), "null")) { + whereValue = ""; + } else if (StringUtils.equalsIgnoreCase(filterItemDTO.getTerm(), "not_null")) { + whereValue = ""; + } else if (StringUtils.equalsIgnoreCase(filterItemDTO.getTerm(), "empty")) { + whereValue = "''"; + } else if (StringUtils.equalsIgnoreCase(filterItemDTO.getTerm(), "not_empty")) { + whereValue = "''"; + } else if (StringUtils.containsIgnoreCase(filterItemDTO.getTerm(), "in") || StringUtils.containsIgnoreCase(filterItemDTO.getTerm(), "not in")) { + whereValue = "('" + String.join("','", value.split(",")) + "')"; + } else if (StringUtils.containsIgnoreCase(filterItemDTO.getTerm(), "like")) { + whereValue = "'%" + value + "%'"; + } else { + whereValue = String.format(MongoConstants.WHERE_VALUE_VALUE, value); + } + list.add(SQLObj.builder() + .whereField(whereName) + .whereTermAndValue(whereTerm + whereValue) + .build()); + } + List strList = new ArrayList<>(); + list.forEach(ele -> strList.add(ele.getWhereField() + " " + ele.getWhereTermAndValue())); + if (CollectionUtils.isNotEmpty(list)) { + res.add("(" + String.join(" " + getLogic(request.getLogic()) + " ", strList) + ")"); + } + } + } + return CollectionUtils.isNotEmpty(res) ? "(" + String.join(" AND ", res) + ")" : null; + } + + public String transExtFilterList(SQLObj tableObj, List requestList) { + if (CollectionUtils.isEmpty(requestList)) { + return null; + } + List list = new ArrayList<>(); + for (ChartExtFilterRequest request : requestList) { + List value = request.getValue(); + + List whereNameList = new ArrayList<>(); + List fieldList = new ArrayList<>(); + if (request.getIsTree()) { + fieldList.addAll(request.getDatasetTableFieldList()); + } else { + fieldList.add(request.getDatasetTableField()); + } + + for (DatasetTableField field : fieldList) { + if (CollectionUtils.isEmpty(value) || ObjectUtils.isEmpty(field)) { + continue; + } + String whereName = ""; + + String originName; + if (ObjectUtils.isNotEmpty(field.getExtField()) && field.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originName = calcFieldRegex(field.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(field.getExtField()) && field.getExtField() == 1) { + originName = String.format(MongoConstants.KEYWORD_FIX, tableObj.getTableAlias(), field.getOriginName()); + } else { + originName = String.format(MongoConstants.KEYWORD_FIX, tableObj.getTableAlias(), field.getOriginName()); + } + + if (field.getDeType() == 1) { + if (field.getDeExtractType() == 0 || field.getDeExtractType() == 5) { + whereName = String.format(MongoConstants.STR_TO_DATE, originName, StringUtils.isNotEmpty(field.getDateFormat()) ? field.getDateFormat() : MongoConstants.DEFAULT_DATE_FORMAT); + } + if (field.getDeExtractType() == 2 || field.getDeExtractType() == 3 || field.getDeExtractType() == 4) { + String cast = String.format(MongoConstants.CAST, originName, MongoConstants.DEFAULT_INT_FORMAT) + "/1000"; + whereName = String.format(MongoConstants.FROM_UNIXTIME, cast, MongoConstants.DEFAULT_DATE_FORMAT); + } + if (field.getDeExtractType() == 1) { + whereName = originName; + } + } else if (field.getDeType() == 2 || field.getDeType() == 3) { + if (field.getDeExtractType() == 0 || field.getDeExtractType() == 5) { + whereName = String.format(MongoConstants.CAST, originName, MongoConstants.DEFAULT_FLOAT_FORMAT); + } + if (field.getDeExtractType() == 1) { + whereName = String.format(MongoConstants.UNIX_TIMESTAMP, originName); + } + if (field.getDeExtractType() == 2 || field.getDeExtractType() == 3 || field.getDeExtractType() == 4) { + whereName = originName; + } + } else { + whereName = originName; + } + whereNameList.add(whereName); + } + + String whereName = ""; + if (request.getIsTree()) { + whereName = "CONCAT(" + StringUtils.join(whereNameList, ",',',") + ")"; + } else { + whereName = whereNameList.get(0); + } + String whereTerm = transMysqlFilterTerm(request.getOperator()); + String whereValue = ""; + + if (StringUtils.containsIgnoreCase(request.getOperator(), "in")) { + whereValue = "('" + StringUtils.join(value, "','") + "')"; + } else if (StringUtils.containsIgnoreCase(request.getOperator(), "like")) { + String keyword = value.get(0).toUpperCase(); + whereValue = "'%" + keyword + "%'"; + whereName = "upper(" + whereName + ")"; + } else if (StringUtils.containsIgnoreCase(request.getOperator(), "between")) { + if (request.getDatasetTableField().getDeType() == 1) { + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + String startTime = simpleDateFormat.format(new Date(Long.parseLong(value.get(0)))); + String endTime = simpleDateFormat.format(new Date(Long.parseLong(value.get(1)))); + whereValue = String.format(MongoConstants.WHERE_BETWEEN, startTime, endTime); + } else { + whereValue = String.format(MongoConstants.WHERE_BETWEEN, value.get(0), value.get(1)); + } + } else { + whereValue = String.format(MongoConstants.WHERE_VALUE_VALUE, value.get(0)); + } + list.add(SQLObj.builder() + .whereField(whereName) + .whereTermAndValue(whereTerm + whereValue) + .build()); + } + List strList = new ArrayList<>(); + list.forEach(ele -> strList.add(ele.getWhereField() + " " + ele.getWhereTermAndValue())); + return CollectionUtils.isNotEmpty(list) ? "(" + String.join(" AND ", strList) + ")" : null; + } + + private String sqlFix(String sql) { + if (sql.lastIndexOf(";") == (sql.length() - 1)) { + sql = sql.substring(0, sql.length() - 1); + } + return sql; + } + + private String transDateFormat(String dateStyle, String datePattern) { + String split = "-"; + if (StringUtils.equalsIgnoreCase(datePattern, "date_sub")) { + split = "-"; + } else if (StringUtils.equalsIgnoreCase(datePattern, "date_split")) { + split = "/"; + } else { + split = "-"; + } + + if (StringUtils.isEmpty(dateStyle)) { + return "%Y-%m-%d %H:%i:%S"; + } + + switch (dateStyle) { + case "y": + return "%Y"; + case "y_M": + return "%Y" + split + "%m"; + case "y_M_d": + return "%Y" + split + "%m" + split + "%d"; + case "H_m_s": + return "%H:%i:%S"; + case "y_M_d_H_m": + return "%Y" + split + "%m" + split + "%d" + " %H:%i"; + case "y_M_d_H_m_s": + return "%Y" + split + "%m" + split + "%d" + " %H:%i:%S"; + default: + return "%Y-%m-%d %H:%i:%S"; + } + } + + private SQLObj getXFields(ChartViewFieldDTO x, String originField, String fieldAlias) { + String fieldName = ""; + if (x.getDeExtractType() == 1) { + if (x.getDeType() == 2 || x.getDeType() == 3) { + fieldName = String.format(MongoConstants.UNIX_TIMESTAMP, originField) + "*1000"; + } else if (x.getDeType() == 1) { + String format = transDateFormat(x.getDateStyle(), x.getDatePattern()); + fieldName = String.format(MongoConstants.DATE_FORMAT, originField, format); + } else { + fieldName = originField; + } + } else { + if (x.getDeType() == 1) { + String format = transDateFormat(x.getDateStyle(), x.getDatePattern()); + if (x.getDeExtractType() == 0) { + fieldName = String.format(MongoConstants.DATE_FORMAT, String.format(MongoConstants.STR_TO_DATE, originField, StringUtils.isNotEmpty(x.getDateFormat()) ? x.getDateFormat() : MongoConstants.DEFAULT_DATE_FORMAT), format); + } else { + String cast = String.format(MongoConstants.CAST, originField, MongoConstants.DEFAULT_INT_FORMAT) + "/1000"; + String from_unixtime = String.format(MongoConstants.FROM_UNIXTIME, cast, MongoConstants.DEFAULT_DATE_FORMAT); + fieldName = String.format(MongoConstants.DATE_FORMAT, from_unixtime, format); + } + } else { + if (x.getDeType() == DeTypeConstants.DE_INT) { + fieldName = String.format(MongoConstants.CAST, originField, MongoConstants.DEFAULT_INT_FORMAT); + } else if (x.getDeType() == DeTypeConstants.DE_FLOAT) { + fieldName = String.format(MongoConstants.CAST, originField, MongoConstants.DEFAULT_FLOAT_FORMAT); + } else { + fieldName = originField; + } + } + } + return SQLObj.builder() + .fieldName(fieldName) + .fieldAlias(fieldAlias) + .build(); + } + + private List getXWheres(ChartViewFieldDTO x, String originField, String fieldAlias) { + List list = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(x.getFilter()) && x.getFilter().size() > 0) { + x.getFilter().forEach(f -> { + String whereName = ""; + String whereTerm = transMysqlFilterTerm(f.getTerm()); + String whereValue = ""; + if (x.getDeType() == 1 && x.getDeExtractType() != 1) { + String cast = String.format(MongoConstants.CAST, originField, MongoConstants.DEFAULT_INT_FORMAT) + "/1000"; + whereName = String.format(MongoConstants.FROM_UNIXTIME, cast, MongoConstants.DEFAULT_DATE_FORMAT); + } else { + whereName = originField; + } + if (StringUtils.equalsIgnoreCase(f.getTerm(), "null")) { + whereValue = ""; + } else if (StringUtils.equalsIgnoreCase(f.getTerm(), "not_null")) { + whereValue = ""; + } else if (StringUtils.equalsIgnoreCase(f.getTerm(), "empty")) { + whereValue = "''"; + } else if (StringUtils.equalsIgnoreCase(f.getTerm(), "not_empty")) { + whereValue = "''"; + } else if (StringUtils.containsIgnoreCase(f.getTerm(), "in")) { + whereValue = "('" + StringUtils.join(f.getValue(), "','") + "')"; + } else if (StringUtils.containsIgnoreCase(f.getTerm(), "like")) { + whereValue = "'%" + f.getValue() + "%'"; + } else { + whereValue = String.format(MongoConstants.WHERE_VALUE_VALUE, f.getValue()); + } + list.add(SQLObj.builder() + .whereField(whereName) + .whereAlias(fieldAlias) + .whereTermAndValue(whereTerm + whereValue) + .build()); + }); + } + return list; + } + + private SQLObj getYFields(ChartViewFieldDTO y, String originField, String fieldAlias) { + String fieldName = ""; + if (StringUtils.equalsIgnoreCase(y.getOriginName(), "*")) { + fieldName = MongoConstants.AGG_COUNT; + } else if (SQLConstants.DIMENSION_TYPE.contains(y.getDeType())) { + if (StringUtils.equalsIgnoreCase(y.getSummary(), "count_distinct")) { + fieldName = String.format(MongoConstants.AGG_FIELD, "COUNT", "DISTINCT " + originField); + } else if (StringUtils.equalsIgnoreCase(y.getSummary(), "group_concat")) { + fieldName = String.format(MongoConstants.GROUP_CONCAT, originField); + } else { + fieldName = String.format(MongoConstants.AGG_FIELD, y.getSummary(), originField); + } + } else { + if (StringUtils.equalsIgnoreCase(y.getSummary(), "avg") || StringUtils.containsIgnoreCase(y.getSummary(), "pop")) { + String cast = String.format(MongoConstants.CAST, originField, y.getDeType() == 2 ? MongoConstants.DEFAULT_INT_FORMAT : MongoConstants.DEFAULT_FLOAT_FORMAT); + String agg = String.format(MongoConstants.AGG_FIELD, y.getSummary(), cast); + fieldName = String.format(MongoConstants.CAST, agg, MongoConstants.DEFAULT_FLOAT_FORMAT); + } else { + String cast = String.format(MongoConstants.CAST, originField, y.getDeType() == 2 ? MongoConstants.DEFAULT_INT_FORMAT : MongoConstants.DEFAULT_FLOAT_FORMAT); + if (StringUtils.equalsIgnoreCase(y.getSummary(), "count_distinct")) { + fieldName = String.format(MongoConstants.AGG_FIELD, "COUNT", "DISTINCT " + cast); + } else { + fieldName = String.format(MongoConstants.AGG_FIELD, y.getSummary(), cast); + } + } + } + return SQLObj.builder() + .fieldName(fieldName) + .fieldAlias(fieldAlias) + .build(); + } + + private String getYWheres(ChartViewFieldDTO y, String originField, String fieldAlias) { + List list = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(y.getFilter()) && y.getFilter().size() > 0) { + y.getFilter().forEach(f -> { + String whereTerm = transMysqlFilterTerm(f.getTerm()); + String whereValue = ""; + // 原始类型不是时间,在de中被转成时间的字段做处理 + if (StringUtils.equalsIgnoreCase(f.getTerm(), "null")) { + whereValue = ""; + } else if (StringUtils.equalsIgnoreCase(f.getTerm(), "not_null")) { + whereValue = ""; + } else if (StringUtils.equalsIgnoreCase(f.getTerm(), "empty")) { + whereValue = "''"; + } else if (StringUtils.equalsIgnoreCase(f.getTerm(), "not_empty")) { + whereValue = "''"; + } else if (StringUtils.containsIgnoreCase(f.getTerm(), "in")) { + whereValue = "('" + StringUtils.join(f.getValue(), "','") + "')"; + } else if (StringUtils.containsIgnoreCase(f.getTerm(), "like")) { + whereValue = "'%" + f.getValue() + "%'"; + } else { + whereValue = String.format(MongoConstants.WHERE_VALUE_VALUE, f.getValue()); + } + list.add(SQLObj.builder() + .whereField(fieldAlias) + .whereAlias(fieldAlias) + .whereTermAndValue(whereTerm + whereValue) + .build()); + }); + } + List strList = new ArrayList<>(); + list.forEach(ele -> strList.add(ele.getWhereField() + " " + ele.getWhereTermAndValue())); + return CollectionUtils.isNotEmpty(list) ? "(" + String.join(" " + getLogic(y.getLogic()) + " ", strList) + ")" : null; + } + + private String calcFieldRegex(String originField, SQLObj tableObj) { + originField = originField.replaceAll("[\\t\\n\\r]]", ""); + // 正则提取[xxx] + String regex = "\\[(.*?)]"; + Pattern pattern = Pattern.compile(regex); + Matcher matcher = pattern.matcher(originField); + Set ids = new HashSet<>(); + while (matcher.find()) { + String id = matcher.group(1); + ids.add(id); + } + if (CollectionUtils.isEmpty(ids)) { + return originField; + } + DatasetTableFieldExample datasetTableFieldExample = new DatasetTableFieldExample(); + datasetTableFieldExample.createCriteria().andIdIn(new ArrayList<>(ids)); + List calcFields = datasetTableFieldMapper.selectByExample(datasetTableFieldExample); + for (DatasetTableField ele : calcFields) { + originField = originField.replaceAll("\\[" + ele.getId() + "]", + String.format(MongoConstants.KEYWORD_FIX, tableObj.getTableAlias(), ele.getOriginName())); + } + return originField; + } + + private String sqlLimit(String sql, ChartViewWithBLOBs view) { + if (StringUtils.equalsIgnoreCase(view.getResultMode(), "custom")) { + return sql + " LIMIT 0," + view.getResultCount(); + } else { + return sql; + } + } + + @Override + public String sqlForPreview(String table, Datasource ds) { + return "SELECT * FROM " + String.format(MongoConstants.KEYWORD_TABLE, table); + } + + public List dateformat() { + ObjectMapper objectMapper = new ObjectMapper(); + List dateformats = new ArrayList<>(); + try{ + dateformats = objectMapper.readValue("[\n" + + "{\"dateformat\": \"%Y%m%d\"},\n" + + "{\"dateformat\": \"%Y-%m-%d\"},\n" + + "{\"dateformat\": \"%Y/%m/%d\"},\n" + + "{\"dateformat\": \"%Y%m%d %H:%i:%S\"},\n" + + "{\"dateformat\": \"%Y/%m/%d %H:%i:%S\"},\n" + + "{\"dateformat\": \"%Y-%m-%d %H:%i:%S\"}\n" + + "]", new TypeReference>() {} ); + }catch (Exception e){} + return dateformats; + } +} diff --git a/extensions/dataease-extensions-datasource/mongo/mongo-backend/src/main/java/io/dataease/plugins/datasource/mongo/service/MongoService.java b/extensions/dataease-extensions-datasource/mongo/mongo-backend/src/main/java/io/dataease/plugins/datasource/mongo/service/MongoService.java new file mode 100644 index 0000000000..69ae136824 --- /dev/null +++ b/extensions/dataease-extensions-datasource/mongo/mongo-backend/src/main/java/io/dataease/plugins/datasource/mongo/service/MongoService.java @@ -0,0 +1,58 @@ +package io.dataease.plugins.datasource.mongo.service; + +import io.dataease.plugins.common.constants.DatabaseClassification; +import io.dataease.plugins.common.constants.DatasourceCalculationMode; +import io.dataease.plugins.common.dto.StaticResource; +import io.dataease.plugins.common.dto.datasource.DataSourceType; +import io.dataease.plugins.datasource.service.DatasourceService; +import org.springframework.stereotype.Service; + +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + +@Service +public class MongoService extends DatasourceService { + + + @Override + public List components() { + List result = new ArrayList<>(); + result.add("mongobi"); + return result; + } + @Override + protected InputStream readContent(String s) { + InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream("static/" + s); + return resourceAsStream; + } + + @Override + public List staticResources() { + List results = new ArrayList<>(); + StaticResource staticResource = new StaticResource(); + staticResource.setName("mongobi"); + staticResource.setSuffix("jpg"); + results.add(staticResource); + results.add(pluginSvg()); + return results; + } + + @Override + public DataSourceType getDataSourceType() { + DataSourceType dataSourceType = new DataSourceType("mongobi", "Mongodb-BI" , true , "characterEncoding=UTF-8&connectTimeout=5000&useSSL=true&allowPublicKeyRetrieval=true&verifyServerCertificate=false", DatasourceCalculationMode.DIRECT, true); + dataSourceType.setKeywordPrefix("`"); + dataSourceType.setKeywordSuffix("`"); + dataSourceType.setAliasPrefix(""); + dataSourceType.setAliasSuffix(""); + dataSourceType.setDatabaseClassification(DatabaseClassification.OLTP); + return dataSourceType; + } + + private StaticResource pluginSvg() { + StaticResource staticResource = new StaticResource(); + staticResource.setName("mongo-backend"); + staticResource.setSuffix("svg"); + return staticResource; + } +} diff --git a/extensions/dataease-extensions-datasource/mongo/mongo-frontend/.babelrc b/extensions/dataease-extensions-datasource/mongo/mongo-frontend/.babelrc new file mode 100644 index 0000000000..3a280ba34b --- /dev/null +++ b/extensions/dataease-extensions-datasource/mongo/mongo-frontend/.babelrc @@ -0,0 +1,12 @@ +{ + "presets": [ + ["env", { + "modules": false, + "targets": { + "browsers": ["> 1%", "last 2 versions", "not ie <= 8"] + } + }], + "stage-2" + ], + "plugins": ["transform-vue-jsx", "transform-runtime"] +} diff --git a/extensions/dataease-extensions-datasource/mongo/mongo-frontend/.gitignore b/extensions/dataease-extensions-datasource/mongo/mongo-frontend/.gitignore new file mode 100644 index 0000000000..541a820f6c --- /dev/null +++ b/extensions/dataease-extensions-datasource/mongo/mongo-frontend/.gitignore @@ -0,0 +1,14 @@ +.DS_Store +node_modules/ +/dist/ +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Editor directories and files +.idea +.vscode +*.suo +*.ntvs* +*.njsproj +*.sln diff --git a/extensions/dataease-extensions-datasource/mongo/mongo-frontend/README.md b/extensions/dataease-extensions-datasource/mongo/mongo-frontend/README.md new file mode 100644 index 0000000000..c1e4be95e0 --- /dev/null +++ b/extensions/dataease-extensions-datasource/mongo/mongo-frontend/README.md @@ -0,0 +1,21 @@ +# deplugin-view-frontend + +> A Vue.js project + +## Build Setup + +``` bash +# install dependencies +npm install + +# serve with hot reload at localhost:8080 +npm run dev + +# build for production with minification +npm run build + +# build for production and view the bundle analyzer report +npm run build --report +``` + +For a detailed explanation on how things work, check out the [guide](http://vuejs-templates.github.io/webpack/) and [docs for vue-loader](http://vuejs.github.io/vue-loader). diff --git a/extensions/dataease-extensions-datasource/mongo/mongo-frontend/build/build-async-plugins.js b/extensions/dataease-extensions-datasource/mongo/mongo-frontend/build/build-async-plugins.js new file mode 100644 index 0000000000..2303854531 --- /dev/null +++ b/extensions/dataease-extensions-datasource/mongo/mongo-frontend/build/build-async-plugins.js @@ -0,0 +1,35 @@ +'use strict' +require('./check-versions')() + +process.env.NODE_ENV = 'production' + +const ora = require('ora') +const chalk = require('chalk') +const webpack = require('webpack') +const webpackConfig = require('./webpack.async-plugins') + +const spinner = ora('building for sync-plugins...') +spinner.start() + +webpack(webpackConfig, function (err, stats) { + spinner.stop() + if (err) throw err + process.stdout.write(stats.toString({ + colors: true, + modules: false, + children: false, + chunks: false, + chunkModules: false + }) + '\n\n') + + if (stats.hasErrors()) { + console.log(chalk.red(' Build failed with errors.\n')) + process.exit(1) + } + + console.log(chalk.cyan(' Build complete.\n')) + console.log(chalk.yellow( + ' Tip: built files are meant to be served over an HTTP server.\n' + + ' Opening index.html over file:// won\'t work.\n' + )) +}) diff --git a/extensions/dataease-extensions-datasource/mongo/mongo-frontend/build/build.js b/extensions/dataease-extensions-datasource/mongo/mongo-frontend/build/build.js new file mode 100644 index 0000000000..8f2ad8ad49 --- /dev/null +++ b/extensions/dataease-extensions-datasource/mongo/mongo-frontend/build/build.js @@ -0,0 +1,41 @@ +'use strict' +require('./check-versions')() + +process.env.NODE_ENV = 'production' + +const ora = require('ora') +const rm = require('rimraf') +const path = require('path') +const chalk = require('chalk') +const webpack = require('webpack') +const config = require('../config') +const webpackConfig = require('./webpack.prod.conf') + +const spinner = ora('building for production...') +spinner.start() + +rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => { + if (err) throw err + webpack(webpackConfig, (err, stats) => { + spinner.stop() + if (err) throw err + process.stdout.write(stats.toString({ + colors: true, + modules: false, + children: false, // If you are using ts-loader, setting this to true will make TypeScript errors show up during build. + chunks: false, + chunkModules: false + }) + '\n\n') + + if (stats.hasErrors()) { + console.log(chalk.red(' Build failed with errors.\n')) + process.exit(1) + } + + console.log(chalk.cyan(' Build complete.\n')) + console.log(chalk.yellow( + ' Tip: built files are meant to be served over an HTTP server.\n' + + ' Opening index.html over file:// won\'t work.\n' + )) + }) +}) diff --git a/extensions/dataease-extensions-datasource/mongo/mongo-frontend/build/check-versions.js b/extensions/dataease-extensions-datasource/mongo/mongo-frontend/build/check-versions.js new file mode 100644 index 0000000000..3ef972a08d --- /dev/null +++ b/extensions/dataease-extensions-datasource/mongo/mongo-frontend/build/check-versions.js @@ -0,0 +1,54 @@ +'use strict' +const chalk = require('chalk') +const semver = require('semver') +const packageConfig = require('../package.json') +const shell = require('shelljs') + +function exec (cmd) { + return require('child_process').execSync(cmd).toString().trim() +} + +const versionRequirements = [ + { + name: 'node', + currentVersion: semver.clean(process.version), + versionRequirement: packageConfig.engines.node + } +] + +if (shell.which('npm')) { + versionRequirements.push({ + name: 'npm', + currentVersion: exec('npm --version'), + versionRequirement: packageConfig.engines.npm + }) +} + +module.exports = function () { + const warnings = [] + + for (let i = 0; i < versionRequirements.length; i++) { + const mod = versionRequirements[i] + + if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) { + warnings.push(mod.name + ': ' + + chalk.red(mod.currentVersion) + ' should be ' + + chalk.green(mod.versionRequirement) + ) + } + } + + if (warnings.length) { + console.log('') + console.log(chalk.yellow('To use this template, you must update following to modules:')) + console.log() + + for (let i = 0; i < warnings.length; i++) { + const warning = warnings[i] + console.log(' ' + warning) + } + + console.log() + process.exit(1) + } +} diff --git a/extensions/dataease-extensions-datasource/mongo/mongo-frontend/build/logo.png b/extensions/dataease-extensions-datasource/mongo/mongo-frontend/build/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..f3d2503fc2a44b5053b0837ebea6e87a2d339a43 GIT binary patch literal 6849 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 { + const notifier = require('node-notifier') + + return (severity, errors) => { + if (severity !== 'error') return + + const error = errors[0] + const filename = error.file && error.file.split('!').pop() + + notifier.notify({ + title: packageConfig.name, + message: severity + ': ' + error.name, + subtitle: filename || '', + icon: path.join(__dirname, 'logo.png') + }) + } +} diff --git a/extensions/dataease-extensions-datasource/mongo/mongo-frontend/build/vue-loader.conf.js b/extensions/dataease-extensions-datasource/mongo/mongo-frontend/build/vue-loader.conf.js new file mode 100644 index 0000000000..33ed58bc0a --- /dev/null +++ b/extensions/dataease-extensions-datasource/mongo/mongo-frontend/build/vue-loader.conf.js @@ -0,0 +1,22 @@ +'use strict' +const utils = require('./utils') +const config = require('../config') +const isProduction = process.env.NODE_ENV === 'production' +const sourceMapEnabled = isProduction + ? config.build.productionSourceMap + : config.dev.cssSourceMap + +module.exports = { + loaders: utils.cssLoaders({ + sourceMap: sourceMapEnabled, + extract: isProduction + }), + cssSourceMap: sourceMapEnabled, + cacheBusting: config.dev.cacheBusting, + transformToRequire: { + video: ['src', 'poster'], + source: 'src', + img: 'src', + image: 'xlink:href' + } +} diff --git a/extensions/dataease-extensions-datasource/mongo/mongo-frontend/build/webpack.async-plugins.js b/extensions/dataease-extensions-datasource/mongo/mongo-frontend/build/webpack.async-plugins.js new file mode 100644 index 0000000000..04eef77f4c --- /dev/null +++ b/extensions/dataease-extensions-datasource/mongo/mongo-frontend/build/webpack.async-plugins.js @@ -0,0 +1,103 @@ +const webpack = require('webpack') +const path = require('path') +const utils = require('./utils') +const CopyPlugin = require("copy-webpack-plugin"); +const VueLoaderPlugin = require('vue-loader/lib/plugin'); +function resolve (dir) { + return path.join(__dirname, '..', dir) +} + +module.exports = { + mode: 'development', + entry: { + 'mongobi': resolve('/src/views/mongobi.vue') + }, + output: { + path: resolve('/static/'), + filename: '[name].js' + }, + resolve: { + extensions: ['.js', '.vue', '.json'], + alias: { + 'vue$': 'vue/dist/vue.esm.js', + '@': resolve('src') + } + }, + externals: { + vue: 'vue' + }, + module: { + rules: [ + { + test: /\.vue$/, + loader: 'vue-loader', + options: { + transformAssetUrls: { + video: 'src', + source: 'src', + img: 'src', + image: 'xlink:href' + } + } + }, + { + test: /.(sa|sc|c)ss$/, + use: [ + {loader: 'vue-style-loader'}, + 'css-loader', + 'sass-loader' + ] + }, + { + test: /\.js$/, + loader: 'babel-loader', + include: [resolve('src'), resolve('test')] + }, + { + test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: utils.assetsPath('img/[name].[hash:7].[ext]') + } + }, + { + test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: utils.assetsPath('media/[name].[hash:7].[ext]') + } + }, + { + test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: utils.assetsPath('fonts/[name].[hash:7].[ext]') + } + }, + { + test: /\.svg$/, + include: [path.resolve('src/icons')], + use: [ + { + loader: 'svg-sprite-loader', + options: { + symbolId: 'icon-[name]', + }, + } + ], + } + ] + }, + plugins: [ + new VueLoaderPlugin(), + new webpack.DefinePlugin({ + 'process.env.NODE_ENV': '"production"' + }), + new CopyPlugin([ + {from: 'src/icons/svg/'} + ]), + ] +} diff --git a/extensions/dataease-extensions-datasource/mongo/mongo-frontend/build/webpack.base.conf.js b/extensions/dataease-extensions-datasource/mongo/mongo-frontend/build/webpack.base.conf.js new file mode 100644 index 0000000000..6ccc02dab4 --- /dev/null +++ b/extensions/dataease-extensions-datasource/mongo/mongo-frontend/build/webpack.base.conf.js @@ -0,0 +1,91 @@ +'use strict' +const path = require('path') +const utils = require('./utils') +const config = require('../config') +const vueLoaderConfig = require('./vue-loader.conf') + +function resolve (dir) { + return path.join(__dirname, '..', dir) +} + + + +module.exports = { + context: path.resolve(__dirname, '../'), + entry: { + app: './src/main.js' + }, + output: { + path: config.build.assetsRoot, + filename: '[name].js', + publicPath: process.env.NODE_ENV === 'production' + ? config.build.assetsPublicPath + : config.dev.assetsPublicPath + }, + resolve: { + extensions: ['.js', '.vue', '.json'], + alias: { + 'vue$': 'vue/dist/vue.esm.js', + '@': resolve('src'), + } + }, + module: { + rules: [ + { + test: /\.vue$/, + loader: 'vue-loader', + options: vueLoaderConfig + }, + { + test: /\.js$/, + loader: 'babel-loader', + include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')] + }, + { + test: /\.svg$/, + loader: 'svg-sprite-loader', + include: [resolve('src/icons')], + options: { + symbolId: 'icon-[name]' + } + }, + { + test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, + loader: 'url-loader', + exclude: [resolve('src/icons')], + options: { + limit: 10000, + name: utils.assetsPath('img/[name].[hash:7].[ext]') + } + }, + { + test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: utils.assetsPath('media/[name].[hash:7].[ext]') + } + }, + { + test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: utils.assetsPath('fonts/[name].[hash:7].[ext]') + } + } + ] + }, + node: { + // prevent webpack from injecting useless setImmediate polyfill because Vue + // source contains it (although only uses it if it's native). + setImmediate: false, + // prevent webpack from injecting mocks to Node native modules + // that does not make sense for the client + dgram: 'empty', + fs: 'empty', + net: 'empty', + tls: 'empty', + child_process: 'empty' + } +} diff --git a/extensions/dataease-extensions-datasource/mongo/mongo-frontend/build/webpack.dev.conf.js b/extensions/dataease-extensions-datasource/mongo/mongo-frontend/build/webpack.dev.conf.js new file mode 100755 index 0000000000..070ae221f3 --- /dev/null +++ b/extensions/dataease-extensions-datasource/mongo/mongo-frontend/build/webpack.dev.conf.js @@ -0,0 +1,95 @@ +'use strict' +const utils = require('./utils') +const webpack = require('webpack') +const config = require('../config') +const merge = require('webpack-merge') +const path = require('path') +const baseWebpackConfig = require('./webpack.base.conf') +const CopyWebpackPlugin = require('copy-webpack-plugin') +const HtmlWebpackPlugin = require('html-webpack-plugin') +const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin') +const portfinder = require('portfinder') + +const HOST = process.env.HOST +const PORT = process.env.PORT && Number(process.env.PORT) + +const devWebpackConfig = merge(baseWebpackConfig, { + module: { + rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true }) + }, + // cheap-module-eval-source-map is faster for development + devtool: config.dev.devtool, + + // these devServer options should be customized in /config/index.js + devServer: { + clientLogLevel: 'warning', + historyApiFallback: { + rewrites: [ + { from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') }, + ], + }, + hot: true, + contentBase: false, // since we use CopyWebpackPlugin. + compress: true, + host: HOST || config.dev.host, + port: PORT || config.dev.port, + open: config.dev.autoOpenBrowser, + overlay: config.dev.errorOverlay + ? { warnings: false, errors: true } + : false, + publicPath: config.dev.assetsPublicPath, + proxy: config.dev.proxyTable, + quiet: true, // necessary for FriendlyErrorsPlugin + watchOptions: { + poll: config.dev.poll, + } + }, + plugins: [ + new webpack.DefinePlugin({ + 'process.env': require('../config/dev.env') + }), + new webpack.HotModuleReplacementPlugin(), + new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update. + new webpack.NoEmitOnErrorsPlugin(), + // https://github.com/ampedandwired/html-webpack-plugin + new HtmlWebpackPlugin({ + filename: 'index.html', + template: 'index.html', + inject: true + }), + // copy custom static assets + new CopyWebpackPlugin([ + { + from: path.resolve(__dirname, '../static'), + to: config.dev.assetsSubDirectory, + ignore: ['.*'] + } + ]) + ] +}) + +module.exports = new Promise((resolve, reject) => { + portfinder.basePort = process.env.PORT || config.dev.port + portfinder.getPort((err, port) => { + if (err) { + reject(err) + } else { + // publish the new Port, necessary for e2e tests + process.env.PORT = port + // add port to devServer config + devWebpackConfig.devServer.port = port + + // Add FriendlyErrorsPlugin + devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({ + compilationSuccessInfo: { + messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`], + }, + onErrors: config.dev.notifyOnErrors + ? utils.createNotifierCallback() + : undefined + })) + + resolve(devWebpackConfig) + } + }) +}) diff --git a/extensions/dataease-extensions-datasource/mongo/mongo-frontend/build/webpack.prod.conf.js b/extensions/dataease-extensions-datasource/mongo/mongo-frontend/build/webpack.prod.conf.js new file mode 100644 index 0000000000..3e25238ef6 --- /dev/null +++ b/extensions/dataease-extensions-datasource/mongo/mongo-frontend/build/webpack.prod.conf.js @@ -0,0 +1,145 @@ +'use strict' +const path = require('path') +const utils = require('./utils') +const webpack = require('webpack') +const config = require('../config') +const merge = require('webpack-merge') +const baseWebpackConfig = require('./webpack.base.conf') +const CopyWebpackPlugin = require('copy-webpack-plugin') +const HtmlWebpackPlugin = require('html-webpack-plugin') +const ExtractTextPlugin = require('extract-text-webpack-plugin') +const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin') +const UglifyJsPlugin = require('uglifyjs-webpack-plugin') + +const env = require('../config/prod.env') + +const webpackConfig = merge(baseWebpackConfig, { + module: { + rules: utils.styleLoaders({ + sourceMap: config.build.productionSourceMap, + extract: true, + usePostCSS: true + }) + }, + devtool: config.build.productionSourceMap ? config.build.devtool : false, + output: { + path: config.build.assetsRoot, + filename: utils.assetsPath('js/[name].[chunkhash].js'), + chunkFilename: utils.assetsPath('js/[id].[chunkhash].js') + }, + plugins: [ + // http://vuejs.github.io/vue-loader/en/workflow/production.html + new webpack.DefinePlugin({ + 'process.env': env + }), + new UglifyJsPlugin({ + uglifyOptions: { + compress: { + warnings: false + } + }, + sourceMap: config.build.productionSourceMap, + parallel: true + }), + // extract css into its own file + new ExtractTextPlugin({ + filename: utils.assetsPath('css/[name].[contenthash].css'), + // Setting the following option to `false` will not extract CSS from codesplit chunks. + // Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack. + // It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`, + // increasing file size: https://github.com/vuejs-templates/webpack/issues/1110 + allChunks: true, + }), + // Compress extracted CSS. We are using this plugin so that possible + // duplicated CSS from different components can be deduped. + new OptimizeCSSPlugin({ + cssProcessorOptions: config.build.productionSourceMap + ? { safe: true, map: { inline: false } } + : { safe: true } + }), + // generate dist index.html with correct asset hash for caching. + // you can customize output by editing /index.html + // see https://github.com/ampedandwired/html-webpack-plugin + new HtmlWebpackPlugin({ + filename: config.build.index, + template: 'index.html', + inject: true, + minify: { + removeComments: true, + collapseWhitespace: true, + removeAttributeQuotes: true + // more options: + // https://github.com/kangax/html-minifier#options-quick-reference + }, + // necessary to consistently work with multiple chunks via CommonsChunkPlugin + chunksSortMode: 'dependency' + }), + // keep module.id stable when vendor modules does not change + new webpack.HashedModuleIdsPlugin(), + // enable scope hoisting + new webpack.optimize.ModuleConcatenationPlugin(), + // split vendor js into its own file + new webpack.optimize.CommonsChunkPlugin({ + name: 'vendor', + minChunks (module) { + // any required modules inside node_modules are extracted to vendor + return ( + module.resource && + /\.js$/.test(module.resource) && + module.resource.indexOf( + path.join(__dirname, '../node_modules') + ) === 0 + ) + } + }), + // extract webpack runtime and module manifest to its own file in order to + // prevent vendor hash from being updated whenever app bundle is updated + new webpack.optimize.CommonsChunkPlugin({ + name: 'manifest', + minChunks: Infinity + }), + // This instance extracts shared chunks from code split chunks and bundles them + // in a separate chunk, similar to the vendor chunk + // see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk + new webpack.optimize.CommonsChunkPlugin({ + name: 'app', + async: 'vendor-async', + children: true, + minChunks: 3 + }), + + // copy custom static assets + new CopyWebpackPlugin([ + { + from: path.resolve(__dirname, '../static'), + to: config.build.assetsSubDirectory, + ignore: ['.*'] + } + ]) + ] +}) + +if (config.build.productionGzip) { + const CompressionWebpackPlugin = require('compression-webpack-plugin') + + webpackConfig.plugins.push( + new CompressionWebpackPlugin({ + asset: '[path].gz[query]', + algorithm: 'gzip', + test: new RegExp( + '\\.(' + + config.build.productionGzipExtensions.join('|') + + ')$' + ), + threshold: 10240, + minRatio: 0.8 + }) + ) +} + +if (config.build.bundleAnalyzerReport) { + const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin + webpackConfig.plugins.push(new BundleAnalyzerPlugin()) +} + +module.exports = webpackConfig diff --git a/extensions/dataease-extensions-datasource/mongo/mongo-frontend/config/dev.env.js b/extensions/dataease-extensions-datasource/mongo/mongo-frontend/config/dev.env.js new file mode 100644 index 0000000000..1e22973ae7 --- /dev/null +++ b/extensions/dataease-extensions-datasource/mongo/mongo-frontend/config/dev.env.js @@ -0,0 +1,7 @@ +'use strict' +const merge = require('webpack-merge') +const prodEnv = require('./prod.env') + +module.exports = merge(prodEnv, { + NODE_ENV: '"development"' +}) diff --git a/extensions/dataease-extensions-datasource/mongo/mongo-frontend/config/index.js b/extensions/dataease-extensions-datasource/mongo/mongo-frontend/config/index.js new file mode 100644 index 0000000000..c5eded7f81 --- /dev/null +++ b/extensions/dataease-extensions-datasource/mongo/mongo-frontend/config/index.js @@ -0,0 +1,69 @@ +'use strict' +// Template version: 1.3.1 +// see http://vuejs-templates.github.io/webpack for documentation. + +const path = require('path') + +module.exports = { + dev: { + + // Paths + assetsSubDirectory: 'static', + assetsPublicPath: '/', + proxyTable: {}, + + // Various Dev Server settings + host: 'localhost', // can be overwritten by process.env.HOST + port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined + autoOpenBrowser: false, + errorOverlay: true, + notifyOnErrors: true, + poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions- + + + /** + * Source Maps + */ + + // https://webpack.js.org/configuration/devtool/#development + devtool: 'cheap-module-eval-source-map', + + // If you have problems debugging vue-files in devtools, + // set this to false - it *may* help + // https://vue-loader.vuejs.org/en/options.html#cachebusting + cacheBusting: true, + + cssSourceMap: true + }, + + build: { + // Template for index.html + index: path.resolve(__dirname, '../dist/index.html'), + + // Paths + assetsRoot: path.resolve(__dirname, '../dist'), + assetsSubDirectory: 'static', + assetsPublicPath: '/', + + /** + * Source Maps + */ + + productionSourceMap: true, + // https://webpack.js.org/configuration/devtool/#production + devtool: '#source-map', + + // Gzip off by default as many popular static hosts such as + // Surge or Netlify already gzip all static assets for you. + // Before setting to `true`, make sure to: + // npm install --save-dev compression-webpack-plugin + productionGzip: false, + productionGzipExtensions: ['js', 'css'], + + // Run the build command with an extra argument to + // View the bundle analyzer report after build finishes: + // `npm run build --report` + // Set to `true` or `false` to always turn it on or off + bundleAnalyzerReport: process.env.npm_config_report + } +} diff --git a/extensions/dataease-extensions-datasource/mongo/mongo-frontend/config/prod.env.js b/extensions/dataease-extensions-datasource/mongo/mongo-frontend/config/prod.env.js new file mode 100644 index 0000000000..a6f997616e --- /dev/null +++ b/extensions/dataease-extensions-datasource/mongo/mongo-frontend/config/prod.env.js @@ -0,0 +1,4 @@ +'use strict' +module.exports = { + NODE_ENV: '"production"' +} diff --git a/extensions/dataease-extensions-datasource/mongo/mongo-frontend/index.html b/extensions/dataease-extensions-datasource/mongo/mongo-frontend/index.html new file mode 100644 index 0000000000..03ce3fdf27 --- /dev/null +++ b/extensions/dataease-extensions-datasource/mongo/mongo-frontend/index.html @@ -0,0 +1,12 @@ + + + + + + deplugin-view-frontend + + +
+ + + diff --git a/extensions/dataease-extensions-datasource/mongo/mongo-frontend/package.json b/extensions/dataease-extensions-datasource/mongo/mongo-frontend/package.json new file mode 100644 index 0000000000..64a3ce7ad6 --- /dev/null +++ b/extensions/dataease-extensions-datasource/mongo/mongo-frontend/package.json @@ -0,0 +1,75 @@ +{ + "name": "deplugin-datasource-frontend", + "version": "1.0.0", + "description": "A Vue.js project", + "author": "", + "private": true, + "scripts": { + "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js", + "start": "npm run dev", + "build": "node build/build.js", + "buildPlugin": "node build/build-async-plugins.js" + }, + "dependencies": { + "@riophae/vue-treeselect": "0.4.0", + "highcharts": "^10.0.0", + "svg-sprite-loader": "^6.0.11", + "svgo": "1.2.2", + "svgo-loader": "^3.0.1", + "vue": "^2.5.2", + "vue-i18n": "7.3.2", + "vue-router": "^3.0.1", + "vue-uuid": "2.0.2", + "vuedraggable": "^2.24.3" + }, + "devDependencies": { + "autoprefixer": "^7.1.2", + "babel-core": "^6.22.1", + "babel-helper-vue-jsx-merge-props": "^2.0.3", + "babel-loader": "^7.1.1", + "babel-plugin-syntax-jsx": "^6.18.0", + "babel-plugin-transform-runtime": "^6.22.0", + "babel-plugin-transform-vue-jsx": "^3.5.0", + "babel-preset-env": "^1.3.2", + "babel-preset-stage-2": "^6.22.0", + "chalk": "^2.0.1", + "copy-webpack-plugin": "^4.6.0", + "css-loader": "^0.28.0", + "element-ui": "2.15.7", + "extract-text-webpack-plugin": "^4.0.0-beta.0", + "file-loader": "^1.1.4", + "friendly-errors-webpack-plugin": "^1.6.1", + "html-webpack-plugin": "^3.2.0", + "js-cookie": "2.2.0", + "node-notifier": "^8.0.1", + "optimize-css-assets-webpack-plugin": "^3.2.0", + "ora": "^1.2.0", + "portfinder": "^1.0.13", + "postcss-import": "^11.0.0", + "postcss-loader": "^2.0.8", + "postcss-url": "^7.2.1", + "rimraf": "^2.6.0", + "sass": "^1.33.0", + "sass-loader": "^7.3.1", + "semver": "^5.3.0", + "shelljs": "^0.8.5", + "uglifyjs-webpack-plugin": "^1.1.1", + "url-loader": "^0.5.8", + "vue-loader": "^15.6.4", + "vue-style-loader": "^4.1.2", + "vue-template-compiler": "^2.5.2", + "webpack": "^4.8.1", + "webpack-bundle-analyzer": "^3.3.2", + "webpack-dev-server": "^3.1.11", + "webpack-merge": "^4.1.0" + }, + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + }, + "browserslist": [ + "> 1%", + "last 2 versions", + "not ie <= 8" + ] +} diff --git a/extensions/dataease-extensions-datasource/mongo/mongo-frontend/pom.xml b/extensions/dataease-extensions-datasource/mongo/mongo-frontend/pom.xml new file mode 100644 index 0000000000..686065e7cc --- /dev/null +++ b/extensions/dataease-extensions-datasource/mongo/mongo-frontend/pom.xml @@ -0,0 +1,80 @@ + + + + + io.dataease + mongo + ${dataease.version} + + + 4.0.0 + mongo-frontend + + + UTF-8 + UTF-8 + 1.9.1 + + + + + + maven-clean-plugin + + + + static + + ** + + false + + + + + + + + com.github.eirslett + frontend-maven-plugin + ${frontend-maven-plugin.version} + + + install node and npm + + install-node-and-npm + + + + v16.20.2 + 7.6.3 + + + + + npm install + + npm + + + + install --force + + + + + npm run buildPlugin + + npm + + + run buildPlugin + + + + + + + diff --git a/extensions/dataease-extensions-datasource/mongo/mongo-frontend/src/App.vue b/extensions/dataease-extensions-datasource/mongo/mongo-frontend/src/App.vue new file mode 100644 index 0000000000..8542e07722 --- /dev/null +++ b/extensions/dataease-extensions-datasource/mongo/mongo-frontend/src/App.vue @@ -0,0 +1,23 @@ + + + + + diff --git a/extensions/dataease-extensions-datasource/mongo/mongo-frontend/src/assets/logo.png b/extensions/dataease-extensions-datasource/mongo/mongo-frontend/src/assets/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..f3d2503fc2a44b5053b0837ebea6e87a2d339a43 GIT binary patch literal 6849 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 +
+

{{ msg }}

+

Essential Links

+ +

Ecosystem

+ +
+ + + + + + diff --git a/extensions/dataease-extensions-datasource/mongo/mongo-frontend/src/de-base/lang/en.js b/extensions/dataease-extensions-datasource/mongo/mongo-frontend/src/de-base/lang/en.js new file mode 100644 index 0000000000..f1dae13210 --- /dev/null +++ b/extensions/dataease-extensions-datasource/mongo/mongo-frontend/src/de-base/lang/en.js @@ -0,0 +1,23 @@ +export default { + plugin_view_3d_pie: { + type_title: '3D-PIE', + label: 'Label', + angle: 'Angle' + }, + host: 'Host', + port: 'Port', + dataBase: 'Catalog', + schema: 'Schema', + username: 'User', + password: 'Password', + get_schema: 'Get Schema', + please_choose_schema: 'Please select Schema', + query_timeout: 'Query timeout (seconds)', + extra_params: 'Extra JDBC connection string', + second: 'second', + please_select: 'Please select', + query_timeout: 'query timeout', + enter_the_port: 'Please enter the port', + one_user_name: 'enter one user name', + input_a_password: 'Please input a password' +} diff --git a/extensions/dataease-extensions-datasource/mongo/mongo-frontend/src/de-base/lang/index.js b/extensions/dataease-extensions-datasource/mongo/mongo-frontend/src/de-base/lang/index.js new file mode 100644 index 0000000000..e50d0478e6 --- /dev/null +++ b/extensions/dataease-extensions-datasource/mongo/mongo-frontend/src/de-base/lang/index.js @@ -0,0 +1,49 @@ +import Vue from 'vue' +import VueI18n from 'vue-i18n' +import Cookies from 'js-cookie' +import elementEnLocale from 'element-ui/lib/locale/lang/en' // element-ui lang +import elementZhLocale from 'element-ui/lib/locale/lang/zh-CN'// element-ui lang +import elementTWLocale from 'element-ui/lib/locale/lang/zh-TW'// element-ui lang + +import localMessages from './messages' + + +Vue.use(VueI18n) + +const messages = { + en_US: { + ...localMessages['en_US'], + ...elementEnLocale + }, + zh_CN: { + ...localMessages['zh_CN'], + ...elementZhLocale + }, + zh_TW: { + ...localMessages['zh_TW'], + ...elementTWLocale + } +} +export function getLanguage () { + const chooseLanguage = Cookies.get('language') + if (chooseLanguage) return chooseLanguage + + // if has not choose language + const language = (navigator.language || navigator.browserLanguage).toLowerCase() + const locales = Object.keys(messages) + for (const locale of locales) { + if (language.indexOf(locale) > -1) { + return locale + } + } + return 'zh_CN' +} +const i18n = new VueI18n({ + // set locale + // options: en | zh | es + locale: getLanguage(), + // set locale messages + messages +}) + +export default i18n diff --git a/extensions/dataease-extensions-datasource/mongo/mongo-frontend/src/de-base/lang/messages.js b/extensions/dataease-extensions-datasource/mongo/mongo-frontend/src/de-base/lang/messages.js new file mode 100644 index 0000000000..844f8c0673 --- /dev/null +++ b/extensions/dataease-extensions-datasource/mongo/mongo-frontend/src/de-base/lang/messages.js @@ -0,0 +1,17 @@ +import enLocale from './en' +import zhLocale from './zh' +import twLocale from './tw' + +const messages = { + en_US: { + ...enLocale + }, + zh_CN: { + ...zhLocale + }, + zh_TW: { + ...twLocale + } +} + +export default messages \ No newline at end of file diff --git a/extensions/dataease-extensions-datasource/mongo/mongo-frontend/src/de-base/lang/tw.js b/extensions/dataease-extensions-datasource/mongo/mongo-frontend/src/de-base/lang/tw.js new file mode 100644 index 0000000000..a64099c861 --- /dev/null +++ b/extensions/dataease-extensions-datasource/mongo/mongo-frontend/src/de-base/lang/tw.js @@ -0,0 +1,23 @@ +export default { + plugin_view_3d_pie: { + type_title: '3D餅圖', + label: '標籤', + angle: '角度' + }, + host: '主機名', + port: '端口', + dataBase: '數據庫', + schema: 'Schema', + username: '用戶名', + password: '密碼', + get_schema: '获取 Schema', + please_choose_schema: '请选择 Schema', + query_timeout: '査詢超時(秒)', + extra_params: '額外的JDBC連接字符串', + second: '秒', + please_select: '請選擇', + query_timeout: '査詢超時', + enter_the_port: '請輸入埠', + one_user_name: '請輸入用戶名', + input_a_password: '請輸入密碼' +} diff --git a/extensions/dataease-extensions-datasource/mongo/mongo-frontend/src/de-base/lang/zh.js b/extensions/dataease-extensions-datasource/mongo/mongo-frontend/src/de-base/lang/zh.js new file mode 100644 index 0000000000..678ec2d364 --- /dev/null +++ b/extensions/dataease-extensions-datasource/mongo/mongo-frontend/src/de-base/lang/zh.js @@ -0,0 +1,23 @@ +export default { + plugin_view_3d_pie: { + type_title: '3D饼图', + label: '标签', + angle: '角度' + }, + host: '主机名', + port: '端口', + dataBase: '数据库', + schema: 'Schema', + username: '用户名', + password: '密码', + get_schema: '获取 Schema', + please_choose_schema: '请选择 Schema', + query_timeout: '查询超时(秒)', + extra_params: '额外的JDBC连接字符串', + second: '秒', + please_select: '请选择', + query_timeout: '查询超时', + enter_the_port: '请输入端口', + one_user_name: '请输入用户名', + input_a_password: '请输入密码' +} diff --git a/extensions/dataease-extensions-datasource/mongo/mongo-frontend/src/icons/index.js b/extensions/dataease-extensions-datasource/mongo/mongo-frontend/src/icons/index.js new file mode 100644 index 0000000000..2c6b309c96 --- /dev/null +++ b/extensions/dataease-extensions-datasource/mongo/mongo-frontend/src/icons/index.js @@ -0,0 +1,9 @@ +import Vue from 'vue' +import SvgIcon from '@/components/SvgIcon'// svg component + +// register globally +Vue.component('svg-icon', SvgIcon) + +const req = require.context('./svg', false, /\.svg$/) +const requireAll = requireContext => requireContext.keys().map(requireContext) +requireAll(req) diff --git a/extensions/dataease-extensions-datasource/mongo/mongo-frontend/src/icons/svg/mongo-backend.svg b/extensions/dataease-extensions-datasource/mongo/mongo-frontend/src/icons/svg/mongo-backend.svg new file mode 100644 index 0000000000..f61c4a1a00 --- /dev/null +++ b/extensions/dataease-extensions-datasource/mongo/mongo-frontend/src/icons/svg/mongo-backend.svg @@ -0,0 +1 @@ +【icon】插件管理-导出 diff --git a/extensions/dataease-extensions-datasource/mongo/mongo-frontend/src/icons/svg/mongobi.jpg b/extensions/dataease-extensions-datasource/mongo/mongo-frontend/src/icons/svg/mongobi.jpg new file mode 100644 index 0000000000000000000000000000000000000000..dfb14739d64d8de5916efb73a4c0b5237471d746 GIT binary patch literal 9124 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 literal 0 HcmV?d00001 diff --git a/extensions/dataease-extensions-datasource/mongo/mongo-frontend/src/icons/svgo.yml b/extensions/dataease-extensions-datasource/mongo/mongo-frontend/src/icons/svgo.yml new file mode 100644 index 0000000000..d11906aec2 --- /dev/null +++ b/extensions/dataease-extensions-datasource/mongo/mongo-frontend/src/icons/svgo.yml @@ -0,0 +1,22 @@ +# replace default config + +# multipass: true +# full: true + +plugins: + + # - name + # + # or: + # - name: false + # - name: true + # + # or: + # - name: + # param1: 1 + # param2: 2 + +- removeAttrs: + attrs: + - 'fill' + - 'fill-rule' diff --git a/extensions/dataease-extensions-datasource/mongo/mongo-frontend/src/main.js b/extensions/dataease-extensions-datasource/mongo/mongo-frontend/src/main.js new file mode 100644 index 0000000000..99c5626590 --- /dev/null +++ b/extensions/dataease-extensions-datasource/mongo/mongo-frontend/src/main.js @@ -0,0 +1,33 @@ +// The Vue build version to load with the `import` command +// (runtime-only or standalone) has been set in webpack.base.conf with an alias. +import Vue from 'vue' +import App from './App' +import router from './router' +import ElementUI from 'element-ui' +import Cookies from 'js-cookie' +import i18n from './de-base/lang' +import draggable from 'vuedraggable' +import Treeselect from '@riophae/vue-treeselect' +import '@riophae/vue-treeselect/dist/vue-treeselect.css' +Vue.config.productionTip = false +Vue.use(ElementUI, { + size: Cookies.get('size') || 'medium', + i18n: (key, value) => i18n.t(key, value) +}) +Vue.component('Treeselect', Treeselect) +Vue.component('draggable', draggable) +Vue.prototype.hasDataPermission = function(pTarget, pSource) { + + if (pSource && pTarget) { + return pSource.indexOf(pTarget) > -1 + } + return false +} +/* eslint-disable no-new */ +new Vue({ + el: '#app', + router, + i18n, + components: { App }, + template: '' +}) diff --git a/extensions/dataease-extensions-datasource/mongo/mongo-frontend/src/router/index.js b/extensions/dataease-extensions-datasource/mongo/mongo-frontend/src/router/index.js new file mode 100644 index 0000000000..b5b55fa1fc --- /dev/null +++ b/extensions/dataease-extensions-datasource/mongo/mongo-frontend/src/router/index.js @@ -0,0 +1,21 @@ +import Vue from 'vue' +import Router from 'vue-router' +import HelloWorld from '@/components/HelloWorld' +import maxcompute from '@/views/maxcompute' + +Vue.use(Router) + +export default new Router({ + routes: [ + { + path: '/', + name: 'HelloWorld', + component: HelloWorld + }, + { + path: '/maxcompute', + name: 'maxcompute', + component: maxcompute + } + ] +}) diff --git a/extensions/dataease-extensions-datasource/mongo/mongo-frontend/src/utils/compare.js b/extensions/dataease-extensions-datasource/mongo/mongo-frontend/src/utils/compare.js new file mode 100644 index 0000000000..b06a104a10 --- /dev/null +++ b/extensions/dataease-extensions-datasource/mongo/mongo-frontend/src/utils/compare.js @@ -0,0 +1,29 @@ +export const compareItem = { + type: 'none', // year-yoy/month-yoy等 + resultData: 'percent', // 对比差sub,百分比percent等 + field: '', + custom: { + field: '', + calcType: '0', // 0-增长值,1-增长率 + timeType: '0', // 0-固定日期,1-日期区间 + currentTime: '', + compareTime: '', + currentTimeRange: [], + compareTimeRange: [] + } +} + +export const compareYearList = [ + { name: 'year_mom', value: 'year_mom' } +] + +export const compareMonthList = [ + { name: 'month_mom', value: 'month_mom' }, + { name: 'year_yoy', value: 'year_yoy' } +] + +export const compareDayList = [ + { name: 'day_mom', value: 'day_mom' }, + { name: 'month_yoy', value: 'month_yoy' }, + { name: 'year_yoy', value: 'year_yoy' } +] diff --git a/extensions/dataease-extensions-datasource/mongo/mongo-frontend/src/utils/validate.js b/extensions/dataease-extensions-datasource/mongo/mongo-frontend/src/utils/validate.js new file mode 100644 index 0000000000..3e8ffa9448 --- /dev/null +++ b/extensions/dataease-extensions-datasource/mongo/mongo-frontend/src/utils/validate.js @@ -0,0 +1,15 @@ +/** + * Created by PanJiaChen on 16/11/18. + */ + +/** + * @param {string} path + * @returns {Boolean} + */ +export function isExternal(path) { + return /^(https?:|mailto:|tel:)/.test(path) || /^(http?:|mailto:|tel:)/.test(path) || path.startsWith('/api/pluginCommon/staticInfo') +} + + + + diff --git a/extensions/dataease-extensions-datasource/mongo/mongo-frontend/src/views/dePwd.vue b/extensions/dataease-extensions-datasource/mongo/mongo-frontend/src/views/dePwd.vue new file mode 100644 index 0000000000..61bf3e88ee --- /dev/null +++ b/extensions/dataease-extensions-datasource/mongo/mongo-frontend/src/views/dePwd.vue @@ -0,0 +1,75 @@ + + + + \ No newline at end of file diff --git a/extensions/dataease-extensions-datasource/mongo/mongo-frontend/src/views/mongobi.vue b/extensions/dataease-extensions-datasource/mongo/mongo-frontend/src/views/mongobi.vue new file mode 100644 index 0000000000..831421428a --- /dev/null +++ b/extensions/dataease-extensions-datasource/mongo/mongo-frontend/src/views/mongobi.vue @@ -0,0 +1,177 @@ + + + + + diff --git a/extensions/dataease-extensions-datasource/mongo/plugin.json b/extensions/dataease-extensions-datasource/mongo/plugin.json new file mode 100644 index 0000000000..0bd1dc1bdc --- /dev/null +++ b/extensions/dataease-extensions-datasource/mongo/plugin.json @@ -0,0 +1,13 @@ +{ + "name":"Mongo 数据源插件", + "free":0, + "store":"default", + "cost":0, + "category":"datasource", + "descript":"Mongo 插件,值得拥有", + "version":"1.18.0", + "creator":"DATAEASE", + "moduleName":"mongo-backend", + "require":"1.12.0", + "dsType":"mongobi" +} diff --git a/extensions/dataease-extensions-datasource/mongo/pom.xml b/extensions/dataease-extensions-datasource/mongo/pom.xml new file mode 100644 index 0000000000..75541936ef --- /dev/null +++ b/extensions/dataease-extensions-datasource/mongo/pom.xml @@ -0,0 +1,19 @@ + + + + dataease-extensions-datasource + io.dataease + ${dataease.version} + + 4.0.0 + + mongo + pom + + mongo-frontend + mongo-backend + + + diff --git a/extensions/dataease-extensions-datasource/pom.xml b/extensions/dataease-extensions-datasource/pom.xml new file mode 100644 index 0000000000..07ba2430b0 --- /dev/null +++ b/extensions/dataease-extensions-datasource/pom.xml @@ -0,0 +1,24 @@ + + + + dataease-extensions + io.dataease + ${dataease.version} + + 4.0.0 + pom + + maxcompute + presto + dm + mongo + kylin + kingbase + + + dataease-extensions-datasource + + + diff --git a/extensions/dataease-extensions-datasource/presto/build.sh b/extensions/dataease-extensions-datasource/presto/build.sh new file mode 100755 index 0000000000..e6af1535ef --- /dev/null +++ b/extensions/dataease-extensions-datasource/presto/build.sh @@ -0,0 +1,6 @@ +#!/bin/sh +mvn clean package + +cp presto-backend/target/presto-backend-1.18.0.jar . + +zip -r presto.zip ./presto-backend-1.18.0.jar ./prestoDriver ./plugin.json diff --git a/extensions/dataease-extensions-datasource/presto/plugin.json b/extensions/dataease-extensions-datasource/presto/plugin.json new file mode 100644 index 0000000000..d823556ea1 --- /dev/null +++ b/extensions/dataease-extensions-datasource/presto/plugin.json @@ -0,0 +1,13 @@ +{ + "name":"Presto 数据源插件", + "free":0, + "store":"default", + "cost":0, + "category":"datasource", + "descript":"Presto 插件,值得拥有", + "version":"1.18.0", + "creator":"DATAEASE", + "moduleName":"presto-backend", + "require":"1.11.0", + "dsType":"presto" +} diff --git a/extensions/dataease-extensions-datasource/presto/pom.xml b/extensions/dataease-extensions-datasource/presto/pom.xml new file mode 100644 index 0000000000..0758a805b8 --- /dev/null +++ b/extensions/dataease-extensions-datasource/presto/pom.xml @@ -0,0 +1,19 @@ + + + + dataease-extensions-datasource + io.dataease + ${dataease.version} + + 4.0.0 + + presto + pom + + presto-frontend + presto-backend + + + diff --git a/extensions/dataease-extensions-datasource/presto/presto-backend/pom.xml b/extensions/dataease-extensions-datasource/presto/presto-backend/pom.xml new file mode 100644 index 0000000000..d1d3734857 --- /dev/null +++ b/extensions/dataease-extensions-datasource/presto/presto-backend/pom.xml @@ -0,0 +1,109 @@ + + + + presto + io.dataease + ${dataease.version} + + 4.0.0 + + presto-backend + + + + io.dataease + dataease-plugin-datasource + + + + + + + src/main/java + + **/*.properties + **/*.xml + + false + + + src/main/resources + + **/* + + false + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 11 + 11 + + + + + org.apache.maven.plugins + maven-jar-plugin + 2.4 + + + **/server/** + **/*.properties + **/Application* + + + + + + maven-clean-plugin + + + + src/main/resources/static + + ** + + false + + + + + + + + + org.apache.maven.plugins + maven-antrun-plugin + + + main-class-placement + generate-resources + + + + + + + + + + + + run + + + + + + + + + + + diff --git a/extensions/dataease-extensions-datasource/presto/presto-backend/src/main/java/io/dataease/plugins/datasource/dm/provider/PrestoConfig.java b/extensions/dataease-extensions-datasource/presto/presto-backend/src/main/java/io/dataease/plugins/datasource/dm/provider/PrestoConfig.java new file mode 100644 index 0000000000..4a4692174f --- /dev/null +++ b/extensions/dataease-extensions-datasource/presto/presto-backend/src/main/java/io/dataease/plugins/datasource/dm/provider/PrestoConfig.java @@ -0,0 +1,22 @@ +package io.dataease.plugins.datasource.dm.provider; + +import io.dataease.plugins.datasource.entity.JdbcConfiguration; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class PrestoConfig extends JdbcConfiguration { + + private String driver = "io.prestosql.jdbc.PrestoDriver"; + private String extraParams; + + + public String getJdbc() { + return "jdbc:presto://HOST:PORT/DATABASE/SCHEMA" + .replace("HOST", getHost().trim()) + .replace("PORT", getPort().toString()) + .replace("DATABASE", getDataBase().trim()) + .replace("SCHEMA", getSchema().trim()); + } +} diff --git a/extensions/dataease-extensions-datasource/presto/presto-backend/src/main/java/io/dataease/plugins/datasource/dm/provider/PrestoDsProvider.java b/extensions/dataease-extensions-datasource/presto/presto-backend/src/main/java/io/dataease/plugins/datasource/dm/provider/PrestoDsProvider.java new file mode 100644 index 0000000000..4277d77128 --- /dev/null +++ b/extensions/dataease-extensions-datasource/presto/presto-backend/src/main/java/io/dataease/plugins/datasource/dm/provider/PrestoDsProvider.java @@ -0,0 +1,154 @@ +package io.dataease.plugins.datasource.dm.provider; + +import com.google.gson.Gson; +import io.dataease.plugins.common.base.domain.DeDriver; +import io.dataease.plugins.common.base.mapper.DeDriverMapper; +import io.dataease.plugins.common.dto.datasource.TableDesc; +import io.dataease.plugins.common.dto.datasource.TableField; +import io.dataease.plugins.common.exception.DataEaseException; +import io.dataease.plugins.common.request.datasource.DatasourceRequest; +import io.dataease.plugins.datasource.entity.JdbcConfiguration; +import io.dataease.plugins.datasource.provider.DefaultJdbcProvider; +import io.dataease.plugins.datasource.provider.ExtendedJdbcClassLoader; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.lang.reflect.Method; +import java.sql.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; + + +@Component() +public class PrestoDsProvider extends DefaultJdbcProvider { + @Resource + private DeDriverMapper deDriverMapper; + + @Override + public String getType() { + return "presto"; + } + + @Override + public boolean isUseDatasourcePool() { + return false; + } + + @Override + public Connection getConnection(DatasourceRequest datasourceRequest) throws Exception { + PrestoConfig prestoConfig = new Gson().fromJson(datasourceRequest.getDatasource().getConfiguration(), PrestoConfig.class); + + String defaultDriver = prestoConfig.getDriver(); + String customDriver = prestoConfig.getCustomDriver(); + + String url = prestoConfig.getJdbc(); + Properties props = new Properties(); + DeDriver deDriver = null; + if(StringUtils.isNotEmpty(prestoConfig.getAuthMethod()) && prestoConfig.getAuthMethod().equalsIgnoreCase("kerberos")){ + System.setProperty("java.security.krb5.conf", "/opt/dataease/conf/krb5.conf"); + ExtendedJdbcClassLoader classLoader; + if(isDefaultClassLoader(customDriver)){ + classLoader = extendedJdbcClassLoader; + }else { + deDriver = deDriverMapper.selectByPrimaryKey(customDriver); + classLoader = getCustomJdbcClassLoader(deDriver); + } + Class ConfigurationClass = classLoader.loadClass("org.apache.hadoop.conf.Configuration"); + Method set = ConfigurationClass.getMethod("set",String.class, String.class) ; + Object obj = ConfigurationClass.newInstance(); + set.invoke(obj, "hadoop.security.authentication", "Kerberos"); + + Class UserGroupInformationClass = classLoader.loadClass("org.apache.hadoop.security.UserGroupInformation"); + Method setConfiguration = UserGroupInformationClass.getMethod("setConfiguration",ConfigurationClass) ; + Method loginUserFromKeytab = UserGroupInformationClass.getMethod("loginUserFromKeytab",String.class, String.class) ; + setConfiguration.invoke(null, obj); + loginUserFromKeytab.invoke(null, prestoConfig.getUsername(), "/opt/dataease/conf/" + prestoConfig.getPassword()); + }else { + if (StringUtils.isNotBlank(prestoConfig.getUsername())) { + props.setProperty("user", prestoConfig.getUsername()); + if (StringUtils.isNotBlank(prestoConfig.getPassword())) { + props.setProperty("password", prestoConfig.getPassword()); + } + } + } + + Connection conn; + String driverClassName ; + ExtendedJdbcClassLoader jdbcClassLoader; + if(isDefaultClassLoader(customDriver)){ + driverClassName = defaultDriver; + jdbcClassLoader = extendedJdbcClassLoader; + }else { + if(deDriver == null){ + deDriver = deDriverMapper.selectByPrimaryKey(customDriver); + } + driverClassName = deDriver.getDriverClass(); + jdbcClassLoader = getCustomJdbcClassLoader(deDriver); + } + + Driver driverClass = (Driver) jdbcClassLoader.loadClass(driverClassName).newInstance(); + ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + try { + Thread.currentThread().setContextClassLoader(jdbcClassLoader); + conn= driverClass.connect(url, props); + }catch (Exception e){ + e.printStackTrace(); + throw e; + }finally { + Thread.currentThread().setContextClassLoader(classLoader); + } + return conn; + } + + @Override + public List getTables(DatasourceRequest datasourceRequest) throws Exception { + List tables = new ArrayList<>(); + String queryStr = getTablesSql(datasourceRequest); + JdbcConfiguration jdbcConfiguration = new Gson().fromJson(datasourceRequest.getDatasource().getConfiguration(), JdbcConfiguration.class); + int queryTimeout = jdbcConfiguration.getQueryTimeout() > 0 ? jdbcConfiguration.getQueryTimeout() : 0; + try (Connection con = getConnectionFromPool(datasourceRequest); Statement statement = getStatement(con, queryTimeout); ResultSet resultSet = statement.executeQuery(queryStr)) { + while (resultSet.next()) { + tables.add(getTableDesc(datasourceRequest, resultSet)); + } + } catch (Exception e) { + DataEaseException.throwException(e); + } + + return tables; + } + + private TableDesc getTableDesc(DatasourceRequest datasourceRequest, ResultSet resultSet) throws SQLException { + TableDesc tableDesc = new TableDesc(); + tableDesc.setName(resultSet.getString(1)); + return tableDesc; + } + + @Override + public List getTableFields(DatasourceRequest datasourceRequest) throws Exception { + datasourceRequest.setQuery("select * from " + datasourceRequest.getTable() + " limit 0"); + return fetchResultField(datasourceRequest); + } + + @Override + public String checkStatus(DatasourceRequest datasourceRequest) throws Exception { + String queryStr = getTablesSql(datasourceRequest); + JdbcConfiguration jdbcConfiguration = new Gson().fromJson(datasourceRequest.getDatasource().getConfiguration(), JdbcConfiguration.class); + int queryTimeout = jdbcConfiguration.getQueryTimeout() > 0 ? jdbcConfiguration.getQueryTimeout() : 0; + try (Connection con = getConnection(datasourceRequest); Statement statement = getStatement(con, queryTimeout); ResultSet resultSet = statement.executeQuery(queryStr)) { + } catch (Exception e) { + e.printStackTrace(); + DataEaseException.throwException(e.getMessage()); + } + return "Success"; + } + + + @Override + public String getTablesSql(DatasourceRequest datasourceRequest) throws Exception { + PrestoConfig prestoConfig = new Gson().fromJson(datasourceRequest.getDatasource().getConfiguration(), PrestoConfig.class); + return "show tables in " + prestoConfig.getDataBase() + "." + prestoConfig.getSchema(); + } + +} diff --git a/extensions/dataease-extensions-datasource/presto/presto-backend/src/main/java/io/dataease/plugins/datasource/dm/query/PrestoConstants.java b/extensions/dataease-extensions-datasource/presto/presto-backend/src/main/java/io/dataease/plugins/datasource/dm/query/PrestoConstants.java new file mode 100644 index 0000000000..a71916ecfb --- /dev/null +++ b/extensions/dataease-extensions-datasource/presto/presto-backend/src/main/java/io/dataease/plugins/datasource/dm/query/PrestoConstants.java @@ -0,0 +1,45 @@ +package io.dataease.plugins.datasource.dm.query; + + + +import io.dataease.plugins.common.constants.datasource.SQLConstants; + + +public class PrestoConstants extends SQLConstants { + + public static final String KEYWORD_TABLE = "%s" ; + + public static final String KEYWORD_FIX = "%s." + "%s"; + + public static final String UNIX_TIMESTAMP = "to_unixtime(%s)"; + + public static final String FROM_UNIXTIME = "from_unixtime(%s)"; + + public static final String CAST = "CAST(%s AS %s)"; + + public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss"; + + public static final String FORMAT_DATETIME = "format_datetime(%s, '%s')"; + + public static final String date_parse = "date_parse(%s, '%s')"; + + public static final String DEFAULT_INT_FORMAT = "bigint"; + + public static final String DEFAULT_FLOAT_FORMAT = "DOUBLE"; + + public static final String WHERE_VALUE_NULL = "(NULL,'')"; + + public static final String WHERE_VALUE_VALUE = "'%s'"; + + public static final String AGG_COUNT = "COUNT(*)"; + + public static final String AGG_FIELD = "%s(%s)"; + + public static final String WHERE_BETWEEN = "'%s' AND '%s'"; + + public static final String BRACKETS = "(%s)"; + + public static final String NAME = "pg"; + + +} diff --git a/extensions/dataease-extensions-datasource/presto/presto-backend/src/main/java/io/dataease/plugins/datasource/dm/query/PrestoQueryProvider.java b/extensions/dataease-extensions-datasource/presto/presto-backend/src/main/java/io/dataease/plugins/datasource/dm/query/PrestoQueryProvider.java new file mode 100644 index 0000000000..c2ec9926d6 --- /dev/null +++ b/extensions/dataease-extensions-datasource/presto/presto-backend/src/main/java/io/dataease/plugins/datasource/dm/query/PrestoQueryProvider.java @@ -0,0 +1,1287 @@ +package io.dataease.plugins.datasource.dm.query; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.gson.Gson; +import io.dataease.plugins.common.base.domain.ChartViewWithBLOBs; +import io.dataease.plugins.common.base.domain.DatasetTableField; +import io.dataease.plugins.common.base.domain.DatasetTableFieldExample; +import io.dataease.plugins.common.base.domain.Datasource; +import io.dataease.plugins.common.base.mapper.DatasetTableFieldMapper; +import io.dataease.plugins.common.constants.DeTypeConstants; +import io.dataease.plugins.common.constants.datasource.SQLConstants; +import io.dataease.plugins.common.constants.datasource.SqlServerSQLConstants; +import io.dataease.plugins.common.dto.chart.ChartCustomFilterItemDTO; +import io.dataease.plugins.common.dto.chart.ChartFieldCustomFilterDTO; +import io.dataease.plugins.common.dto.chart.ChartViewFieldDTO; +import io.dataease.plugins.common.dto.datasource.DeSortField; +import io.dataease.plugins.common.dto.sqlObj.SQLObj; +import io.dataease.plugins.common.request.chart.ChartExtFilterRequest; +import io.dataease.plugins.common.request.permission.DataSetRowPermissionsTreeDTO; +import io.dataease.plugins.common.request.permission.DatasetRowPermissionsTreeItem; +import io.dataease.plugins.datasource.dm.provider.PrestoConfig; +import io.dataease.plugins.datasource.entity.Dateformat; +import io.dataease.plugins.datasource.entity.JdbcConfiguration; +import io.dataease.plugins.datasource.entity.PageInfo; +import io.dataease.plugins.datasource.query.QueryProvider; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.ObjectUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Component; +import org.stringtemplate.v4.ST; +import org.stringtemplate.v4.STGroup; +import org.stringtemplate.v4.STGroupFile; + +import javax.annotation.Resource; +import java.text.MessageFormat; +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +import static io.dataease.plugins.common.constants.datasource.SQLConstants.TABLE_ALIAS_PREFIX; + + +@Component() +public class PrestoQueryProvider extends QueryProvider { + @Resource + private DatasetTableFieldMapper datasetTableFieldMapper; + + private static final Gson json = new Gson(); + + @Override + public Integer transFieldType(String field) { + field = field.contains("(") ? field.split("\\(")[0] : field; + field = field.toUpperCase(); + switch (field) { + case "DATE": + case "DATETIME": + case "TIMESTAMP": + case "TIME": + return DeTypeConstants.DE_TIME;// 时间 + case "TINYINT": + case "SMALLINT": + case "INT": + case "BIGINT": + case "INTEGER": + return DeTypeConstants.DE_INT;// 整型 + case "FLOAT": + case "DOUBLE": + case "DECIMAL": + return DeTypeConstants.DE_FLOAT;// 浮点 + case "BOOLEAN": + return DeTypeConstants.DE_BOOL;// 布尔 + case "BINARY": + return DeTypeConstants.DE_BINARY;// 二进制 + default: + return DeTypeConstants.DE_STRING; + } + } + + @Override + public String createSQLPreview(String sql, String orderBy) { + return "SELECT * FROM (" + sqlFix(sql) + ") AS DE_TMP " + " LIMIT 1000"; + } + + @Override + public String createQuerySQL(String table, List fields, boolean isGroup, Datasource ds, List fieldCustomFilter, List rowPermissionsTree) { + return createQuerySQL(table, fields, isGroup, ds, fieldCustomFilter, rowPermissionsTree, null); + } + + @Override + public String createQuerySQL(String table, List fields, boolean isGroup, Datasource ds, List fieldCustomFilter, List rowPermissionsTree, List sortFields) { + SQLObj tableObj = SQLObj.builder() + .tableName((table.startsWith("(") && table.endsWith(")")) ? table : String.format(PrestoConstants.KEYWORD_TABLE, table)) + .tableAlias(String.format(TABLE_ALIAS_PREFIX, 0)) + .build(); + + setSchema(tableObj, ds); + List xFields = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(fields)) { + for (int i = 0; i < fields.size(); i++) { + DatasetTableField f = fields.get(i); + String originField; + if (ObjectUtils.isNotEmpty(f.getExtField()) && f.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originField = calcFieldRegex(f.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(f.getExtField()) && f.getExtField() == 1) { + originField = String.format(PrestoConstants.KEYWORD_FIX, tableObj.getTableAlias(), f.getOriginName()); + } else { + originField = String.format(PrestoConstants.KEYWORD_FIX, tableObj.getTableAlias(), f.getOriginName()); + } + String fieldAlias = String.format(SQLConstants.FIELD_ALIAS_X_PREFIX, i); + String fieldName = ""; + // 处理横轴字段 + if (f.getDeExtractType() == DeTypeConstants.DE_TIME) { + if (f.getDeType() == DeTypeConstants.DE_INT || f.getDeType() == DeTypeConstants.DE_FLOAT) { + fieldName = String.format(PrestoConstants.UNIX_TIMESTAMP, originField); + } else { + fieldName = originField; + } + } else if (f.getDeExtractType() == DeTypeConstants.DE_STRING) { + if (f.getDeType() == DeTypeConstants.DE_INT) { + fieldName = String.format(PrestoConstants.CAST, originField, PrestoConstants.DEFAULT_INT_FORMAT); + } else if (f.getDeType() == DeTypeConstants.DE_FLOAT) { + fieldName = String.format(PrestoConstants.CAST, originField, PrestoConstants.DEFAULT_FLOAT_FORMAT); + } else if (f.getDeType() == DeTypeConstants.DE_TIME) { + fieldName = String.format(PrestoConstants.date_parse, originField, StringUtils.isNotEmpty(f.getDateFormat()) ? f.getDateFormat() : PrestoConstants.DEFAULT_DATE_FORMAT); + } else { + fieldName = originField; + } + } else { + if (f.getDeType() == DeTypeConstants.DE_TIME) { + fieldName = String.format(PrestoConstants.FORMAT_DATETIME, String.format(PrestoConstants.FROM_UNIXTIME, originField + "/1000"), PrestoConstants.DEFAULT_DATE_FORMAT); + } else if (f.getDeType() == DeTypeConstants.DE_INT) { + fieldName = String.format(PrestoConstants.CAST, originField, PrestoConstants.DEFAULT_INT_FORMAT); + } else { + fieldName = originField; + } + } + xFields.add(SQLObj.builder() + .fieldName(fieldName) + .fieldAlias(fieldAlias) + .build()); + } + } + + STGroup stg = new STGroupFile(SQLConstants.SQL_TEMPLATE); + ST st_sql = stg.getInstanceOf("previewSql"); + st_sql.add("isGroup", isGroup); + if (CollectionUtils.isNotEmpty(xFields)) st_sql.add("groups", xFields); + if (ObjectUtils.isNotEmpty(tableObj)) st_sql.add("table", tableObj); + String customWheres = transCustomFilterList(tableObj, fieldCustomFilter); + // row permissions tree + String whereTrees = transFilterTrees(tableObj, rowPermissionsTree); + List wheres = new ArrayList<>(); + if (customWheres != null) wheres.add(customWheres); + if (whereTrees != null) wheres.add(whereTrees); + if (CollectionUtils.isNotEmpty(wheres)) st_sql.add("filters", wheres); + + List xOrders = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(sortFields)) { + int step = fields.size(); + for (int i = step; i < (step + sortFields.size()); i++) { + DeSortField deSortField = sortFields.get(i - step); + SQLObj order = buildSortField(deSortField, tableObj, i); + xOrders.add(order); + } + } + if (ObjectUtils.isNotEmpty(xOrders)) { + st_sql.add("orders", xOrders); + } + + return st_sql.render(); + } + + private SQLObj buildSortField(DeSortField f, SQLObj tableObj, int i) { + String originField; + if (ObjectUtils.isNotEmpty(f.getExtField()) && f.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originField = calcFieldRegex(f.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(f.getExtField()) && f.getExtField() == 1) { + originField = String.format(PrestoConstants.KEYWORD_FIX, tableObj.getTableAlias(), f.getOriginName()); + } else { + originField = String.format(PrestoConstants.KEYWORD_FIX, tableObj.getTableAlias(), f.getOriginName()); + } + String fieldAlias = String.format(SQLConstants.FIELD_ALIAS_X_PREFIX, i); + String fieldName = ""; + // 处理横轴字段 + if (f.getDeExtractType() == DeTypeConstants.DE_TIME) { + if (f.getDeType() == DeTypeConstants.DE_INT || f.getDeType() == DeTypeConstants.DE_FLOAT) { + fieldName = String.format(PrestoConstants.UNIX_TIMESTAMP, originField); + } else { + fieldName = originField; + } + } else if (f.getDeExtractType() == DeTypeConstants.DE_STRING) { + if (f.getDeType() == DeTypeConstants.DE_INT) { + fieldName = String.format(PrestoConstants.CAST, originField, PrestoConstants.DEFAULT_INT_FORMAT); + } else if (f.getDeType() == DeTypeConstants.DE_FLOAT) { + fieldName = String.format(PrestoConstants.CAST, originField, PrestoConstants.DEFAULT_FLOAT_FORMAT); + } else if (f.getDeType() == DeTypeConstants.DE_TIME) { + fieldName = String.format(PrestoConstants.date_parse, originField, StringUtils.isNotEmpty(f.getDateFormat()) ? f.getDateFormat() : PrestoConstants.DEFAULT_DATE_FORMAT); + } else { + fieldName = originField; + } + } else { + if (f.getDeType() == DeTypeConstants.DE_TIME) { + fieldName = String.format(PrestoConstants.FORMAT_DATETIME, String.format(PrestoConstants.FROM_UNIXTIME, originField + "/1000"), PrestoConstants.DEFAULT_DATE_FORMAT); + } else if (f.getDeType() == DeTypeConstants.DE_INT) { + fieldName = String.format(PrestoConstants.CAST, originField, PrestoConstants.DEFAULT_INT_FORMAT); + } else { + fieldName = originField; + } + } + SQLObj result = SQLObj.builder().orderField(originField).orderAlias(originField).orderDirection(f.getOrderDirection()).build(); + return result; + } + + @Override + public String createQuerySQLAsTmp(String sql, List fields, boolean isGroup, List fieldCustomFilter, List rowPermissionsTree, List sortFields) { + return createQuerySQL("(" + sqlFix(sql) + ")", fields, isGroup, null, fieldCustomFilter, rowPermissionsTree, sortFields); + } + + @Override + public String createQuerySQLAsTmp(String sql, List fields, boolean isGroup, List fieldCustomFilter, List rowPermissionsTree) { + return createQuerySQL("(" + sqlFix(sql) + ")", fields, isGroup, null, fieldCustomFilter, rowPermissionsTree); + } + + @Override + public String createQueryTableWithPage(String table, List fields, Integer page, Integer pageSize, Integer realSize, boolean isGroup, Datasource ds, List fieldCustomFilter, List rowPermissionsTree) { + return createQuerySQL(table, fields, isGroup, ds, fieldCustomFilter, rowPermissionsTree) + " LIMIT " + realSize; + } + + @Override + public String createQuerySQLWithPage(String sql, List fields, Integer page, Integer pageSize, Integer realSize, boolean isGroup, List fieldCustomFilter, List rowPermissionsTree) { + return createQuerySQLAsTmp(sql, fields, isGroup, fieldCustomFilter, rowPermissionsTree) + " LIMIT " + realSize; + } + + @Override + public String createQueryTableWithLimit(String table, List fields, Integer limit, boolean isGroup, Datasource ds, List fieldCustomFilter, List rowPermissionsTree) { + return createQuerySQL(table, fields, isGroup, ds, fieldCustomFilter, rowPermissionsTree) + " LIMIT " + limit; + } + + @Override + public String createQuerySqlWithLimit(String sql, List fields, Integer limit, boolean isGroup, List fieldCustomFilter, List rowPermissionsTree) { + return createQuerySQLAsTmp(sql, fields, isGroup, fieldCustomFilter, rowPermissionsTree) + " LIMIT " + limit; + } + + @Override + public String getSQL(String table, List xAxis, List yAxis, List fieldCustomFilter, List rowPermissionsTree, List extFilterRequestList, Datasource ds, ChartViewWithBLOBs view) { + SQLObj tableObj = SQLObj.builder() + .tableName((table.startsWith("(") && table.endsWith(")")) ? table : String.format(PrestoConstants.KEYWORD_TABLE, table)) + .tableAlias(String.format(TABLE_ALIAS_PREFIX, 0)) + .build(); + setSchema(tableObj, ds); + List xFields = new ArrayList<>(); + List xOrders = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(xAxis)) { + for (int i = 0; i < xAxis.size(); i++) { + ChartViewFieldDTO x = xAxis.get(i); + String originField; + if (ObjectUtils.isNotEmpty(x.getExtField()) && x.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originField = calcFieldRegex(x.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(x.getExtField()) && x.getExtField() == 1) { + originField = String.format(PrestoConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getOriginName()); + } else { + originField = String.format(PrestoConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getOriginName()); + } + String fieldAlias = String.format(SQLConstants.FIELD_ALIAS_X_PREFIX, i); + // 处理横轴字段 + xFields.add(getXFields(x, originField, fieldAlias)); + // 处理横轴排序 + if (StringUtils.isNotEmpty(x.getSort()) && !StringUtils.equalsIgnoreCase(x.getSort(), "none")) { + xOrders.add(SQLObj.builder() + .orderField(originField) + .orderAlias(fieldAlias) + .orderDirection(x.getSort()) + .build()); + } + } + } + List yFields = new ArrayList<>(); + List yWheres = new ArrayList<>(); + List yOrders = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(yAxis)) { + for (int i = 0; i < yAxis.size(); i++) { + ChartViewFieldDTO y = yAxis.get(i); + String originField; + if (ObjectUtils.isNotEmpty(y.getExtField()) && y.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originField = calcFieldRegex(y.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(y.getExtField()) && y.getExtField() == 1) { + originField = String.format(PrestoConstants.KEYWORD_FIX, tableObj.getTableAlias(), y.getOriginName()); + } else { + originField = String.format(PrestoConstants.KEYWORD_FIX, tableObj.getTableAlias(), y.getOriginName()); + } + String fieldAlias = String.format(SQLConstants.FIELD_ALIAS_Y_PREFIX, i); + // 处理纵轴字段 + yFields.add(getYFields(y, originField, fieldAlias)); + // 处理纵轴过滤 + yWheres.add(getYWheres(y, originField, fieldAlias)); + // 处理纵轴排序 + if (StringUtils.isNotEmpty(y.getSort()) && !StringUtils.equalsIgnoreCase(y.getSort(), "none")) { + yOrders.add(SQLObj.builder() + .orderField(originField) + .orderAlias(fieldAlias) + .orderDirection(y.getSort()) + .build()); + } + } + } + // 处理视图中字段过滤 + String customWheres = transCustomFilterList(tableObj, fieldCustomFilter); + // 处理仪表板字段过滤 + String extWheres = transExtFilterList(tableObj, extFilterRequestList); + // row permissions tree + String whereTrees = transFilterTrees(tableObj, rowPermissionsTree); + // 构建sql所有参数 + List fields = new ArrayList<>(); + fields.addAll(xFields); + fields.addAll(yFields); + List wheres = new ArrayList<>(); + if (customWheres != null) wheres.add(customWheres); + if (extWheres != null) wheres.add(extWheres); + if (whereTrees != null) wheres.add(whereTrees); + List groups = new ArrayList<>(); + groups.addAll(xFields); + // 外层再次套sql + List orders = new ArrayList<>(); + orders.addAll(xOrders); + orders.addAll(yOrders); + List aggWheres = new ArrayList<>(); + aggWheres.addAll(yWheres.stream().filter(ObjectUtils::isNotEmpty).collect(Collectors.toList())); + + STGroup stg = new STGroupFile(SQLConstants.SQL_TEMPLATE); + ST st_sql = stg.getInstanceOf("querySql"); + if (CollectionUtils.isNotEmpty(xFields)) st_sql.add("groups", xFields); + if (CollectionUtils.isNotEmpty(yFields)) st_sql.add("aggregators", yFields); + if (CollectionUtils.isNotEmpty(wheres)) st_sql.add("filters", wheres); + if (ObjectUtils.isNotEmpty(tableObj)) st_sql.add("table", tableObj); + String sql = st_sql.render(); + + ST st = stg.getInstanceOf("querySql"); + SQLObj tableSQL = SQLObj.builder() + .tableName(String.format(PrestoConstants.BRACKETS, sql)) + .tableAlias(String.format(TABLE_ALIAS_PREFIX, 1)) + .build(); + if (CollectionUtils.isNotEmpty(aggWheres)) st.add("filters", aggWheres); + if (CollectionUtils.isNotEmpty(orders)) st.add("orders", orders); + if (ObjectUtils.isNotEmpty(tableSQL)) st.add("table", tableSQL); + return sqlLimit(st.render(), view); + } + + + private String originalTableInfo(String table, List xAxis, List fieldCustomFilter, List rowPermissionsTree, List extFilterRequestList, Datasource ds, ChartViewWithBLOBs view) { + SQLObj tableObj = SQLObj.builder() + .tableName((table.startsWith("(") && table.endsWith(")")) ? table : String.format(PrestoConstants.KEYWORD_TABLE, table)) + .tableAlias(String.format(TABLE_ALIAS_PREFIX, 0)) + .build(); + setSchema(tableObj, ds); + List xFields = new ArrayList<>(); + List xOrders = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(xAxis)) { + for (int i = 0; i < xAxis.size(); i++) { + ChartViewFieldDTO x = xAxis.get(i); + String originField; + if (ObjectUtils.isNotEmpty(x.getExtField()) && x.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originField = calcFieldRegex(x.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(x.getExtField()) && x.getExtField() == 1) { + originField = String.format(PrestoConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getOriginName()); + } else { + if (x.getDeType() == 2 || x.getDeType() == 3) { + originField = String.format(PrestoConstants.CAST, String.format(PrestoConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getOriginName()), PrestoConstants.DEFAULT_FLOAT_FORMAT); + } else { + originField = String.format(PrestoConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getOriginName()); + } + } + String fieldAlias = String.format(SQLConstants.FIELD_ALIAS_X_PREFIX, i); + // 处理横轴字段 + xFields.add(getXFields(x, originField, fieldAlias)); + // 处理横轴排序 + if (StringUtils.isNotEmpty(x.getSort()) && !StringUtils.equalsIgnoreCase(x.getSort(), "none")) { + xOrders.add(SQLObj.builder() + .orderField(originField) + .orderAlias(fieldAlias) + .orderDirection(x.getSort()) + .build()); + } + } + } + // 处理视图中字段过滤 + String customWheres = transCustomFilterList(tableObj, fieldCustomFilter); + // 处理仪表板字段过滤 + String extWheres = transExtFilterList(tableObj, extFilterRequestList); + // row permissions tree + String whereTrees = transFilterTrees(tableObj, rowPermissionsTree); + // 构建sql所有参数 + List fields = new ArrayList<>(); + fields.addAll(xFields); + List wheres = new ArrayList<>(); + if (customWheres != null) wheres.add(customWheres); + if (extWheres != null) wheres.add(extWheres); + if (whereTrees != null) wheres.add(whereTrees); + List groups = new ArrayList<>(); + groups.addAll(xFields); + // 外层再次套sql + List orders = new ArrayList<>(); + orders.addAll(xOrders); + + STGroup stg = new STGroupFile(SQLConstants.SQL_TEMPLATE); + ST st_sql = stg.getInstanceOf("previewSql"); + st_sql.add("isGroup", false); + if (CollectionUtils.isNotEmpty(xFields)) st_sql.add("groups", xFields); + if (CollectionUtils.isNotEmpty(wheres)) st_sql.add("filters", wheres); + if (ObjectUtils.isNotEmpty(tableObj)) st_sql.add("table", tableObj); + String sql = st_sql.render(); + + ST st = stg.getInstanceOf("previewSql"); + st.add("isGroup", false); + SQLObj tableSQL = SQLObj.builder() + .tableName(String.format(PrestoConstants.BRACKETS, sql)) + .tableAlias(String.format(TABLE_ALIAS_PREFIX, 1)) + .build(); + if (CollectionUtils.isNotEmpty(orders)) st.add("orders", orders); + if (ObjectUtils.isNotEmpty(tableSQL)) st.add("table", tableSQL); + return st.render(); + } + + @Override + public String getSQLTableInfo(String table, List xAxis, List fieldCustomFilter, List rowPermissionsTree, List extFilterRequestList, Datasource ds, ChartViewWithBLOBs view) { + return sqlLimit(originalTableInfo(table, xAxis, fieldCustomFilter, rowPermissionsTree, extFilterRequestList, ds, view), view); + } + + @Override + public String getSQLAsTmpTableInfo(String sql, List xAxis, List fieldCustomFilter, List rowPermissionsTree, List extFilterRequestList, Datasource ds, ChartViewWithBLOBs view) { + return getSQLTableInfo("(" + sqlFix(sql) + ")", xAxis, fieldCustomFilter, rowPermissionsTree, extFilterRequestList, ds, view); + } + + + @Override + public String getSQLAsTmp(String sql, List xAxis, List yAxis, List fieldCustomFilter, List rowPermissionsTree, List extFilterRequestList, ChartViewWithBLOBs view) { + return getSQL("(" + sqlFix(sql) + ")", xAxis, yAxis, fieldCustomFilter, rowPermissionsTree, extFilterRequestList, null, view); + } + + @Override + public String getSQLStack(String table, List xAxis, List yAxis, List fieldCustomFilter, List rowPermissionsTree, List extFilterRequestList, List extStack, Datasource ds, ChartViewWithBLOBs view) { + SQLObj tableObj = SQLObj.builder() + .tableName((table.startsWith("(") && table.endsWith(")")) ? table : String.format(PrestoConstants.KEYWORD_TABLE, table)) + .tableAlias(String.format(TABLE_ALIAS_PREFIX, 0)) + .build(); + setSchema(tableObj, ds); + List xFields = new ArrayList<>(); + List xOrders = new ArrayList<>(); + List xList = new ArrayList<>(); + xList.addAll(xAxis); + xList.addAll(extStack); + if (CollectionUtils.isNotEmpty(xList)) { + for (int i = 0; i < xList.size(); i++) { + ChartViewFieldDTO x = xList.get(i); + String originField; + if (ObjectUtils.isNotEmpty(x.getExtField()) && x.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originField = calcFieldRegex(x.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(x.getExtField()) && x.getExtField() == 1) { + originField = String.format(PrestoConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getOriginName()); + } else { + originField = String.format(PrestoConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getOriginName()); + } + String fieldAlias = String.format(SQLConstants.FIELD_ALIAS_X_PREFIX, i); + // 处理横轴字段 + xFields.add(getXFields(x, originField, fieldAlias)); + // 处理横轴排序 + if (StringUtils.isNotEmpty(x.getSort()) && !StringUtils.equalsIgnoreCase(x.getSort(), "none")) { + xOrders.add(SQLObj.builder() + .orderField(originField) + .orderAlias(fieldAlias) + .orderDirection(x.getSort()) + .build()); + } + } + } + List yFields = new ArrayList<>(); + List yWheres = new ArrayList<>(); + List yOrders = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(yAxis)) { + for (int i = 0; i < yAxis.size(); i++) { + ChartViewFieldDTO y = yAxis.get(i); + String originField; + if (ObjectUtils.isNotEmpty(y.getExtField()) && y.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originField = calcFieldRegex(y.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(y.getExtField()) && y.getExtField() == 1) { + originField = String.format(PrestoConstants.KEYWORD_FIX, tableObj.getTableAlias(), y.getOriginName()); + } else { + originField = String.format(PrestoConstants.KEYWORD_FIX, tableObj.getTableAlias(), y.getOriginName()); + } + String fieldAlias = String.format(SQLConstants.FIELD_ALIAS_Y_PREFIX, i); + // 处理纵轴字段 + yFields.add(getYFields(y, originField, fieldAlias)); + // 处理纵轴过滤 + yWheres.add(getYWheres(y, originField, fieldAlias)); + // 处理纵轴排序 + if (StringUtils.isNotEmpty(y.getSort()) && !StringUtils.equalsIgnoreCase(y.getSort(), "none")) { + yOrders.add(SQLObj.builder() + .orderField(originField) + .orderAlias(fieldAlias) + .orderDirection(y.getSort()) + .build()); + } + } + } + // 处理视图中字段过滤 + String customWheres = transCustomFilterList(tableObj, fieldCustomFilter); + // 处理仪表板字段过滤 + String extWheres = transExtFilterList(tableObj, extFilterRequestList); + // row permissions tree + String whereTrees = transFilterTrees(tableObj, rowPermissionsTree); + // 构建sql所有参数 + List fields = new ArrayList<>(); + fields.addAll(xFields); + fields.addAll(yFields); + List wheres = new ArrayList<>(); + if (customWheres != null) wheres.add(customWheres); + if (extWheres != null) wheres.add(extWheres); + if (whereTrees != null) wheres.add(whereTrees); + List groups = new ArrayList<>(); + groups.addAll(xFields); + // 外层再次套sql + List orders = new ArrayList<>(); + orders.addAll(xOrders); + orders.addAll(yOrders); + List aggWheres = new ArrayList<>(); + aggWheres.addAll(yWheres.stream().filter(ObjectUtils::isNotEmpty).collect(Collectors.toList())); + + STGroup stg = new STGroupFile(SQLConstants.SQL_TEMPLATE); + ST st_sql = stg.getInstanceOf("querySql"); + if (CollectionUtils.isNotEmpty(xFields)) st_sql.add("groups", xFields); + if (CollectionUtils.isNotEmpty(yFields)) st_sql.add("aggregators", yFields); + if (CollectionUtils.isNotEmpty(wheres)) st_sql.add("filters", wheres); + if (ObjectUtils.isNotEmpty(tableObj)) st_sql.add("table", tableObj); + String sql = st_sql.render(); + + ST st = stg.getInstanceOf("querySql"); + SQLObj tableSQL = SQLObj.builder() + .tableName(String.format(PrestoConstants.BRACKETS, sql)) + .tableAlias(String.format(TABLE_ALIAS_PREFIX, 1)) + .build(); + if (CollectionUtils.isNotEmpty(aggWheres)) st.add("filters", aggWheres); + if (CollectionUtils.isNotEmpty(orders)) st.add("orders", orders); + if (ObjectUtils.isNotEmpty(tableSQL)) st.add("table", tableSQL); + return sqlLimit(st.render(), view); + } + + @Override + public String getSQLAsTmpStack(String table, List xAxis, List yAxis, List fieldCustomFilter, List rowPermissionsTree, List extFilterRequestList, List extStack, ChartViewWithBLOBs view) { + return getSQLStack("(" + sqlFix(table) + ")", xAxis, yAxis, fieldCustomFilter, rowPermissionsTree, extFilterRequestList, extStack, null, view); + } + + @Override + public String getSQLScatter(String table, List xAxis, List yAxis, List fieldCustomFilter, List rowPermissionsTree, List extFilterRequestList, List extBubble, Datasource ds, ChartViewWithBLOBs view) { + SQLObj tableObj = SQLObj.builder() + .tableName((table.startsWith("(") && table.endsWith(")")) ? table : String.format(PrestoConstants.KEYWORD_TABLE, table)) + .tableAlias(String.format(TABLE_ALIAS_PREFIX, 0)) + .build(); + setSchema(tableObj, ds); + List xFields = new ArrayList<>(); + List xOrders = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(xAxis)) { + for (int i = 0; i < xAxis.size(); i++) { + ChartViewFieldDTO x = xAxis.get(i); + String originField; + if (ObjectUtils.isNotEmpty(x.getExtField()) && x.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originField = calcFieldRegex(x.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(x.getExtField()) && x.getExtField() == 1) { + originField = String.format(PrestoConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getOriginName()); + } else { + originField = String.format(PrestoConstants.KEYWORD_FIX, tableObj.getTableAlias(), x.getOriginName()); + } + String fieldAlias = String.format(SQLConstants.FIELD_ALIAS_X_PREFIX, i); + // 处理横轴字段 + xFields.add(getXFields(x, originField, fieldAlias)); + // 处理横轴排序 + if (StringUtils.isNotEmpty(x.getSort()) && !StringUtils.equalsIgnoreCase(x.getSort(), "none")) { + xOrders.add(SQLObj.builder() + .orderField(originField) + .orderAlias(fieldAlias) + .orderDirection(x.getSort()) + .build()); + } + } + } + List yFields = new ArrayList<>(); + List yWheres = new ArrayList<>(); + List yOrders = new ArrayList<>(); + List yList = new ArrayList<>(); + yList.addAll(yAxis); + yList.addAll(extBubble); + if (CollectionUtils.isNotEmpty(yList)) { + for (int i = 0; i < yList.size(); i++) { + ChartViewFieldDTO y = yList.get(i); + String originField; + if (ObjectUtils.isNotEmpty(y.getExtField()) && y.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originField = calcFieldRegex(y.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(y.getExtField()) && y.getExtField() == 1) { + originField = String.format(PrestoConstants.KEYWORD_FIX, tableObj.getTableAlias(), y.getOriginName()); + } else { + originField = String.format(PrestoConstants.KEYWORD_FIX, tableObj.getTableAlias(), y.getOriginName()); + } + String fieldAlias = String.format(SQLConstants.FIELD_ALIAS_Y_PREFIX, i); + // 处理纵轴字段 + yFields.add(getYFields(y, originField, fieldAlias)); + // 处理纵轴过滤 + yWheres.add(getYWheres(y, originField, fieldAlias)); + // 处理纵轴排序 + if (StringUtils.isNotEmpty(y.getSort()) && !StringUtils.equalsIgnoreCase(y.getSort(), "none")) { + yOrders.add(SQLObj.builder() + .orderField(originField) + .orderAlias(fieldAlias) + .orderDirection(y.getSort()) + .build()); + } + } + } + // 处理视图中字段过滤 + String customWheres = transCustomFilterList(tableObj, fieldCustomFilter); + // 处理仪表板字段过滤 + String extWheres = transExtFilterList(tableObj, extFilterRequestList); + // row permissions tree + String whereTrees = transFilterTrees(tableObj, rowPermissionsTree); + // 构建sql所有参数 + List fields = new ArrayList<>(); + fields.addAll(xFields); + fields.addAll(yFields); + List wheres = new ArrayList<>(); + if (customWheres != null) wheres.add(customWheres); + if (extWheres != null) wheres.add(extWheres); + if (whereTrees != null) wheres.add(whereTrees); + List groups = new ArrayList<>(); + groups.addAll(xFields); + // 外层再次套sql + List orders = new ArrayList<>(); + orders.addAll(xOrders); + orders.addAll(yOrders); + List aggWheres = new ArrayList<>(); + aggWheres.addAll(yWheres.stream().filter(ObjectUtils::isNotEmpty).collect(Collectors.toList())); + + STGroup stg = new STGroupFile(SQLConstants.SQL_TEMPLATE); + ST st_sql = stg.getInstanceOf("querySql"); + if (CollectionUtils.isNotEmpty(xFields)) st_sql.add("groups", xFields); + if (CollectionUtils.isNotEmpty(yFields)) st_sql.add("aggregators", yFields); + if (CollectionUtils.isNotEmpty(wheres)) st_sql.add("filters", wheres); + if (ObjectUtils.isNotEmpty(tableObj)) st_sql.add("table", tableObj); + String sql = st_sql.render(); + + ST st = stg.getInstanceOf("querySql"); + SQLObj tableSQL = SQLObj.builder() + .tableName(String.format(PrestoConstants.BRACKETS, sql)) + .tableAlias(String.format(TABLE_ALIAS_PREFIX, 1)) + .build(); + if (CollectionUtils.isNotEmpty(aggWheres)) st.add("filters", aggWheres); + if (CollectionUtils.isNotEmpty(orders)) st.add("orders", orders); + if (ObjectUtils.isNotEmpty(tableSQL)) st.add("table", tableSQL); + return sqlLimit(st.render(), view); + } + + @Override + public String getSQLAsTmpScatter(String table, List xAxis, List yAxis, List fieldCustomFilter, List rowPermissionsTree, List extFilterRequestList, List extBubble, ChartViewWithBLOBs view) { + return getSQLScatter("(" + sqlFix(table) + ")", xAxis, yAxis, fieldCustomFilter, rowPermissionsTree, extFilterRequestList, extBubble, null, view); + } + + @Override + public String searchTable(String table) { + return "SELECT table_name FROM information_schema.TABLES WHERE table_name ='" + table + "'"; + } + + @Override + public String getSQLSummary(String table, List yAxis, List fieldCustomFilter, List rowPermissionsTree, List extFilterRequestList, ChartViewWithBLOBs view, Datasource ds) { + // 字段汇总 排序等 + SQLObj tableObj = SQLObj.builder() + .tableName((table.startsWith("(") && table.endsWith(")")) ? table : String.format(PrestoConstants.KEYWORD_TABLE, table)) + .tableAlias(String.format(TABLE_ALIAS_PREFIX, 0)) + .build(); + setSchema(tableObj, ds); + List yFields = new ArrayList<>(); + List yWheres = new ArrayList<>(); + List yOrders = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(yAxis)) { + for (int i = 0; i < yAxis.size(); i++) { + ChartViewFieldDTO y = yAxis.get(i); + String originField; + if (ObjectUtils.isNotEmpty(y.getExtField()) && y.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originField = calcFieldRegex(y.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(y.getExtField()) && y.getExtField() == 1) { + originField = String.format(PrestoConstants.KEYWORD_FIX, tableObj.getTableAlias(), y.getOriginName()); + } else { + originField = String.format(PrestoConstants.KEYWORD_FIX, tableObj.getTableAlias(), y.getOriginName()); + } + String fieldAlias = String.format(SQLConstants.FIELD_ALIAS_Y_PREFIX, i); + // 处理纵轴字段 + yFields.add(getYFields(y, originField, fieldAlias)); + // 处理纵轴过滤 + yWheres.add(getYWheres(y, originField, fieldAlias)); + // 处理纵轴排序 + if (StringUtils.isNotEmpty(y.getSort()) && !StringUtils.equalsIgnoreCase(y.getSort(), "none")) { + yOrders.add(SQLObj.builder() + .orderField(originField) + .orderAlias(fieldAlias) + .orderDirection(y.getSort()) + .build()); + } + } + } + // 处理视图中字段过滤 + String customWheres = transCustomFilterList(tableObj, fieldCustomFilter); + // 处理仪表板字段过滤 + String extWheres = transExtFilterList(tableObj, extFilterRequestList); + // row permissions tree + String whereTrees = transFilterTrees(tableObj, rowPermissionsTree); + // 构建sql所有参数 + List fields = new ArrayList<>(); + fields.addAll(yFields); + List wheres = new ArrayList<>(); + if (customWheres != null) wheres.add(customWheres); + if (extWheres != null) wheres.add(extWheres); + if (whereTrees != null) wheres.add(whereTrees); + List groups = new ArrayList<>(); + // 外层再次套sql + List orders = new ArrayList<>(); + orders.addAll(yOrders); + List aggWheres = new ArrayList<>(); + aggWheres.addAll(yWheres.stream().filter(ObjectUtils::isNotEmpty).collect(Collectors.toList())); + + STGroup stg = new STGroupFile(SQLConstants.SQL_TEMPLATE); + ST st_sql = stg.getInstanceOf("querySql"); + if (CollectionUtils.isNotEmpty(yFields)) st_sql.add("aggregators", yFields); + if (CollectionUtils.isNotEmpty(wheres)) st_sql.add("filters", wheres); + if (ObjectUtils.isNotEmpty(tableObj)) st_sql.add("table", tableObj); + String sql = st_sql.render(); + + ST st = stg.getInstanceOf("querySql"); + SQLObj tableSQL = SQLObj.builder() + .tableName(String.format(PrestoConstants.BRACKETS, sql)) + .tableAlias(String.format(TABLE_ALIAS_PREFIX, 1)) + .build(); + if (CollectionUtils.isNotEmpty(aggWheres)) st.add("filters", aggWheres); + if (CollectionUtils.isNotEmpty(orders)) st.add("orders", orders); + if (ObjectUtils.isNotEmpty(tableSQL)) st.add("table", tableSQL); + return sqlLimit(st.render(), view); + } + + @Override + public String getSQLSummaryAsTmp(String sql, List yAxis, List fieldCustomFilter, List rowPermissionsTree, List extFilterRequestList, ChartViewWithBLOBs view) { + return getSQLSummary("(" + sqlFix(sql) + ")", yAxis, fieldCustomFilter, rowPermissionsTree, extFilterRequestList, view, null); + } + + @Override + public String wrapSql(String sql) { + sql = sql.trim(); + if (sql.lastIndexOf(";") == (sql.length() - 1)) { + sql = sql.substring(0, sql.length() - 1); + } + String tmpSql = "SELECT * FROM (" + sql + ") AS tmp " + " LIMIT 0 "; + return tmpSql; + } + + @Override + public String createRawQuerySQL(String table, List fields, Datasource ds) { + String[] array = fields.stream().map(f -> { + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.append("\"").append(f.getOriginName()).append("\" AS ").append(f.getDataeaseName()); + return stringBuilder.toString(); + }).toArray(String[]::new); + if (ds != null) { + String schema = new Gson().fromJson(ds.getConfiguration(), JdbcConfiguration.class).getSchema(); + String tableWithSchema = String.format(SqlServerSQLConstants.KEYWORD_TABLE, schema) + "." + String.format(SqlServerSQLConstants.KEYWORD_TABLE, table); + return MessageFormat.format("SELECT {0} FROM {1} ", StringUtils.join(array, ","), tableWithSchema); + } else { + return MessageFormat.format("SELECT {0} FROM {1} ", StringUtils.join(array, ","), table); + } + } + + @Override + public String createRawQuerySQLAsTmp(String sql, List fields) { + return createRawQuerySQL(" (" + sqlFix(sql) + ") AS tmp ", fields, null); + } + + @Override + public String transTreeItem(SQLObj tableObj, DatasetRowPermissionsTreeItem item) { + String res = null; + DatasetTableField field = item.getField(); + if (ObjectUtils.isEmpty(field)) { + return null; + } + String whereName = ""; + String originName; + if (ObjectUtils.isNotEmpty(field.getExtField()) && field.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originName = calcFieldRegex(field.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(field.getExtField()) && field.getExtField() == 1) { + originName = String.format(PrestoConstants.KEYWORD_FIX, tableObj.getTableAlias(), field.getOriginName()); + } else { + originName = String.format(PrestoConstants.KEYWORD_FIX, tableObj.getTableAlias(), field.getOriginName()); + } + if (field.getDeType() == 1) { + if (field.getDeExtractType() == 0 || field.getDeExtractType() == 5) { + whereName = String.format(PrestoConstants.CAST, originName, "timestamp"); + } + if (field.getDeExtractType() == 2 || field.getDeExtractType() == 3 || field.getDeExtractType() == 4) { + String cast = String.format(PrestoConstants.CAST, originName, "bigint"); + whereName = String.format(PrestoConstants.FROM_UNIXTIME, cast); + } + if (field.getDeExtractType() == 1) { + whereName = originName; + } + } else if (field.getDeType() == 2 || field.getDeType() == 3) { + if (field.getDeExtractType() == 0 || field.getDeExtractType() == 5) { + whereName = String.format(PrestoConstants.CAST, originName, PrestoConstants.DEFAULT_FLOAT_FORMAT); + } + if (field.getDeExtractType() == 1) { + whereName = String.format(PrestoConstants.UNIX_TIMESTAMP, originName); + } + if (field.getDeExtractType() == 2 || field.getDeExtractType() == 3 || field.getDeExtractType() == 4) { + whereName = originName; + } + } else { + whereName = originName; + } + + if (StringUtils.equalsIgnoreCase(item.getFilterType(), "enum")) { + if (CollectionUtils.isNotEmpty(item.getEnumValue())) { + res = "(" + whereName + " IN ('" + String.join("','", item.getEnumValue()) + "'))"; + } + } else { + String value = item.getValue(); + String whereTerm = transMysqlFilterTerm(item.getTerm()); + String whereValue = ""; + + if (StringUtils.equalsIgnoreCase(item.getTerm(), "null")) { + whereValue = ""; + } else if (StringUtils.equalsIgnoreCase(item.getTerm(), "not_null")) { + whereValue = ""; + } else if (StringUtils.equalsIgnoreCase(item.getTerm(), "empty")) { + whereValue = "''"; + } else if (StringUtils.equalsIgnoreCase(item.getTerm(), "not_empty")) { + whereValue = "''"; + } else if (StringUtils.containsIgnoreCase(item.getTerm(), "in") || StringUtils.containsIgnoreCase(item.getTerm(), "not in")) { + whereValue = "('" + String.join("','", value.split(",")) + "')"; + } else if (StringUtils.containsIgnoreCase(item.getTerm(), "like")) { + whereValue = "'%" + value + "%'"; + } else { + whereValue = String.format(PrestoConstants.WHERE_VALUE_VALUE, value); + } + SQLObj build = SQLObj.builder() + .whereField(whereName) + .whereTermAndValue(whereTerm + whereValue) + .build(); + res = build.getWhereField() + " " + build.getWhereTermAndValue(); + } + return res; + } + + @Override + public String convertTableToSql(String tableName, Datasource ds) { + String schema = new Gson().fromJson(ds.getConfiguration(), JdbcConfiguration.class).getSchema(); + schema = String.format(PrestoConstants.KEYWORD_TABLE, schema); + return createSQLPreview("SELECT * FROM " + schema + "." + String.format(PrestoConstants.KEYWORD_TABLE, tableName), null); + } + + public String transMysqlFilterTerm(String term) { + switch (term) { + case "eq": + return " = "; + case "not_eq": + return " <> "; + case "lt": + return " < "; + case "le": + return " <= "; + case "gt": + return " > "; + case "ge": + return " >= "; + case "in": + return " IN "; + case "not in": + return " NOT IN "; + case "like": + return " LIKE "; + case "not like": + return " NOT LIKE "; + case "null": + return " IS NULL "; + case "not_null": + return " IS NOT NULL "; + case "empty": + return " = "; + case "not_empty": + return " <> "; + case "between": + return " BETWEEN "; + default: + return ""; + } + } + + public String transCustomFilterList(SQLObj tableObj, List requestList) { + if (CollectionUtils.isEmpty(requestList)) { + return null; + } + List res = new ArrayList<>(); + for (ChartFieldCustomFilterDTO request : requestList) { + List list = new ArrayList<>(); + DatasetTableField field = request.getField(); + + if (ObjectUtils.isEmpty(field)) { + continue; + } + String whereName = ""; + String originName; + if (ObjectUtils.isNotEmpty(field.getExtField()) && field.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originName = calcFieldRegex(field.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(field.getExtField()) && field.getExtField() == 1) { + originName = String.format(PrestoConstants.KEYWORD_FIX, tableObj.getTableAlias(), field.getOriginName()); + } else { + originName = String.format(PrestoConstants.KEYWORD_FIX, tableObj.getTableAlias(), field.getOriginName()); + } + if (field.getDeType() == 1) { + if (field.getDeExtractType() == 0 || field.getDeExtractType() == 5) { + whereName = String.format(PrestoConstants.date_parse, originName, StringUtils.isNotEmpty(field.getDateFormat()) ? field.getDateFormat() : PrestoConstants.DEFAULT_DATE_FORMAT); + } + if (field.getDeExtractType() == 2 || field.getDeExtractType() == 3 || field.getDeExtractType() == 4) { + String cast = String.format(PrestoConstants.CAST, originName, "bigint"); + whereName = String.format(PrestoConstants.FROM_UNIXTIME, cast); + } + if (field.getDeExtractType() == 1) { + whereName = originName; + } + } else if (field.getDeType() == 2 || field.getDeType() == 3) { + if (field.getDeExtractType() == 0 || field.getDeExtractType() == 5) { + whereName = String.format(PrestoConstants.CAST, originName, PrestoConstants.DEFAULT_FLOAT_FORMAT); + } + if (field.getDeExtractType() == 1) { + whereName = String.format(PrestoConstants.UNIX_TIMESTAMP, originName); + } + if (field.getDeExtractType() == 2 || field.getDeExtractType() == 3 || field.getDeExtractType() == 4) { + whereName = originName; + } + } else { + whereName = originName; + } + + if (StringUtils.equalsIgnoreCase(request.getFilterType(), "enum")) { + if (CollectionUtils.isNotEmpty(request.getEnumCheckField())) { + res.add("(" + whereName + " IN ('" + String.join("','", request.getEnumCheckField()) + "'))"); + } + } else { + List filter = request.getFilter(); + for (ChartCustomFilterItemDTO filterItemDTO : filter) { + String value = filterItemDTO.getValue(); + String whereTerm = transMysqlFilterTerm(filterItemDTO.getTerm()); + String whereValue = ""; + + if (StringUtils.equalsIgnoreCase(filterItemDTO.getTerm(), "null")) { + whereValue = ""; + } else if (StringUtils.equalsIgnoreCase(filterItemDTO.getTerm(), "not_null")) { + whereValue = ""; + } else if (StringUtils.equalsIgnoreCase(filterItemDTO.getTerm(), "empty")) { + whereValue = "''"; + } else if (StringUtils.equalsIgnoreCase(filterItemDTO.getTerm(), "not_empty")) { + whereValue = "''"; + } else if (StringUtils.containsIgnoreCase(filterItemDTO.getTerm(), "in") || StringUtils.containsIgnoreCase(filterItemDTO.getTerm(), "not in")) { + whereValue = "('" + String.join("','", value.split(",")) + "')"; + } else if (StringUtils.containsIgnoreCase(filterItemDTO.getTerm(), "like")) { + whereValue = "'%" + value + "%'"; + } else { + whereValue = String.format(PrestoConstants.WHERE_VALUE_VALUE, value); + } + list.add(SQLObj.builder() + .whereField(whereName) + .whereTermAndValue(whereTerm + whereValue) + .build()); + } + + List strList = new ArrayList<>(); + list.forEach(ele -> strList.add(ele.getWhereField() + " " + ele.getWhereTermAndValue())); + if (CollectionUtils.isNotEmpty(list)) { + res.add("(" + String.join(" " + getLogic(request.getLogic()) + " ", strList) + ")"); + } + } + } + return CollectionUtils.isNotEmpty(res) ? "(" + String.join(" AND ", res) + ")" : null; + } + + public String transExtFilterList(SQLObj tableObj, List requestList) { + if (CollectionUtils.isEmpty(requestList)) { + return null; + } + List list = new ArrayList<>(); + for (ChartExtFilterRequest request : requestList) { + List value = request.getValue(); + + List whereNameList = new ArrayList<>(); + List fieldList = new ArrayList<>(); + if (request.getIsTree()) { + fieldList.addAll(request.getDatasetTableFieldList()); + } else { + fieldList.add(request.getDatasetTableField()); + } + + for (DatasetTableField field : fieldList) { + if (CollectionUtils.isEmpty(value) || ObjectUtils.isEmpty(field)) { + continue; + } + String whereName = ""; + + String originName; + if (ObjectUtils.isNotEmpty(field.getExtField()) && field.getExtField() == 2) { + // 解析origin name中有关联的字段生成sql表达式 + originName = calcFieldRegex(field.getOriginName(), tableObj); + } else if (ObjectUtils.isNotEmpty(field.getExtField()) && field.getExtField() == 1) { + originName = String.format(PrestoConstants.KEYWORD_FIX, tableObj.getTableAlias(), field.getOriginName()); + } else { + originName = String.format(PrestoConstants.KEYWORD_FIX, tableObj.getTableAlias(), field.getOriginName()); + } + + if (field.getDeType() == 1) { + if (field.getDeExtractType() == 0 || field.getDeExtractType() == 5) { + whereName = String.format(PrestoConstants.date_parse, originName, StringUtils.isNotEmpty(field.getDateFormat()) ? field.getDateFormat() : PrestoConstants.DEFAULT_DATE_FORMAT); + } + if (field.getDeExtractType() == 2 || field.getDeExtractType() == 3 || field.getDeExtractType() == 4) { + String cast = String.format(PrestoConstants.CAST, originName, "bigint"); + whereName = String.format(PrestoConstants.FROM_UNIXTIME, cast); + } + if (field.getDeExtractType() == 1) { + whereName = originName; + } + } else if (field.getDeType() == 2 || field.getDeType() == 3) { + if (field.getDeExtractType() == 0 || field.getDeExtractType() == 5) { + whereName = String.format(PrestoConstants.CAST, originName, PrestoConstants.DEFAULT_FLOAT_FORMAT); + } + if (field.getDeExtractType() == 1) { + whereName = String.format(PrestoConstants.UNIX_TIMESTAMP, originName); + } + if (field.getDeExtractType() == 2 || field.getDeExtractType() == 3 || field.getDeExtractType() == 4) { + whereName = originName; + } + } else { + whereName = originName; + } + whereNameList.add(whereName); + } + + String whereName = ""; + if (request.getIsTree()) { + whereName = "CONCAT(" + StringUtils.join(whereNameList, ",',',") + ")"; + } else { + whereName = whereNameList.get(0); + } + String whereTerm = transMysqlFilterTerm(request.getOperator()); + String whereValue = ""; + + if (StringUtils.containsIgnoreCase(request.getOperator(), "in")) { + whereValue = "('" + StringUtils.join(value, "','") + "')"; + } else if (StringUtils.containsIgnoreCase(request.getOperator(), "like")) { + String keyword = value.get(0).toUpperCase(); + whereValue = "'%" + keyword + "%'"; + whereName = "upper(" + whereName + ")"; + } else if (StringUtils.containsIgnoreCase(request.getOperator(), "between")) { + if (request.getDatasetTableField().getDeType() == 1) { + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + String startTime = simpleDateFormat.format(new Date(Long.parseLong(value.get(0)))); + String endTime = simpleDateFormat.format(new Date(Long.parseLong(value.get(1)))); + whereValue = String.format(PrestoConstants.WHERE_BETWEEN, startTime, endTime); + } else { + whereValue = String.format(PrestoConstants.WHERE_BETWEEN, value.get(0), value.get(1)); + } + } else { + whereValue = String.format(PrestoConstants.WHERE_VALUE_VALUE, value.get(0)); + } + list.add(SQLObj.builder() + .whereField(whereName) + .whereTermAndValue(whereTerm + whereValue) + .build()); + } + List strList = new ArrayList<>(); + list.forEach(ele -> strList.add(ele.getWhereField() + " " + ele.getWhereTermAndValue())); + return CollectionUtils.isNotEmpty(list) ? "(" + String.join(" AND ", strList) + ")" : null; + } + + private String sqlFix(String sql) { + if (sql.lastIndexOf(";") == (sql.length() - 1)) { + sql = sql.substring(0, sql.length() - 1); + } + return sql; + } + + private String transDateFormat(String dateStyle, String datePattern) { + String split = "-"; + if (StringUtils.equalsIgnoreCase(datePattern, "date_sub")) { + split = "-"; + } else if (StringUtils.equalsIgnoreCase(datePattern, "date_split")) { + split = "/"; + } else { + split = "-"; + } + + if (StringUtils.isEmpty(dateStyle)) { + return "yyyy-MM-dd HH:mm:ss"; + } + + switch (dateStyle) { + case "y": + return "yyyy"; + case "y_M": + return "yyyy" + split + "MM"; + case "y_M_d": + return "yyyy" + split + "MM" + split + "dd"; + case "H_m_s": + return "hh:mi:ss"; + case "y_M_d_H_m": + return "yyyy" + split + "MM" + split + "dd" + " HH:mm"; + case "y_M_d_H_m_s": + return "yyyy" + split + "MM" + split + "dd" + " HH:mm:ss"; + default: + return "yyyy-MM-dd HH:mm:s"; + } + } + + private SQLObj getXFields(ChartViewFieldDTO x, String originField, String fieldAlias) { + String fieldName = ""; + if (x.getDeExtractType() == DeTypeConstants.DE_TIME) { + if (x.getDeType() == 2 || x.getDeType() == 3) { + fieldName = String.format(PrestoConstants.UNIX_TIMESTAMP, originField); + } else if (x.getDeType() == DeTypeConstants.DE_TIME) { + String format = transDateFormat(x.getDateStyle(), x.getDatePattern()); + fieldName = String.format(PrestoConstants.FORMAT_DATETIME, originField, format); + } else { + fieldName = originField; + } + } else { + if (x.getDeType() == DeTypeConstants.DE_TIME) { + String format = transDateFormat(x.getDateStyle(), x.getDatePattern()); + if (x.getDeExtractType() == DeTypeConstants.DE_STRING) { + fieldName = String.format(PrestoConstants.FORMAT_DATETIME, String.format(PrestoConstants.date_parse, originField, StringUtils.isNotEmpty(x.getDateFormat()) ? x.getDateFormat() : PrestoConstants.DEFAULT_DATE_FORMAT), format); + } else { + String from_unixtime = String.format(PrestoConstants.FROM_UNIXTIME, originField + "/1000"); + fieldName = String.format(PrestoConstants.FORMAT_DATETIME, from_unixtime, format); + } + } else { + if (x.getDeType() == DeTypeConstants.DE_INT) { + fieldName = String.format(PrestoConstants.CAST, originField, PrestoConstants.DEFAULT_INT_FORMAT); + } else if (x.getDeType() == DeTypeConstants.DE_FLOAT) { + fieldName = String.format(PrestoConstants.CAST, originField, PrestoConstants.DEFAULT_FLOAT_FORMAT); + } else { + fieldName = originField; + } + } + } + return SQLObj.builder() + .fieldName(fieldName) + .fieldAlias(fieldAlias) + .build(); + } + + private SQLObj getYFields(ChartViewFieldDTO y, String originField, String fieldAlias) { + String fieldName = ""; + if (StringUtils.equalsIgnoreCase(y.getOriginName(), "*")) { + fieldName = PrestoConstants.AGG_COUNT; + } else if (SQLConstants.DIMENSION_TYPE.contains(y.getDeType())) { + fieldName = String.format(PrestoConstants.AGG_FIELD, y.getSummary(), originField); + } else { + if (StringUtils.equalsIgnoreCase(y.getSummary(), "avg") || StringUtils.containsIgnoreCase(y.getSummary(), "pop")) { + String cast = String.format(PrestoConstants.CAST, originField, y.getDeType() == DeTypeConstants.DE_INT ? PrestoConstants.DEFAULT_INT_FORMAT : PrestoConstants.DEFAULT_FLOAT_FORMAT); + String agg = String.format(PrestoConstants.AGG_FIELD, y.getSummary(), cast); + fieldName = String.format(PrestoConstants.CAST, agg, PrestoConstants.DEFAULT_FLOAT_FORMAT); + } else { + String cast = String.format(PrestoConstants.CAST, originField, y.getDeType() == DeTypeConstants.DE_INT ? PrestoConstants.DEFAULT_INT_FORMAT : PrestoConstants.DEFAULT_FLOAT_FORMAT); + fieldName = String.format(PrestoConstants.AGG_FIELD, y.getSummary(), cast); + } + } + return SQLObj.builder() + .fieldName(fieldName) + .fieldAlias(fieldAlias) + .build(); + } + + private String getYWheres(ChartViewFieldDTO y, String originField, String fieldAlias) { + List list = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(y.getFilter()) && y.getFilter().size() > 0) { + y.getFilter().forEach(f -> { + String whereTerm = transMysqlFilterTerm(f.getTerm()); + String whereValue = ""; + // 原始类型不是时间,在de中被转成时间的字段做处理 + if (StringUtils.equalsIgnoreCase(f.getTerm(), "null")) { + whereValue = ""; + } else if (StringUtils.equalsIgnoreCase(f.getTerm(), "not_null")) { + whereValue = ""; + } else if (StringUtils.equalsIgnoreCase(f.getTerm(), "empty")) { + whereValue = "''"; + } else if (StringUtils.equalsIgnoreCase(f.getTerm(), "not_empty")) { + whereValue = "''"; + } else if (StringUtils.containsIgnoreCase(f.getTerm(), "in")) { + whereValue = "('" + StringUtils.join(f.getValue(), "','") + "')"; + } else if (StringUtils.containsIgnoreCase(f.getTerm(), "like")) { + whereValue = "'%" + f.getValue() + "%'"; + } else { + whereValue = String.format(PrestoConstants.WHERE_VALUE_VALUE, f.getValue()); + } + list.add(SQLObj.builder() + .whereField(fieldAlias) + .whereAlias(fieldAlias) + .whereTermAndValue(whereTerm + whereValue) + .build()); + }); + } + List strList = new ArrayList<>(); + list.forEach(ele -> strList.add(ele.getWhereField() + " " + ele.getWhereTermAndValue())); + return CollectionUtils.isNotEmpty(list) ? "(" + String.join(" " + getLogic(y.getLogic()) + " ", strList) + ")" : null; + } + + private String calcFieldRegex(String originField, SQLObj tableObj) { + originField = originField.replaceAll("[\\t\\n\\r]]", ""); + // 正则提取[xxx] + String regex = "\\[(.*?)]"; + Pattern pattern = Pattern.compile(regex); + Matcher matcher = pattern.matcher(originField); + Set ids = new HashSet<>(); + while (matcher.find()) { + String id = matcher.group(1); + ids.add(id); + } + if (CollectionUtils.isEmpty(ids)) { + return originField; + } + DatasetTableFieldExample datasetTableFieldExample = new DatasetTableFieldExample(); + datasetTableFieldExample.createCriteria().andIdIn(new ArrayList<>(ids)); + List calcFields = datasetTableFieldMapper.selectByExample(datasetTableFieldExample); + for (DatasetTableField ele : calcFields) { + originField = originField.replaceAll("\\[" + ele.getId() + "]", + String.format(PrestoConstants.KEYWORD_FIX, tableObj.getTableAlias(), ele.getOriginName())); + } + return originField; + } + + private String sqlLimit(String sql, ChartViewWithBLOBs view) { + if (StringUtils.equalsIgnoreCase(view.getResultMode(), "custom")) { + return sql + " LIMIT " + view.getResultCount(); + } else { + return sql; + } + } + + public void setSchema(SQLObj tableObj, Datasource ds) { + if (ds != null && !tableObj.getTableName().startsWith("(") && !tableObj.getTableName().endsWith(")")) { + PrestoConfig prestoConfig = json.fromJson(ds.getConfiguration(), PrestoConfig.class); + String schema = prestoConfig.getSchema(); + String database = prestoConfig.getDataBase(); + tableObj.setTableName(database + "." + schema + "." + tableObj.getTableName()); + } + } + + public List dateformat() { + ObjectMapper objectMapper = new ObjectMapper(); + List dateformats = new ArrayList<>(); + try{ + dateformats = objectMapper.readValue("[\n" + + "{\"dateformat\": \"yyyy-MM-dd\"},\n" + + "{\"dateformat\": \"yyyy/MM/dd\"},\n" + + "{\"dateformat\": \"YyyyyMMdd\"},\n" + + "{\"dateformat\": \"yyyy-MM-dd HH:mm:s\"},\n" + + "{\"dateformat\": \"yyyy-MM-dd HH:mm:s\"},\n" + + "{\"dateformat\": \"yyyy-MM-dd HH:mm:s\"}\n" + + "]", new TypeReference>() {} ); + }catch (Exception e){} + return dateformats; + } + + public String getResultCount(boolean isTable, String sql, List xAxis, List fieldCustomFilter, List rowPermissionsTree, List extFilterRequestList, Datasource ds, ChartViewWithBLOBs view) { + return null; + } +} diff --git a/extensions/dataease-extensions-datasource/presto/presto-backend/src/main/java/io/dataease/plugins/datasource/dm/service/PrestoService.java b/extensions/dataease-extensions-datasource/presto/presto-backend/src/main/java/io/dataease/plugins/datasource/dm/service/PrestoService.java new file mode 100644 index 0000000000..4bc58d98a0 --- /dev/null +++ b/extensions/dataease-extensions-datasource/presto/presto-backend/src/main/java/io/dataease/plugins/datasource/dm/service/PrestoService.java @@ -0,0 +1,54 @@ +package io.dataease.plugins.datasource.dm.service; + +import io.dataease.plugins.common.constants.DatabaseClassification; +import io.dataease.plugins.common.constants.DatasourceCalculationMode; +import io.dataease.plugins.common.dto.StaticResource; +import io.dataease.plugins.common.dto.datasource.DataSourceType; +import io.dataease.plugins.datasource.service.DatasourceService; +import org.springframework.stereotype.Service; + +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + +@Service +public class PrestoService extends DatasourceService { + + + @Override + public List components() { + List result = new ArrayList<>(); + result.add("presto"); + return result; + } + @Override + protected InputStream readContent(String s) { + InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream("static/" + s); + return resourceAsStream; + } + + @Override + public List staticResources() { + List results = new ArrayList<>(); + StaticResource staticResource = new StaticResource(); + staticResource.setName("presto"); + staticResource.setSuffix("jpg"); + results.add(staticResource); + results.add(pluginSvg()); + return results; + } + + @Override + public DataSourceType getDataSourceType() { + DataSourceType dataSourceType = new DataSourceType("presto", "Presto" , true , "", DatasourceCalculationMode.DIRECT, true); + dataSourceType.setDatabaseClassification(DatabaseClassification.OLAP); + return dataSourceType; + } + + private StaticResource pluginSvg() { + StaticResource staticResource = new StaticResource(); + staticResource.setName("presto-backend"); + staticResource.setSuffix("svg"); + return staticResource; + } +} diff --git a/extensions/dataease-extensions-datasource/presto/presto-frontend/.babelrc b/extensions/dataease-extensions-datasource/presto/presto-frontend/.babelrc new file mode 100644 index 0000000000..3a280ba34b --- /dev/null +++ b/extensions/dataease-extensions-datasource/presto/presto-frontend/.babelrc @@ -0,0 +1,12 @@ +{ + "presets": [ + ["env", { + "modules": false, + "targets": { + "browsers": ["> 1%", "last 2 versions", "not ie <= 8"] + } + }], + "stage-2" + ], + "plugins": ["transform-vue-jsx", "transform-runtime"] +} diff --git a/extensions/dataease-extensions-datasource/presto/presto-frontend/.editorconfig b/extensions/dataease-extensions-datasource/presto/presto-frontend/.editorconfig new file mode 100644 index 0000000000..9d08a1a828 --- /dev/null +++ b/extensions/dataease-extensions-datasource/presto/presto-frontend/.editorconfig @@ -0,0 +1,9 @@ +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true diff --git a/extensions/dataease-extensions-datasource/presto/presto-frontend/.gitignore b/extensions/dataease-extensions-datasource/presto/presto-frontend/.gitignore new file mode 100644 index 0000000000..541a820f6c --- /dev/null +++ b/extensions/dataease-extensions-datasource/presto/presto-frontend/.gitignore @@ -0,0 +1,14 @@ +.DS_Store +node_modules/ +/dist/ +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Editor directories and files +.idea +.vscode +*.suo +*.ntvs* +*.njsproj +*.sln diff --git a/extensions/dataease-extensions-datasource/presto/presto-frontend/.postcssrc.js b/extensions/dataease-extensions-datasource/presto/presto-frontend/.postcssrc.js new file mode 100644 index 0000000000..eee3e92d7f --- /dev/null +++ b/extensions/dataease-extensions-datasource/presto/presto-frontend/.postcssrc.js @@ -0,0 +1,10 @@ +// https://github.com/michael-ciniawsky/postcss-load-config + +module.exports = { + "plugins": { + "postcss-import": {}, + "postcss-url": {}, + // to edit target browsers: use "browserslist" field in package.json + "autoprefixer": {} + } +} diff --git a/extensions/dataease-extensions-datasource/presto/presto-frontend/README.md b/extensions/dataease-extensions-datasource/presto/presto-frontend/README.md new file mode 100644 index 0000000000..c1e4be95e0 --- /dev/null +++ b/extensions/dataease-extensions-datasource/presto/presto-frontend/README.md @@ -0,0 +1,21 @@ +# deplugin-view-frontend + +> A Vue.js project + +## Build Setup + +``` bash +# install dependencies +npm install + +# serve with hot reload at localhost:8080 +npm run dev + +# build for production with minification +npm run build + +# build for production and view the bundle analyzer report +npm run build --report +``` + +For a detailed explanation on how things work, check out the [guide](http://vuejs-templates.github.io/webpack/) and [docs for vue-loader](http://vuejs.github.io/vue-loader). diff --git a/extensions/dataease-extensions-datasource/presto/presto-frontend/build/build-async-plugins.js b/extensions/dataease-extensions-datasource/presto/presto-frontend/build/build-async-plugins.js new file mode 100644 index 0000000000..2303854531 --- /dev/null +++ b/extensions/dataease-extensions-datasource/presto/presto-frontend/build/build-async-plugins.js @@ -0,0 +1,35 @@ +'use strict' +require('./check-versions')() + +process.env.NODE_ENV = 'production' + +const ora = require('ora') +const chalk = require('chalk') +const webpack = require('webpack') +const webpackConfig = require('./webpack.async-plugins') + +const spinner = ora('building for sync-plugins...') +spinner.start() + +webpack(webpackConfig, function (err, stats) { + spinner.stop() + if (err) throw err + process.stdout.write(stats.toString({ + colors: true, + modules: false, + children: false, + chunks: false, + chunkModules: false + }) + '\n\n') + + if (stats.hasErrors()) { + console.log(chalk.red(' Build failed with errors.\n')) + process.exit(1) + } + + console.log(chalk.cyan(' Build complete.\n')) + console.log(chalk.yellow( + ' Tip: built files are meant to be served over an HTTP server.\n' + + ' Opening index.html over file:// won\'t work.\n' + )) +}) diff --git a/extensions/dataease-extensions-datasource/presto/presto-frontend/build/build.js b/extensions/dataease-extensions-datasource/presto/presto-frontend/build/build.js new file mode 100644 index 0000000000..8f2ad8ad49 --- /dev/null +++ b/extensions/dataease-extensions-datasource/presto/presto-frontend/build/build.js @@ -0,0 +1,41 @@ +'use strict' +require('./check-versions')() + +process.env.NODE_ENV = 'production' + +const ora = require('ora') +const rm = require('rimraf') +const path = require('path') +const chalk = require('chalk') +const webpack = require('webpack') +const config = require('../config') +const webpackConfig = require('./webpack.prod.conf') + +const spinner = ora('building for production...') +spinner.start() + +rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => { + if (err) throw err + webpack(webpackConfig, (err, stats) => { + spinner.stop() + if (err) throw err + process.stdout.write(stats.toString({ + colors: true, + modules: false, + children: false, // If you are using ts-loader, setting this to true will make TypeScript errors show up during build. + chunks: false, + chunkModules: false + }) + '\n\n') + + if (stats.hasErrors()) { + console.log(chalk.red(' Build failed with errors.\n')) + process.exit(1) + } + + console.log(chalk.cyan(' Build complete.\n')) + console.log(chalk.yellow( + ' Tip: built files are meant to be served over an HTTP server.\n' + + ' Opening index.html over file:// won\'t work.\n' + )) + }) +}) diff --git a/extensions/dataease-extensions-datasource/presto/presto-frontend/build/check-versions.js b/extensions/dataease-extensions-datasource/presto/presto-frontend/build/check-versions.js new file mode 100644 index 0000000000..3ef972a08d --- /dev/null +++ b/extensions/dataease-extensions-datasource/presto/presto-frontend/build/check-versions.js @@ -0,0 +1,54 @@ +'use strict' +const chalk = require('chalk') +const semver = require('semver') +const packageConfig = require('../package.json') +const shell = require('shelljs') + +function exec (cmd) { + return require('child_process').execSync(cmd).toString().trim() +} + +const versionRequirements = [ + { + name: 'node', + currentVersion: semver.clean(process.version), + versionRequirement: packageConfig.engines.node + } +] + +if (shell.which('npm')) { + versionRequirements.push({ + name: 'npm', + currentVersion: exec('npm --version'), + versionRequirement: packageConfig.engines.npm + }) +} + +module.exports = function () { + const warnings = [] + + for (let i = 0; i < versionRequirements.length; i++) { + const mod = versionRequirements[i] + + if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) { + warnings.push(mod.name + ': ' + + chalk.red(mod.currentVersion) + ' should be ' + + chalk.green(mod.versionRequirement) + ) + } + } + + if (warnings.length) { + console.log('') + console.log(chalk.yellow('To use this template, you must update following to modules:')) + console.log() + + for (let i = 0; i < warnings.length; i++) { + const warning = warnings[i] + console.log(' ' + warning) + } + + console.log() + process.exit(1) + } +} diff --git a/extensions/dataease-extensions-datasource/presto/presto-frontend/build/logo.png b/extensions/dataease-extensions-datasource/presto/presto-frontend/build/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..f3d2503fc2a44b5053b0837ebea6e87a2d339a43 GIT binary patch literal 6849 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 { + const notifier = require('node-notifier') + + return (severity, errors) => { + if (severity !== 'error') return + + const error = errors[0] + const filename = error.file && error.file.split('!').pop() + + notifier.notify({ + title: packageConfig.name, + message: severity + ': ' + error.name, + subtitle: filename || '', + icon: path.join(__dirname, 'logo.png') + }) + } +} diff --git a/extensions/dataease-extensions-datasource/presto/presto-frontend/build/vue-loader.conf.js b/extensions/dataease-extensions-datasource/presto/presto-frontend/build/vue-loader.conf.js new file mode 100644 index 0000000000..33ed58bc0a --- /dev/null +++ b/extensions/dataease-extensions-datasource/presto/presto-frontend/build/vue-loader.conf.js @@ -0,0 +1,22 @@ +'use strict' +const utils = require('./utils') +const config = require('../config') +const isProduction = process.env.NODE_ENV === 'production' +const sourceMapEnabled = isProduction + ? config.build.productionSourceMap + : config.dev.cssSourceMap + +module.exports = { + loaders: utils.cssLoaders({ + sourceMap: sourceMapEnabled, + extract: isProduction + }), + cssSourceMap: sourceMapEnabled, + cacheBusting: config.dev.cacheBusting, + transformToRequire: { + video: ['src', 'poster'], + source: 'src', + img: 'src', + image: 'xlink:href' + } +} diff --git a/extensions/dataease-extensions-datasource/presto/presto-frontend/build/webpack.async-plugins.js b/extensions/dataease-extensions-datasource/presto/presto-frontend/build/webpack.async-plugins.js new file mode 100644 index 0000000000..e021615a24 --- /dev/null +++ b/extensions/dataease-extensions-datasource/presto/presto-frontend/build/webpack.async-plugins.js @@ -0,0 +1,91 @@ +const webpack = require('webpack') +const path = require('path') +const utils = require('./utils') +const CopyPlugin = require("copy-webpack-plugin"); +const VueLoaderPlugin = require('vue-loader/lib/plugin'); +function resolve (dir) { + return path.join(__dirname, '..', dir) +} + +module.exports = { + mode: 'development', + entry: { + 'presto': resolve('/src/views/presto.vue') + }, + output: { + path: resolve('/static/'), + filename: '[name].js' + }, + resolve: { + extensions: ['.js', '.vue', '.json'], + alias: { + 'vue$': 'vue/dist/vue.esm.js', + '@': resolve('src') + } + }, + externals: { + vue: 'vue' + }, + module: { + rules: [ + { + test: /\.vue$/, + loader: 'vue-loader', + options: { + transformAssetUrls: { + video: 'src', + source: 'src', + img: 'src', + image: 'xlink:href' + } + } + }, + { + test: /.(sa|sc|c)ss$/, + use: [ + {loader: 'vue-style-loader'}, + 'css-loader', + 'sass-loader' + ] + }, + { + test: /\.js$/, + loader: 'babel-loader', + include: [resolve('src'), resolve('test')] + }, + { + test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: utils.assetsPath('img/[name].[hash:7].[ext]') + } + }, + { + test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: utils.assetsPath('media/[name].[hash:7].[ext]') + } + }, + { + test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: utils.assetsPath('fonts/[name].[hash:7].[ext]') + } + } + ] + }, + plugins: [ + new VueLoaderPlugin(), + new webpack.DefinePlugin({ + 'process.env.NODE_ENV': '"production"' + }), + new CopyPlugin([ + {from: 'src/icons/svg/'} + ]), + ] +} diff --git a/extensions/dataease-extensions-datasource/presto/presto-frontend/build/webpack.base.conf.js b/extensions/dataease-extensions-datasource/presto/presto-frontend/build/webpack.base.conf.js new file mode 100644 index 0000000000..7ef785a39e --- /dev/null +++ b/extensions/dataease-extensions-datasource/presto/presto-frontend/build/webpack.base.conf.js @@ -0,0 +1,103 @@ +'use strict' +const path = require('path') +const utils = require('./utils') +const config = require('../config') +const vueLoaderConfig = require('./vue-loader.conf') + +function resolve (dir) { + return path.join(__dirname, '..', dir) +} + + + +module.exports = { + context: path.resolve(__dirname, '../'), + entry: { + app: './src/main.js' + }, + output: { + path: config.build.assetsRoot, + filename: '[name].js', + publicPath: process.env.NODE_ENV === 'production' + ? config.build.assetsPublicPath + : config.dev.assetsPublicPath + }, + resolve: { + extensions: ['.js', '.vue', '.json'], + alias: { + 'vue$': 'vue/dist/vue.esm.js', + '@': resolve('src'), + } + }, + module: { + rules: [ + { + test: /\.vue$/, + loader: 'vue-loader', + options: vueLoaderConfig + }, + { + test: /\.js$/, + loader: 'babel-loader', + include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')] + }, + { + test: /\.svg$/, + loader: 'svg-sprite-loader', + include: [resolve('src/icons')], + options: { + symbolId: 'icon-[name]' + } + }, + { + test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, + loader: 'url-loader', + exclude: [resolve('src/icons')], + options: { + limit: 10000, + name: utils.assetsPath('img/[name].[hash:7].[ext]') + } + }, + { + test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: utils.assetsPath('media/[name].[hash:7].[ext]') + } + }, + { + test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: utils.assetsPath('fonts/[name].[hash:7].[ext]') + } + }, + { + test: /\.svg$/, + include: [path.resolve('src/icons')], + use: [ + { + loader: 'svg-sprite-loader', + options: { + symbolId: 'icon-[name]', + }, + } + ], + } + ] + }, + node: { + // prevent webpack from injecting useless setImmediate polyfill because Vue + // source contains it (although only uses it if it's native). + setImmediate: false, + // prevent webpack from injecting mocks to Node native modules + // that does not make sense for the client + dgram: 'empty', + fs: 'empty', + net: 'empty', + tls: 'empty', + child_process: 'empty' + } +} diff --git a/extensions/dataease-extensions-datasource/presto/presto-frontend/build/webpack.dev.conf.js b/extensions/dataease-extensions-datasource/presto/presto-frontend/build/webpack.dev.conf.js new file mode 100755 index 0000000000..070ae221f3 --- /dev/null +++ b/extensions/dataease-extensions-datasource/presto/presto-frontend/build/webpack.dev.conf.js @@ -0,0 +1,95 @@ +'use strict' +const utils = require('./utils') +const webpack = require('webpack') +const config = require('../config') +const merge = require('webpack-merge') +const path = require('path') +const baseWebpackConfig = require('./webpack.base.conf') +const CopyWebpackPlugin = require('copy-webpack-plugin') +const HtmlWebpackPlugin = require('html-webpack-plugin') +const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin') +const portfinder = require('portfinder') + +const HOST = process.env.HOST +const PORT = process.env.PORT && Number(process.env.PORT) + +const devWebpackConfig = merge(baseWebpackConfig, { + module: { + rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true }) + }, + // cheap-module-eval-source-map is faster for development + devtool: config.dev.devtool, + + // these devServer options should be customized in /config/index.js + devServer: { + clientLogLevel: 'warning', + historyApiFallback: { + rewrites: [ + { from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') }, + ], + }, + hot: true, + contentBase: false, // since we use CopyWebpackPlugin. + compress: true, + host: HOST || config.dev.host, + port: PORT || config.dev.port, + open: config.dev.autoOpenBrowser, + overlay: config.dev.errorOverlay + ? { warnings: false, errors: true } + : false, + publicPath: config.dev.assetsPublicPath, + proxy: config.dev.proxyTable, + quiet: true, // necessary for FriendlyErrorsPlugin + watchOptions: { + poll: config.dev.poll, + } + }, + plugins: [ + new webpack.DefinePlugin({ + 'process.env': require('../config/dev.env') + }), + new webpack.HotModuleReplacementPlugin(), + new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update. + new webpack.NoEmitOnErrorsPlugin(), + // https://github.com/ampedandwired/html-webpack-plugin + new HtmlWebpackPlugin({ + filename: 'index.html', + template: 'index.html', + inject: true + }), + // copy custom static assets + new CopyWebpackPlugin([ + { + from: path.resolve(__dirname, '../static'), + to: config.dev.assetsSubDirectory, + ignore: ['.*'] + } + ]) + ] +}) + +module.exports = new Promise((resolve, reject) => { + portfinder.basePort = process.env.PORT || config.dev.port + portfinder.getPort((err, port) => { + if (err) { + reject(err) + } else { + // publish the new Port, necessary for e2e tests + process.env.PORT = port + // add port to devServer config + devWebpackConfig.devServer.port = port + + // Add FriendlyErrorsPlugin + devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({ + compilationSuccessInfo: { + messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`], + }, + onErrors: config.dev.notifyOnErrors + ? utils.createNotifierCallback() + : undefined + })) + + resolve(devWebpackConfig) + } + }) +}) diff --git a/extensions/dataease-extensions-datasource/presto/presto-frontend/build/webpack.prod.conf.js b/extensions/dataease-extensions-datasource/presto/presto-frontend/build/webpack.prod.conf.js new file mode 100644 index 0000000000..3e25238ef6 --- /dev/null +++ b/extensions/dataease-extensions-datasource/presto/presto-frontend/build/webpack.prod.conf.js @@ -0,0 +1,145 @@ +'use strict' +const path = require('path') +const utils = require('./utils') +const webpack = require('webpack') +const config = require('../config') +const merge = require('webpack-merge') +const baseWebpackConfig = require('./webpack.base.conf') +const CopyWebpackPlugin = require('copy-webpack-plugin') +const HtmlWebpackPlugin = require('html-webpack-plugin') +const ExtractTextPlugin = require('extract-text-webpack-plugin') +const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin') +const UglifyJsPlugin = require('uglifyjs-webpack-plugin') + +const env = require('../config/prod.env') + +const webpackConfig = merge(baseWebpackConfig, { + module: { + rules: utils.styleLoaders({ + sourceMap: config.build.productionSourceMap, + extract: true, + usePostCSS: true + }) + }, + devtool: config.build.productionSourceMap ? config.build.devtool : false, + output: { + path: config.build.assetsRoot, + filename: utils.assetsPath('js/[name].[chunkhash].js'), + chunkFilename: utils.assetsPath('js/[id].[chunkhash].js') + }, + plugins: [ + // http://vuejs.github.io/vue-loader/en/workflow/production.html + new webpack.DefinePlugin({ + 'process.env': env + }), + new UglifyJsPlugin({ + uglifyOptions: { + compress: { + warnings: false + } + }, + sourceMap: config.build.productionSourceMap, + parallel: true + }), + // extract css into its own file + new ExtractTextPlugin({ + filename: utils.assetsPath('css/[name].[contenthash].css'), + // Setting the following option to `false` will not extract CSS from codesplit chunks. + // Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack. + // It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`, + // increasing file size: https://github.com/vuejs-templates/webpack/issues/1110 + allChunks: true, + }), + // Compress extracted CSS. We are using this plugin so that possible + // duplicated CSS from different components can be deduped. + new OptimizeCSSPlugin({ + cssProcessorOptions: config.build.productionSourceMap + ? { safe: true, map: { inline: false } } + : { safe: true } + }), + // generate dist index.html with correct asset hash for caching. + // you can customize output by editing /index.html + // see https://github.com/ampedandwired/html-webpack-plugin + new HtmlWebpackPlugin({ + filename: config.build.index, + template: 'index.html', + inject: true, + minify: { + removeComments: true, + collapseWhitespace: true, + removeAttributeQuotes: true + // more options: + // https://github.com/kangax/html-minifier#options-quick-reference + }, + // necessary to consistently work with multiple chunks via CommonsChunkPlugin + chunksSortMode: 'dependency' + }), + // keep module.id stable when vendor modules does not change + new webpack.HashedModuleIdsPlugin(), + // enable scope hoisting + new webpack.optimize.ModuleConcatenationPlugin(), + // split vendor js into its own file + new webpack.optimize.CommonsChunkPlugin({ + name: 'vendor', + minChunks (module) { + // any required modules inside node_modules are extracted to vendor + return ( + module.resource && + /\.js$/.test(module.resource) && + module.resource.indexOf( + path.join(__dirname, '../node_modules') + ) === 0 + ) + } + }), + // extract webpack runtime and module manifest to its own file in order to + // prevent vendor hash from being updated whenever app bundle is updated + new webpack.optimize.CommonsChunkPlugin({ + name: 'manifest', + minChunks: Infinity + }), + // This instance extracts shared chunks from code split chunks and bundles them + // in a separate chunk, similar to the vendor chunk + // see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk + new webpack.optimize.CommonsChunkPlugin({ + name: 'app', + async: 'vendor-async', + children: true, + minChunks: 3 + }), + + // copy custom static assets + new CopyWebpackPlugin([ + { + from: path.resolve(__dirname, '../static'), + to: config.build.assetsSubDirectory, + ignore: ['.*'] + } + ]) + ] +}) + +if (config.build.productionGzip) { + const CompressionWebpackPlugin = require('compression-webpack-plugin') + + webpackConfig.plugins.push( + new CompressionWebpackPlugin({ + asset: '[path].gz[query]', + algorithm: 'gzip', + test: new RegExp( + '\\.(' + + config.build.productionGzipExtensions.join('|') + + ')$' + ), + threshold: 10240, + minRatio: 0.8 + }) + ) +} + +if (config.build.bundleAnalyzerReport) { + const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin + webpackConfig.plugins.push(new BundleAnalyzerPlugin()) +} + +module.exports = webpackConfig diff --git a/extensions/dataease-extensions-datasource/presto/presto-frontend/config/dev.env.js b/extensions/dataease-extensions-datasource/presto/presto-frontend/config/dev.env.js new file mode 100644 index 0000000000..1e22973ae7 --- /dev/null +++ b/extensions/dataease-extensions-datasource/presto/presto-frontend/config/dev.env.js @@ -0,0 +1,7 @@ +'use strict' +const merge = require('webpack-merge') +const prodEnv = require('./prod.env') + +module.exports = merge(prodEnv, { + NODE_ENV: '"development"' +}) diff --git a/extensions/dataease-extensions-datasource/presto/presto-frontend/config/index.js b/extensions/dataease-extensions-datasource/presto/presto-frontend/config/index.js new file mode 100644 index 0000000000..c5eded7f81 --- /dev/null +++ b/extensions/dataease-extensions-datasource/presto/presto-frontend/config/index.js @@ -0,0 +1,69 @@ +'use strict' +// Template version: 1.3.1 +// see http://vuejs-templates.github.io/webpack for documentation. + +const path = require('path') + +module.exports = { + dev: { + + // Paths + assetsSubDirectory: 'static', + assetsPublicPath: '/', + proxyTable: {}, + + // Various Dev Server settings + host: 'localhost', // can be overwritten by process.env.HOST + port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined + autoOpenBrowser: false, + errorOverlay: true, + notifyOnErrors: true, + poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions- + + + /** + * Source Maps + */ + + // https://webpack.js.org/configuration/devtool/#development + devtool: 'cheap-module-eval-source-map', + + // If you have problems debugging vue-files in devtools, + // set this to false - it *may* help + // https://vue-loader.vuejs.org/en/options.html#cachebusting + cacheBusting: true, + + cssSourceMap: true + }, + + build: { + // Template for index.html + index: path.resolve(__dirname, '../dist/index.html'), + + // Paths + assetsRoot: path.resolve(__dirname, '../dist'), + assetsSubDirectory: 'static', + assetsPublicPath: '/', + + /** + * Source Maps + */ + + productionSourceMap: true, + // https://webpack.js.org/configuration/devtool/#production + devtool: '#source-map', + + // Gzip off by default as many popular static hosts such as + // Surge or Netlify already gzip all static assets for you. + // Before setting to `true`, make sure to: + // npm install --save-dev compression-webpack-plugin + productionGzip: false, + productionGzipExtensions: ['js', 'css'], + + // Run the build command with an extra argument to + // View the bundle analyzer report after build finishes: + // `npm run build --report` + // Set to `true` or `false` to always turn it on or off + bundleAnalyzerReport: process.env.npm_config_report + } +} diff --git a/extensions/dataease-extensions-datasource/presto/presto-frontend/config/prod.env.js b/extensions/dataease-extensions-datasource/presto/presto-frontend/config/prod.env.js new file mode 100644 index 0000000000..a6f997616e --- /dev/null +++ b/extensions/dataease-extensions-datasource/presto/presto-frontend/config/prod.env.js @@ -0,0 +1,4 @@ +'use strict' +module.exports = { + NODE_ENV: '"production"' +} diff --git a/extensions/dataease-extensions-datasource/presto/presto-frontend/index.html b/extensions/dataease-extensions-datasource/presto/presto-frontend/index.html new file mode 100644 index 0000000000..03ce3fdf27 --- /dev/null +++ b/extensions/dataease-extensions-datasource/presto/presto-frontend/index.html @@ -0,0 +1,12 @@ + + + + + + deplugin-view-frontend + + +
+ + + diff --git a/extensions/dataease-extensions-datasource/presto/presto-frontend/package.json b/extensions/dataease-extensions-datasource/presto/presto-frontend/package.json new file mode 100644 index 0000000000..64a3ce7ad6 --- /dev/null +++ b/extensions/dataease-extensions-datasource/presto/presto-frontend/package.json @@ -0,0 +1,75 @@ +{ + "name": "deplugin-datasource-frontend", + "version": "1.0.0", + "description": "A Vue.js project", + "author": "", + "private": true, + "scripts": { + "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js", + "start": "npm run dev", + "build": "node build/build.js", + "buildPlugin": "node build/build-async-plugins.js" + }, + "dependencies": { + "@riophae/vue-treeselect": "0.4.0", + "highcharts": "^10.0.0", + "svg-sprite-loader": "^6.0.11", + "svgo": "1.2.2", + "svgo-loader": "^3.0.1", + "vue": "^2.5.2", + "vue-i18n": "7.3.2", + "vue-router": "^3.0.1", + "vue-uuid": "2.0.2", + "vuedraggable": "^2.24.3" + }, + "devDependencies": { + "autoprefixer": "^7.1.2", + "babel-core": "^6.22.1", + "babel-helper-vue-jsx-merge-props": "^2.0.3", + "babel-loader": "^7.1.1", + "babel-plugin-syntax-jsx": "^6.18.0", + "babel-plugin-transform-runtime": "^6.22.0", + "babel-plugin-transform-vue-jsx": "^3.5.0", + "babel-preset-env": "^1.3.2", + "babel-preset-stage-2": "^6.22.0", + "chalk": "^2.0.1", + "copy-webpack-plugin": "^4.6.0", + "css-loader": "^0.28.0", + "element-ui": "2.15.7", + "extract-text-webpack-plugin": "^4.0.0-beta.0", + "file-loader": "^1.1.4", + "friendly-errors-webpack-plugin": "^1.6.1", + "html-webpack-plugin": "^3.2.0", + "js-cookie": "2.2.0", + "node-notifier": "^8.0.1", + "optimize-css-assets-webpack-plugin": "^3.2.0", + "ora": "^1.2.0", + "portfinder": "^1.0.13", + "postcss-import": "^11.0.0", + "postcss-loader": "^2.0.8", + "postcss-url": "^7.2.1", + "rimraf": "^2.6.0", + "sass": "^1.33.0", + "sass-loader": "^7.3.1", + "semver": "^5.3.0", + "shelljs": "^0.8.5", + "uglifyjs-webpack-plugin": "^1.1.1", + "url-loader": "^0.5.8", + "vue-loader": "^15.6.4", + "vue-style-loader": "^4.1.2", + "vue-template-compiler": "^2.5.2", + "webpack": "^4.8.1", + "webpack-bundle-analyzer": "^3.3.2", + "webpack-dev-server": "^3.1.11", + "webpack-merge": "^4.1.0" + }, + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + }, + "browserslist": [ + "> 1%", + "last 2 versions", + "not ie <= 8" + ] +} diff --git a/extensions/dataease-extensions-datasource/presto/presto-frontend/pom.xml b/extensions/dataease-extensions-datasource/presto/presto-frontend/pom.xml new file mode 100644 index 0000000000..ecdd508d28 --- /dev/null +++ b/extensions/dataease-extensions-datasource/presto/presto-frontend/pom.xml @@ -0,0 +1,80 @@ + + + + + io.dataease + presto + ${dataease.version} + + + 4.0.0 + presto-frontend + + + UTF-8 + UTF-8 + 1.9.1 + + + + + + maven-clean-plugin + + + + static + + ** + + false + + + + + + + + com.github.eirslett + frontend-maven-plugin + ${frontend-maven-plugin.version} + + + install node and npm + + install-node-and-npm + + + + v16.20.2 + 7.6.3 + + + + + npm install + + npm + + + + install --force + + + + + npm run buildPlugin + + npm + + + run buildPlugin + + + + + + + diff --git a/extensions/dataease-extensions-datasource/presto/presto-frontend/src/App.vue b/extensions/dataease-extensions-datasource/presto/presto-frontend/src/App.vue new file mode 100644 index 0000000000..8542e07722 --- /dev/null +++ b/extensions/dataease-extensions-datasource/presto/presto-frontend/src/App.vue @@ -0,0 +1,23 @@ + + + + + diff --git a/extensions/dataease-extensions-datasource/presto/presto-frontend/src/assets/logo.png b/extensions/dataease-extensions-datasource/presto/presto-frontend/src/assets/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..f3d2503fc2a44b5053b0837ebea6e87a2d339a43 GIT binary patch literal 6849 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 +
+

{{ msg }}

+

Essential Links

+ +

Ecosystem

+ +
+ + + + + + diff --git a/extensions/dataease-extensions-datasource/presto/presto-frontend/src/de-base/lang/en.js b/extensions/dataease-extensions-datasource/presto/presto-frontend/src/de-base/lang/en.js new file mode 100644 index 0000000000..ddb290ce52 --- /dev/null +++ b/extensions/dataease-extensions-datasource/presto/presto-frontend/src/de-base/lang/en.js @@ -0,0 +1,20 @@ +export default { + plugin_view_3d_pie: { + type_title: '3D-PIE', + label: 'Label', + angle: 'Angle' + }, + host: 'Host', + port: 'Port', + dataBase: 'Catalog', + schema: 'Schema', + username: 'User', + password: 'Password', + query_timeout: 'Query timeout (seconds)', + second: 'second', + please_select: 'Please select', + query_timeout: 'query timeout', + enter_the_port: 'Please enter the port', + one_user_name: 'enter one user name', + input_a_password: 'Please input a password' +} diff --git a/extensions/dataease-extensions-datasource/presto/presto-frontend/src/de-base/lang/index.js b/extensions/dataease-extensions-datasource/presto/presto-frontend/src/de-base/lang/index.js new file mode 100644 index 0000000000..e50d0478e6 --- /dev/null +++ b/extensions/dataease-extensions-datasource/presto/presto-frontend/src/de-base/lang/index.js @@ -0,0 +1,49 @@ +import Vue from 'vue' +import VueI18n from 'vue-i18n' +import Cookies from 'js-cookie' +import elementEnLocale from 'element-ui/lib/locale/lang/en' // element-ui lang +import elementZhLocale from 'element-ui/lib/locale/lang/zh-CN'// element-ui lang +import elementTWLocale from 'element-ui/lib/locale/lang/zh-TW'// element-ui lang + +import localMessages from './messages' + + +Vue.use(VueI18n) + +const messages = { + en_US: { + ...localMessages['en_US'], + ...elementEnLocale + }, + zh_CN: { + ...localMessages['zh_CN'], + ...elementZhLocale + }, + zh_TW: { + ...localMessages['zh_TW'], + ...elementTWLocale + } +} +export function getLanguage () { + const chooseLanguage = Cookies.get('language') + if (chooseLanguage) return chooseLanguage + + // if has not choose language + const language = (navigator.language || navigator.browserLanguage).toLowerCase() + const locales = Object.keys(messages) + for (const locale of locales) { + if (language.indexOf(locale) > -1) { + return locale + } + } + return 'zh_CN' +} +const i18n = new VueI18n({ + // set locale + // options: en | zh | es + locale: getLanguage(), + // set locale messages + messages +}) + +export default i18n diff --git a/extensions/dataease-extensions-datasource/presto/presto-frontend/src/de-base/lang/messages.js b/extensions/dataease-extensions-datasource/presto/presto-frontend/src/de-base/lang/messages.js new file mode 100644 index 0000000000..844f8c0673 --- /dev/null +++ b/extensions/dataease-extensions-datasource/presto/presto-frontend/src/de-base/lang/messages.js @@ -0,0 +1,17 @@ +import enLocale from './en' +import zhLocale from './zh' +import twLocale from './tw' + +const messages = { + en_US: { + ...enLocale + }, + zh_CN: { + ...zhLocale + }, + zh_TW: { + ...twLocale + } +} + +export default messages \ No newline at end of file diff --git a/extensions/dataease-extensions-datasource/presto/presto-frontend/src/de-base/lang/tw.js b/extensions/dataease-extensions-datasource/presto/presto-frontend/src/de-base/lang/tw.js new file mode 100644 index 0000000000..032938d07f --- /dev/null +++ b/extensions/dataease-extensions-datasource/presto/presto-frontend/src/de-base/lang/tw.js @@ -0,0 +1,20 @@ +export default { + plugin_view_3d_pie: { + type_title: '3D餅圖', + label: '標籤', + angle: '角度' + }, + host: '主機名', + port: '端口', + dataBase: '數據庫', + schema: 'Schema', + username: '用戶名', + password: '密碼', + query_timeout: '査詢超時(秒)', + second: '秒', + please_select: '請選擇', + query_timeout: '査詢超時', + enter_the_port: '請輸入埠', + one_user_name: '請輸入用戶名', + input_a_password: '請輸入密碼' +} diff --git a/extensions/dataease-extensions-datasource/presto/presto-frontend/src/de-base/lang/zh.js b/extensions/dataease-extensions-datasource/presto/presto-frontend/src/de-base/lang/zh.js new file mode 100644 index 0000000000..2e0294a68c --- /dev/null +++ b/extensions/dataease-extensions-datasource/presto/presto-frontend/src/de-base/lang/zh.js @@ -0,0 +1,20 @@ +export default { + plugin_view_3d_pie: { + type_title: '3D饼图', + label: '标签', + angle: '角度' + }, + host: '主机名', + port: '端口', + dataBase: '数据库', + schema: 'Schema', + username: '用户名', + password: '密码', + query_timeout: '查询超时(秒)', + second: '秒', + please_select: '请选择', + query_timeout: '查询超时', + enter_the_port: '请输入端口', + one_user_name: '请输入用户名', + input_a_password: '请输入密码' +} diff --git a/extensions/dataease-extensions-datasource/presto/presto-frontend/src/icons/index.js b/extensions/dataease-extensions-datasource/presto/presto-frontend/src/icons/index.js new file mode 100644 index 0000000000..2c6b309c96 --- /dev/null +++ b/extensions/dataease-extensions-datasource/presto/presto-frontend/src/icons/index.js @@ -0,0 +1,9 @@ +import Vue from 'vue' +import SvgIcon from '@/components/SvgIcon'// svg component + +// register globally +Vue.component('svg-icon', SvgIcon) + +const req = require.context('./svg', false, /\.svg$/) +const requireAll = requireContext => requireContext.keys().map(requireContext) +requireAll(req) diff --git a/extensions/dataease-extensions-datasource/presto/presto-frontend/src/icons/svg/de_pwd_invisible.svg b/extensions/dataease-extensions-datasource/presto/presto-frontend/src/icons/svg/de_pwd_invisible.svg new file mode 100644 index 0000000000..661ebba33e --- /dev/null +++ b/extensions/dataease-extensions-datasource/presto/presto-frontend/src/icons/svg/de_pwd_invisible.svg @@ -0,0 +1,3 @@ + + + diff --git a/extensions/dataease-extensions-datasource/presto/presto-frontend/src/icons/svg/de_pwd_visible.svg b/extensions/dataease-extensions-datasource/presto/presto-frontend/src/icons/svg/de_pwd_visible.svg new file mode 100644 index 0000000000..4e7ba5e799 --- /dev/null +++ b/extensions/dataease-extensions-datasource/presto/presto-frontend/src/icons/svg/de_pwd_visible.svg @@ -0,0 +1,3 @@ + + + diff --git a/extensions/dataease-extensions-datasource/presto/presto-frontend/src/icons/svg/presto-backend.svg b/extensions/dataease-extensions-datasource/presto/presto-frontend/src/icons/svg/presto-backend.svg new file mode 100644 index 0000000000..0612c80c26 --- /dev/null +++ b/extensions/dataease-extensions-datasource/presto/presto-frontend/src/icons/svg/presto-backend.svg @@ -0,0 +1 @@ +【icon】插件管理-导出 diff --git a/extensions/dataease-extensions-datasource/presto/presto-frontend/src/icons/svg/presto.jpg b/extensions/dataease-extensions-datasource/presto/presto-frontend/src/icons/svg/presto.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f1193f0b3e625a86af81e3a475003644d1b6f348 GIT binary patch literal 9532 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 BA1VL< literal 0 HcmV?d00001 diff --git a/extensions/dataease-extensions-datasource/presto/presto-frontend/src/icons/svgo.yml b/extensions/dataease-extensions-datasource/presto/presto-frontend/src/icons/svgo.yml new file mode 100644 index 0000000000..d11906aec2 --- /dev/null +++ b/extensions/dataease-extensions-datasource/presto/presto-frontend/src/icons/svgo.yml @@ -0,0 +1,22 @@ +# replace default config + +# multipass: true +# full: true + +plugins: + + # - name + # + # or: + # - name: false + # - name: true + # + # or: + # - name: + # param1: 1 + # param2: 2 + +- removeAttrs: + attrs: + - 'fill' + - 'fill-rule' diff --git a/extensions/dataease-extensions-datasource/presto/presto-frontend/src/main.js b/extensions/dataease-extensions-datasource/presto/presto-frontend/src/main.js new file mode 100644 index 0000000000..99c5626590 --- /dev/null +++ b/extensions/dataease-extensions-datasource/presto/presto-frontend/src/main.js @@ -0,0 +1,33 @@ +// The Vue build version to load with the `import` command +// (runtime-only or standalone) has been set in webpack.base.conf with an alias. +import Vue from 'vue' +import App from './App' +import router from './router' +import ElementUI from 'element-ui' +import Cookies from 'js-cookie' +import i18n from './de-base/lang' +import draggable from 'vuedraggable' +import Treeselect from '@riophae/vue-treeselect' +import '@riophae/vue-treeselect/dist/vue-treeselect.css' +Vue.config.productionTip = false +Vue.use(ElementUI, { + size: Cookies.get('size') || 'medium', + i18n: (key, value) => i18n.t(key, value) +}) +Vue.component('Treeselect', Treeselect) +Vue.component('draggable', draggable) +Vue.prototype.hasDataPermission = function(pTarget, pSource) { + + if (pSource && pTarget) { + return pSource.indexOf(pTarget) > -1 + } + return false +} +/* eslint-disable no-new */ +new Vue({ + el: '#app', + router, + i18n, + components: { App }, + template: '' +}) diff --git a/extensions/dataease-extensions-datasource/presto/presto-frontend/src/router/index.js b/extensions/dataease-extensions-datasource/presto/presto-frontend/src/router/index.js new file mode 100644 index 0000000000..b5b55fa1fc --- /dev/null +++ b/extensions/dataease-extensions-datasource/presto/presto-frontend/src/router/index.js @@ -0,0 +1,21 @@ +import Vue from 'vue' +import Router from 'vue-router' +import HelloWorld from '@/components/HelloWorld' +import maxcompute from '@/views/maxcompute' + +Vue.use(Router) + +export default new Router({ + routes: [ + { + path: '/', + name: 'HelloWorld', + component: HelloWorld + }, + { + path: '/maxcompute', + name: 'maxcompute', + component: maxcompute + } + ] +}) diff --git a/extensions/dataease-extensions-datasource/presto/presto-frontend/src/utils/compare.js b/extensions/dataease-extensions-datasource/presto/presto-frontend/src/utils/compare.js new file mode 100644 index 0000000000..b06a104a10 --- /dev/null +++ b/extensions/dataease-extensions-datasource/presto/presto-frontend/src/utils/compare.js @@ -0,0 +1,29 @@ +export const compareItem = { + type: 'none', // year-yoy/month-yoy等 + resultData: 'percent', // 对比差sub,百分比percent等 + field: '', + custom: { + field: '', + calcType: '0', // 0-增长值,1-增长率 + timeType: '0', // 0-固定日期,1-日期区间 + currentTime: '', + compareTime: '', + currentTimeRange: [], + compareTimeRange: [] + } +} + +export const compareYearList = [ + { name: 'year_mom', value: 'year_mom' } +] + +export const compareMonthList = [ + { name: 'month_mom', value: 'month_mom' }, + { name: 'year_yoy', value: 'year_yoy' } +] + +export const compareDayList = [ + { name: 'day_mom', value: 'day_mom' }, + { name: 'month_yoy', value: 'month_yoy' }, + { name: 'year_yoy', value: 'year_yoy' } +] diff --git a/extensions/dataease-extensions-datasource/presto/presto-frontend/src/utils/validate.js b/extensions/dataease-extensions-datasource/presto/presto-frontend/src/utils/validate.js new file mode 100644 index 0000000000..3e8ffa9448 --- /dev/null +++ b/extensions/dataease-extensions-datasource/presto/presto-frontend/src/utils/validate.js @@ -0,0 +1,15 @@ +/** + * Created by PanJiaChen on 16/11/18. + */ + +/** + * @param {string} path + * @returns {Boolean} + */ +export function isExternal(path) { + return /^(https?:|mailto:|tel:)/.test(path) || /^(http?:|mailto:|tel:)/.test(path) || path.startsWith('/api/pluginCommon/staticInfo') +} + + + + diff --git a/extensions/dataease-extensions-datasource/presto/presto-frontend/src/views/dePwd.vue b/extensions/dataease-extensions-datasource/presto/presto-frontend/src/views/dePwd.vue new file mode 100644 index 0000000000..61bf3e88ee --- /dev/null +++ b/extensions/dataease-extensions-datasource/presto/presto-frontend/src/views/dePwd.vue @@ -0,0 +1,75 @@ + + + + \ No newline at end of file diff --git a/extensions/dataease-extensions-datasource/presto/presto-frontend/src/views/presto.vue b/extensions/dataease-extensions-datasource/presto/presto-frontend/src/views/presto.vue new file mode 100644 index 0000000000..a1d2aa15f7 --- /dev/null +++ b/extensions/dataease-extensions-datasource/presto/presto-frontend/src/views/presto.vue @@ -0,0 +1,167 @@ + + + + + diff --git a/extensions/dataease-extensions-view/pom.xml b/extensions/dataease-extensions-view/pom.xml new file mode 100644 index 0000000000..0df3753f94 --- /dev/null +++ b/extensions/dataease-extensions-view/pom.xml @@ -0,0 +1,24 @@ + + + + dataease-extensions + io.dataease + ${dataease.version} + + 4.0.0 + pom + + view-bubblemap + view-3dpie + view-symbolmap + view-sankey + view-chartmix + view-racebar + + + dataease-extensions-view + + + diff --git a/extensions/dataease-extensions-view/view-3dpie/build.sh b/extensions/dataease-extensions-view/view-3dpie/build.sh new file mode 100644 index 0000000000..738ec8be7d --- /dev/null +++ b/extensions/dataease-extensions-view/view-3dpie/build.sh @@ -0,0 +1,8 @@ +#!/bin/sh +mvn clean package + +cp view-3dpie-backend/target/view-3dpie-backend-1.18.3.jar . + +zip -r 3dpie.zip ./view-3dpie-backend-1.18.3.jar ./plugin.json + +rm -f ./view-3dpie-backend-1.18.3.jar diff --git a/extensions/dataease-extensions-view/view-3dpie/plugin.json b/extensions/dataease-extensions-view/view-3dpie/plugin.json new file mode 100644 index 0000000000..1151b075c4 --- /dev/null +++ b/extensions/dataease-extensions-view/view-3dpie/plugin.json @@ -0,0 +1,13 @@ +{ + "name": "3D 饼图插件", + "free": 0, + "store": "thirdpart", + "cost": 0, + "category": "view", + "descript": "High Chart 3D 饼图插件", + "version": "1.18.3", + "creator": "DATAEASE", + "moduleName": "view-3dpie-backend", + "require": "1.10.0", + "dsType": "" +} \ No newline at end of file diff --git a/extensions/dataease-extensions-view/view-3dpie/pom.xml b/extensions/dataease-extensions-view/view-3dpie/pom.xml new file mode 100644 index 0000000000..0d0c0f335a --- /dev/null +++ b/extensions/dataease-extensions-view/view-3dpie/pom.xml @@ -0,0 +1,19 @@ + + + + dataease-extensions-view + io.dataease + ${dataease.version} + + 4.0.0 + + view-3dpie + pom + + view-3dpie-frontend + view-3dpie-backend + + + diff --git a/extensions/dataease-extensions-view/view-3dpie/view-3dpie-backend/pom.xml b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-backend/pom.xml new file mode 100644 index 0000000000..18bd300376 --- /dev/null +++ b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-backend/pom.xml @@ -0,0 +1,109 @@ + + + + view-3dpie + io.dataease + ${dataease.version} + + 4.0.0 + + view-3dpie-backend + + + + io.dataease + dataease-plugin-view + + + + + + + src/main/java + + **/*.properties + **/*.xml + + false + + + src/main/resources + + **/* + + false + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 11 + 11 + + + + + org.apache.maven.plugins + maven-jar-plugin + 2.4 + + + **/server/** + **/*.properties + **/Application* + + + + + + maven-clean-plugin + + + + src/main/resources/static + + ** + + false + + + + + + + + + org.apache.maven.plugins + maven-antrun-plugin + + + main-class-placement + generate-resources + + + + + + + + + + + + run + + + + + + + + + + + diff --git a/extensions/dataease-extensions-view/view-3dpie/view-3dpie-backend/src/main/java/io/dataease/plugins/view/official/impl/Pie3DService.java b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-backend/src/main/java/io/dataease/plugins/view/official/impl/Pie3DService.java new file mode 100644 index 0000000000..8b0914b20b --- /dev/null +++ b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-backend/src/main/java/io/dataease/plugins/view/official/impl/Pie3DService.java @@ -0,0 +1,88 @@ +package io.dataease.plugins.view.official.impl; + +import io.dataease.plugins.common.dto.StaticResource; +import io.dataease.plugins.view.entity.PluginViewField; +import io.dataease.plugins.view.entity.PluginViewParam; +import io.dataease.plugins.view.entity.PluginViewType; +import io.dataease.plugins.view.service.ViewPluginService; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.stereotype.Service; + +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + +@Service +public class Pie3DService extends ViewPluginService { + + private static final String VIEW_TYPE_VALUE = "3d-pie"; + /*下版这些常量移到sdk*/ + private static final String TYPE = "-type"; + private static final String DATA = "-data"; + private static final String STYLE = "-style"; + private static final String VIEW = "-view"; + private static final String SUFFIX = "svg"; + /*下版这些常量移到sdk*/ + private static final String VIEW_TYPE = VIEW_TYPE_VALUE + TYPE; + private static final String VIEW_DATA = VIEW_TYPE_VALUE + DATA; + private static final String VIEW_STYLE = VIEW_TYPE_VALUE + STYLE; + private static final String VIEW_VIEW = VIEW_TYPE_VALUE + VIEW; + + @Override + public PluginViewType viewType() { + PluginViewType pluginViewType = new PluginViewType(); + pluginViewType.setRender("highcharts"); + pluginViewType.setCategory("chart.chart_type_distribute"); + pluginViewType.setValue(VIEW_TYPE_VALUE); + return pluginViewType; + } + + @Override + public Object format(Object o) { + return null; + } + + @Override + public List components() { + List results = new ArrayList<>(); + results.add(VIEW_VIEW); + results.add(VIEW_DATA); + results.add(VIEW_TYPE); + results.add(VIEW_STYLE); + return results; + } + + @Override + public List staticResources() { + List results = new ArrayList<>(); + StaticResource staticResource = new StaticResource(); + staticResource.setName(VIEW_TYPE_VALUE); + staticResource.setSuffix(SUFFIX); + results.add(staticResource); + results.add(pluginSvg()); + return results; + } + + private StaticResource pluginSvg() { + StaticResource staticResource = new StaticResource(); + staticResource.setName("view-3dpie-backend"); + staticResource.setSuffix("svg"); + return staticResource; + } + + @Override + protected InputStream readContent(String s) { + InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream("static/" + s); + return resourceAsStream; + } + + @Override + public String generateSQL(PluginViewParam param) { + List xAxis = param.getFieldsByType("xAxis"); + List yAxis = param.getFieldsByType("yAxis"); + if (CollectionUtils.isEmpty(xAxis) || CollectionUtils.isEmpty(yAxis)){ + return null; + } + return super.generateSQL(param); + } +} diff --git a/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/.babelrc b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/.babelrc new file mode 100644 index 0000000000..3a280ba34b --- /dev/null +++ b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/.babelrc @@ -0,0 +1,12 @@ +{ + "presets": [ + ["env", { + "modules": false, + "targets": { + "browsers": ["> 1%", "last 2 versions", "not ie <= 8"] + } + }], + "stage-2" + ], + "plugins": ["transform-vue-jsx", "transform-runtime"] +} diff --git a/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/.editorconfig b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/.editorconfig new file mode 100644 index 0000000000..9d08a1a828 --- /dev/null +++ b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/.editorconfig @@ -0,0 +1,9 @@ +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true diff --git a/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/.gitignore b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/.gitignore new file mode 100644 index 0000000000..541a820f6c --- /dev/null +++ b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/.gitignore @@ -0,0 +1,14 @@ +.DS_Store +node_modules/ +/dist/ +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Editor directories and files +.idea +.vscode +*.suo +*.ntvs* +*.njsproj +*.sln diff --git a/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/.postcssrc.js b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/.postcssrc.js new file mode 100644 index 0000000000..eee3e92d7f --- /dev/null +++ b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/.postcssrc.js @@ -0,0 +1,10 @@ +// https://github.com/michael-ciniawsky/postcss-load-config + +module.exports = { + "plugins": { + "postcss-import": {}, + "postcss-url": {}, + // to edit target browsers: use "browserslist" field in package.json + "autoprefixer": {} + } +} diff --git a/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/README.md b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/README.md new file mode 100644 index 0000000000..c1e4be95e0 --- /dev/null +++ b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/README.md @@ -0,0 +1,21 @@ +# deplugin-view-frontend + +> A Vue.js project + +## Build Setup + +``` bash +# install dependencies +npm install + +# serve with hot reload at localhost:8080 +npm run dev + +# build for production with minification +npm run build + +# build for production and view the bundle analyzer report +npm run build --report +``` + +For a detailed explanation on how things work, check out the [guide](http://vuejs-templates.github.io/webpack/) and [docs for vue-loader](http://vuejs.github.io/vue-loader). diff --git a/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/build/build-async-plugins.js b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/build/build-async-plugins.js new file mode 100644 index 0000000000..2303854531 --- /dev/null +++ b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/build/build-async-plugins.js @@ -0,0 +1,35 @@ +'use strict' +require('./check-versions')() + +process.env.NODE_ENV = 'production' + +const ora = require('ora') +const chalk = require('chalk') +const webpack = require('webpack') +const webpackConfig = require('./webpack.async-plugins') + +const spinner = ora('building for sync-plugins...') +spinner.start() + +webpack(webpackConfig, function (err, stats) { + spinner.stop() + if (err) throw err + process.stdout.write(stats.toString({ + colors: true, + modules: false, + children: false, + chunks: false, + chunkModules: false + }) + '\n\n') + + if (stats.hasErrors()) { + console.log(chalk.red(' Build failed with errors.\n')) + process.exit(1) + } + + console.log(chalk.cyan(' Build complete.\n')) + console.log(chalk.yellow( + ' Tip: built files are meant to be served over an HTTP server.\n' + + ' Opening index.html over file:// won\'t work.\n' + )) +}) diff --git a/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/build/build.js b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/build/build.js new file mode 100644 index 0000000000..8f2ad8ad49 --- /dev/null +++ b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/build/build.js @@ -0,0 +1,41 @@ +'use strict' +require('./check-versions')() + +process.env.NODE_ENV = 'production' + +const ora = require('ora') +const rm = require('rimraf') +const path = require('path') +const chalk = require('chalk') +const webpack = require('webpack') +const config = require('../config') +const webpackConfig = require('./webpack.prod.conf') + +const spinner = ora('building for production...') +spinner.start() + +rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => { + if (err) throw err + webpack(webpackConfig, (err, stats) => { + spinner.stop() + if (err) throw err + process.stdout.write(stats.toString({ + colors: true, + modules: false, + children: false, // If you are using ts-loader, setting this to true will make TypeScript errors show up during build. + chunks: false, + chunkModules: false + }) + '\n\n') + + if (stats.hasErrors()) { + console.log(chalk.red(' Build failed with errors.\n')) + process.exit(1) + } + + console.log(chalk.cyan(' Build complete.\n')) + console.log(chalk.yellow( + ' Tip: built files are meant to be served over an HTTP server.\n' + + ' Opening index.html over file:// won\'t work.\n' + )) + }) +}) diff --git a/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/build/check-versions.js b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/build/check-versions.js new file mode 100644 index 0000000000..3ef972a08d --- /dev/null +++ b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/build/check-versions.js @@ -0,0 +1,54 @@ +'use strict' +const chalk = require('chalk') +const semver = require('semver') +const packageConfig = require('../package.json') +const shell = require('shelljs') + +function exec (cmd) { + return require('child_process').execSync(cmd).toString().trim() +} + +const versionRequirements = [ + { + name: 'node', + currentVersion: semver.clean(process.version), + versionRequirement: packageConfig.engines.node + } +] + +if (shell.which('npm')) { + versionRequirements.push({ + name: 'npm', + currentVersion: exec('npm --version'), + versionRequirement: packageConfig.engines.npm + }) +} + +module.exports = function () { + const warnings = [] + + for (let i = 0; i < versionRequirements.length; i++) { + const mod = versionRequirements[i] + + if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) { + warnings.push(mod.name + ': ' + + chalk.red(mod.currentVersion) + ' should be ' + + chalk.green(mod.versionRequirement) + ) + } + } + + if (warnings.length) { + console.log('') + console.log(chalk.yellow('To use this template, you must update following to modules:')) + console.log() + + for (let i = 0; i < warnings.length; i++) { + const warning = warnings[i] + console.log(' ' + warning) + } + + console.log() + process.exit(1) + } +} diff --git a/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/build/logo.png b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/build/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..f3d2503fc2a44b5053b0837ebea6e87a2d339a43 GIT binary patch literal 6849 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 { + const notifier = require('node-notifier') + + return (severity, errors) => { + if (severity !== 'error') return + + const error = errors[0] + const filename = error.file && error.file.split('!').pop() + + notifier.notify({ + title: packageConfig.name, + message: severity + ': ' + error.name, + subtitle: filename || '', + icon: path.join(__dirname, 'logo.png') + }) + } +} diff --git a/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/build/vue-loader.conf.js b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/build/vue-loader.conf.js new file mode 100644 index 0000000000..33ed58bc0a --- /dev/null +++ b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/build/vue-loader.conf.js @@ -0,0 +1,22 @@ +'use strict' +const utils = require('./utils') +const config = require('../config') +const isProduction = process.env.NODE_ENV === 'production' +const sourceMapEnabled = isProduction + ? config.build.productionSourceMap + : config.dev.cssSourceMap + +module.exports = { + loaders: utils.cssLoaders({ + sourceMap: sourceMapEnabled, + extract: isProduction + }), + cssSourceMap: sourceMapEnabled, + cacheBusting: config.dev.cacheBusting, + transformToRequire: { + video: ['src', 'poster'], + source: 'src', + img: 'src', + image: 'xlink:href' + } +} diff --git a/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/build/webpack.async-plugins.js b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/build/webpack.async-plugins.js new file mode 100644 index 0000000000..2f67ecbe56 --- /dev/null +++ b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/build/webpack.async-plugins.js @@ -0,0 +1,97 @@ +const webpack = require('webpack') +const path = require('path') +const utils = require('./utils') +const CopyPlugin = require("copy-webpack-plugin"); +const VueLoaderPlugin = require('vue-loader/lib/plugin'); +function resolve (dir) { + return path.join(__dirname, '..', dir) +} + +module.exports = { + mode: 'development', + entry: { + + // PluginDemo: resolve('/src/views/PluginDemo.vue') + '3d-pie-view': resolve('/src/views/highcharts/3dpie/index.vue'), + '3d-pie-data': resolve('/src/views/highcharts/3dpie/data.vue'), + '3d-pie-type': resolve('/src/views/highcharts/3dpie/type.vue'), + '3d-pie-style': resolve('/src/views/highcharts/3dpie/style.vue') + + }, + output: { + path: resolve('/static/'), + filename: '[name].js' + }, + resolve: { + extensions: ['.js', '.vue', '.json'], + alias: { + 'vue$': 'vue/dist/vue.esm.js', + '@': resolve('src') + } + }, + externals: { + vue: 'vue' + }, + module: { + rules: [ + { + test: /\.vue$/, + loader: 'vue-loader', + options: { + transformAssetUrls: { + video: 'src', + source: 'src', + img: 'src', + image: 'xlink:href' + } + } + }, + { + test: /.(sa|sc|c)ss$/, + use: [ + {loader: 'vue-style-loader'}, + 'css-loader', + 'sass-loader' + ] + }, + { + test: /\.js$/, + loader: 'babel-loader', + include: [resolve('src'), resolve('test')] + }, + { + test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: utils.assetsPath('img/[name].[hash:7].[ext]') + } + }, + { + test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: utils.assetsPath('media/[name].[hash:7].[ext]') + } + }, + { + test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: utils.assetsPath('fonts/[name].[hash:7].[ext]') + } + } + ] + }, + plugins: [ + new VueLoaderPlugin(), + new webpack.DefinePlugin({ + 'process.env.NODE_ENV': '"production"' + }), + new CopyPlugin([ + {from: 'src/icons/svg/'} + ]), + ] +} diff --git a/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/build/webpack.base.conf.js b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/build/webpack.base.conf.js new file mode 100644 index 0000000000..6ccc02dab4 --- /dev/null +++ b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/build/webpack.base.conf.js @@ -0,0 +1,91 @@ +'use strict' +const path = require('path') +const utils = require('./utils') +const config = require('../config') +const vueLoaderConfig = require('./vue-loader.conf') + +function resolve (dir) { + return path.join(__dirname, '..', dir) +} + + + +module.exports = { + context: path.resolve(__dirname, '../'), + entry: { + app: './src/main.js' + }, + output: { + path: config.build.assetsRoot, + filename: '[name].js', + publicPath: process.env.NODE_ENV === 'production' + ? config.build.assetsPublicPath + : config.dev.assetsPublicPath + }, + resolve: { + extensions: ['.js', '.vue', '.json'], + alias: { + 'vue$': 'vue/dist/vue.esm.js', + '@': resolve('src'), + } + }, + module: { + rules: [ + { + test: /\.vue$/, + loader: 'vue-loader', + options: vueLoaderConfig + }, + { + test: /\.js$/, + loader: 'babel-loader', + include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')] + }, + { + test: /\.svg$/, + loader: 'svg-sprite-loader', + include: [resolve('src/icons')], + options: { + symbolId: 'icon-[name]' + } + }, + { + test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, + loader: 'url-loader', + exclude: [resolve('src/icons')], + options: { + limit: 10000, + name: utils.assetsPath('img/[name].[hash:7].[ext]') + } + }, + { + test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: utils.assetsPath('media/[name].[hash:7].[ext]') + } + }, + { + test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: utils.assetsPath('fonts/[name].[hash:7].[ext]') + } + } + ] + }, + node: { + // prevent webpack from injecting useless setImmediate polyfill because Vue + // source contains it (although only uses it if it's native). + setImmediate: false, + // prevent webpack from injecting mocks to Node native modules + // that does not make sense for the client + dgram: 'empty', + fs: 'empty', + net: 'empty', + tls: 'empty', + child_process: 'empty' + } +} diff --git a/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/build/webpack.dev.conf.js b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/build/webpack.dev.conf.js new file mode 100755 index 0000000000..070ae221f3 --- /dev/null +++ b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/build/webpack.dev.conf.js @@ -0,0 +1,95 @@ +'use strict' +const utils = require('./utils') +const webpack = require('webpack') +const config = require('../config') +const merge = require('webpack-merge') +const path = require('path') +const baseWebpackConfig = require('./webpack.base.conf') +const CopyWebpackPlugin = require('copy-webpack-plugin') +const HtmlWebpackPlugin = require('html-webpack-plugin') +const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin') +const portfinder = require('portfinder') + +const HOST = process.env.HOST +const PORT = process.env.PORT && Number(process.env.PORT) + +const devWebpackConfig = merge(baseWebpackConfig, { + module: { + rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true }) + }, + // cheap-module-eval-source-map is faster for development + devtool: config.dev.devtool, + + // these devServer options should be customized in /config/index.js + devServer: { + clientLogLevel: 'warning', + historyApiFallback: { + rewrites: [ + { from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') }, + ], + }, + hot: true, + contentBase: false, // since we use CopyWebpackPlugin. + compress: true, + host: HOST || config.dev.host, + port: PORT || config.dev.port, + open: config.dev.autoOpenBrowser, + overlay: config.dev.errorOverlay + ? { warnings: false, errors: true } + : false, + publicPath: config.dev.assetsPublicPath, + proxy: config.dev.proxyTable, + quiet: true, // necessary for FriendlyErrorsPlugin + watchOptions: { + poll: config.dev.poll, + } + }, + plugins: [ + new webpack.DefinePlugin({ + 'process.env': require('../config/dev.env') + }), + new webpack.HotModuleReplacementPlugin(), + new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update. + new webpack.NoEmitOnErrorsPlugin(), + // https://github.com/ampedandwired/html-webpack-plugin + new HtmlWebpackPlugin({ + filename: 'index.html', + template: 'index.html', + inject: true + }), + // copy custom static assets + new CopyWebpackPlugin([ + { + from: path.resolve(__dirname, '../static'), + to: config.dev.assetsSubDirectory, + ignore: ['.*'] + } + ]) + ] +}) + +module.exports = new Promise((resolve, reject) => { + portfinder.basePort = process.env.PORT || config.dev.port + portfinder.getPort((err, port) => { + if (err) { + reject(err) + } else { + // publish the new Port, necessary for e2e tests + process.env.PORT = port + // add port to devServer config + devWebpackConfig.devServer.port = port + + // Add FriendlyErrorsPlugin + devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({ + compilationSuccessInfo: { + messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`], + }, + onErrors: config.dev.notifyOnErrors + ? utils.createNotifierCallback() + : undefined + })) + + resolve(devWebpackConfig) + } + }) +}) diff --git a/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/build/webpack.prod.conf.js b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/build/webpack.prod.conf.js new file mode 100644 index 0000000000..3e25238ef6 --- /dev/null +++ b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/build/webpack.prod.conf.js @@ -0,0 +1,145 @@ +'use strict' +const path = require('path') +const utils = require('./utils') +const webpack = require('webpack') +const config = require('../config') +const merge = require('webpack-merge') +const baseWebpackConfig = require('./webpack.base.conf') +const CopyWebpackPlugin = require('copy-webpack-plugin') +const HtmlWebpackPlugin = require('html-webpack-plugin') +const ExtractTextPlugin = require('extract-text-webpack-plugin') +const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin') +const UglifyJsPlugin = require('uglifyjs-webpack-plugin') + +const env = require('../config/prod.env') + +const webpackConfig = merge(baseWebpackConfig, { + module: { + rules: utils.styleLoaders({ + sourceMap: config.build.productionSourceMap, + extract: true, + usePostCSS: true + }) + }, + devtool: config.build.productionSourceMap ? config.build.devtool : false, + output: { + path: config.build.assetsRoot, + filename: utils.assetsPath('js/[name].[chunkhash].js'), + chunkFilename: utils.assetsPath('js/[id].[chunkhash].js') + }, + plugins: [ + // http://vuejs.github.io/vue-loader/en/workflow/production.html + new webpack.DefinePlugin({ + 'process.env': env + }), + new UglifyJsPlugin({ + uglifyOptions: { + compress: { + warnings: false + } + }, + sourceMap: config.build.productionSourceMap, + parallel: true + }), + // extract css into its own file + new ExtractTextPlugin({ + filename: utils.assetsPath('css/[name].[contenthash].css'), + // Setting the following option to `false` will not extract CSS from codesplit chunks. + // Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack. + // It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`, + // increasing file size: https://github.com/vuejs-templates/webpack/issues/1110 + allChunks: true, + }), + // Compress extracted CSS. We are using this plugin so that possible + // duplicated CSS from different components can be deduped. + new OptimizeCSSPlugin({ + cssProcessorOptions: config.build.productionSourceMap + ? { safe: true, map: { inline: false } } + : { safe: true } + }), + // generate dist index.html with correct asset hash for caching. + // you can customize output by editing /index.html + // see https://github.com/ampedandwired/html-webpack-plugin + new HtmlWebpackPlugin({ + filename: config.build.index, + template: 'index.html', + inject: true, + minify: { + removeComments: true, + collapseWhitespace: true, + removeAttributeQuotes: true + // more options: + // https://github.com/kangax/html-minifier#options-quick-reference + }, + // necessary to consistently work with multiple chunks via CommonsChunkPlugin + chunksSortMode: 'dependency' + }), + // keep module.id stable when vendor modules does not change + new webpack.HashedModuleIdsPlugin(), + // enable scope hoisting + new webpack.optimize.ModuleConcatenationPlugin(), + // split vendor js into its own file + new webpack.optimize.CommonsChunkPlugin({ + name: 'vendor', + minChunks (module) { + // any required modules inside node_modules are extracted to vendor + return ( + module.resource && + /\.js$/.test(module.resource) && + module.resource.indexOf( + path.join(__dirname, '../node_modules') + ) === 0 + ) + } + }), + // extract webpack runtime and module manifest to its own file in order to + // prevent vendor hash from being updated whenever app bundle is updated + new webpack.optimize.CommonsChunkPlugin({ + name: 'manifest', + minChunks: Infinity + }), + // This instance extracts shared chunks from code split chunks and bundles them + // in a separate chunk, similar to the vendor chunk + // see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk + new webpack.optimize.CommonsChunkPlugin({ + name: 'app', + async: 'vendor-async', + children: true, + minChunks: 3 + }), + + // copy custom static assets + new CopyWebpackPlugin([ + { + from: path.resolve(__dirname, '../static'), + to: config.build.assetsSubDirectory, + ignore: ['.*'] + } + ]) + ] +}) + +if (config.build.productionGzip) { + const CompressionWebpackPlugin = require('compression-webpack-plugin') + + webpackConfig.plugins.push( + new CompressionWebpackPlugin({ + asset: '[path].gz[query]', + algorithm: 'gzip', + test: new RegExp( + '\\.(' + + config.build.productionGzipExtensions.join('|') + + ')$' + ), + threshold: 10240, + minRatio: 0.8 + }) + ) +} + +if (config.build.bundleAnalyzerReport) { + const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin + webpackConfig.plugins.push(new BundleAnalyzerPlugin()) +} + +module.exports = webpackConfig diff --git a/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/config/dev.env.js b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/config/dev.env.js new file mode 100644 index 0000000000..1e22973ae7 --- /dev/null +++ b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/config/dev.env.js @@ -0,0 +1,7 @@ +'use strict' +const merge = require('webpack-merge') +const prodEnv = require('./prod.env') + +module.exports = merge(prodEnv, { + NODE_ENV: '"development"' +}) diff --git a/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/config/index.js b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/config/index.js new file mode 100644 index 0000000000..c5eded7f81 --- /dev/null +++ b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/config/index.js @@ -0,0 +1,69 @@ +'use strict' +// Template version: 1.3.1 +// see http://vuejs-templates.github.io/webpack for documentation. + +const path = require('path') + +module.exports = { + dev: { + + // Paths + assetsSubDirectory: 'static', + assetsPublicPath: '/', + proxyTable: {}, + + // Various Dev Server settings + host: 'localhost', // can be overwritten by process.env.HOST + port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined + autoOpenBrowser: false, + errorOverlay: true, + notifyOnErrors: true, + poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions- + + + /** + * Source Maps + */ + + // https://webpack.js.org/configuration/devtool/#development + devtool: 'cheap-module-eval-source-map', + + // If you have problems debugging vue-files in devtools, + // set this to false - it *may* help + // https://vue-loader.vuejs.org/en/options.html#cachebusting + cacheBusting: true, + + cssSourceMap: true + }, + + build: { + // Template for index.html + index: path.resolve(__dirname, '../dist/index.html'), + + // Paths + assetsRoot: path.resolve(__dirname, '../dist'), + assetsSubDirectory: 'static', + assetsPublicPath: '/', + + /** + * Source Maps + */ + + productionSourceMap: true, + // https://webpack.js.org/configuration/devtool/#production + devtool: '#source-map', + + // Gzip off by default as many popular static hosts such as + // Surge or Netlify already gzip all static assets for you. + // Before setting to `true`, make sure to: + // npm install --save-dev compression-webpack-plugin + productionGzip: false, + productionGzipExtensions: ['js', 'css'], + + // Run the build command with an extra argument to + // View the bundle analyzer report after build finishes: + // `npm run build --report` + // Set to `true` or `false` to always turn it on or off + bundleAnalyzerReport: process.env.npm_config_report + } +} diff --git a/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/config/prod.env.js b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/config/prod.env.js new file mode 100644 index 0000000000..a6f997616e --- /dev/null +++ b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/config/prod.env.js @@ -0,0 +1,4 @@ +'use strict' +module.exports = { + NODE_ENV: '"production"' +} diff --git a/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/index.html b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/index.html new file mode 100644 index 0000000000..03ce3fdf27 --- /dev/null +++ b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/index.html @@ -0,0 +1,12 @@ + + + + + + deplugin-view-frontend + + +
+ + + diff --git a/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/package.json b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/package.json new file mode 100644 index 0000000000..2fd98cc1aa --- /dev/null +++ b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/package.json @@ -0,0 +1,73 @@ +{ + "name": "deplugin-view-frontend", + "version": "1.0.0", + "description": "A Vue.js project", + "author": "", + "private": true, + "scripts": { + "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js", + "start": "npm run dev", + "build": "node build/build.js", + "buildPlugin": "node build/build-async-plugins.js" + }, + "dependencies": { + "@riophae/vue-treeselect": "0.4.0", + "highcharts": "^10.0.0", + "vue": "^2.5.2", + "vue-i18n": "7.3.2", + "vue-router": "^3.0.1", + "vue-uuid": "2.0.2", + "vuedraggable": "^2.24.3" + }, + "devDependencies": { + "autoprefixer": "^7.1.2", + "babel-core": "^6.22.1", + "babel-helper-vue-jsx-merge-props": "^2.0.3", + "babel-loader": "^7.1.1", + "babel-plugin-syntax-jsx": "^6.18.0", + "babel-plugin-transform-runtime": "^6.22.0", + "babel-plugin-transform-vue-jsx": "^3.5.0", + "babel-preset-env": "^1.3.2", + "babel-preset-stage-2": "^6.22.0", + "chalk": "^2.0.1", + "copy-webpack-plugin": "^4.6.0", + "css-loader": "^0.28.0", + "element-ui": "2.15.7", + "extract-text-webpack-plugin": "^4.0.0-beta.0", + "file-loader": "^1.1.4", + "friendly-errors-webpack-plugin": "^1.6.1", + "html-webpack-plugin": "^3.2.0", + "js-cookie": "2.2.0", + "node-notifier": "^8.0.1", + "optimize-css-assets-webpack-plugin": "^3.2.0", + "ora": "^1.2.0", + "portfinder": "^1.0.13", + "postcss-import": "^11.0.0", + "postcss-loader": "^2.0.8", + "postcss-url": "^7.2.1", + "rimraf": "^2.6.0", + "sass": "^1.33.0", + "sass-loader": "^7.3.1", + "semver": "^5.3.0", + "shelljs": "^0.8.5", + "svg-sprite-loader": "4.1.3", + "uglifyjs-webpack-plugin": "^1.1.1", + "url-loader": "^0.5.8", + "vue-loader": "^15.6.4", + "vue-style-loader": "^4.1.2", + "vue-template-compiler": "^2.5.2", + "webpack": "^4.8.1", + "webpack-bundle-analyzer": "^3.3.2", + "webpack-dev-server": "^3.1.11", + "webpack-merge": "^4.1.0" + }, + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + }, + "browserslist": [ + "> 1%", + "last 2 versions", + "not ie <= 8" + ] +} diff --git a/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/pom.xml b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/pom.xml new file mode 100644 index 0000000000..c5c4a10107 --- /dev/null +++ b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/pom.xml @@ -0,0 +1,80 @@ + + + + + io.dataease + view-3dpie + ${dataease.version} + + + 4.0.0 + view-3dpie-frontend + + + UTF-8 + UTF-8 + 1.9.1 + + + + + + maven-clean-plugin + + + + static + + ** + + false + + + + + + + + com.github.eirslett + frontend-maven-plugin + ${frontend-maven-plugin.version} + + + install node and npm + + install-node-and-npm + + + + v16.20.2 + 7.6.3 + + + + + npm install + + npm + + + + install --force + + + + + npm run buildPlugin + + npm + + + run buildPlugin + + + + + + + diff --git a/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/App.vue b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/App.vue new file mode 100644 index 0000000000..8542e07722 --- /dev/null +++ b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/App.vue @@ -0,0 +1,23 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/assets/logo.png b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/assets/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..f3d2503fc2a44b5053b0837ebea6e87a2d339a43 GIT binary patch literal 6849 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 +
+

{{ msg }}

+

Essential Links

+ +

Ecosystem

+ +
+ + + + + + diff --git a/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/components/SvgIcon/index.vue b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/components/SvgIcon/index.vue new file mode 100644 index 0000000000..f81b67f667 --- /dev/null +++ b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/components/SvgIcon/index.vue @@ -0,0 +1,60 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/components/selector/BackgroundColorSelector.vue b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/components/selector/BackgroundColorSelector.vue new file mode 100644 index 0000000000..e1cbf5fe18 --- /dev/null +++ b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/components/selector/BackgroundColorSelector.vue @@ -0,0 +1,102 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/components/selector/ColorSelector.vue b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/components/selector/ColorSelector.vue new file mode 100644 index 0000000000..326e9c8e77 --- /dev/null +++ b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/components/selector/ColorSelector.vue @@ -0,0 +1,290 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/components/selector/LabelSelector.vue b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/components/selector/LabelSelector.vue new file mode 100644 index 0000000000..a160bb7231 --- /dev/null +++ b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/components/selector/LabelSelector.vue @@ -0,0 +1,165 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/components/selector/LegendSelector.vue b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/components/selector/LegendSelector.vue new file mode 100644 index 0000000000..5125412616 --- /dev/null +++ b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/components/selector/LegendSelector.vue @@ -0,0 +1,165 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/components/selector/TitleSelector.vue b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/components/selector/TitleSelector.vue new file mode 100644 index 0000000000..8cb2e7c160 --- /dev/null +++ b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/components/selector/TitleSelector.vue @@ -0,0 +1,164 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/components/selector/TooltipSelector.vue b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/components/selector/TooltipSelector.vue new file mode 100644 index 0000000000..fbd16a64e3 --- /dev/null +++ b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/components/selector/TooltipSelector.vue @@ -0,0 +1,144 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/components/views/ChartDragItem.vue b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/components/views/ChartDragItem.vue new file mode 100644 index 0000000000..53ae1e2ad0 --- /dev/null +++ b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/components/views/ChartDragItem.vue @@ -0,0 +1,278 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/components/views/DimensionExtItem.vue b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/components/views/DimensionExtItem.vue new file mode 100644 index 0000000000..c414ad2d36 --- /dev/null +++ b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/components/views/DimensionExtItem.vue @@ -0,0 +1,256 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/components/views/DimensionItem.vue b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/components/views/DimensionItem.vue new file mode 100644 index 0000000000..3e37f94967 --- /dev/null +++ b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/components/views/DimensionItem.vue @@ -0,0 +1,256 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/components/views/DrillItem.vue b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/components/views/DrillItem.vue new file mode 100644 index 0000000000..7321b8a08c --- /dev/null +++ b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/components/views/DrillItem.vue @@ -0,0 +1,146 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/components/views/FieldErrorTips.vue b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/components/views/FieldErrorTips.vue new file mode 100644 index 0000000000..9d7b574721 --- /dev/null +++ b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/components/views/FieldErrorTips.vue @@ -0,0 +1,21 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/components/views/FilterItem.vue b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/components/views/FilterItem.vue new file mode 100644 index 0000000000..9db047f3e5 --- /dev/null +++ b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/components/views/FilterItem.vue @@ -0,0 +1,153 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/components/views/QuotaExtItem.vue b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/components/views/QuotaExtItem.vue new file mode 100644 index 0000000000..c88a060a84 --- /dev/null +++ b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/components/views/QuotaExtItem.vue @@ -0,0 +1,363 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/components/views/QuotaItem.vue b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/components/views/QuotaItem.vue new file mode 100644 index 0000000000..c22da7323a --- /dev/null +++ b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/components/views/QuotaItem.vue @@ -0,0 +1,344 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/components/views/ViewTrackBar.vue b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/components/views/ViewTrackBar.vue new file mode 100644 index 0000000000..605c0627b5 --- /dev/null +++ b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/components/views/ViewTrackBar.vue @@ -0,0 +1,59 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/components/views/utils.js b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/components/views/utils.js new file mode 100644 index 0000000000..0290965c94 --- /dev/null +++ b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/components/views/utils.js @@ -0,0 +1,34 @@ +export function getItemType(dimensionData, quotaData, item) { + // 将item的字段在数据集维度、指标字段中查询一遍,如果遇到id不存在、字段类型不一致、维度指标不一致,则提示 + const status = item.groupType + let checked = false + if (status === 'd') { + for (let i = 0; i < dimensionData.length; i++) { + const ele = dimensionData[i] + if (ele.id === item.id && ele.deType === item.deType && ele.groupType === item.groupType) { + checked = true + break + } + } + } + if (status === 'q') { + for (let i = 0; i < quotaData.length; i++) { + const ele = quotaData[i] + if (ele.id === item.id && ele.deType === item.deType && ele.groupType === item.groupType) { + checked = true + break + } + } + } + + if (checked) { + if (status === 'd') { + return '' + } else if (status === 'q') { + return 'success' + } + } else { + return 'danger' + } + } + \ No newline at end of file diff --git a/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/de-base/lang/en.js b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/de-base/lang/en.js new file mode 100644 index 0000000000..6a8f3edb98 --- /dev/null +++ b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/de-base/lang/en.js @@ -0,0 +1,7 @@ +export default { + plugin_view_3d_pie: { + type_title: '3D-PIE', + label: 'Label', + angle: 'Angle' + } +} \ No newline at end of file diff --git a/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/de-base/lang/index.js b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/de-base/lang/index.js new file mode 100644 index 0000000000..e50d0478e6 --- /dev/null +++ b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/de-base/lang/index.js @@ -0,0 +1,49 @@ +import Vue from 'vue' +import VueI18n from 'vue-i18n' +import Cookies from 'js-cookie' +import elementEnLocale from 'element-ui/lib/locale/lang/en' // element-ui lang +import elementZhLocale from 'element-ui/lib/locale/lang/zh-CN'// element-ui lang +import elementTWLocale from 'element-ui/lib/locale/lang/zh-TW'// element-ui lang + +import localMessages from './messages' + + +Vue.use(VueI18n) + +const messages = { + en_US: { + ...localMessages['en_US'], + ...elementEnLocale + }, + zh_CN: { + ...localMessages['zh_CN'], + ...elementZhLocale + }, + zh_TW: { + ...localMessages['zh_TW'], + ...elementTWLocale + } +} +export function getLanguage () { + const chooseLanguage = Cookies.get('language') + if (chooseLanguage) return chooseLanguage + + // if has not choose language + const language = (navigator.language || navigator.browserLanguage).toLowerCase() + const locales = Object.keys(messages) + for (const locale of locales) { + if (language.indexOf(locale) > -1) { + return locale + } + } + return 'zh_CN' +} +const i18n = new VueI18n({ + // set locale + // options: en | zh | es + locale: getLanguage(), + // set locale messages + messages +}) + +export default i18n diff --git a/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/de-base/lang/messages.js b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/de-base/lang/messages.js new file mode 100644 index 0000000000..844f8c0673 --- /dev/null +++ b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/de-base/lang/messages.js @@ -0,0 +1,17 @@ +import enLocale from './en' +import zhLocale from './zh' +import twLocale from './tw' + +const messages = { + en_US: { + ...enLocale + }, + zh_CN: { + ...zhLocale + }, + zh_TW: { + ...twLocale + } +} + +export default messages \ No newline at end of file diff --git a/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/de-base/lang/tw.js b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/de-base/lang/tw.js new file mode 100644 index 0000000000..02e895c68e --- /dev/null +++ b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/de-base/lang/tw.js @@ -0,0 +1,7 @@ +export default { + plugin_view_3d_pie: { + type_title: '3D餅圖', + label: '標籤', + angle: '角度' + } +} \ No newline at end of file diff --git a/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/de-base/lang/zh.js b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/de-base/lang/zh.js new file mode 100644 index 0000000000..cb58cc1f90 --- /dev/null +++ b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/de-base/lang/zh.js @@ -0,0 +1,7 @@ +export default { + plugin_view_3d_pie: { + type_title: '3D饼图', + label: '标签', + angle: '角度' + } +} diff --git a/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/icons/index.js b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/icons/index.js new file mode 100644 index 0000000000..2c6b309c96 --- /dev/null +++ b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/icons/index.js @@ -0,0 +1,9 @@ +import Vue from 'vue' +import SvgIcon from '@/components/SvgIcon'// svg component + +// register globally +Vue.component('svg-icon', SvgIcon) + +const req = require.context('./svg', false, /\.svg$/) +const requireAll = requireContext => requireContext.keys().map(requireContext) +requireAll(req) diff --git a/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/icons/svg/3d-pie.svg b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/icons/svg/3d-pie.svg new file mode 100644 index 0000000000..d1cccbf81c --- /dev/null +++ b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/icons/svg/3d-pie.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/icons/svg/view-3dpie-backend.svg b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/icons/svg/view-3dpie-backend.svg new file mode 100644 index 0000000000..4c3af7e10c --- /dev/null +++ b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/icons/svg/view-3dpie-backend.svg @@ -0,0 +1 @@ +【icon】插件管理-导出 diff --git a/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/icons/svgo.yml b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/icons/svgo.yml new file mode 100644 index 0000000000..e69de29bb2 diff --git a/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/main.js b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/main.js new file mode 100644 index 0000000000..fb8f35373c --- /dev/null +++ b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/main.js @@ -0,0 +1,34 @@ +// The Vue build version to load with the `import` command +// (runtime-only or standalone) has been set in webpack.base.conf with an alias. +import Vue from 'vue' +import App from './App' +import router from './router' +import ElementUI from 'element-ui' +import Cookies from 'js-cookie' +import i18n from './de-base/lang' +import draggable from 'vuedraggable' +import Treeselect from '@riophae/vue-treeselect' +import '@riophae/vue-treeselect/dist/vue-treeselect.css' +import '@/icons' // icon +Vue.config.productionTip = false +Vue.use(ElementUI, { + size: Cookies.get('size') || 'medium', + i18n: (key, value) => i18n.t(key, value) +}) +Vue.component('Treeselect', Treeselect) +Vue.component('draggable', draggable) +Vue.prototype.hasDataPermission = function(pTarget, pSource) { + + if (pSource && pTarget) { + return pSource.indexOf(pTarget) > -1 + } + return false +} +/* eslint-disable no-new */ +new Vue({ + el: '#app', + router, + i18n, + components: { App }, + template: '' +}) diff --git a/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/router/index.js b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/router/index.js new file mode 100644 index 0000000000..5e83b013fd --- /dev/null +++ b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/router/index.js @@ -0,0 +1,21 @@ +import Vue from 'vue' +import Router from 'vue-router' +import HelloWorld from '@/components/HelloWorld' +import Pie3D from '@/views/highcharts/3dpie/type' + +Vue.use(Router) + +export default new Router({ + routes: [ + { + path: '/', + name: 'HelloWorld', + component: HelloWorld + }, + { + path: '/3d-pie', + name: '3d-pie', + component: Pie3D + } + ] +}) diff --git a/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/utils/3dpie.js b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/utils/3dpie.js new file mode 100644 index 0000000000..46b4ffbf14 --- /dev/null +++ b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/utils/3dpie.js @@ -0,0 +1,268 @@ +export const DEFAULT_COLOR_CASE = { + value: 'default', + colors: ['#5470c6', '#91cc75', '#fac858', '#ee6666', '#73c0de', '#3ba272', '#fc8452', '#9a60b4', '#ea7ccc'], + alpha: 100, + tableHeaderBgColor: '#e1eaff', + tableItemBgColor: '#ffffff', + tableFontColor: '#000000', + tableStripe: true, + dimensionColor: '#000000', + quotaColor: '#000000', + tableBorderColor: '#cfdaf4' +} + +export const COLOR_PANEL = [ + '#ff4500', + '#ff8c00', + '#ffd700', + '#90ee90', + '#00ced1', + '#1e90ff', + '#c71585', + '#999999', + '#000000', + '#FFFFFF' +] + +export const DEFAULT_LABEL = { + show: false, + position: 'top', + color: '#909399', + fontSize: '10', + formatter: '{c}', + gaugeFormatter: '{value}', + labelLine: { + show: true + } +} +export const DEFAULT_TOOLTIP = { + show: true, + trigger: 'item', + confine: true, + textStyle: { + fontSize: '10', + color: '#909399' + }, + formatter: '' +} +export const DEFAULT_TITLE_STYLE = { + show: true, + fontSize: '18', + color: '#303133', + hPosition: 'center', + vPosition: 'top', + isItalic: false, + isBolder: false +} +export const DEFAULT_BACKGROUND_COLOR = { + color: '#ffffff', + alpha: 100, + borderRadius: 5 +} +export const BASE_PIE = { + chart: { + options3d: { + enabled: true, + alpha: 45, + beta: 0 + } + }, + credits: { + enabled: false + }, + title: { + text: '', + style: { + fontWeight: 'normal' + } + }, + legend: {}, + + plotOptions: { + pie: { + allowPointSelect: true, + cursor: 'pointer', + depth: 35, + dataLabels: { + enabled: true + }, + showInLegend: false + } + }, + + + tooltip: {}, + + series: [ + { + name: '', + type: 'pie', + data: [] + } + ] +} + + +let terminalType = 'pc' +export function basePieOption(chart_option, chart, terminal = 'pc') { + console.log('apple......') + terminalType = terminal + let customAttr = {} + if (chart.customAttr) { + customAttr = JSON.parse(chart.customAttr) + if (customAttr.color) { + chart_option.colors = customAttr.color.colors + } + // tooltip + if (customAttr.tooltip) { + const tooltip = JSON.parse(JSON.stringify(customAttr.tooltip)) + const reg = new RegExp('\n', 'g') + tooltip.formatter = tooltip.formatter.replace(reg, '
') + + chart_option.tooltip.enabled = tooltip.show + chart_option.tooltip.style = {fontSize: tooltip.textStyle.fontSize, color: tooltip.textStyle.color} + let formatter = tooltip.formatter + formatter = formatter.replace('{a}', '{series.name}') + formatter = formatter.replace('{b}', '{point.name}') + formatter = formatter.replace('{c}', '{point.y}') + formatter = formatter.replace('{d', '{point.percentage') + chart_option.tooltip.formatter = formatter + + } + + // label + if (customAttr.label) { + const dataLabels = {} + dataLabels.enabled = customAttr.label.show + dataLabels.color = customAttr.label.color + dataLabels.style = {color: customAttr.label.color, fontSize: customAttr.label.fontSize} + const reg = new RegExp('\n', 'g') + let formatter = customAttr.label.formatter.replace(reg, '
') + formatter = formatter.replace('{a}', '{series.name}') + formatter = formatter.replace('{b}', '{point.name}') + formatter = formatter.replace('{c}', '{point.y}') + formatter = formatter.replace('{d', '{point.percentage') + dataLabels.format = formatter + + chart_option.plotOptions.pie.dataLabels = dataLabels + + } + } + + // 处理data + if (chart.data) { + chart_option.title.text = chart.title + if (chart.data.series.length > 0) { + chart_option.series[0].name = chart.data.series[0].name + // size + /*if (customAttr.size) { + chart_option.series[0].radius = [customAttr.size.pieInnerRadius + '%', customAttr.size.pieOuterRadius + '%'] + }*/ + + const valueArr = chart.data.series[0].data + for (let i = 0; i < valueArr.length; i++) { + + const y = valueArr[i] + y.name = chart.data.x[i] + y.y = y.value + + chart_option.series[0].data.push(y) + } + } + } + + componentStyle(chart_option, chart) + return chart_option +} +export function componentStyle(chart_option, chart) { + const padding = '8px' + if (chart.customStyle) { + const customStyle = JSON.parse(chart.customStyle) + + if (customStyle.text) { + chart_option.title.text = customStyle.text.show ? chart.title : '' + const style = chart_option.title.style ? chart_option.title.style : {} + style.fontSize = customStyle.text.fontSize + style.color = customStyle.text.color + customStyle.text.isItalic ? style.fontStyle = 'italic' : style.fontStyle = 'normal' + customStyle.text.isBolder ? style.fontWeight = 'bold' : style.fontWeight = 'normal' + chart_option.title.textStyle = style + chart_option.title.align = customStyle.text.hPosition + chart_option.title.verticalAlign = customStyle.text.vPosition + } + + if (customStyle.legend && chart_option.legend) { + chart_option.plotOptions.pie.showInLegend = customStyle.legend.show + // chart_option.legend.padding = padding + chart_option.legend.layout = customStyle.legend.orient + chart_option.legend.verticalAlign = customStyle.legend.vPosition + chart_option.legend.align = customStyle.legend.hPosition + + chart_option.legend.itemStyle = customStyle.legend.textStyle + + } + + if (customStyle.background) { + + chart_option.chart.backgroundColor = hexColorToRGBA(customStyle.background.color, customStyle.background.alpha) + } + } +} +export function hexColorToRGBA(hex, alpha) { + const rgb = [] // 定义rgb数组 + if (/^\#[0-9A-F]{3}$/i.test(hex)) { // 判断传入是否为#三位十六进制数 + let sixHex = '#' + hex.replace(/[0-9A-F]/ig, function(kw) { + sixHex += kw + kw // 把三位16进制数转化为六位 + }) + hex = sixHex // 保存回hex + } + if (/^#[0-9A-F]{6}$/i.test(hex)) { // 判断传入是否为#六位十六进制数 + hex.replace(/[0-9A-F]{2}/ig, function(kw) { + // eslint-disable-next-line no-eval + rgb.push(eval('0x' + kw)) // 十六进制转化为十进制并存如数组 + }) + return `rgba(${rgb.join(',')},${alpha / 100})` // 输出RGB格式颜色 + } else { + return 'rgb(0,0,0)' + } +} + + + +export const DEFAULT_YAXIS_EXT_STYLE = { + show: true, + position: 'right', + name: '', + nameTextStyle: { + color: '#333333', + fontSize: 12 + }, + axisLabel: { + show: true, + color: '#333333', + fontSize: '12', + rotate: 0, + formatter: '{value}' + }, + splitLine: { + show: true, + lineStyle: { + color: '#cccccc', + width: 1, + style: 'solid' + } + }, + axisValue: { + auto: true, + min: null, + max: null, + split: null, + splitCount: null + } +} + +export function uuid() { + return (((1+Math.random())*0x10000)|0).toString(16).substring(1); +} + diff --git a/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/utils/compare.js b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/utils/compare.js new file mode 100644 index 0000000000..b06a104a10 --- /dev/null +++ b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/utils/compare.js @@ -0,0 +1,29 @@ +export const compareItem = { + type: 'none', // year-yoy/month-yoy等 + resultData: 'percent', // 对比差sub,百分比percent等 + field: '', + custom: { + field: '', + calcType: '0', // 0-增长值,1-增长率 + timeType: '0', // 0-固定日期,1-日期区间 + currentTime: '', + compareTime: '', + currentTimeRange: [], + compareTimeRange: [] + } +} + +export const compareYearList = [ + { name: 'year_mom', value: 'year_mom' } +] + +export const compareMonthList = [ + { name: 'month_mom', value: 'month_mom' }, + { name: 'year_yoy', value: 'year_yoy' } +] + +export const compareDayList = [ + { name: 'day_mom', value: 'day_mom' }, + { name: 'month_yoy', value: 'month_yoy' }, + { name: 'year_yoy', value: 'year_yoy' } +] diff --git a/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/utils/map.js b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/utils/map.js new file mode 100644 index 0000000000..b851cc4d87 --- /dev/null +++ b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/utils/map.js @@ -0,0 +1,350 @@ +export const DEFAULT_COLOR_CASE = { + value: 'default', + colors: ['#5470c6', '#91cc75', '#fac858', '#ee6666', '#73c0de', '#3ba272', '#fc8452', '#9a60b4', '#ea7ccc'], + alpha: 100, + tableHeaderBgColor: '#e1eaff', + tableItemBgColor: '#ffffff', + tableFontColor: '#000000', + tableStripe: true, + dimensionColor: '#000000', + quotaColor: '#000000', + tableBorderColor: '#cfdaf4' +} + +export const COLOR_PANEL = [ + '#ff4500', + '#ff8c00', + '#ffd700', + '#90ee90', + '#00ced1', + '#1e90ff', + '#c71585', + '#999999', + '#000000', + '#FFFFFF' +] + +export const DEFAULT_LABEL = { + show: false, + position: 'top', + color: '#909399', + fontSize: '10', + formatter: '{c}', + gaugeFormatter: '{value}', + labelLine: { + show: true + } + } + export const DEFAULT_TOOLTIP = { + show: true, + trigger: 'item', + confine: true, + textStyle: { + fontSize: '10', + color: '#909399' + }, + formatter: '' + } + export const DEFAULT_TITLE_STYLE = { + show: true, + fontSize: '18', + color: '#303133', + hPosition: 'center', + vPosition: 'top', + isItalic: false, + isBolder: false + } + export const DEFAULT_LEGEND_STYLE = { + show: true, + hPosition: 'center', + vPosition: 'bottom', + orient: 'horizontal', + icon: 'circle', + textStyle: { + color: '#333333', + fontSize: '12' + } + } + export const DEFAULT_BACKGROUND_COLOR = { + color: '#ffffff', + alpha: 100, + borderRadius: 5 + } +export const BASE_MAP = { + title: { + text: '', + textStyle: { + fontWeight: 'normal' + } + }, + visualMap: { + min: 50, + max: 52, + text: ['High', 'Low'], + realtime: false, + calculable: true, + inRange: { + color: ['lightskyblue', 'yellow', 'orangered'] + }, + right: 0 + }, + + tooltip: {}, + geo: [ + { + show: true, + map: 'BUDDLE_MAP_BORDER', + + emphasis: { + disabled: true + }, + itemStyle: { + borderWidth: 2, + borderColor: '#d1d1d1', + borderType: 'solid' + }, + + roam: false + }, + { + show: true, + map: 'BUDDLE_MAP', + label: { + normal: { + show: false + }, + emphasis: { + show: false + } + }, + itemStyle: { + areaColor: '#f3f3f3', + borderType: 'dashed', + borderColor: '#fff' + }, + + roam: false + } + ], + series: [ + { + name: '', + type: 'scatter', + coordinateSystem: 'geo', + data: [] + } + ] +} +const convertData = (mapData, chart) => { + let maxVal = 0 + const k = terminalType === 'pc' ? 30 : 15 + const names = chart.data.x + const results = [] + for (let index = 0; index < names.length; index++) { + const name = names[index]; + const item = chart.data.series[0].data[index] + results.push({name, value: (mapData[name] ? mapData[name].concat(item.value) : []), dimensionList: item.dimensionList, quotaList: item.quotaList}) + maxVal = Math.max(maxVal, item.value) + } + const rate = k / maxVal + + return { + value: results, + rate: rate + } +} + +let terminalType = 'pc' +export function baseMapOption(chart_option, chart, mapData, terminal = 'pc') { + terminalType = terminal + // 处理shape attr + let customAttr = {} + if (chart.customAttr) { + customAttr = JSON.parse(chart.customAttr) + if (customAttr.color) { + chart_option.color = customAttr.color.colors + } + // tooltip + if (customAttr.tooltip) { + const tooltip = JSON.parse(JSON.stringify(customAttr.tooltip)) + const reg = new RegExp('\n', 'g') + const text = tooltip.formatter.replace(reg, '
') + tooltip.formatter = function(params) { + const a = params.seriesName + const b = params.name + const c = params.value ? params.value[2] : '' + return text.replace(new RegExp('{a}', 'g'), a).replace(new RegExp('{b}', 'g'), b).replace(new RegExp('{c}', 'g'), c) + } + chart_option.tooltip = tooltip + } + } + // 处理data + if (chart.data) { + chart_option.title.text = chart.title + if (chart.data.series && chart.data.series.length > 0) { + chart_option.series[0].name = chart.data.series[0].name + // label + if (customAttr.label) { + const text = customAttr.label.formatter + chart_option.series[0].label = customAttr.label + chart_option.series[0].label.formatter = function(params) { + const a = params.seriesName + const b = params.name + const c = params.value ? params.value[2] : '' + return text.replace(new RegExp('{a}', 'g'), a).replace(new RegExp('{b}', 'g'), b).replace(new RegExp('{c}', 'g'), c) + } + chart_option.series[0].labelLine = customAttr.label.labelLine + } + + // visualMap + const valueArr = chart.data.series[0].data + if (valueArr && valueArr.length > 0) { + const values = [] + valueArr.forEach(function(ele) { + values.push(ele.value) + }) + chart_option.visualMap.min = Math.min(...values) + chart_option.visualMap.max = Math.max(...values) + if (chart_option.visualMap.min === chart_option.visualMap.max) { + chart_option.visualMap.min = 0 + } + } else { + chart_option.visualMap.min = 0 + chart_option.visualMap.max = 0 + } + if (chart_option.visualMap.min === 0 && chart_option.visualMap.max === 0) { + chart_option.visualMap.max = 100 + } + // color + if (customAttr.color && customAttr.color.colors) { + chart_option.visualMap.inRange.color = customAttr.color.colors + chart_option.visualMap.inRange.colorAlpha = customAttr.color.alpha / 100 + } + // chart_option.visualMap = null + + const convert = convertData(mapData, chart) + chart_option.series[0].data = convert.value + chart_option.series[0].symbolSize = val => val[2] * convert.rate + + } + } + // console.log(chart_option); + componentStyle(chart_option, chart) + return chart_option +} +export function componentStyle(chart_option, chart) { + const padding = '8px' + if (chart.customStyle) { + const customStyle = JSON.parse(chart.customStyle) + if (customStyle.text) { + chart_option.title.show = customStyle.text.show + // 水平方向 + if (customStyle.text.hPosition === 'left') { + chart_option.title.left = padding + } else if (customStyle.text.hPosition === 'right') { + chart_option.title.right = padding + } else { + chart_option.title.left = customStyle.text.hPosition + } + // 垂直方向 + if (customStyle.text.vPosition === 'top') { + chart_option.title.top = padding + } else if (customStyle.text.vPosition === 'bottom') { + chart_option.title.bottom = padding + } else { + chart_option.title.top = customStyle.text.vPosition + } + const style = chart_option.title.textStyle ? chart_option.title.textStyle : {} + style.fontSize = customStyle.text.fontSize + style.color = customStyle.text.color + customStyle.text.isItalic ? style.fontStyle = 'italic' : style.fontStyle = 'normal' + customStyle.text.isBolder ? style.fontWeight = 'bold' : style.fontWeight = 'normal' + chart_option.title.textStyle = style + } + if (customStyle.legend && chart_option.legend) { + chart_option.legend.show = customStyle.legend.show + // 水平方向 + if (customStyle.legend.hPosition === 'left') { + chart_option.legend.left = padding + } else if (customStyle.legend.hPosition === 'right') { + chart_option.legend.right = padding + } else { + chart_option.legend.left = customStyle.legend.hPosition + } + // 垂直方向 + if (customStyle.legend.vPosition === 'top') { + chart_option.legend.top = padding + } else if (customStyle.legend.vPosition === 'bottom') { + chart_option.legend.bottom = padding + } else { + chart_option.legend.top = customStyle.legend.vPosition + } + chart_option.legend.orient = customStyle.legend.orient + chart_option.legend.icon = customStyle.legend.icon + chart_option.legend.textStyle = customStyle.legend.textStyle + + } + + if (customStyle.background) { + chart_option.backgroundColor = hexColorToRGBA(customStyle.background.color, customStyle.background.alpha) + } + } +} +export function hexColorToRGBA(hex, alpha) { + const rgb = [] // 定义rgb数组 + if (/^\#[0-9A-F]{3}$/i.test(hex)) { // 判断传入是否为#三位十六进制数 + let sixHex = '#' + hex.replace(/[0-9A-F]/ig, function(kw) { + sixHex += kw + kw // 把三位16进制数转化为六位 + }) + hex = sixHex // 保存回hex + } + if (/^#[0-9A-F]{6}$/i.test(hex)) { // 判断传入是否为#六位十六进制数 + hex.replace(/[0-9A-F]{2}/ig, function(kw) { + // eslint-disable-next-line no-eval + rgb.push(eval('0x' + kw)) // 十六进制转化为十进制并存如数组 + }) + return `rgba(${rgb.join(',')},${alpha / 100})` // 输出RGB格式颜色 + } else { + return 'rgb(0,0,0)' + } +} + + + +export const DEFAULT_YAXIS_EXT_STYLE = { + show: true, + position: 'right', + name: '', + nameTextStyle: { + color: '#333333', + fontSize: 12 + }, + axisLabel: { + show: true, + color: '#333333', + fontSize: '12', + rotate: 0, + formatter: '{value}' + }, + splitLine: { + show: true, + lineStyle: { + color: '#cccccc', + width: 1, + style: 'solid' + } + }, + axisValue: { + auto: true, + min: null, + max: null, + split: null, + splitCount: null + } +} + +export function uuid() { + return (((1+Math.random())*0x10000)|0).toString(16).substring(1); +} + diff --git a/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/utils/validate.js b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/utils/validate.js new file mode 100644 index 0000000000..3e8ffa9448 --- /dev/null +++ b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/utils/validate.js @@ -0,0 +1,15 @@ +/** + * Created by PanJiaChen on 16/11/18. + */ + +/** + * @param {string} path + * @returns {Boolean} + */ +export function isExternal(path) { + return /^(https?:|mailto:|tel:)/.test(path) || /^(http?:|mailto:|tel:)/.test(path) || path.startsWith('/api/pluginCommon/staticInfo') +} + + + + diff --git a/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/views/PluginDemo.vue b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/views/PluginDemo.vue new file mode 100644 index 0000000000..1164dfab1d --- /dev/null +++ b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/views/PluginDemo.vue @@ -0,0 +1,55 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/views/highcharts/3dpie/data.vue b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/views/highcharts/3dpie/data.vue new file mode 100644 index 0000000000..593b84a29b --- /dev/null +++ b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/views/highcharts/3dpie/data.vue @@ -0,0 +1,680 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/views/highcharts/3dpie/index.vue b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/views/highcharts/3dpie/index.vue new file mode 100644 index 0000000000..e938e799da --- /dev/null +++ b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/views/highcharts/3dpie/index.vue @@ -0,0 +1,244 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/views/highcharts/3dpie/style.vue b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/views/highcharts/3dpie/style.vue new file mode 100644 index 0000000000..e6c10d8d33 --- /dev/null +++ b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/views/highcharts/3dpie/style.vue @@ -0,0 +1,162 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/views/highcharts/3dpie/type.vue b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/views/highcharts/3dpie/type.vue new file mode 100644 index 0000000000..c227610e1f --- /dev/null +++ b/extensions/dataease-extensions-view/view-3dpie/view-3dpie-frontend/src/views/highcharts/3dpie/type.vue @@ -0,0 +1,63 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-bubblemap/build.sh b/extensions/dataease-extensions-view/view-bubblemap/build.sh new file mode 100644 index 0000000000..1ebadcac5f --- /dev/null +++ b/extensions/dataease-extensions-view/view-bubblemap/build.sh @@ -0,0 +1,8 @@ +#!/bin/sh +mvn clean package + +cp view-bubblemap-backend/target/view-bubblemap-backend-1.18.3.jar . + +zip -r bubblemap.zip ./view-bubblemap-backend-1.18.3.jar ./plugin.json + +rm -f ./view-bubblemap-backend-1.18.3.jar diff --git a/extensions/dataease-extensions-view/view-bubblemap/plugin.json b/extensions/dataease-extensions-view/view-bubblemap/plugin.json new file mode 100644 index 0000000000..0b54a66529 --- /dev/null +++ b/extensions/dataease-extensions-view/view-bubblemap/plugin.json @@ -0,0 +1,13 @@ +{ + "name": "气泡地图", + "free": 0, + "store": "thirdpart", + "cost": 0, + "category": "view", + "descript": "ECharts 气泡地图插件", + "version": "1.18.3", + "creator": "DATAEASE", + "moduleName": "view-bubblemap-backend", + "require": "1.10.0", + "dsType": "" +} \ No newline at end of file diff --git a/extensions/dataease-extensions-view/view-bubblemap/pom.xml b/extensions/dataease-extensions-view/view-bubblemap/pom.xml new file mode 100644 index 0000000000..c5f77e0809 --- /dev/null +++ b/extensions/dataease-extensions-view/view-bubblemap/pom.xml @@ -0,0 +1,22 @@ + + + + dataease-extensions-view + io.dataease + ${dataease.version} + + 4.0.0 + pom + + view-bubblemap + + + + view-bubblemap-frontend + view-bubblemap-backend + + + + diff --git a/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-backend/pom.xml b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-backend/pom.xml new file mode 100644 index 0000000000..ee13ffb8e8 --- /dev/null +++ b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-backend/pom.xml @@ -0,0 +1,161 @@ + + + + io.dataease + view-bubblemap + ${dataease.version} + + 4.0.0 + + + 11 + + + view-bubblemap-backend + + + + io.dataease + dataease-plugin-view + + + + + + + src/main/java + + **/*.properties + **/*.xml + + false + + + src/main/resources + + **/* + + false + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 11 + 11 + + + + + org.apache.maven.plugins + maven-jar-plugin + 2.4 + + + **/server/** + **/*.properties + **/Application* + + + + + + maven-clean-plugin + + + + src/main/resources/static + + ** + + false + + + + + + + + + org.apache.maven.plugins + maven-antrun-plugin + + + main-class-placement + generate-resources + + + + + + + + + + + + run + + + + + + + org.apache.maven.plugins + maven-resources-plugin + + + copy-and-filter-allatori-config + package + + copy-resources + + + ${basedir}/target + + + ${basedir}/allatori + + allatori.xml + + true + + + + + + + + org.codehaus.mojo + exec-maven-plugin + 3.1.0 + + + run-allatori + package + + exec + + + + + java + + -Xms128m + -Xmx512m + -jar + ${basedir}/target/classes/allatori/allatori.jar + ${basedir}/target/classes/allatori/allatori.xml + + + + + + + + diff --git a/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-backend/src/main/java/io/dataease/plugins/view/official/impl/BubbleMapService.java b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-backend/src/main/java/io/dataease/plugins/view/official/impl/BubbleMapService.java new file mode 100644 index 0000000000..49b5635b69 --- /dev/null +++ b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-backend/src/main/java/io/dataease/plugins/view/official/impl/BubbleMapService.java @@ -0,0 +1,113 @@ +package io.dataease.plugins.view.official.impl; + +import io.dataease.plugins.common.dto.StaticResource; +import io.dataease.plugins.view.entity.PluginViewField; +import io.dataease.plugins.view.entity.PluginViewParam; +import io.dataease.plugins.view.entity.PluginViewType; +import io.dataease.plugins.view.service.ViewPluginService; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.stereotype.Service; + +import java.io.InputStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Service +public class BubbleMapService extends ViewPluginService { + + private static final String VIEW_TYPE_VALUE = "buddle-map"; + private static final String[] VIEW_STYLE_PROPERTIES = + { + "color-selector", + "label-selector", + "tooltip-selector", + "title-selector", + "suspension-selector" + }; + + private static final Map VIEW_STYLE_PROPERTY_INNER = new HashMap(); + + static { + VIEW_STYLE_PROPERTY_INNER.put("color-selector", new String[]{"value", "alpha"}); + VIEW_STYLE_PROPERTY_INNER.put("label-selector", new String[]{"show", "fontSize", "color", "position", "formatter"}); + VIEW_STYLE_PROPERTY_INNER.put("tooltip-selector", new String[]{"show", "textStyle", "formatter"}); + VIEW_STYLE_PROPERTY_INNER.put("title-selector", new String[]{"show", "title", "fontSize", "color", "hPosition", "vPosition", "isItalic", "isBolder"}); + VIEW_STYLE_PROPERTY_INNER.put("suspension-selector", new String[]{"show"}); + } + + /*下版这些常量移到sdk*/ + private static final String TYPE = "-type"; + private static final String DATA = "-data"; + private static final String STYLE = "-style"; + private static final String VIEW = "-view"; + private static final String SUFFIX = "svg"; + /*下版这些常量移到sdk*/ + private static final String VIEW_TYPE = VIEW_TYPE_VALUE + TYPE; + private static final String VIEW_DATA = VIEW_TYPE_VALUE + DATA; + private static final String VIEW_STYLE = VIEW_TYPE_VALUE + STYLE; + private static final String VIEW_VIEW = VIEW_TYPE_VALUE + VIEW; + + + @Override + public PluginViewType viewType() { + PluginViewType pluginViewType = new PluginViewType(); + pluginViewType.setRender("echarts"); + pluginViewType.setCategory("chart.chart_type_space"); + pluginViewType.setValue(VIEW_TYPE_VALUE); + pluginViewType.setProperties(VIEW_STYLE_PROPERTIES); + pluginViewType.setPropertyInner(VIEW_STYLE_PROPERTY_INNER); + return pluginViewType; + } + + @Override + public Object format(Object o) { + return null; + } + + @Override + public List components() { + List results = new ArrayList<>(); + results.add(VIEW_VIEW); + results.add(VIEW_DATA); + results.add(VIEW_TYPE); + results.add(VIEW_STYLE); + return results; + } + + @Override + public List staticResources() { + List results = new ArrayList<>(); + StaticResource staticResource = new StaticResource(); + staticResource.setName(VIEW_TYPE_VALUE); + staticResource.setSuffix(SUFFIX); + results.add(staticResource); + results.add(pluginSvg()); + return results; + } + + private StaticResource pluginSvg() { + StaticResource staticResource = new StaticResource(); + staticResource.setName("view-bubblemap-backend"); + staticResource.setSuffix("svg"); + return staticResource; + } + + @Override + protected InputStream readContent(String s) { + InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream("static/" + s); + return resourceAsStream; + } + + @Override + public String generateSQL(PluginViewParam param) { + List xAxis = param.getFieldsByType("xAxis"); + List yAxis = param.getFieldsByType("yAxis"); + if (CollectionUtils.isEmpty(xAxis) || CollectionUtils.isEmpty(yAxis)) { + return null; + } + return super.generateSQL(param); + } + +} diff --git a/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-backend/src/main/resources/allatori/allatori.xml b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-backend/src/main/resources/allatori/allatori.xml new file mode 100644 index 0000000000..f97cb84fef --- /dev/null +++ b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-backend/src/main/resources/allatori/allatori.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-backend/src/main/resources/application.properties b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-backend/src/main/resources/application.properties new file mode 100644 index 0000000000..0e9c1c78c1 --- /dev/null +++ b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-backend/src/main/resources/application.properties @@ -0,0 +1,28 @@ +server.port=8083 +# Hikari +spring.datasource.type=com.zaxxer.hikari.HikariDataSource + +# 数据库配置 +spring.datasource.url=jdbc:mysql://rm-uf6m17586w7yuwm805o.mysql.rds.aliyuncs.com:3306/dataease?autoReconnect=false&useUnicode=true&characterEncoding=UTF-8&characterSetResults=UTF-8&zeroDateTimeBehavior=convertToNull&useSSL=false +spring.datasource.username=root +spring.datasource.password=Password123@mysql +spring.datasource.hikari.minimum-idle=5 +spring.datasource.hikari.maximum-pool-size=15 +spring.datasource.hikari.auto-commit=true +spring.datasource.hikari.idle-timeout=30000 +spring.datasource.hikari.pool-name=DatebookHikariCP +spring.datasource.hikari.max-lifetime=1800000 +spring.datasource.hikari.connection-timeout=30000 +spring.datasource.hikari.connection-test-query=SELECT 1 + +# mybatis +mybatis.configuration.cache-enabled=true +mybatis.configuration.lazy-loading-enabled=false +mybatis.configuration.aggressive-lazy-loading=true +mybatis.configuration.multiple-result-sets-enabled=true +mybatis.configuration.use-column-label=true +mybatis.configuration.auto-mapping-behavior=full +mybatis.configuration.default-statement-timeout=25000 +mybatis.configuration.map-underscore-to-camel-case=true + + diff --git a/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/.babelrc b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/.babelrc new file mode 100644 index 0000000000..3a280ba34b --- /dev/null +++ b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/.babelrc @@ -0,0 +1,12 @@ +{ + "presets": [ + ["env", { + "modules": false, + "targets": { + "browsers": ["> 1%", "last 2 versions", "not ie <= 8"] + } + }], + "stage-2" + ], + "plugins": ["transform-vue-jsx", "transform-runtime"] +} diff --git a/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/.editorconfig b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/.editorconfig new file mode 100644 index 0000000000..9d08a1a828 --- /dev/null +++ b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/.editorconfig @@ -0,0 +1,9 @@ +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true diff --git a/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/.gitignore b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/.gitignore new file mode 100644 index 0000000000..541a820f6c --- /dev/null +++ b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/.gitignore @@ -0,0 +1,14 @@ +.DS_Store +node_modules/ +/dist/ +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Editor directories and files +.idea +.vscode +*.suo +*.ntvs* +*.njsproj +*.sln diff --git a/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/.postcssrc.js b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/.postcssrc.js new file mode 100644 index 0000000000..eee3e92d7f --- /dev/null +++ b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/.postcssrc.js @@ -0,0 +1,10 @@ +// https://github.com/michael-ciniawsky/postcss-load-config + +module.exports = { + "plugins": { + "postcss-import": {}, + "postcss-url": {}, + // to edit target browsers: use "browserslist" field in package.json + "autoprefixer": {} + } +} diff --git a/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/README.md b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/README.md new file mode 100644 index 0000000000..c1e4be95e0 --- /dev/null +++ b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/README.md @@ -0,0 +1,21 @@ +# deplugin-view-frontend + +> A Vue.js project + +## Build Setup + +``` bash +# install dependencies +npm install + +# serve with hot reload at localhost:8080 +npm run dev + +# build for production with minification +npm run build + +# build for production and view the bundle analyzer report +npm run build --report +``` + +For a detailed explanation on how things work, check out the [guide](http://vuejs-templates.github.io/webpack/) and [docs for vue-loader](http://vuejs.github.io/vue-loader). diff --git a/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/build/build-async-plugins.js b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/build/build-async-plugins.js new file mode 100644 index 0000000000..2303854531 --- /dev/null +++ b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/build/build-async-plugins.js @@ -0,0 +1,35 @@ +'use strict' +require('./check-versions')() + +process.env.NODE_ENV = 'production' + +const ora = require('ora') +const chalk = require('chalk') +const webpack = require('webpack') +const webpackConfig = require('./webpack.async-plugins') + +const spinner = ora('building for sync-plugins...') +spinner.start() + +webpack(webpackConfig, function (err, stats) { + spinner.stop() + if (err) throw err + process.stdout.write(stats.toString({ + colors: true, + modules: false, + children: false, + chunks: false, + chunkModules: false + }) + '\n\n') + + if (stats.hasErrors()) { + console.log(chalk.red(' Build failed with errors.\n')) + process.exit(1) + } + + console.log(chalk.cyan(' Build complete.\n')) + console.log(chalk.yellow( + ' Tip: built files are meant to be served over an HTTP server.\n' + + ' Opening index.html over file:// won\'t work.\n' + )) +}) diff --git a/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/build/build.js b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/build/build.js new file mode 100644 index 0000000000..8f2ad8ad49 --- /dev/null +++ b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/build/build.js @@ -0,0 +1,41 @@ +'use strict' +require('./check-versions')() + +process.env.NODE_ENV = 'production' + +const ora = require('ora') +const rm = require('rimraf') +const path = require('path') +const chalk = require('chalk') +const webpack = require('webpack') +const config = require('../config') +const webpackConfig = require('./webpack.prod.conf') + +const spinner = ora('building for production...') +spinner.start() + +rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => { + if (err) throw err + webpack(webpackConfig, (err, stats) => { + spinner.stop() + if (err) throw err + process.stdout.write(stats.toString({ + colors: true, + modules: false, + children: false, // If you are using ts-loader, setting this to true will make TypeScript errors show up during build. + chunks: false, + chunkModules: false + }) + '\n\n') + + if (stats.hasErrors()) { + console.log(chalk.red(' Build failed with errors.\n')) + process.exit(1) + } + + console.log(chalk.cyan(' Build complete.\n')) + console.log(chalk.yellow( + ' Tip: built files are meant to be served over an HTTP server.\n' + + ' Opening index.html over file:// won\'t work.\n' + )) + }) +}) diff --git a/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/build/check-versions.js b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/build/check-versions.js new file mode 100644 index 0000000000..3ef972a08d --- /dev/null +++ b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/build/check-versions.js @@ -0,0 +1,54 @@ +'use strict' +const chalk = require('chalk') +const semver = require('semver') +const packageConfig = require('../package.json') +const shell = require('shelljs') + +function exec (cmd) { + return require('child_process').execSync(cmd).toString().trim() +} + +const versionRequirements = [ + { + name: 'node', + currentVersion: semver.clean(process.version), + versionRequirement: packageConfig.engines.node + } +] + +if (shell.which('npm')) { + versionRequirements.push({ + name: 'npm', + currentVersion: exec('npm --version'), + versionRequirement: packageConfig.engines.npm + }) +} + +module.exports = function () { + const warnings = [] + + for (let i = 0; i < versionRequirements.length; i++) { + const mod = versionRequirements[i] + + if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) { + warnings.push(mod.name + ': ' + + chalk.red(mod.currentVersion) + ' should be ' + + chalk.green(mod.versionRequirement) + ) + } + } + + if (warnings.length) { + console.log('') + console.log(chalk.yellow('To use this template, you must update following to modules:')) + console.log() + + for (let i = 0; i < warnings.length; i++) { + const warning = warnings[i] + console.log(' ' + warning) + } + + console.log() + process.exit(1) + } +} diff --git a/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/build/logo.png b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/build/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..f3d2503fc2a44b5053b0837ebea6e87a2d339a43 GIT binary patch literal 6849 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 { + const notifier = require('node-notifier') + + return (severity, errors) => { + if (severity !== 'error') return + + const error = errors[0] + const filename = error.file && error.file.split('!').pop() + + notifier.notify({ + title: packageConfig.name, + message: severity + ': ' + error.name, + subtitle: filename || '', + icon: path.join(__dirname, 'logo.png') + }) + } +} diff --git a/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/build/vue-loader.conf.js b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/build/vue-loader.conf.js new file mode 100644 index 0000000000..33ed58bc0a --- /dev/null +++ b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/build/vue-loader.conf.js @@ -0,0 +1,22 @@ +'use strict' +const utils = require('./utils') +const config = require('../config') +const isProduction = process.env.NODE_ENV === 'production' +const sourceMapEnabled = isProduction + ? config.build.productionSourceMap + : config.dev.cssSourceMap + +module.exports = { + loaders: utils.cssLoaders({ + sourceMap: sourceMapEnabled, + extract: isProduction + }), + cssSourceMap: sourceMapEnabled, + cacheBusting: config.dev.cacheBusting, + transformToRequire: { + video: ['src', 'poster'], + source: 'src', + img: 'src', + image: 'xlink:href' + } +} diff --git a/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/build/webpack.async-plugins.js b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/build/webpack.async-plugins.js new file mode 100644 index 0000000000..12d537649b --- /dev/null +++ b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/build/webpack.async-plugins.js @@ -0,0 +1,97 @@ +const webpack = require('webpack') +const path = require('path') +const utils = require('./utils') +const CopyPlugin = require("copy-webpack-plugin"); +const VueLoaderPlugin = require('vue-loader/lib/plugin'); +function resolve (dir) { + return path.join(__dirname, '..', dir) +} + +module.exports = { + mode: 'development', + entry: { + + 'buddle-map-view': resolve('/src/views/echarts/map/buddle/index.vue'), + 'buddle-map-data': resolve('/src/views/echarts/map/buddle/data.vue'), + 'buddle-map-type': resolve('/src/views/echarts/map/buddle/type.vue'), + 'buddle-map-style': resolve('/src/views/echarts/map/buddle/style.vue') + + }, + output: { + path: resolve('/static/'), + filename: '[name].js' + }, + resolve: { + extensions: ['.js', '.vue', '.json'], + alias: { + 'vue$': 'vue/dist/vue.esm.js', + '@': resolve('src') + } + }, + externals: { + vue: 'vue' + }, + module: { + rules: [ + { + test: /\.vue$/, + loader: 'vue-loader', + options: { + transformAssetUrls: { + video: 'src', + source: 'src', + img: 'src', + image: 'xlink:href' + } + } + }, + { + test: /.(sa|sc|c)ss$/, + use: [ + {loader: 'vue-style-loader'}, + 'css-loader', + 'sass-loader' + ] + }, + { + test: /\.js$/, + loader: 'babel-loader', + include: [resolve('src'), resolve('test')] + }, + { + test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: utils.assetsPath('img/[name].[hash:7].[ext]') + } + }, + { + test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: utils.assetsPath('media/[name].[hash:7].[ext]') + } + }, + { + test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: utils.assetsPath('fonts/[name].[hash:7].[ext]') + } + } + ] + }, + plugins: [ + new VueLoaderPlugin(), + new webpack.DefinePlugin({ + 'process.env.NODE_ENV': '"production"' + }), + new CopyPlugin([ + {from: 'src/icons/svg/'} + ]) + + ] +} diff --git a/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/build/webpack.base.conf.js b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/build/webpack.base.conf.js new file mode 100644 index 0000000000..6ccc02dab4 --- /dev/null +++ b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/build/webpack.base.conf.js @@ -0,0 +1,91 @@ +'use strict' +const path = require('path') +const utils = require('./utils') +const config = require('../config') +const vueLoaderConfig = require('./vue-loader.conf') + +function resolve (dir) { + return path.join(__dirname, '..', dir) +} + + + +module.exports = { + context: path.resolve(__dirname, '../'), + entry: { + app: './src/main.js' + }, + output: { + path: config.build.assetsRoot, + filename: '[name].js', + publicPath: process.env.NODE_ENV === 'production' + ? config.build.assetsPublicPath + : config.dev.assetsPublicPath + }, + resolve: { + extensions: ['.js', '.vue', '.json'], + alias: { + 'vue$': 'vue/dist/vue.esm.js', + '@': resolve('src'), + } + }, + module: { + rules: [ + { + test: /\.vue$/, + loader: 'vue-loader', + options: vueLoaderConfig + }, + { + test: /\.js$/, + loader: 'babel-loader', + include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')] + }, + { + test: /\.svg$/, + loader: 'svg-sprite-loader', + include: [resolve('src/icons')], + options: { + symbolId: 'icon-[name]' + } + }, + { + test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, + loader: 'url-loader', + exclude: [resolve('src/icons')], + options: { + limit: 10000, + name: utils.assetsPath('img/[name].[hash:7].[ext]') + } + }, + { + test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: utils.assetsPath('media/[name].[hash:7].[ext]') + } + }, + { + test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: utils.assetsPath('fonts/[name].[hash:7].[ext]') + } + } + ] + }, + node: { + // prevent webpack from injecting useless setImmediate polyfill because Vue + // source contains it (although only uses it if it's native). + setImmediate: false, + // prevent webpack from injecting mocks to Node native modules + // that does not make sense for the client + dgram: 'empty', + fs: 'empty', + net: 'empty', + tls: 'empty', + child_process: 'empty' + } +} diff --git a/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/build/webpack.dev.conf.js b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/build/webpack.dev.conf.js new file mode 100755 index 0000000000..070ae221f3 --- /dev/null +++ b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/build/webpack.dev.conf.js @@ -0,0 +1,95 @@ +'use strict' +const utils = require('./utils') +const webpack = require('webpack') +const config = require('../config') +const merge = require('webpack-merge') +const path = require('path') +const baseWebpackConfig = require('./webpack.base.conf') +const CopyWebpackPlugin = require('copy-webpack-plugin') +const HtmlWebpackPlugin = require('html-webpack-plugin') +const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin') +const portfinder = require('portfinder') + +const HOST = process.env.HOST +const PORT = process.env.PORT && Number(process.env.PORT) + +const devWebpackConfig = merge(baseWebpackConfig, { + module: { + rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true }) + }, + // cheap-module-eval-source-map is faster for development + devtool: config.dev.devtool, + + // these devServer options should be customized in /config/index.js + devServer: { + clientLogLevel: 'warning', + historyApiFallback: { + rewrites: [ + { from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') }, + ], + }, + hot: true, + contentBase: false, // since we use CopyWebpackPlugin. + compress: true, + host: HOST || config.dev.host, + port: PORT || config.dev.port, + open: config.dev.autoOpenBrowser, + overlay: config.dev.errorOverlay + ? { warnings: false, errors: true } + : false, + publicPath: config.dev.assetsPublicPath, + proxy: config.dev.proxyTable, + quiet: true, // necessary for FriendlyErrorsPlugin + watchOptions: { + poll: config.dev.poll, + } + }, + plugins: [ + new webpack.DefinePlugin({ + 'process.env': require('../config/dev.env') + }), + new webpack.HotModuleReplacementPlugin(), + new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update. + new webpack.NoEmitOnErrorsPlugin(), + // https://github.com/ampedandwired/html-webpack-plugin + new HtmlWebpackPlugin({ + filename: 'index.html', + template: 'index.html', + inject: true + }), + // copy custom static assets + new CopyWebpackPlugin([ + { + from: path.resolve(__dirname, '../static'), + to: config.dev.assetsSubDirectory, + ignore: ['.*'] + } + ]) + ] +}) + +module.exports = new Promise((resolve, reject) => { + portfinder.basePort = process.env.PORT || config.dev.port + portfinder.getPort((err, port) => { + if (err) { + reject(err) + } else { + // publish the new Port, necessary for e2e tests + process.env.PORT = port + // add port to devServer config + devWebpackConfig.devServer.port = port + + // Add FriendlyErrorsPlugin + devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({ + compilationSuccessInfo: { + messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`], + }, + onErrors: config.dev.notifyOnErrors + ? utils.createNotifierCallback() + : undefined + })) + + resolve(devWebpackConfig) + } + }) +}) diff --git a/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/build/webpack.prod.conf.js b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/build/webpack.prod.conf.js new file mode 100644 index 0000000000..3e25238ef6 --- /dev/null +++ b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/build/webpack.prod.conf.js @@ -0,0 +1,145 @@ +'use strict' +const path = require('path') +const utils = require('./utils') +const webpack = require('webpack') +const config = require('../config') +const merge = require('webpack-merge') +const baseWebpackConfig = require('./webpack.base.conf') +const CopyWebpackPlugin = require('copy-webpack-plugin') +const HtmlWebpackPlugin = require('html-webpack-plugin') +const ExtractTextPlugin = require('extract-text-webpack-plugin') +const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin') +const UglifyJsPlugin = require('uglifyjs-webpack-plugin') + +const env = require('../config/prod.env') + +const webpackConfig = merge(baseWebpackConfig, { + module: { + rules: utils.styleLoaders({ + sourceMap: config.build.productionSourceMap, + extract: true, + usePostCSS: true + }) + }, + devtool: config.build.productionSourceMap ? config.build.devtool : false, + output: { + path: config.build.assetsRoot, + filename: utils.assetsPath('js/[name].[chunkhash].js'), + chunkFilename: utils.assetsPath('js/[id].[chunkhash].js') + }, + plugins: [ + // http://vuejs.github.io/vue-loader/en/workflow/production.html + new webpack.DefinePlugin({ + 'process.env': env + }), + new UglifyJsPlugin({ + uglifyOptions: { + compress: { + warnings: false + } + }, + sourceMap: config.build.productionSourceMap, + parallel: true + }), + // extract css into its own file + new ExtractTextPlugin({ + filename: utils.assetsPath('css/[name].[contenthash].css'), + // Setting the following option to `false` will not extract CSS from codesplit chunks. + // Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack. + // It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`, + // increasing file size: https://github.com/vuejs-templates/webpack/issues/1110 + allChunks: true, + }), + // Compress extracted CSS. We are using this plugin so that possible + // duplicated CSS from different components can be deduped. + new OptimizeCSSPlugin({ + cssProcessorOptions: config.build.productionSourceMap + ? { safe: true, map: { inline: false } } + : { safe: true } + }), + // generate dist index.html with correct asset hash for caching. + // you can customize output by editing /index.html + // see https://github.com/ampedandwired/html-webpack-plugin + new HtmlWebpackPlugin({ + filename: config.build.index, + template: 'index.html', + inject: true, + minify: { + removeComments: true, + collapseWhitespace: true, + removeAttributeQuotes: true + // more options: + // https://github.com/kangax/html-minifier#options-quick-reference + }, + // necessary to consistently work with multiple chunks via CommonsChunkPlugin + chunksSortMode: 'dependency' + }), + // keep module.id stable when vendor modules does not change + new webpack.HashedModuleIdsPlugin(), + // enable scope hoisting + new webpack.optimize.ModuleConcatenationPlugin(), + // split vendor js into its own file + new webpack.optimize.CommonsChunkPlugin({ + name: 'vendor', + minChunks (module) { + // any required modules inside node_modules are extracted to vendor + return ( + module.resource && + /\.js$/.test(module.resource) && + module.resource.indexOf( + path.join(__dirname, '../node_modules') + ) === 0 + ) + } + }), + // extract webpack runtime and module manifest to its own file in order to + // prevent vendor hash from being updated whenever app bundle is updated + new webpack.optimize.CommonsChunkPlugin({ + name: 'manifest', + minChunks: Infinity + }), + // This instance extracts shared chunks from code split chunks and bundles them + // in a separate chunk, similar to the vendor chunk + // see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk + new webpack.optimize.CommonsChunkPlugin({ + name: 'app', + async: 'vendor-async', + children: true, + minChunks: 3 + }), + + // copy custom static assets + new CopyWebpackPlugin([ + { + from: path.resolve(__dirname, '../static'), + to: config.build.assetsSubDirectory, + ignore: ['.*'] + } + ]) + ] +}) + +if (config.build.productionGzip) { + const CompressionWebpackPlugin = require('compression-webpack-plugin') + + webpackConfig.plugins.push( + new CompressionWebpackPlugin({ + asset: '[path].gz[query]', + algorithm: 'gzip', + test: new RegExp( + '\\.(' + + config.build.productionGzipExtensions.join('|') + + ')$' + ), + threshold: 10240, + minRatio: 0.8 + }) + ) +} + +if (config.build.bundleAnalyzerReport) { + const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin + webpackConfig.plugins.push(new BundleAnalyzerPlugin()) +} + +module.exports = webpackConfig diff --git a/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/config/dev.env.js b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/config/dev.env.js new file mode 100644 index 0000000000..1e22973ae7 --- /dev/null +++ b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/config/dev.env.js @@ -0,0 +1,7 @@ +'use strict' +const merge = require('webpack-merge') +const prodEnv = require('./prod.env') + +module.exports = merge(prodEnv, { + NODE_ENV: '"development"' +}) diff --git a/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/config/index.js b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/config/index.js new file mode 100644 index 0000000000..c5eded7f81 --- /dev/null +++ b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/config/index.js @@ -0,0 +1,69 @@ +'use strict' +// Template version: 1.3.1 +// see http://vuejs-templates.github.io/webpack for documentation. + +const path = require('path') + +module.exports = { + dev: { + + // Paths + assetsSubDirectory: 'static', + assetsPublicPath: '/', + proxyTable: {}, + + // Various Dev Server settings + host: 'localhost', // can be overwritten by process.env.HOST + port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined + autoOpenBrowser: false, + errorOverlay: true, + notifyOnErrors: true, + poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions- + + + /** + * Source Maps + */ + + // https://webpack.js.org/configuration/devtool/#development + devtool: 'cheap-module-eval-source-map', + + // If you have problems debugging vue-files in devtools, + // set this to false - it *may* help + // https://vue-loader.vuejs.org/en/options.html#cachebusting + cacheBusting: true, + + cssSourceMap: true + }, + + build: { + // Template for index.html + index: path.resolve(__dirname, '../dist/index.html'), + + // Paths + assetsRoot: path.resolve(__dirname, '../dist'), + assetsSubDirectory: 'static', + assetsPublicPath: '/', + + /** + * Source Maps + */ + + productionSourceMap: true, + // https://webpack.js.org/configuration/devtool/#production + devtool: '#source-map', + + // Gzip off by default as many popular static hosts such as + // Surge or Netlify already gzip all static assets for you. + // Before setting to `true`, make sure to: + // npm install --save-dev compression-webpack-plugin + productionGzip: false, + productionGzipExtensions: ['js', 'css'], + + // Run the build command with an extra argument to + // View the bundle analyzer report after build finishes: + // `npm run build --report` + // Set to `true` or `false` to always turn it on or off + bundleAnalyzerReport: process.env.npm_config_report + } +} diff --git a/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/config/prod.env.js b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/config/prod.env.js new file mode 100644 index 0000000000..a6f997616e --- /dev/null +++ b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/config/prod.env.js @@ -0,0 +1,4 @@ +'use strict' +module.exports = { + NODE_ENV: '"production"' +} diff --git a/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/index.html b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/index.html new file mode 100644 index 0000000000..03ce3fdf27 --- /dev/null +++ b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/index.html @@ -0,0 +1,12 @@ + + + + + + deplugin-view-frontend + + +
+ + + diff --git a/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/package.json b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/package.json new file mode 100644 index 0000000000..9f3f16ac31 --- /dev/null +++ b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/package.json @@ -0,0 +1,72 @@ +{ + "name": "deplugin-view-frontend", + "version": "1.0.0", + "description": "A Vue.js project", + "author": "", + "private": true, + "scripts": { + "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js", + "start": "npm run dev", + "build": "node build/build.js", + "buildPlugin": "node build/build-async-plugins.js" + }, + "dependencies": { + "@riophae/vue-treeselect": "0.4.0", + "vue": "^2.5.2", + "vue-i18n": "7.3.2", + "vue-router": "^3.0.1", + "vue-uuid": "2.0.2", + "vuedraggable": "^2.24.3" + }, + "devDependencies": { + "autoprefixer": "^7.1.2", + "babel-core": "^6.22.1", + "babel-helper-vue-jsx-merge-props": "^2.0.3", + "babel-loader": "^7.1.1", + "babel-plugin-syntax-jsx": "^6.18.0", + "babel-plugin-transform-runtime": "^6.22.0", + "babel-plugin-transform-vue-jsx": "^3.5.0", + "babel-preset-env": "^1.3.2", + "babel-preset-stage-2": "^6.22.0", + "chalk": "^2.0.1", + "copy-webpack-plugin": "^4.6.0", + "css-loader": "^0.28.0", + "element-ui": "2.15.7", + "extract-text-webpack-plugin": "^4.0.0-beta.0", + "file-loader": "^1.1.4", + "friendly-errors-webpack-plugin": "^1.6.1", + "html-webpack-plugin": "^3.2.0", + "js-cookie": "2.2.0", + "node-notifier": "^8.0.1", + "optimize-css-assets-webpack-plugin": "^3.2.0", + "ora": "^1.2.0", + "portfinder": "^1.0.13", + "postcss-import": "^11.0.0", + "postcss-loader": "^2.0.8", + "postcss-url": "^7.2.1", + "rimraf": "^2.6.0", + "sass": "^1.33.0", + "sass-loader": "^7.3.1", + "semver": "^5.3.0", + "shelljs": "^0.8.5", + "svg-sprite-loader": "4.1.3", + "uglifyjs-webpack-plugin": "^1.1.1", + "url-loader": "^0.5.8", + "vue-loader": "^15.6.4", + "vue-style-loader": "^4.1.2", + "vue-template-compiler": "^2.5.2", + "webpack": "^4.8.1", + "webpack-bundle-analyzer": "^3.3.2", + "webpack-dev-server": "^3.1.11", + "webpack-merge": "^4.1.0" + }, + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + }, + "browserslist": [ + "> 1%", + "last 2 versions", + "not ie <= 8" + ] +} diff --git a/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/pom.xml b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/pom.xml new file mode 100644 index 0000000000..aa8c91048e --- /dev/null +++ b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/pom.xml @@ -0,0 +1,80 @@ + + + + + io.dataease + view-bubblemap + ${dataease.version} + + + 4.0.0 + view-bubblemap-frontend + + + UTF-8 + UTF-8 + 1.9.1 + + + + + + maven-clean-plugin + + + + static + + ** + + false + + + + + + + + com.github.eirslett + frontend-maven-plugin + ${frontend-maven-plugin.version} + + + install node and npm + + install-node-and-npm + + + + v16.20.2 + 7.6.3 + + + + + npm install + + npm + + + + install --force + + + + + npm run buildPlugin + + npm + + + run buildPlugin + + + + + + + diff --git a/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/App.vue b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/App.vue new file mode 100644 index 0000000000..8542e07722 --- /dev/null +++ b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/App.vue @@ -0,0 +1,23 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/assets/logo.png b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/assets/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..f3d2503fc2a44b5053b0837ebea6e87a2d339a43 GIT binary patch literal 6849 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 +
+

{{ msg }}

+

Essential Links

+ +

Ecosystem

+ +
+ + + + + + diff --git a/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/components/SvgIcon/index.vue b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/components/SvgIcon/index.vue new file mode 100644 index 0000000000..0446ae9079 --- /dev/null +++ b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/components/SvgIcon/index.vue @@ -0,0 +1,68 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/components/selector/BackgroundColorSelector.vue b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/components/selector/BackgroundColorSelector.vue new file mode 100644 index 0000000000..2b63c34b80 --- /dev/null +++ b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/components/selector/BackgroundColorSelector.vue @@ -0,0 +1,102 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/components/selector/ColorSelector.vue b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/components/selector/ColorSelector.vue new file mode 100644 index 0000000000..818c86da35 --- /dev/null +++ b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/components/selector/ColorSelector.vue @@ -0,0 +1,335 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/components/selector/LabelSelector.vue b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/components/selector/LabelSelector.vue new file mode 100644 index 0000000000..b50acc1763 --- /dev/null +++ b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/components/selector/LabelSelector.vue @@ -0,0 +1,203 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/components/selector/SuspensionSelector.vue b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/components/selector/SuspensionSelector.vue new file mode 100644 index 0000000000..547d0bcad0 --- /dev/null +++ b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/components/selector/SuspensionSelector.vue @@ -0,0 +1,116 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/components/selector/TitleSelector.vue b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/components/selector/TitleSelector.vue new file mode 100644 index 0000000000..ce0c34bedc --- /dev/null +++ b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/components/selector/TitleSelector.vue @@ -0,0 +1,164 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/components/selector/TooltipSelector.vue b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/components/selector/TooltipSelector.vue new file mode 100644 index 0000000000..af8cab1259 --- /dev/null +++ b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/components/selector/TooltipSelector.vue @@ -0,0 +1,159 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/components/views/ChartDragItem.vue b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/components/views/ChartDragItem.vue new file mode 100644 index 0000000000..53ae1e2ad0 --- /dev/null +++ b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/components/views/ChartDragItem.vue @@ -0,0 +1,278 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/components/views/DimensionExtItem.vue b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/components/views/DimensionExtItem.vue new file mode 100644 index 0000000000..c414ad2d36 --- /dev/null +++ b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/components/views/DimensionExtItem.vue @@ -0,0 +1,256 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/components/views/DimensionItem.vue b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/components/views/DimensionItem.vue new file mode 100644 index 0000000000..156e95f5c0 --- /dev/null +++ b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/components/views/DimensionItem.vue @@ -0,0 +1,256 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/components/views/DrillItem.vue b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/components/views/DrillItem.vue new file mode 100644 index 0000000000..4049ac49c0 --- /dev/null +++ b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/components/views/DrillItem.vue @@ -0,0 +1,146 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/components/views/FieldErrorTips.vue b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/components/views/FieldErrorTips.vue new file mode 100644 index 0000000000..9d7b574721 --- /dev/null +++ b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/components/views/FieldErrorTips.vue @@ -0,0 +1,21 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/components/views/FilterItem.vue b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/components/views/FilterItem.vue new file mode 100644 index 0000000000..3dd5952d69 --- /dev/null +++ b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/components/views/FilterItem.vue @@ -0,0 +1,154 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/components/views/QuotaExtItem.vue b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/components/views/QuotaExtItem.vue new file mode 100644 index 0000000000..c88a060a84 --- /dev/null +++ b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/components/views/QuotaExtItem.vue @@ -0,0 +1,363 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/components/views/QuotaItem.vue b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/components/views/QuotaItem.vue new file mode 100644 index 0000000000..b081f99c2f --- /dev/null +++ b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/components/views/QuotaItem.vue @@ -0,0 +1,345 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/components/views/ViewTrackBar.vue b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/components/views/ViewTrackBar.vue new file mode 100644 index 0000000000..605c0627b5 --- /dev/null +++ b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/components/views/ViewTrackBar.vue @@ -0,0 +1,59 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/components/views/utils.js b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/components/views/utils.js new file mode 100644 index 0000000000..0290965c94 --- /dev/null +++ b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/components/views/utils.js @@ -0,0 +1,34 @@ +export function getItemType(dimensionData, quotaData, item) { + // 将item的字段在数据集维度、指标字段中查询一遍,如果遇到id不存在、字段类型不一致、维度指标不一致,则提示 + const status = item.groupType + let checked = false + if (status === 'd') { + for (let i = 0; i < dimensionData.length; i++) { + const ele = dimensionData[i] + if (ele.id === item.id && ele.deType === item.deType && ele.groupType === item.groupType) { + checked = true + break + } + } + } + if (status === 'q') { + for (let i = 0; i < quotaData.length; i++) { + const ele = quotaData[i] + if (ele.id === item.id && ele.deType === item.deType && ele.groupType === item.groupType) { + checked = true + break + } + } + } + + if (checked) { + if (status === 'd') { + return '' + } else if (status === 'q') { + return 'success' + } + } else { + return 'danger' + } + } + \ No newline at end of file diff --git a/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/de-base/lang/en.js b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/de-base/lang/en.js new file mode 100644 index 0000000000..72c77c6ece --- /dev/null +++ b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/de-base/lang/en.js @@ -0,0 +1,8 @@ +export default { + plugin_view_buddle_map: { + type_title: 'Bubble Map', + area: 'Area', + buddle_size: 'Bubble Size', + area_range: 'Map Ranger' + } +} \ No newline at end of file diff --git a/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/de-base/lang/index.js b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/de-base/lang/index.js new file mode 100644 index 0000000000..37660077b2 --- /dev/null +++ b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/de-base/lang/index.js @@ -0,0 +1,48 @@ +import Vue from 'vue' +import VueI18n from 'vue-i18n' +import Cookies from 'js-cookie' +import elementEnLocale from 'element-ui/lib/locale/lang/en' // element-ui lang +import elementZhLocale from 'element-ui/lib/locale/lang/zh-CN'// element-ui lang +import elementTWLocale from 'element-ui/lib/locale/lang/zh-TW'// element-ui lang + +import localMessages from './messages' + +Vue.use(VueI18n) + +const messages = { + en_US: { + ...localMessages['en_US'], + ...elementEnLocale + }, + zh_CN: { + ...localMessages['zh_CN'], + ...elementZhLocale + }, + zh_TW: { + ...localMessages['zh_TW'], + ...elementTWLocale + } +} +export function getLanguage () { + const chooseLanguage = Cookies.get('language') + if (chooseLanguage) return chooseLanguage + + // if has not choose language + const language = (navigator.language || navigator.browserLanguage).toLowerCase() + const locales = Object.keys(messages) + for (const locale of locales) { + if (language.indexOf(locale) > -1) { + return locale + } + } + return 'zh_CN' +} +const i18n = new VueI18n({ + // set locale + // options: en | zh | es + locale: getLanguage(), + // set locale messages + messages +}) + +export default i18n diff --git a/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/de-base/lang/messages.js b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/de-base/lang/messages.js new file mode 100644 index 0000000000..844f8c0673 --- /dev/null +++ b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/de-base/lang/messages.js @@ -0,0 +1,17 @@ +import enLocale from './en' +import zhLocale from './zh' +import twLocale from './tw' + +const messages = { + en_US: { + ...enLocale + }, + zh_CN: { + ...zhLocale + }, + zh_TW: { + ...twLocale + } +} + +export default messages \ No newline at end of file diff --git a/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/de-base/lang/tw.js b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/de-base/lang/tw.js new file mode 100644 index 0000000000..5f17cae602 --- /dev/null +++ b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/de-base/lang/tw.js @@ -0,0 +1,8 @@ +export default { + plugin_view_buddle_map: { + type_title: '氣泡地圖', + area: '地區', + buddle_size: '氣泡大小', + area_range: '地圖範圍' + } +} \ No newline at end of file diff --git a/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/de-base/lang/zh.js b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/de-base/lang/zh.js new file mode 100644 index 0000000000..9386792797 --- /dev/null +++ b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/de-base/lang/zh.js @@ -0,0 +1,8 @@ +export default { + plugin_view_buddle_map: { + type_title: '气泡地图', + area: '地区', + buddle_size: '气泡大小', + area_range: '地图范围' + } +} \ No newline at end of file diff --git a/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/icons/index.js b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/icons/index.js new file mode 100644 index 0000000000..2c6b309c96 --- /dev/null +++ b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/icons/index.js @@ -0,0 +1,9 @@ +import Vue from 'vue' +import SvgIcon from '@/components/SvgIcon'// svg component + +// register globally +Vue.component('svg-icon', SvgIcon) + +const req = require.context('./svg', false, /\.svg$/) +const requireAll = requireContext => requireContext.keys().map(requireContext) +requireAll(req) diff --git a/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/icons/svg/buddle-map.svg b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/icons/svg/buddle-map.svg new file mode 100644 index 0000000000..5b10c334fa --- /dev/null +++ b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/icons/svg/buddle-map.svg @@ -0,0 +1 @@ + diff --git a/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/icons/svg/view-bubblemap-backend.svg b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/icons/svg/view-bubblemap-backend.svg new file mode 100644 index 0000000000..58f6a07f97 --- /dev/null +++ b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/icons/svg/view-bubblemap-backend.svg @@ -0,0 +1 @@ +【icon】插件管理-导出 \ No newline at end of file diff --git a/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/icons/svgo.yml b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/icons/svgo.yml new file mode 100644 index 0000000000..e69de29bb2 diff --git a/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/main.js b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/main.js new file mode 100644 index 0000000000..fb8f35373c --- /dev/null +++ b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/main.js @@ -0,0 +1,34 @@ +// The Vue build version to load with the `import` command +// (runtime-only or standalone) has been set in webpack.base.conf with an alias. +import Vue from 'vue' +import App from './App' +import router from './router' +import ElementUI from 'element-ui' +import Cookies from 'js-cookie' +import i18n from './de-base/lang' +import draggable from 'vuedraggable' +import Treeselect from '@riophae/vue-treeselect' +import '@riophae/vue-treeselect/dist/vue-treeselect.css' +import '@/icons' // icon +Vue.config.productionTip = false +Vue.use(ElementUI, { + size: Cookies.get('size') || 'medium', + i18n: (key, value) => i18n.t(key, value) +}) +Vue.component('Treeselect', Treeselect) +Vue.component('draggable', draggable) +Vue.prototype.hasDataPermission = function(pTarget, pSource) { + + if (pSource && pTarget) { + return pSource.indexOf(pTarget) > -1 + } + return false +} +/* eslint-disable no-new */ +new Vue({ + el: '#app', + router, + i18n, + components: { App }, + template: '' +}) diff --git a/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/router/index.js b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/router/index.js new file mode 100644 index 0000000000..2ed15dc60d --- /dev/null +++ b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/router/index.js @@ -0,0 +1,27 @@ +import Vue from 'vue' +import Router from 'vue-router' +import HelloWorld from '@/components/HelloWorld' +import BuddleType from '@/views/echarts/map/buddle/type' +import BuddleData from '@/views/echarts/map/test' + +Vue.use(Router) + +export default new Router({ + routes: [ + { + path: '/', + name: 'HelloWorld', + component: HelloWorld + }, + { + path: '/buddle-type', + name: 'buddle-type', + component: BuddleType + }, + { + path: '/buddle-data', + name: 'buddle-data', + component: BuddleData + } + ] +}) diff --git a/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/utils/compare.js b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/utils/compare.js new file mode 100644 index 0000000000..b06a104a10 --- /dev/null +++ b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/utils/compare.js @@ -0,0 +1,29 @@ +export const compareItem = { + type: 'none', // year-yoy/month-yoy等 + resultData: 'percent', // 对比差sub,百分比percent等 + field: '', + custom: { + field: '', + calcType: '0', // 0-增长值,1-增长率 + timeType: '0', // 0-固定日期,1-日期区间 + currentTime: '', + compareTime: '', + currentTimeRange: [], + compareTimeRange: [] + } +} + +export const compareYearList = [ + { name: 'year_mom', value: 'year_mom' } +] + +export const compareMonthList = [ + { name: 'month_mom', value: 'month_mom' }, + { name: 'year_yoy', value: 'year_yoy' } +] + +export const compareDayList = [ + { name: 'day_mom', value: 'day_mom' }, + { name: 'month_yoy', value: 'month_yoy' }, + { name: 'year_yoy', value: 'year_yoy' } +] diff --git a/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/utils/map.js b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/utils/map.js new file mode 100644 index 0000000000..3dea431749 --- /dev/null +++ b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/utils/map.js @@ -0,0 +1,370 @@ +export const DEFAULT_COLOR_CASE = { + value: 'default', + colors: ['#5470c6', '#91cc75', '#fac858', '#ee6666', '#73c0de', '#3ba272', '#fc8452', '#9a60b4', '#ea7ccc'], + alpha: 100, + tableHeaderBgColor: '#e1eaff', + tableItemBgColor: '#ffffff', + tableFontColor: '#000000', + tableStripe: true, + dimensionColor: '#000000', + quotaColor: '#000000', + tableBorderColor: '#cfdaf4', + areaBorderColor: '#303133', + areaBaseColor: '#ffffff' +} + +export const COLOR_PANEL = [ + '#ff4500', + '#ff8c00', + '#ffd700', + '#90ee90', + '#00ced1', + '#1e90ff', + '#c71585', + '#999999', + '#000000', + '#FFFFFF' +] + +export const DEFAULT_LABEL = { + show: false, + position: 'top', + color: '#909399', + fontSize: '10', + formatter: '{c}', + gaugeFormatter: '{value}', + labelLine: { + show: true + } +} +export const DEFAULT_TOOLTIP = { + show: true, + trigger: 'item', + confine: true, + textStyle: { + fontSize: '10', + color: '#909399' + }, + formatter: '' +} +export const DEFAULT_TITLE_STYLE = { + show: true, + fontSize: '18', + color: '#303133', + hPosition: 'center', + vPosition: 'top', + isItalic: false, + isBolder: false +} +export const DEFAULT_BACKGROUND_COLOR = { + color: '#ffffff', + alpha: 100, + borderRadius: 5 +} +export const DEFAULT_SUSPENSION = { + show: true +} +export const BASE_MAP = { + title: { + text: '', + textStyle: { + fontWeight: 'normal' + } + }, + visualMap: { + min: 50, + max: 52, + text: ['High', 'Low'], + realtime: false, + calculable: true, + inRange: { + color: ['lightskyblue', 'yellow', 'orangered'] + }, + right: 0, + textStyle: {} + }, + + tooltip: {}, + geo: [ + { + show: true, + roam: true, + map: 'BUDDLE_MAP', + label: { + normal: { + show: false + }, + emphasis: { + show: false + } + }, + itemStyle: { + areaColor: '#f3f3f3', + borderType: 'dashed', + borderColor: '#fff' + } + } + ], + series: [{ + name: '', + type: 'scatter', + coordinateSystem: 'geo', + data: [] + }] +} +const convertData = (mapData, chart, curAreaCode) => { + if (chart.senior) { + const senior = JSON.parse(chart.senior) + const mapMapping = senior && senior.mapMapping && senior.mapMapping[curAreaCode] + if (mapMapping) { + for (const key in mapMapping) { + if (Object.hasOwnProperty.call(mapMapping, key)) { + const element = mapMapping[key] + if (element && mapData[key]) { + mapData[element] = mapData[key] + } + + } + } + } + } + let maxVal = 0 + const k = terminalType === 'pc' ? 30 : 15 + const names = chart.data.x + const results = [] + for (let index = 0; index < names.length; index++) { + const name = names[index]; + const item = chart.data.series[0].data[index] + results.push({ + name, + value: (mapData[name] ? mapData[name].concat(item.value) : []), + dimensionList: item.dimensionList, + quotaList: item.quotaList + }) + maxVal = Math.max(maxVal, item.value) + } + const rate = k / maxVal + + return { + value: results, + rate: rate + } +} + +let terminalType = 'pc' +export function baseMapOption(chart_option, chart, mapData, terminal = 'pc', themeStyle, curAreaCode) { + terminalType = terminal + let customAttr = {} + if (chart.customAttr) { + customAttr = JSON.parse(chart.customAttr) + if (customAttr.color) { + chart_option.color = customAttr.color.colors + if (customAttr.color.areaBorderColor) { + chart_option.geo.forEach(item => { + item.itemStyle.borderColor = customAttr.color.areaBorderColor + }) + } + if (customAttr.color.areaBaseColor) { + chart_option.geo[chart_option.geo.length - 1].itemStyle.areaColor = customAttr.color.areaBaseColor + chart_option.geo[chart_option.geo.length - 1].itemStyle.opacity = 0.7 + chart_option.geo[chart_option.geo.length - 1].emphasis = { + itemStyle: { + areaColor: customAttr.color.areaBaseColor, + opacity: 1 + } + } + } + } + if (customAttr.tooltip) { + const tooltip = JSON.parse(JSON.stringify(customAttr.tooltip)) + const reg = new RegExp('\n', 'g') + const text = tooltip.formatter.replace(reg, '
') + tooltip.formatter = function (params) { + const a = params.seriesName + const b = params.name + const c = params.value ? params.value[2] : '' + return text.replace(new RegExp('{a}', 'g'), a).replace(new RegExp('{b}', 'g'), b).replace(new RegExp('{c}', 'g'), c) + } + chart_option.tooltip = tooltip + } + } + chart_option.title.text = chart.title + if (chart.data) { + if (chart.data.series && chart.data.series.length > 0) { + chart_option.series[0].name = chart.data.series[0].name + if (customAttr.label) { + const text = customAttr.label.formatter + chart_option.series[0].label = customAttr.label + chart_option.series[0].label.formatter = function (params) { + const a = params.seriesName + const b = params.name + const c = params.value ? params.value[2] : '' + return text.replace(new RegExp('{a}', 'g'), a).replace(new RegExp('{b}', 'g'), b).replace(new RegExp('{c}', 'g'), c) + } + chart_option.series[0].labelLine = customAttr.label.labelLine + } + + const valueArr = chart.data.series[0].data + if (valueArr && valueArr.length > 0) { + const values = [] + valueArr.forEach(function (ele) { + values.push(ele.value) + }) + chart_option.visualMap.min = Math.min(...values) + chart_option.visualMap.max = Math.max(...values) + if (chart_option.visualMap.min === chart_option.visualMap.max) { + chart_option.visualMap.min = 0 + } + } else { + chart_option.visualMap.min = 0 + chart_option.visualMap.max = 0 + } + if (chart_option.visualMap.min === 0 && chart_option.visualMap.max === 0) { + chart_option.visualMap.max = 100 + } + if (customAttr.color && customAttr.color.colors) { + chart_option.visualMap.inRange.color = customAttr.color.colors + chart_option.visualMap.inRange.colorAlpha = customAttr.color.alpha / 100 + } + if (themeStyle) { + + chart_option.visualMap.textStyle = { + color: themeStyle + } + } + if (customAttr.suspension && !customAttr.suspension.show) { + chart_option.visualMap.show = false + } else if ('show' in chart_option.visualMap) { + delete chart_option.visualMap.show + } + const convert = convertData(mapData, chart, curAreaCode) + chart_option.series[0].data = convert.value + chart_option.series[0].symbolSize = val => val[2] * convert.rate + + if (chart.senior) { + const senior = JSON.parse(chart.senior) + + senior && senior.mapMapping && senior.mapMapping[curAreaCode] && (chart_option.series[0].nameMap = senior.mapMapping[curAreaCode]) + } + + } + } + componentStyle(chart_option, chart) + return chart_option +} +export function componentStyle(chart_option, chart) { + const padding = '8px' + if (chart.customStyle) { + const customStyle = JSON.parse(chart.customStyle) + if (customStyle.text) { + chart_option.title.show = customStyle.text.show + if (customStyle.text.hPosition === 'left') { + chart_option.title.left = padding + } else if (customStyle.text.hPosition === 'right') { + chart_option.title.right = padding + } else { + chart_option.title.left = customStyle.text.hPosition + } + if (customStyle.text.vPosition === 'top') { + chart_option.title.top = padding + } else if (customStyle.text.vPosition === 'bottom') { + chart_option.title.bottom = padding + } else { + chart_option.title.top = customStyle.text.vPosition + } + const style = chart_option.title.textStyle ? chart_option.title.textStyle : {} + style.fontSize = customStyle.text.fontSize + style.color = customStyle.text.color + customStyle.text.isItalic ? style.fontStyle = 'italic' : style.fontStyle = 'normal' + customStyle.text.isBolder ? style.fontWeight = 'bold' : style.fontWeight = 'normal' + chart_option.title.textStyle = style + } + if (customStyle.legend && chart_option.legend) { + chart_option.legend.show = customStyle.legend.show + if (customStyle.legend.hPosition === 'left') { + chart_option.legend.left = padding + } else if (customStyle.legend.hPosition === 'right') { + chart_option.legend.right = padding + } else { + chart_option.legend.left = customStyle.legend.hPosition + } + if (customStyle.legend.vPosition === 'top') { + chart_option.legend.top = padding + } else if (customStyle.legend.vPosition === 'bottom') { + chart_option.legend.bottom = padding + } else { + chart_option.legend.top = customStyle.legend.vPosition + } + chart_option.legend.orient = customStyle.legend.orient + chart_option.legend.icon = customStyle.legend.icon + chart_option.legend.textStyle = customStyle.legend.textStyle + + } + + if (customStyle.background) { + chart_option.backgroundColor = hexColorToRGBA(customStyle.background.color, customStyle.background.alpha) + } + } +} +export function hexColorToRGBA(hex, alpha) { + const rgb = [] + if (/^\#[0-9A-F]{3}$/i.test(hex)) { + let sixHex = '#' + hex.replace(/[0-9A-F]/ig, function (kw) { + sixHex += kw + kw + }) + hex = sixHex + } + if (/^#[0-9A-F]{6}$/i.test(hex)) { + hex.replace(/[0-9A-F]{2}/ig, function (kw) { + rgb.push(eval('0x' + kw)) + }) + return `rgba(${rgb.join(',')},${alpha / 100})` + } else { + return 'rgb(0,0,0)' + } +} + + + +export const DEFAULT_YAXIS_EXT_STYLE = { + show: true, + position: 'right', + name: '', + nameTextStyle: { + color: '#333333', + fontSize: 12 + }, + axisLabel: { + show: true, + color: '#333333', + fontSize: '12', + rotate: 0, + formatter: '{value}' + }, + splitLine: { + show: true, + lineStyle: { + color: '#cccccc', + width: 1, + style: 'solid' + } + }, + axisValue: { + auto: true, + min: null, + max: null, + split: null, + splitCount: null + } +} + +export function uuid() { + return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1); +} + +export const reverseColor = colorValue => { + colorValue = '0x' + colorValue.replace(/#/g, '') + const str = '000000' + (0xFFFFFF - colorValue).toString(16) + return '#' + str.substring(str.length - 6, str.length) +} diff --git a/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/utils/nationalCenterPoint.js b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/utils/nationalCenterPoint.js new file mode 100644 index 0000000000..f328ebb850 --- /dev/null +++ b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/utils/nationalCenterPoint.js @@ -0,0 +1,750 @@ +export const centerPointJson = { + "Angola": [ + 17.87, + -11.2 + ], + "Afghanistan": [ + 67.71, + 33.94 + ], + "Albania": [ + 20.17, + 41.15 + ], + "Algeria": [ + 1.66, + 28.03 + ], + "Andorra": [ + 1.52, + 42.51 + ], + "Anguilla": [ + -63.07, + 18.22 + ], + "Argentina": [ + -63.62, + -38.42 + ], + "Armenia": [ + 45.04, + 40.07 + ], + "Ascension": [ + -90.94, + 30.2 + ], + "Australia": [ + 133.78, + -25.27 + ], + "Austria": [ + 14.55, + 47.52 + ], + "Azerbaijan": [ + 47.58, + 40.14 + ], + "Bahamas": [ + -77.4, + 25.03 + ], + "Bahrain": [ + 50.56, + 26.07 + ], + "Bangladesh": [ + 90.36, + 23.68 + ], + "Barbados": [ + -59.54, + 13.19 + ], + "Belarus": [ + 27.95, + 53.71 + ], + "Belgium": [ + 4.47, + 50.5 + ], + "Belize": [ + -88.5, + 17.19 + ], + "Benin": [ + 2.32, + 9.31 + ], + "Bermuda Is": [ + -64.75, + 32.31 + ], + "Bolivia": [ + -63.59, + -16.29 + ], + "Botswana": [ + 24.68, + -22.33 + ], + "Brazil": [ + -51.93, + -14.24 + ], + "Brunei": [ + 114.73, + 4.54 + ], + "Bulgaria": [ + 25.49, + 42.73 + ], + "Burkina-faso": [ + -1.56, + 12.24 + ], + "Burma": [ + 95.96, + 21.92 + ], + "Burundi": [ + 29.92, + -3.37 + ], + "Cameroon": [ + 12.35, + 7.37 + ], + "Canada": [ + -106.35, + 56.13 + ], + "Cayman Is": [ + -117.64, + 33.64 + ], + "Central African Republic": [ + 20.94, + 6.61 + ], + "Chad": [ + 18.73, + 15.45 + ], + "Chile": [ + -71.54, + -35.68 + ], + "China": [ + 104.2, + 35.86 + ], + "Colombia": [ + -74.3, + 4.57 + ], + "Cook Is": [ + -90.49, + 47.61 + ], + "Costa Rica": [ + -83.75, + 9.75 + ], + "Croatia": [ + 15.2, + 45.1 + ], + "Cuba": [ + -77.78, + 21.52 + ], + "Cyprus": [ + 33.43, + 35.13 + ], + "Czech Republic": [ + 15.47, + 49.82 + ], + "Denmark": [ + 9.5, + 56.26 + ], + "Djibouti": [ + 42.59, + 11.83 + ], + "Dominica Rep": [ + -0.19, + 51.52 + ], + "Ecuador": [ + -78.18, + -1.83 + ], + "Egypt": [ + 30.8, + 26.82 + ], + "EI Salvador": [ + -88.9, + 13.79 + ], + "Estonia": [ + 25.01, + 58.6 + ], + "Ethiopia": [ + 40.49, + 9.15 + ], + "Fiji": [ + 178.07, + -17.71 + ], + "Finland": [ + 25.75, + 61.92 + ], + "France": [ + 2.21, + 46.23 + ], + "French Guiana": [ + -53.13, + 3.93 + ], + "Gabon": [ + 11.61, + -0.8 + ], + "Gambia": [ + -15.31, + 13.44 + ], + "Georgia": [ + -82.9, + 32.17 + ], + "Germany": [ + 10.45, + 51.17 + ], + "Ghana": [ + -1.02, + 7.95 + ], + "Gibraltar": [ + -5.35, + 36.14 + ], + "Greece": [ + 21.82, + 39.07 + ], + "Grenada": [ + -61.68, + 12.12 + ], + "Guam": [ + 144.79, + 13.44 + ], + "Guatemala": [ + -90.23, + 15.78 + ], + "Guinea": [ + -9.7, + 9.95 + ], + "Guyana": [ + -58.93, + 4.86 + ], + "Haiti": [ + -72.29, + 18.97 + ], + "Honduras": [ + -86.24, + 15.2 + ], + "Hong Kong": [ + 114.11, + 22.4 + ], + "Hungary": [ + 19.5, + 47.16 + ], + "Iceland": [ + -19.02, + 64.96 + ], + "India": [ + 78.96, + 20.59 + ], + "Indonesia": [ + 113.92, + -0.79 + ], + "Iran": [ + 53.69, + 32.43 + ], + "Iraq": [ + 43.68, + 33.22 + ], + "Ireland": [ + -8.24, + 53.41 + ], + "Israel": [ + 34.85, + 31.05 + ], + "Italy": [ + 12.57, + 41.87 + ], + "Ivory Coast": [ + -5.55, + 7.54 + ], + "Japan": [ + 138.25, + 36.2 + ], + "Jordan": [ + 36.24, + 30.59 + ], + "Kampuchea": [ + 105.46, + 12 + ], + "Kazakhstan": [ + 66.92, + 48.02 + ], + "Kenya": [ + 37.91, + -0.02 + ], + "Korea": [ + 127.98, + 37.66 + ], + "Kuwait": [ + 47.48, + 29.31 + ], + "Kyrgyzstan": [ + 74.77, + 41.2 + ], + "Laos": [ + 102.5, + 19.86 + ], + "Latvia": [ + 24.6, + 56.88 + ], + "Lebanon": [ + 35.86, + 33.85 + ], + "Lesotho": [ + 28.23, + -29.61 + ], + "Liberia": [ + -9.43, + 6.43 + ], + "Libya": [ + 17.23, + 26.34 + ], + "Liechtenstein": [ + 9.56, + 47.17 + ], + "Lithuania": [ + 23.88, + 55.17 + ], + "Luxembourg": [ + 6.13, + 49.82 + ], + "Macao": [ + 113.54, + 22.2 + ], + "Madagascar": [ + 46.87, + -18.77 + ], + "Malawi": [ + 34.3, + -13.25 + ], + "Malaysia": [ + 101.98, + 4.21 + ], + "Maldives": [ + 73.54, + 1.98 + ], + "Mali": [ + -4, + 17.57 + ], + "Malta": [ + 14.38, + 35.94 + ], + "Mariana Is": [ + -43.41, + -20.37 + ], + "Martinique": [ + -61.02, + 14.64 + ], + "Mauritius": [ + 57.55, + -20.35 + ], + "Mexico": [ + -102.55, + 23.63 + ], + "Monaco": [ + 7.42, + 43.74 + ], + "Mongolia": [ + 103.85, + 46.86 + ], + "Montserrat Is": [ + -62.19, + 16.74 + ], + "Morocco": [ + -7.09, + 31.79 + ], + "Mozambique": [ + 35.53, + -18.67 + ], + "Namibia": [ + 18.49, + -22.96 + ], + "Nauru": [ + 166.93, + -0.52 + ], + "Nepal": [ + 84.12, + 28.39 + ], + "Netheriands Antilles": [ + -68.26, + 12.2 + ], + "Netherlands": [ + 5.29, + 52.13 + ], + "New Zealand": [ + 174.89, + -40.9 + ], + "Nicaragua": [ + -85.21, + 12.87 + ], + "Niger": [ + 8.08, + 17.61 + ], + "Nigeria": [ + 8.68, + 9.08 + ], + "North Korea": [ + 127.51, + 40.34 + ], + "Oman": [ + 55.98, + 21.47 + ], + "Pakistan": [ + 69.35, + 30.38 + ], + "Panama": [ + -80.78, + 8.54 + ], + "Papua New Cuinea": [ + 143.96, + -6.31 + ], + "Paraguay": [ + -58.44, + -23.44 + ], + "Peru": [ + -75.02, + -9.19 + ], + "Philippines": [ + 121.77, + 12.88 + ], + "Poland": [ + 19.15, + 51.92 + ], + "French Polynesia": [ + -149.41, + -17.68 + ], + "Portugal": [ + -8.22, + 39.4 + ], + "Puerto Rico": [ + -66.59, + 18.22 + ], + "Qatar": [ + 51.18, + 25.35 + ], + "Reunion": [ + 55.54, + -21.12 + ], + "Romania": [ + 24.97, + 45.94 + ], + "Russia": [ + 105.32, + 61.52 + ], + "Saint Lueia": [ + -60.98, + 13.91 + ], + "Saint Vincent": [ + 7.64, + 45.75 + ], + "Samoa Eastern": [ + -121.83, + 37.35 + ], + "Samoa Western": [ + -124.15, + 40.8 + ], + "San Marino": [ + 12.46, + 43.94 + ], + "Sao Tome and Principe": [ + 6.61, + 0.19 + ], + "Saudi Arabia": [ + 45.08, + 23.89 + ], + "Senegal": [ + -14.45, + 14.5 + ], + "Seychelles": [ + 55.49, + -4.68 + ], + "Sierra Leone": [ + -11.78, + 8.46 + ], + "Singapore": [ + 103.82, + 1.35 + ], + "Slovakia": [ + 19.7, + 48.67 + ], + "Slovenia": [ + 15, + 46.15 + ], + "Solomon Is": [ + -97.37, + 38.92 + ], + "Somali": [ + 46.2, + 5.15 + ], + "South Africa": [ + 22.94, + -30.56 + ], + "Spain": [ + -3.75, + 40.46 + ], + "Sri Lanka": [ + 80.77, + 7.87 + ], + "St.Lucia": [ + -60.98, + 13.91 + ], + "St.Vincent": [ + -91.06, + 29.99 + ], + "Sudan": [ + 30.22, + 12.86 + ], + "Suriname": [ + -56.03, + 3.92 + ], + "Swaziland": [ + 31.47, + -26.52 + ], + "Sweden": [ + 18.64, + 60.13 + ], + "Switzerland": [ + 8.23, + 46.82 + ], + "Syria": [ + 39, + 34.8 + ], + "Taiwan": [ + 120.96, + 23.7 + ], + "Tajikstan": [ + 71.28, + 38.86 + ], + "Thailand": [ + 100.99, + 15.87 + ], + "Togo": [ + 0.82, + 8.62 + ], + "Tonga": [ + -175.2, + -21.18 + ], + "Trinidad and Tobago": [ + -61.22, + 10.69 + ], + "Tunisia": [ + 9.54, + 33.89 + ], + "Turkey": [ + 35.24, + 38.96 + ], + "Turkmenistan": [ + 59.56, + 38.97 + ], + "Uganda": [ + 32.29, + 1.37 + ], + "Ukraine": [ + 31.17, + 48.38 + ], + "United Arab Emirates": [ + 53.85, + 23.42 + ], + "United Kingdom": [ + -3.44, + 55.38 + ], + "United States": [ + -95.71, + 37.09 + ], + "Uruguay": [ + -55.77, + -32.52 + ], + "Uzbekistan": [ + 64.59, + 41.38 + ], + "Venezuela": [ + -66.59, + 6.42 + ], + "Vietnam": [ + 108.28, + 14.06 + ], + "Yemen": [ + 48.52, + 15.55 + ], + "Yugoslavia": [ + 121.02, + 14.48 + ], + "Zimbabwe": [ + 29.15, + -19.02 + ], + "Zaire": [ + 21.76, + -4.04 + ], + "Zambia": [ + 27.85, + -13.13 + ] +} \ No newline at end of file diff --git a/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/utils/validate.js b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/utils/validate.js new file mode 100644 index 0000000000..9becfa3b87 --- /dev/null +++ b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/utils/validate.js @@ -0,0 +1,16 @@ +/** + * Created by PanJiaChen on 16/11/18. + */ + +/** + * @param {string} path + * @returns {Boolean} + */ +export function isExternal(path) { + return /^(https?:|mailto:|tel:)/.test(path) +} + + + + + \ No newline at end of file diff --git a/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/views/PluginDemo.vue b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/views/PluginDemo.vue new file mode 100644 index 0000000000..1164dfab1d --- /dev/null +++ b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/views/PluginDemo.vue @@ -0,0 +1,55 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/views/echarts/map/buddle/data.vue b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/views/echarts/map/buddle/data.vue new file mode 100644 index 0000000000..b4e0834faa --- /dev/null +++ b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/views/echarts/map/buddle/data.vue @@ -0,0 +1,721 @@ + + + + + \ No newline at end of file diff --git a/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/views/echarts/map/buddle/format.js b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/views/echarts/map/buddle/format.js new file mode 100644 index 0000000000..92567b67dc --- /dev/null +++ b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/views/echarts/map/buddle/format.js @@ -0,0 +1,47 @@ +export default class BuddleMap { + + constructor(param, view) { + this.param = param + this.view = view + this.widgets = [ + { + labels: ['地区', '维度'], + value: this.view.xaxis, + dragMove: this.onMove, + dragAdd: this.addXaxis, + dragUpdate: this.calcData, + solt: 'dimension-item' + },{ + labels: ['数据', '指标'], + value: this.view.yaxis, + dragMove: this.onMove, + dragAdd: this.addYaxis, + dragUpdate: this.calcData, + solt: 'quota-item' + } + ] + } + + + calcData(cache) { + + } + + onMove(e) { + + } + + addXaxis(e) { + + } + + addYaxis(e) { + + } + + + + + + +} \ No newline at end of file diff --git a/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/views/echarts/map/buddle/index.vue b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/views/echarts/map/buddle/index.vue new file mode 100644 index 0000000000..951824a1c9 --- /dev/null +++ b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/views/echarts/map/buddle/index.vue @@ -0,0 +1,442 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/views/echarts/map/buddle/style.vue b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/views/echarts/map/buddle/style.vue new file mode 100644 index 0000000000..5e91499364 --- /dev/null +++ b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/views/echarts/map/buddle/style.vue @@ -0,0 +1,160 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/views/echarts/map/buddle/type.vue b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/views/echarts/map/buddle/type.vue new file mode 100644 index 0000000000..571c882c93 --- /dev/null +++ b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/views/echarts/map/buddle/type.vue @@ -0,0 +1,58 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/views/echarts/map/test.vue b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/views/echarts/map/test.vue new file mode 100644 index 0000000000..cfe2c7926b --- /dev/null +++ b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/src/views/echarts/map/test.vue @@ -0,0 +1,21 @@ + + + + + \ No newline at end of file diff --git a/extensions/dataease-extensions-view/view-chartmix/build.sh b/extensions/dataease-extensions-view/view-chartmix/build.sh new file mode 100644 index 0000000000..f66a518028 --- /dev/null +++ b/extensions/dataease-extensions-view/view-chartmix/build.sh @@ -0,0 +1,8 @@ +#!/bin/sh +mvn clean package + +cp view-chartmix-backend/target/view-chartmix-backend-1.18.9.jar . + +zip -r chartmix.zip ./view-chartmix-backend-1.18.9.jar ./plugin.json + +rm -f ./view-chartmix-backend-1.18.9.jar diff --git a/extensions/dataease-extensions-view/view-chartmix/plugin.json b/extensions/dataease-extensions-view/view-chartmix/plugin.json new file mode 100644 index 0000000000..80a3f79aee --- /dev/null +++ b/extensions/dataease-extensions-view/view-chartmix/plugin.json @@ -0,0 +1,13 @@ +{ + "name": "AntV 组合图", + "free": 0, + "store": "default", + "cost": 0, + "category": "view", + "descript": "AntV G2Plot 组合图插件", + "version": "1.18.9", + "creator": "DATAEASE", + "moduleName": "view-chartmix-backend", + "require": "1.18.9", + "dsType": "" +} diff --git a/extensions/dataease-extensions-view/view-chartmix/pom.xml b/extensions/dataease-extensions-view/view-chartmix/pom.xml new file mode 100644 index 0000000000..3554e02c3e --- /dev/null +++ b/extensions/dataease-extensions-view/view-chartmix/pom.xml @@ -0,0 +1,20 @@ + + + + dataease-extensions-view + io.dataease + ${dataease.version} + + 4.0.0 + + view-chartmix + pom + + view-chartmix-frontend + view-chartmix-backend + + + + diff --git a/extensions/dataease-extensions-view/view-chartmix/view-chartmix-backend/pom.xml b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-backend/pom.xml new file mode 100644 index 0000000000..7aae2b3e53 --- /dev/null +++ b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-backend/pom.xml @@ -0,0 +1,109 @@ + + + + view-chartmix + io.dataease + ${dataease.version} + + 4.0.0 + + view-chartmix-backend + + + + io.dataease + dataease-plugin-view + + + + + + + src/main/java + + **/*.properties + **/*.xml + + false + + + src/main/resources + + **/* + + false + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 11 + 11 + + + + + org.apache.maven.plugins + maven-jar-plugin + 2.4 + + + **/server/** + **/*.properties + **/Application* + + + + + + maven-clean-plugin + + + + src/main/resources/static + + ** + + false + + + + + + + + + org.apache.maven.plugins + maven-antrun-plugin + + + main-class-placement + generate-resources + + + + + + + + + + + + run + + + + + + + + + + + diff --git a/extensions/dataease-extensions-view/view-chartmix/view-chartmix-backend/src/main/java/io/dataease/plugins/view/official/handler/DefaultViewStatHandler.java b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-backend/src/main/java/io/dataease/plugins/view/official/handler/DefaultViewStatHandler.java new file mode 100644 index 0000000000..0f37d52e44 --- /dev/null +++ b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-backend/src/main/java/io/dataease/plugins/view/official/handler/DefaultViewStatHandler.java @@ -0,0 +1,103 @@ +package io.dataease.plugins.view.official.handler; + +import io.dataease.plugins.common.constants.datasource.SQLConstants; +import io.dataease.plugins.common.request.permission.DataSetRowPermissionsTreeDTO; +import io.dataease.plugins.common.util.ConstantsUtil; +import io.dataease.plugins.view.entity.*; +import io.dataease.plugins.view.handler.PluginViewStatHandler; +import io.dataease.plugins.view.service.ViewPluginBaseService; +import io.dataease.plugins.view.service.ViewPluginService; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.ObjectUtils; +import org.stringtemplate.v4.ST; +import org.stringtemplate.v4.STGroup; +import org.stringtemplate.v4.STGroupFile; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +public class DefaultViewStatHandler implements PluginViewStatHandler { + + @Override + public String build(PluginViewParam pluginViewParam, ViewPluginService viewPluginService) { + ViewPluginBaseService baseService = viewPluginService.getBaseService(); + PluginViewSet pluginViewSet = pluginViewParam.getPluginViewSet(); + List rowPermissionsTree = pluginViewParam.getRowPermissionsTree(); + String dsType = pluginViewSet.getDsType(); + PluginViewSQL tableObj = baseService.getTableObj(pluginViewSet); + + Map> fieldSQLMap = new HashMap<>(); + + + for (int i = 0; i < pluginViewParam.getPluginViewFields().size(); i++) { + PluginViewField pluginViewField = pluginViewParam.getPluginViewFields().get(i); + String typeKey = pluginViewField.getTypeField(); + PluginSingleField pluginSingleField = baseService.buildField(dsType, pluginViewField, tableObj, i); + List lists = fieldSQLMap.getOrDefault(typeKey, new ArrayList<>()); + lists.add(pluginSingleField); + fieldSQLMap.put(typeKey, lists); + } + + List xFields = fieldSQLMap.getOrDefault("xAxis", new ArrayList<>()).stream().filter(singleField -> ObjectUtils.isNotEmpty(singleField.getField())).map(PluginSingleField::getField).collect(Collectors.toList()); + List xOrders = fieldSQLMap.getOrDefault("xAxis", new ArrayList<>()).stream().filter(singleField -> ObjectUtils.isNotEmpty(singleField.getSort())).map(PluginSingleField::getSort).collect(Collectors.toList()); + // List xWheres = fieldSQLMap.get("xAxis").stream().map(singleField -> singleField.getWhere()).collect(Collectors.toList()); + + List yFields = fieldSQLMap.getOrDefault("yAxis", new ArrayList<>()).stream().filter(singleField -> ObjectUtils.isNotEmpty(singleField.getField())).map(PluginSingleField::getField).collect(Collectors.toList()); + List yOrders = fieldSQLMap.getOrDefault("yAxis", new ArrayList<>()).stream().filter(singleField -> ObjectUtils.isNotEmpty(singleField.getSort())).map(PluginSingleField::getSort).collect(Collectors.toList()); + List yWheres = fieldSQLMap.getOrDefault("yAxis", new ArrayList<>()).stream().filter(singleField -> ObjectUtils.isNotEmpty(singleField.getWhere())).map(PluginSingleField::getWhere).collect(Collectors.toList()); + + /*List yExtFields = fieldSQLMap.getOrDefault("yAxisExt", new ArrayList<>()).stream().filter(singleField -> ObjectUtils.isNotEmpty(singleField.getField())).map(PluginSingleField::getField).collect(Collectors.toList()); + List yExtOrders = fieldSQLMap.getOrDefault("yAxisExt", new ArrayList<>()).stream().filter(singleField -> ObjectUtils.isNotEmpty(singleField.getSort())).map(PluginSingleField::getSort).collect(Collectors.toList()); + List yExtWheres = fieldSQLMap.getOrDefault("yAxisExt", new ArrayList<>()).stream().filter(singleField -> ObjectUtils.isNotEmpty(singleField.getWhere())).map(PluginSingleField::getWhere).collect(Collectors.toList()); + + yFields.addAll(yExtFields); + yOrders.addAll(yExtOrders); + yWheres.addAll(yExtWheres);*/ + + // 处理视图中字段过滤 + String customWheres = baseService.customWhere(dsType, pluginViewParam.getPluginChartFieldCustomFilters(), tableObj); + // 处理仪表板字段过滤 + String panelWheres = baseService.panelWhere(dsType, pluginViewParam.getPluginChartExtFilters(), tableObj); + // 构建sql所有参数 + + String permissionWhere = baseService.permissionWhere(dsType, rowPermissionsTree, tableObj); + List wheres = new ArrayList<>(); + if (customWheres != null) wheres.add(customWheres); + if (panelWheres != null) wheres.add(panelWheres); + if (permissionWhere != null) wheres.add(permissionWhere); + List groups = new ArrayList<>(); + groups.addAll(xFields); + + // 外层再次套sql + List orders = new ArrayList<>(); + orders.addAll(xOrders); + orders.addAll(yOrders); + List aggWheres = new ArrayList<>(); + aggWheres.addAll(yWheres.stream().filter(ObjectUtils::isNotEmpty).collect(Collectors.toList())); + + STGroup stg = new STGroupFile(SQLConstants.SQL_TEMPLATE); + ST st_sql = stg.getInstanceOf("querySql"); + if (CollectionUtils.isNotEmpty(xFields)) st_sql.add("groups", xFields); + if (CollectionUtils.isNotEmpty(yFields)) st_sql.add("aggregators", yFields); + if (CollectionUtils.isNotEmpty(wheres)) st_sql.add("filters", wheres); + if (ObjectUtils.isNotEmpty(tableObj)) st_sql.add("table", tableObj); + String sql = st_sql.render(); + + String brackets = ConstantsUtil.constantsValue(dsType, "BRACKETS"); + String table_alias_prefix = ConstantsUtil.constantsValue(dsType, "TABLE_ALIAS_PREFIX"); + + ST st = stg.getInstanceOf("querySql"); + PluginViewSQL tableSQL = PluginViewSQL.builder() + .tableName(String.format(brackets, sql)) + .tableAlias(String.format(table_alias_prefix, 1)) + .build(); + if (CollectionUtils.isNotEmpty(aggWheres)) st.add("filters", aggWheres); + if (CollectionUtils.isNotEmpty(orders)) st.add("orders", orders); + if (ObjectUtils.isNotEmpty(tableSQL)) st.add("table", tableSQL); + return baseService.sqlLimit(dsType, st.render(), pluginViewParam.getPluginViewLimit()); + } + +} diff --git a/extensions/dataease-extensions-view/view-chartmix/view-chartmix-backend/src/main/java/io/dataease/plugins/view/official/impl/ChartMixService.java b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-backend/src/main/java/io/dataease/plugins/view/official/impl/ChartMixService.java new file mode 100644 index 0000000000..df669c06be --- /dev/null +++ b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-backend/src/main/java/io/dataease/plugins/view/official/impl/ChartMixService.java @@ -0,0 +1,192 @@ +package io.dataease.plugins.view.official.impl; + +import com.google.gson.Gson; +import io.dataease.plugins.common.dto.StaticResource; +import io.dataease.plugins.view.entity.*; +import io.dataease.plugins.view.official.handler.DefaultViewStatHandler; +import io.dataease.plugins.view.service.ViewPluginService; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; + +import java.io.InputStream; +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Service +public class ChartMixService extends ViewPluginService { + private static final String VIEW_TYPE_VALUE = "chart-mix"; + + /* 下版这些常量移到sdk */ + private static final String TYPE = "-type"; + private static final String DATA = "-data"; + private static final String STYLE = "-style"; + private static final String VIEW = "-view"; + private static final String SUFFIX = "svg"; + /* 下版这些常量移到sdk */ + private static final String VIEW_TYPE = VIEW_TYPE_VALUE + TYPE; + private static final String VIEW_DATA = VIEW_TYPE_VALUE + DATA; + private static final String VIEW_STYLE = VIEW_TYPE_VALUE + STYLE; + private static final String VIEW_VIEW = VIEW_TYPE_VALUE + VIEW; + + private static final String[] VIEW_STYLE_PROPERTIES = { + "color-selector", + "label-selector", + "tooltip-selector-ant-v", + "title-selector-ant-v" + }; + + private static final Map VIEW_STYLE_PROPERTY_INNER = new HashMap<>(); + + static { + VIEW_STYLE_PROPERTY_INNER.put("color-selector", new String[]{"value"}); + VIEW_STYLE_PROPERTY_INNER.put("label-selector", new String[]{"show", "fontSize", "color"}); + VIEW_STYLE_PROPERTY_INNER.put("tooltip-selector-ant-v", new String[]{"show", "fontSize", "color", "backgroundColor"}); + VIEW_STYLE_PROPERTY_INNER.put("title-selector-ant-v", new String[]{"show", "title", "fontSize", "color", "hPosition", "vPosition", "isItalic", "isBolder"}); + } + + @Override + public PluginViewType viewType() { + PluginViewType pluginViewType = new PluginViewType(); + pluginViewType.setRender("antv"); + pluginViewType.setCategory("chart.chart_type_trend"); + pluginViewType.setValue(VIEW_TYPE_VALUE); + pluginViewType.setProperties(VIEW_STYLE_PROPERTIES); + pluginViewType.setPropertyInner(VIEW_STYLE_PROPERTY_INNER); + return pluginViewType; + } + + @Override + public Object format(Object o) { + return null; + } + + @Override + public List components() { + List results = new ArrayList<>(); + results.add(VIEW_VIEW); + results.add(VIEW_DATA); + results.add(VIEW_TYPE); + results.add(VIEW_STYLE); + return results; + } + + @Override + public List staticResources() { + List results = new ArrayList<>(); + StaticResource staticResource = new StaticResource(); + staticResource.setName(VIEW_TYPE_VALUE); + staticResource.setSuffix(SUFFIX); + results.add(staticResource); + results.add(pluginSvg()); + return results; + } + + private StaticResource pluginSvg() { + StaticResource staticResource = new StaticResource(); + staticResource.setName("view-chartmix-backend"); + staticResource.setSuffix("svg"); + return staticResource; + } + + + @Override + protected InputStream readContent(String s) { + InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream("static/" + s); + return resourceAsStream; + } + + @Override + public String generateSQL(PluginViewParam param) { + List xAxis = param.getFieldsByType("xAxis"); + List yAxis = param.getFieldsByType("yAxis"); + /*if (yAxis == null) { + yAxis = new ArrayList<>(); + } + List yAxisExt = param.getFieldsByType("yAxisExt"); + if (CollectionUtils.isNotEmpty(yAxisExt)) { + yAxis.addAll(yAxisExt); + }*/ + System.out.println(new Gson().toJson(yAxis)); + if (CollectionUtils.isEmpty(xAxis) || CollectionUtils.isEmpty(yAxis)) { + return null; + } + String sql = new DefaultViewStatHandler().build(param, this); + System.out.println(sql); + return sql; + + } + + + @Override + public Map formatResult(PluginViewParam pluginViewParam, List data, Boolean isDrill) { + List xAxis = new ArrayList<>(); + List yAxis = new ArrayList<>(); + + System.out.println("pluginViewParam: " + new Gson().toJson(pluginViewParam)); + + pluginViewParam.getPluginViewFields().forEach(pluginViewField -> { + if (StringUtils.equals(pluginViewField.getTypeField(), "xAxis")) { + xAxis.add(pluginViewField); + } + if (StringUtils.equals(pluginViewField.getTypeField(), "yAxis")) { + yAxis.add(pluginViewField); + } + }); + Map map = new HashMap<>(); + + List series = format(pluginViewParam.getPluginViewLimit().getType(), data, xAxis, yAxis); + + map.put("data", series); + + System.out.println(new Gson().toJson(map)); + + return map; + } + + private List format(String type, List data, List xAxis, List yAxis) { + List series = new ArrayList<>(); + for (PluginViewField y : yAxis) { + PluginSeries series1 = new PluginSeries(); + series1.setName(y.getName()); + series1.setType(type); + series1.setData(new ArrayList<>()); + series.add(series1); + } + for (int i1 = 0; i1 < data.size(); i1++) { + String[] d = data.get(i1); + + for (int i = xAxis.size(); i < xAxis.size() + yAxis.size(); i++) { + List dimensionList = new ArrayList<>(); + List quotaList = new ArrayList<>(); + PluginAxisChartData axisChartDataDTO = new PluginAxisChartData(); + + for (int j = 0; j < xAxis.size(); j++) { + PluginChartDimension chartDimensionDTO = new PluginChartDimension(); + chartDimensionDTO.setId(xAxis.get(j).getId()); + chartDimensionDTO.setValue(d[j]); + dimensionList.add(chartDimensionDTO); + } + axisChartDataDTO.setDimensionList(dimensionList); + + int j = i - xAxis.size(); + PluginChartQuota chartQuotaDTO = new PluginChartQuota(); + chartQuotaDTO.setId(yAxis.get(j).getId()); + quotaList.add(chartQuotaDTO); + axisChartDataDTO.setQuotaList(quotaList); + try { + axisChartDataDTO.setValue(StringUtils.isEmpty(d[i]) ? null : new BigDecimal(d[i])); + } catch (Exception e) { + axisChartDataDTO.setValue(new BigDecimal(0)); + } + series.get(j).getData().add(axisChartDataDTO); + } + + } + return series; + } + +} diff --git a/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/.babelrc b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/.babelrc new file mode 100644 index 0000000000..3a280ba34b --- /dev/null +++ b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/.babelrc @@ -0,0 +1,12 @@ +{ + "presets": [ + ["env", { + "modules": false, + "targets": { + "browsers": ["> 1%", "last 2 versions", "not ie <= 8"] + } + }], + "stage-2" + ], + "plugins": ["transform-vue-jsx", "transform-runtime"] +} diff --git a/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/.editorconfig b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/.editorconfig new file mode 100644 index 0000000000..9d08a1a828 --- /dev/null +++ b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/.editorconfig @@ -0,0 +1,9 @@ +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true diff --git a/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/.gitignore b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/.gitignore new file mode 100644 index 0000000000..541a820f6c --- /dev/null +++ b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/.gitignore @@ -0,0 +1,14 @@ +.DS_Store +node_modules/ +/dist/ +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Editor directories and files +.idea +.vscode +*.suo +*.ntvs* +*.njsproj +*.sln diff --git a/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/.postcssrc.js b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/.postcssrc.js new file mode 100644 index 0000000000..eee3e92d7f --- /dev/null +++ b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/.postcssrc.js @@ -0,0 +1,10 @@ +// https://github.com/michael-ciniawsky/postcss-load-config + +module.exports = { + "plugins": { + "postcss-import": {}, + "postcss-url": {}, + // to edit target browsers: use "browserslist" field in package.json + "autoprefixer": {} + } +} diff --git a/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/README.md b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/README.md new file mode 100644 index 0000000000..c1e4be95e0 --- /dev/null +++ b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/README.md @@ -0,0 +1,21 @@ +# deplugin-view-frontend + +> A Vue.js project + +## Build Setup + +``` bash +# install dependencies +npm install + +# serve with hot reload at localhost:8080 +npm run dev + +# build for production with minification +npm run build + +# build for production and view the bundle analyzer report +npm run build --report +``` + +For a detailed explanation on how things work, check out the [guide](http://vuejs-templates.github.io/webpack/) and [docs for vue-loader](http://vuejs.github.io/vue-loader). diff --git a/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/build/build-async-plugins.js b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/build/build-async-plugins.js new file mode 100644 index 0000000000..2303854531 --- /dev/null +++ b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/build/build-async-plugins.js @@ -0,0 +1,35 @@ +'use strict' +require('./check-versions')() + +process.env.NODE_ENV = 'production' + +const ora = require('ora') +const chalk = require('chalk') +const webpack = require('webpack') +const webpackConfig = require('./webpack.async-plugins') + +const spinner = ora('building for sync-plugins...') +spinner.start() + +webpack(webpackConfig, function (err, stats) { + spinner.stop() + if (err) throw err + process.stdout.write(stats.toString({ + colors: true, + modules: false, + children: false, + chunks: false, + chunkModules: false + }) + '\n\n') + + if (stats.hasErrors()) { + console.log(chalk.red(' Build failed with errors.\n')) + process.exit(1) + } + + console.log(chalk.cyan(' Build complete.\n')) + console.log(chalk.yellow( + ' Tip: built files are meant to be served over an HTTP server.\n' + + ' Opening index.html over file:// won\'t work.\n' + )) +}) diff --git a/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/build/build.js b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/build/build.js new file mode 100644 index 0000000000..8f2ad8ad49 --- /dev/null +++ b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/build/build.js @@ -0,0 +1,41 @@ +'use strict' +require('./check-versions')() + +process.env.NODE_ENV = 'production' + +const ora = require('ora') +const rm = require('rimraf') +const path = require('path') +const chalk = require('chalk') +const webpack = require('webpack') +const config = require('../config') +const webpackConfig = require('./webpack.prod.conf') + +const spinner = ora('building for production...') +spinner.start() + +rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => { + if (err) throw err + webpack(webpackConfig, (err, stats) => { + spinner.stop() + if (err) throw err + process.stdout.write(stats.toString({ + colors: true, + modules: false, + children: false, // If you are using ts-loader, setting this to true will make TypeScript errors show up during build. + chunks: false, + chunkModules: false + }) + '\n\n') + + if (stats.hasErrors()) { + console.log(chalk.red(' Build failed with errors.\n')) + process.exit(1) + } + + console.log(chalk.cyan(' Build complete.\n')) + console.log(chalk.yellow( + ' Tip: built files are meant to be served over an HTTP server.\n' + + ' Opening index.html over file:// won\'t work.\n' + )) + }) +}) diff --git a/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/build/check-versions.js b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/build/check-versions.js new file mode 100644 index 0000000000..3ef972a08d --- /dev/null +++ b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/build/check-versions.js @@ -0,0 +1,54 @@ +'use strict' +const chalk = require('chalk') +const semver = require('semver') +const packageConfig = require('../package.json') +const shell = require('shelljs') + +function exec (cmd) { + return require('child_process').execSync(cmd).toString().trim() +} + +const versionRequirements = [ + { + name: 'node', + currentVersion: semver.clean(process.version), + versionRequirement: packageConfig.engines.node + } +] + +if (shell.which('npm')) { + versionRequirements.push({ + name: 'npm', + currentVersion: exec('npm --version'), + versionRequirement: packageConfig.engines.npm + }) +} + +module.exports = function () { + const warnings = [] + + for (let i = 0; i < versionRequirements.length; i++) { + const mod = versionRequirements[i] + + if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) { + warnings.push(mod.name + ': ' + + chalk.red(mod.currentVersion) + ' should be ' + + chalk.green(mod.versionRequirement) + ) + } + } + + if (warnings.length) { + console.log('') + console.log(chalk.yellow('To use this template, you must update following to modules:')) + console.log() + + for (let i = 0; i < warnings.length; i++) { + const warning = warnings[i] + console.log(' ' + warning) + } + + console.log() + process.exit(1) + } +} diff --git a/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/build/logo.png b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/build/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..f3d2503fc2a44b5053b0837ebea6e87a2d339a43 GIT binary patch literal 6849 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 { + const notifier = require('node-notifier') + + return (severity, errors) => { + if (severity !== 'error') return + + const error = errors[0] + const filename = error.file && error.file.split('!').pop() + + notifier.notify({ + title: packageConfig.name, + message: severity + ': ' + error.name, + subtitle: filename || '', + icon: path.join(__dirname, 'logo.png') + }) + } +} diff --git a/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/build/vue-loader.conf.js b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/build/vue-loader.conf.js new file mode 100644 index 0000000000..33ed58bc0a --- /dev/null +++ b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/build/vue-loader.conf.js @@ -0,0 +1,22 @@ +'use strict' +const utils = require('./utils') +const config = require('../config') +const isProduction = process.env.NODE_ENV === 'production' +const sourceMapEnabled = isProduction + ? config.build.productionSourceMap + : config.dev.cssSourceMap + +module.exports = { + loaders: utils.cssLoaders({ + sourceMap: sourceMapEnabled, + extract: isProduction + }), + cssSourceMap: sourceMapEnabled, + cacheBusting: config.dev.cacheBusting, + transformToRequire: { + video: ['src', 'poster'], + source: 'src', + img: 'src', + image: 'xlink:href' + } +} diff --git a/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/build/webpack.async-plugins.js b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/build/webpack.async-plugins.js new file mode 100644 index 0000000000..3751023bdf --- /dev/null +++ b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/build/webpack.async-plugins.js @@ -0,0 +1,97 @@ +const webpack = require('webpack') +const path = require('path') +const utils = require('./utils') +const CopyPlugin = require("copy-webpack-plugin"); +const VueLoaderPlugin = require('vue-loader/lib/plugin'); +function resolve (dir) { + return path.join(__dirname, '..', dir) +} + +module.exports = { + mode: 'development', + entry: { + + // PluginDemo: resolve('/src/views/PluginDemo.vue') + 'chart-mix-view': resolve('/src/views/antv/chartmix/index.vue'), + 'chart-mix-data': resolve('/src/views/antv/chartmix/data.vue'), + 'chart-mix-type': resolve('/src/views/antv/chartmix/type.vue'), + 'chart-mix-style': resolve('/src/views/antv/chartmix/style.vue') + + }, + output: { + path: resolve('/static/'), + filename: '[name].js' + }, + resolve: { + extensions: ['.js', '.vue', '.json'], + alias: { + 'vue$': 'vue/dist/vue.esm.js', + '@': resolve('src') + } + }, + externals: { + vue: 'vue' + }, + module: { + rules: [ + { + test: /\.vue$/, + loader: 'vue-loader', + options: { + transformAssetUrls: { + video: 'src', + source: 'src', + img: 'src', + image: 'xlink:href' + } + } + }, + { + test: /.(sa|sc|c)ss$/, + use: [ + {loader: 'vue-style-loader'}, + 'css-loader', + 'sass-loader' + ] + }, + { + test: /\.js$/, + loader: 'babel-loader', + include: [resolve('src'), resolve('test')] + }, + { + test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: utils.assetsPath('img/[name].[hash:7].[ext]') + } + }, + { + test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: utils.assetsPath('media/[name].[hash:7].[ext]') + } + }, + { + test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: utils.assetsPath('fonts/[name].[hash:7].[ext]') + } + } + ] + }, + plugins: [ + new VueLoaderPlugin(), + new webpack.DefinePlugin({ + 'process.env.NODE_ENV': '"production"' + }), + new CopyPlugin([ + {from: 'src/icons/svg/'} + ]), + ] +} diff --git a/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/build/webpack.base.conf.js b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/build/webpack.base.conf.js new file mode 100644 index 0000000000..6ccc02dab4 --- /dev/null +++ b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/build/webpack.base.conf.js @@ -0,0 +1,91 @@ +'use strict' +const path = require('path') +const utils = require('./utils') +const config = require('../config') +const vueLoaderConfig = require('./vue-loader.conf') + +function resolve (dir) { + return path.join(__dirname, '..', dir) +} + + + +module.exports = { + context: path.resolve(__dirname, '../'), + entry: { + app: './src/main.js' + }, + output: { + path: config.build.assetsRoot, + filename: '[name].js', + publicPath: process.env.NODE_ENV === 'production' + ? config.build.assetsPublicPath + : config.dev.assetsPublicPath + }, + resolve: { + extensions: ['.js', '.vue', '.json'], + alias: { + 'vue$': 'vue/dist/vue.esm.js', + '@': resolve('src'), + } + }, + module: { + rules: [ + { + test: /\.vue$/, + loader: 'vue-loader', + options: vueLoaderConfig + }, + { + test: /\.js$/, + loader: 'babel-loader', + include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')] + }, + { + test: /\.svg$/, + loader: 'svg-sprite-loader', + include: [resolve('src/icons')], + options: { + symbolId: 'icon-[name]' + } + }, + { + test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, + loader: 'url-loader', + exclude: [resolve('src/icons')], + options: { + limit: 10000, + name: utils.assetsPath('img/[name].[hash:7].[ext]') + } + }, + { + test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: utils.assetsPath('media/[name].[hash:7].[ext]') + } + }, + { + test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: utils.assetsPath('fonts/[name].[hash:7].[ext]') + } + } + ] + }, + node: { + // prevent webpack from injecting useless setImmediate polyfill because Vue + // source contains it (although only uses it if it's native). + setImmediate: false, + // prevent webpack from injecting mocks to Node native modules + // that does not make sense for the client + dgram: 'empty', + fs: 'empty', + net: 'empty', + tls: 'empty', + child_process: 'empty' + } +} diff --git a/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/build/webpack.dev.conf.js b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/build/webpack.dev.conf.js new file mode 100755 index 0000000000..070ae221f3 --- /dev/null +++ b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/build/webpack.dev.conf.js @@ -0,0 +1,95 @@ +'use strict' +const utils = require('./utils') +const webpack = require('webpack') +const config = require('../config') +const merge = require('webpack-merge') +const path = require('path') +const baseWebpackConfig = require('./webpack.base.conf') +const CopyWebpackPlugin = require('copy-webpack-plugin') +const HtmlWebpackPlugin = require('html-webpack-plugin') +const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin') +const portfinder = require('portfinder') + +const HOST = process.env.HOST +const PORT = process.env.PORT && Number(process.env.PORT) + +const devWebpackConfig = merge(baseWebpackConfig, { + module: { + rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true }) + }, + // cheap-module-eval-source-map is faster for development + devtool: config.dev.devtool, + + // these devServer options should be customized in /config/index.js + devServer: { + clientLogLevel: 'warning', + historyApiFallback: { + rewrites: [ + { from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') }, + ], + }, + hot: true, + contentBase: false, // since we use CopyWebpackPlugin. + compress: true, + host: HOST || config.dev.host, + port: PORT || config.dev.port, + open: config.dev.autoOpenBrowser, + overlay: config.dev.errorOverlay + ? { warnings: false, errors: true } + : false, + publicPath: config.dev.assetsPublicPath, + proxy: config.dev.proxyTable, + quiet: true, // necessary for FriendlyErrorsPlugin + watchOptions: { + poll: config.dev.poll, + } + }, + plugins: [ + new webpack.DefinePlugin({ + 'process.env': require('../config/dev.env') + }), + new webpack.HotModuleReplacementPlugin(), + new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update. + new webpack.NoEmitOnErrorsPlugin(), + // https://github.com/ampedandwired/html-webpack-plugin + new HtmlWebpackPlugin({ + filename: 'index.html', + template: 'index.html', + inject: true + }), + // copy custom static assets + new CopyWebpackPlugin([ + { + from: path.resolve(__dirname, '../static'), + to: config.dev.assetsSubDirectory, + ignore: ['.*'] + } + ]) + ] +}) + +module.exports = new Promise((resolve, reject) => { + portfinder.basePort = process.env.PORT || config.dev.port + portfinder.getPort((err, port) => { + if (err) { + reject(err) + } else { + // publish the new Port, necessary for e2e tests + process.env.PORT = port + // add port to devServer config + devWebpackConfig.devServer.port = port + + // Add FriendlyErrorsPlugin + devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({ + compilationSuccessInfo: { + messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`], + }, + onErrors: config.dev.notifyOnErrors + ? utils.createNotifierCallback() + : undefined + })) + + resolve(devWebpackConfig) + } + }) +}) diff --git a/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/build/webpack.prod.conf.js b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/build/webpack.prod.conf.js new file mode 100644 index 0000000000..1f71ad6454 --- /dev/null +++ b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/build/webpack.prod.conf.js @@ -0,0 +1,147 @@ +'use strict' +const path = require('path') +const utils = require('./utils') +const webpack = require('webpack') +const config = require('../config') +const merge = require('webpack-merge') +const baseWebpackConfig = require('./webpack.base.conf') +const CopyWebpackPlugin = require('copy-webpack-plugin') +const HtmlWebpackPlugin = require('html-webpack-plugin') +const ExtractTextPlugin = require('extract-text-webpack-plugin') +const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin') +const UglifyJsPlugin = require('uglifyjs-webpack-plugin') +const VueLoaderPlugin = require('vue-loader/lib/plugin'); + +const env = require('../config/prod.env') + +const webpackConfig = merge(baseWebpackConfig, { + module: { + rules: utils.styleLoaders({ + sourceMap: config.build.productionSourceMap, + extract: true, + usePostCSS: true + }) + }, + devtool: config.build.productionSourceMap ? config.build.devtool : false, + output: { + path: config.build.assetsRoot, + filename: utils.assetsPath('js/[name].[chunkhash].js'), + chunkFilename: utils.assetsPath('js/[id].[chunkhash].js') + }, + plugins: [ + new VueLoaderPlugin(), + // http://vuejs.github.io/vue-loader/en/workflow/production.html + new webpack.DefinePlugin({ + 'process.env': env + }), + new UglifyJsPlugin({ + uglifyOptions: { + compress: { + warnings: false + } + }, + sourceMap: config.build.productionSourceMap, + parallel: true + }), + // extract css into its own file + new ExtractTextPlugin({ + filename: utils.assetsPath('css/[name].[contenthash].css'), + // Setting the following option to `false` will not extract CSS from codesplit chunks. + // Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack. + // It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`, + // increasing file size: https://github.com/vuejs-templates/webpack/issues/1110 + allChunks: true, + }), + // Compress extracted CSS. We are using this plugin so that possible + // duplicated CSS from different components can be deduped. + new OptimizeCSSPlugin({ + cssProcessorOptions: config.build.productionSourceMap + ? { safe: true, map: { inline: false } } + : { safe: true } + }), + // generate dist index.html with correct asset hash for caching. + // you can customize output by editing /index.html + // see https://github.com/ampedandwired/html-webpack-plugin + new HtmlWebpackPlugin({ + filename: config.build.index, + template: 'index.html', + inject: true, + minify: { + removeComments: true, + collapseWhitespace: true, + removeAttributeQuotes: true + // more options: + // https://github.com/kangax/html-minifier#options-quick-reference + }, + // necessary to consistently work with multiple chunks via CommonsChunkPlugin + chunksSortMode: 'dependency' + }), + // keep module.id stable when vendor modules does not change + new webpack.HashedModuleIdsPlugin(), + // enable scope hoisting + new webpack.optimize.ModuleConcatenationPlugin(), + // split vendor js into its own file + new webpack.optimize.CommonsChunkPlugin({ + name: 'vendor', + minChunks (module) { + // any required modules inside node_modules are extracted to vendor + return ( + module.resource && + /\.js$/.test(module.resource) && + module.resource.indexOf( + path.join(__dirname, '../node_modules') + ) === 0 + ) + } + }), + // extract webpack runtime and module manifest to its own file in order to + // prevent vendor hash from being updated whenever app bundle is updated + new webpack.optimize.CommonsChunkPlugin({ + name: 'manifest', + minChunks: Infinity + }), + // This instance extracts shared chunks from code split chunks and bundles them + // in a separate chunk, similar to the vendor chunk + // see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk + new webpack.optimize.CommonsChunkPlugin({ + name: 'app', + async: 'vendor-async', + children: true, + minChunks: 3 + }), + + // copy custom static assets + new CopyWebpackPlugin([ + { + from: path.resolve(__dirname, '../static'), + to: config.build.assetsSubDirectory, + ignore: ['.*'] + } + ]) + ] +}) + +if (config.build.productionGzip) { + const CompressionWebpackPlugin = require('compression-webpack-plugin') + + webpackConfig.plugins.push( + new CompressionWebpackPlugin({ + asset: '[path].gz[query]', + algorithm: 'gzip', + test: new RegExp( + '\\.(' + + config.build.productionGzipExtensions.join('|') + + ')$' + ), + threshold: 10240, + minRatio: 0.8 + }) + ) +} + +if (config.build.bundleAnalyzerReport) { + const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin + webpackConfig.plugins.push(new BundleAnalyzerPlugin()) +} + +module.exports = webpackConfig diff --git a/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/config/dev.env.js b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/config/dev.env.js new file mode 100644 index 0000000000..1e22973ae7 --- /dev/null +++ b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/config/dev.env.js @@ -0,0 +1,7 @@ +'use strict' +const merge = require('webpack-merge') +const prodEnv = require('./prod.env') + +module.exports = merge(prodEnv, { + NODE_ENV: '"development"' +}) diff --git a/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/config/index.js b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/config/index.js new file mode 100644 index 0000000000..c5eded7f81 --- /dev/null +++ b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/config/index.js @@ -0,0 +1,69 @@ +'use strict' +// Template version: 1.3.1 +// see http://vuejs-templates.github.io/webpack for documentation. + +const path = require('path') + +module.exports = { + dev: { + + // Paths + assetsSubDirectory: 'static', + assetsPublicPath: '/', + proxyTable: {}, + + // Various Dev Server settings + host: 'localhost', // can be overwritten by process.env.HOST + port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined + autoOpenBrowser: false, + errorOverlay: true, + notifyOnErrors: true, + poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions- + + + /** + * Source Maps + */ + + // https://webpack.js.org/configuration/devtool/#development + devtool: 'cheap-module-eval-source-map', + + // If you have problems debugging vue-files in devtools, + // set this to false - it *may* help + // https://vue-loader.vuejs.org/en/options.html#cachebusting + cacheBusting: true, + + cssSourceMap: true + }, + + build: { + // Template for index.html + index: path.resolve(__dirname, '../dist/index.html'), + + // Paths + assetsRoot: path.resolve(__dirname, '../dist'), + assetsSubDirectory: 'static', + assetsPublicPath: '/', + + /** + * Source Maps + */ + + productionSourceMap: true, + // https://webpack.js.org/configuration/devtool/#production + devtool: '#source-map', + + // Gzip off by default as many popular static hosts such as + // Surge or Netlify already gzip all static assets for you. + // Before setting to `true`, make sure to: + // npm install --save-dev compression-webpack-plugin + productionGzip: false, + productionGzipExtensions: ['js', 'css'], + + // Run the build command with an extra argument to + // View the bundle analyzer report after build finishes: + // `npm run build --report` + // Set to `true` or `false` to always turn it on or off + bundleAnalyzerReport: process.env.npm_config_report + } +} diff --git a/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/config/prod.env.js b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/config/prod.env.js new file mode 100644 index 0000000000..a6f997616e --- /dev/null +++ b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/config/prod.env.js @@ -0,0 +1,4 @@ +'use strict' +module.exports = { + NODE_ENV: '"production"' +} diff --git a/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/index.html b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/index.html new file mode 100644 index 0000000000..03ce3fdf27 --- /dev/null +++ b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/index.html @@ -0,0 +1,12 @@ + + + + + + deplugin-view-frontend + + +
+ + + diff --git a/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/package.json b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/package.json new file mode 100644 index 0000000000..dd121e3144 --- /dev/null +++ b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/package.json @@ -0,0 +1,75 @@ +{ + "name": "deplugin-view-frontend", + "version": "1.0.0", + "description": "A Vue.js project", + "author": "", + "private": true, + "scripts": { + "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js", + "start": "npm run dev", + "build": "node build/build.js", + "buildPlugin": "node build/build-async-plugins.js" + }, + "dependencies": { + "@antv/g2plot": "^2.4.31", + "@riophae/vue-treeselect": "0.4.0", + "lodash": "^4.17.21", + "vue": "2.6.10", + "vue-i18n": "7.3.2", + "vue-router": "^3.0.1", + "vue-uuid": "2.0.2", + "vuedraggable": "^2.24.3", + "vuex": "3.1.0" + }, + "devDependencies": { + "autoprefixer": "^7.1.2", + "babel-core": "^6.22.1", + "babel-helper-vue-jsx-merge-props": "^2.0.3", + "babel-loader": "^7.1.1", + "babel-plugin-syntax-jsx": "^6.18.0", + "babel-plugin-transform-runtime": "^6.22.0", + "babel-plugin-transform-vue-jsx": "^3.5.0", + "babel-preset-env": "^1.3.2", + "babel-preset-stage-2": "^6.22.0", + "chalk": "^2.0.1", + "copy-webpack-plugin": "^4.6.0", + "css-loader": "^0.28.0", + "element-ui": "2.15.7", + "extract-text-webpack-plugin": "^4.0.0-beta.0", + "file-loader": "^1.1.4", + "friendly-errors-webpack-plugin": "^1.6.1", + "html-webpack-plugin": "^3.2.0", + "js-cookie": "2.2.0", + "node-notifier": "^8.0.1", + "optimize-css-assets-webpack-plugin": "^3.2.0", + "ora": "^1.2.0", + "portfinder": "^1.0.13", + "postcss-import": "^11.0.0", + "postcss-loader": "^2.0.8", + "postcss-url": "^7.2.1", + "rimraf": "^2.6.0", + "sass": "^1.33.0", + "sass-loader": "^7.3.1", + "semver": "^5.3.0", + "shelljs": "^0.8.5", + "svg-sprite-loader": "4.1.3", + "uglifyjs-webpack-plugin": "^1.1.1", + "url-loader": "^0.5.8", + "vue-loader": "^15.6.4", + "vue-style-loader": "^4.1.2", + "vue-template-compiler": "2.6.10", + "webpack": "^4.8.1", + "webpack-bundle-analyzer": "^3.3.2", + "webpack-dev-server": "^3.1.11", + "webpack-merge": "^4.1.0" + }, + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + }, + "browserslist": [ + "> 1%", + "last 2 versions", + "not ie <= 8" + ] +} diff --git a/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/pom.xml b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/pom.xml new file mode 100644 index 0000000000..21ee6745e0 --- /dev/null +++ b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/pom.xml @@ -0,0 +1,80 @@ + + + + + io.dataease + view-chartmix + ${dataease.version} + + + 4.0.0 + view-chartmix-frontend + + + UTF-8 + UTF-8 + 1.9.1 + + + + + + maven-clean-plugin + + + + static + + ** + + false + + + + + + + + com.github.eirslett + frontend-maven-plugin + ${frontend-maven-plugin.version} + + + install node and npm + + install-node-and-npm + + + + v16.20.2 + 7.6.3 + + + + + npm install + + npm + + + + install + + + + + npm run buildPlugin + + npm + + + run buildPlugin + + + + + + + diff --git a/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/App.vue b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/App.vue new file mode 100644 index 0000000000..8542e07722 --- /dev/null +++ b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/App.vue @@ -0,0 +1,23 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/assets/logo.png b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/assets/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..f3d2503fc2a44b5053b0837ebea6e87a2d339a43 GIT binary patch literal 6849 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 +
+

{{ msg }}

+

Essential Links

+ +

Ecosystem

+ +
+ + + + + + diff --git a/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/SvgIcon/index.vue b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/SvgIcon/index.vue new file mode 100644 index 0000000000..f81b67f667 --- /dev/null +++ b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/SvgIcon/index.vue @@ -0,0 +1,60 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/selector/BackgroundColorSelector.vue b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/selector/BackgroundColorSelector.vue new file mode 100644 index 0000000000..e1cbf5fe18 --- /dev/null +++ b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/selector/BackgroundColorSelector.vue @@ -0,0 +1,102 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/selector/ColorSelector.vue b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/selector/ColorSelector.vue new file mode 100644 index 0000000000..3a579e8889 --- /dev/null +++ b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/selector/ColorSelector.vue @@ -0,0 +1,306 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/selector/LabelSelector.vue b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/selector/LabelSelector.vue new file mode 100644 index 0000000000..16b95033cc --- /dev/null +++ b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/selector/LabelSelector.vue @@ -0,0 +1,259 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/selector/LegendSelector.vue b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/selector/LegendSelector.vue new file mode 100644 index 0000000000..5125412616 --- /dev/null +++ b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/selector/LegendSelector.vue @@ -0,0 +1,165 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/selector/SizeSelectorAntV.vue b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/selector/SizeSelectorAntV.vue new file mode 100644 index 0000000000..7ca0b08909 --- /dev/null +++ b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/selector/SizeSelectorAntV.vue @@ -0,0 +1,130 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/selector/TitleSelector.vue b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/selector/TitleSelector.vue new file mode 100644 index 0000000000..938dd29c36 --- /dev/null +++ b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/selector/TitleSelector.vue @@ -0,0 +1,269 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/selector/TooltipSelector.vue b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/selector/TooltipSelector.vue new file mode 100644 index 0000000000..c59e0f6185 --- /dev/null +++ b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/selector/TooltipSelector.vue @@ -0,0 +1,144 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/selector/TooltipSelectorAntV.vue b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/selector/TooltipSelectorAntV.vue new file mode 100644 index 0000000000..111041be39 --- /dev/null +++ b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/selector/TooltipSelectorAntV.vue @@ -0,0 +1,228 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/views/ChartDragItem.vue b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/views/ChartDragItem.vue new file mode 100644 index 0000000000..53ae1e2ad0 --- /dev/null +++ b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/views/ChartDragItem.vue @@ -0,0 +1,278 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/views/ChartTitleUpdate.vue b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/views/ChartTitleUpdate.vue new file mode 100644 index 0000000000..efadca90bb --- /dev/null +++ b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/views/ChartTitleUpdate.vue @@ -0,0 +1,480 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/views/DimensionExtItem.vue b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/views/DimensionExtItem.vue new file mode 100644 index 0000000000..c414ad2d36 --- /dev/null +++ b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/views/DimensionExtItem.vue @@ -0,0 +1,256 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/views/DrillItem.vue b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/views/DrillItem.vue new file mode 100644 index 0000000000..7321b8a08c --- /dev/null +++ b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/views/DrillItem.vue @@ -0,0 +1,146 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/views/FieldErrorTips.vue b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/views/FieldErrorTips.vue new file mode 100644 index 0000000000..9d7b574721 --- /dev/null +++ b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/views/FieldErrorTips.vue @@ -0,0 +1,21 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/views/FilterItem.vue b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/views/FilterItem.vue new file mode 100644 index 0000000000..3dd5952d69 --- /dev/null +++ b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/views/FilterItem.vue @@ -0,0 +1,154 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/views/LocationLineItem.vue b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/views/LocationLineItem.vue new file mode 100644 index 0000000000..7b2985d08f --- /dev/null +++ b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/views/LocationLineItem.vue @@ -0,0 +1,170 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/views/QuotaExtItem.vue b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/views/QuotaExtItem.vue new file mode 100644 index 0000000000..826d1394e9 --- /dev/null +++ b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/views/QuotaExtItem.vue @@ -0,0 +1,414 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/views/QuotaItem.vue b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/views/QuotaItem.vue new file mode 100644 index 0000000000..9eb9dbaf68 --- /dev/null +++ b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/views/QuotaItem.vue @@ -0,0 +1,414 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/views/SankeyDimensionItem.vue b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/views/SankeyDimensionItem.vue new file mode 100644 index 0000000000..74a88f39bc --- /dev/null +++ b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/views/SankeyDimensionItem.vue @@ -0,0 +1,420 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/views/ViewTrackBar.vue b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/views/ViewTrackBar.vue new file mode 100644 index 0000000000..a58cad9770 --- /dev/null +++ b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/views/ViewTrackBar.vue @@ -0,0 +1,80 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/views/utils.js b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/views/utils.js new file mode 100644 index 0000000000..307c4f637e --- /dev/null +++ b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/components/views/utils.js @@ -0,0 +1,99 @@ +export function getItemType(dimensionData, quotaData, item) { + // Check whether the current view is in template status + // ( dimensionData and quotaData have no data). If yes, return 'success' directly + if (dimensionData.length === 0 && quotaData.length === 0) { + return 'success' + } + // 将item的字段在数据集维度、指标字段中查询一遍,如果遇到id不存在、字段类型不一致、维度指标不一致,则提示 + const status = item.groupType + let checked = false + if (status === 'd') { + for (let i = 0; i < dimensionData.length; i++) { + const ele = dimensionData[i] + if (item.chartId) { + if (ele.dataeaseName === item.dataeaseName && ele.deType === item.deType && ele.groupType === item.groupType) { + checked = true + break + } + } else { + if (ele.id === item.id && ele.deType === item.deType && ele.groupType === item.groupType) { + checked = true + break + } + } + } + } + if (status === 'q') { + for (let i = 0; i < quotaData.length; i++) { + const ele = quotaData[i] + if (item.chartId) { + if (ele.dataeaseName === item.dataeaseName && ele.deType === item.deType && ele.groupType === item.groupType) { + checked = true + break + } + } else { + if (ele.id === item.id && ele.deType === item.deType && ele.groupType === item.groupType) { + checked = true + break + } + } + } + } + + if (checked) { + if (status === 'd') { + return '' + } else if (status === 'q') { + return 'success' + } + } else { + return 'danger' + } +} + +export function getRemark(chart) { + const remark = {} + if (chart.customStyle) { + const customStyle = JSON.parse(chart.customStyle) + if (customStyle.text) { + const title = JSON.parse(JSON.stringify(customStyle.text)) + remark.show = title.remarkShow ? title.remarkShow : false + remark.content = title.remark ? title.remark : '' + remark.bgFill = title.remarkBackgroundColor ? title.remarkBackgroundColor : '#ffffffff' + } + } + return remark +} + +export function getOriginFieldName(dimensionList, quotaList, field) { + let originName = '' + for (let i = 0; i < dimensionList.length; i++) { + const item = dimensionList[i] + if (item.id === field.id) { + originName = item.name + break + } + } + for (let i = 0; i < quotaList.length; i++) { + const item = quotaList[i] + if (item.id === field.id) { + originName = item.name + break + } + } + return originName +} + +export function resetValueFormatter(item) { + if (item) { + item.formatterCfg = { + type: 'auto', // auto,value,percent + unit: 1, // 换算单位 + suffix: '', // 单位后缀 + decimalCount: 2, // 小数位数 + thousandSeparator: true// 千分符 + } + } +} + +export const quotaViews = ['label', 'richTextView', 'text', 'gauge', 'liquid'] diff --git a/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/de-base/lang/en.js b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/de-base/lang/en.js new file mode 100644 index 0000000000..f48bb572e7 --- /dev/null +++ b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/de-base/lang/en.js @@ -0,0 +1,22 @@ +export default { + plugin_view_chartmix: { + source: 'Source', + target: 'Target', + map_type: 'Map Type', + link_line: 'Link Line', + mark_size: 'Weight', + type_title: 'ChartMix', + label: 'Area', + angle: 'Symbol', + marker: 'Marker', + pentagon: 'Pentagon', + hexagon: 'Hexagon', + octagon: 'Octagon', + hexagram: 'Hexagram', + border: 'Border', + light: 'Light', + dark: 'Dark', + label_format_tip: 'The field value can be read in the form of {field Name}, the fields in the label and the tips are interchangeable, and the built-in latitude and longitude related fields', + tooltip_format_tip: 'The field value can be read in the form of {field Name}, the fields in the label and the tips are interchangeable, and the built-in latitude and longitude related fields.(the label does not support line breaks)', + } +} diff --git a/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/de-base/lang/index.js b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/de-base/lang/index.js new file mode 100644 index 0000000000..e50d0478e6 --- /dev/null +++ b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/de-base/lang/index.js @@ -0,0 +1,49 @@ +import Vue from 'vue' +import VueI18n from 'vue-i18n' +import Cookies from 'js-cookie' +import elementEnLocale from 'element-ui/lib/locale/lang/en' // element-ui lang +import elementZhLocale from 'element-ui/lib/locale/lang/zh-CN'// element-ui lang +import elementTWLocale from 'element-ui/lib/locale/lang/zh-TW'// element-ui lang + +import localMessages from './messages' + + +Vue.use(VueI18n) + +const messages = { + en_US: { + ...localMessages['en_US'], + ...elementEnLocale + }, + zh_CN: { + ...localMessages['zh_CN'], + ...elementZhLocale + }, + zh_TW: { + ...localMessages['zh_TW'], + ...elementTWLocale + } +} +export function getLanguage () { + const chooseLanguage = Cookies.get('language') + if (chooseLanguage) return chooseLanguage + + // if has not choose language + const language = (navigator.language || navigator.browserLanguage).toLowerCase() + const locales = Object.keys(messages) + for (const locale of locales) { + if (language.indexOf(locale) > -1) { + return locale + } + } + return 'zh_CN' +} +const i18n = new VueI18n({ + // set locale + // options: en | zh | es + locale: getLanguage(), + // set locale messages + messages +}) + +export default i18n diff --git a/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/de-base/lang/messages.js b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/de-base/lang/messages.js new file mode 100644 index 0000000000..844f8c0673 --- /dev/null +++ b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/de-base/lang/messages.js @@ -0,0 +1,17 @@ +import enLocale from './en' +import zhLocale from './zh' +import twLocale from './tw' + +const messages = { + en_US: { + ...enLocale + }, + zh_CN: { + ...zhLocale + }, + zh_TW: { + ...twLocale + } +} + +export default messages \ No newline at end of file diff --git a/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/de-base/lang/tw.js b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/de-base/lang/tw.js new file mode 100644 index 0000000000..cd211e19d0 --- /dev/null +++ b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/de-base/lang/tw.js @@ -0,0 +1,23 @@ +export default { + plugin_view_chartmix: { + type_title: '組合圖', + source: '源', + target: '目標', + map_type: '類型', + link_line: '連線', + mark_size: '權重', + label: '區域', + angle: '符號', + marker: '標記', + pentagon: '五邊形', + hexagon: '六邊形', + + octagon: '八邊形', + hexagram: '六角星', + border: '邊框', + light: '亮色', + dark: '暗色', + label_format_tip: '可以${fieldName}的形式讀取字段值,標籤和提示中的字段互相通用,內置經緯度相關字段', + tooltip_format_tip: '可以${fieldName}的形式讀取字段值,標籤和提示中的字段互相通用,內置經緯度相關字段(標籤不支持換行)', + } +} diff --git a/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/de-base/lang/zh.js b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/de-base/lang/zh.js new file mode 100644 index 0000000000..894e2ed166 --- /dev/null +++ b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/de-base/lang/zh.js @@ -0,0 +1,21 @@ +export default { + plugin_view_chartmix: { + type_title: '组合图', + source: '源', + target: '目标', + map_type: '类型', + link_line: '连线', + mark_size: '权重', + angle: '符号', + marker: '标记', + pentagon: '五角形', + hexagon: '六角形', + octagon: '八角形', + hexagram: '六角星', + border: '边框', + light: '亮色', + dark: '暗色', + label_format_tip: '可以${fieldName}的形式读取字段值,标签和提示中的字段互相通用,内置经纬度相关字段', + tooltip_format_tip: '可以${fieldName}的形式读取字段值,标签和提示中的字段互相通用,内置经纬度相关字段(标签不支持换行)', + } +} diff --git a/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/icons/index.js b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/icons/index.js new file mode 100644 index 0000000000..2c6b309c96 --- /dev/null +++ b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/icons/index.js @@ -0,0 +1,9 @@ +import Vue from 'vue' +import SvgIcon from '@/components/SvgIcon'// svg component + +// register globally +Vue.component('svg-icon', SvgIcon) + +const req = require.context('./svg', false, /\.svg$/) +const requireAll = requireContext => requireContext.keys().map(requireContext) +requireAll(req) diff --git a/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/icons/svg/chart-mix.svg b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/icons/svg/chart-mix.svg new file mode 100644 index 0000000000..634d13d261 --- /dev/null +++ b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/icons/svg/chart-mix.svg @@ -0,0 +1 @@ + diff --git a/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/icons/svg/view-chart-mix-backend.svg b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/icons/svg/view-chart-mix-backend.svg new file mode 100644 index 0000000000..becfdb6caf --- /dev/null +++ b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/icons/svg/view-chart-mix-backend.svg @@ -0,0 +1 @@ +【icon】插件管理-导出 \ No newline at end of file diff --git a/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/icons/svgo.yml b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/icons/svgo.yml new file mode 100644 index 0000000000..e69de29bb2 diff --git a/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/main.js b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/main.js new file mode 100644 index 0000000000..b1d6ebdf5f --- /dev/null +++ b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/main.js @@ -0,0 +1,36 @@ +// The Vue build version to load with the `import` command +// (runtime-only or standalone) has been set in webpack.base.conf with an alias. +import Vue from 'vue' +import App from './App' +import router from './router' +import ElementUI from 'element-ui' +import Cookies from 'js-cookie' +import i18n from './de-base/lang' +import draggable from 'vuedraggable' +import Treeselect from '@riophae/vue-treeselect' +import '@riophae/vue-treeselect/dist/vue-treeselect.css' +import '@/icons' // icon +import { GaodeMap } from '@antv/l7-maps' +Vue.config.productionTip = false +Vue.use(ElementUI, { + size: Cookies.get('size') || 'medium', + i18n: (key, value) => i18n.t(key, value) +}) +Vue.component('Treeselect', Treeselect) +Vue.component('draggable', draggable) +Vue.prototype.hasDataPermission = function(pTarget, pSource) { + + if (pSource && pTarget) { + return pSource.indexOf(pTarget) > -1 + } + return false +} +Vue.prototype.$gaodeMap = GaodeMap +/* eslint-disable no-new */ +new Vue({ + el: '#app', + router, + i18n, + components: { App }, + template: '' +}) diff --git a/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/router/index.js b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/router/index.js new file mode 100644 index 0000000000..5a43526962 --- /dev/null +++ b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/router/index.js @@ -0,0 +1,21 @@ +import Vue from 'vue' +import Router from 'vue-router' +import HelloWorld from '@/components/HelloWorld' +import SymbolMap from '@/views/antv/chartmix/type' + +Vue.use(Router) + +export default new Router({ + routes: [ + { + path: '/', + name: 'HelloWorld', + component: HelloWorld + }, + { + path: '/chart-mix', + name: 'chart-mix', + component: SymbolMap + } + ] +}) diff --git a/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/utils/chartmix.js b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/utils/chartmix.js new file mode 100644 index 0000000000..697800dd8d --- /dev/null +++ b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/utils/chartmix.js @@ -0,0 +1,73 @@ +// import {PointLayer, Popup } from '@antv/l7'; + +export const DEFAULT_COLOR_CASE = { + value: 'default', + colors: ['#5470c6', '#91cc75', '#fac858', '#ee6666', '#73c0de', '#3ba272', '#fc8452', '#9a60b4', '#ea7ccc'], + alpha: 100, + tableHeaderBgColor: '#e1eaff', + tableItemBgColor: '#ffffff', + tableFontColor: '#000000', + tableStripe: true, + dimensionColor: '#000000', + quotaColor: '#000000', + tableBorderColor: '#cfdaf4' +} + +export const COLOR_PANEL = [ + '#ff4500', + '#ff8c00', + '#ffd700', + '#90ee90', + '#00ced1', + '#1e90ff', + '#c71585', + '#999999', + '#000000', + '#FFFFFF' +] + + +export const DEFAULT_BACKGROUND_COLOR = { + color: '#ffffff', + alpha: 100, + borderRadius: 5 +} + + + + +export function baseSymbolMap(scene, container, chart, action, $pointLayer, $popup) { + let _self = this + + +} + + +export function hexColorToRGBA(hex, alpha) { + const rgb = [] // 定义rgb数组 + if (/^\#[0-9A-F]{3}$/i.test(hex)) { // 判断传入是否为#三位十六进制数 + let sixHex = '#' + hex.replace(/[0-9A-F]/ig, function(kw) { + sixHex += kw + kw // 把三位16进制数转化为六位 + }) + hex = sixHex // 保存回hex + } + if (/^#[0-9A-F]{6}$/i.test(hex)) { // 判断传入是否为#六位十六进制数 + hex.replace(/[0-9A-F]{2}/ig, function(kw) { + // eslint-disable-next-line no-eval + rgb.push(eval('0x' + kw)) // 十六进制转化为十进制并存如数组 + }) + return `rgba(${rgb.join(',')},${alpha / 100})` // 输出RGB格式颜色 + } else { + return 'rgb(0,0,0)' + } +} + + + + + +export function uuid() { + return (((1+Math.random())*0x10000)|0).toString(16).substring(1); +} + diff --git a/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/utils/clickoutside.js b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/utils/clickoutside.js new file mode 100644 index 0000000000..fb030a98eb --- /dev/null +++ b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/utils/clickoutside.js @@ -0,0 +1,68 @@ +const nodeList = []; +const ctx = '@@clickoutsideContext'; + +let startClick; +let seed = 0; + + +function createDocumentHandler(el, binding, vnode) { + return function(mouseup = {}, mousedown = {}) { + if (!vnode || + !vnode.context || + !mouseup.target || + !mousedown.target || + el.contains(mouseup.target) || + el.contains(mousedown.target) || + el === mouseup.target || + (vnode.context.popperElm && + (vnode.context.popperElm.contains(mouseup.target) || + vnode.context.popperElm.contains(mousedown.target)))) return; + + if (binding.expression && + el[ctx].methodName && + vnode.context[el[ctx].methodName]) { + vnode.context[el[ctx].methodName](); + } else { + el[ctx].bindingFn && el[ctx].bindingFn(); + } + }; +} + +/** + * v-clickoutside + * @desc 点击元素外面才会触发的事件 + * @example + * ```vue + *
+ * ``` + */ +export default { + bind(el, binding, vnode) { + nodeList.push(el); + const id = seed++; + el[ctx] = { + id, + documentHandler: createDocumentHandler(el, binding, vnode), + methodName: binding.expression, + bindingFn: binding.value + }; + }, + + update(el, binding, vnode) { + el[ctx].documentHandler = createDocumentHandler(el, binding, vnode); + el[ctx].methodName = binding.expression; + el[ctx].bindingFn = binding.value; + }, + + unbind(el) { + let len = nodeList.length; + + for (let i = 0; i < len; i++) { + if (nodeList[i][ctx].id === el[ctx].id) { + nodeList.splice(i, 1); + break; + } + } + delete el[ctx]; + } +}; diff --git a/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/utils/compare.js b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/utils/compare.js new file mode 100644 index 0000000000..b06a104a10 --- /dev/null +++ b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/utils/compare.js @@ -0,0 +1,29 @@ +export const compareItem = { + type: 'none', // year-yoy/month-yoy等 + resultData: 'percent', // 对比差sub,百分比percent等 + field: '', + custom: { + field: '', + calcType: '0', // 0-增长值,1-增长率 + timeType: '0', // 0-固定日期,1-日期区间 + currentTime: '', + compareTime: '', + currentTimeRange: [], + compareTimeRange: [] + } +} + +export const compareYearList = [ + { name: 'year_mom', value: 'year_mom' } +] + +export const compareMonthList = [ + { name: 'month_mom', value: 'month_mom' }, + { name: 'year_yoy', value: 'year_yoy' } +] + +export const compareDayList = [ + { name: 'day_mom', value: 'day_mom' }, + { name: 'month_yoy', value: 'month_yoy' }, + { name: 'year_yoy', value: 'year_yoy' } +] diff --git a/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/utils/formatter.js b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/utils/formatter.js new file mode 100644 index 0000000000..5a51c89dda --- /dev/null +++ b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/utils/formatter.js @@ -0,0 +1,74 @@ +export const formatterItem = { + type: 'auto', // auto,value,percent + unit: 1, // 换算单位 + suffix: '', // 单位后缀 + decimalCount: 2, // 小数位数 + thousandSeparator: true// 千分符 +} + +// 单位list +export const unitList = [ + { name: 'unit_none', value: 1 }, + { name: 'unit_thousand', value: 1000 }, + { name: 'unit_ten_thousand', value: 10000 }, + { name: 'unit_million', value: 1000000 }, + { name: 'unit_hundred_million', value: 100000000 } +] + +// 格式化方式 +export const formatterType = [ + { name: 'value_formatter_auto', value: 'auto' }, + { name: 'value_formatter_value', value: 'value' }, + { name: 'value_formatter_percent', value: 'percent' } +] + +export function valueFormatter(value, formatter) { + if (value === null || value === undefined) { + return null + } + // 1.unit 2.decimal 3.thousand separator and suffix + let result + if (formatter.type === 'auto') { + result = transSeparatorAndSuffix(transUnit(value, formatter), formatter) + } else if (formatter.type === 'value') { + result = transSeparatorAndSuffix(transDecimal(transUnit(value, formatter), formatter), formatter) + } else if (formatter.type === 'percent') { + value = value * 100 + result = transSeparatorAndSuffix(transDecimal(value, formatter), formatter) + } else { + result = value + } + return result +} + +function transUnit(value, formatter) { + return value / formatter.unit +} + +function transDecimal(value, formatter) { + return value.toFixed(formatter.decimalCount) +} + +function transSeparatorAndSuffix(value, formatter) { + let str = value + '' + if (formatter.thousandSeparator) { + const thousandsReg = /(\d)(?=(\d{3})+$)/g + const numArr = str.split('.') + numArr[0] = numArr[0].replace(thousandsReg, '$1,') + str = numArr.join('.') + } + if (formatter.type === 'percent') { + str += '%' + } else { + if (formatter.unit === 1000) { + str += '千' + } else if (formatter.unit === 10000) { + str += '万' + } else if (formatter.unit === 1000000) { + str += '百万' + } else if (formatter.unit === 100000000) { + str += '亿' + } + } + return str + formatter.suffix.replace(/(^\s*)|(\s*$)/g, '') +} diff --git a/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/utils/map.js b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/utils/map.js new file mode 100644 index 0000000000..6030857ca0 --- /dev/null +++ b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/utils/map.js @@ -0,0 +1,595 @@ +export const DEFAULT_COLOR_CASE = { + value: 'default', + colors: ['#5470c6', '#91cc75', '#fac858', '#ee6666', '#73c0de', '#3ba272', '#fc8452', '#9a60b4', '#ea7ccc'], + alpha: 100, + tableHeaderBgColor: '#e1eaff', + tableItemBgColor: '#ffffff', + tableFontColor: '#000000', + tableStripe: true, + dimensionColor: '#000000', + quotaColor: '#000000', + tableBorderColor: '#cfdaf4' +} +export const DEFAULT_SIZE = { + barDefault: true, + barWidth: 40, + barGap: 0.4, + lineWidth: 2, + lineType: 'solid', + lineSymbol: 'marker', + lineSymbolSize: 4, + lineSmooth: true, + lineArea: false, + pieInnerRadius: 0, + pieOuterRadius: 80, + pieRoseType: 'radius', + pieRoseRadius: 5, + funnelWidth: 80, + radarShape: 'polygon', + radarSize: 80, + tableTitleFontSize: 12, + tableItemFontSize: 12, + tableTitleHeight: 36, + tableItemHeight: 36, + tablePageSize: '20', + tableColumnMode: 'custom', + tableColumnWidth: 100, + tableHeaderAlign: 'left', + tableItemAlign: 'right', + gaugeMin: 0, + gaugeMax: 100, + gaugeStartAngle: 225, + gaugeEndAngle: -45, + dimensionFontSize: 18, + quotaFontSize: 18, + spaceSplit: 10, + dimensionShow: true, + quotaShow: true, + scatterSymbol: 'marker', + scatterSymbolSize: 15, + symbolOpacity: 5, + symbolStrokeWidth: 1, + treemapWidth: 80, + treemapHeight: 80, + liquidMax: 100, + liquidSize: 80, + liquidOutlineBorder: 4, + liquidOutlineDistance: 8, + liquidWaveLength: 128, + liquidWaveCount: 3, + liquidShape: 'circle', + tablePageMode: 'page' +} +export const COLOR_PANEL = [ + '#ff4500', + '#ff8c00', + '#ffd700', + '#90ee90', + '#00ced1', + '#1e90ff', + '#c71585', + '#999999', + '#000000', + '#FFFFFF' +] + +export const DEFAULT_LABEL = { + show: true, + position: 'middle', + color: '#000000', + fontSize: '10', + formatter: '{c}', + gaugeFormatter: '{value}', + labelLine: { + show: true + }, + fields: null, + labelTemplate: '{busiValue}', + initialized: true +} +export const DEFAULT_TOOLTIP = { + show: true, + trigger: 'item', + confine: true, + textStyle: { + fontSize: '10', + color: '#909399' + }, + backgroundColor: '#ffffff', + formatter: '', + tooltipTemplate: '{busiValue}' +} +export const DEFAULT_TITLE_STYLE = { + show: true, + fontSize: '18', + color: '#000000', + hPosition: 'left', + vPosition: 'top', + isItalic: false, + isBolder: true, + remarkShow: false, + remark: '', + remarkBackgroundColor: '#ffffffff', + fontFamily: 'Microsoft YaHei', + letterSpace: '0', + fontShadow: false +} +export const DEFAULT_LEGEND_STYLE = { + show: true, + hPosition: 'center', + vPosition: 'bottom', + orient: 'horizontal', + icon: 'circle', + textStyle: { + color: '#333333', + fontSize: '12' + } +} +export const DEFAULT_BACKGROUND_COLOR = { + color: '#ffffff', + alpha: 100, + borderRadius: 5 +} +export const DEFAULT_BASE_MAP_STYLE = { + baseMapTheme: 'light' +} +export const BASE_MAP = { + title: { + text: '', + textStyle: { + fontWeight: 'normal' + } + }, + visualMap: { + min: 50, + max: 52, + text: ['High', 'Low'], + realtime: false, + calculable: true, + inRange: { + color: ['lightskyblue', 'yellow', 'orangered'] + }, + right: 0 + }, + + tooltip: {}, + geo: [ + { + show: true, + map: 'BUDDLE_MAP_BORDER', + + emphasis: { + disabled: true + }, + itemStyle: { + borderWidth: 2, + borderColor: '#d1d1d1', + borderType: 'solid' + }, + + roam: false + }, + { + show: true, + map: 'BUDDLE_MAP', + label: { + normal: { + show: false + }, + emphasis: { + show: false + } + }, + itemStyle: { + areaColor: '#f3f3f3', + borderType: 'dashed', + borderColor: '#fff' + }, + + roam: false + } + ], + series: [ + { + name: '', + type: 'scatter', + coordinateSystem: 'geo', + data: [] + } + ] +} + +export const compareItem = { + type: 'none', // year-yoy/month-yoy等 + resultData: 'percent', // 对比差sub,百分比percent等 + field: '', + custom: { + field: '', + calcType: '0', // 0-增长值,1-增长率 + timeType: '0', // 0-固定日期,1-日期区间 + currentTime: '', + compareTime: '', + currentTimeRange: [], + compareTimeRange: [] + } +} + +export const formatterItem = { + type: 'auto', // auto,value,percent + unit: 1, // 换算单位 + suffix: '', // 单位后缀 + decimalCount: 2, // 小数位数 + thousandSeparator: true// 千分符 +} + +const convertData = (mapData, chart) => { + let maxVal = 0 + const k = terminalType === 'pc' ? 30 : 15 + const names = chart.data.x + const results = [] + for (let index = 0; index < names.length; index++) { + const name = names[index]; + const item = chart.data.series[0].data[index] + results.push({ + name, + value: (mapData[name] ? mapData[name].concat(item.value) : []), + dimensionList: item.dimensionList, + quotaList: item.quotaList + }) + maxVal = Math.max(maxVal, item.value) + } + const rate = k / maxVal + + return { + value: results, + rate: rate + } +} + +let terminalType = 'pc' + +export function baseMapOption(chart_option, chart, mapData, terminal = 'pc') { + terminalType = terminal + // 处理shape attr + let customAttr = {} + if (chart.customAttr) { + customAttr = JSON.parse(chart.customAttr) + if (customAttr.color) { + chart_option.color = customAttr.color.colors + } + // tooltip + if (customAttr.tooltip) { + const tooltip = JSON.parse(JSON.stringify(customAttr.tooltip)) + const reg = new RegExp('\n', 'g') + const text = tooltip.formatter.replace(reg, '
') + tooltip.formatter = function (params) { + const a = params.seriesName + const b = params.name + const c = params.value ? params.value[2] : '' + return text.replace(new RegExp('{a}', 'g'), a).replace(new RegExp('{b}', 'g'), b).replace(new RegExp('{c}', 'g'), c) + } + chart_option.tooltip = tooltip + } + } + // 处理data + if (chart.data) { + chart_option.title.text = chart.title + if (chart.data.series && chart.data.series.length > 0) { + chart_option.series[0].name = chart.data.series[0].name + // label + if (customAttr.label) { + const text = customAttr.label.formatter + chart_option.series[0].label = customAttr.label + chart_option.series[0].label.formatter = function (params) { + const a = params.seriesName + const b = params.name + const c = params.value ? params.value[2] : '' + return text.replace(new RegExp('{a}', 'g'), a).replace(new RegExp('{b}', 'g'), b).replace(new RegExp('{c}', 'g'), c) + } + chart_option.series[0].labelLine = customAttr.label.labelLine + } + + // visualMap + const valueArr = chart.data.series[0].data + if (valueArr && valueArr.length > 0) { + const values = [] + valueArr.forEach(function (ele) { + values.push(ele.value) + }) + chart_option.visualMap.min = Math.min(...values) + chart_option.visualMap.max = Math.max(...values) + if (chart_option.visualMap.min === chart_option.visualMap.max) { + chart_option.visualMap.min = 0 + } + } else { + chart_option.visualMap.min = 0 + chart_option.visualMap.max = 0 + } + if (chart_option.visualMap.min === 0 && chart_option.visualMap.max === 0) { + chart_option.visualMap.max = 100 + } + // color + if (customAttr.color && customAttr.color.colors) { + chart_option.visualMap.inRange.color = customAttr.color.colors + chart_option.visualMap.inRange.colorAlpha = customAttr.color.alpha / 100 + } + // chart_option.visualMap = null + + const convert = convertData(mapData, chart) + chart_option.series[0].data = convert.value + chart_option.series[0].symbolSize = val => val[2] * convert.rate + + } + } + // console.log(chart_option); + componentStyle(chart_option, chart) + return chart_option +} + +export function componentStyle(chart_option, chart) { + const padding = '8px' + if (chart.customStyle) { + const customStyle = JSON.parse(chart.customStyle) + if (customStyle.text) { + chart_option.title.show = customStyle.text.show + // 水平方向 + if (customStyle.text.hPosition === 'left') { + chart_option.title.left = padding + } else if (customStyle.text.hPosition === 'right') { + chart_option.title.right = padding + } else { + chart_option.title.left = customStyle.text.hPosition + } + // 垂直方向 + if (customStyle.text.vPosition === 'top') { + chart_option.title.top = padding + } else if (customStyle.text.vPosition === 'bottom') { + chart_option.title.bottom = padding + } else { + chart_option.title.top = customStyle.text.vPosition + } + const style = chart_option.title.textStyle ? chart_option.title.textStyle : {} + style.fontSize = customStyle.text.fontSize + style.color = customStyle.text.color + customStyle.text.isItalic ? style.fontStyle = 'italic' : style.fontStyle = 'normal' + customStyle.text.isBolder ? style.fontWeight = 'bold' : style.fontWeight = 'normal' + chart_option.title.textStyle = style + } + if (customStyle.legend && chart_option.legend) { + chart_option.legend.show = customStyle.legend.show + // 水平方向 + if (customStyle.legend.hPosition === 'left') { + chart_option.legend.left = padding + } else if (customStyle.legend.hPosition === 'right') { + chart_option.legend.right = padding + } else { + chart_option.legend.left = customStyle.legend.hPosition + } + // 垂直方向 + if (customStyle.legend.vPosition === 'top') { + chart_option.legend.top = padding + } else if (customStyle.legend.vPosition === 'bottom') { + chart_option.legend.bottom = padding + } else { + chart_option.legend.top = customStyle.legend.vPosition + } + chart_option.legend.orient = customStyle.legend.orient + chart_option.legend.icon = customStyle.legend.icon + chart_option.legend.textStyle = customStyle.legend.textStyle + + } + + if (customStyle.background) { + chart_option.backgroundColor = hexColorToRGBA(customStyle.background.color, customStyle.background.alpha) + } + } +} + +export function hexColorToRGBA(hex, alpha) { + const rgb = [] // 定义rgb数组 + if (/^\#[0-9A-F]{3}$/i.test(hex)) { // 判断传入是否为#三位十六进制数 + let sixHex = '#' + hex.replace(/[0-9A-F]/ig, function (kw) { + sixHex += kw + kw // 把三位16进制数转化为六位 + }) + hex = sixHex // 保存回hex + } + if (/^#[0-9A-F]{6}$/i.test(hex)) { // 判断传入是否为#六位十六进制数 + hex.replace(/[0-9A-F]{2}/ig, function (kw) { + // eslint-disable-next-line no-eval + rgb.push(eval('0x' + kw)) // 十六进制转化为十进制并存如数组 + }) + return `rgba(${rgb.join(',')},${alpha / 100})` // 输出RGB格式颜色 + } else { + return 'rgb(0,0,0)' + } +} + + +export const DEFAULT_YAXIS_EXT_STYLE = { + show: true, + position: 'right', + name: '', + nameTextStyle: { + color: '#333333', + fontSize: 12 + }, + axisLabel: { + show: true, + color: '#333333', + fontSize: '12', + rotate: 0, + formatter: '{value}' + }, + splitLine: { + show: true, + lineStyle: { + color: '#cccccc', + width: 1, + style: 'solid' + } + }, + axisValue: { + auto: true, + min: null, + max: null, + split: null, + splitCount: null + } +} + +export const getDefaultTemplate = (chart, type, feed, showKey) => { + if (!chart || !chart.viewFields || !type) return null; + let viewFields = [] + if (chart.viewFields instanceof Array) { + viewFields = JSON.parse(JSON.stringify(chart.viewFields)) + } else { + viewFields = JSON.parse(chart.viewFields) + } + const separator = feed ? '\n' : ' ' + return viewFields.filter(field => field.busiType && field.busiType === type).map(field => { + const fieldName = field.name + let template = "${" + field.name + "}" + if (showKey) { + template = fieldName + ":${" + field.name + "}" + } + return template + }).join(separator) +} + +export function uuid() { + return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1); +} + +export const reverseColor = colorValue => { + colorValue = '0x' + colorValue.replace(/#/g, '') + const str = '000000' + (0xFFFFFF - colorValue).toString(16) + return '#' + str.substring(str.length - 6, str.length) +} + + +export const DEFAULT_XAXIS_STYLE = { + show: true, + position: 'bottom', + name: '', + nameTextStyle: { + color: '#333333', + fontSize: 12 + }, + axisLabel: { + show: true, + color: '#333333', + fontSize: '12', + rotate: 0, + formatter: '{value}' + }, + axisLine: { + show: true, + lineStyle: { + color: '#cccccc', + width: 1, + style: 'solid' + } + }, + splitLine: { + show: false, + lineStyle: { + color: '#cccccc', + width: 1, + style: 'solid' + } + }, + axisValue: { + auto: true, + min: null, + max: null, + split: null, + splitCount: null + }, + axisLabelFormatter: { + type: 'auto', // auto,value,percent + unit: 1, // 换算单位 + suffix: '', // 单位后缀 + decimalCount: 2, // 小数位数 + thousandSeparator: true// 千分符 + } +} + +export const DEFAULT_YAXIS_STYLE = { + show: true, + position: 'left', + name: '', + nameTextStyle: { + color: '#333333', + fontSize: 12 + }, + axisLabel: { + show: true, + color: '#333333', + fontSize: '12', + rotate: 0, + formatter: '{value}' + }, + axisLine: { + show: false, + lineStyle: { + color: '#cccccc', + width: 1, + style: 'solid' + } + }, + splitLine: { + show: true, + lineStyle: { + color: '#cccccc', + width: 1, + style: 'solid' + } + }, + axisValue: { + auto: true, + min: null, + max: null, + split: null, + splitCount: null + }, + axisLabelFormatter: { + type: 'auto', // auto,value,percent + unit: 1, // 换算单位 + suffix: '', // 单位后缀 + decimalCount: 2, // 小数位数 + thousandSeparator: true// 千分符 + } +} + +export function transAxisPosition(chart, axis) { + if (chart.type.includes('horizontal')) { + switch (axis.position) { + case 'top': + return 'left' + case 'bottom': + return 'right' + case 'left': + return 'bottom' + case 'right': + return 'top' + default: + return axis.position + } + } else { + return axis.position + } +} + +export function getLineDash(type) { + switch (type) { + case 'solid': + return [0, 0] + case 'dashed': + return [10, 8] + case 'dotted': + return [2, 2] + default: + return [0, 0] + } +} diff --git a/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/utils/validate.js b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/utils/validate.js new file mode 100644 index 0000000000..3e8ffa9448 --- /dev/null +++ b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/utils/validate.js @@ -0,0 +1,15 @@ +/** + * Created by PanJiaChen on 16/11/18. + */ + +/** + * @param {string} path + * @returns {Boolean} + */ +export function isExternal(path) { + return /^(https?:|mailto:|tel:)/.test(path) || /^(http?:|mailto:|tel:)/.test(path) || path.startsWith('/api/pluginCommon/staticInfo') +} + + + + diff --git a/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/views/PluginDemo.vue b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/views/PluginDemo.vue new file mode 100644 index 0000000000..1164dfab1d --- /dev/null +++ b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/views/PluginDemo.vue @@ -0,0 +1,55 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/views/antv/chartmix/data.vue b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/views/antv/chartmix/data.vue new file mode 100644 index 0000000000..678959c715 --- /dev/null +++ b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/views/antv/chartmix/data.vue @@ -0,0 +1,663 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/views/antv/chartmix/index.vue b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/views/antv/chartmix/index.vue new file mode 100644 index 0000000000..88e62a3d6e --- /dev/null +++ b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/views/antv/chartmix/index.vue @@ -0,0 +1,717 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/views/antv/chartmix/style.vue b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/views/antv/chartmix/style.vue new file mode 100644 index 0000000000..34a13fcf87 --- /dev/null +++ b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/views/antv/chartmix/style.vue @@ -0,0 +1,175 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/views/antv/chartmix/type.vue b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/views/antv/chartmix/type.vue new file mode 100644 index 0000000000..db7ca40b93 --- /dev/null +++ b/extensions/dataease-extensions-view/view-chartmix/view-chartmix-frontend/src/views/antv/chartmix/type.vue @@ -0,0 +1,63 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-racebar/build.sh b/extensions/dataease-extensions-view/view-racebar/build.sh new file mode 100644 index 0000000000..d9fca1ae58 --- /dev/null +++ b/extensions/dataease-extensions-view/view-racebar/build.sh @@ -0,0 +1,8 @@ +#!/bin/sh +mvn clean package + +cp view-racebar-backend/target/view-racebar-backend-1.18.10.jar . + +zip -r racebar.zip ./view-racebar-backend-1.18.10.jar ./plugin.json + +rm -f ./view-racebar-backend-1.18.10.jar diff --git a/extensions/dataease-extensions-view/view-racebar/plugin.json b/extensions/dataease-extensions-view/view-racebar/plugin.json new file mode 100644 index 0000000000..6eacf6d870 --- /dev/null +++ b/extensions/dataease-extensions-view/view-racebar/plugin.json @@ -0,0 +1,13 @@ +{ + "name": "ECharts 动态排序图", + "free": 0, + "store": "thirdpart", + "cost": 0, + "category": "view", + "descript": "ECharts 动态排序图插件", + "version": "1.18.10", + "creator": "DATAEASE", + "moduleName": "view-racebar-backend", + "require": "1.18.10", + "dsType": "" +} \ No newline at end of file diff --git a/extensions/dataease-extensions-view/view-racebar/pom.xml b/extensions/dataease-extensions-view/view-racebar/pom.xml new file mode 100644 index 0000000000..30fba28ad2 --- /dev/null +++ b/extensions/dataease-extensions-view/view-racebar/pom.xml @@ -0,0 +1,20 @@ + + + + dataease-extensions-view + io.dataease + ${dataease.version} + + 4.0.0 + + view-racebar + pom + + view-racebar-frontend + view-racebar-backend + + + + diff --git a/extensions/dataease-extensions-view/view-racebar/view-racebar-backend/pom.xml b/extensions/dataease-extensions-view/view-racebar/view-racebar-backend/pom.xml new file mode 100644 index 0000000000..027a76cf9e --- /dev/null +++ b/extensions/dataease-extensions-view/view-racebar/view-racebar-backend/pom.xml @@ -0,0 +1,109 @@ + + + + view-racebar + io.dataease + ${dataease.version} + + 4.0.0 + + view-racebar-backend + + + + io.dataease + dataease-plugin-view + + + + + + + src/main/java + + **/*.properties + **/*.xml + + false + + + src/main/resources + + **/* + + false + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 11 + 11 + + + + + org.apache.maven.plugins + maven-jar-plugin + 2.4 + + + **/server/** + **/*.properties + **/Application* + + + + + + maven-clean-plugin + + + + src/main/resources/static + + ** + + false + + + + + + + + + org.apache.maven.plugins + maven-antrun-plugin + + + main-class-placement + generate-resources + + + + + + + + + + + + run + + + + + + + + + + + diff --git a/extensions/dataease-extensions-view/view-racebar/view-racebar-backend/src/main/java/io/dataease/plugins/view/official/handler/DefaultViewStatHandler.java b/extensions/dataease-extensions-view/view-racebar/view-racebar-backend/src/main/java/io/dataease/plugins/view/official/handler/DefaultViewStatHandler.java new file mode 100644 index 0000000000..176a1e7ecd --- /dev/null +++ b/extensions/dataease-extensions-view/view-racebar/view-racebar-backend/src/main/java/io/dataease/plugins/view/official/handler/DefaultViewStatHandler.java @@ -0,0 +1,107 @@ +package io.dataease.plugins.view.official.handler; + +import com.google.gson.Gson; +import io.dataease.plugins.common.constants.datasource.SQLConstants; +import io.dataease.plugins.common.request.permission.DataSetRowPermissionsTreeDTO; +import io.dataease.plugins.common.util.ConstantsUtil; +import io.dataease.plugins.view.entity.*; +import io.dataease.plugins.view.handler.PluginViewStatHandler; +import io.dataease.plugins.view.service.ViewPluginBaseService; +import io.dataease.plugins.view.service.ViewPluginService; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.ObjectUtils; +import org.apache.commons.lang3.StringUtils; +import org.stringtemplate.v4.ST; +import org.stringtemplate.v4.STGroup; +import org.stringtemplate.v4.STGroupFile; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +public class DefaultViewStatHandler implements PluginViewStatHandler { + + @Override + public String build(PluginViewParam pluginViewParam, ViewPluginService viewPluginService) { + + + ViewPluginBaseService baseService = viewPluginService.getBaseService(); + PluginViewSet pluginViewSet = pluginViewParam.getPluginViewSet(); + List rowPermissionsTree = pluginViewParam.getRowPermissionsTree(); + String dsType = pluginViewSet.getDsType(); + PluginViewSQL tableObj = baseService.getTableObj(pluginViewSet); + + Map> fieldSQLMap = new HashMap<>(); + + + for (int i = 0; i < pluginViewParam.getPluginViewFields().size(); i++) { + PluginViewField pluginViewField = pluginViewParam.getPluginViewFields().get(i); + if (StringUtils.equals(pluginViewField.getTypeField(), "xAxisExt")) { + pluginViewField.setTypeField("xAxis"); + pluginViewField.setExtField(1); + } + String typeKey = pluginViewField.getTypeField(); + PluginSingleField pluginSingleField = baseService.buildField(dsType, pluginViewField, tableObj, i); + List lists = fieldSQLMap.getOrDefault(typeKey, new ArrayList<>()); + lists.add(pluginSingleField); + fieldSQLMap.put(typeKey, lists); + } + + + List xFields = fieldSQLMap.getOrDefault("xAxis", new ArrayList<>()).stream().filter(singleField -> ObjectUtils.isNotEmpty(singleField.getField())).map(PluginSingleField::getField).collect(Collectors.toList()); + + // List xWheres = fieldSQLMap.get("xAxis").stream().map(singleField -> singleField.getWhere()).collect(Collectors.toList()); + + List yFields = fieldSQLMap.getOrDefault("yAxis", new ArrayList<>()).stream().filter(singleField -> ObjectUtils.isNotEmpty(singleField.getField())).map(PluginSingleField::getField).collect(Collectors.toList()); + List yWheres = fieldSQLMap.getOrDefault("yAxis", new ArrayList<>()).stream().filter(singleField -> ObjectUtils.isNotEmpty(singleField.getWhere())).map(PluginSingleField::getWhere).collect(Collectors.toList()); + + /*List yExtFields = fieldSQLMap.getOrDefault("yAxisExt", new ArrayList<>()).stream().filter(singleField -> ObjectUtils.isNotEmpty(singleField.getField())).map(PluginSingleField::getField).collect(Collectors.toList()); + List yExtOrders = fieldSQLMap.getOrDefault("yAxisExt", new ArrayList<>()).stream().filter(singleField -> ObjectUtils.isNotEmpty(singleField.getSort())).map(PluginSingleField::getSort).collect(Collectors.toList()); + List yExtWheres = fieldSQLMap.getOrDefault("yAxisExt", new ArrayList<>()).stream().filter(singleField -> ObjectUtils.isNotEmpty(singleField.getWhere())).map(PluginSingleField::getWhere).collect(Collectors.toList()); + + yFields.addAll(yExtFields); + yOrders.addAll(yExtOrders); + yWheres.addAll(yExtWheres);*/ + + // 处理视图中字段过滤 + String customWheres = baseService.customWhere(dsType, pluginViewParam.getPluginChartFieldCustomFilters(), tableObj); + // 处理仪表板字段过滤 + String panelWheres = baseService.panelWhere(dsType, pluginViewParam.getPluginChartExtFilters(), tableObj); + // 构建sql所有参数 + + String permissionWhere = baseService.permissionWhere(dsType, rowPermissionsTree, tableObj); + List wheres = new ArrayList<>(); + if (customWheres != null) wheres.add(customWheres); + if (panelWheres != null) wheres.add(panelWheres); + if (permissionWhere != null) wheres.add(permissionWhere); + List groups = new ArrayList<>(); + groups.addAll(xFields); + + // 外层再次套sql + List aggWheres = new ArrayList<>(); + aggWheres.addAll(yWheres.stream().filter(ObjectUtils::isNotEmpty).collect(Collectors.toList())); + + STGroup stg = new STGroupFile(SQLConstants.SQL_TEMPLATE); + ST st_sql = stg.getInstanceOf("querySql"); + if (CollectionUtils.isNotEmpty(groups)) st_sql.add("groups", groups); + if (CollectionUtils.isNotEmpty(yFields)) st_sql.add("aggregators", yFields); + if (CollectionUtils.isNotEmpty(wheres)) st_sql.add("filters", wheres); + if (ObjectUtils.isNotEmpty(tableObj)) st_sql.add("table", tableObj); + String sql = st_sql.render(); + + String brackets = ConstantsUtil.constantsValue(dsType, "BRACKETS"); + String table_alias_prefix = ConstantsUtil.constantsValue(dsType, "TABLE_ALIAS_PREFIX"); + + ST st = stg.getInstanceOf("querySql"); + PluginViewSQL tableSQL = PluginViewSQL.builder() + .tableName(String.format(brackets, sql)) + .tableAlias(String.format(table_alias_prefix, 1)) + .build(); + if (CollectionUtils.isNotEmpty(aggWheres)) st.add("filters", aggWheres); + if (ObjectUtils.isNotEmpty(tableSQL)) st.add("table", tableSQL); + return baseService.sqlLimit(dsType, st.render(), pluginViewParam.getPluginViewLimit()); + } + +} diff --git a/extensions/dataease-extensions-view/view-racebar/view-racebar-backend/src/main/java/io/dataease/plugins/view/official/impl/RaceBarService.java b/extensions/dataease-extensions-view/view-racebar/view-racebar-backend/src/main/java/io/dataease/plugins/view/official/impl/RaceBarService.java new file mode 100644 index 0000000000..d5819a48b9 --- /dev/null +++ b/extensions/dataease-extensions-view/view-racebar/view-racebar-backend/src/main/java/io/dataease/plugins/view/official/impl/RaceBarService.java @@ -0,0 +1,186 @@ +package io.dataease.plugins.view.official.impl; + +import com.google.gson.Gson; +import io.dataease.plugins.common.dto.StaticResource; +import io.dataease.plugins.view.entity.PluginViewField; +import io.dataease.plugins.view.entity.PluginViewParam; +import io.dataease.plugins.view.entity.PluginViewType; +import io.dataease.plugins.view.official.handler.DefaultViewStatHandler; +import io.dataease.plugins.view.service.ViewPluginService; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; + +import java.io.InputStream; +import java.util.*; +import java.util.stream.Collectors; + +@Service +public class RaceBarService extends ViewPluginService { + private static final String VIEW_TYPE_VALUE = "race-bar"; + + /* 下版这些常量移到sdk */ + private static final String TYPE = "-type"; + private static final String DATA = "-data"; + private static final String STYLE = "-style"; + private static final String VIEW = "-view"; + private static final String SUFFIX = "svg"; + /* 下版这些常量移到sdk */ + private static final String VIEW_TYPE = VIEW_TYPE_VALUE + TYPE; + private static final String VIEW_DATA = VIEW_TYPE_VALUE + DATA; + private static final String VIEW_STYLE = VIEW_TYPE_VALUE + STYLE; + private static final String VIEW_VIEW = VIEW_TYPE_VALUE + VIEW; + + private static final String[] VIEW_STYLE_PROPERTIES = { + "color-selector", + "label-selector", + "tooltip-selector", + "title-selector", + }; + + private static final Map VIEW_STYLE_PROPERTY_INNER = new HashMap<>(); + + static { + VIEW_STYLE_PROPERTY_INNER.put("color-selector", new String[]{"value", "alpha"}); + VIEW_STYLE_PROPERTY_INNER.put("label-selector", new String[]{"show", "fontSize", "color", "position", "formatter"}); + VIEW_STYLE_PROPERTY_INNER.put("tooltip-selector", new String[]{"show", "textStyle", "formatter"}); + VIEW_STYLE_PROPERTY_INNER.put("title-selector", new String[]{"show", "title", "fontSize", "color", "hPosition", "vPosition", "isItalic", "isBolder"}); + } + + @Override + public PluginViewType viewType() { + PluginViewType pluginViewType = new PluginViewType(); + pluginViewType.setRender("echarts"); + pluginViewType.setCategory("chart.chart_type_compare"); + pluginViewType.setValue(VIEW_TYPE_VALUE); + pluginViewType.setProperties(VIEW_STYLE_PROPERTIES); + pluginViewType.setPropertyInner(VIEW_STYLE_PROPERTY_INNER); + return pluginViewType; + } + + @Override + public Object format(Object o) { + return null; + } + + @Override + public List components() { + List results = new ArrayList<>(); + results.add(VIEW_VIEW); + results.add(VIEW_DATA); + results.add(VIEW_TYPE); + results.add(VIEW_STYLE); + return results; + } + + @Override + public List staticResources() { + List results = new ArrayList<>(); + StaticResource staticResource = new StaticResource(); + staticResource.setName(VIEW_TYPE_VALUE); + staticResource.setSuffix(SUFFIX); + results.add(staticResource); + results.add(pluginSvg()); + return results; + } + + private StaticResource pluginSvg() { + StaticResource staticResource = new StaticResource(); + staticResource.setName("view-racebar-backend"); + staticResource.setSuffix("svg"); + return staticResource; + } + + + @Override + protected InputStream readContent(String s) { + InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream("static/" + s); + return resourceAsStream; + } + + @Override + public String generateSQL(PluginViewParam param) { + + List xAxis = param.getFieldsByType("xAxis"); + List yAxis = param.getFieldsByType("yAxis"); + + if (CollectionUtils.isEmpty(xAxis) || CollectionUtils.isEmpty(yAxis) || xAxis.size() < 2) { + return null; + } + String sql = new DefaultViewStatHandler().build(param, this); + return sql; + + } + + @Override + public Map formatResult(PluginViewParam pluginViewParam, List data, Boolean isDrill) { + return format(pluginViewParam, data, isDrill); + } + + + public Map format(PluginViewParam pluginViewParam, List data, boolean isDrill) { + + Map map = new HashMap<>(); + + map.put("data", data); + + Map encode = new HashMap<>(); + + String type = null; + + for (int i = 0; i < pluginViewParam.getPluginViewFields().size(); i++) { + PluginViewField p = pluginViewParam.getPluginViewFields().get(i); + if (StringUtils.equals(p.getTypeField(), "yAxis")) { + encode.put("x", i); + type = p.getType(); + } else if (StringUtils.equals(p.getTypeField(), "xAxis")) { + if (p.getExtField() == 1) { + map.put("extIndex", i); + } else { + encode.put("y", i); + } + } + } + map.put("encode", encode); + + Set xs = new HashSet<>(); + data.forEach(ss -> { + xs.add(ss[encode.get("y")]); + }); + + Map> groupData = data.stream().collect(Collectors.toMap( + k -> k[(Integer) map.get("extIndex")], + v -> { + List list = new ArrayList<>(); + list.add(v); + return list; + }, + (oldList, newList) -> { + oldList.addAll(newList); + return oldList; + }) + ); + + for (String key : groupData.keySet()) { + String finalType = type; + groupData.put(key, groupData.get(key).stream().sorted((o1, o2) -> { + if (StringUtils.equals(finalType, "LONG")) { + return Long.valueOf(o2[encode.get("x")]).compareTo(Long.valueOf(o1[encode.get("x")])); + } else if (StringUtils.equals(finalType, "DOUBLE")) { + return Double.valueOf(o2[encode.get("x")]).compareTo(Double.valueOf(o1[encode.get("x")])); + } + return o2[encode.get("x")].compareTo(o1[encode.get("x")]); + }).collect(Collectors.toList())); + + } + + map.put("groupData", groupData); + + map.put("extXs", new ArrayList<>(groupData.keySet()).stream().sorted().collect(Collectors.toList())); + + map.put("xs", new ArrayList<>(xs).stream().sorted().collect(Collectors.toList())); + + return map; + } + +} diff --git a/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/.babelrc b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/.babelrc new file mode 100644 index 0000000000..3a280ba34b --- /dev/null +++ b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/.babelrc @@ -0,0 +1,12 @@ +{ + "presets": [ + ["env", { + "modules": false, + "targets": { + "browsers": ["> 1%", "last 2 versions", "not ie <= 8"] + } + }], + "stage-2" + ], + "plugins": ["transform-vue-jsx", "transform-runtime"] +} diff --git a/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/.editorconfig b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/.editorconfig new file mode 100644 index 0000000000..9d08a1a828 --- /dev/null +++ b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/.editorconfig @@ -0,0 +1,9 @@ +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true diff --git a/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/.gitignore b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/.gitignore new file mode 100644 index 0000000000..541a820f6c --- /dev/null +++ b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/.gitignore @@ -0,0 +1,14 @@ +.DS_Store +node_modules/ +/dist/ +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Editor directories and files +.idea +.vscode +*.suo +*.ntvs* +*.njsproj +*.sln diff --git a/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/.postcssrc.js b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/.postcssrc.js new file mode 100644 index 0000000000..eee3e92d7f --- /dev/null +++ b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/.postcssrc.js @@ -0,0 +1,10 @@ +// https://github.com/michael-ciniawsky/postcss-load-config + +module.exports = { + "plugins": { + "postcss-import": {}, + "postcss-url": {}, + // to edit target browsers: use "browserslist" field in package.json + "autoprefixer": {} + } +} diff --git a/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/README.md b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/README.md new file mode 100644 index 0000000000..c1e4be95e0 --- /dev/null +++ b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/README.md @@ -0,0 +1,21 @@ +# deplugin-view-frontend + +> A Vue.js project + +## Build Setup + +``` bash +# install dependencies +npm install + +# serve with hot reload at localhost:8080 +npm run dev + +# build for production with minification +npm run build + +# build for production and view the bundle analyzer report +npm run build --report +``` + +For a detailed explanation on how things work, check out the [guide](http://vuejs-templates.github.io/webpack/) and [docs for vue-loader](http://vuejs.github.io/vue-loader). diff --git a/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/build/build-async-plugins.js b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/build/build-async-plugins.js new file mode 100644 index 0000000000..2303854531 --- /dev/null +++ b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/build/build-async-plugins.js @@ -0,0 +1,35 @@ +'use strict' +require('./check-versions')() + +process.env.NODE_ENV = 'production' + +const ora = require('ora') +const chalk = require('chalk') +const webpack = require('webpack') +const webpackConfig = require('./webpack.async-plugins') + +const spinner = ora('building for sync-plugins...') +spinner.start() + +webpack(webpackConfig, function (err, stats) { + spinner.stop() + if (err) throw err + process.stdout.write(stats.toString({ + colors: true, + modules: false, + children: false, + chunks: false, + chunkModules: false + }) + '\n\n') + + if (stats.hasErrors()) { + console.log(chalk.red(' Build failed with errors.\n')) + process.exit(1) + } + + console.log(chalk.cyan(' Build complete.\n')) + console.log(chalk.yellow( + ' Tip: built files are meant to be served over an HTTP server.\n' + + ' Opening index.html over file:// won\'t work.\n' + )) +}) diff --git a/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/build/build.js b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/build/build.js new file mode 100644 index 0000000000..8f2ad8ad49 --- /dev/null +++ b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/build/build.js @@ -0,0 +1,41 @@ +'use strict' +require('./check-versions')() + +process.env.NODE_ENV = 'production' + +const ora = require('ora') +const rm = require('rimraf') +const path = require('path') +const chalk = require('chalk') +const webpack = require('webpack') +const config = require('../config') +const webpackConfig = require('./webpack.prod.conf') + +const spinner = ora('building for production...') +spinner.start() + +rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => { + if (err) throw err + webpack(webpackConfig, (err, stats) => { + spinner.stop() + if (err) throw err + process.stdout.write(stats.toString({ + colors: true, + modules: false, + children: false, // If you are using ts-loader, setting this to true will make TypeScript errors show up during build. + chunks: false, + chunkModules: false + }) + '\n\n') + + if (stats.hasErrors()) { + console.log(chalk.red(' Build failed with errors.\n')) + process.exit(1) + } + + console.log(chalk.cyan(' Build complete.\n')) + console.log(chalk.yellow( + ' Tip: built files are meant to be served over an HTTP server.\n' + + ' Opening index.html over file:// won\'t work.\n' + )) + }) +}) diff --git a/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/build/check-versions.js b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/build/check-versions.js new file mode 100644 index 0000000000..3ef972a08d --- /dev/null +++ b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/build/check-versions.js @@ -0,0 +1,54 @@ +'use strict' +const chalk = require('chalk') +const semver = require('semver') +const packageConfig = require('../package.json') +const shell = require('shelljs') + +function exec (cmd) { + return require('child_process').execSync(cmd).toString().trim() +} + +const versionRequirements = [ + { + name: 'node', + currentVersion: semver.clean(process.version), + versionRequirement: packageConfig.engines.node + } +] + +if (shell.which('npm')) { + versionRequirements.push({ + name: 'npm', + currentVersion: exec('npm --version'), + versionRequirement: packageConfig.engines.npm + }) +} + +module.exports = function () { + const warnings = [] + + for (let i = 0; i < versionRequirements.length; i++) { + const mod = versionRequirements[i] + + if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) { + warnings.push(mod.name + ': ' + + chalk.red(mod.currentVersion) + ' should be ' + + chalk.green(mod.versionRequirement) + ) + } + } + + if (warnings.length) { + console.log('') + console.log(chalk.yellow('To use this template, you must update following to modules:')) + console.log() + + for (let i = 0; i < warnings.length; i++) { + const warning = warnings[i] + console.log(' ' + warning) + } + + console.log() + process.exit(1) + } +} diff --git a/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/build/logo.png b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/build/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..f3d2503fc2a44b5053b0837ebea6e87a2d339a43 GIT binary patch literal 6849 zcmaKRcUV(fvo}bjDT-7nLI_nlK}sT_69H+`qzVWDA|yaU?}j417wLi^B1KB1SLsC& zL0ag7$U(XW5YR7p&Ux?sP$d4lvMt8C^+TcQu4F zQqv!UF!I+kw)c0jhd6+g6oCr9P?7)?!qX1ui*iL{p}sKCAGuJ{{W)0z1pLF|=>h}& zt(2Lr0Z`2ig8<5i%Zk}cO5Fm=LByqGWaS`oqChZdEFmc`0hSb#gg|Aap^{+WKOYcj zHjINK)KDG%&s?Mt4CL(T=?;~U@bU2x_mLKN!#GJuK_CzbNw5SMEJorG!}_5;?R>@1 zSl)jns3WlU7^J%=(hUtfmuUCU&C3%8B5C^f5>W2Cy8jW3#{Od{lF1}|?c61##3dzA zsPlFG;l_FzBK}8>|H_Ru_H#!_7$UH4UKo3lKOA}g1(R&|e@}GINYVzX?q=_WLZCgh z)L|eJMce`D0EIwgRaNETDsr+?vQknSGAi=7H00r`QnI%oQnFxm`G2umXso9l+8*&Q z7WqF|$p49js$mdzo^BXpH#gURy=UO;=IMrYc5?@+sR4y_?d*~0^YP7d+y0{}0)zBM zIKVM(DBvICK#~7N0a+PY6)7;u=dutmNqK3AlsrUU9U`d;msiucB_|8|2kY=(7XA;G zwDA8AR)VCA#JOkxm#6oHNS^YVuOU;8p$N)2{`;oF|rQ?B~K$%rHDxXs+_G zF5|-uqHZvSzq}L;5Kcy_P+x0${33}Ofb6+TX&=y;;PkEOpz%+_bCw_{<&~ zeLV|!bP%l1qxywfVr9Z9JI+++EO^x>ZuCK);=$VIG1`kxK8F2M8AdC$iOe3cj1fo(ce4l-9 z7*zKy3={MixvUk=enQE;ED~7tv%qh&3lR<0m??@w{ILF|e#QOyPkFYK!&Up7xWNtL zOW%1QMC<3o;G9_S1;NkPB6bqbCOjeztEc6TsBM<(q9((JKiH{01+Ud=uw9B@{;(JJ z-DxI2*{pMq`q1RQc;V8@gYAY44Z!%#W~M9pRxI(R?SJ7sy7em=Z5DbuDlr@*q|25V)($-f}9c#?D%dU^RS<(wz?{P zFFHtCab*!rl(~j@0(Nadvwg8q|4!}L^>d?0al6}Rrv9$0M#^&@zjbfJy_n!%mVHK4 z6pLRIQ^Uq~dnyy$`ay51Us6WaP%&O;@49m&{G3z7xV3dLtt1VTOMYl3UW~Rm{Eq4m zF?Zl_v;?7EFx1_+#WFUXxcK78IV)FO>42@cm@}2I%pVbZqQ}3;p;sDIm&knay03a^ zn$5}Q$G!@fTwD$e(x-~aWP0h+4NRz$KlnO_H2c< z(XX#lPuW_%H#Q+c&(nRyX1-IadKR-%$4FYC0fsCmL9ky3 zKpxyjd^JFR+vg2!=HWf}2Z?@Td`0EG`kU?{8zKrvtsm)|7>pPk9nu@2^z96aU2<#` z2QhvH5w&V;wER?mopu+nqu*n8p~(%QkwSs&*0eJwa zMXR05`OSFpfyRb!Y_+H@O%Y z0=K^y6B8Gcbl?SA)qMP3Z+=C(?8zL@=74R=EVnE?vY!1BQy2@q*RUgRx4yJ$k}MnL zs!?74QciNb-LcG*&o<9=DSL>1n}ZNd)w1z3-0Pd^4ED1{qd=9|!!N?xnXjM!EuylY z5=!H>&hSofh8V?Jofyd!h`xDI1fYAuV(sZwwN~{$a}MX^=+0TH*SFp$vyxmUv7C*W zv^3Gl0+eTFgBi3FVD;$nhcp)ka*4gSskYIqQ&+M}xP9yLAkWzBI^I%zR^l1e?bW_6 zIn{mo{dD=)9@V?s^fa55jh78rP*Ze<3`tRCN4*mpO$@7a^*2B*7N_|A(Ve2VB|)_o z$=#_=aBkhe(ifX}MLT()@5?OV+~7cXC3r!%{QJxriXo9I%*3q4KT4Xxzyd{ z9;_%=W%q!Vw$Z7F3lUnY+1HZ*lO;4;VR2+i4+D(m#01OYq|L_fbnT;KN<^dkkCwtd zF7n+O7KvAw8c`JUh6LmeIrk4`F3o|AagKSMK3))_5Cv~y2Bb2!Ibg9BO7Vkz?pAYX zoI=B}+$R22&IL`NCYUYjrdhwjnMx_v=-Qcx-jmtN>!Zqf|n1^SWrHy zK|MwJ?Z#^>)rfT5YSY{qjZ&`Fjd;^vv&gF-Yj6$9-Dy$<6zeP4s+78gS2|t%Z309b z0^fp~ue_}i`U9j!<|qF92_3oB09NqgAoehQ`)<)dSfKoJl_A6Ec#*Mx9Cpd-p#$Ez z={AM*r-bQs6*z$!*VA4|QE7bf@-4vb?Q+pPKLkY2{yKsw{&udv_2v8{Dbd zm~8VAv!G~s)`O3|Q6vFUV%8%+?ZSVUa(;fhPNg#vab@J*9XE4#D%)$UU-T5`fwjz! z6&gA^`OGu6aUk{l*h9eB?opVdrHK>Q@U>&JQ_2pR%}TyOXGq_6s56_`U(WoOaAb+K zXQr#6H}>a-GYs9^bGP2Y&hSP5gEtW+GVC4=wy0wQk=~%CSXj=GH6q z-T#s!BV`xZVxm{~jr_ezYRpqqIcXC=Oq`b{lu`Rt(IYr4B91hhVC?yg{ol4WUr3v9 zOAk2LG>CIECZ-WIs0$N}F#eoIUEtZudc7DPYIjzGqDLWk_A4#(LgacooD z2K4IWs@N`Bddm-{%oy}!k0^i6Yh)uJ1S*90>|bm3TOZxcV|ywHUb(+CeX-o1|LTZM zwU>dY3R&U)T(}5#Neh?-CWT~@{6Ke@sI)uSuzoah8COy)w)B)aslJmp`WUcjdia-0 zl2Y}&L~XfA`uYQboAJ1;J{XLhYjH){cObH3FDva+^8ioOQy%Z=xyjGLmWMrzfFoH; zEi3AG`_v+%)&lDJE;iJWJDI@-X9K5O)LD~j*PBe(wu+|%ar~C+LK1+-+lK=t# z+Xc+J7qp~5q=B~rD!x78)?1+KUIbYr^5rcl&tB-cTtj+e%{gpZZ4G~6r15+d|J(ky zjg@@UzMW0k9@S#W(1H{u;Nq(7llJbq;;4t$awM;l&(2s+$l!Ay9^Ge|34CVhr7|BG z?dAR83smef^frq9V(OH+a+ki#q&-7TkWfFM=5bsGbU(8mC;>QTCWL5ydz9s6k@?+V zcjiH`VI=59P-(-DWXZ~5DH>B^_H~;4$)KUhnmGo*G!Tq8^LjfUDO)lASN*=#AY_yS zqW9UX(VOCO&p@kHdUUgsBO0KhXxn1sprK5h8}+>IhX(nSXZKwlNsjk^M|RAaqmCZB zHBolOHYBas@&{PT=R+?d8pZu zUHfyucQ`(umXSW7o?HQ3H21M`ZJal+%*)SH1B1j6rxTlG3hx1IGJN^M7{$j(9V;MZ zRKybgVuxKo#XVM+?*yTy{W+XHaU5Jbt-UG33x{u(N-2wmw;zzPH&4DE103HV@ER86 z|FZEmQb|&1s5#`$4!Cm}&`^{(4V}OP$bk`}v6q6rm;P!H)W|2i^e{7lTk2W@jo_9q z*aw|U7#+g59Fv(5qI`#O-qPj#@_P>PC#I(GSp3DLv7x-dmYK=C7lPF8a)bxb=@)B1 zUZ`EqpXV2dR}B&r`uM}N(TS99ZT0UB%IN|0H%DcVO#T%L_chrgn#m6%x4KE*IMfjX zJ%4veCEqbXZ`H`F_+fELMC@wuy_ch%t*+Z+1I}wN#C+dRrf2X{1C8=yZ_%Pt6wL_~ zZ2NN-hXOT4P4n$QFO7yYHS-4wF1Xfr-meG9Pn;uK51?hfel`d38k{W)F*|gJLT2#T z<~>spMu4(mul-8Q3*pf=N4DcI)zzjqAgbE2eOT7~&f1W3VsdD44Ffe;3mJp-V@8UC z)|qnPc12o~$X-+U@L_lWqv-RtvB~%hLF($%Ew5w>^NR82qC_0FB z)=hP1-OEx?lLi#jnLzH}a;Nvr@JDO-zQWd}#k^an$Kwml;MrD&)sC5b`s0ZkVyPkb zt}-jOq^%_9>YZe7Y}PhW{a)c39G`kg(P4@kxjcYfgB4XOOcmezdUI7j-!gs7oAo2o zx(Ph{G+YZ`a%~kzK!HTAA5NXE-7vOFRr5oqY$rH>WI6SFvWmahFav!CfRMM3%8J&c z*p+%|-fNS_@QrFr(at!JY9jCg9F-%5{nb5Bo~z@Y9m&SHYV`49GAJjA5h~h4(G!Se zZmK{Bo7ivCfvl}@A-ptkFGcWXAzj3xfl{evi-OG(TaCn1FAHxRc{}B|x+Ua1D=I6M z!C^ZIvK6aS_c&(=OQDZfm>O`Nxsw{ta&yiYPA~@e#c%N>>#rq)k6Aru-qD4(D^v)y z*>Rs;YUbD1S8^D(ps6Jbj0K3wJw>L4m)0e(6Pee3Y?gy9i0^bZO?$*sv+xKV?WBlh zAp*;v6w!a8;A7sLB*g-^<$Z4L7|5jXxxP1}hQZ<55f9<^KJ>^mKlWSGaLcO0=$jem zWyZkRwe~u{{tU63DlCaS9$Y4CP4f?+wwa(&1ou)b>72ydrFvm`Rj-0`kBJgK@nd(*Eh!(NC{F-@=FnF&Y!q`7){YsLLHf0_B6aHc# z>WIuHTyJwIH{BJ4)2RtEauC7Yq7Cytc|S)4^*t8Va3HR zg=~sN^tp9re@w=GTx$;zOWMjcg-7X3Wk^N$n;&Kf1RgVG2}2L-(0o)54C509C&77i zrjSi{X*WV=%C17((N^6R4Ya*4#6s_L99RtQ>m(%#nQ#wrRC8Y%yxkH;d!MdY+Tw@r zjpSnK`;C-U{ATcgaxoEpP0Gf+tx);buOMlK=01D|J+ROu37qc*rD(w`#O=3*O*w9?biwNoq3WN1`&Wp8TvKj3C z3HR9ssH7a&Vr<6waJrU zdLg!ieYz%U^bmpn%;(V%%ugMk92&?_XX1K@mwnVSE6!&%P%Wdi7_h`CpScvspMx?N zQUR>oadnG17#hNc$pkTp+9lW+MBKHRZ~74XWUryd)4yd zj98$%XmIL4(9OnoeO5Fnyn&fpQ9b0h4e6EHHw*l68j;>(ya`g^S&y2{O8U>1*>4zR zq*WSI_2o$CHQ?x0!wl9bpx|Cm2+kFMR)oMud1%n2=qn5nE&t@Fgr#=Zv2?}wtEz^T z9rrj=?IH*qI5{G@Rn&}^Z{+TW}mQeb9=8b<_a`&Cm#n%n~ zU47MvCBsdXFB1+adOO)03+nczfWa#vwk#r{o{dF)QWya9v2nv43Zp3%Ps}($lA02*_g25t;|T{A5snSY?3A zrRQ~(Ygh_ebltHo1VCbJb*eOAr;4cnlXLvI>*$-#AVsGg6B1r7@;g^L zFlJ_th0vxO7;-opU@WAFe;<}?!2q?RBrFK5U{*ai@NLKZ^};Ul}beukveh?TQn;$%9=R+DX07m82gP$=}Uo_%&ngV`}Hyv8g{u z3SWzTGV|cwQuFIs7ZDOqO_fGf8Q`8MwL}eUp>q?4eqCmOTcwQuXtQckPy|4F1on8l zP*h>d+cH#XQf|+6c|S{7SF(Lg>bR~l(0uY?O{OEVlaxa5@e%T&xju=o1`=OD#qc16 zSvyH*my(dcp6~VqR;o(#@m44Lug@~_qw+HA=mS#Z^4reBy8iV?H~I;{LQWk3aKK8$bLRyt$g?- { + const notifier = require('node-notifier') + + return (severity, errors) => { + if (severity !== 'error') return + + const error = errors[0] + const filename = error.file && error.file.split('!').pop() + + notifier.notify({ + title: packageConfig.name, + message: severity + ': ' + error.name, + subtitle: filename || '', + icon: path.join(__dirname, 'logo.png') + }) + } +} diff --git a/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/build/vue-loader.conf.js b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/build/vue-loader.conf.js new file mode 100644 index 0000000000..33ed58bc0a --- /dev/null +++ b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/build/vue-loader.conf.js @@ -0,0 +1,22 @@ +'use strict' +const utils = require('./utils') +const config = require('../config') +const isProduction = process.env.NODE_ENV === 'production' +const sourceMapEnabled = isProduction + ? config.build.productionSourceMap + : config.dev.cssSourceMap + +module.exports = { + loaders: utils.cssLoaders({ + sourceMap: sourceMapEnabled, + extract: isProduction + }), + cssSourceMap: sourceMapEnabled, + cacheBusting: config.dev.cacheBusting, + transformToRequire: { + video: ['src', 'poster'], + source: 'src', + img: 'src', + image: 'xlink:href' + } +} diff --git a/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/build/webpack.async-plugins.js b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/build/webpack.async-plugins.js new file mode 100644 index 0000000000..71b6c82d3d --- /dev/null +++ b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/build/webpack.async-plugins.js @@ -0,0 +1,97 @@ +const webpack = require('webpack') +const path = require('path') +const utils = require('./utils') +const CopyPlugin = require("copy-webpack-plugin"); +const VueLoaderPlugin = require('vue-loader/lib/plugin'); +function resolve (dir) { + return path.join(__dirname, '..', dir) +} + +module.exports = { + mode: 'development', + entry: { + + // PluginDemo: resolve('/src/views/PluginDemo.vue') + 'race-bar-view': resolve('/src/views/antv/racebar/index.vue'), + 'race-bar-data': resolve('/src/views/antv/racebar/data.vue'), + 'race-bar-type': resolve('/src/views/antv/racebar/type.vue'), + 'race-bar-style': resolve('/src/views/antv/racebar/style.vue') + + }, + output: { + path: resolve('/static/'), + filename: '[name].js' + }, + resolve: { + extensions: ['.js', '.vue', '.json'], + alias: { + 'vue$': 'vue/dist/vue.esm.js', + '@': resolve('src') + } + }, + externals: { + vue: 'vue' + }, + module: { + rules: [ + { + test: /\.vue$/, + loader: 'vue-loader', + options: { + transformAssetUrls: { + video: 'src', + source: 'src', + img: 'src', + image: 'xlink:href' + } + } + }, + { + test: /.(sa|sc|c)ss$/, + use: [ + {loader: 'vue-style-loader'}, + 'css-loader', + 'sass-loader' + ] + }, + { + test: /\.js$/, + loader: 'babel-loader', + include: [resolve('src'), resolve('test')] + }, + { + test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: utils.assetsPath('img/[name].[hash:7].[ext]') + } + }, + { + test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: utils.assetsPath('media/[name].[hash:7].[ext]') + } + }, + { + test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: utils.assetsPath('fonts/[name].[hash:7].[ext]') + } + } + ] + }, + plugins: [ + new VueLoaderPlugin(), + new webpack.DefinePlugin({ + 'process.env.NODE_ENV': '"production"' + }), + new CopyPlugin([ + {from: 'src/icons/svg/'} + ]), + ] +} diff --git a/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/build/webpack.base.conf.js b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/build/webpack.base.conf.js new file mode 100644 index 0000000000..6ccc02dab4 --- /dev/null +++ b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/build/webpack.base.conf.js @@ -0,0 +1,91 @@ +'use strict' +const path = require('path') +const utils = require('./utils') +const config = require('../config') +const vueLoaderConfig = require('./vue-loader.conf') + +function resolve (dir) { + return path.join(__dirname, '..', dir) +} + + + +module.exports = { + context: path.resolve(__dirname, '../'), + entry: { + app: './src/main.js' + }, + output: { + path: config.build.assetsRoot, + filename: '[name].js', + publicPath: process.env.NODE_ENV === 'production' + ? config.build.assetsPublicPath + : config.dev.assetsPublicPath + }, + resolve: { + extensions: ['.js', '.vue', '.json'], + alias: { + 'vue$': 'vue/dist/vue.esm.js', + '@': resolve('src'), + } + }, + module: { + rules: [ + { + test: /\.vue$/, + loader: 'vue-loader', + options: vueLoaderConfig + }, + { + test: /\.js$/, + loader: 'babel-loader', + include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')] + }, + { + test: /\.svg$/, + loader: 'svg-sprite-loader', + include: [resolve('src/icons')], + options: { + symbolId: 'icon-[name]' + } + }, + { + test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, + loader: 'url-loader', + exclude: [resolve('src/icons')], + options: { + limit: 10000, + name: utils.assetsPath('img/[name].[hash:7].[ext]') + } + }, + { + test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: utils.assetsPath('media/[name].[hash:7].[ext]') + } + }, + { + test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: utils.assetsPath('fonts/[name].[hash:7].[ext]') + } + } + ] + }, + node: { + // prevent webpack from injecting useless setImmediate polyfill because Vue + // source contains it (although only uses it if it's native). + setImmediate: false, + // prevent webpack from injecting mocks to Node native modules + // that does not make sense for the client + dgram: 'empty', + fs: 'empty', + net: 'empty', + tls: 'empty', + child_process: 'empty' + } +} diff --git a/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/build/webpack.dev.conf.js b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/build/webpack.dev.conf.js new file mode 100755 index 0000000000..070ae221f3 --- /dev/null +++ b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/build/webpack.dev.conf.js @@ -0,0 +1,95 @@ +'use strict' +const utils = require('./utils') +const webpack = require('webpack') +const config = require('../config') +const merge = require('webpack-merge') +const path = require('path') +const baseWebpackConfig = require('./webpack.base.conf') +const CopyWebpackPlugin = require('copy-webpack-plugin') +const HtmlWebpackPlugin = require('html-webpack-plugin') +const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin') +const portfinder = require('portfinder') + +const HOST = process.env.HOST +const PORT = process.env.PORT && Number(process.env.PORT) + +const devWebpackConfig = merge(baseWebpackConfig, { + module: { + rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true }) + }, + // cheap-module-eval-source-map is faster for development + devtool: config.dev.devtool, + + // these devServer options should be customized in /config/index.js + devServer: { + clientLogLevel: 'warning', + historyApiFallback: { + rewrites: [ + { from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') }, + ], + }, + hot: true, + contentBase: false, // since we use CopyWebpackPlugin. + compress: true, + host: HOST || config.dev.host, + port: PORT || config.dev.port, + open: config.dev.autoOpenBrowser, + overlay: config.dev.errorOverlay + ? { warnings: false, errors: true } + : false, + publicPath: config.dev.assetsPublicPath, + proxy: config.dev.proxyTable, + quiet: true, // necessary for FriendlyErrorsPlugin + watchOptions: { + poll: config.dev.poll, + } + }, + plugins: [ + new webpack.DefinePlugin({ + 'process.env': require('../config/dev.env') + }), + new webpack.HotModuleReplacementPlugin(), + new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update. + new webpack.NoEmitOnErrorsPlugin(), + // https://github.com/ampedandwired/html-webpack-plugin + new HtmlWebpackPlugin({ + filename: 'index.html', + template: 'index.html', + inject: true + }), + // copy custom static assets + new CopyWebpackPlugin([ + { + from: path.resolve(__dirname, '../static'), + to: config.dev.assetsSubDirectory, + ignore: ['.*'] + } + ]) + ] +}) + +module.exports = new Promise((resolve, reject) => { + portfinder.basePort = process.env.PORT || config.dev.port + portfinder.getPort((err, port) => { + if (err) { + reject(err) + } else { + // publish the new Port, necessary for e2e tests + process.env.PORT = port + // add port to devServer config + devWebpackConfig.devServer.port = port + + // Add FriendlyErrorsPlugin + devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({ + compilationSuccessInfo: { + messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`], + }, + onErrors: config.dev.notifyOnErrors + ? utils.createNotifierCallback() + : undefined + })) + + resolve(devWebpackConfig) + } + }) +}) diff --git a/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/build/webpack.prod.conf.js b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/build/webpack.prod.conf.js new file mode 100644 index 0000000000..1f71ad6454 --- /dev/null +++ b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/build/webpack.prod.conf.js @@ -0,0 +1,147 @@ +'use strict' +const path = require('path') +const utils = require('./utils') +const webpack = require('webpack') +const config = require('../config') +const merge = require('webpack-merge') +const baseWebpackConfig = require('./webpack.base.conf') +const CopyWebpackPlugin = require('copy-webpack-plugin') +const HtmlWebpackPlugin = require('html-webpack-plugin') +const ExtractTextPlugin = require('extract-text-webpack-plugin') +const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin') +const UglifyJsPlugin = require('uglifyjs-webpack-plugin') +const VueLoaderPlugin = require('vue-loader/lib/plugin'); + +const env = require('../config/prod.env') + +const webpackConfig = merge(baseWebpackConfig, { + module: { + rules: utils.styleLoaders({ + sourceMap: config.build.productionSourceMap, + extract: true, + usePostCSS: true + }) + }, + devtool: config.build.productionSourceMap ? config.build.devtool : false, + output: { + path: config.build.assetsRoot, + filename: utils.assetsPath('js/[name].[chunkhash].js'), + chunkFilename: utils.assetsPath('js/[id].[chunkhash].js') + }, + plugins: [ + new VueLoaderPlugin(), + // http://vuejs.github.io/vue-loader/en/workflow/production.html + new webpack.DefinePlugin({ + 'process.env': env + }), + new UglifyJsPlugin({ + uglifyOptions: { + compress: { + warnings: false + } + }, + sourceMap: config.build.productionSourceMap, + parallel: true + }), + // extract css into its own file + new ExtractTextPlugin({ + filename: utils.assetsPath('css/[name].[contenthash].css'), + // Setting the following option to `false` will not extract CSS from codesplit chunks. + // Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack. + // It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`, + // increasing file size: https://github.com/vuejs-templates/webpack/issues/1110 + allChunks: true, + }), + // Compress extracted CSS. We are using this plugin so that possible + // duplicated CSS from different components can be deduped. + new OptimizeCSSPlugin({ + cssProcessorOptions: config.build.productionSourceMap + ? { safe: true, map: { inline: false } } + : { safe: true } + }), + // generate dist index.html with correct asset hash for caching. + // you can customize output by editing /index.html + // see https://github.com/ampedandwired/html-webpack-plugin + new HtmlWebpackPlugin({ + filename: config.build.index, + template: 'index.html', + inject: true, + minify: { + removeComments: true, + collapseWhitespace: true, + removeAttributeQuotes: true + // more options: + // https://github.com/kangax/html-minifier#options-quick-reference + }, + // necessary to consistently work with multiple chunks via CommonsChunkPlugin + chunksSortMode: 'dependency' + }), + // keep module.id stable when vendor modules does not change + new webpack.HashedModuleIdsPlugin(), + // enable scope hoisting + new webpack.optimize.ModuleConcatenationPlugin(), + // split vendor js into its own file + new webpack.optimize.CommonsChunkPlugin({ + name: 'vendor', + minChunks (module) { + // any required modules inside node_modules are extracted to vendor + return ( + module.resource && + /\.js$/.test(module.resource) && + module.resource.indexOf( + path.join(__dirname, '../node_modules') + ) === 0 + ) + } + }), + // extract webpack runtime and module manifest to its own file in order to + // prevent vendor hash from being updated whenever app bundle is updated + new webpack.optimize.CommonsChunkPlugin({ + name: 'manifest', + minChunks: Infinity + }), + // This instance extracts shared chunks from code split chunks and bundles them + // in a separate chunk, similar to the vendor chunk + // see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk + new webpack.optimize.CommonsChunkPlugin({ + name: 'app', + async: 'vendor-async', + children: true, + minChunks: 3 + }), + + // copy custom static assets + new CopyWebpackPlugin([ + { + from: path.resolve(__dirname, '../static'), + to: config.build.assetsSubDirectory, + ignore: ['.*'] + } + ]) + ] +}) + +if (config.build.productionGzip) { + const CompressionWebpackPlugin = require('compression-webpack-plugin') + + webpackConfig.plugins.push( + new CompressionWebpackPlugin({ + asset: '[path].gz[query]', + algorithm: 'gzip', + test: new RegExp( + '\\.(' + + config.build.productionGzipExtensions.join('|') + + ')$' + ), + threshold: 10240, + minRatio: 0.8 + }) + ) +} + +if (config.build.bundleAnalyzerReport) { + const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin + webpackConfig.plugins.push(new BundleAnalyzerPlugin()) +} + +module.exports = webpackConfig diff --git a/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/config/dev.env.js b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/config/dev.env.js new file mode 100644 index 0000000000..1e22973ae7 --- /dev/null +++ b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/config/dev.env.js @@ -0,0 +1,7 @@ +'use strict' +const merge = require('webpack-merge') +const prodEnv = require('./prod.env') + +module.exports = merge(prodEnv, { + NODE_ENV: '"development"' +}) diff --git a/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/config/index.js b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/config/index.js new file mode 100644 index 0000000000..c5eded7f81 --- /dev/null +++ b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/config/index.js @@ -0,0 +1,69 @@ +'use strict' +// Template version: 1.3.1 +// see http://vuejs-templates.github.io/webpack for documentation. + +const path = require('path') + +module.exports = { + dev: { + + // Paths + assetsSubDirectory: 'static', + assetsPublicPath: '/', + proxyTable: {}, + + // Various Dev Server settings + host: 'localhost', // can be overwritten by process.env.HOST + port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined + autoOpenBrowser: false, + errorOverlay: true, + notifyOnErrors: true, + poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions- + + + /** + * Source Maps + */ + + // https://webpack.js.org/configuration/devtool/#development + devtool: 'cheap-module-eval-source-map', + + // If you have problems debugging vue-files in devtools, + // set this to false - it *may* help + // https://vue-loader.vuejs.org/en/options.html#cachebusting + cacheBusting: true, + + cssSourceMap: true + }, + + build: { + // Template for index.html + index: path.resolve(__dirname, '../dist/index.html'), + + // Paths + assetsRoot: path.resolve(__dirname, '../dist'), + assetsSubDirectory: 'static', + assetsPublicPath: '/', + + /** + * Source Maps + */ + + productionSourceMap: true, + // https://webpack.js.org/configuration/devtool/#production + devtool: '#source-map', + + // Gzip off by default as many popular static hosts such as + // Surge or Netlify already gzip all static assets for you. + // Before setting to `true`, make sure to: + // npm install --save-dev compression-webpack-plugin + productionGzip: false, + productionGzipExtensions: ['js', 'css'], + + // Run the build command with an extra argument to + // View the bundle analyzer report after build finishes: + // `npm run build --report` + // Set to `true` or `false` to always turn it on or off + bundleAnalyzerReport: process.env.npm_config_report + } +} diff --git a/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/config/prod.env.js b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/config/prod.env.js new file mode 100644 index 0000000000..a6f997616e --- /dev/null +++ b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/config/prod.env.js @@ -0,0 +1,4 @@ +'use strict' +module.exports = { + NODE_ENV: '"production"' +} diff --git a/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/index.html b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/index.html new file mode 100644 index 0000000000..03ce3fdf27 --- /dev/null +++ b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/index.html @@ -0,0 +1,12 @@ + + + + + + deplugin-view-frontend + + +
+ + + diff --git a/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/package.json b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/package.json new file mode 100644 index 0000000000..01a456b08b --- /dev/null +++ b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/package.json @@ -0,0 +1,74 @@ +{ + "name": "deplugin-view-frontend", + "version": "1.0.0", + "description": "A Vue.js project", + "author": "", + "private": true, + "scripts": { + "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js", + "start": "npm run dev", + "build": "node build/build.js", + "buildPlugin": "node build/build-async-plugins.js" + }, + "dependencies": { + "@riophae/vue-treeselect": "0.4.0", + "lodash": "^4.17.21", + "vue": "2.6.10", + "vue-i18n": "7.3.2", + "vue-router": "^3.0.1", + "vue-uuid": "2.0.2", + "vuedraggable": "^2.24.3", + "vuex": "3.1.0" + }, + "devDependencies": { + "autoprefixer": "^7.1.2", + "babel-core": "^6.22.1", + "babel-helper-vue-jsx-merge-props": "^2.0.3", + "babel-loader": "^7.1.1", + "babel-plugin-syntax-jsx": "^6.18.0", + "babel-plugin-transform-runtime": "^6.22.0", + "babel-plugin-transform-vue-jsx": "^3.5.0", + "babel-preset-env": "^1.3.2", + "babel-preset-stage-2": "^6.22.0", + "chalk": "^2.0.1", + "copy-webpack-plugin": "^4.6.0", + "css-loader": "^0.28.0", + "element-ui": "2.15.7", + "extract-text-webpack-plugin": "^4.0.0-beta.0", + "file-loader": "^1.1.4", + "friendly-errors-webpack-plugin": "^1.6.1", + "html-webpack-plugin": "^3.2.0", + "js-cookie": "2.2.0", + "node-notifier": "^8.0.1", + "optimize-css-assets-webpack-plugin": "^3.2.0", + "ora": "^1.2.0", + "portfinder": "^1.0.13", + "postcss-import": "^11.0.0", + "postcss-loader": "^2.0.8", + "postcss-url": "^7.2.1", + "rimraf": "^2.6.0", + "sass": "^1.33.0", + "sass-loader": "^7.3.1", + "semver": "^5.3.0", + "shelljs": "^0.8.5", + "svg-sprite-loader": "4.1.3", + "uglifyjs-webpack-plugin": "^1.1.1", + "url-loader": "^0.5.8", + "vue-loader": "^15.6.4", + "vue-style-loader": "^4.1.2", + "vue-template-compiler": "2.6.10", + "webpack": "^4.8.1", + "webpack-bundle-analyzer": "^3.3.2", + "webpack-dev-server": "^3.1.11", + "webpack-merge": "^4.1.0" + }, + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + }, + "browserslist": [ + "> 1%", + "last 2 versions", + "not ie <= 8" + ] +} diff --git a/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/pom.xml b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/pom.xml new file mode 100644 index 0000000000..3bc0fa25ec --- /dev/null +++ b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/pom.xml @@ -0,0 +1,80 @@ + + + + + io.dataease + view-racebar + ${dataease.version} + + + 4.0.0 + view-racebar-frontend + + + UTF-8 + UTF-8 + 1.9.1 + + + + + + maven-clean-plugin + + + + static + + ** + + false + + + + + + + + com.github.eirslett + frontend-maven-plugin + ${frontend-maven-plugin.version} + + + install node and npm + + install-node-and-npm + + + + v16.20.2 + 7.6.3 + + + + + npm install + + npm + + + + install + + + + + npm run buildPlugin + + npm + + + run buildPlugin + + + + + + + diff --git a/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/App.vue b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/App.vue new file mode 100644 index 0000000000..8542e07722 --- /dev/null +++ b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/App.vue @@ -0,0 +1,23 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/assets/logo.png b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/assets/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..f3d2503fc2a44b5053b0837ebea6e87a2d339a43 GIT binary patch literal 6849 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 +
+

{{ msg }}

+

Essential Links

+ +

Ecosystem

+ +
+ + + + + + diff --git a/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/SvgIcon/index.vue b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/SvgIcon/index.vue new file mode 100644 index 0000000000..f81b67f667 --- /dev/null +++ b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/SvgIcon/index.vue @@ -0,0 +1,60 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/selector/BackgroundColorSelector.vue b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/selector/BackgroundColorSelector.vue new file mode 100644 index 0000000000..e1cbf5fe18 --- /dev/null +++ b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/selector/BackgroundColorSelector.vue @@ -0,0 +1,102 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/selector/ColorSelector.vue b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/selector/ColorSelector.vue new file mode 100644 index 0000000000..3a579e8889 --- /dev/null +++ b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/selector/ColorSelector.vue @@ -0,0 +1,306 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/selector/GraphicSetting.vue b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/selector/GraphicSetting.vue new file mode 100644 index 0000000000..a1e4f0e4fe --- /dev/null +++ b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/selector/GraphicSetting.vue @@ -0,0 +1,177 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/selector/LabelSelector.vue b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/selector/LabelSelector.vue new file mode 100644 index 0000000000..354d70f2eb --- /dev/null +++ b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/selector/LabelSelector.vue @@ -0,0 +1,220 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/selector/LegendSelector.vue b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/selector/LegendSelector.vue new file mode 100644 index 0000000000..5125412616 --- /dev/null +++ b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/selector/LegendSelector.vue @@ -0,0 +1,165 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/selector/MarginSelector.vue b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/selector/MarginSelector.vue new file mode 100644 index 0000000000..7eb26d6a70 --- /dev/null +++ b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/selector/MarginSelector.vue @@ -0,0 +1,280 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/selector/SizeSelectorAntV.vue b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/selector/SizeSelectorAntV.vue new file mode 100644 index 0000000000..4cacee920a --- /dev/null +++ b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/selector/SizeSelectorAntV.vue @@ -0,0 +1,130 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/selector/SliderSetting.vue b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/selector/SliderSetting.vue new file mode 100644 index 0000000000..147bd6f3dd --- /dev/null +++ b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/selector/SliderSetting.vue @@ -0,0 +1,159 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/selector/TitleSelector.vue b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/selector/TitleSelector.vue new file mode 100644 index 0000000000..c77337e92a --- /dev/null +++ b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/selector/TitleSelector.vue @@ -0,0 +1,319 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/selector/TooltipSelector.vue b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/selector/TooltipSelector.vue new file mode 100644 index 0000000000..bba74bfd46 --- /dev/null +++ b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/selector/TooltipSelector.vue @@ -0,0 +1,152 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/selector/XAxisSelector.vue b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/selector/XAxisSelector.vue new file mode 100644 index 0000000000..c21be86386 --- /dev/null +++ b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/selector/XAxisSelector.vue @@ -0,0 +1,493 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/selector/YAxisSelector.vue b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/selector/YAxisSelector.vue new file mode 100644 index 0000000000..e7b29e2b54 --- /dev/null +++ b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/selector/YAxisSelector.vue @@ -0,0 +1,493 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/views/ChartDragItem.vue b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/views/ChartDragItem.vue new file mode 100644 index 0000000000..53ae1e2ad0 --- /dev/null +++ b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/views/ChartDragItem.vue @@ -0,0 +1,278 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/views/ChartTitleUpdate.vue b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/views/ChartTitleUpdate.vue new file mode 100644 index 0000000000..ed97a67067 --- /dev/null +++ b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/views/ChartTitleUpdate.vue @@ -0,0 +1,480 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/views/DimensionExtItem.vue b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/views/DimensionExtItem.vue new file mode 100644 index 0000000000..a62c724092 --- /dev/null +++ b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/views/DimensionExtItem.vue @@ -0,0 +1,371 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/views/DimensionItem.vue b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/views/DimensionItem.vue new file mode 100644 index 0000000000..d4c34cdbd6 --- /dev/null +++ b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/views/DimensionItem.vue @@ -0,0 +1,415 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/views/DrillItem.vue b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/views/DrillItem.vue new file mode 100644 index 0000000000..7321b8a08c --- /dev/null +++ b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/views/DrillItem.vue @@ -0,0 +1,146 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/views/FieldErrorTips.vue b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/views/FieldErrorTips.vue new file mode 100644 index 0000000000..9d7b574721 --- /dev/null +++ b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/views/FieldErrorTips.vue @@ -0,0 +1,21 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/views/FilterItem.vue b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/views/FilterItem.vue new file mode 100644 index 0000000000..3dd5952d69 --- /dev/null +++ b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/views/FilterItem.vue @@ -0,0 +1,154 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/views/LocationLineItem.vue b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/views/LocationLineItem.vue new file mode 100644 index 0000000000..7b2985d08f --- /dev/null +++ b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/views/LocationLineItem.vue @@ -0,0 +1,170 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/views/QuotaExtItem.vue b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/views/QuotaExtItem.vue new file mode 100644 index 0000000000..79b2ff1867 --- /dev/null +++ b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/views/QuotaExtItem.vue @@ -0,0 +1,410 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/views/QuotaItem.vue b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/views/QuotaItem.vue new file mode 100644 index 0000000000..84f4ca7bc9 --- /dev/null +++ b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/views/QuotaItem.vue @@ -0,0 +1,395 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/views/ViewTrackBar.vue b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/views/ViewTrackBar.vue new file mode 100644 index 0000000000..a58cad9770 --- /dev/null +++ b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/views/ViewTrackBar.vue @@ -0,0 +1,80 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/views/utils.js b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/views/utils.js new file mode 100644 index 0000000000..307c4f637e --- /dev/null +++ b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/components/views/utils.js @@ -0,0 +1,99 @@ +export function getItemType(dimensionData, quotaData, item) { + // Check whether the current view is in template status + // ( dimensionData and quotaData have no data). If yes, return 'success' directly + if (dimensionData.length === 0 && quotaData.length === 0) { + return 'success' + } + // 将item的字段在数据集维度、指标字段中查询一遍,如果遇到id不存在、字段类型不一致、维度指标不一致,则提示 + const status = item.groupType + let checked = false + if (status === 'd') { + for (let i = 0; i < dimensionData.length; i++) { + const ele = dimensionData[i] + if (item.chartId) { + if (ele.dataeaseName === item.dataeaseName && ele.deType === item.deType && ele.groupType === item.groupType) { + checked = true + break + } + } else { + if (ele.id === item.id && ele.deType === item.deType && ele.groupType === item.groupType) { + checked = true + break + } + } + } + } + if (status === 'q') { + for (let i = 0; i < quotaData.length; i++) { + const ele = quotaData[i] + if (item.chartId) { + if (ele.dataeaseName === item.dataeaseName && ele.deType === item.deType && ele.groupType === item.groupType) { + checked = true + break + } + } else { + if (ele.id === item.id && ele.deType === item.deType && ele.groupType === item.groupType) { + checked = true + break + } + } + } + } + + if (checked) { + if (status === 'd') { + return '' + } else if (status === 'q') { + return 'success' + } + } else { + return 'danger' + } +} + +export function getRemark(chart) { + const remark = {} + if (chart.customStyle) { + const customStyle = JSON.parse(chart.customStyle) + if (customStyle.text) { + const title = JSON.parse(JSON.stringify(customStyle.text)) + remark.show = title.remarkShow ? title.remarkShow : false + remark.content = title.remark ? title.remark : '' + remark.bgFill = title.remarkBackgroundColor ? title.remarkBackgroundColor : '#ffffffff' + } + } + return remark +} + +export function getOriginFieldName(dimensionList, quotaList, field) { + let originName = '' + for (let i = 0; i < dimensionList.length; i++) { + const item = dimensionList[i] + if (item.id === field.id) { + originName = item.name + break + } + } + for (let i = 0; i < quotaList.length; i++) { + const item = quotaList[i] + if (item.id === field.id) { + originName = item.name + break + } + } + return originName +} + +export function resetValueFormatter(item) { + if (item) { + item.formatterCfg = { + type: 'auto', // auto,value,percent + unit: 1, // 换算单位 + suffix: '', // 单位后缀 + decimalCount: 2, // 小数位数 + thousandSeparator: true// 千分符 + } + } +} + +export const quotaViews = ['label', 'richTextView', 'text', 'gauge', 'liquid'] diff --git a/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/de-base/lang/en.js b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/de-base/lang/en.js new file mode 100644 index 0000000000..40dc579ea8 --- /dev/null +++ b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/de-base/lang/en.js @@ -0,0 +1,29 @@ +export default { + plugin_view_racebar: { + source: 'XAxis', + sourceExt: 'Group', + target: 'YAxis', + map_type: 'Map Type', + link_line: 'Link Line', + mark_size: 'YAxis', + type_title: 'RaceBar', + label: 'Area', + angle: 'Symbol', + marker: 'Marker', + pentagon: 'Pentagon', + hexagon: 'Hexagon', + octagon: 'Octagon', + hexagram: 'Hexagram', + border: 'Border', + light: 'Light', + dark: 'Dark', + label_format_tip: 'The field value can be read in the form of {field Name}, the fields in the label and the tips are interchangeable, and the built-in latitude and longitude related fields', + tooltip_format_tip: 'The field value can be read in the form of {field Name}, the fields in the label and the tips are interchangeable, and the built-in latitude and longitude related fields.(the label does not support line breaks)', + graphic: 'Group Setting', + slider: 'RaceBar Setting', + slider_auto: 'Auto', + slider_repeat: 'Repeat', + slider_timeout: 'Timeout', + slider_max: 'Max Number', + } +} diff --git a/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/de-base/lang/index.js b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/de-base/lang/index.js new file mode 100644 index 0000000000..e50d0478e6 --- /dev/null +++ b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/de-base/lang/index.js @@ -0,0 +1,49 @@ +import Vue from 'vue' +import VueI18n from 'vue-i18n' +import Cookies from 'js-cookie' +import elementEnLocale from 'element-ui/lib/locale/lang/en' // element-ui lang +import elementZhLocale from 'element-ui/lib/locale/lang/zh-CN'// element-ui lang +import elementTWLocale from 'element-ui/lib/locale/lang/zh-TW'// element-ui lang + +import localMessages from './messages' + + +Vue.use(VueI18n) + +const messages = { + en_US: { + ...localMessages['en_US'], + ...elementEnLocale + }, + zh_CN: { + ...localMessages['zh_CN'], + ...elementZhLocale + }, + zh_TW: { + ...localMessages['zh_TW'], + ...elementTWLocale + } +} +export function getLanguage () { + const chooseLanguage = Cookies.get('language') + if (chooseLanguage) return chooseLanguage + + // if has not choose language + const language = (navigator.language || navigator.browserLanguage).toLowerCase() + const locales = Object.keys(messages) + for (const locale of locales) { + if (language.indexOf(locale) > -1) { + return locale + } + } + return 'zh_CN' +} +const i18n = new VueI18n({ + // set locale + // options: en | zh | es + locale: getLanguage(), + // set locale messages + messages +}) + +export default i18n diff --git a/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/de-base/lang/messages.js b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/de-base/lang/messages.js new file mode 100644 index 0000000000..844f8c0673 --- /dev/null +++ b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/de-base/lang/messages.js @@ -0,0 +1,17 @@ +import enLocale from './en' +import zhLocale from './zh' +import twLocale from './tw' + +const messages = { + en_US: { + ...enLocale + }, + zh_CN: { + ...zhLocale + }, + zh_TW: { + ...twLocale + } +} + +export default messages \ No newline at end of file diff --git a/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/de-base/lang/tw.js b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/de-base/lang/tw.js new file mode 100644 index 0000000000..72ad095c3b --- /dev/null +++ b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/de-base/lang/tw.js @@ -0,0 +1,30 @@ +export default { + plugin_view_racebar: { + type_title: '動態排序圖', + source: '主軸', + sourceExt: '分組', + target: '值', + map_type: '類型', + link_line: '連線', + mark_size: '值', + label: '區域', + angle: '符號', + marker: '標記', + pentagon: '五邊形', + hexagon: '六邊形', + + octagon: '八邊形', + hexagram: '六角星', + border: '邊框', + light: '亮色', + dark: '暗色', + label_format_tip: '可以${fieldName}的形式讀取字段值,標籤和提示中的字段互相通用,內置經緯度相關字段', + tooltip_format_tip: '可以${fieldName}的形式讀取字段值,標籤和提示中的字段互相通用,內置經緯度相關字段(標籤不支持換行)', + graphic: '動態分組', + slider: '動態排序配置', + slider_auto: '自動', + slider_repeat: '重復', + slider_timeout: '間隔', + slider_max: '顯示個數', + } +} diff --git a/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/de-base/lang/zh.js b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/de-base/lang/zh.js new file mode 100644 index 0000000000..f69931bb1a --- /dev/null +++ b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/de-base/lang/zh.js @@ -0,0 +1,28 @@ +export default { + plugin_view_racebar: { + type_title: '动态排序图', + source: '主轴', + sourceExt: '分组', + target: '值', + map_type: '类型', + link_line: '连线', + mark_size: '值', + angle: '符号', + marker: '标记', + pentagon: '五角形', + hexagon: '六角形', + octagon: '八角形', + hexagram: '六角星', + border: '边框', + light: '亮色', + dark: '暗色', + label_format_tip: '可以${fieldName}的形式读取字段值,标签和提示中的字段互相通用,内置经纬度相关字段', + tooltip_format_tip: '可以${fieldName}的形式读取字段值,标签和提示中的字段互相通用,内置经纬度相关字段(标签不支持换行)', + graphic: '动态分组', + slider: '动态排序配置', + slider_auto: '自动', + slider_repeat: '重复', + slider_timeout: '间隔', + slider_max: '显示个数', + } +} diff --git a/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/icons/index.js b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/icons/index.js new file mode 100644 index 0000000000..2c6b309c96 --- /dev/null +++ b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/icons/index.js @@ -0,0 +1,9 @@ +import Vue from 'vue' +import SvgIcon from '@/components/SvgIcon'// svg component + +// register globally +Vue.component('svg-icon', SvgIcon) + +const req = require.context('./svg', false, /\.svg$/) +const requireAll = requireContext => requireContext.keys().map(requireContext) +requireAll(req) diff --git a/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/icons/svg/race-bar.svg b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/icons/svg/race-bar.svg new file mode 100644 index 0000000000..392d871658 --- /dev/null +++ b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/icons/svg/race-bar.svg @@ -0,0 +1 @@ + diff --git a/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/icons/svg/view-race-bar-backend.svg b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/icons/svg/view-race-bar-backend.svg new file mode 100644 index 0000000000..becfdb6caf --- /dev/null +++ b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/icons/svg/view-race-bar-backend.svg @@ -0,0 +1 @@ +【icon】插件管理-导出 \ No newline at end of file diff --git a/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/icons/svgo.yml b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/icons/svgo.yml new file mode 100644 index 0000000000..e69de29bb2 diff --git a/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/main.js b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/main.js new file mode 100644 index 0000000000..b1d6ebdf5f --- /dev/null +++ b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/main.js @@ -0,0 +1,36 @@ +// The Vue build version to load with the `import` command +// (runtime-only or standalone) has been set in webpack.base.conf with an alias. +import Vue from 'vue' +import App from './App' +import router from './router' +import ElementUI from 'element-ui' +import Cookies from 'js-cookie' +import i18n from './de-base/lang' +import draggable from 'vuedraggable' +import Treeselect from '@riophae/vue-treeselect' +import '@riophae/vue-treeselect/dist/vue-treeselect.css' +import '@/icons' // icon +import { GaodeMap } from '@antv/l7-maps' +Vue.config.productionTip = false +Vue.use(ElementUI, { + size: Cookies.get('size') || 'medium', + i18n: (key, value) => i18n.t(key, value) +}) +Vue.component('Treeselect', Treeselect) +Vue.component('draggable', draggable) +Vue.prototype.hasDataPermission = function(pTarget, pSource) { + + if (pSource && pTarget) { + return pSource.indexOf(pTarget) > -1 + } + return false +} +Vue.prototype.$gaodeMap = GaodeMap +/* eslint-disable no-new */ +new Vue({ + el: '#app', + router, + i18n, + components: { App }, + template: '' +}) diff --git a/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/router/index.js b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/router/index.js new file mode 100644 index 0000000000..58f8665bbc --- /dev/null +++ b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/router/index.js @@ -0,0 +1,21 @@ +import Vue from 'vue' +import Router from 'vue-router' +import HelloWorld from '@/components/HelloWorld' +import SymbolMap from '@/views/antv/racebar/type' + +Vue.use(Router) + +export default new Router({ + routes: [ + { + path: '/', + name: 'HelloWorld', + component: HelloWorld + }, + { + path: '/race-bar', + name: 'race-bar', + component: SymbolMap + } + ] +}) diff --git a/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/utils/clickoutside.js b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/utils/clickoutside.js new file mode 100644 index 0000000000..fb030a98eb --- /dev/null +++ b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/utils/clickoutside.js @@ -0,0 +1,68 @@ +const nodeList = []; +const ctx = '@@clickoutsideContext'; + +let startClick; +let seed = 0; + + +function createDocumentHandler(el, binding, vnode) { + return function(mouseup = {}, mousedown = {}) { + if (!vnode || + !vnode.context || + !mouseup.target || + !mousedown.target || + el.contains(mouseup.target) || + el.contains(mousedown.target) || + el === mouseup.target || + (vnode.context.popperElm && + (vnode.context.popperElm.contains(mouseup.target) || + vnode.context.popperElm.contains(mousedown.target)))) return; + + if (binding.expression && + el[ctx].methodName && + vnode.context[el[ctx].methodName]) { + vnode.context[el[ctx].methodName](); + } else { + el[ctx].bindingFn && el[ctx].bindingFn(); + } + }; +} + +/** + * v-clickoutside + * @desc 点击元素外面才会触发的事件 + * @example + * ```vue + *
+ * ``` + */ +export default { + bind(el, binding, vnode) { + nodeList.push(el); + const id = seed++; + el[ctx] = { + id, + documentHandler: createDocumentHandler(el, binding, vnode), + methodName: binding.expression, + bindingFn: binding.value + }; + }, + + update(el, binding, vnode) { + el[ctx].documentHandler = createDocumentHandler(el, binding, vnode); + el[ctx].methodName = binding.expression; + el[ctx].bindingFn = binding.value; + }, + + unbind(el) { + let len = nodeList.length; + + for (let i = 0; i < len; i++) { + if (nodeList[i][ctx].id === el[ctx].id) { + nodeList.splice(i, 1); + break; + } + } + delete el[ctx]; + } +}; diff --git a/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/utils/compare.js b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/utils/compare.js new file mode 100644 index 0000000000..b06a104a10 --- /dev/null +++ b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/utils/compare.js @@ -0,0 +1,29 @@ +export const compareItem = { + type: 'none', // year-yoy/month-yoy等 + resultData: 'percent', // 对比差sub,百分比percent等 + field: '', + custom: { + field: '', + calcType: '0', // 0-增长值,1-增长率 + timeType: '0', // 0-固定日期,1-日期区间 + currentTime: '', + compareTime: '', + currentTimeRange: [], + compareTimeRange: [] + } +} + +export const compareYearList = [ + { name: 'year_mom', value: 'year_mom' } +] + +export const compareMonthList = [ + { name: 'month_mom', value: 'month_mom' }, + { name: 'year_yoy', value: 'year_yoy' } +] + +export const compareDayList = [ + { name: 'day_mom', value: 'day_mom' }, + { name: 'month_yoy', value: 'month_yoy' }, + { name: 'year_yoy', value: 'year_yoy' } +] diff --git a/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/utils/formatter.js b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/utils/formatter.js new file mode 100644 index 0000000000..dfe5bc792b --- /dev/null +++ b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/utils/formatter.js @@ -0,0 +1,77 @@ +export const formatterItem = { + type: 'auto', // auto,value,percent + unit: 1, // 换算单位 + suffix: '', // 单位后缀 + decimalCount: 2, // 小数位数 + thousandSeparator: true// 千分符 +} + +// 单位list +export const unitList = [ + { name: 'unit_none', value: 1 }, + { name: 'unit_thousand', value: 1000 }, + { name: 'unit_ten_thousand', value: 10000 }, + { name: 'unit_million', value: 1000000 }, + { name: 'unit_hundred_million', value: 100000000 } +] + +// 格式化方式 +export const formatterType = [ + { name: 'value_formatter_auto', value: 'auto' }, + { name: 'value_formatter_value', value: 'value' }, + { name: 'value_formatter_percent', value: 'percent' } +] + +export function valueFormatter(value, formatter) { + if (value === null || value === undefined) { + return null + } + if(formatter == undefined){ + return value; + } + // 1.unit 2.decimal 3.thousand separator and suffix + let result + if (formatter.type === 'auto') { + result = transSeparatorAndSuffix(transUnit(value, formatter), formatter) + } else if (formatter.type === 'value') { + result = transSeparatorAndSuffix(transDecimal(transUnit(value, formatter), formatter), formatter) + } else if (formatter.type === 'percent') { + value = value * 100 + result = transSeparatorAndSuffix(transDecimal(value, formatter), formatter) + } else { + result = value + } + return result +} + +function transUnit(value, formatter) { + return value / formatter.unit +} + +function transDecimal(value, formatter) { + return value.toFixed(formatter.decimalCount) +} + +function transSeparatorAndSuffix(value, formatter) { + let str = value + '' + if (formatter.thousandSeparator) { + const thousandsReg = /(\d)(?=(\d{3})+$)/g + const numArr = str.split('.') + numArr[0] = numArr[0].replace(thousandsReg, '$1,') + str = numArr.join('.') + } + if (formatter.type === 'percent') { + str += '%' + } else { + if (formatter.unit === 1000) { + str += '千' + } else if (formatter.unit === 10000) { + str += '万' + } else if (formatter.unit === 1000000) { + str += '百万' + } else if (formatter.unit === 100000000) { + str += '亿' + } + } + return str + formatter.suffix.replace(/(^\s*)|(\s*$)/g, '') +} diff --git a/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/utils/map.js b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/utils/map.js new file mode 100644 index 0000000000..caa4c17e11 --- /dev/null +++ b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/utils/map.js @@ -0,0 +1,849 @@ +import {valueFormatter} from "./formatter"; + +export const DEFAULT_COLOR_CASE = { + value: 'default', + colors: ['#5470c6', '#91cc75', '#fac858', '#ee6666', '#73c0de', '#3ba272', '#fc8452', '#9a60b4', '#ea7ccc'], + alpha: 100, + tableHeaderBgColor: '#e1eaff', + tableItemBgColor: '#ffffff', + tableFontColor: '#000000', + tableStripe: true, + dimensionColor: '#000000', + quotaColor: '#000000', + tableBorderColor: '#cfdaf4' +} +export const DEFAULT_SIZE = { + barDefault: true, + barWidth: 40, + barGap: 0.4, + lineWidth: 2, + lineType: 'solid', + lineSymbol: 'marker', + lineSymbolSize: 4, + lineSmooth: true, + lineArea: false, + pieInnerRadius: 0, + pieOuterRadius: 80, + pieRoseType: 'radius', + pieRoseRadius: 5, + funnelWidth: 80, + radarShape: 'polygon', + radarSize: 80, + tableTitleFontSize: 12, + tableItemFontSize: 12, + tableTitleHeight: 36, + tableItemHeight: 36, + tablePageSize: '20', + tableColumnMode: 'custom', + tableColumnWidth: 100, + tableHeaderAlign: 'left', + tableItemAlign: 'right', + gaugeMin: 0, + gaugeMax: 100, + gaugeStartAngle: 225, + gaugeEndAngle: -45, + dimensionFontSize: 18, + quotaFontSize: 18, + spaceSplit: 10, + dimensionShow: true, + quotaShow: true, + scatterSymbol: 'marker', + scatterSymbolSize: 15, + symbolOpacity: 5, + symbolStrokeWidth: 1, + treemapWidth: 80, + treemapHeight: 80, + liquidMax: 100, + liquidSize: 80, + liquidOutlineBorder: 4, + liquidOutlineDistance: 8, + liquidWaveLength: 128, + liquidWaveCount: 3, + liquidShape: 'circle', + tablePageMode: 'page' +} +export const COLOR_PANEL = [ + '#ff4500', + '#ff8c00', + '#ffd700', + '#90ee90', + '#00ced1', + '#1e90ff', + '#c71585', + '#999999', + '#000000', + '#FFFFFF' +] + +export const DEFAULT_SLIDER = { + show: false, + auto: true, + repeat: true, + timeout: 2, + fontSize: '10', + color: '#000000', + max: 10, +} +export const DEFAULT_Graphic = { + show: true, + fontSize: '60', + color: '#000000', + alpha: 25, + bottom: 90, + right: 60, +} + +export const DEFAULT_LABEL = { + show: true, + position: 'middle', + color: '#000000', + fontSize: '10', + labelLine: { + show: true + }, + fields: null, + initialized: true +} +export const DEFAULT_TOOLTIP = { + show: true, + trigger: 'item', + confine: true, + textStyle: { + fontSize: '10', + color: '#909399' + }, + backgroundColor: '#ffffff', + formatter: '', +} + +export const BASE_ECHARTS_SELECT = { + itemStyle: { + shadowBlur: 2 + } +} + +export const CHART_FONT_FAMILY = [ + {name: '微软雅黑', value: 'Microsoft YaHei'}, + {name: '宋体', value: 'SimSun'}, + {name: '黑体', value: 'SimHei'}, + {name: '楷体', value: 'KaiTi'} +] + +export const CHART_FONT_LETTER_SPACE = [ + {name: '0px', value: '0'}, + {name: '1px', value: '1'}, + {name: '2px', value: '2'}, + {name: '3px', value: '3'}, + {name: '4px', value: '4'}, + {name: '5px', value: '5'}, + {name: '6px', value: '6'}, + {name: '7px', value: '7'}, + {name: '8px', value: '8'}, + {name: '9px', value: '9'}, + {name: '10px', value: '10'} +] + +export const DEFAULT_TITLE_STYLE = { + show: true, + fontSize: '18', + color: '#000000', + hPosition: 'left', + vPosition: 'top', + isItalic: false, + isBolder: true, + remarkShow: false, + remark: '', + remarkBackgroundColor: '#ffffffff', + fontFamily: 'Microsoft YaHei', + letterSpace: '0', + fontShadow: false +} +export const DEFAULT_LEGEND_STYLE = { + show: true, + hPosition: 'center', + vPosition: 'bottom', + orient: 'horizontal', + icon: 'circle', + textStyle: { + color: '#333333', + fontSize: '12' + } +} +export const DEFAULT_BACKGROUND_COLOR = { + color: '#ffffff', + alpha: 100, + borderRadius: 5 +} +export const DEFAULT_BASE_MAP_STYLE = { + baseMapTheme: 'light' +} +export const BASE_MAP = { + title: { + text: '', + textStyle: { + fontWeight: 'normal' + } + }, + visualMap: { + min: 50, + max: 52, + text: ['High', 'Low'], + realtime: false, + calculable: true, + inRange: { + color: ['lightskyblue', 'yellow', 'orangered'] + }, + right: 0 + }, + + tooltip: {}, + geo: [ + { + show: true, + map: 'BUDDLE_MAP_BORDER', + + emphasis: { + disabled: true + }, + itemStyle: { + borderWidth: 2, + borderColor: '#d1d1d1', + borderType: 'solid' + }, + + roam: false + }, + { + show: true, + map: 'BUDDLE_MAP', + label: { + normal: { + show: false + }, + emphasis: { + show: false + } + }, + itemStyle: { + areaColor: '#f3f3f3', + borderType: 'dashed', + borderColor: '#fff' + }, + + roam: false + } + ], + series: [ + { + name: '', + type: 'scatter', + coordinateSystem: 'geo', + data: [] + } + ] +} + +export const compareItem = { + type: 'none', // year-yoy/month-yoy等 + resultData: 'percent', // 对比差sub,百分比percent等 + field: '', + custom: { + field: '', + calcType: '0', // 0-增长值,1-增长率 + timeType: '0', // 0-固定日期,1-日期区间 + currentTime: '', + compareTime: '', + currentTimeRange: [], + compareTimeRange: [] + } +} + +export const formatterItem = { + type: 'auto', // auto,value,percent + unit: 1, // 换算单位 + suffix: '', // 单位后缀 + decimalCount: 2, // 小数位数 + thousandSeparator: true// 千分符 +} + +export const DEFAULT_XAXIS_STYLE = { + show: true, + position: 'bottom', + name: '', + nameTextStyle: { + color: '#333333', + fontSize: 12 + }, + axisLabel: { + show: true, + color: '#333333', + fontSize: '12', + rotate: 0, + formatter: '{value}' + }, + axisLine: { + show: true, + lineStyle: { + color: '#cccccc', + width: 1, + style: 'solid' + } + }, + splitLine: { + show: false, + lineStyle: { + color: '#cccccc', + width: 1, + style: 'solid' + } + }, + axisValue: { + auto: true, + min: null, + max: null, + split: null, + splitCount: null + }, + axisLabelFormatter: { + type: 'auto', // auto,value,percent + unit: 1, // 换算单位 + suffix: '', // 单位后缀 + decimalCount: 2, // 小数位数 + thousandSeparator: true// 千分符 + } +} + +export const DEFAULT_YAXIS_STYLE = { + show: true, + position: 'left', + name: '', + nameTextStyle: { + color: '#333333', + fontSize: 12 + }, + axisLabel: { + show: true, + color: '#333333', + fontSize: '12', + rotate: 0, + formatter: '{value}' + }, + axisLine: { + show: false, + lineStyle: { + color: '#cccccc', + width: 1, + style: 'solid' + } + }, + splitLine: { + show: true, + lineStyle: { + color: '#cccccc', + width: 1, + style: 'solid' + } + }, + axisValue: { + auto: true, + min: null, + max: null, + split: null, + splitCount: null + }, + axisLabelFormatter: { + type: 'auto', // auto,value,percent + unit: 1, // 换算单位 + suffix: '', // 单位后缀 + decimalCount: 2, // 小数位数 + thousandSeparator: true// 千分符 + } +} + +export const DEFAULT_MARGIN_STYLE = { + marginModel: 'auto', + marginTop: 40, + marginBottom: 44, + marginLeft: 15, + marginRight: 10 +} + +export const HORIZONTAL_BAR = { + title: { + text: '', + textStyle: { + fontWeight: 'normal' + } + }, + grid: { + // top: 40, + // bottom: 44, + // left: 15, + // right: 40, + //containLabel: true + }, + tooltip: {}, + legend: { + show: true, + type: 'scroll', + itemWidth: 10, + itemHeight: 10, + icon: 'rect', + data: [] + }, + xAxis: { + max: 'dataMax', + axisLabel: { + formatter: function (n) { + return Math.round(n) + ''; + } + } + }, + yAxis: { + type: 'category', + inverse: true, + max: 10, + animationDuration: 300, + animationDurationUpdate: 300 + }, + dataset: { + source: [] + }, + series: [ + { + realtimeSort: true, + seriesLayoutBy: 'column', + type: 'bar', + } + ], + // Disable init animation. + animationDuration: 0, + animationDurationUpdate: 2000, + animationEasing: 'linear', + animationEasingUpdate: 'linear', + graphic: { + elements: [ + { + type: 'text', + right: 60, + bottom: 60, + style: { + font: 'bolder 50px monospace', + fill: 'rgba(100, 100, 100, 0.25)' + }, + z: 100 + } + ] + }, + dataZoom: [ + { + type: 'slider', + show: false, + xAxisIndex: [0], + start: 0, + end: 100 + }, + { + type: 'slider', + show: false, + yAxisIndex: [0], + left: '93%', + start: 0, + end: 100 + }, + { + type: 'inside', + disabled: true, + xAxisIndex: [0], + start: 0, + end: 100 + }, + { + type: 'inside', + disabled: true, + yAxisIndex: [0], + start: 0, + end: 100 + } + ] +} + +export function transAxisPosition(chart, axis) { + if (chart.type.includes('horizontal')) { + switch (axis.position) { + case 'top': + return 'left' + case 'bottom': + return 'right' + case 'left': + return 'bottom' + case 'right': + return 'top' + default: + return axis.position + } + } else { + return axis.position + } +} + +const convertData = (mapData, chart) => { + let maxVal = 0 + const k = terminalType === 'pc' ? 30 : 15 + const names = chart.data.x + const results = [] + for (let index = 0; index < names.length; index++) { + const name = names[index]; + const item = chart.data.series[0].data[index] + results.push({ + name, + value: (mapData[name] ? mapData[name].concat(item.value) : []), + dimensionList: item.dimensionList, + quotaList: item.quotaList + }) + maxVal = Math.max(maxVal, item.value) + } + const rate = k / maxVal + + return { + value: results, + rate: rate + } +} + +let terminalType = 'pc' + + +export function componentStyle(chart_option, chart) { + let xAxisLabelFormatter = null + let yAxisLabelFormatter = null + let yExtAxisLabelFormatter = null + const xFormatter = function (value) { + if (!xAxisLabelFormatter) { + return valueFormatter(value, formatterItem) + } else { + return valueFormatter(value, xAxisLabelFormatter) + } + } + + const yFormatter = function (value) { + if (!yAxisLabelFormatter) { + return valueFormatter(value, formatterItem) + } else { + return valueFormatter(value, yAxisLabelFormatter) + } + } + + const yExtFormatter = function (value) { + if (!yExtAxisLabelFormatter) { + return valueFormatter(value, formatterItem) + } else { + return valueFormatter(value, yExtAxisLabelFormatter) + } + } + + const padding = '8px' + if (chart.customStyle) { + const customStyle = JSON.parse(chart.customStyle) + if (customStyle.text) { + chart_option.title.show = customStyle.text.show + // 水平方向 + if (customStyle.text.hPosition === 'left') { + chart_option.title.left = padding + } else if (customStyle.text.hPosition === 'right') { + chart_option.title.right = padding + } else { + chart_option.title.left = customStyle.text.hPosition + } + // 垂直方向 + if (customStyle.text.vPosition === 'top') { + chart_option.title.top = padding + } else if (customStyle.text.vPosition === 'bottom') { + chart_option.title.bottom = padding + } else { + chart_option.title.top = customStyle.text.vPosition + } + const style = chart_option.title.textStyle ? chart_option.title.textStyle : {} + style.fontSize = customStyle.text.fontSize + style.color = customStyle.text.color + customStyle.text.isItalic ? style.fontStyle = 'italic' : style.fontStyle = 'normal' + customStyle.text.isBolder ? style.fontWeight = 'bold' : style.fontWeight = 'normal' + chart_option.title.textStyle = style + } + if (customStyle.legend && chart_option.legend) { + chart_option.legend.show = customStyle.legend.show + // 水平方向 + if (customStyle.legend.hPosition === 'left') { + chart_option.legend.left = padding + } else if (customStyle.legend.hPosition === 'right') { + chart_option.legend.right = padding + } else { + chart_option.legend.left = customStyle.legend.hPosition + } + // 垂直方向 + if (customStyle.legend.vPosition === 'top') { + chart_option.legend.top = padding + } else if (customStyle.legend.vPosition === 'bottom') { + chart_option.legend.bottom = padding + } else { + chart_option.legend.top = customStyle.legend.vPosition + } + chart_option.legend.orient = customStyle.legend.orient + chart_option.legend.icon = customStyle.legend.icon + chart_option.legend.textStyle = customStyle.legend.textStyle + if (chart.type === 'treemap' || chart.type === 'gauge') { + chart_option.legend.show = false + } + } + + if (customStyle.margin && customStyle.margin.marginModel && customStyle.margin.marginModel !== 'auto') { + const unit = getMarginUnit(customStyle.margin) + const result = {containLabel: true} + const realUnit = (unit === '%' ? unit : '') + if (customStyle.margin.marginTop != null) { + result.top = customStyle.margin.marginTop + realUnit + } + if (customStyle.margin.marginBottom != null) { + result.bottom = customStyle.margin.marginBottom + realUnit + } + if (customStyle.margin.marginLeft != null) { + result.left = customStyle.margin.marginLeft + realUnit + } + if (customStyle.margin.marginRight != null) { + result.right = customStyle.margin.marginRight + realUnit + } + if (!chart_option.grid) { + chart_option.grid = {} + } + Object.assign(chart_option.grid, JSON.parse(JSON.stringify(result))) + } + if (customStyle.background) { + chart_option.backgroundColor = hexColorToRGBA(customStyle.background.color, customStyle.background.alpha) + } + } +} + +export function hexColorToRGBA(hex, alpha) { + const rgb = [] // 定义rgb数组 + if (/^\#[0-9A-F]{3}$/i.test(hex)) { // 判断传入是否为#三位十六进制数 + let sixHex = '#' + hex.replace(/[0-9A-F]/ig, function (kw) { + sixHex += kw + kw // 把三位16进制数转化为六位 + }) + hex = sixHex // 保存回hex + } + if (/^#[0-9A-F]{6}$/i.test(hex)) { // 判断传入是否为#六位十六进制数 + hex.replace(/[0-9A-F]{2}/ig, function (kw) { + // eslint-disable-next-line no-eval + rgb.push(eval('0x' + kw)) // 十六进制转化为十进制并存如数组 + }) + return `rgba(${rgb.join(',')},${alpha / 100})` // 输出RGB格式颜色 + } else { + return 'rgb(0,0,0)' + } +} + + +export const DEFAULT_YAXIS_EXT_STYLE = { + show: true, + position: 'right', + name: '', + nameTextStyle: { + color: '#333333', + fontSize: 12 + }, + axisLabel: { + show: true, + color: '#333333', + fontSize: '12', + rotate: 0, + formatter: '{value}' + }, + splitLine: { + show: true, + lineStyle: { + color: '#cccccc', + width: 1, + style: 'solid' + } + }, + axisValue: { + auto: true, + min: null, + max: null, + split: null, + splitCount: null + } +} + +export const getDefaultTemplate = (chart, type, feed, showKey) => { + if (!chart || !chart.viewFields || !type) return null; + let viewFields = [] + if (chart.viewFields instanceof Array) { + viewFields = JSON.parse(JSON.stringify(chart.viewFields)) + } else { + viewFields = JSON.parse(chart.viewFields) + } + const separator = feed ? '\n' : ' ' + return viewFields.filter(field => field.busiType && field.busiType === type).map(field => { + const fieldName = field.name + let template = "${" + field.name + "}" + if (showKey) { + template = fieldName + ":${" + field.name + "}" + } + return template + }).join(separator) +} + +export function uuid() { + return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1); +} + +export const reverseColor = colorValue => { + colorValue = '0x' + colorValue.replace(/#/g, '') + const str = '000000' + (0xFFFFFF - colorValue).toString(16) + return '#' + str.substring(str.length - 6, str.length) +} + +export function seniorCfg(chart_option, chart) { + if (chart.senior && chart.type && (chart.type.includes('bar') || chart.type.includes('line') || chart.type.includes('mix'))) { + const senior = JSON.parse(chart.senior) + if (senior.functionCfg) { + if (senior.functionCfg.sliderShow) { + chart_option.dataZoom = [ + { + type: 'inside', + start: parseInt(senior.functionCfg.sliderRange[0]), + end: parseInt(senior.functionCfg.sliderRange[1]) + }, + { + type: 'slider', + start: parseInt(senior.functionCfg.sliderRange[0]), + end: parseInt(senior.functionCfg.sliderRange[1]) + } + ] + if (senior.functionCfg.sliderBg) { + chart_option.dataZoom[1].dataBackground = { + lineStyle: {color: hexToRgba(senior.functionCfg.sliderBg, 0.5)}, + areaStyle: {color: hexToRgba(senior.functionCfg.sliderBg, 0.5)} + } + chart_option.dataZoom[1].borderColor = hexToRgba(senior.functionCfg.sliderBg, 0.3) + } + if (senior.functionCfg.sliderFillBg) { + chart_option.dataZoom[1].selectedDataBackground = { + lineStyle: {color: senior.functionCfg.sliderFillBg}, + areaStyle: {color: senior.functionCfg.sliderFillBg} + } + const rgba = hexToRgba(senior.functionCfg.sliderFillBg, 0.2) + chart_option.dataZoom[1].fillerColor = rgba + } + if (senior.functionCfg.sliderTextClolor) { + chart_option.dataZoom[1].textStyle = {color: senior.functionCfg.sliderTextClolor} + const rgba = hexToRgba(senior.functionCfg.sliderTextClolor, 0.5) + chart_option.dataZoom[1].handleStyle = {color: rgba} + } + + if (chart.type.includes('horizontal')) { + chart_option.dataZoom[0].yAxisIndex = [0] + chart_option.dataZoom[1].yAxisIndex = [0] + chart_option.dataZoom[1].left = '10px' + } + } + } + // begin mark line settings + if (chart_option.series && chart_option.series.length > 0) { + chart_option.series[0].markLine = { + symbol: 'none', + data: [] + } + } + if (senior.assistLine && senior.assistLine.length > 0) { + if (chart_option.series && chart_option.series.length > 0) { + const customStyle = JSON.parse(chart.customStyle) + let xAxis, yAxis, axisFormatterCfg + if (customStyle.xAxis) { + xAxis = JSON.parse(JSON.stringify(customStyle.xAxis)) + if (chart.type.includes('horizontal')) { + axisFormatterCfg = xAxis.axisLabelFormatter ? xAxis.axisLabelFormatter : DEFAULT_XAXIS_STYLE.axisLabelFormatter + } + } + if (customStyle.yAxis) { + yAxis = JSON.parse(JSON.stringify(customStyle.yAxis)) + if (!chart.type.includes('horizontal')) { + axisFormatterCfg = yAxis.axisLabelFormatter ? yAxis.axisLabelFormatter : DEFAULT_YAXIS_STYLE.axisLabelFormatter + } + } + + const fixedLines = senior.assistLine.filter(ele => ele.field === '0') + const dynamicLines = chart.data.dynamicAssistLines + const lines = fixedLines.concat(dynamicLines) + + lines.forEach(ele => { + if (chart.type.includes('horizontal')) { + chart_option.series[0].markLine.data.push({ + symbol: 'none', + xAxis: parseFloat(ele.value), + name: ele.name, + lineStyle: { + color: ele.color, + type: ele.lineType + }, + label: { + show: true, + color: ele.color, + fontSize: ele.fontSize ? parseInt(ele.fontSize) : 10, + position: xAxis.position === 'bottom' ? 'insideStartTop' : 'insideEndTop', + formatter: function (param) { + return ele.name + ' : ' + valueFormatter(param.value, axisFormatterCfg) + } + }, + tooltip: { + show: false + } + }) + } else { + chart_option.series[0].markLine.data.push({ + symbol: 'none', + yAxis: parseFloat(ele.value), + name: ele.name, + lineStyle: { + color: ele.color, + type: ele.lineType + }, + label: { + show: true, + color: ele.color, + fontSize: ele.fontSize ? parseInt(ele.fontSize) : 10, + position: yAxis.position === 'left' ? 'insideStartTop' : 'insideEndTop', + formatter: function (param) { + return ele.name + ' : ' + valueFormatter(param.value, axisFormatterCfg) + } + }, + tooltip: { + show: false + } + }) + } + }) + } + } + } +} + +const hexToRgba = (hex, opacity) => { + let rgbaColor = '' + const reg = /^#[\da-f]{6}$/i + if (reg.test(hex)) { + rgbaColor = `rgba(${parseInt('0x' + hex.slice(1, 3))},${parseInt( + '0x' + hex.slice(3, 5) + )},${parseInt('0x' + hex.slice(5, 7))},${opacity})` + } + return rgbaColor +} + +export const getMarginUnit = marginForm => { + if (!marginForm.marginModel || marginForm.marginModel === 'auto') return null + if (marginForm.marginModel === 'absolute') return 'px' + if (marginForm.marginModel === 'relative') return '%' + return null +} diff --git a/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/utils/validate.js b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/utils/validate.js new file mode 100644 index 0000000000..3e8ffa9448 --- /dev/null +++ b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/utils/validate.js @@ -0,0 +1,15 @@ +/** + * Created by PanJiaChen on 16/11/18. + */ + +/** + * @param {string} path + * @returns {Boolean} + */ +export function isExternal(path) { + return /^(https?:|mailto:|tel:)/.test(path) || /^(http?:|mailto:|tel:)/.test(path) || path.startsWith('/api/pluginCommon/staticInfo') +} + + + + diff --git a/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/views/PluginDemo.vue b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/views/PluginDemo.vue new file mode 100644 index 0000000000..1164dfab1d --- /dev/null +++ b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/views/PluginDemo.vue @@ -0,0 +1,55 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/views/antv/racebar/data.vue b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/views/antv/racebar/data.vue new file mode 100644 index 0000000000..499f1c3b58 --- /dev/null +++ b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/views/antv/racebar/data.vue @@ -0,0 +1,682 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/views/antv/racebar/index.vue b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/views/antv/racebar/index.vue new file mode 100644 index 0000000000..6bb96cde53 --- /dev/null +++ b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/views/antv/racebar/index.vue @@ -0,0 +1,690 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/views/antv/racebar/style.vue b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/views/antv/racebar/style.vue new file mode 100644 index 0000000000..3db2d2a63d --- /dev/null +++ b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/views/antv/racebar/style.vue @@ -0,0 +1,251 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/views/antv/racebar/type.vue b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/views/antv/racebar/type.vue new file mode 100644 index 0000000000..b1702e363b --- /dev/null +++ b/extensions/dataease-extensions-view/view-racebar/view-racebar-frontend/src/views/antv/racebar/type.vue @@ -0,0 +1,63 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-sankey/build.sh b/extensions/dataease-extensions-view/view-sankey/build.sh new file mode 100644 index 0000000000..8f59a26490 --- /dev/null +++ b/extensions/dataease-extensions-view/view-sankey/build.sh @@ -0,0 +1,8 @@ +#!/bin/sh +mvn clean package + +cp view-sankey-backend/target/view-sankey-backend-1.18.9.jar . + +zip -r sankey.zip ./view-sankey-backend-1.18.9.jar ./plugin.json + +rm -f ./view-sankey-backend-1.18.9.jar diff --git a/extensions/dataease-extensions-view/view-sankey/plugin.json b/extensions/dataease-extensions-view/view-sankey/plugin.json new file mode 100644 index 0000000000..a05fd1497d --- /dev/null +++ b/extensions/dataease-extensions-view/view-sankey/plugin.json @@ -0,0 +1,13 @@ +{ + "name": "桑基图", + "free": 0, + "store": "default", + "cost": 0, + "category": "view", + "descript": "AntV G2Plot 桑基图插件", + "version": "1.18.9", + "creator": "DATAEASE", + "moduleName": "view-sankey-backend", + "require": "1.18.9", + "dsType": "" +} diff --git a/extensions/dataease-extensions-view/view-sankey/pom.xml b/extensions/dataease-extensions-view/view-sankey/pom.xml new file mode 100644 index 0000000000..2e3ac1d6f3 --- /dev/null +++ b/extensions/dataease-extensions-view/view-sankey/pom.xml @@ -0,0 +1,20 @@ + + + + dataease-extensions-view + io.dataease + ${dataease.version} + + 4.0.0 + + view-sankey + pom + + view-sankey-frontend + view-sankey-backend + + + + diff --git a/extensions/dataease-extensions-view/view-sankey/view-sankey-backend/pom.xml b/extensions/dataease-extensions-view/view-sankey/view-sankey-backend/pom.xml new file mode 100644 index 0000000000..a47e0dbe55 --- /dev/null +++ b/extensions/dataease-extensions-view/view-sankey/view-sankey-backend/pom.xml @@ -0,0 +1,109 @@ + + + + view-sankey + io.dataease + ${dataease.version} + + 4.0.0 + + view-sankey-backend + + + + io.dataease + dataease-plugin-view + + + + + + + src/main/java + + **/*.properties + **/*.xml + + false + + + src/main/resources + + **/* + + false + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 11 + 11 + + + + + org.apache.maven.plugins + maven-jar-plugin + 2.4 + + + **/server/** + **/*.properties + **/Application* + + + + + + maven-clean-plugin + + + + src/main/resources/static + + ** + + false + + + + + + + + + org.apache.maven.plugins + maven-antrun-plugin + + + main-class-placement + generate-resources + + + + + + + + + + + + run + + + + + + + + + + + diff --git a/extensions/dataease-extensions-view/view-sankey/view-sankey-backend/src/main/java/io/dataease/plugins/view/official/impl/SankeyService.java b/extensions/dataease-extensions-view/view-sankey/view-sankey-backend/src/main/java/io/dataease/plugins/view/official/impl/SankeyService.java new file mode 100644 index 0000000000..9aa7f6142d --- /dev/null +++ b/extensions/dataease-extensions-view/view-sankey/view-sankey-backend/src/main/java/io/dataease/plugins/view/official/impl/SankeyService.java @@ -0,0 +1,122 @@ +package io.dataease.plugins.view.official.impl; + +import io.dataease.plugins.common.dto.StaticResource; +import io.dataease.plugins.view.entity.PluginViewField; +import io.dataease.plugins.view.entity.PluginViewParam; +import io.dataease.plugins.view.entity.PluginViewType; +import io.dataease.plugins.view.service.ViewPluginService; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.stereotype.Service; + +import java.io.InputStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Service +public class SankeyService extends ViewPluginService { + + private static final String VIEW_TYPE_VALUE = "sankey"; + + /* 下版这些常量移到sdk */ + private static final String TYPE = "-type"; + private static final String DATA = "-data"; + private static final String STYLE = "-style"; + private static final String VIEW = "-view"; + private static final String SUFFIX = "svg"; + /* 下版这些常量移到sdk */ + private static final String VIEW_TYPE = VIEW_TYPE_VALUE + TYPE; + private static final String VIEW_DATA = VIEW_TYPE_VALUE + DATA; + private static final String VIEW_STYLE = VIEW_TYPE_VALUE + STYLE; + private static final String VIEW_VIEW = VIEW_TYPE_VALUE + VIEW; + + private static final String[] VIEW_STYLE_PROPERTIES = { + "color-selector", + "label-selector", + "tooltip-selector-ant-v", + "title-selector-ant-v" + }; + + private static final Map VIEW_STYLE_PROPERTY_INNER = new HashMap<>(); + + static { + VIEW_STYLE_PROPERTY_INNER.put("color-selector", new String[]{"value"}); + VIEW_STYLE_PROPERTY_INNER.put("label-selector", new String[]{"show", "fontSize", "color"}); + VIEW_STYLE_PROPERTY_INNER.put("tooltip-selector-ant-v", new String[]{"show", "fontSize", "color", "backgroundColor"}); + VIEW_STYLE_PROPERTY_INNER.put("title-selector-ant-v", new String[]{"show", "title", "fontSize", "color", "hPosition", "vPosition", "isItalic", "isBolder"}); + } + + @Override + public PluginViewType viewType() { + PluginViewType pluginViewType = new PluginViewType(); + pluginViewType.setRender("antv"); + pluginViewType.setCategory("chart.chart_type_relation"); + pluginViewType.setValue(VIEW_TYPE_VALUE); + pluginViewType.setProperties(VIEW_STYLE_PROPERTIES); + pluginViewType.setPropertyInner(VIEW_STYLE_PROPERTY_INNER); + return pluginViewType; + } + + @Override + public Object format(Object o) { + return null; + } + + @Override + public List components() { + List results = new ArrayList<>(); + results.add(VIEW_VIEW); + results.add(VIEW_DATA); + results.add(VIEW_TYPE); + results.add(VIEW_STYLE); + return results; + } + + @Override + public List staticResources() { + List results = new ArrayList<>(); + StaticResource staticResource = new StaticResource(); + staticResource.setName(VIEW_TYPE_VALUE); + staticResource.setSuffix(SUFFIX); + results.add(staticResource); + results.add(pluginSvg()); + return results; + } + + private StaticResource pluginSvg() { + StaticResource staticResource = new StaticResource(); + staticResource.setName("view-sankey-backend"); + staticResource.setSuffix("svg"); + return staticResource; + } + + + @Override + protected InputStream readContent(String s) { + InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream("static/" + s); + return resourceAsStream; + } + + @Override + public String generateSQL(PluginViewParam param) { + System.out.println("************* generateSQL **************"); + List xAxis = param.getFieldsByType("xAxis"); + List yAxis = param.getFieldsByType("yAxis"); + if (CollectionUtils.isEmpty(xAxis) || CollectionUtils.isEmpty(yAxis)) { + return null; + } + return super.generateSQL(param); + + } + + @Override + public Map formatResult(PluginViewParam pluginViewParam, List data, Boolean isDrill) { + Map map = super.formatResult(pluginViewParam, data, isDrill); + + map.put("data", map.get("series")); + + return map; + } + +} diff --git a/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/.babelrc b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/.babelrc new file mode 100644 index 0000000000..3a280ba34b --- /dev/null +++ b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/.babelrc @@ -0,0 +1,12 @@ +{ + "presets": [ + ["env", { + "modules": false, + "targets": { + "browsers": ["> 1%", "last 2 versions", "not ie <= 8"] + } + }], + "stage-2" + ], + "plugins": ["transform-vue-jsx", "transform-runtime"] +} diff --git a/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/.editorconfig b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/.editorconfig new file mode 100644 index 0000000000..9d08a1a828 --- /dev/null +++ b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/.editorconfig @@ -0,0 +1,9 @@ +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true diff --git a/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/.gitignore b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/.gitignore new file mode 100644 index 0000000000..541a820f6c --- /dev/null +++ b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/.gitignore @@ -0,0 +1,14 @@ +.DS_Store +node_modules/ +/dist/ +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Editor directories and files +.idea +.vscode +*.suo +*.ntvs* +*.njsproj +*.sln diff --git a/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/.postcssrc.js b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/.postcssrc.js new file mode 100644 index 0000000000..eee3e92d7f --- /dev/null +++ b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/.postcssrc.js @@ -0,0 +1,10 @@ +// https://github.com/michael-ciniawsky/postcss-load-config + +module.exports = { + "plugins": { + "postcss-import": {}, + "postcss-url": {}, + // to edit target browsers: use "browserslist" field in package.json + "autoprefixer": {} + } +} diff --git a/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/README.md b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/README.md new file mode 100644 index 0000000000..c1e4be95e0 --- /dev/null +++ b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/README.md @@ -0,0 +1,21 @@ +# deplugin-view-frontend + +> A Vue.js project + +## Build Setup + +``` bash +# install dependencies +npm install + +# serve with hot reload at localhost:8080 +npm run dev + +# build for production with minification +npm run build + +# build for production and view the bundle analyzer report +npm run build --report +``` + +For a detailed explanation on how things work, check out the [guide](http://vuejs-templates.github.io/webpack/) and [docs for vue-loader](http://vuejs.github.io/vue-loader). diff --git a/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/build/build-async-plugins.js b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/build/build-async-plugins.js new file mode 100644 index 0000000000..2303854531 --- /dev/null +++ b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/build/build-async-plugins.js @@ -0,0 +1,35 @@ +'use strict' +require('./check-versions')() + +process.env.NODE_ENV = 'production' + +const ora = require('ora') +const chalk = require('chalk') +const webpack = require('webpack') +const webpackConfig = require('./webpack.async-plugins') + +const spinner = ora('building for sync-plugins...') +spinner.start() + +webpack(webpackConfig, function (err, stats) { + spinner.stop() + if (err) throw err + process.stdout.write(stats.toString({ + colors: true, + modules: false, + children: false, + chunks: false, + chunkModules: false + }) + '\n\n') + + if (stats.hasErrors()) { + console.log(chalk.red(' Build failed with errors.\n')) + process.exit(1) + } + + console.log(chalk.cyan(' Build complete.\n')) + console.log(chalk.yellow( + ' Tip: built files are meant to be served over an HTTP server.\n' + + ' Opening index.html over file:// won\'t work.\n' + )) +}) diff --git a/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/build/build.js b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/build/build.js new file mode 100644 index 0000000000..8f2ad8ad49 --- /dev/null +++ b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/build/build.js @@ -0,0 +1,41 @@ +'use strict' +require('./check-versions')() + +process.env.NODE_ENV = 'production' + +const ora = require('ora') +const rm = require('rimraf') +const path = require('path') +const chalk = require('chalk') +const webpack = require('webpack') +const config = require('../config') +const webpackConfig = require('./webpack.prod.conf') + +const spinner = ora('building for production...') +spinner.start() + +rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => { + if (err) throw err + webpack(webpackConfig, (err, stats) => { + spinner.stop() + if (err) throw err + process.stdout.write(stats.toString({ + colors: true, + modules: false, + children: false, // If you are using ts-loader, setting this to true will make TypeScript errors show up during build. + chunks: false, + chunkModules: false + }) + '\n\n') + + if (stats.hasErrors()) { + console.log(chalk.red(' Build failed with errors.\n')) + process.exit(1) + } + + console.log(chalk.cyan(' Build complete.\n')) + console.log(chalk.yellow( + ' Tip: built files are meant to be served over an HTTP server.\n' + + ' Opening index.html over file:// won\'t work.\n' + )) + }) +}) diff --git a/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/build/check-versions.js b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/build/check-versions.js new file mode 100644 index 0000000000..3ef972a08d --- /dev/null +++ b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/build/check-versions.js @@ -0,0 +1,54 @@ +'use strict' +const chalk = require('chalk') +const semver = require('semver') +const packageConfig = require('../package.json') +const shell = require('shelljs') + +function exec (cmd) { + return require('child_process').execSync(cmd).toString().trim() +} + +const versionRequirements = [ + { + name: 'node', + currentVersion: semver.clean(process.version), + versionRequirement: packageConfig.engines.node + } +] + +if (shell.which('npm')) { + versionRequirements.push({ + name: 'npm', + currentVersion: exec('npm --version'), + versionRequirement: packageConfig.engines.npm + }) +} + +module.exports = function () { + const warnings = [] + + for (let i = 0; i < versionRequirements.length; i++) { + const mod = versionRequirements[i] + + if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) { + warnings.push(mod.name + ': ' + + chalk.red(mod.currentVersion) + ' should be ' + + chalk.green(mod.versionRequirement) + ) + } + } + + if (warnings.length) { + console.log('') + console.log(chalk.yellow('To use this template, you must update following to modules:')) + console.log() + + for (let i = 0; i < warnings.length; i++) { + const warning = warnings[i] + console.log(' ' + warning) + } + + console.log() + process.exit(1) + } +} diff --git a/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/build/logo.png b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/build/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..f3d2503fc2a44b5053b0837ebea6e87a2d339a43 GIT binary patch literal 6849 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 { + const notifier = require('node-notifier') + + return (severity, errors) => { + if (severity !== 'error') return + + const error = errors[0] + const filename = error.file && error.file.split('!').pop() + + notifier.notify({ + title: packageConfig.name, + message: severity + ': ' + error.name, + subtitle: filename || '', + icon: path.join(__dirname, 'logo.png') + }) + } +} diff --git a/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/build/vue-loader.conf.js b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/build/vue-loader.conf.js new file mode 100644 index 0000000000..33ed58bc0a --- /dev/null +++ b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/build/vue-loader.conf.js @@ -0,0 +1,22 @@ +'use strict' +const utils = require('./utils') +const config = require('../config') +const isProduction = process.env.NODE_ENV === 'production' +const sourceMapEnabled = isProduction + ? config.build.productionSourceMap + : config.dev.cssSourceMap + +module.exports = { + loaders: utils.cssLoaders({ + sourceMap: sourceMapEnabled, + extract: isProduction + }), + cssSourceMap: sourceMapEnabled, + cacheBusting: config.dev.cacheBusting, + transformToRequire: { + video: ['src', 'poster'], + source: 'src', + img: 'src', + image: 'xlink:href' + } +} diff --git a/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/build/webpack.async-plugins.js b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/build/webpack.async-plugins.js new file mode 100644 index 0000000000..aa7c48ee27 --- /dev/null +++ b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/build/webpack.async-plugins.js @@ -0,0 +1,97 @@ +const webpack = require('webpack') +const path = require('path') +const utils = require('./utils') +const CopyPlugin = require("copy-webpack-plugin"); +const VueLoaderPlugin = require('vue-loader/lib/plugin'); +function resolve (dir) { + return path.join(__dirname, '..', dir) +} + +module.exports = { + mode: 'development', + entry: { + + // PluginDemo: resolve('/src/views/PluginDemo.vue') + 'sankey-view': resolve('/src/views/antv/sankey/index.vue'), + 'sankey-data': resolve('/src/views/antv/sankey/data.vue'), + 'sankey-type': resolve('/src/views/antv/sankey/type.vue'), + 'sankey-style': resolve('/src/views/antv/sankey/style.vue') + + }, + output: { + path: resolve('/static/'), + filename: '[name].js' + }, + resolve: { + extensions: ['.js', '.vue', '.json'], + alias: { + 'vue$': 'vue/dist/vue.esm.js', + '@': resolve('src') + } + }, + externals: { + vue: 'vue' + }, + module: { + rules: [ + { + test: /\.vue$/, + loader: 'vue-loader', + options: { + transformAssetUrls: { + video: 'src', + source: 'src', + img: 'src', + image: 'xlink:href' + } + } + }, + { + test: /.(sa|sc|c)ss$/, + use: [ + {loader: 'vue-style-loader'}, + 'css-loader', + 'sass-loader' + ] + }, + { + test: /\.js$/, + loader: 'babel-loader', + include: [resolve('src'), resolve('test')] + }, + { + test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: utils.assetsPath('img/[name].[hash:7].[ext]') + } + }, + { + test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: utils.assetsPath('media/[name].[hash:7].[ext]') + } + }, + { + test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: utils.assetsPath('fonts/[name].[hash:7].[ext]') + } + } + ] + }, + plugins: [ + new VueLoaderPlugin(), + new webpack.DefinePlugin({ + 'process.env.NODE_ENV': '"production"' + }), + new CopyPlugin([ + {from: 'src/icons/svg/'} + ]), + ] +} diff --git a/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/build/webpack.base.conf.js b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/build/webpack.base.conf.js new file mode 100644 index 0000000000..6ccc02dab4 --- /dev/null +++ b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/build/webpack.base.conf.js @@ -0,0 +1,91 @@ +'use strict' +const path = require('path') +const utils = require('./utils') +const config = require('../config') +const vueLoaderConfig = require('./vue-loader.conf') + +function resolve (dir) { + return path.join(__dirname, '..', dir) +} + + + +module.exports = { + context: path.resolve(__dirname, '../'), + entry: { + app: './src/main.js' + }, + output: { + path: config.build.assetsRoot, + filename: '[name].js', + publicPath: process.env.NODE_ENV === 'production' + ? config.build.assetsPublicPath + : config.dev.assetsPublicPath + }, + resolve: { + extensions: ['.js', '.vue', '.json'], + alias: { + 'vue$': 'vue/dist/vue.esm.js', + '@': resolve('src'), + } + }, + module: { + rules: [ + { + test: /\.vue$/, + loader: 'vue-loader', + options: vueLoaderConfig + }, + { + test: /\.js$/, + loader: 'babel-loader', + include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')] + }, + { + test: /\.svg$/, + loader: 'svg-sprite-loader', + include: [resolve('src/icons')], + options: { + symbolId: 'icon-[name]' + } + }, + { + test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, + loader: 'url-loader', + exclude: [resolve('src/icons')], + options: { + limit: 10000, + name: utils.assetsPath('img/[name].[hash:7].[ext]') + } + }, + { + test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: utils.assetsPath('media/[name].[hash:7].[ext]') + } + }, + { + test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: utils.assetsPath('fonts/[name].[hash:7].[ext]') + } + } + ] + }, + node: { + // prevent webpack from injecting useless setImmediate polyfill because Vue + // source contains it (although only uses it if it's native). + setImmediate: false, + // prevent webpack from injecting mocks to Node native modules + // that does not make sense for the client + dgram: 'empty', + fs: 'empty', + net: 'empty', + tls: 'empty', + child_process: 'empty' + } +} diff --git a/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/build/webpack.dev.conf.js b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/build/webpack.dev.conf.js new file mode 100755 index 0000000000..070ae221f3 --- /dev/null +++ b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/build/webpack.dev.conf.js @@ -0,0 +1,95 @@ +'use strict' +const utils = require('./utils') +const webpack = require('webpack') +const config = require('../config') +const merge = require('webpack-merge') +const path = require('path') +const baseWebpackConfig = require('./webpack.base.conf') +const CopyWebpackPlugin = require('copy-webpack-plugin') +const HtmlWebpackPlugin = require('html-webpack-plugin') +const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin') +const portfinder = require('portfinder') + +const HOST = process.env.HOST +const PORT = process.env.PORT && Number(process.env.PORT) + +const devWebpackConfig = merge(baseWebpackConfig, { + module: { + rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true }) + }, + // cheap-module-eval-source-map is faster for development + devtool: config.dev.devtool, + + // these devServer options should be customized in /config/index.js + devServer: { + clientLogLevel: 'warning', + historyApiFallback: { + rewrites: [ + { from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') }, + ], + }, + hot: true, + contentBase: false, // since we use CopyWebpackPlugin. + compress: true, + host: HOST || config.dev.host, + port: PORT || config.dev.port, + open: config.dev.autoOpenBrowser, + overlay: config.dev.errorOverlay + ? { warnings: false, errors: true } + : false, + publicPath: config.dev.assetsPublicPath, + proxy: config.dev.proxyTable, + quiet: true, // necessary for FriendlyErrorsPlugin + watchOptions: { + poll: config.dev.poll, + } + }, + plugins: [ + new webpack.DefinePlugin({ + 'process.env': require('../config/dev.env') + }), + new webpack.HotModuleReplacementPlugin(), + new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update. + new webpack.NoEmitOnErrorsPlugin(), + // https://github.com/ampedandwired/html-webpack-plugin + new HtmlWebpackPlugin({ + filename: 'index.html', + template: 'index.html', + inject: true + }), + // copy custom static assets + new CopyWebpackPlugin([ + { + from: path.resolve(__dirname, '../static'), + to: config.dev.assetsSubDirectory, + ignore: ['.*'] + } + ]) + ] +}) + +module.exports = new Promise((resolve, reject) => { + portfinder.basePort = process.env.PORT || config.dev.port + portfinder.getPort((err, port) => { + if (err) { + reject(err) + } else { + // publish the new Port, necessary for e2e tests + process.env.PORT = port + // add port to devServer config + devWebpackConfig.devServer.port = port + + // Add FriendlyErrorsPlugin + devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({ + compilationSuccessInfo: { + messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`], + }, + onErrors: config.dev.notifyOnErrors + ? utils.createNotifierCallback() + : undefined + })) + + resolve(devWebpackConfig) + } + }) +}) diff --git a/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/build/webpack.prod.conf.js b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/build/webpack.prod.conf.js new file mode 100644 index 0000000000..1f71ad6454 --- /dev/null +++ b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/build/webpack.prod.conf.js @@ -0,0 +1,147 @@ +'use strict' +const path = require('path') +const utils = require('./utils') +const webpack = require('webpack') +const config = require('../config') +const merge = require('webpack-merge') +const baseWebpackConfig = require('./webpack.base.conf') +const CopyWebpackPlugin = require('copy-webpack-plugin') +const HtmlWebpackPlugin = require('html-webpack-plugin') +const ExtractTextPlugin = require('extract-text-webpack-plugin') +const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin') +const UglifyJsPlugin = require('uglifyjs-webpack-plugin') +const VueLoaderPlugin = require('vue-loader/lib/plugin'); + +const env = require('../config/prod.env') + +const webpackConfig = merge(baseWebpackConfig, { + module: { + rules: utils.styleLoaders({ + sourceMap: config.build.productionSourceMap, + extract: true, + usePostCSS: true + }) + }, + devtool: config.build.productionSourceMap ? config.build.devtool : false, + output: { + path: config.build.assetsRoot, + filename: utils.assetsPath('js/[name].[chunkhash].js'), + chunkFilename: utils.assetsPath('js/[id].[chunkhash].js') + }, + plugins: [ + new VueLoaderPlugin(), + // http://vuejs.github.io/vue-loader/en/workflow/production.html + new webpack.DefinePlugin({ + 'process.env': env + }), + new UglifyJsPlugin({ + uglifyOptions: { + compress: { + warnings: false + } + }, + sourceMap: config.build.productionSourceMap, + parallel: true + }), + // extract css into its own file + new ExtractTextPlugin({ + filename: utils.assetsPath('css/[name].[contenthash].css'), + // Setting the following option to `false` will not extract CSS from codesplit chunks. + // Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack. + // It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`, + // increasing file size: https://github.com/vuejs-templates/webpack/issues/1110 + allChunks: true, + }), + // Compress extracted CSS. We are using this plugin so that possible + // duplicated CSS from different components can be deduped. + new OptimizeCSSPlugin({ + cssProcessorOptions: config.build.productionSourceMap + ? { safe: true, map: { inline: false } } + : { safe: true } + }), + // generate dist index.html with correct asset hash for caching. + // you can customize output by editing /index.html + // see https://github.com/ampedandwired/html-webpack-plugin + new HtmlWebpackPlugin({ + filename: config.build.index, + template: 'index.html', + inject: true, + minify: { + removeComments: true, + collapseWhitespace: true, + removeAttributeQuotes: true + // more options: + // https://github.com/kangax/html-minifier#options-quick-reference + }, + // necessary to consistently work with multiple chunks via CommonsChunkPlugin + chunksSortMode: 'dependency' + }), + // keep module.id stable when vendor modules does not change + new webpack.HashedModuleIdsPlugin(), + // enable scope hoisting + new webpack.optimize.ModuleConcatenationPlugin(), + // split vendor js into its own file + new webpack.optimize.CommonsChunkPlugin({ + name: 'vendor', + minChunks (module) { + // any required modules inside node_modules are extracted to vendor + return ( + module.resource && + /\.js$/.test(module.resource) && + module.resource.indexOf( + path.join(__dirname, '../node_modules') + ) === 0 + ) + } + }), + // extract webpack runtime and module manifest to its own file in order to + // prevent vendor hash from being updated whenever app bundle is updated + new webpack.optimize.CommonsChunkPlugin({ + name: 'manifest', + minChunks: Infinity + }), + // This instance extracts shared chunks from code split chunks and bundles them + // in a separate chunk, similar to the vendor chunk + // see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk + new webpack.optimize.CommonsChunkPlugin({ + name: 'app', + async: 'vendor-async', + children: true, + minChunks: 3 + }), + + // copy custom static assets + new CopyWebpackPlugin([ + { + from: path.resolve(__dirname, '../static'), + to: config.build.assetsSubDirectory, + ignore: ['.*'] + } + ]) + ] +}) + +if (config.build.productionGzip) { + const CompressionWebpackPlugin = require('compression-webpack-plugin') + + webpackConfig.plugins.push( + new CompressionWebpackPlugin({ + asset: '[path].gz[query]', + algorithm: 'gzip', + test: new RegExp( + '\\.(' + + config.build.productionGzipExtensions.join('|') + + ')$' + ), + threshold: 10240, + minRatio: 0.8 + }) + ) +} + +if (config.build.bundleAnalyzerReport) { + const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin + webpackConfig.plugins.push(new BundleAnalyzerPlugin()) +} + +module.exports = webpackConfig diff --git a/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/config/dev.env.js b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/config/dev.env.js new file mode 100644 index 0000000000..1e22973ae7 --- /dev/null +++ b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/config/dev.env.js @@ -0,0 +1,7 @@ +'use strict' +const merge = require('webpack-merge') +const prodEnv = require('./prod.env') + +module.exports = merge(prodEnv, { + NODE_ENV: '"development"' +}) diff --git a/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/config/index.js b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/config/index.js new file mode 100644 index 0000000000..c5eded7f81 --- /dev/null +++ b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/config/index.js @@ -0,0 +1,69 @@ +'use strict' +// Template version: 1.3.1 +// see http://vuejs-templates.github.io/webpack for documentation. + +const path = require('path') + +module.exports = { + dev: { + + // Paths + assetsSubDirectory: 'static', + assetsPublicPath: '/', + proxyTable: {}, + + // Various Dev Server settings + host: 'localhost', // can be overwritten by process.env.HOST + port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined + autoOpenBrowser: false, + errorOverlay: true, + notifyOnErrors: true, + poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions- + + + /** + * Source Maps + */ + + // https://webpack.js.org/configuration/devtool/#development + devtool: 'cheap-module-eval-source-map', + + // If you have problems debugging vue-files in devtools, + // set this to false - it *may* help + // https://vue-loader.vuejs.org/en/options.html#cachebusting + cacheBusting: true, + + cssSourceMap: true + }, + + build: { + // Template for index.html + index: path.resolve(__dirname, '../dist/index.html'), + + // Paths + assetsRoot: path.resolve(__dirname, '../dist'), + assetsSubDirectory: 'static', + assetsPublicPath: '/', + + /** + * Source Maps + */ + + productionSourceMap: true, + // https://webpack.js.org/configuration/devtool/#production + devtool: '#source-map', + + // Gzip off by default as many popular static hosts such as + // Surge or Netlify already gzip all static assets for you. + // Before setting to `true`, make sure to: + // npm install --save-dev compression-webpack-plugin + productionGzip: false, + productionGzipExtensions: ['js', 'css'], + + // Run the build command with an extra argument to + // View the bundle analyzer report after build finishes: + // `npm run build --report` + // Set to `true` or `false` to always turn it on or off + bundleAnalyzerReport: process.env.npm_config_report + } +} diff --git a/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/config/prod.env.js b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/config/prod.env.js new file mode 100644 index 0000000000..a6f997616e --- /dev/null +++ b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/config/prod.env.js @@ -0,0 +1,4 @@ +'use strict' +module.exports = { + NODE_ENV: '"production"' +} diff --git a/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/index.html b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/index.html new file mode 100644 index 0000000000..03ce3fdf27 --- /dev/null +++ b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/index.html @@ -0,0 +1,12 @@ + + + + + + deplugin-view-frontend + + +
+ + + diff --git a/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/package.json b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/package.json new file mode 100644 index 0000000000..dd121e3144 --- /dev/null +++ b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/package.json @@ -0,0 +1,75 @@ +{ + "name": "deplugin-view-frontend", + "version": "1.0.0", + "description": "A Vue.js project", + "author": "", + "private": true, + "scripts": { + "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js", + "start": "npm run dev", + "build": "node build/build.js", + "buildPlugin": "node build/build-async-plugins.js" + }, + "dependencies": { + "@antv/g2plot": "^2.4.31", + "@riophae/vue-treeselect": "0.4.0", + "lodash": "^4.17.21", + "vue": "2.6.10", + "vue-i18n": "7.3.2", + "vue-router": "^3.0.1", + "vue-uuid": "2.0.2", + "vuedraggable": "^2.24.3", + "vuex": "3.1.0" + }, + "devDependencies": { + "autoprefixer": "^7.1.2", + "babel-core": "^6.22.1", + "babel-helper-vue-jsx-merge-props": "^2.0.3", + "babel-loader": "^7.1.1", + "babel-plugin-syntax-jsx": "^6.18.0", + "babel-plugin-transform-runtime": "^6.22.0", + "babel-plugin-transform-vue-jsx": "^3.5.0", + "babel-preset-env": "^1.3.2", + "babel-preset-stage-2": "^6.22.0", + "chalk": "^2.0.1", + "copy-webpack-plugin": "^4.6.0", + "css-loader": "^0.28.0", + "element-ui": "2.15.7", + "extract-text-webpack-plugin": "^4.0.0-beta.0", + "file-loader": "^1.1.4", + "friendly-errors-webpack-plugin": "^1.6.1", + "html-webpack-plugin": "^3.2.0", + "js-cookie": "2.2.0", + "node-notifier": "^8.0.1", + "optimize-css-assets-webpack-plugin": "^3.2.0", + "ora": "^1.2.0", + "portfinder": "^1.0.13", + "postcss-import": "^11.0.0", + "postcss-loader": "^2.0.8", + "postcss-url": "^7.2.1", + "rimraf": "^2.6.0", + "sass": "^1.33.0", + "sass-loader": "^7.3.1", + "semver": "^5.3.0", + "shelljs": "^0.8.5", + "svg-sprite-loader": "4.1.3", + "uglifyjs-webpack-plugin": "^1.1.1", + "url-loader": "^0.5.8", + "vue-loader": "^15.6.4", + "vue-style-loader": "^4.1.2", + "vue-template-compiler": "2.6.10", + "webpack": "^4.8.1", + "webpack-bundle-analyzer": "^3.3.2", + "webpack-dev-server": "^3.1.11", + "webpack-merge": "^4.1.0" + }, + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + }, + "browserslist": [ + "> 1%", + "last 2 versions", + "not ie <= 8" + ] +} diff --git a/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/pom.xml b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/pom.xml new file mode 100644 index 0000000000..a44dc1de4b --- /dev/null +++ b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/pom.xml @@ -0,0 +1,80 @@ + + + + + io.dataease + view-sankey + ${dataease.version} + + + 4.0.0 + view-sankey-frontend + + + UTF-8 + UTF-8 + 1.9.1 + + + + + + maven-clean-plugin + + + + static + + ** + + false + + + + + + + + com.github.eirslett + frontend-maven-plugin + ${frontend-maven-plugin.version} + + + install node and npm + + install-node-and-npm + + + + v16.20.2 + 7.6.3 + + + + + npm install + + npm + + + + install + + + + + npm run buildPlugin + + npm + + + run buildPlugin + + + + + + + diff --git a/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/App.vue b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/App.vue new file mode 100644 index 0000000000..8542e07722 --- /dev/null +++ b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/App.vue @@ -0,0 +1,23 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/assets/logo.png b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/assets/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..f3d2503fc2a44b5053b0837ebea6e87a2d339a43 GIT binary patch literal 6849 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 +
+

{{ msg }}

+

Essential Links

+ +

Ecosystem

+ +
+ + + + + + diff --git a/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/SvgIcon/index.vue b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/SvgIcon/index.vue new file mode 100644 index 0000000000..f81b67f667 --- /dev/null +++ b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/SvgIcon/index.vue @@ -0,0 +1,60 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/selector/BackgroundColorSelector.vue b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/selector/BackgroundColorSelector.vue new file mode 100644 index 0000000000..e1cbf5fe18 --- /dev/null +++ b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/selector/BackgroundColorSelector.vue @@ -0,0 +1,102 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/selector/ColorSelector.vue b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/selector/ColorSelector.vue new file mode 100644 index 0000000000..3a579e8889 --- /dev/null +++ b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/selector/ColorSelector.vue @@ -0,0 +1,306 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/selector/LabelSelector.vue b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/selector/LabelSelector.vue new file mode 100644 index 0000000000..d05c4bd3a0 --- /dev/null +++ b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/selector/LabelSelector.vue @@ -0,0 +1,259 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/selector/LegendSelector.vue b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/selector/LegendSelector.vue new file mode 100644 index 0000000000..5125412616 --- /dev/null +++ b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/selector/LegendSelector.vue @@ -0,0 +1,165 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/selector/SizeSelectorAntV.vue b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/selector/SizeSelectorAntV.vue new file mode 100644 index 0000000000..859824039c --- /dev/null +++ b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/selector/SizeSelectorAntV.vue @@ -0,0 +1,130 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/selector/TitleSelector.vue b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/selector/TitleSelector.vue new file mode 100644 index 0000000000..938dd29c36 --- /dev/null +++ b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/selector/TitleSelector.vue @@ -0,0 +1,269 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/selector/TooltipSelector.vue b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/selector/TooltipSelector.vue new file mode 100644 index 0000000000..c59e0f6185 --- /dev/null +++ b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/selector/TooltipSelector.vue @@ -0,0 +1,144 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/selector/TooltipSelectorAntV.vue b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/selector/TooltipSelectorAntV.vue new file mode 100644 index 0000000000..a10b229c16 --- /dev/null +++ b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/selector/TooltipSelectorAntV.vue @@ -0,0 +1,228 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/views/ChartDragItem.vue b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/views/ChartDragItem.vue new file mode 100644 index 0000000000..53ae1e2ad0 --- /dev/null +++ b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/views/ChartDragItem.vue @@ -0,0 +1,278 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/views/ChartTitleUpdate.vue b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/views/ChartTitleUpdate.vue new file mode 100644 index 0000000000..efadca90bb --- /dev/null +++ b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/views/ChartTitleUpdate.vue @@ -0,0 +1,480 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/views/DimensionExtItem.vue b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/views/DimensionExtItem.vue new file mode 100644 index 0000000000..c414ad2d36 --- /dev/null +++ b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/views/DimensionExtItem.vue @@ -0,0 +1,256 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/views/DrillItem.vue b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/views/DrillItem.vue new file mode 100644 index 0000000000..7321b8a08c --- /dev/null +++ b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/views/DrillItem.vue @@ -0,0 +1,146 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/views/FieldErrorTips.vue b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/views/FieldErrorTips.vue new file mode 100644 index 0000000000..9d7b574721 --- /dev/null +++ b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/views/FieldErrorTips.vue @@ -0,0 +1,21 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/views/FilterItem.vue b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/views/FilterItem.vue new file mode 100644 index 0000000000..3dd5952d69 --- /dev/null +++ b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/views/FilterItem.vue @@ -0,0 +1,154 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/views/LocationLineItem.vue b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/views/LocationLineItem.vue new file mode 100644 index 0000000000..7b2985d08f --- /dev/null +++ b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/views/LocationLineItem.vue @@ -0,0 +1,170 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/views/QuotaExtItem.vue b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/views/QuotaExtItem.vue new file mode 100644 index 0000000000..1e2cb07397 --- /dev/null +++ b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/views/QuotaExtItem.vue @@ -0,0 +1,363 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/views/SankeyDimensionItem.vue b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/views/SankeyDimensionItem.vue new file mode 100644 index 0000000000..5ee652a9c3 --- /dev/null +++ b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/views/SankeyDimensionItem.vue @@ -0,0 +1,342 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/views/SankeyQuotaItem.vue b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/views/SankeyQuotaItem.vue new file mode 100644 index 0000000000..aac90dda1a --- /dev/null +++ b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/views/SankeyQuotaItem.vue @@ -0,0 +1,333 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/views/ViewTrackBar.vue b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/views/ViewTrackBar.vue new file mode 100644 index 0000000000..a58cad9770 --- /dev/null +++ b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/views/ViewTrackBar.vue @@ -0,0 +1,80 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/views/utils.js b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/views/utils.js new file mode 100644 index 0000000000..499c79b3d7 --- /dev/null +++ b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/components/views/utils.js @@ -0,0 +1,86 @@ +export function getItemType(dimensionData, quotaData, item) { + // Check whether the current view is in template status + // ( dimensionData and quotaData have no data). If yes, return 'success' directly + if (dimensionData.length === 0 && quotaData.length === 0) { + return 'success' + } + // 将item的字段在数据集维度、指标字段中查询一遍,如果遇到id不存在、字段类型不一致、维度指标不一致,则提示 + const status = item.groupType + let checked = false + if (status === 'd') { + for (let i = 0; i < dimensionData.length; i++) { + const ele = dimensionData[i] + if (item.chartId) { + if (ele.dataeaseName === item.dataeaseName && ele.deType === item.deType && ele.groupType === item.groupType) { + checked = true + break + } + } else { + if (ele.id === item.id && ele.deType === item.deType && ele.groupType === item.groupType) { + checked = true + break + } + } + } + } + if (status === 'q') { + for (let i = 0; i < quotaData.length; i++) { + const ele = quotaData[i] + if (item.chartId) { + if (ele.dataeaseName === item.dataeaseName && ele.deType === item.deType && ele.groupType === item.groupType) { + checked = true + break + } + } else { + if (ele.id === item.id && ele.deType === item.deType && ele.groupType === item.groupType) { + checked = true + break + } + } + } + } + + if (checked) { + if (status === 'd') { + return '' + } else if (status === 'q') { + return 'success' + } + } else { + return 'danger' + } +} + +export function getRemark(chart) { + const remark = {} + if (chart.customStyle) { + const customStyle = JSON.parse(chart.customStyle) + if (customStyle.text) { + const title = JSON.parse(JSON.stringify(customStyle.text)) + remark.show = title.remarkShow ? title.remarkShow : false + remark.content = title.remark ? title.remark : '' + remark.bgFill = title.remarkBackgroundColor ? title.remarkBackgroundColor : '#ffffffff' + } + } + return remark +} + +export function getOriginFieldName(dimensionList, quotaList, field) { + let originName = '' + for (let i = 0; i < dimensionList.length; i++) { + const item = dimensionList[i] + if (item.id === field.id) { + originName = item.name + break + } + } + for (let i = 0; i < quotaList.length; i++) { + const item = quotaList[i] + if (item.id === field.id) { + originName = item.name + break + } + } + return originName +} + diff --git a/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/de-base/lang/en.js b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/de-base/lang/en.js new file mode 100644 index 0000000000..f95dd2fd17 --- /dev/null +++ b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/de-base/lang/en.js @@ -0,0 +1,22 @@ +export default { + plugin_view_sankey: { + source: 'Source', + target: 'Target', + map_type: 'Map Type', + link_line: 'Link Line', + mark_size: 'Weight', + type_title: 'Sankey', + label: 'Area', + angle: 'Symbol', + marker: 'Marker', + pentagon: 'Pentagon', + hexagon: 'Hexagon', + octagon: 'Octagon', + hexagram: 'Hexagram', + border: 'Border', + light: 'Light', + dark: 'Dark', + label_format_tip: 'The field value can be read in the form of {field Name}, the fields in the label and the tips are interchangeable, and the built-in latitude and longitude related fields', + tooltip_format_tip: 'The field value can be read in the form of {field Name}, the fields in the label and the tips are interchangeable, and the built-in latitude and longitude related fields.(the label does not support line breaks)', + } +} diff --git a/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/de-base/lang/index.js b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/de-base/lang/index.js new file mode 100644 index 0000000000..e50d0478e6 --- /dev/null +++ b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/de-base/lang/index.js @@ -0,0 +1,49 @@ +import Vue from 'vue' +import VueI18n from 'vue-i18n' +import Cookies from 'js-cookie' +import elementEnLocale from 'element-ui/lib/locale/lang/en' // element-ui lang +import elementZhLocale from 'element-ui/lib/locale/lang/zh-CN'// element-ui lang +import elementTWLocale from 'element-ui/lib/locale/lang/zh-TW'// element-ui lang + +import localMessages from './messages' + + +Vue.use(VueI18n) + +const messages = { + en_US: { + ...localMessages['en_US'], + ...elementEnLocale + }, + zh_CN: { + ...localMessages['zh_CN'], + ...elementZhLocale + }, + zh_TW: { + ...localMessages['zh_TW'], + ...elementTWLocale + } +} +export function getLanguage () { + const chooseLanguage = Cookies.get('language') + if (chooseLanguage) return chooseLanguage + + // if has not choose language + const language = (navigator.language || navigator.browserLanguage).toLowerCase() + const locales = Object.keys(messages) + for (const locale of locales) { + if (language.indexOf(locale) > -1) { + return locale + } + } + return 'zh_CN' +} +const i18n = new VueI18n({ + // set locale + // options: en | zh | es + locale: getLanguage(), + // set locale messages + messages +}) + +export default i18n diff --git a/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/de-base/lang/messages.js b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/de-base/lang/messages.js new file mode 100644 index 0000000000..844f8c0673 --- /dev/null +++ b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/de-base/lang/messages.js @@ -0,0 +1,17 @@ +import enLocale from './en' +import zhLocale from './zh' +import twLocale from './tw' + +const messages = { + en_US: { + ...enLocale + }, + zh_CN: { + ...zhLocale + }, + zh_TW: { + ...twLocale + } +} + +export default messages \ No newline at end of file diff --git a/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/de-base/lang/tw.js b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/de-base/lang/tw.js new file mode 100644 index 0000000000..de6b2135d0 --- /dev/null +++ b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/de-base/lang/tw.js @@ -0,0 +1,23 @@ +export default { + plugin_view_sankey: { + type_title: '桑基圖', + source: '源', + target: '目標', + map_type: '類型', + link_line: '連線', + mark_size: '權重', + label: '區域', + angle: '符號', + marker: '標記', + pentagon: '五邊形', + hexagon: '六邊形', + + octagon: '八邊形', + hexagram: '六角星', + border: '邊框', + light: '亮色', + dark: '暗色', + label_format_tip: '可以${fieldName}的形式讀取字段值,標籤和提示中的字段互相通用,內置經緯度相關字段', + tooltip_format_tip: '可以${fieldName}的形式讀取字段值,標籤和提示中的字段互相通用,內置經緯度相關字段(標籤不支持換行)', + } +} diff --git a/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/de-base/lang/zh.js b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/de-base/lang/zh.js new file mode 100644 index 0000000000..3258839384 --- /dev/null +++ b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/de-base/lang/zh.js @@ -0,0 +1,21 @@ +export default { + plugin_view_sankey: { + type_title: '桑基图', + source: '源', + target: '目标', + map_type: '类型', + link_line: '连线', + mark_size: '权重', + angle: '符号', + marker: '标记', + pentagon: '五角形', + hexagon: '六角形', + octagon: '八角形', + hexagram: '六角星', + border: '边框', + light: '亮色', + dark: '暗色', + label_format_tip: '可以${fieldName}的形式读取字段值,标签和提示中的字段互相通用,内置经纬度相关字段', + tooltip_format_tip: '可以${fieldName}的形式读取字段值,标签和提示中的字段互相通用,内置经纬度相关字段(标签不支持换行)', + } +} diff --git a/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/icons/index.js b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/icons/index.js new file mode 100644 index 0000000000..2c6b309c96 --- /dev/null +++ b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/icons/index.js @@ -0,0 +1,9 @@ +import Vue from 'vue' +import SvgIcon from '@/components/SvgIcon'// svg component + +// register globally +Vue.component('svg-icon', SvgIcon) + +const req = require.context('./svg', false, /\.svg$/) +const requireAll = requireContext => requireContext.keys().map(requireContext) +requireAll(req) diff --git a/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/icons/svg/sankey.svg b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/icons/svg/sankey.svg new file mode 100644 index 0000000000..a07394207c --- /dev/null +++ b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/icons/svg/sankey.svg @@ -0,0 +1 @@ + diff --git a/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/icons/svg/view-sankey-backend.svg b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/icons/svg/view-sankey-backend.svg new file mode 100644 index 0000000000..becfdb6caf --- /dev/null +++ b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/icons/svg/view-sankey-backend.svg @@ -0,0 +1 @@ +【icon】插件管理-导出 \ No newline at end of file diff --git a/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/icons/svgo.yml b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/icons/svgo.yml new file mode 100644 index 0000000000..e69de29bb2 diff --git a/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/main.js b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/main.js new file mode 100644 index 0000000000..b1d6ebdf5f --- /dev/null +++ b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/main.js @@ -0,0 +1,36 @@ +// The Vue build version to load with the `import` command +// (runtime-only or standalone) has been set in webpack.base.conf with an alias. +import Vue from 'vue' +import App from './App' +import router from './router' +import ElementUI from 'element-ui' +import Cookies from 'js-cookie' +import i18n from './de-base/lang' +import draggable from 'vuedraggable' +import Treeselect from '@riophae/vue-treeselect' +import '@riophae/vue-treeselect/dist/vue-treeselect.css' +import '@/icons' // icon +import { GaodeMap } from '@antv/l7-maps' +Vue.config.productionTip = false +Vue.use(ElementUI, { + size: Cookies.get('size') || 'medium', + i18n: (key, value) => i18n.t(key, value) +}) +Vue.component('Treeselect', Treeselect) +Vue.component('draggable', draggable) +Vue.prototype.hasDataPermission = function(pTarget, pSource) { + + if (pSource && pTarget) { + return pSource.indexOf(pTarget) > -1 + } + return false +} +Vue.prototype.$gaodeMap = GaodeMap +/* eslint-disable no-new */ +new Vue({ + el: '#app', + router, + i18n, + components: { App }, + template: '' +}) diff --git a/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/router/index.js b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/router/index.js new file mode 100644 index 0000000000..30a99f3140 --- /dev/null +++ b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/router/index.js @@ -0,0 +1,21 @@ +import Vue from 'vue' +import Router from 'vue-router' +import HelloWorld from '@/components/HelloWorld' +import SymbolMap from '@/views/antv/sankey/type' + +Vue.use(Router) + +export default new Router({ + routes: [ + { + path: '/', + name: 'HelloWorld', + component: HelloWorld + }, + { + path: '/sankey', + name: 'sankey', + component: SymbolMap + } + ] +}) diff --git a/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/utils/clickoutside.js b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/utils/clickoutside.js new file mode 100644 index 0000000000..fb030a98eb --- /dev/null +++ b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/utils/clickoutside.js @@ -0,0 +1,68 @@ +const nodeList = []; +const ctx = '@@clickoutsideContext'; + +let startClick; +let seed = 0; + + +function createDocumentHandler(el, binding, vnode) { + return function(mouseup = {}, mousedown = {}) { + if (!vnode || + !vnode.context || + !mouseup.target || + !mousedown.target || + el.contains(mouseup.target) || + el.contains(mousedown.target) || + el === mouseup.target || + (vnode.context.popperElm && + (vnode.context.popperElm.contains(mouseup.target) || + vnode.context.popperElm.contains(mousedown.target)))) return; + + if (binding.expression && + el[ctx].methodName && + vnode.context[el[ctx].methodName]) { + vnode.context[el[ctx].methodName](); + } else { + el[ctx].bindingFn && el[ctx].bindingFn(); + } + }; +} + +/** + * v-clickoutside + * @desc 点击元素外面才会触发的事件 + * @example + * ```vue + *
+ * ``` + */ +export default { + bind(el, binding, vnode) { + nodeList.push(el); + const id = seed++; + el[ctx] = { + id, + documentHandler: createDocumentHandler(el, binding, vnode), + methodName: binding.expression, + bindingFn: binding.value + }; + }, + + update(el, binding, vnode) { + el[ctx].documentHandler = createDocumentHandler(el, binding, vnode); + el[ctx].methodName = binding.expression; + el[ctx].bindingFn = binding.value; + }, + + unbind(el) { + let len = nodeList.length; + + for (let i = 0; i < len; i++) { + if (nodeList[i][ctx].id === el[ctx].id) { + nodeList.splice(i, 1); + break; + } + } + delete el[ctx]; + } +}; diff --git a/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/utils/compare.js b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/utils/compare.js new file mode 100644 index 0000000000..b06a104a10 --- /dev/null +++ b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/utils/compare.js @@ -0,0 +1,29 @@ +export const compareItem = { + type: 'none', // year-yoy/month-yoy等 + resultData: 'percent', // 对比差sub,百分比percent等 + field: '', + custom: { + field: '', + calcType: '0', // 0-增长值,1-增长率 + timeType: '0', // 0-固定日期,1-日期区间 + currentTime: '', + compareTime: '', + currentTimeRange: [], + compareTimeRange: [] + } +} + +export const compareYearList = [ + { name: 'year_mom', value: 'year_mom' } +] + +export const compareMonthList = [ + { name: 'month_mom', value: 'month_mom' }, + { name: 'year_yoy', value: 'year_yoy' } +] + +export const compareDayList = [ + { name: 'day_mom', value: 'day_mom' }, + { name: 'month_yoy', value: 'month_yoy' }, + { name: 'year_yoy', value: 'year_yoy' } +] diff --git a/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/utils/map.js b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/utils/map.js new file mode 100644 index 0000000000..d8fd412e2f --- /dev/null +++ b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/utils/map.js @@ -0,0 +1,469 @@ +export const DEFAULT_COLOR_CASE = { + value: 'default', + colors: ['#5470c6', '#91cc75', '#fac858', '#ee6666', '#73c0de', '#3ba272', '#fc8452', '#9a60b4', '#ea7ccc'], + alpha: 100, + tableHeaderBgColor: '#e1eaff', + tableItemBgColor: '#ffffff', + tableFontColor: '#000000', + tableStripe: true, + dimensionColor: '#000000', + quotaColor: '#000000', + tableBorderColor: '#cfdaf4' +} +export const DEFAULT_SIZE = { + barDefault: true, + barWidth: 40, + barGap: 0.4, + lineWidth: 2, + lineType: 'solid', + lineSymbol: 'marker', + lineSymbolSize: 4, + lineSmooth: true, + lineArea: false, + pieInnerRadius: 0, + pieOuterRadius: 80, + pieRoseType: 'radius', + pieRoseRadius: 5, + funnelWidth: 80, + radarShape: 'polygon', + radarSize: 80, + tableTitleFontSize: 12, + tableItemFontSize: 12, + tableTitleHeight: 36, + tableItemHeight: 36, + tablePageSize: '20', + tableColumnMode: 'custom', + tableColumnWidth: 100, + tableHeaderAlign: 'left', + tableItemAlign: 'right', + gaugeMin: 0, + gaugeMax: 100, + gaugeStartAngle: 225, + gaugeEndAngle: -45, + dimensionFontSize: 18, + quotaFontSize: 18, + spaceSplit: 10, + dimensionShow: true, + quotaShow: true, + scatterSymbol: 'marker', + scatterSymbolSize: 15, + symbolOpacity: 5, + symbolStrokeWidth: 1, + treemapWidth: 80, + treemapHeight: 80, + liquidMax: 100, + liquidSize: 80, + liquidOutlineBorder: 4, + liquidOutlineDistance: 8, + liquidWaveLength: 128, + liquidWaveCount: 3, + liquidShape: 'circle', + tablePageMode: 'page' +} +export const COLOR_PANEL = [ + '#ff4500', + '#ff8c00', + '#ffd700', + '#90ee90', + '#00ced1', + '#1e90ff', + '#c71585', + '#999999', + '#000000', + '#FFFFFF' +] + +export const DEFAULT_LABEL = { + show: true, + position: 'middle', + color: '#000000', + fontSize: '10', + formatter: '{c}', + gaugeFormatter: '{value}', + labelLine: { + show: true + }, + fields: null, + labelTemplate: '{busiValue}', + initialized: true +} +export const DEFAULT_TOOLTIP = { + show: true, + trigger: 'item', + confine: true, + textStyle: { + fontSize: '10', + color: '#909399' + }, + backgroundColor: '#ffffff', + formatter: '', + tooltipTemplate: '{busiValue}' +} +export const DEFAULT_TITLE_STYLE = { + show: true, + fontSize: '18', + color: '#000000', + hPosition: 'left', + vPosition: 'top', + isItalic: false, + isBolder: true, + remarkShow: false, + remark: '', + remarkBackgroundColor: '#ffffffff', + fontFamily: 'Microsoft YaHei', + letterSpace: '0', + fontShadow: false +} +export const DEFAULT_LEGEND_STYLE = { + show: true, + hPosition: 'center', + vPosition: 'bottom', + orient: 'horizontal', + icon: 'circle', + textStyle: { + color: '#333333', + fontSize: '12' + } +} +export const DEFAULT_BACKGROUND_COLOR = { + color: '#ffffff', + alpha: 100, + borderRadius: 5 +} +export const DEFAULT_BASE_MAP_STYLE = { + baseMapTheme: 'light' +} +export const BASE_MAP = { + title: { + text: '', + textStyle: { + fontWeight: 'normal' + } + }, + visualMap: { + min: 50, + max: 52, + text: ['High', 'Low'], + realtime: false, + calculable: true, + inRange: { + color: ['lightskyblue', 'yellow', 'orangered'] + }, + right: 0 + }, + + tooltip: {}, + geo: [ + { + show: true, + map: 'BUDDLE_MAP_BORDER', + + emphasis: { + disabled: true + }, + itemStyle: { + borderWidth: 2, + borderColor: '#d1d1d1', + borderType: 'solid' + }, + + roam: false + }, + { + show: true, + map: 'BUDDLE_MAP', + label: { + normal: { + show: false + }, + emphasis: { + show: false + } + }, + itemStyle: { + areaColor: '#f3f3f3', + borderType: 'dashed', + borderColor: '#fff' + }, + + roam: false + } + ], + series: [ + { + name: '', + type: 'scatter', + coordinateSystem: 'geo', + data: [] + } + ] +} + +export const compareItem = { + type: 'none', // year-yoy/month-yoy等 + resultData: 'percent', // 对比差sub,百分比percent等 + field: '', + custom: { + field: '', + calcType: '0', // 0-增长值,1-增长率 + timeType: '0', // 0-固定日期,1-日期区间 + currentTime: '', + compareTime: '', + currentTimeRange: [], + compareTimeRange: [] + } +} + +export const formatterItem = { + type: 'auto', // auto,value,percent + unit: 1, // 换算单位 + suffix: '', // 单位后缀 + decimalCount: 2, // 小数位数 + thousandSeparator: true// 千分符 +} + +const convertData = (mapData, chart) => { + let maxVal = 0 + const k = terminalType === 'pc' ? 30 : 15 + const names = chart.data.x + const results = [] + for (let index = 0; index < names.length; index++) { + const name = names[index]; + const item = chart.data.series[0].data[index] + results.push({ + name, + value: (mapData[name] ? mapData[name].concat(item.value) : []), + dimensionList: item.dimensionList, + quotaList: item.quotaList + }) + maxVal = Math.max(maxVal, item.value) + } + const rate = k / maxVal + + return { + value: results, + rate: rate + } +} + +let terminalType = 'pc' + +export function baseMapOption(chart_option, chart, mapData, terminal = 'pc') { + terminalType = terminal + // 处理shape attr + let customAttr = {} + if (chart.customAttr) { + customAttr = JSON.parse(chart.customAttr) + if (customAttr.color) { + chart_option.color = customAttr.color.colors + } + // tooltip + if (customAttr.tooltip) { + const tooltip = JSON.parse(JSON.stringify(customAttr.tooltip)) + const reg = new RegExp('\n', 'g') + const text = tooltip.formatter.replace(reg, '
') + tooltip.formatter = function (params) { + const a = params.seriesName + const b = params.name + const c = params.value ? params.value[2] : '' + return text.replace(new RegExp('{a}', 'g'), a).replace(new RegExp('{b}', 'g'), b).replace(new RegExp('{c}', 'g'), c) + } + chart_option.tooltip = tooltip + } + } + // 处理data + if (chart.data) { + chart_option.title.text = chart.title + if (chart.data.series && chart.data.series.length > 0) { + chart_option.series[0].name = chart.data.series[0].name + // label + if (customAttr.label) { + const text = customAttr.label.formatter + chart_option.series[0].label = customAttr.label + chart_option.series[0].label.formatter = function (params) { + const a = params.seriesName + const b = params.name + const c = params.value ? params.value[2] : '' + return text.replace(new RegExp('{a}', 'g'), a).replace(new RegExp('{b}', 'g'), b).replace(new RegExp('{c}', 'g'), c) + } + chart_option.series[0].labelLine = customAttr.label.labelLine + } + + // visualMap + const valueArr = chart.data.series[0].data + if (valueArr && valueArr.length > 0) { + const values = [] + valueArr.forEach(function (ele) { + values.push(ele.value) + }) + chart_option.visualMap.min = Math.min(...values) + chart_option.visualMap.max = Math.max(...values) + if (chart_option.visualMap.min === chart_option.visualMap.max) { + chart_option.visualMap.min = 0 + } + } else { + chart_option.visualMap.min = 0 + chart_option.visualMap.max = 0 + } + if (chart_option.visualMap.min === 0 && chart_option.visualMap.max === 0) { + chart_option.visualMap.max = 100 + } + // color + if (customAttr.color && customAttr.color.colors) { + chart_option.visualMap.inRange.color = customAttr.color.colors + chart_option.visualMap.inRange.colorAlpha = customAttr.color.alpha / 100 + } + // chart_option.visualMap = null + + const convert = convertData(mapData, chart) + chart_option.series[0].data = convert.value + chart_option.series[0].symbolSize = val => val[2] * convert.rate + + } + } + // console.log(chart_option); + componentStyle(chart_option, chart) + return chart_option +} + +export function componentStyle(chart_option, chart) { + const padding = '8px' + if (chart.customStyle) { + const customStyle = JSON.parse(chart.customStyle) + if (customStyle.text) { + chart_option.title.show = customStyle.text.show + // 水平方向 + if (customStyle.text.hPosition === 'left') { + chart_option.title.left = padding + } else if (customStyle.text.hPosition === 'right') { + chart_option.title.right = padding + } else { + chart_option.title.left = customStyle.text.hPosition + } + // 垂直方向 + if (customStyle.text.vPosition === 'top') { + chart_option.title.top = padding + } else if (customStyle.text.vPosition === 'bottom') { + chart_option.title.bottom = padding + } else { + chart_option.title.top = customStyle.text.vPosition + } + const style = chart_option.title.textStyle ? chart_option.title.textStyle : {} + style.fontSize = customStyle.text.fontSize + style.color = customStyle.text.color + customStyle.text.isItalic ? style.fontStyle = 'italic' : style.fontStyle = 'normal' + customStyle.text.isBolder ? style.fontWeight = 'bold' : style.fontWeight = 'normal' + chart_option.title.textStyle = style + } + if (customStyle.legend && chart_option.legend) { + chart_option.legend.show = customStyle.legend.show + // 水平方向 + if (customStyle.legend.hPosition === 'left') { + chart_option.legend.left = padding + } else if (customStyle.legend.hPosition === 'right') { + chart_option.legend.right = padding + } else { + chart_option.legend.left = customStyle.legend.hPosition + } + // 垂直方向 + if (customStyle.legend.vPosition === 'top') { + chart_option.legend.top = padding + } else if (customStyle.legend.vPosition === 'bottom') { + chart_option.legend.bottom = padding + } else { + chart_option.legend.top = customStyle.legend.vPosition + } + chart_option.legend.orient = customStyle.legend.orient + chart_option.legend.icon = customStyle.legend.icon + chart_option.legend.textStyle = customStyle.legend.textStyle + + } + + if (customStyle.background) { + chart_option.backgroundColor = hexColorToRGBA(customStyle.background.color, customStyle.background.alpha) + } + } +} + +export function hexColorToRGBA(hex, alpha) { + const rgb = [] // 定义rgb数组 + if (/^\#[0-9A-F]{3}$/i.test(hex)) { // 判断传入是否为#三位十六进制数 + let sixHex = '#' + hex.replace(/[0-9A-F]/ig, function (kw) { + sixHex += kw + kw // 把三位16进制数转化为六位 + }) + hex = sixHex // 保存回hex + } + if (/^#[0-9A-F]{6}$/i.test(hex)) { // 判断传入是否为#六位十六进制数 + hex.replace(/[0-9A-F]{2}/ig, function (kw) { + // eslint-disable-next-line no-eval + rgb.push(eval('0x' + kw)) // 十六进制转化为十进制并存如数组 + }) + return `rgba(${rgb.join(',')},${alpha / 100})` // 输出RGB格式颜色 + } else { + return 'rgb(0,0,0)' + } +} + + +export const DEFAULT_YAXIS_EXT_STYLE = { + show: true, + position: 'right', + name: '', + nameTextStyle: { + color: '#333333', + fontSize: 12 + }, + axisLabel: { + show: true, + color: '#333333', + fontSize: '12', + rotate: 0, + formatter: '{value}' + }, + splitLine: { + show: true, + lineStyle: { + color: '#cccccc', + width: 1, + style: 'solid' + } + }, + axisValue: { + auto: true, + min: null, + max: null, + split: null, + splitCount: null + } +} + +export const getDefaultTemplate = (chart, type, feed, showKey) => { + if (!chart || !chart.viewFields || !type) return null; + let viewFields = [] + if (chart.viewFields instanceof Array) { + viewFields = JSON.parse(JSON.stringify(chart.viewFields)) + } else { + viewFields = JSON.parse(chart.viewFields) + } + const separator = feed ? '\n' : ' ' + return viewFields.filter(field => field.busiType && field.busiType === type).map(field => { + const fieldName = field.name + let template = "${" + field.name + "}" + if (showKey) { + template = fieldName + ":${" + field.name + "}" + } + return template + }).join(separator) +} + +export function uuid() { + return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1); +} + +export const reverseColor = colorValue => { + colorValue = '0x' + colorValue.replace(/#/g, '') + const str = '000000' + (0xFFFFFF - colorValue).toString(16) + return '#' + str.substring(str.length - 6, str.length) +} + diff --git a/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/utils/sankey.js b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/utils/sankey.js new file mode 100644 index 0000000000..697800dd8d --- /dev/null +++ b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/utils/sankey.js @@ -0,0 +1,73 @@ +// import {PointLayer, Popup } from '@antv/l7'; + +export const DEFAULT_COLOR_CASE = { + value: 'default', + colors: ['#5470c6', '#91cc75', '#fac858', '#ee6666', '#73c0de', '#3ba272', '#fc8452', '#9a60b4', '#ea7ccc'], + alpha: 100, + tableHeaderBgColor: '#e1eaff', + tableItemBgColor: '#ffffff', + tableFontColor: '#000000', + tableStripe: true, + dimensionColor: '#000000', + quotaColor: '#000000', + tableBorderColor: '#cfdaf4' +} + +export const COLOR_PANEL = [ + '#ff4500', + '#ff8c00', + '#ffd700', + '#90ee90', + '#00ced1', + '#1e90ff', + '#c71585', + '#999999', + '#000000', + '#FFFFFF' +] + + +export const DEFAULT_BACKGROUND_COLOR = { + color: '#ffffff', + alpha: 100, + borderRadius: 5 +} + + + + +export function baseSymbolMap(scene, container, chart, action, $pointLayer, $popup) { + let _self = this + + +} + + +export function hexColorToRGBA(hex, alpha) { + const rgb = [] // 定义rgb数组 + if (/^\#[0-9A-F]{3}$/i.test(hex)) { // 判断传入是否为#三位十六进制数 + let sixHex = '#' + hex.replace(/[0-9A-F]/ig, function(kw) { + sixHex += kw + kw // 把三位16进制数转化为六位 + }) + hex = sixHex // 保存回hex + } + if (/^#[0-9A-F]{6}$/i.test(hex)) { // 判断传入是否为#六位十六进制数 + hex.replace(/[0-9A-F]{2}/ig, function(kw) { + // eslint-disable-next-line no-eval + rgb.push(eval('0x' + kw)) // 十六进制转化为十进制并存如数组 + }) + return `rgba(${rgb.join(',')},${alpha / 100})` // 输出RGB格式颜色 + } else { + return 'rgb(0,0,0)' + } +} + + + + + +export function uuid() { + return (((1+Math.random())*0x10000)|0).toString(16).substring(1); +} + diff --git a/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/utils/validate.js b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/utils/validate.js new file mode 100644 index 0000000000..3e8ffa9448 --- /dev/null +++ b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/utils/validate.js @@ -0,0 +1,15 @@ +/** + * Created by PanJiaChen on 16/11/18. + */ + +/** + * @param {string} path + * @returns {Boolean} + */ +export function isExternal(path) { + return /^(https?:|mailto:|tel:)/.test(path) || /^(http?:|mailto:|tel:)/.test(path) || path.startsWith('/api/pluginCommon/staticInfo') +} + + + + diff --git a/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/views/PluginDemo.vue b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/views/PluginDemo.vue new file mode 100644 index 0000000000..1164dfab1d --- /dev/null +++ b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/views/PluginDemo.vue @@ -0,0 +1,55 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/views/antv/sankey/data.vue b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/views/antv/sankey/data.vue new file mode 100644 index 0000000000..8c91a0b4ab --- /dev/null +++ b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/views/antv/sankey/data.vue @@ -0,0 +1,717 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/views/antv/sankey/index.vue b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/views/antv/sankey/index.vue new file mode 100644 index 0000000000..799b4aa88e --- /dev/null +++ b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/views/antv/sankey/index.vue @@ -0,0 +1,527 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/views/antv/sankey/style.vue b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/views/antv/sankey/style.vue new file mode 100644 index 0000000000..34a13fcf87 --- /dev/null +++ b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/views/antv/sankey/style.vue @@ -0,0 +1,175 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/views/antv/sankey/type.vue b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/views/antv/sankey/type.vue new file mode 100644 index 0000000000..29e668e134 --- /dev/null +++ b/extensions/dataease-extensions-view/view-sankey/view-sankey-frontend/src/views/antv/sankey/type.vue @@ -0,0 +1,63 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-symbolmap/build.sh b/extensions/dataease-extensions-view/view-symbolmap/build.sh new file mode 100644 index 0000000000..b3f74b429f --- /dev/null +++ b/extensions/dataease-extensions-view/view-symbolmap/build.sh @@ -0,0 +1,8 @@ +#!/bin/sh +mvn clean package + +cp view-symbolmap-backend/target/view-symbolmap-backend-1.18.3.jar . + +zip -r symbolmap.zip ./view-symbolmap-backend-1.18.3.jar ./plugin.json + +rm -f ./view-symbolmap-backend-1.18.3.jar diff --git a/extensions/dataease-extensions-view/view-symbolmap/plugin.json b/extensions/dataease-extensions-view/view-symbolmap/plugin.json new file mode 100644 index 0000000000..a015116b9f --- /dev/null +++ b/extensions/dataease-extensions-view/view-symbolmap/plugin.json @@ -0,0 +1,13 @@ +{ + "name": "符号地图", + "free": 0, + "store": "thirdpart", + "cost": 0, + "category": "view", + "descript": "AntV L7 符号地图插件", + "version": "1.18.3", + "creator": "DATAEASE", + "moduleName": "view-symbolmap-backend", + "require": "1.10.0", + "dsType": "" +} \ No newline at end of file diff --git a/extensions/dataease-extensions-view/view-symbolmap/pom.xml b/extensions/dataease-extensions-view/view-symbolmap/pom.xml new file mode 100644 index 0000000000..51c5253fca --- /dev/null +++ b/extensions/dataease-extensions-view/view-symbolmap/pom.xml @@ -0,0 +1,20 @@ + + + + dataease-extensions-view + io.dataease + ${dataease.version} + + 4.0.0 + + view-symbolmap + pom + + view-symbolmap-frontend + view-symbolmap-backend + + + + diff --git a/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-backend/pom.xml b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-backend/pom.xml new file mode 100644 index 0000000000..7f9f77bce6 --- /dev/null +++ b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-backend/pom.xml @@ -0,0 +1,109 @@ + + + + view-symbolmap + io.dataease + ${dataease.version} + + 4.0.0 + + view-symbolmap-backend + + + + io.dataease + dataease-plugin-view + + + + + + + src/main/java + + **/*.properties + **/*.xml + + false + + + src/main/resources + + **/* + + false + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 11 + 11 + + + + + org.apache.maven.plugins + maven-jar-plugin + 2.4 + + + **/server/** + **/*.properties + **/Application* + + + + + + maven-clean-plugin + + + + src/main/resources/static + + ** + + false + + + + + + + + + org.apache.maven.plugins + maven-antrun-plugin + + + main-class-placement + generate-resources + + + + + + + + + + + + run + + + + + + + + + + + diff --git a/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-backend/src/main/java/io/dataease/plugins/view/official/dto/SymbolMapResultDTO.java b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-backend/src/main/java/io/dataease/plugins/view/official/dto/SymbolMapResultDTO.java new file mode 100644 index 0000000000..63a1189dc1 --- /dev/null +++ b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-backend/src/main/java/io/dataease/plugins/view/official/dto/SymbolMapResultDTO.java @@ -0,0 +1,18 @@ +package io.dataease.plugins.view.official.dto; + +import java.util.Map; + +import io.dataease.plugins.common.dto.chart.AxisChartDataAntVDTO; +import lombok.Data; + +@Data +public class SymbolMapResultDTO extends AxisChartDataAntVDTO { + + private String longitude; + + private String latitude; + + private Object busiValue; + + private Map properties; +} diff --git a/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-backend/src/main/java/io/dataease/plugins/view/official/handler/SymbolMapRSHandler.java b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-backend/src/main/java/io/dataease/plugins/view/official/handler/SymbolMapRSHandler.java new file mode 100644 index 0000000000..3c83a67450 --- /dev/null +++ b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-backend/src/main/java/io/dataease/plugins/view/official/handler/SymbolMapRSHandler.java @@ -0,0 +1,142 @@ +package io.dataease.plugins.view.official.handler; + +import io.dataease.plugins.common.dto.chart.AxisChartDataAntVDTO; +import io.dataease.plugins.common.dto.chart.ChartDimensionDTO; +import io.dataease.plugins.common.dto.chart.ChartQuotaDTO; +import io.dataease.plugins.view.entity.*; +import io.dataease.plugins.view.handler.PluginViewRSHandler; +import io.dataease.plugins.view.official.dto.SymbolMapResultDTO; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Component; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.annotation.PostConstruct; + +@Component +public class SymbolMapRSHandler implements PluginViewRSHandler { + + private static List trans2Ykeys = new ArrayList(); + + @PostConstruct + public void init() { + trans2Ykeys.add("labelAxis"); + trans2Ykeys.add("tooltipAxis"); + } + + public List getTrans2Ykeys() { + return trans2Ykeys; + } + + @Override + public Map format(PluginViewParam pluginViewParam, List data, boolean isDrill) { + List xAxis = new ArrayList<>(); + List yAxis = new ArrayList<>(); + + pluginViewParam.getPluginViewFields().forEach(pluginViewField -> { + if (StringUtils.equals(pluginViewField.getTypeField(), "xAxis")) { + xAxis.add(pluginViewField); + } + if (StringUtils.equals(pluginViewField.getTypeField(), "yAxis") + || trans2Ykeys.contains(pluginViewField.getTypeField())) { + yAxis.add(pluginViewField); + } + }); + Map map = new HashMap<>(); + List datalist = new ArrayList<>(); + + for (int i1 = 0; i1 < data.size(); i1++) { + String[] row = data.get(i1); + + StringBuilder a = new StringBuilder(); + if (isDrill) { + a.append(row[xAxis.size() - 1]); + } else { + for (int i = 0; i < xAxis.size(); i++) { + if (i == xAxis.size() - 1) { + a.append(row[i]); + } else { + a.append(row[i]).append("\n"); + } + } + } + + if (CollectionUtils.isEmpty(yAxis)) { + for (int i = 0; i < xAxis.size() + yAxis.size(); i++) { + SymbolMapResultDTO axisChartDataDTO = new SymbolMapResultDTO(); + axisChartDataDTO.setField(a.toString()); + axisChartDataDTO.setName(a.toString()); + + List dimensionList = new ArrayList<>(); + List quotaList = new ArrayList<>(); + + for (int j = 0; j < xAxis.size(); j++) { + ChartDimensionDTO chartDimensionDTO = new ChartDimensionDTO(); + chartDimensionDTO.setId(xAxis.get(j).getId()); + chartDimensionDTO.setValue(row[j]); + dimensionList.add(chartDimensionDTO); + } + axisChartDataDTO.setDimensionList(dimensionList); + + int j = i - xAxis.size(); + if (j > -1) { + ChartQuotaDTO chartQuotaDTO = new ChartQuotaDTO(); + chartQuotaDTO.setId(yAxis.get(j).getId()); + quotaList.add(chartQuotaDTO); + axisChartDataDTO.setQuotaList(quotaList); + try { + axisChartDataDTO.setBusiValue(row[i]); + axisChartDataDTO.setValue(StringUtils.isEmpty(row[i]) ? null : new BigDecimal(row[i])); + } catch (Exception e) { + axisChartDataDTO.setValue(new BigDecimal(0)); + } + axisChartDataDTO.setCategory(yAxis.get(j).getName()); + } + axisChartDataDTO.setLongitude(dimensionList.get(0).getValue()); + axisChartDataDTO.setLatitude(dimensionList.get(1).getValue()); + datalist.add(axisChartDataDTO); + } + } else { + SymbolMapResultDTO axisChartDataDTO = new SymbolMapResultDTO(); + axisChartDataDTO.setField(a.toString()); + axisChartDataDTO.setName(a.toString()); + + List dimensionList = new ArrayList<>(); + + for (int j = 0; j < xAxis.size(); j++) { + ChartDimensionDTO chartDimensionDTO = new ChartDimensionDTO(); + chartDimensionDTO.setId(xAxis.get(j).getId()); + chartDimensionDTO.setValue(row[j]); + dimensionList.add(chartDimensionDTO); + } + axisChartDataDTO.setDimensionList(dimensionList); + axisChartDataDTO.setQuotaList(new ArrayList<>()); + axisChartDataDTO.setProperties(new HashMap<>()); + int step = xAxis.size(); + Boolean valueFilled = false; + for (int i = 0; i < yAxis.size(); i++) { + PluginViewField curY = yAxis.get(i); + ChartQuotaDTO chartQuotaDTO = new ChartQuotaDTO(); + chartQuotaDTO.setId(curY.getId()); + axisChartDataDTO.getQuotaList().add(chartQuotaDTO); + axisChartDataDTO.getProperties().put(curY.getName(), row[i + step]); + axisChartDataDTO.setLongitude(dimensionList.get(0).getValue()); + axisChartDataDTO.setLatitude(dimensionList.get(1).getValue()); + if (StringUtils.equals(curY.getTypeField(), "yAxis") && !valueFilled) { + axisChartDataDTO.setCategory(curY.getName()); + axisChartDataDTO.setBusiValue(row[i + step]); + valueFilled = true; + } + } + datalist.add(axisChartDataDTO); + } + } + map.put("data", datalist); + return map; + } +} diff --git a/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-backend/src/main/java/io/dataease/plugins/view/official/handler/SymbolMapStatHandler.java b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-backend/src/main/java/io/dataease/plugins/view/official/handler/SymbolMapStatHandler.java new file mode 100644 index 0000000000..76f02f9de4 --- /dev/null +++ b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-backend/src/main/java/io/dataease/plugins/view/official/handler/SymbolMapStatHandler.java @@ -0,0 +1,101 @@ +package io.dataease.plugins.view.official.handler; + +import io.dataease.plugins.common.constants.datasource.SQLConstants; +import io.dataease.plugins.common.util.ConstantsUtil; +import io.dataease.plugins.view.entity.*; +import io.dataease.plugins.view.handler.PluginViewStatHandler; +import io.dataease.plugins.view.service.ViewPluginBaseService; +import io.dataease.plugins.view.service.ViewPluginService; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.ObjectUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Component; +import org.stringtemplate.v4.ST; +import org.stringtemplate.v4.STGroup; +import org.stringtemplate.v4.STGroupFile; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +@Component +public class SymbolMapStatHandler implements PluginViewStatHandler { + + @Override + public String build(PluginViewParam pluginViewParam, ViewPluginService viewPluginService) { + ViewPluginBaseService baseService = viewPluginService.getBaseService(); + PluginViewSet pluginViewSet = pluginViewParam.getPluginViewSet(); + String dsType = pluginViewSet.getDsType(); + PluginViewSQL tableObj = baseService.getTableObj(pluginViewSet); + + Map> fieldSQLMap = new HashMap<>(); + + for (int i = 0; i < pluginViewParam.getPluginViewFields().size(); i++) { + PluginViewField pluginViewField = pluginViewParam.getPluginViewFields().get(i); + String typeKey = pluginViewField.getTypeField(); + PluginSingleField pluginSingleField = baseService.buildField(dsType, pluginViewField, tableObj, i); + List lists = fieldSQLMap.getOrDefault(typeKey, new ArrayList<>()); + lists.add(pluginSingleField); + fieldSQLMap.put(typeKey, lists); + } + + List xFields = fieldSQLMap.get("xAxis").stream() + .filter(singleField -> ObjectUtils.isNotEmpty(singleField.getField())) + .map(singleField -> singleField.getField()).collect(Collectors.toList()); + List xOrders = fieldSQLMap.get("xAxis").stream() + .filter(singleField -> ObjectUtils.isNotEmpty(singleField.getSort())) + .map(singleField -> singleField.getSort()).collect(Collectors.toList()); + + // 处理视图中字段过滤 + String customWheres = baseService.customWhere(dsType, pluginViewParam.getPluginChartFieldCustomFilters(), + tableObj); + // 处理仪表板字段过滤 + String panelWheres = baseService.panelWhere(dsType, pluginViewParam.getPluginChartExtFilters(), tableObj); + // 构建sql所有参数 + + String permissionWhere = baseService.permissionWhere(dsType, pluginViewParam.getRowPermissionsTree(), tableObj); + List wheres = new ArrayList<>(); + if (customWheres != null) + wheres.add(customWheres); + if (panelWheres != null) + wheres.add(panelWheres); + if (StringUtils.isNotBlank(permissionWhere)) { + wheres.add(permissionWhere); + } + List groups = new ArrayList<>(); + groups.addAll(xFields); + // 外层再次套sql + List orders = new ArrayList<>(); + orders.addAll(xOrders); + + STGroup stg = new STGroupFile(SQLConstants.SQL_TEMPLATE); + + ST st_sql = stg.getInstanceOf("previewSql"); + st_sql.add("isGroup", false); + if (CollectionUtils.isNotEmpty(xFields)) + st_sql.add("groups", xFields); + if (CollectionUtils.isNotEmpty(wheres)) + st_sql.add("filters", wheres); + if (ObjectUtils.isNotEmpty(tableObj)) + st_sql.add("table", tableObj); + String sql = st_sql.render(); + + String brackets = ConstantsUtil.constantsValue(dsType, "BRACKETS"); + String table_alias_prefix = ConstantsUtil.constantsValue(dsType, "TABLE_ALIAS_PREFIX"); + + ST st = stg.getInstanceOf("previewSql"); + st.add("isGroup", false); + PluginViewSQL tableSQL = PluginViewSQL.builder() + .tableName(String.format(brackets, sql)) + .tableAlias(String.format(table_alias_prefix, 1)) + .build(); + if (CollectionUtils.isNotEmpty(orders)) + st.add("orders", orders); + if (ObjectUtils.isNotEmpty(tableSQL)) + st.add("table", tableSQL); + return baseService.sqlLimit(dsType, st.render(), pluginViewParam.getPluginViewLimit()); + } + +} diff --git a/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-backend/src/main/java/io/dataease/plugins/view/official/impl/SymbolMapService.java b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-backend/src/main/java/io/dataease/plugins/view/official/impl/SymbolMapService.java new file mode 100644 index 0000000000..a4f5f46d5d --- /dev/null +++ b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-backend/src/main/java/io/dataease/plugins/view/official/impl/SymbolMapService.java @@ -0,0 +1,161 @@ +package io.dataease.plugins.view.official.impl; + +import io.dataease.plugins.common.dto.StaticResource; + +import io.dataease.plugins.view.entity.*; +import io.dataease.plugins.view.official.handler.SymbolMapRSHandler; +import io.dataease.plugins.view.official.handler.SymbolMapStatHandler; +import io.dataease.plugins.view.service.ViewPluginService; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; + +import com.google.common.reflect.TypeToken; +import com.google.gson.Gson; + +import java.io.InputStream; +import java.lang.reflect.Type; +import java.util.*; + +@Service +public class SymbolMapService extends ViewPluginService { + + private static Gson gson = new Gson(); + + @Resource + private SymbolMapStatHandler symbolMapStatHandler; + + @Resource + private SymbolMapRSHandler symbolMapRSHandler; + + private static final String VIEW_TYPE_VALUE = "symbol-map"; + + private static final String[] VIEW_STYLE_PROPERTIES = { + "color-selector", + "size-selector-ant-v", + "tooltip-selector-ant-v", + "title-selector-ant-v" + }; + + private static final Map VIEW_STYLE_PROPERTY_INNER = new HashMap(); + + static { + VIEW_STYLE_PROPERTY_INNER.put("color-selector", new String[] { "value", "alpha" }); + VIEW_STYLE_PROPERTY_INNER.put("size-selector-ant-v", + new String[] { "scatterSymbolSize", "symbolOpacity", "symbolStrokeWidth" }); + // VIEW_STYLE_PROPERTY_INNER.put("size-selector-ant-v", new + // String[]{"scatterSymbol", + // "scatterSymbolSize","symbolOpacity","symbolStrokeWidth"}); + VIEW_STYLE_PROPERTY_INNER.put("tooltip-selector-ant-v", new String[] { "show", "textStyle", "formatter" }); + VIEW_STYLE_PROPERTY_INNER.put("title-selector-ant-v", new String[] { "show", "title", "fontSize", "color", + "hPosition", "vPosition", "isItalic", "isBolder" }); + } + + /* 下版这些常量移到sdk */ + private static final String TYPE = "-type"; + private static final String DATA = "-data"; + private static final String STYLE = "-style"; + private static final String VIEW = "-view"; + private static final String SUFFIX = "svg"; + /* 下版这些常量移到sdk */ + private static final String VIEW_TYPE = VIEW_TYPE_VALUE + TYPE; + private static final String VIEW_DATA = VIEW_TYPE_VALUE + DATA; + private static final String VIEW_STYLE = VIEW_TYPE_VALUE + STYLE; + private static final String VIEW_VIEW = VIEW_TYPE_VALUE + VIEW; + + @Override + public PluginViewType viewType() { + PluginViewType pluginViewType = new PluginViewType(); + pluginViewType.setRender("antv"); + pluginViewType.setCategory("chart.chart_type_space"); + pluginViewType.setValue(VIEW_TYPE_VALUE); + pluginViewType.setProperties(VIEW_STYLE_PROPERTIES); + pluginViewType.setPropertyInner(VIEW_STYLE_PROPERTY_INNER); + return pluginViewType; + } + + @Override + public Object format(Object o) { + return null; + } + + @Override + public List components() { + List results = new ArrayList<>(); + results.add(VIEW_VIEW); + results.add(VIEW_DATA); + results.add(VIEW_TYPE); + results.add(VIEW_STYLE); + return results; + } + + @Override + public List staticResources() { + List results = new ArrayList<>(); + StaticResource staticResource = new StaticResource(); + staticResource.setName(VIEW_TYPE_VALUE); + staticResource.setSuffix(SUFFIX); + results.add(staticResource); + addImage(results); + results.add(pluginSvg()); + return results; + } + + private StaticResource pluginSvg() { + StaticResource staticResource = new StaticResource(); + staticResource.setName("view-symbolmap-backend"); + staticResource.setSuffix("svg"); + return staticResource; + } + + private void addImage(List results) { + StaticResource staticResource = new StaticResource(); + staticResource.setName("map-marker"); + staticResource.setSuffix(SUFFIX); + results.add(staticResource); + } + + @Override + protected InputStream readContent(String s) { + InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream("static/" + s); + return resourceAsStream; + } + + @Override + public String generateSQL(PluginViewParam pluginViewParam) { + Type tokenType = new TypeToken>() { + }.getType(); + + List pluginViewFields = gson.fromJson(gson.toJson(pluginViewParam.getPluginViewFields()), + tokenType); + List trans2Ykeys = symbolMapRSHandler.getTrans2Ykeys(); + pluginViewParam.getPluginViewFields().forEach(field -> { + if (trans2Ykeys.contains(field.getTypeField())) { + field.setTypeField("yAxis"); + } + }); + List xAxis = pluginViewParam.getFieldsByType("xAxis"); + List yAxis = pluginViewParam.getFieldsByType("yAxis"); + if (CollectionUtils.isEmpty(xAxis) || xAxis.size() < 2) { + return null; + } + + if (CollectionUtils.isNotEmpty(yAxis)) { + String generateSQL = super.generateSQL(pluginViewParam); + pluginViewParam.setPluginViewFields(pluginViewFields); + return generateSQL; + } + + // 下面考虑符号大小为空的情况 + String result = symbolMapStatHandler.build(pluginViewParam, this); + // pluginViewParam.setPluginViewFields(pluginViewFields); + return result; + + } + + @Override + public Map formatResult(PluginViewParam pluginViewParam, List data, Boolean isDrill) { + return symbolMapRSHandler.format(pluginViewParam, data, isDrill); + } +} diff --git a/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/.babelrc b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/.babelrc new file mode 100644 index 0000000000..3a280ba34b --- /dev/null +++ b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/.babelrc @@ -0,0 +1,12 @@ +{ + "presets": [ + ["env", { + "modules": false, + "targets": { + "browsers": ["> 1%", "last 2 versions", "not ie <= 8"] + } + }], + "stage-2" + ], + "plugins": ["transform-vue-jsx", "transform-runtime"] +} diff --git a/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/.editorconfig b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/.editorconfig new file mode 100644 index 0000000000..9d08a1a828 --- /dev/null +++ b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/.editorconfig @@ -0,0 +1,9 @@ +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true diff --git a/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/.gitignore b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/.gitignore new file mode 100644 index 0000000000..541a820f6c --- /dev/null +++ b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/.gitignore @@ -0,0 +1,14 @@ +.DS_Store +node_modules/ +/dist/ +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Editor directories and files +.idea +.vscode +*.suo +*.ntvs* +*.njsproj +*.sln diff --git a/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/.postcssrc.js b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/.postcssrc.js new file mode 100644 index 0000000000..eee3e92d7f --- /dev/null +++ b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/.postcssrc.js @@ -0,0 +1,10 @@ +// https://github.com/michael-ciniawsky/postcss-load-config + +module.exports = { + "plugins": { + "postcss-import": {}, + "postcss-url": {}, + // to edit target browsers: use "browserslist" field in package.json + "autoprefixer": {} + } +} diff --git a/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/README.md b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/README.md new file mode 100644 index 0000000000..c1e4be95e0 --- /dev/null +++ b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/README.md @@ -0,0 +1,21 @@ +# deplugin-view-frontend + +> A Vue.js project + +## Build Setup + +``` bash +# install dependencies +npm install + +# serve with hot reload at localhost:8080 +npm run dev + +# build for production with minification +npm run build + +# build for production and view the bundle analyzer report +npm run build --report +``` + +For a detailed explanation on how things work, check out the [guide](http://vuejs-templates.github.io/webpack/) and [docs for vue-loader](http://vuejs.github.io/vue-loader). diff --git a/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/build/build-async-plugins.js b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/build/build-async-plugins.js new file mode 100644 index 0000000000..2303854531 --- /dev/null +++ b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/build/build-async-plugins.js @@ -0,0 +1,35 @@ +'use strict' +require('./check-versions')() + +process.env.NODE_ENV = 'production' + +const ora = require('ora') +const chalk = require('chalk') +const webpack = require('webpack') +const webpackConfig = require('./webpack.async-plugins') + +const spinner = ora('building for sync-plugins...') +spinner.start() + +webpack(webpackConfig, function (err, stats) { + spinner.stop() + if (err) throw err + process.stdout.write(stats.toString({ + colors: true, + modules: false, + children: false, + chunks: false, + chunkModules: false + }) + '\n\n') + + if (stats.hasErrors()) { + console.log(chalk.red(' Build failed with errors.\n')) + process.exit(1) + } + + console.log(chalk.cyan(' Build complete.\n')) + console.log(chalk.yellow( + ' Tip: built files are meant to be served over an HTTP server.\n' + + ' Opening index.html over file:// won\'t work.\n' + )) +}) diff --git a/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/build/build.js b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/build/build.js new file mode 100644 index 0000000000..8f2ad8ad49 --- /dev/null +++ b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/build/build.js @@ -0,0 +1,41 @@ +'use strict' +require('./check-versions')() + +process.env.NODE_ENV = 'production' + +const ora = require('ora') +const rm = require('rimraf') +const path = require('path') +const chalk = require('chalk') +const webpack = require('webpack') +const config = require('../config') +const webpackConfig = require('./webpack.prod.conf') + +const spinner = ora('building for production...') +spinner.start() + +rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => { + if (err) throw err + webpack(webpackConfig, (err, stats) => { + spinner.stop() + if (err) throw err + process.stdout.write(stats.toString({ + colors: true, + modules: false, + children: false, // If you are using ts-loader, setting this to true will make TypeScript errors show up during build. + chunks: false, + chunkModules: false + }) + '\n\n') + + if (stats.hasErrors()) { + console.log(chalk.red(' Build failed with errors.\n')) + process.exit(1) + } + + console.log(chalk.cyan(' Build complete.\n')) + console.log(chalk.yellow( + ' Tip: built files are meant to be served over an HTTP server.\n' + + ' Opening index.html over file:// won\'t work.\n' + )) + }) +}) diff --git a/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/build/check-versions.js b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/build/check-versions.js new file mode 100644 index 0000000000..3ef972a08d --- /dev/null +++ b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/build/check-versions.js @@ -0,0 +1,54 @@ +'use strict' +const chalk = require('chalk') +const semver = require('semver') +const packageConfig = require('../package.json') +const shell = require('shelljs') + +function exec (cmd) { + return require('child_process').execSync(cmd).toString().trim() +} + +const versionRequirements = [ + { + name: 'node', + currentVersion: semver.clean(process.version), + versionRequirement: packageConfig.engines.node + } +] + +if (shell.which('npm')) { + versionRequirements.push({ + name: 'npm', + currentVersion: exec('npm --version'), + versionRequirement: packageConfig.engines.npm + }) +} + +module.exports = function () { + const warnings = [] + + for (let i = 0; i < versionRequirements.length; i++) { + const mod = versionRequirements[i] + + if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) { + warnings.push(mod.name + ': ' + + chalk.red(mod.currentVersion) + ' should be ' + + chalk.green(mod.versionRequirement) + ) + } + } + + if (warnings.length) { + console.log('') + console.log(chalk.yellow('To use this template, you must update following to modules:')) + console.log() + + for (let i = 0; i < warnings.length; i++) { + const warning = warnings[i] + console.log(' ' + warning) + } + + console.log() + process.exit(1) + } +} diff --git a/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/build/logo.png b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/build/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..f3d2503fc2a44b5053b0837ebea6e87a2d339a43 GIT binary patch literal 6849 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 { + const notifier = require('node-notifier') + + return (severity, errors) => { + if (severity !== 'error') return + + const error = errors[0] + const filename = error.file && error.file.split('!').pop() + + notifier.notify({ + title: packageConfig.name, + message: severity + ': ' + error.name, + subtitle: filename || '', + icon: path.join(__dirname, 'logo.png') + }) + } +} diff --git a/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/build/vue-loader.conf.js b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/build/vue-loader.conf.js new file mode 100644 index 0000000000..33ed58bc0a --- /dev/null +++ b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/build/vue-loader.conf.js @@ -0,0 +1,22 @@ +'use strict' +const utils = require('./utils') +const config = require('../config') +const isProduction = process.env.NODE_ENV === 'production' +const sourceMapEnabled = isProduction + ? config.build.productionSourceMap + : config.dev.cssSourceMap + +module.exports = { + loaders: utils.cssLoaders({ + sourceMap: sourceMapEnabled, + extract: isProduction + }), + cssSourceMap: sourceMapEnabled, + cacheBusting: config.dev.cacheBusting, + transformToRequire: { + video: ['src', 'poster'], + source: 'src', + img: 'src', + image: 'xlink:href' + } +} diff --git a/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/build/webpack.async-plugins.js b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/build/webpack.async-plugins.js new file mode 100644 index 0000000000..add7b2a25a --- /dev/null +++ b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/build/webpack.async-plugins.js @@ -0,0 +1,97 @@ +const webpack = require('webpack') +const path = require('path') +const utils = require('./utils') +const CopyPlugin = require("copy-webpack-plugin"); +const VueLoaderPlugin = require('vue-loader/lib/plugin'); +function resolve (dir) { + return path.join(__dirname, '..', dir) +} + +module.exports = { + mode: 'development', + entry: { + + // PluginDemo: resolve('/src/views/PluginDemo.vue') + 'symbol-map-view': resolve('/src/views/antv/symbolmap/index.vue'), + 'symbol-map-data': resolve('/src/views/antv/symbolmap/data.vue'), + 'symbol-map-type': resolve('/src/views/antv/symbolmap/type.vue'), + 'symbol-map-style': resolve('/src/views/antv/symbolmap/style.vue') + + }, + output: { + path: resolve('/static/'), + filename: '[name].js' + }, + resolve: { + extensions: ['.js', '.vue', '.json'], + alias: { + 'vue$': 'vue/dist/vue.esm.js', + '@': resolve('src') + } + }, + externals: { + vue: 'vue' + }, + module: { + rules: [ + { + test: /\.vue$/, + loader: 'vue-loader', + options: { + transformAssetUrls: { + video: 'src', + source: 'src', + img: 'src', + image: 'xlink:href' + } + } + }, + { + test: /.(sa|sc|c)ss$/, + use: [ + {loader: 'vue-style-loader'}, + 'css-loader', + 'sass-loader' + ] + }, + { + test: /\.js$/, + loader: 'babel-loader', + include: [resolve('src'), resolve('test')] + }, + { + test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: utils.assetsPath('img/[name].[hash:7].[ext]') + } + }, + { + test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: utils.assetsPath('media/[name].[hash:7].[ext]') + } + }, + { + test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: utils.assetsPath('fonts/[name].[hash:7].[ext]') + } + } + ] + }, + plugins: [ + new VueLoaderPlugin(), + new webpack.DefinePlugin({ + 'process.env.NODE_ENV': '"production"' + }), + new CopyPlugin([ + {from: 'src/icons/svg/'} + ]), + ] +} diff --git a/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/build/webpack.base.conf.js b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/build/webpack.base.conf.js new file mode 100644 index 0000000000..6ccc02dab4 --- /dev/null +++ b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/build/webpack.base.conf.js @@ -0,0 +1,91 @@ +'use strict' +const path = require('path') +const utils = require('./utils') +const config = require('../config') +const vueLoaderConfig = require('./vue-loader.conf') + +function resolve (dir) { + return path.join(__dirname, '..', dir) +} + + + +module.exports = { + context: path.resolve(__dirname, '../'), + entry: { + app: './src/main.js' + }, + output: { + path: config.build.assetsRoot, + filename: '[name].js', + publicPath: process.env.NODE_ENV === 'production' + ? config.build.assetsPublicPath + : config.dev.assetsPublicPath + }, + resolve: { + extensions: ['.js', '.vue', '.json'], + alias: { + 'vue$': 'vue/dist/vue.esm.js', + '@': resolve('src'), + } + }, + module: { + rules: [ + { + test: /\.vue$/, + loader: 'vue-loader', + options: vueLoaderConfig + }, + { + test: /\.js$/, + loader: 'babel-loader', + include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')] + }, + { + test: /\.svg$/, + loader: 'svg-sprite-loader', + include: [resolve('src/icons')], + options: { + symbolId: 'icon-[name]' + } + }, + { + test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, + loader: 'url-loader', + exclude: [resolve('src/icons')], + options: { + limit: 10000, + name: utils.assetsPath('img/[name].[hash:7].[ext]') + } + }, + { + test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: utils.assetsPath('media/[name].[hash:7].[ext]') + } + }, + { + test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: utils.assetsPath('fonts/[name].[hash:7].[ext]') + } + } + ] + }, + node: { + // prevent webpack from injecting useless setImmediate polyfill because Vue + // source contains it (although only uses it if it's native). + setImmediate: false, + // prevent webpack from injecting mocks to Node native modules + // that does not make sense for the client + dgram: 'empty', + fs: 'empty', + net: 'empty', + tls: 'empty', + child_process: 'empty' + } +} diff --git a/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/build/webpack.dev.conf.js b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/build/webpack.dev.conf.js new file mode 100755 index 0000000000..070ae221f3 --- /dev/null +++ b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/build/webpack.dev.conf.js @@ -0,0 +1,95 @@ +'use strict' +const utils = require('./utils') +const webpack = require('webpack') +const config = require('../config') +const merge = require('webpack-merge') +const path = require('path') +const baseWebpackConfig = require('./webpack.base.conf') +const CopyWebpackPlugin = require('copy-webpack-plugin') +const HtmlWebpackPlugin = require('html-webpack-plugin') +const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin') +const portfinder = require('portfinder') + +const HOST = process.env.HOST +const PORT = process.env.PORT && Number(process.env.PORT) + +const devWebpackConfig = merge(baseWebpackConfig, { + module: { + rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true }) + }, + // cheap-module-eval-source-map is faster for development + devtool: config.dev.devtool, + + // these devServer options should be customized in /config/index.js + devServer: { + clientLogLevel: 'warning', + historyApiFallback: { + rewrites: [ + { from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') }, + ], + }, + hot: true, + contentBase: false, // since we use CopyWebpackPlugin. + compress: true, + host: HOST || config.dev.host, + port: PORT || config.dev.port, + open: config.dev.autoOpenBrowser, + overlay: config.dev.errorOverlay + ? { warnings: false, errors: true } + : false, + publicPath: config.dev.assetsPublicPath, + proxy: config.dev.proxyTable, + quiet: true, // necessary for FriendlyErrorsPlugin + watchOptions: { + poll: config.dev.poll, + } + }, + plugins: [ + new webpack.DefinePlugin({ + 'process.env': require('../config/dev.env') + }), + new webpack.HotModuleReplacementPlugin(), + new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update. + new webpack.NoEmitOnErrorsPlugin(), + // https://github.com/ampedandwired/html-webpack-plugin + new HtmlWebpackPlugin({ + filename: 'index.html', + template: 'index.html', + inject: true + }), + // copy custom static assets + new CopyWebpackPlugin([ + { + from: path.resolve(__dirname, '../static'), + to: config.dev.assetsSubDirectory, + ignore: ['.*'] + } + ]) + ] +}) + +module.exports = new Promise((resolve, reject) => { + portfinder.basePort = process.env.PORT || config.dev.port + portfinder.getPort((err, port) => { + if (err) { + reject(err) + } else { + // publish the new Port, necessary for e2e tests + process.env.PORT = port + // add port to devServer config + devWebpackConfig.devServer.port = port + + // Add FriendlyErrorsPlugin + devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({ + compilationSuccessInfo: { + messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`], + }, + onErrors: config.dev.notifyOnErrors + ? utils.createNotifierCallback() + : undefined + })) + + resolve(devWebpackConfig) + } + }) +}) diff --git a/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/build/webpack.prod.conf.js b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/build/webpack.prod.conf.js new file mode 100644 index 0000000000..1f71ad6454 --- /dev/null +++ b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/build/webpack.prod.conf.js @@ -0,0 +1,147 @@ +'use strict' +const path = require('path') +const utils = require('./utils') +const webpack = require('webpack') +const config = require('../config') +const merge = require('webpack-merge') +const baseWebpackConfig = require('./webpack.base.conf') +const CopyWebpackPlugin = require('copy-webpack-plugin') +const HtmlWebpackPlugin = require('html-webpack-plugin') +const ExtractTextPlugin = require('extract-text-webpack-plugin') +const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin') +const UglifyJsPlugin = require('uglifyjs-webpack-plugin') +const VueLoaderPlugin = require('vue-loader/lib/plugin'); + +const env = require('../config/prod.env') + +const webpackConfig = merge(baseWebpackConfig, { + module: { + rules: utils.styleLoaders({ + sourceMap: config.build.productionSourceMap, + extract: true, + usePostCSS: true + }) + }, + devtool: config.build.productionSourceMap ? config.build.devtool : false, + output: { + path: config.build.assetsRoot, + filename: utils.assetsPath('js/[name].[chunkhash].js'), + chunkFilename: utils.assetsPath('js/[id].[chunkhash].js') + }, + plugins: [ + new VueLoaderPlugin(), + // http://vuejs.github.io/vue-loader/en/workflow/production.html + new webpack.DefinePlugin({ + 'process.env': env + }), + new UglifyJsPlugin({ + uglifyOptions: { + compress: { + warnings: false + } + }, + sourceMap: config.build.productionSourceMap, + parallel: true + }), + // extract css into its own file + new ExtractTextPlugin({ + filename: utils.assetsPath('css/[name].[contenthash].css'), + // Setting the following option to `false` will not extract CSS from codesplit chunks. + // Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack. + // It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`, + // increasing file size: https://github.com/vuejs-templates/webpack/issues/1110 + allChunks: true, + }), + // Compress extracted CSS. We are using this plugin so that possible + // duplicated CSS from different components can be deduped. + new OptimizeCSSPlugin({ + cssProcessorOptions: config.build.productionSourceMap + ? { safe: true, map: { inline: false } } + : { safe: true } + }), + // generate dist index.html with correct asset hash for caching. + // you can customize output by editing /index.html + // see https://github.com/ampedandwired/html-webpack-plugin + new HtmlWebpackPlugin({ + filename: config.build.index, + template: 'index.html', + inject: true, + minify: { + removeComments: true, + collapseWhitespace: true, + removeAttributeQuotes: true + // more options: + // https://github.com/kangax/html-minifier#options-quick-reference + }, + // necessary to consistently work with multiple chunks via CommonsChunkPlugin + chunksSortMode: 'dependency' + }), + // keep module.id stable when vendor modules does not change + new webpack.HashedModuleIdsPlugin(), + // enable scope hoisting + new webpack.optimize.ModuleConcatenationPlugin(), + // split vendor js into its own file + new webpack.optimize.CommonsChunkPlugin({ + name: 'vendor', + minChunks (module) { + // any required modules inside node_modules are extracted to vendor + return ( + module.resource && + /\.js$/.test(module.resource) && + module.resource.indexOf( + path.join(__dirname, '../node_modules') + ) === 0 + ) + } + }), + // extract webpack runtime and module manifest to its own file in order to + // prevent vendor hash from being updated whenever app bundle is updated + new webpack.optimize.CommonsChunkPlugin({ + name: 'manifest', + minChunks: Infinity + }), + // This instance extracts shared chunks from code split chunks and bundles them + // in a separate chunk, similar to the vendor chunk + // see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk + new webpack.optimize.CommonsChunkPlugin({ + name: 'app', + async: 'vendor-async', + children: true, + minChunks: 3 + }), + + // copy custom static assets + new CopyWebpackPlugin([ + { + from: path.resolve(__dirname, '../static'), + to: config.build.assetsSubDirectory, + ignore: ['.*'] + } + ]) + ] +}) + +if (config.build.productionGzip) { + const CompressionWebpackPlugin = require('compression-webpack-plugin') + + webpackConfig.plugins.push( + new CompressionWebpackPlugin({ + asset: '[path].gz[query]', + algorithm: 'gzip', + test: new RegExp( + '\\.(' + + config.build.productionGzipExtensions.join('|') + + ')$' + ), + threshold: 10240, + minRatio: 0.8 + }) + ) +} + +if (config.build.bundleAnalyzerReport) { + const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin + webpackConfig.plugins.push(new BundleAnalyzerPlugin()) +} + +module.exports = webpackConfig diff --git a/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/config/dev.env.js b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/config/dev.env.js new file mode 100644 index 0000000000..1e22973ae7 --- /dev/null +++ b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/config/dev.env.js @@ -0,0 +1,7 @@ +'use strict' +const merge = require('webpack-merge') +const prodEnv = require('./prod.env') + +module.exports = merge(prodEnv, { + NODE_ENV: '"development"' +}) diff --git a/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/config/index.js b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/config/index.js new file mode 100644 index 0000000000..c5eded7f81 --- /dev/null +++ b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/config/index.js @@ -0,0 +1,69 @@ +'use strict' +// Template version: 1.3.1 +// see http://vuejs-templates.github.io/webpack for documentation. + +const path = require('path') + +module.exports = { + dev: { + + // Paths + assetsSubDirectory: 'static', + assetsPublicPath: '/', + proxyTable: {}, + + // Various Dev Server settings + host: 'localhost', // can be overwritten by process.env.HOST + port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined + autoOpenBrowser: false, + errorOverlay: true, + notifyOnErrors: true, + poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions- + + + /** + * Source Maps + */ + + // https://webpack.js.org/configuration/devtool/#development + devtool: 'cheap-module-eval-source-map', + + // If you have problems debugging vue-files in devtools, + // set this to false - it *may* help + // https://vue-loader.vuejs.org/en/options.html#cachebusting + cacheBusting: true, + + cssSourceMap: true + }, + + build: { + // Template for index.html + index: path.resolve(__dirname, '../dist/index.html'), + + // Paths + assetsRoot: path.resolve(__dirname, '../dist'), + assetsSubDirectory: 'static', + assetsPublicPath: '/', + + /** + * Source Maps + */ + + productionSourceMap: true, + // https://webpack.js.org/configuration/devtool/#production + devtool: '#source-map', + + // Gzip off by default as many popular static hosts such as + // Surge or Netlify already gzip all static assets for you. + // Before setting to `true`, make sure to: + // npm install --save-dev compression-webpack-plugin + productionGzip: false, + productionGzipExtensions: ['js', 'css'], + + // Run the build command with an extra argument to + // View the bundle analyzer report after build finishes: + // `npm run build --report` + // Set to `true` or `false` to always turn it on or off + bundleAnalyzerReport: process.env.npm_config_report + } +} diff --git a/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/config/prod.env.js b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/config/prod.env.js new file mode 100644 index 0000000000..a6f997616e --- /dev/null +++ b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/config/prod.env.js @@ -0,0 +1,4 @@ +'use strict' +module.exports = { + NODE_ENV: '"production"' +} diff --git a/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/index.html b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/index.html new file mode 100644 index 0000000000..03ce3fdf27 --- /dev/null +++ b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/index.html @@ -0,0 +1,12 @@ + + + + + + deplugin-view-frontend + + +
+ + + diff --git a/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/package.json b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/package.json new file mode 100644 index 0000000000..48531de436 --- /dev/null +++ b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/package.json @@ -0,0 +1,82 @@ +{ + "name": "deplugin-view-frontend", + "version": "1.0.0", + "description": "A Vue.js project", + "author": "", + "private": true, + "scripts": { + "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js", + "start": "npm run dev", + "build": "node build/build.js", + "buildPlugin": "node build/build-async-plugins.js" + }, + "dependencies": { + "@antv/l7": "2.15.0", + "@antv/l7-component": "2.15.0", + "@antv/l7-core": "2.15.0", + "@antv/l7-layers": "2.15.0", + "@antv/l7-maps": "2.15.0", + "@antv/l7-renderer": "2.15.0", + "@antv/l7-scene": "2.15.0", + "@antv/l7-source": "2.15.0", + "@antv/l7-utils": "2.15.0", + "@riophae/vue-treeselect": "0.4.0", + "highcharts": "^10.0.0", + "vue": "^2.5.2", + "vue-i18n": "7.3.2", + "vue-router": "^3.0.1", + "vue-uuid": "2.0.2", + "vuedraggable": "^2.24.3" + }, + "devDependencies": { + "autoprefixer": "^7.1.2", + "babel-core": "^6.22.1", + "babel-helper-vue-jsx-merge-props": "^2.0.3", + "babel-loader": "^7.1.1", + "babel-plugin-syntax-jsx": "^6.18.0", + "babel-plugin-transform-runtime": "^6.22.0", + "babel-plugin-transform-vue-jsx": "^3.5.0", + "babel-preset-env": "^1.3.2", + "babel-preset-stage-2": "^6.22.0", + "chalk": "^2.0.1", + "copy-webpack-plugin": "^4.6.0", + "css-loader": "^0.28.0", + "element-ui": "2.15.7", + "extract-text-webpack-plugin": "^4.0.0-beta.0", + "file-loader": "^1.1.4", + "friendly-errors-webpack-plugin": "^1.6.1", + "html-webpack-plugin": "^3.2.0", + "js-cookie": "2.2.0", + "node-notifier": "^8.0.1", + "optimize-css-assets-webpack-plugin": "^3.2.0", + "ora": "^1.2.0", + "portfinder": "^1.0.13", + "postcss-import": "^11.0.0", + "postcss-loader": "^2.0.8", + "postcss-url": "^7.2.1", + "rimraf": "^2.6.0", + "sass": "^1.33.0", + "sass-loader": "^7.3.1", + "semver": "^5.3.0", + "shelljs": "^0.8.5", + "svg-sprite-loader": "4.1.3", + "uglifyjs-webpack-plugin": "^1.1.1", + "url-loader": "^0.5.8", + "vue-loader": "^15.6.4", + "vue-style-loader": "^4.1.2", + "vue-template-compiler": "^2.5.2", + "webpack": "^4.8.1", + "webpack-bundle-analyzer": "^3.3.2", + "webpack-dev-server": "^3.1.11", + "webpack-merge": "^4.1.0" + }, + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + }, + "browserslist": [ + "> 1%", + "last 2 versions", + "not ie <= 8" + ] +} diff --git a/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/pom.xml b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/pom.xml new file mode 100644 index 0000000000..ff15b278bc --- /dev/null +++ b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/pom.xml @@ -0,0 +1,80 @@ + + + + + io.dataease + view-symbolmap + ${dataease.version} + + + 4.0.0 + view-symbolmap-frontend + + + UTF-8 + UTF-8 + 1.9.1 + + + + + + maven-clean-plugin + + + + static + + ** + + false + + + + + + + + com.github.eirslett + frontend-maven-plugin + ${frontend-maven-plugin.version} + + + install node and npm + + install-node-and-npm + + + + v16.20.2 + 7.6.3 + + + + + npm install + + npm + + + + install + + + + + npm run buildPlugin + + npm + + + run buildPlugin + + + + + + + diff --git a/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/App.vue b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/App.vue new file mode 100644 index 0000000000..8542e07722 --- /dev/null +++ b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/App.vue @@ -0,0 +1,23 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/assets/logo.png b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/assets/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..f3d2503fc2a44b5053b0837ebea6e87a2d339a43 GIT binary patch literal 6849 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 +
+

{{ msg }}

+

Essential Links

+ +

Ecosystem

+ +
+ + + + + + diff --git a/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/SvgIcon/index.vue b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/SvgIcon/index.vue new file mode 100644 index 0000000000..f81b67f667 --- /dev/null +++ b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/SvgIcon/index.vue @@ -0,0 +1,60 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/selector/BackgroundColorSelector.vue b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/selector/BackgroundColorSelector.vue new file mode 100644 index 0000000000..e1cbf5fe18 --- /dev/null +++ b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/selector/BackgroundColorSelector.vue @@ -0,0 +1,102 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/selector/BaseMapStyleSelector.vue b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/selector/BaseMapStyleSelector.vue new file mode 100644 index 0000000000..819a284785 --- /dev/null +++ b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/selector/BaseMapStyleSelector.vue @@ -0,0 +1,99 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/selector/ColorSelector.vue b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/selector/ColorSelector.vue new file mode 100644 index 0000000000..326e9c8e77 --- /dev/null +++ b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/selector/ColorSelector.vue @@ -0,0 +1,290 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/selector/LabelSelector.vue b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/selector/LabelSelector.vue new file mode 100644 index 0000000000..2a24e2f573 --- /dev/null +++ b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/selector/LabelSelector.vue @@ -0,0 +1,244 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/selector/LegendSelector.vue b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/selector/LegendSelector.vue new file mode 100644 index 0000000000..5125412616 --- /dev/null +++ b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/selector/LegendSelector.vue @@ -0,0 +1,165 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/selector/SizeSelectorAntV.vue b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/selector/SizeSelectorAntV.vue new file mode 100644 index 0000000000..b2d4348efa --- /dev/null +++ b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/selector/SizeSelectorAntV.vue @@ -0,0 +1,130 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/selector/TitleSelector.vue b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/selector/TitleSelector.vue new file mode 100644 index 0000000000..938dd29c36 --- /dev/null +++ b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/selector/TitleSelector.vue @@ -0,0 +1,269 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/selector/TooltipSelector.vue b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/selector/TooltipSelector.vue new file mode 100644 index 0000000000..fbd16a64e3 --- /dev/null +++ b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/selector/TooltipSelector.vue @@ -0,0 +1,144 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/selector/TooltipSelectorAntV.vue b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/selector/TooltipSelectorAntV.vue new file mode 100644 index 0000000000..334d6cf03f --- /dev/null +++ b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/selector/TooltipSelectorAntV.vue @@ -0,0 +1,225 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/views/ChartDragItem.vue b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/views/ChartDragItem.vue new file mode 100644 index 0000000000..53ae1e2ad0 --- /dev/null +++ b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/views/ChartDragItem.vue @@ -0,0 +1,278 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/views/DimensionExtItem.vue b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/views/DimensionExtItem.vue new file mode 100644 index 0000000000..c414ad2d36 --- /dev/null +++ b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/views/DimensionExtItem.vue @@ -0,0 +1,256 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/views/DrillItem.vue b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/views/DrillItem.vue new file mode 100644 index 0000000000..7321b8a08c --- /dev/null +++ b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/views/DrillItem.vue @@ -0,0 +1,146 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/views/FieldErrorTips.vue b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/views/FieldErrorTips.vue new file mode 100644 index 0000000000..9d7b574721 --- /dev/null +++ b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/views/FieldErrorTips.vue @@ -0,0 +1,21 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/views/FilterItem.vue b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/views/FilterItem.vue new file mode 100644 index 0000000000..3dd5952d69 --- /dev/null +++ b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/views/FilterItem.vue @@ -0,0 +1,154 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/views/LocationLineItem.vue b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/views/LocationLineItem.vue new file mode 100644 index 0000000000..7b2985d08f --- /dev/null +++ b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/views/LocationLineItem.vue @@ -0,0 +1,170 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/views/LocationXItem.vue b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/views/LocationXItem.vue new file mode 100644 index 0000000000..fcd54e70e1 --- /dev/null +++ b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/views/LocationXItem.vue @@ -0,0 +1,170 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/views/LocationYItem.vue b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/views/LocationYItem.vue new file mode 100644 index 0000000000..93e30656e1 --- /dev/null +++ b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/views/LocationYItem.vue @@ -0,0 +1,170 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/views/QuotaExtItem.vue b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/views/QuotaExtItem.vue new file mode 100644 index 0000000000..c88a060a84 --- /dev/null +++ b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/views/QuotaExtItem.vue @@ -0,0 +1,363 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/views/QuotaItem.vue b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/views/QuotaItem.vue new file mode 100644 index 0000000000..775f98eae0 --- /dev/null +++ b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/views/QuotaItem.vue @@ -0,0 +1,310 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/views/ViewTrackBar.vue b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/views/ViewTrackBar.vue new file mode 100644 index 0000000000..605c0627b5 --- /dev/null +++ b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/views/ViewTrackBar.vue @@ -0,0 +1,59 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/views/utils.js b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/views/utils.js new file mode 100644 index 0000000000..bceed82dcc --- /dev/null +++ b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/components/views/utils.js @@ -0,0 +1,48 @@ +export function getItemType(dimensionData, quotaData, item) { + // 将item的字段在数据集维度、指标字段中查询一遍,如果遇到id不存在、字段类型不一致、维度指标不一致,则提示 + const status = item.groupType + let checked = false + if (status === 'd') { + for (let i = 0; i < dimensionData.length; i++) { + const ele = dimensionData[i] + if (ele.id === item.id && ele.deType === item.deType && ele.groupType === item.groupType) { + checked = true + break + } + } + } + if (status === 'q') { + for (let i = 0; i < quotaData.length; i++) { + const ele = quotaData[i] + if (ele.id === item.id && ele.deType === item.deType && ele.groupType === item.groupType) { + checked = true + break + } + } + } + + if (checked) { + if (status === 'd') { + return '' + } else if (status === 'q') { + return 'success' + } + } else { + return 'danger' + } +} + +export function getRemark(chart) { + const remark = {} + if (chart.customStyle) { + const customStyle = JSON.parse(chart.customStyle) + if (customStyle.text) { + const title = JSON.parse(JSON.stringify(customStyle.text)) + remark.show = title.remarkShow ? title.remarkShow : false + remark.content = title.remark ? title.remark : '' + remark.bgFill = title.remarkBackgroundColor ? title.remarkBackgroundColor : '#ffffffff' + } + } + return remark +} + diff --git a/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/de-base/lang/en.js b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/de-base/lang/en.js new file mode 100644 index 0000000000..4f5692dbfd --- /dev/null +++ b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/de-base/lang/en.js @@ -0,0 +1,23 @@ +export default { + plugin_view_symbol_map: { + longitude: 'Longitude', + latitude: 'Latitude', + map_type: 'Map Type', + link_line: 'Link Line', + mark_size: 'Mark Size', + type_title: 'Symbol Map', + label: 'Area', + angle: 'Symbol', + marker: 'Marker', + pentagon: 'Pentagon', + hexagon: 'Hexagon', + octagon: 'Octagon', + hexagram: 'Hexagram', + border: 'Border', + light: 'Light', + dark: 'Dark', + label_format_tip: 'The field value can be read in the form of {field Name}, the fields in the label and the tips are interchangeable, and the built-in latitude and longitude related fields', + tooltip_format_tip: 'The field value can be read in the form of {field Name}, the fields in the label and the tips are interchangeable, and the built-in latitude and longitude related fields.(the label does not support line breaks)', + mark_size_tip: 'When this quota is in effect, the bubble size attribute in the style size will be invalid' + } +} diff --git a/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/de-base/lang/index.js b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/de-base/lang/index.js new file mode 100644 index 0000000000..e50d0478e6 --- /dev/null +++ b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/de-base/lang/index.js @@ -0,0 +1,49 @@ +import Vue from 'vue' +import VueI18n from 'vue-i18n' +import Cookies from 'js-cookie' +import elementEnLocale from 'element-ui/lib/locale/lang/en' // element-ui lang +import elementZhLocale from 'element-ui/lib/locale/lang/zh-CN'// element-ui lang +import elementTWLocale from 'element-ui/lib/locale/lang/zh-TW'// element-ui lang + +import localMessages from './messages' + + +Vue.use(VueI18n) + +const messages = { + en_US: { + ...localMessages['en_US'], + ...elementEnLocale + }, + zh_CN: { + ...localMessages['zh_CN'], + ...elementZhLocale + }, + zh_TW: { + ...localMessages['zh_TW'], + ...elementTWLocale + } +} +export function getLanguage () { + const chooseLanguage = Cookies.get('language') + if (chooseLanguage) return chooseLanguage + + // if has not choose language + const language = (navigator.language || navigator.browserLanguage).toLowerCase() + const locales = Object.keys(messages) + for (const locale of locales) { + if (language.indexOf(locale) > -1) { + return locale + } + } + return 'zh_CN' +} +const i18n = new VueI18n({ + // set locale + // options: en | zh | es + locale: getLanguage(), + // set locale messages + messages +}) + +export default i18n diff --git a/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/de-base/lang/messages.js b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/de-base/lang/messages.js new file mode 100644 index 0000000000..844f8c0673 --- /dev/null +++ b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/de-base/lang/messages.js @@ -0,0 +1,17 @@ +import enLocale from './en' +import zhLocale from './zh' +import twLocale from './tw' + +const messages = { + en_US: { + ...enLocale + }, + zh_CN: { + ...zhLocale + }, + zh_TW: { + ...twLocale + } +} + +export default messages \ No newline at end of file diff --git a/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/de-base/lang/tw.js b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/de-base/lang/tw.js new file mode 100644 index 0000000000..c9c64494c2 --- /dev/null +++ b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/de-base/lang/tw.js @@ -0,0 +1,24 @@ +export default { + plugin_view_symbol_map: { + type_title: '符號地圖', + longitude: '經度', + latitude: '緯度', + map_type: '類型', + link_line: '連線', + mark_size: '標記大小', + label: '區域', + angle: '符號', + marker: '標記', + pentagon: '五邊形', + hexagon: '六邊形', + + octagon: '八邊形', + hexagram: '六角星', + border: '邊框', + light: '亮色', + dark: '暗色', + label_format_tip: '可以${fieldName}的形式讀取字段值,標籤和提示中的字段互相通用,內置經緯度相關字段', + tooltip_format_tip: '可以${fieldName}的形式讀取字段值,標籤和提示中的字段互相通用,內置經緯度相關字段(標籤不支持換行)', + mark_size_tip: '該指標生效時,樣式大小中的氣泡大小屬性將失效' + } +} diff --git a/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/de-base/lang/zh.js b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/de-base/lang/zh.js new file mode 100644 index 0000000000..dec48dde04 --- /dev/null +++ b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/de-base/lang/zh.js @@ -0,0 +1,22 @@ +export default { + plugin_view_symbol_map: { + type_title: '符号地图', + longitude: '经度', + latitude: '纬度', + map_type: '类型', + link_line: '连线', + mark_size: '标记大小', + angle: '符号', + marker: '标记', + pentagon: '五角形', + hexagon: '六角形', + octagon: '八角形', + hexagram: '六角星', + border: '边框', + light: '亮色', + dark: '暗色', + label_format_tip: '可以${fieldName}的形式读取字段值,标签和提示中的字段互相通用,内置经纬度相关字段', + tooltip_format_tip: '可以${fieldName}的形式读取字段值,标签和提示中的字段互相通用,内置经纬度相关字段(标签不支持换行)', + mark_size_tip: '该指标生效时,样式大小中的气泡大小属性将失效' + } +} diff --git a/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/icons/index.js b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/icons/index.js new file mode 100644 index 0000000000..2c6b309c96 --- /dev/null +++ b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/icons/index.js @@ -0,0 +1,9 @@ +import Vue from 'vue' +import SvgIcon from '@/components/SvgIcon'// svg component + +// register globally +Vue.component('svg-icon', SvgIcon) + +const req = require.context('./svg', false, /\.svg$/) +const requireAll = requireContext => requireContext.keys().map(requireContext) +requireAll(req) diff --git a/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/icons/svg/map-marker-old.svg b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/icons/svg/map-marker-old.svg new file mode 100644 index 0000000000..5e43dbcdff --- /dev/null +++ b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/icons/svg/map-marker-old.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/icons/svg/map-marker.png b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/icons/svg/map-marker.png new file mode 100644 index 0000000000000000000000000000000000000000..af954a045bb9a76da278c1fb1fdac54da6f5e1d4 GIT binary patch literal 3072 zcmeHIdpy(o8~-L!?sEwz7AqaOY|Ip6VjG)li$$m~LoRb0+D07{$K0ApIrc-L=z?%W zi(F2wJ8~<^=z_Em3b};*c7A`I-ygrffB&54^?E+<=l#5%_w&3y&p%HZ!38HP^^+6; z0J8RYtg8sS|MI=NMKAZ)^A#cx53+H#0e~8|^p>B5i0`7h;?O`-cX!+w^odJMx z1OO6~0pPnRmG}t&VvPV`))xSfzX5=1WWkeDmH;4@L~tV7iVFU*e>U)c+(3LPu1hq2 zIL6h*4Ny8_jf!>%{t$Z@Gsw{L)YI{P;w~ zzBpmbUd(HU10}y7jHRkHJXN!vp0VAvmALz%%##**)xM#hv`62_DO5d(-`@W*O7k0T zESeJh-rwhiX%2&Ebz+u%{F;j_z4-Q>CC{^SaM+{TuO46AFJ0%G=^Q$Say>;jX=j0~ znCiaKk)U4A`8GdU&6 zAk6E7a&vX&<0d1i$%2+4HbwNoT_i^w7GOze;zeX%B;J!M!oOlXVAm6B1ptyJ_E;Mt zO)y`$;iGa|EtQ=pm2S4D+cv6A_mGpUw6n8; zo>ng)Wz-9r3wD04DhXSAyHS)+@3&aZ7p`p*jLS{h*G_<+$JbVAj+zG8h zi<8m}+1|R^$M&7K8hO+#rxDZ|Y5#Hcgqz2AZhYRP5)o(_y07lV5luCuOobao{f95~ z;zx@5*KEx!1#@|-@NIe%C(aa|$w;=?3CtY4=VHlya>IB}1BO+@M!wi<481vqW+i>? zL)|tgXsz%olX&wb8*Wy^dU42NRMg^{+JVW*o&`GIJU}lG*W(|~z;CQ0!0Z`5Mo~Yy zj7rNaoTyLDHBskIctT%2_$V;-Zou7m&`+0kLo}STJvl(bn|BT9!8v>kpNB+ACB;DQ z99p60qU?p*0cG`Ne`+xXB8>Y64#T-47=HN*t=I9+{-duczS+xC1$40tA_hiq`)$op~_)Q3~Dvh4Ik_I+M1 zV#vLIXS?FGgI>&3ZnKnU1yowKn4E=XJtBgCoo-&Hj8w9f$rwcqa;eQ>#YDI6ab+C` zZH)aPXps{un zM)j+GC5wGi@!0Q}fO21@2O+v=AZd6MvHomIJ2#^vY0O$@m6YP4Sud9YwHh$+_n(I$ z1}`hgn6k0$?X#xU)(r|WFWK!FRzvI3HL<}d;_W2nF{QM`lNa0`s>Omf_ckrY=Hkiw zxQUkTs^n5a8ASNq3qfx^?esMYC!P>dkkNb3_)*fCueQWg-VGrlepjAx`@A6 zTsDBAsa#8Xa&2E@d~5Pv%4>c$PeP!_@HP`$;DXO2el87m4|J~17G!eKNA`3 zr8NYLWwQc#gtTnm9H?zla)4a`fyfalZ%J3d@|*#@fnsFQp-x*b_Ngb9t)-~?(Q;?3 zQ}N0zZ;4sF#vMG<4iv@eo62#K=NC^&df7UCPArwRdO6Dk>(sR2xVFjC7tK$Jv>9A9~ zqv_i#Qe)R|z0MC*dwS*CF<;?^_4j2u>(BKu&W(yc{gpw%3uy#c3-0H+OmFa&eAv#p z$)R+IDUT-bx;k9iE;^o-&@m-5agW0B9uw1c+PJj9y^>n>0_ z^vWU69?Npm7H4{=y!*!w{xUpR^vzUYBIl4G#3l!MsTF;0TSZmTW~H`X-#W+EnyxW8 zkPzYVL2{vY4AkPnZoAr*c96Hc&~0x4IT014x#vY^?J9YQni1DCS3b)@ zFPCKaUv^g+Nqe^!TV9W`g+B8%LFJ-*6ig zlu*~TL~ zo#kD6586NIP?@_EEqpI!D})VQO2p`Qbd0P2?TW1{EFDag$4;GXjtUXoQJomuGcjbp zm;j`Ibbtr|xDgy~XoN6?BZ$UENE0(8+*sep3~6Mv9a|XtUjj-5IXIC1zXh4PIz1wR z(_a&)aY0CuA2q-*HaZvx3=RuG!eFoq5tIO!ADI#y4h!~=2saFj2# + + diff --git a/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/icons/svg/symbol-map.svg b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/icons/svg/symbol-map.svg new file mode 100644 index 0000000000..81fa53d188 --- /dev/null +++ b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/icons/svg/symbol-map.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/icons/svg/view-symbolmap-backend.svg b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/icons/svg/view-symbolmap-backend.svg new file mode 100644 index 0000000000..becfdb6caf --- /dev/null +++ b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/icons/svg/view-symbolmap-backend.svg @@ -0,0 +1 @@ +【icon】插件管理-导出 \ No newline at end of file diff --git a/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/icons/svgo.yml b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/icons/svgo.yml new file mode 100644 index 0000000000..e69de29bb2 diff --git a/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/main.js b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/main.js new file mode 100644 index 0000000000..a57d2a8368 --- /dev/null +++ b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/main.js @@ -0,0 +1,36 @@ +// The Vue build version to load with the `import` command +// (runtime-only or standalone) has been set in webpack.base.conf with an alias. +import Vue from 'vue' +import App from './App' +import router from './router' +import ElementUI from 'element-ui' +import Cookies from 'js-cookie' +import i18n from './de-base/lang' +import draggable from 'vuedraggable' +import Treeselect from '@riophae/vue-treeselect' +import '@riophae/vue-treeselect/dist/vue-treeselect.css' +import '@/icons' // icon +import { GaodeMap } from '@antv/l7-maps' +Vue.config.productionTip = false +Vue.use(ElementUI, { + size: Cookies.get('size') || 'medium', + i18n: (key, value) => i18n.t(key, value) +}) +Vue.component('Treeselect', Treeselect) +Vue.component('draggable', draggable) +Vue.prototype.hasDataPermission = function(pTarget, pSource) { + + if (pSource && pTarget) { + return pSource.indexOf(pTarget) > -1 + } + return false +} +Vue.prototype.$gaodeMap = GaodeMap +/* eslint-disable no-new */ +new Vue({ + el: '#app', + router, + i18n, + components: { App }, + template: '' +}) diff --git a/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/router/index.js b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/router/index.js new file mode 100644 index 0000000000..28855997b4 --- /dev/null +++ b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/router/index.js @@ -0,0 +1,21 @@ +import Vue from 'vue' +import Router from 'vue-router' +import HelloWorld from '@/components/HelloWorld' +import SymbolMap from '@/views/antv/symbolmap/type' + +Vue.use(Router) + +export default new Router({ + routes: [ + { + path: '/', + name: 'HelloWorld', + component: HelloWorld + }, + { + path: '/symbol-map', + name: 'symbol-map', + component: SymbolMap + } + ] +}) diff --git a/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/utils/compare.js b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/utils/compare.js new file mode 100644 index 0000000000..b06a104a10 --- /dev/null +++ b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/utils/compare.js @@ -0,0 +1,29 @@ +export const compareItem = { + type: 'none', // year-yoy/month-yoy等 + resultData: 'percent', // 对比差sub,百分比percent等 + field: '', + custom: { + field: '', + calcType: '0', // 0-增长值,1-增长率 + timeType: '0', // 0-固定日期,1-日期区间 + currentTime: '', + compareTime: '', + currentTimeRange: [], + compareTimeRange: [] + } +} + +export const compareYearList = [ + { name: 'year_mom', value: 'year_mom' } +] + +export const compareMonthList = [ + { name: 'month_mom', value: 'month_mom' }, + { name: 'year_yoy', value: 'year_yoy' } +] + +export const compareDayList = [ + { name: 'day_mom', value: 'day_mom' }, + { name: 'month_yoy', value: 'month_yoy' }, + { name: 'year_yoy', value: 'year_yoy' } +] diff --git a/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/utils/map.js b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/utils/map.js new file mode 100644 index 0000000000..19f9155c56 --- /dev/null +++ b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/utils/map.js @@ -0,0 +1,430 @@ +export const DEFAULT_COLOR_CASE = { + value: 'default', + colors: ['#5470c6', '#91cc75', '#fac858', '#ee6666', '#73c0de', '#3ba272', '#fc8452', '#9a60b4', '#ea7ccc'], + alpha: 100, + tableHeaderBgColor: '#e1eaff', + tableItemBgColor: '#ffffff', + tableFontColor: '#000000', + tableStripe: true, + dimensionColor: '#000000', + quotaColor: '#000000', + tableBorderColor: '#cfdaf4' +} +export const DEFAULT_SIZE = { + barDefault: true, + barWidth: 40, + barGap: 0.4, + lineWidth: 2, + lineType: 'solid', + lineSymbol: 'marker', + lineSymbolSize: 4, + lineSmooth: true, + lineArea: false, + pieInnerRadius: 0, + pieOuterRadius: 80, + pieRoseType: 'radius', + pieRoseRadius: 5, + funnelWidth: 80, + radarShape: 'polygon', + radarSize: 80, + tableTitleFontSize: 12, + tableItemFontSize: 12, + tableTitleHeight: 36, + tableItemHeight: 36, + tablePageSize: '20', + tableColumnMode: 'custom', + tableColumnWidth: 100, + tableHeaderAlign: 'left', + tableItemAlign: 'right', + gaugeMin: 0, + gaugeMax: 100, + gaugeStartAngle: 225, + gaugeEndAngle: -45, + dimensionFontSize: 18, + quotaFontSize: 18, + spaceSplit: 10, + dimensionShow: true, + quotaShow: true, + scatterSymbol: 'marker', + scatterSymbolSize: 15, + symbolOpacity: 5, + symbolStrokeWidth: 1, + treemapWidth: 80, + treemapHeight: 80, + liquidMax: 100, + liquidSize: 80, + liquidOutlineBorder: 4, + liquidOutlineDistance: 8, + liquidWaveLength: 128, + liquidWaveCount: 3, + liquidShape: 'circle', + tablePageMode: 'page' +} +export const COLOR_PANEL = [ + '#ff4500', + '#ff8c00', + '#ffd700', + '#90ee90', + '#00ced1', + '#1e90ff', + '#c71585', + '#999999', + '#000000', + '#FFFFFF' +] + +export const DEFAULT_LABEL = { + show: false, + position: 'top', + color: '#909399', + fontSize: '10', + formatter: '{c}', + gaugeFormatter: '{value}', + labelLine: { + show: true + }, + fields: null, + labelTemplate: '{busiValue}' + } + export const DEFAULT_TOOLTIP = { + show: true, + trigger: 'item', + confine: true, + textStyle: { + fontSize: '10', + color: '#909399' + }, + formatter: '', + tooltipTemplate: '{busiValue}' + } + export const DEFAULT_TITLE_STYLE = { + show: true, + fontSize: '18', + color: '#303133', + hPosition: 'center', + vPosition: 'top', + isItalic: false, + isBolder: false + } + export const DEFAULT_LEGEND_STYLE = { + show: true, + hPosition: 'center', + vPosition: 'bottom', + orient: 'horizontal', + icon: 'circle', + textStyle: { + color: '#333333', + fontSize: '12' + } + } + export const DEFAULT_BACKGROUND_COLOR = { + color: '#ffffff', + alpha: 100, + borderRadius: 5 + } + export const DEFAULT_BASE_MAP_STYLE = { + baseMapTheme: 'light' + } +export const BASE_MAP = { + title: { + text: '', + textStyle: { + fontWeight: 'normal' + } + }, + visualMap: { + min: 50, + max: 52, + text: ['High', 'Low'], + realtime: false, + calculable: true, + inRange: { + color: ['lightskyblue', 'yellow', 'orangered'] + }, + right: 0 + }, + + tooltip: {}, + geo: [ + { + show: true, + map: 'BUDDLE_MAP_BORDER', + + emphasis: { + disabled: true + }, + itemStyle: { + borderWidth: 2, + borderColor: '#d1d1d1', + borderType: 'solid' + }, + + roam: false + }, + { + show: true, + map: 'BUDDLE_MAP', + label: { + normal: { + show: false + }, + emphasis: { + show: false + } + }, + itemStyle: { + areaColor: '#f3f3f3', + borderType: 'dashed', + borderColor: '#fff' + }, + + roam: false + } + ], + series: [ + { + name: '', + type: 'scatter', + coordinateSystem: 'geo', + data: [] + } + ] +} +const convertData = (mapData, chart) => { + let maxVal = 0 + const k = terminalType === 'pc' ? 30 : 15 + const names = chart.data.x + const results = [] + for (let index = 0; index < names.length; index++) { + const name = names[index]; + const item = chart.data.series[0].data[index] + results.push({name, value: (mapData[name] ? mapData[name].concat(item.value) : []), dimensionList: item.dimensionList, quotaList: item.quotaList}) + maxVal = Math.max(maxVal, item.value) + } + const rate = k / maxVal + + return { + value: results, + rate: rate + } +} + +let terminalType = 'pc' +export function baseMapOption(chart_option, chart, mapData, terminal = 'pc') { + terminalType = terminal + // 处理shape attr + let customAttr = {} + if (chart.customAttr) { + customAttr = JSON.parse(chart.customAttr) + if (customAttr.color) { + chart_option.color = customAttr.color.colors + } + // tooltip + if (customAttr.tooltip) { + const tooltip = JSON.parse(JSON.stringify(customAttr.tooltip)) + const reg = new RegExp('\n', 'g') + const text = tooltip.formatter.replace(reg, '
') + tooltip.formatter = function(params) { + const a = params.seriesName + const b = params.name + const c = params.value ? params.value[2] : '' + return text.replace(new RegExp('{a}', 'g'), a).replace(new RegExp('{b}', 'g'), b).replace(new RegExp('{c}', 'g'), c) + } + chart_option.tooltip = tooltip + } + } + // 处理data + if (chart.data) { + chart_option.title.text = chart.title + if (chart.data.series && chart.data.series.length > 0) { + chart_option.series[0].name = chart.data.series[0].name + // label + if (customAttr.label) { + const text = customAttr.label.formatter + chart_option.series[0].label = customAttr.label + chart_option.series[0].label.formatter = function(params) { + const a = params.seriesName + const b = params.name + const c = params.value ? params.value[2] : '' + return text.replace(new RegExp('{a}', 'g'), a).replace(new RegExp('{b}', 'g'), b).replace(new RegExp('{c}', 'g'), c) + } + chart_option.series[0].labelLine = customAttr.label.labelLine + } + + // visualMap + const valueArr = chart.data.series[0].data + if (valueArr && valueArr.length > 0) { + const values = [] + valueArr.forEach(function(ele) { + values.push(ele.value) + }) + chart_option.visualMap.min = Math.min(...values) + chart_option.visualMap.max = Math.max(...values) + if (chart_option.visualMap.min === chart_option.visualMap.max) { + chart_option.visualMap.min = 0 + } + } else { + chart_option.visualMap.min = 0 + chart_option.visualMap.max = 0 + } + if (chart_option.visualMap.min === 0 && chart_option.visualMap.max === 0) { + chart_option.visualMap.max = 100 + } + // color + if (customAttr.color && customAttr.color.colors) { + chart_option.visualMap.inRange.color = customAttr.color.colors + chart_option.visualMap.inRange.colorAlpha = customAttr.color.alpha / 100 + } + // chart_option.visualMap = null + + const convert = convertData(mapData, chart) + chart_option.series[0].data = convert.value + chart_option.series[0].symbolSize = val => val[2] * convert.rate + + } + } + // console.log(chart_option); + componentStyle(chart_option, chart) + return chart_option +} +export function componentStyle(chart_option, chart) { + const padding = '8px' + if (chart.customStyle) { + const customStyle = JSON.parse(chart.customStyle) + if (customStyle.text) { + chart_option.title.show = customStyle.text.show + // 水平方向 + if (customStyle.text.hPosition === 'left') { + chart_option.title.left = padding + } else if (customStyle.text.hPosition === 'right') { + chart_option.title.right = padding + } else { + chart_option.title.left = customStyle.text.hPosition + } + // 垂直方向 + if (customStyle.text.vPosition === 'top') { + chart_option.title.top = padding + } else if (customStyle.text.vPosition === 'bottom') { + chart_option.title.bottom = padding + } else { + chart_option.title.top = customStyle.text.vPosition + } + const style = chart_option.title.textStyle ? chart_option.title.textStyle : {} + style.fontSize = customStyle.text.fontSize + style.color = customStyle.text.color + customStyle.text.isItalic ? style.fontStyle = 'italic' : style.fontStyle = 'normal' + customStyle.text.isBolder ? style.fontWeight = 'bold' : style.fontWeight = 'normal' + chart_option.title.textStyle = style + } + if (customStyle.legend && chart_option.legend) { + chart_option.legend.show = customStyle.legend.show + // 水平方向 + if (customStyle.legend.hPosition === 'left') { + chart_option.legend.left = padding + } else if (customStyle.legend.hPosition === 'right') { + chart_option.legend.right = padding + } else { + chart_option.legend.left = customStyle.legend.hPosition + } + // 垂直方向 + if (customStyle.legend.vPosition === 'top') { + chart_option.legend.top = padding + } else if (customStyle.legend.vPosition === 'bottom') { + chart_option.legend.bottom = padding + } else { + chart_option.legend.top = customStyle.legend.vPosition + } + chart_option.legend.orient = customStyle.legend.orient + chart_option.legend.icon = customStyle.legend.icon + chart_option.legend.textStyle = customStyle.legend.textStyle + + } + + if (customStyle.background) { + chart_option.backgroundColor = hexColorToRGBA(customStyle.background.color, customStyle.background.alpha) + } + } +} +export function hexColorToRGBA(hex, alpha) { + const rgb = [] // 定义rgb数组 + if (/^\#[0-9A-F]{3}$/i.test(hex)) { // 判断传入是否为#三位十六进制数 + let sixHex = '#' + hex.replace(/[0-9A-F]/ig, function(kw) { + sixHex += kw + kw // 把三位16进制数转化为六位 + }) + hex = sixHex // 保存回hex + } + if (/^#[0-9A-F]{6}$/i.test(hex)) { // 判断传入是否为#六位十六进制数 + hex.replace(/[0-9A-F]{2}/ig, function(kw) { + // eslint-disable-next-line no-eval + rgb.push(eval('0x' + kw)) // 十六进制转化为十进制并存如数组 + }) + return `rgba(${rgb.join(',')},${alpha / 100})` // 输出RGB格式颜色 + } else { + return 'rgb(0,0,0)' + } +} + + + +export const DEFAULT_YAXIS_EXT_STYLE = { + show: true, + position: 'right', + name: '', + nameTextStyle: { + color: '#333333', + fontSize: 12 + }, + axisLabel: { + show: true, + color: '#333333', + fontSize: '12', + rotate: 0, + formatter: '{value}' + }, + splitLine: { + show: true, + lineStyle: { + color: '#cccccc', + width: 1, + style: 'solid' + } + }, + axisValue: { + auto: true, + min: null, + max: null, + split: null, + splitCount: null + } +} + +export const getDefaultTemplate = (chart, type, feed , showKey) => { + if(!chart || !chart.viewFields || !type) return null; + let viewFields = [] + if (chart.viewFields instanceof Array) { + viewFields = JSON.parse(JSON.stringify(chart.viewFields)) + }else { + viewFields = JSON.parse(chart.viewFields) + } + const separator = feed ? '\n' : ' ' + return viewFields.filter(field => field.busiType && field.busiType === type).map(field => { + const fieldName = field.name + let template = "${"+ field.name +"}" + if(showKey) { + template = fieldName + ":${"+ field.name +"}" + } + return template + }).join(separator) +} + +export function uuid() { + return (((1+Math.random())*0x10000)|0).toString(16).substring(1); +} + +export const reverseColor = colorValue => { + colorValue = '0x' + colorValue.replace(/#/g, '') + const str = '000000' + (0xFFFFFF - colorValue).toString(16) + return '#' + str.substring(str.length - 6, str.length) +} + diff --git a/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/utils/symbolmap.js b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/utils/symbolmap.js new file mode 100644 index 0000000000..697800dd8d --- /dev/null +++ b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/utils/symbolmap.js @@ -0,0 +1,73 @@ +// import {PointLayer, Popup } from '@antv/l7'; + +export const DEFAULT_COLOR_CASE = { + value: 'default', + colors: ['#5470c6', '#91cc75', '#fac858', '#ee6666', '#73c0de', '#3ba272', '#fc8452', '#9a60b4', '#ea7ccc'], + alpha: 100, + tableHeaderBgColor: '#e1eaff', + tableItemBgColor: '#ffffff', + tableFontColor: '#000000', + tableStripe: true, + dimensionColor: '#000000', + quotaColor: '#000000', + tableBorderColor: '#cfdaf4' +} + +export const COLOR_PANEL = [ + '#ff4500', + '#ff8c00', + '#ffd700', + '#90ee90', + '#00ced1', + '#1e90ff', + '#c71585', + '#999999', + '#000000', + '#FFFFFF' +] + + +export const DEFAULT_BACKGROUND_COLOR = { + color: '#ffffff', + alpha: 100, + borderRadius: 5 +} + + + + +export function baseSymbolMap(scene, container, chart, action, $pointLayer, $popup) { + let _self = this + + +} + + +export function hexColorToRGBA(hex, alpha) { + const rgb = [] // 定义rgb数组 + if (/^\#[0-9A-F]{3}$/i.test(hex)) { // 判断传入是否为#三位十六进制数 + let sixHex = '#' + hex.replace(/[0-9A-F]/ig, function(kw) { + sixHex += kw + kw // 把三位16进制数转化为六位 + }) + hex = sixHex // 保存回hex + } + if (/^#[0-9A-F]{6}$/i.test(hex)) { // 判断传入是否为#六位十六进制数 + hex.replace(/[0-9A-F]{2}/ig, function(kw) { + // eslint-disable-next-line no-eval + rgb.push(eval('0x' + kw)) // 十六进制转化为十进制并存如数组 + }) + return `rgba(${rgb.join(',')},${alpha / 100})` // 输出RGB格式颜色 + } else { + return 'rgb(0,0,0)' + } +} + + + + + +export function uuid() { + return (((1+Math.random())*0x10000)|0).toString(16).substring(1); +} + diff --git a/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/utils/validate.js b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/utils/validate.js new file mode 100644 index 0000000000..3e8ffa9448 --- /dev/null +++ b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/utils/validate.js @@ -0,0 +1,15 @@ +/** + * Created by PanJiaChen on 16/11/18. + */ + +/** + * @param {string} path + * @returns {Boolean} + */ +export function isExternal(path) { + return /^(https?:|mailto:|tel:)/.test(path) || /^(http?:|mailto:|tel:)/.test(path) || path.startsWith('/api/pluginCommon/staticInfo') +} + + + + diff --git a/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/views/PluginDemo.vue b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/views/PluginDemo.vue new file mode 100644 index 0000000000..1164dfab1d --- /dev/null +++ b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/views/PluginDemo.vue @@ -0,0 +1,55 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/views/antv/symbolmap/data.vue b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/views/antv/symbolmap/data.vue new file mode 100644 index 0000000000..3b5e8a4620 --- /dev/null +++ b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/views/antv/symbolmap/data.vue @@ -0,0 +1,648 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/views/antv/symbolmap/index.vue b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/views/antv/symbolmap/index.vue new file mode 100644 index 0000000000..b85247228f --- /dev/null +++ b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/views/antv/symbolmap/index.vue @@ -0,0 +1,633 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/views/antv/symbolmap/style.vue b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/views/antv/symbolmap/style.vue new file mode 100644 index 0000000000..88fdbbfb45 --- /dev/null +++ b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/views/antv/symbolmap/style.vue @@ -0,0 +1,199 @@ + + + + + diff --git a/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/views/antv/symbolmap/type.vue b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/views/antv/symbolmap/type.vue new file mode 100644 index 0000000000..982e0cb1ef --- /dev/null +++ b/extensions/dataease-extensions-view/view-symbolmap/view-symbolmap-frontend/src/views/antv/symbolmap/type.vue @@ -0,0 +1,63 @@ + + + + + diff --git a/extensions/pom.xml b/extensions/pom.xml new file mode 100644 index 0000000000..9c727cf479 --- /dev/null +++ b/extensions/pom.xml @@ -0,0 +1,43 @@ + + + 4.0.0 + + io.dataease + dataease-extensions + ${dataease.version} + pom + + + + io.dataease + dataease + ${dataease.version} + + + + + + io.dataease + dataease-plugin-datasource + ${dataease.version} + + + io.dataease + dataease-plugin-view + ${dataease.version} + + + + + + dataease-extensions-view + dataease-extensions-datasource + + diff --git a/pom.xml b/pom.xml index 5b6b65d898..fba16d54d7 100644 --- a/pom.xml +++ b/pom.xml @@ -17,6 +17,7 @@ sdk core + extensions