From 8367033bb46b083a2ab2612ccaa7dc82338fca7a Mon Sep 17 00:00:00 2001 From: fit2cloud-chenyw Date: Wed, 17 Mar 2021 11:22:18 +0800 Subject: [PATCH 01/15] =?UTF-8?q?feat:=20=E4=BB=AA=E8=A1=A8=E7=9B=98?= =?UTF-8?q?=E5=88=86=E4=BA=ABtab?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/views/panel/GrantAuth/index.vue | 30 ++++++++++++++++++++ frontend/src/views/panel/list/PanelList.vue | 18 +++++++++--- 2 files changed, 44 insertions(+), 4 deletions(-) create mode 100644 frontend/src/views/panel/GrantAuth/index.vue diff --git a/frontend/src/views/panel/GrantAuth/index.vue b/frontend/src/views/panel/GrantAuth/index.vue new file mode 100644 index 0000000000..8fbbaade4c --- /dev/null +++ b/frontend/src/views/panel/GrantAuth/index.vue @@ -0,0 +1,30 @@ + + + diff --git a/frontend/src/views/panel/list/PanelList.vue b/frontend/src/views/panel/list/PanelList.vue index 3de67d91e2..259c789bd1 100644 --- a/frontend/src/views/panel/list/PanelList.vue +++ b/frontend/src/views/panel/list/PanelList.vue @@ -111,14 +111,14 @@ - 分享授权 + 取 消 确 定 @@ -129,12 +129,16 @@ + + diff --git a/frontend/src/views/panel/GrantAuth/index.vue b/frontend/src/views/panel/GrantAuth/index.vue index 8fbbaade4c..3c6f310b6e 100644 --- a/frontend/src/views/panel/GrantAuth/index.vue +++ b/frontend/src/views/panel/GrantAuth/index.vue @@ -1,14 +1,28 @@ + + diff --git a/frontend/src/views/panel/GrantAuth/role/index.vue b/frontend/src/views/panel/GrantAuth/role/index.vue new file mode 100644 index 0000000000..8785b10702 --- /dev/null +++ b/frontend/src/views/panel/GrantAuth/role/index.vue @@ -0,0 +1,89 @@ + + + + + diff --git a/frontend/src/views/panel/GrantAuth/user/index.vue b/frontend/src/views/panel/GrantAuth/user/index.vue new file mode 100644 index 0000000000..f36929d659 --- /dev/null +++ b/frontend/src/views/panel/GrantAuth/user/index.vue @@ -0,0 +1,88 @@ + + + + + diff --git a/frontend/src/views/panel/list/PanelList.vue b/frontend/src/views/panel/list/PanelList.vue index 9c0a958ae5..f1770358c8 100644 --- a/frontend/src/views/panel/list/PanelList.vue +++ b/frontend/src/views/panel/list/PanelList.vue @@ -114,8 +114,7 @@ :title="authTitle" :visible.sync="authVisible" :show-close="false" - width="30%" - custom-class="authDialog" + custom-class="de-dialog" :before-close="handleClose" > @@ -484,10 +483,11 @@ export default { }, share(data) { this.authResourceId = data.id - this.authTitle = '把仪表板[' + data.label + ']分享给' + this.authTitle = '把[' + data.label + ']分享给' this.authVisible = true }, handleClose(done) { + this.authResourceId = null this.handleClose = false } } @@ -540,8 +540,4 @@ export default { line-height: 26px; } - /* .el-dialog authDialog >>> div { - padding: 5px !important; - padding-bottom:5px !important; - } */ diff --git a/frontend/src/views/panel/list/PanelViewShow.vue b/frontend/src/views/panel/list/PanelViewShow.vue index 8295a524de..f2eca67623 100644 --- a/frontend/src/views/panel/list/PanelViewShow.vue +++ b/frontend/src/views/panel/list/PanelViewShow.vue @@ -34,7 +34,7 @@ - 名称:{{panelInfo.name}} + 名称:{{ panelInfo.name }} 背景图 From d50fbd21ca3944ae8ce41f46d01502827fda93ad Mon Sep 17 00:00:00 2001 From: junjie Date: Thu, 18 Mar 2021 10:08:12 +0800 Subject: [PATCH 03/15] =?UTF-8?q?feat(=E8=A7=86=E5=9B=BE):=20=E8=A7=86?= =?UTF-8?q?=E5=9B=BE=E7=BC=96=E8=BE=91=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/views/chart/components/ChartComponent.vue | 5 +++-- frontend/src/views/chart/components/ColorSelector.vue | 7 ++++++- frontend/src/views/chart/view/ChartEdit.vue | 2 +- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/frontend/src/views/chart/components/ChartComponent.vue b/frontend/src/views/chart/components/ChartComponent.vue index 3cf27335bc..2e065d2594 100644 --- a/frontend/src/views/chart/components/ChartComponent.vue +++ b/frontend/src/views/chart/components/ChartComponent.vue @@ -52,8 +52,9 @@ export default { // console.log(chart_option); // 处理shape attr if (chart.customAttr) { - if (chart.customAttr.color) { - chart_option.color = chart.customAttr.color.colors + const customAttr = JSON.parse(chart.customAttr) + if (customAttr.color) { + chart_option.color = customAttr.color.colors } } this.myEcharts(chart_option) diff --git a/frontend/src/views/chart/components/ColorSelector.vue b/frontend/src/views/chart/components/ColorSelector.vue index 383cd1ee4f..088e271427 100644 --- a/frontend/src/views/chart/components/ColorSelector.vue +++ b/frontend/src/views/chart/components/ColorSelector.vue @@ -94,7 +94,12 @@ export default { 'chart': { handler: function() { const chart = JSON.parse(JSON.stringify(this.chart)) - this.colorForm.colorCase = chart.customAttr.color.value + if (chart.customAttr) { + const customAttr = JSON.parse(chart.customAttr) + if (customAttr.color) { + this.colorForm.colorCase = customAttr.color.value + } + } } } }, diff --git a/frontend/src/views/chart/view/ChartEdit.vue b/frontend/src/views/chart/view/ChartEdit.vue index b65d2cdb7a..00dc35945f 100644 --- a/frontend/src/views/chart/view/ChartEdit.vue +++ b/frontend/src/views/chart/view/ChartEdit.vue @@ -264,7 +264,7 @@ export default { getData(id) { if (id) { post('/chart/view/getData/' + id, null).then(response => { - this.view = response.data + this.view = JSON.parse(JSON.stringify(response.data)) this.view.xaxis = this.view.xaxis ? JSON.parse(this.view.xaxis) : [] this.view.yaxis = this.view.yaxis ? JSON.parse(this.view.yaxis) : [] this.view.customAttr = this.view.customAttr ? JSON.parse(this.view.customAttr) : {} From 3f5d2bee5332725dc59a93ef54aa696b99648c8a Mon Sep 17 00:00:00 2001 From: junjie Date: Thu, 18 Mar 2021 11:05:14 +0800 Subject: [PATCH 04/15] =?UTF-8?q?feat(=E8=A7=86=E5=9B=BE):=20=E8=A7=86?= =?UTF-8?q?=E5=9B=BE=E7=BB=84=E4=BB=B6=E4=B8=B4=E6=97=B6=E5=B0=81=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/views/chart/chart/bar/baseBar.js | 21 +++++++++++++++++ .../src/views/chart/chart/line/baseLine.js | 21 +++++++++++++++++ .../views/chart/components/ChartComponent.vue | 23 ++++--------------- 3 files changed, 46 insertions(+), 19 deletions(-) create mode 100644 frontend/src/views/chart/chart/bar/baseBar.js create mode 100644 frontend/src/views/chart/chart/line/baseLine.js diff --git a/frontend/src/views/chart/chart/bar/baseBar.js b/frontend/src/views/chart/chart/bar/baseBar.js new file mode 100644 index 0000000000..69788002e1 --- /dev/null +++ b/frontend/src/views/chart/chart/bar/baseBar.js @@ -0,0 +1,21 @@ +export function baseBarOption(chart_option, chart) { +// 处理data + if (chart.data) { + chart_option.title.text = chart.title + chart_option.xAxis.data = chart.data.x + chart.data.series.forEach(function(y) { + chart_option.legend.data.push(y.name) + chart_option.series.push(y) + }) + } + // console.log(chart_option); + // 处理shape attr + if (chart.customAttr) { + const customAttr = JSON.parse(chart.customAttr) + if (customAttr.color) { + chart_option.color = customAttr.color.colors + } + } + return chart_option +} + diff --git a/frontend/src/views/chart/chart/line/baseLine.js b/frontend/src/views/chart/chart/line/baseLine.js new file mode 100644 index 0000000000..d431f2758d --- /dev/null +++ b/frontend/src/views/chart/chart/line/baseLine.js @@ -0,0 +1,21 @@ +export function baseLineOption(chart_option, chart) { +// 处理data + if (chart.data) { + chart_option.title.text = chart.title + chart_option.xAxis.data = chart.data.x + chart.data.series.forEach(function(y) { + chart_option.legend.data.push(y.name) + chart_option.series.push(y) + }) + } + // console.log(chart_option); + // 处理shape attr + if (chart.customAttr) { + const customAttr = JSON.parse(chart.customAttr) + if (customAttr.color) { + chart_option.color = customAttr.color.colors + } + } + return chart_option +} + diff --git a/frontend/src/views/chart/components/ChartComponent.vue b/frontend/src/views/chart/components/ChartComponent.vue index 2e065d2594..4aac1f97ab 100644 --- a/frontend/src/views/chart/components/ChartComponent.vue +++ b/frontend/src/views/chart/components/ChartComponent.vue @@ -6,6 +6,8 @@ diff --git a/frontend/src/views/panel/GrantAuth/index.vue b/frontend/src/views/panel/GrantAuth/index.vue index 3c6f310b6e..da7f8fe016 100644 --- a/frontend/src/views/panel/GrantAuth/index.vue +++ b/frontend/src/views/panel/GrantAuth/index.vue @@ -8,10 +8,16 @@ - - - + + + +
+ + 取 消 + 确 定 + +
@@ -31,11 +37,15 @@ export default { }, data() { return { - activeName: '1', + tabNames: ['grantDept', 'grantRole', 'grantUser'], + activeName: null, showSearchInput: false, - key: null + key: '' } }, + created() { + this.activeName = this.tabNames[0] + }, methods: { handleClick(tab, event) { @@ -45,7 +55,16 @@ export default { this.showSearchInput = true }, closeSearchWidget() { + this.key = '' this.showSearchInput = false + }, + save() { + this.$refs[this.activeName].save() + this.$emit('close-grant', 0) + }, + cancel() { + this.$refs[this.activeName].cancel() + this.$emit('close-grant', 0) } } } @@ -71,6 +90,11 @@ export default { border-right: none; } +.auth-root-class { + margin: 15px 0px 5px; + text-align: right; +} + // ::-webkit-scrollbar { // } diff --git a/frontend/src/views/panel/GrantAuth/role/index.vue b/frontend/src/views/panel/GrantAuth/role/index.vue index 8785b10702..99bca3e460 100644 --- a/frontend/src/views/panel/GrantAuth/role/index.vue +++ b/frontend/src/views/panel/GrantAuth/role/index.vue @@ -2,7 +2,7 @@
import { roleGrid } from '@/api/system/role' import { formatCondition } from '@/utils/index' +import { saveShare, loadShares } from '@/api/panel/share' export default { name: 'GrantRole', props: { resourceId: { type: String, default: null + }, + keyWord: { + type: String, + default: '' } }, data() { @@ -31,7 +36,9 @@ export default { defaultHeadName: '全部', columnLabel: null, filter_options: [{ text: '未分享角色', value: 0 }, { text: '已分享角色', value: 1 }], - fieldName: 'name' + fieldName: 'name', + type: 1, // 类型1代表角色 + shares: [] } }, created() { @@ -50,12 +57,14 @@ export default { const data = response.data // this.total = data.itemCount this.data = data.listObject + this.queryShareNodeIds() }) }, filterHandler(value, row, column) { // const property = column['property'] // return row[property] === value - return row['code'] === 'admin' + const roleId = row['roleId'] + return !(value ^ this.shares.includes(roleId)) }, filterChange(obj) { @@ -65,6 +74,52 @@ export default { return } this.columnLabel = this.filter_options[arr[0]].text + }, + save() { + const rows = this.$refs.table.store.states.selection + const request = this.buildRequest(rows) + saveShare(request).then(res => { + this.$success('保存成功') + return true + }).catch(err => { + this.$error(err.message) + return false + }) + }, + + cancel() { + console.log('role cancel') + }, + buildRequest(rows) { + const targetIds = rows.map(row => row.roleId) + const panelIds = [this.resourceId] + return { + targetIds: targetIds, + panelIds: panelIds, + type: this.type + } + }, + + queryShareNodeIds(callBack) { + const conditionResourceId = { field: 'panel_group_id', operator: 'eq', value: this.resourceId } + const conditionType = { field: 'type', operator: 'eq', value: this.type } + const param = { conditions: [conditionResourceId, conditionType] } + loadShares(param).then(res => { + const shares = res.data + const nodeIds = shares.map(share => share.targetId) + this.shares = nodeIds + this.$nextTick(() => { + this.setCheckNodes() + }) + callBack && callBack() + }) + }, + + setCheckNodes() { + this.data.forEach(node => { + const nodeId = node.roleId + this.shares.includes(nodeId) && this.$refs.table.toggleRowSelection(node, true) + }) } } diff --git a/frontend/src/views/panel/GrantAuth/user/index.vue b/frontend/src/views/panel/GrantAuth/user/index.vue index f36929d659..43b3c57ac5 100644 --- a/frontend/src/views/panel/GrantAuth/user/index.vue +++ b/frontend/src/views/panel/GrantAuth/user/index.vue @@ -2,7 +2,7 @@
import { userLists } from '@/api/system/user' import { formatCondition } from '@/utils/index' +import { saveShare, loadShares } from '@/api/panel/share' export default { name: 'GrantUser', props: { resourceId: { type: String, default: null + }, + keyWord: { + type: String, + default: '' } }, data() { @@ -31,7 +36,9 @@ export default { defaultHeadName: '全部', columnLabel: null, filter_options: [{ text: '未分享人员', value: 0 }, { text: '已分享人员', value: 1 }], - fieldName: 'nickName' + fieldName: 'nickName', + type: 0, // 类型0代表用户 + shares: [] } }, created() { @@ -49,12 +56,14 @@ export default { const data = response.data // this.total = data.itemCount this.data = data.listObject + this.queryShareNodeIds() }) }, filterHandler(value, row, column) { // const property = column['property'] // return row[property] === value - return row['code'] === 'admin' + const userId = row['userId'] + return !(value ^ this.shares.includes(userId)) }, filterChange(obj) { @@ -64,6 +73,53 @@ export default { return } this.columnLabel = this.filter_options[arr[0]].text + }, + + save() { + const rows = this.$refs.table.store.states.selection + const request = this.buildRequest(rows) + saveShare(request).then(res => { + this.$success('保存成功') + return true + }).catch(err => { + this.$error(err.message) + return false + }) + }, + + cancel() { + console.log('user cancel') + }, + buildRequest(rows) { + const targetIds = rows.map(row => row.userId) + const panelIds = [this.resourceId] + return { + targetIds: targetIds, + panelIds: panelIds, + type: this.type + } + }, + + queryShareNodeIds(callBack) { + const conditionResourceId = { field: 'panel_group_id', operator: 'eq', value: this.resourceId } + const conditionType = { field: 'type', operator: 'eq', value: this.type } + const param = { conditions: [conditionResourceId, conditionType] } + loadShares(param).then(res => { + const shares = res.data + const nodeIds = shares.map(share => share.targetId) + this.shares = nodeIds + this.$nextTick(() => { + this.setCheckNodes() + }) + callBack && callBack() + }) + }, + + setCheckNodes() { + this.data.forEach(node => { + const nodeId = node.userId + this.shares.includes(nodeId) && this.$refs.table.toggleRowSelection(node, true) + }) } } diff --git a/frontend/src/views/panel/list/PanelList.vue b/frontend/src/views/panel/list/PanelList.vue index f1770358c8..e4d33e628d 100644 --- a/frontend/src/views/panel/list/PanelList.vue +++ b/frontend/src/views/panel/list/PanelList.vue @@ -113,15 +113,13 @@ - - + + @@ -486,9 +484,9 @@ export default { this.authTitle = '把[' + data.label + ']分享给' this.authVisible = true }, - handleClose(done) { + closeGrant() { this.authResourceId = null - this.handleClose = false + this.authVisible = false } } } From 760b05e2773e21320f1dc91421cb76e8b6653c5a Mon Sep 17 00:00:00 2001 From: fit2cloud-chenyw Date: Thu, 18 Mar 2021 16:56:24 +0800 Subject: [PATCH 06/15] =?UTF-8?q?feat:=20=E5=88=86=E4=BA=AB=E9=A1=B5?= =?UTF-8?q?=E9=9D=A2api?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/api/panel/share.js | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 frontend/src/api/panel/share.js diff --git a/frontend/src/api/panel/share.js b/frontend/src/api/panel/share.js new file mode 100644 index 0000000000..ed12ea2301 --- /dev/null +++ b/frontend/src/api/panel/share.js @@ -0,0 +1,20 @@ +import request from '@/utils/request' + +export function saveShare(data) { + return request({ + url: '/api/share/', + method: 'post', + loading: true, + data + }) +} + +export function loadShares(data) { + return request({ + url: '/api/share/queryWithResourceId', + method: 'post', + loading: true, + data + }) +} + From f891dc5acacb98bd225174af3b2ec2280f2c40fb Mon Sep 17 00:00:00 2001 From: junjie Date: Thu, 18 Mar 2021 17:20:59 +0800 Subject: [PATCH 07/15] =?UTF-8?q?feat(=E8=A7=86=E5=9B=BE):=201.=E4=B8=B0?= =?UTF-8?q?=E5=AF=8Cchart=E7=A7=8D=E7=B1=BB=EF=BC=9B2.echarts=20option?= =?UTF-8?q?=E5=B0=81=E8=A3=85=EF=BC=9B3.=E5=A2=9E=E5=8A=A0=E4=B8=80?= =?UTF-8?q?=E4=BA=9B=E4=B8=8D=E5=A4=AA=E5=A5=BD=E7=9C=8B=E7=9A=84svg?= =?UTF-8?q?=E4=BD=9C=E4=B8=BA=E5=9B=BE=E8=A1=A8=E7=B1=BB=E5=9E=8Bicon-font?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/icons/svg/bar-horizontal.svg | 1 + .../src/icons/svg/bar-stack-horizontal.svg | 1 + frontend/src/icons/svg/bar-stack.svg | 1 + frontend/src/icons/svg/bar.svg | 1 + frontend/src/icons/svg/funnel.svg | 1 + frontend/src/icons/svg/line.svg | 1 + frontend/src/icons/svg/pie.svg | 1 + frontend/src/lang/zh.js | 3 +- frontend/src/views/chart/chart/bar/bar.js | 81 ++++++++++++++++ frontend/src/views/chart/chart/bar/baseBar.js | 21 ---- frontend/src/views/chart/chart/chart.js | 95 ++++++++++++++++++- .../src/views/chart/chart/funnel/funnel.js | 34 +++++++ .../chart/chart/line/{baseLine.js => line.js} | 30 +++--- frontend/src/views/chart/chart/pie/pie.js | 34 +++++++ frontend/src/views/chart/chart/util.js | 19 ++++ .../views/chart/components/ChartComponent.vue | 18 +++- .../views/chart/components/ColorSelector.vue | 10 +- .../src/views/chart/components/QuotaItem.vue | 4 +- frontend/src/views/chart/view/ChartEdit.vue | 36 ++++++- 19 files changed, 346 insertions(+), 46 deletions(-) create mode 100644 frontend/src/icons/svg/bar-horizontal.svg create mode 100644 frontend/src/icons/svg/bar-stack-horizontal.svg create mode 100644 frontend/src/icons/svg/bar-stack.svg create mode 100644 frontend/src/icons/svg/bar.svg create mode 100644 frontend/src/icons/svg/funnel.svg create mode 100644 frontend/src/icons/svg/line.svg create mode 100644 frontend/src/icons/svg/pie.svg create mode 100644 frontend/src/views/chart/chart/bar/bar.js delete mode 100644 frontend/src/views/chart/chart/bar/baseBar.js create mode 100644 frontend/src/views/chart/chart/funnel/funnel.js rename frontend/src/views/chart/chart/line/{baseLine.js => line.js} (53%) create mode 100644 frontend/src/views/chart/chart/pie/pie.js create mode 100644 frontend/src/views/chart/chart/util.js diff --git a/frontend/src/icons/svg/bar-horizontal.svg b/frontend/src/icons/svg/bar-horizontal.svg new file mode 100644 index 0000000000..6ade56b3c8 --- /dev/null +++ b/frontend/src/icons/svg/bar-horizontal.svg @@ -0,0 +1 @@ + diff --git a/frontend/src/icons/svg/bar-stack-horizontal.svg b/frontend/src/icons/svg/bar-stack-horizontal.svg new file mode 100644 index 0000000000..9a78910ab6 --- /dev/null +++ b/frontend/src/icons/svg/bar-stack-horizontal.svg @@ -0,0 +1 @@ + diff --git a/frontend/src/icons/svg/bar-stack.svg b/frontend/src/icons/svg/bar-stack.svg new file mode 100644 index 0000000000..90beda11f0 --- /dev/null +++ b/frontend/src/icons/svg/bar-stack.svg @@ -0,0 +1 @@ + diff --git a/frontend/src/icons/svg/bar.svg b/frontend/src/icons/svg/bar.svg new file mode 100644 index 0000000000..2136e79aad --- /dev/null +++ b/frontend/src/icons/svg/bar.svg @@ -0,0 +1 @@ + diff --git a/frontend/src/icons/svg/funnel.svg b/frontend/src/icons/svg/funnel.svg new file mode 100644 index 0000000000..89190945f5 --- /dev/null +++ b/frontend/src/icons/svg/funnel.svg @@ -0,0 +1 @@ + diff --git a/frontend/src/icons/svg/line.svg b/frontend/src/icons/svg/line.svg new file mode 100644 index 0000000000..c72c676e2b --- /dev/null +++ b/frontend/src/icons/svg/line.svg @@ -0,0 +1 @@ + diff --git a/frontend/src/icons/svg/pie.svg b/frontend/src/icons/svg/pie.svg new file mode 100644 index 0000000000..7d7c52824e --- /dev/null +++ b/frontend/src/icons/svg/pie.svg @@ -0,0 +1 @@ + diff --git a/frontend/src/lang/zh.js b/frontend/src/lang/zh.js index 46ef617959..96afef2bb0 100644 --- a/frontend/src/lang/zh.js +++ b/frontend/src/lang/zh.js @@ -614,7 +614,8 @@ export default { color_gentle: '柔和', color_elegant: '淡雅', color_technology: '科技', - color_simple: '简洁' + color_simple: '简洁', + not_alpha: '不透明度' }, dataset: { datalist: '数据集', diff --git a/frontend/src/views/chart/chart/bar/bar.js b/frontend/src/views/chart/chart/bar/bar.js new file mode 100644 index 0000000000..1200b1d3a3 --- /dev/null +++ b/frontend/src/views/chart/chart/bar/bar.js @@ -0,0 +1,81 @@ +import { hexColorToRGBA } from '../util.js' + +export function baseBarOption(chart_option, chart) { + // 处理shape attr + let customAttr = {} + if (chart.customAttr) { + customAttr = JSON.parse(chart.customAttr) + if (customAttr.color) { + chart_option.color = customAttr.color.colors + } + } + // 处理data + if (chart.data) { + chart_option.title.text = chart.title + chart_option.xAxis.data = chart.data.x + for (let i = 0; i < chart.data.series.length; i++) { + const y = chart.data.series[i] + y.itemStyle = { + color: hexColorToRGBA(customAttr.color.colors[i % 9], customAttr.color.alpha) + } + y.type = 'bar' + chart_option.legend.data.push(y.name) + chart_option.series.push(y) + } + } + // console.log(chart_option); + return chart_option +} + +export function stackBarOption(chart_option, chart) { + baseBarOption(chart_option, chart) + + // ext + chart_option.series.forEach(function(s) { + s.stack = 'stack' + s.emphasis = { + focus: 'series' + } + }) + return chart_option +} + +export function horizontalBarOption(chart_option, chart) { + // 处理shape attr + let customAttr = {} + if (chart.customAttr) { + customAttr = JSON.parse(chart.customAttr) + if (customAttr.color) { + chart_option.color = customAttr.color.colors + } + } + // 处理data + if (chart.data) { + chart_option.title.text = chart.title + chart_option.yAxis.data = chart.data.x + for (let i = 0; i < chart.data.series.length; i++) { + const y = chart.data.series[i] + y.itemStyle = { + color: hexColorToRGBA(customAttr.color.colors[i % 9], customAttr.color.alpha) + } + y.type = 'bar' + chart_option.legend.data.push(y.name) + chart_option.series.push(y) + } + } + // console.log(chart_option); + return chart_option +} + +export function horizontalStackBarOption(chart_option, chart) { + horizontalBarOption(chart_option, chart) + + // ext + chart_option.series.forEach(function(s) { + s.stack = 'stack' + s.emphasis = { + focus: 'series' + } + }) + return chart_option +} diff --git a/frontend/src/views/chart/chart/bar/baseBar.js b/frontend/src/views/chart/chart/bar/baseBar.js deleted file mode 100644 index 69788002e1..0000000000 --- a/frontend/src/views/chart/chart/bar/baseBar.js +++ /dev/null @@ -1,21 +0,0 @@ -export function baseBarOption(chart_option, chart) { -// 处理data - if (chart.data) { - chart_option.title.text = chart.title - chart_option.xAxis.data = chart.data.x - chart.data.series.forEach(function(y) { - chart_option.legend.data.push(y.name) - chart_option.series.push(y) - }) - } - // console.log(chart_option); - // 处理shape attr - if (chart.customAttr) { - const customAttr = JSON.parse(chart.customAttr) - if (customAttr.color) { - chart_option.color = customAttr.color.colors - } - } - return chart_option -} - diff --git a/frontend/src/views/chart/chart/chart.js b/frontend/src/views/chart/chart/chart.js index ee38bc088f..53142e5580 100644 --- a/frontend/src/views/chart/chart/chart.js +++ b/frontend/src/views/chart/chart/chart.js @@ -1,6 +1,7 @@ export const DEFAULT_COLOR_CASE = { value: 'default', - colors: ['#5470c6', '#91cc75', '#fac858', '#ee6666', '#73c0de', '#3ba272', '#fc8452', '#9a60b4', '#ea7ccc'] + colors: ['#5470c6', '#91cc75', '#fac858', '#ee6666', '#73c0de', '#3ba272', '#fc8452', '#9a60b4', '#ea7ccc'], + alpha: 100 } export const BASE_BAR = { title: { @@ -18,6 +19,22 @@ export const BASE_BAR = { }, series: [] } +export const HORIZONTAL_BAR = { + title: { + text: '' + }, + tooltip: {}, + legend: { + data: [] + }, + xAxis: { + type: 'value' + }, + yAxis: { + data: [] + }, + series: [] +} export const BASE_LINE = { title: { @@ -36,6 +53,78 @@ export const BASE_LINE = { series: [] } -export default { - BASE_BAR, BASE_LINE, DEFAULT_COLOR_CASE +export const BASE_PIE = { + title: { + text: '' + }, + tooltip: { + trigger: 'item', + formatter: '{a}
{b}: {c} ({d}%)' + }, + legend: {}, + series: [ + { + name: '', + type: 'pie', + radius: ['0%', '60%'], + avoidLabelOverlap: false, + emphasis: { + itemStyle: { + shadowBlur: 10, + shadowOffsetX: 0, + shadowColor: 'rgba(0, 0, 0, 0.5)' + } + }, + data: [] + } + ] +} + +export const BASE_FUNNEL = { + title: { + text: '' + }, + tooltip: { + trigger: 'item' + }, + legend: { + // data: [] + }, + series: [ + { + name: '', + type: 'funnel', + left: '10%', + top: 60, + bottom: 60, + width: '80%', + min: 0, + max: 100, + minSize: '0%', + maxSize: '100%', + sort: 'descending', + gap: 1, + // label: { + // show: true, + // position: 'inside' + // }, + labelLine: { + length: 10, + lineStyle: { + width: 1, + type: 'solid' + } + }, + itemStyle: { + borderColor: '#fff', + borderWidth: 1 + }, + emphasis: { + label: { + fontSize: 20 + } + }, + data: [] + } + ] } diff --git a/frontend/src/views/chart/chart/funnel/funnel.js b/frontend/src/views/chart/chart/funnel/funnel.js new file mode 100644 index 0000000000..639f58c36a --- /dev/null +++ b/frontend/src/views/chart/chart/funnel/funnel.js @@ -0,0 +1,34 @@ +import { hexColorToRGBA } from '@/views/chart/chart/util' + +export function baseFunnelOption(chart_option, chart) { + // 处理shape attr + let customAttr = {} + if (chart.customAttr) { + customAttr = JSON.parse(chart.customAttr) + if (customAttr.color) { + chart_option.color = customAttr.color.colors + } + } + // 处理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 + const valueArr = chart.data.series[0].data + for (let i = 0; i < valueArr.length; i++) { + const y = { + name: chart.data.x[i], + value: valueArr[i] + } + y.itemStyle = { + color: hexColorToRGBA(customAttr.color.colors[i % 9], customAttr.color.alpha) + } + y.type = 'funnel' + chart_option.series[0].data.push(y) + } + } + } + // console.log(chart_option); + return chart_option +} + diff --git a/frontend/src/views/chart/chart/line/baseLine.js b/frontend/src/views/chart/chart/line/line.js similarity index 53% rename from frontend/src/views/chart/chart/line/baseLine.js rename to frontend/src/views/chart/chart/line/line.js index d431f2758d..8fe395b7e7 100644 --- a/frontend/src/views/chart/chart/line/baseLine.js +++ b/frontend/src/views/chart/chart/line/line.js @@ -1,21 +1,29 @@ +import { hexColorToRGBA } from '@/views/chart/chart/util' + export function baseLineOption(chart_option, chart) { -// 处理data - if (chart.data) { - chart_option.title.text = chart.title - chart_option.xAxis.data = chart.data.x - chart.data.series.forEach(function(y) { - chart_option.legend.data.push(y.name) - chart_option.series.push(y) - }) - } - // console.log(chart_option); // 处理shape attr + let customAttr = {} if (chart.customAttr) { - const customAttr = JSON.parse(chart.customAttr) + customAttr = JSON.parse(chart.customAttr) if (customAttr.color) { chart_option.color = customAttr.color.colors } } + // 处理data + if (chart.data) { + chart_option.title.text = chart.title + chart_option.xAxis.data = chart.data.x + for (let i = 0; i < chart.data.series.length; i++) { + const y = chart.data.series[i] + y.itemStyle = { + color: hexColorToRGBA(customAttr.color.colors[i % 9], customAttr.color.alpha) + } + y.type = 'line' + chart_option.legend.data.push(y.name) + chart_option.series.push(y) + } + } + // console.log(chart_option); return chart_option } diff --git a/frontend/src/views/chart/chart/pie/pie.js b/frontend/src/views/chart/chart/pie/pie.js new file mode 100644 index 0000000000..8739c4a0e1 --- /dev/null +++ b/frontend/src/views/chart/chart/pie/pie.js @@ -0,0 +1,34 @@ +import { hexColorToRGBA } from '@/views/chart/chart/util' + +export function basePieOption(chart_option, chart) { + // 处理shape attr + let customAttr = {} + if (chart.customAttr) { + customAttr = JSON.parse(chart.customAttr) + if (customAttr.color) { + chart_option.color = customAttr.color.colors + } + } + // 处理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 + const valueArr = chart.data.series[0].data + for (let i = 0; i < valueArr.length; i++) { + const y = { + name: chart.data.x[i], + value: valueArr[i] + } + y.itemStyle = { + color: hexColorToRGBA(customAttr.color.colors[i % 9], customAttr.color.alpha) + } + y.type = 'pie' + chart_option.series[0].data.push(y) + } + } + } + // console.log(chart_option); + return chart_option +} + diff --git a/frontend/src/views/chart/chart/util.js b/frontend/src/views/chart/chart/util.js new file mode 100644 index 0000000000..1429a54fd2 --- /dev/null +++ b/frontend/src/views/chart/chart/util.js @@ -0,0 +1,19 @@ +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) { + rgb.push(eval('0x' + kw)) // 十六进制转化为十进制并存如数组 + }) + return `rgba(${rgb.join(',')},${alpha / 100})` // 输出RGB格式颜色 + } else { + console.log(`Input ${hex} is wrong!`) + return 'rgb(0,0,0)' + } +} diff --git a/frontend/src/views/chart/components/ChartComponent.vue b/frontend/src/views/chart/components/ChartComponent.vue index 4aac1f97ab..8af9544824 100644 --- a/frontend/src/views/chart/components/ChartComponent.vue +++ b/frontend/src/views/chart/components/ChartComponent.vue @@ -5,9 +5,11 @@ - From a83864e13da737fa248d1a87547f686d7b3e1e84 Mon Sep 17 00:00:00 2001 From: junjie Date: Thu, 18 Mar 2021 17:55:28 +0800 Subject: [PATCH 08/15] =?UTF-8?q?feat(=E8=A7=86=E5=9B=BE):=20=E6=BC=8F?= =?UTF-8?q?=E6=96=97=E5=9B=BE=E9=85=8D=E7=BD=AE=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/views/chart/chart/chart.js | 2 +- frontend/src/views/chart/chart/funnel/funnel.js | 1 + frontend/src/views/chart/components/ChartComponent.vue | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/frontend/src/views/chart/chart/chart.js b/frontend/src/views/chart/chart/chart.js index 53142e5580..3a0e91698e 100644 --- a/frontend/src/views/chart/chart/chart.js +++ b/frontend/src/views/chart/chart/chart.js @@ -94,7 +94,7 @@ export const BASE_FUNNEL = { { name: '', type: 'funnel', - left: '10%', + left: 'center', top: 60, bottom: 60, width: '80%', diff --git a/frontend/src/views/chart/chart/funnel/funnel.js b/frontend/src/views/chart/chart/funnel/funnel.js index 639f58c36a..96bbcf9a96 100644 --- a/frontend/src/views/chart/chart/funnel/funnel.js +++ b/frontend/src/views/chart/chart/funnel/funnel.js @@ -15,6 +15,7 @@ export function baseFunnelOption(chart_option, chart) { if (chart.data.series.length > 0) { chart_option.series[0].name = chart.data.series[0].name const valueArr = chart.data.series[0].data + chart_option.series[0].max = Math.max.apply(Math, valueArr) for (let i = 0; i < valueArr.length; i++) { const y = { name: chart.data.x[i], diff --git a/frontend/src/views/chart/components/ChartComponent.vue b/frontend/src/views/chart/components/ChartComponent.vue index 8af9544824..fe4e9fffd8 100644 --- a/frontend/src/views/chart/components/ChartComponent.vue +++ b/frontend/src/views/chart/components/ChartComponent.vue @@ -53,7 +53,7 @@ export default { } else if (chart.type === 'funnel') { chart_option = baseFunnelOption(JSON.parse(JSON.stringify(BASE_FUNNEL)), chart) } - // console.log(chart_option); + console.log(chart_option) this.myEcharts(chart_option) }, myEcharts(option) { From e97297fd84321888ffe3cd564f06170d4f479e74 Mon Sep 17 00:00:00 2001 From: TaoJinlong Date: Thu, 18 Mar 2021 17:59:52 +0800 Subject: [PATCH 09/15] =?UTF-8?q?feat:=20=E5=A2=9E=E9=87=8F=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/pom.xml | 5 + .../domain/DatasetTableIncrementalConfig.java | 17 + .../DatasetTableIncrementalConfigExample.java | 480 ++++++++++++++++++ .../DatasetTableIncrementalConfigMapper.java | 22 + .../DatasetTableIncrementalConfigMapper.xml | 164 ++++++ .../commons/constants/ScheduleType.java | 2 +- .../commons/constants/UpdateType.java | 5 + .../dataset/DataSetTableController.java | 12 + .../dataease/job/sechedule/DeScheduleJob.java | 2 + .../job/sechedule/ExtractDataJob.java | 2 +- .../job/sechedule/ScheduleManager.java | 3 +- .../io/dataease/service/ScheduleService.java | 10 +- .../service/dataset/DataSetTableService.java | 53 +- .../dataset/DataSetTableTaskService.java | 4 + .../service/dataset/ExtractDataService.java | 206 ++++++-- .../migration/V13__dataset_tables_incre.sql | 10 + .../src/main/resources/generatorConfig.xml | 19 +- frontend/src/lang/zh.js | 8 +- .../src/views/dataset/data/UpdateInfo.vue | 211 ++++++-- .../src/views/system/datasource/index.vue | 11 +- 20 files changed, 1153 insertions(+), 93 deletions(-) create mode 100644 backend/src/main/java/io/dataease/base/domain/DatasetTableIncrementalConfig.java create mode 100644 backend/src/main/java/io/dataease/base/domain/DatasetTableIncrementalConfigExample.java create mode 100644 backend/src/main/java/io/dataease/base/mapper/DatasetTableIncrementalConfigMapper.java create mode 100644 backend/src/main/java/io/dataease/base/mapper/DatasetTableIncrementalConfigMapper.xml create mode 100644 backend/src/main/java/io/dataease/commons/constants/UpdateType.java create mode 100644 backend/src/main/resources/db/migration/V13__dataset_tables_incre.sql diff --git a/backend/pom.xml b/backend/pom.xml index 177a028f21..1523947dec 100644 --- a/backend/pom.xml +++ b/backend/pom.xml @@ -326,6 +326,11 @@ hbase-common 2.4.1 + + org.apache.hbase + hbase-mapreduce + 2.4.1 + org.testng diff --git a/backend/src/main/java/io/dataease/base/domain/DatasetTableIncrementalConfig.java b/backend/src/main/java/io/dataease/base/domain/DatasetTableIncrementalConfig.java new file mode 100644 index 0000000000..33b94f2d03 --- /dev/null +++ b/backend/src/main/java/io/dataease/base/domain/DatasetTableIncrementalConfig.java @@ -0,0 +1,17 @@ +package io.dataease.base.domain; + +import java.io.Serializable; +import lombok.Data; + +@Data +public class DatasetTableIncrementalConfig implements Serializable { + private String id; + + private String tableId; + + private String incrementalDelete; + + private String incrementalAdd; + + private static final long serialVersionUID = 1L; +} \ No newline at end of file diff --git a/backend/src/main/java/io/dataease/base/domain/DatasetTableIncrementalConfigExample.java b/backend/src/main/java/io/dataease/base/domain/DatasetTableIncrementalConfigExample.java new file mode 100644 index 0000000000..9750acef68 --- /dev/null +++ b/backend/src/main/java/io/dataease/base/domain/DatasetTableIncrementalConfigExample.java @@ -0,0 +1,480 @@ +package io.dataease.base.domain; + +import java.util.ArrayList; +import java.util.List; + +public class DatasetTableIncrementalConfigExample { + protected String orderByClause; + + protected boolean distinct; + + protected List oredCriteria; + + public DatasetTableIncrementalConfigExample() { + oredCriteria = new ArrayList(); + } + + public void setOrderByClause(String orderByClause) { + this.orderByClause = orderByClause; + } + + public String getOrderByClause() { + return orderByClause; + } + + public void setDistinct(boolean distinct) { + this.distinct = distinct; + } + + public boolean isDistinct() { + return distinct; + } + + public List getOredCriteria() { + return oredCriteria; + } + + public void or(Criteria criteria) { + oredCriteria.add(criteria); + } + + public Criteria or() { + Criteria criteria = createCriteriaInternal(); + oredCriteria.add(criteria); + return criteria; + } + + public Criteria createCriteria() { + Criteria criteria = createCriteriaInternal(); + if (oredCriteria.size() == 0) { + oredCriteria.add(criteria); + } + return criteria; + } + + protected Criteria createCriteriaInternal() { + Criteria criteria = new Criteria(); + return criteria; + } + + public void clear() { + oredCriteria.clear(); + orderByClause = null; + distinct = false; + } + + protected abstract static class GeneratedCriteria { + protected List criteria; + + protected GeneratedCriteria() { + super(); + criteria = new ArrayList(); + } + + public boolean isValid() { + return criteria.size() > 0; + } + + public List getAllCriteria() { + return criteria; + } + + public List getCriteria() { + return criteria; + } + + protected void addCriterion(String condition) { + if (condition == null) { + throw new RuntimeException("Value for condition cannot be null"); + } + criteria.add(new Criterion(condition)); + } + + protected void addCriterion(String condition, Object value, String property) { + if (value == null) { + throw new RuntimeException("Value for " + property + " cannot be null"); + } + criteria.add(new Criterion(condition, value)); + } + + protected void addCriterion(String condition, Object value1, Object value2, String property) { + if (value1 == null || value2 == null) { + throw new RuntimeException("Between values for " + property + " cannot be null"); + } + criteria.add(new Criterion(condition, value1, value2)); + } + + public Criteria andIdIsNull() { + addCriterion("id is null"); + return (Criteria) this; + } + + public Criteria andIdIsNotNull() { + addCriterion("id is not null"); + return (Criteria) this; + } + + public Criteria andIdEqualTo(String value) { + addCriterion("id =", value, "id"); + return (Criteria) this; + } + + public Criteria andIdNotEqualTo(String value) { + addCriterion("id <>", value, "id"); + return (Criteria) this; + } + + public Criteria andIdGreaterThan(String value) { + addCriterion("id >", value, "id"); + return (Criteria) this; + } + + public Criteria andIdGreaterThanOrEqualTo(String value) { + addCriterion("id >=", value, "id"); + return (Criteria) this; + } + + public Criteria andIdLessThan(String value) { + addCriterion("id <", value, "id"); + return (Criteria) this; + } + + public Criteria andIdLessThanOrEqualTo(String value) { + addCriterion("id <=", value, "id"); + return (Criteria) this; + } + + public Criteria andIdLike(String value) { + addCriterion("id like", value, "id"); + return (Criteria) this; + } + + public Criteria andIdNotLike(String value) { + addCriterion("id not like", value, "id"); + return (Criteria) this; + } + + public Criteria andIdIn(List values) { + addCriterion("id in", values, "id"); + return (Criteria) this; + } + + public Criteria andIdNotIn(List values) { + addCriterion("id not in", values, "id"); + return (Criteria) this; + } + + public Criteria andIdBetween(String value1, String value2) { + addCriterion("id between", value1, value2, "id"); + return (Criteria) this; + } + + public Criteria andIdNotBetween(String value1, String value2) { + addCriterion("id not between", value1, value2, "id"); + return (Criteria) this; + } + + public Criteria andTableIdIsNull() { + addCriterion("table_id is null"); + return (Criteria) this; + } + + public Criteria andTableIdIsNotNull() { + addCriterion("table_id is not null"); + return (Criteria) this; + } + + public Criteria andTableIdEqualTo(String value) { + addCriterion("table_id =", value, "tableId"); + return (Criteria) this; + } + + public Criteria andTableIdNotEqualTo(String value) { + addCriterion("table_id <>", value, "tableId"); + return (Criteria) this; + } + + public Criteria andTableIdGreaterThan(String value) { + addCriterion("table_id >", value, "tableId"); + return (Criteria) this; + } + + public Criteria andTableIdGreaterThanOrEqualTo(String value) { + addCriterion("table_id >=", value, "tableId"); + return (Criteria) this; + } + + public Criteria andTableIdLessThan(String value) { + addCriterion("table_id <", value, "tableId"); + return (Criteria) this; + } + + public Criteria andTableIdLessThanOrEqualTo(String value) { + addCriterion("table_id <=", value, "tableId"); + return (Criteria) this; + } + + public Criteria andTableIdLike(String value) { + addCriterion("table_id like", value, "tableId"); + return (Criteria) this; + } + + public Criteria andTableIdNotLike(String value) { + addCriterion("table_id not like", value, "tableId"); + return (Criteria) this; + } + + public Criteria andTableIdIn(List values) { + addCriterion("table_id in", values, "tableId"); + return (Criteria) this; + } + + public Criteria andTableIdNotIn(List values) { + addCriterion("table_id not in", values, "tableId"); + return (Criteria) this; + } + + public Criteria andTableIdBetween(String value1, String value2) { + addCriterion("table_id between", value1, value2, "tableId"); + return (Criteria) this; + } + + public Criteria andTableIdNotBetween(String value1, String value2) { + addCriterion("table_id not between", value1, value2, "tableId"); + return (Criteria) this; + } + + public Criteria andIncrementalDeleteIsNull() { + addCriterion("incremental_delete is null"); + return (Criteria) this; + } + + public Criteria andIncrementalDeleteIsNotNull() { + addCriterion("incremental_delete is not null"); + return (Criteria) this; + } + + public Criteria andIncrementalDeleteEqualTo(String value) { + addCriterion("incremental_delete =", value, "incrementalDelete"); + return (Criteria) this; + } + + public Criteria andIncrementalDeleteNotEqualTo(String value) { + addCriterion("incremental_delete <>", value, "incrementalDelete"); + return (Criteria) this; + } + + public Criteria andIncrementalDeleteGreaterThan(String value) { + addCriterion("incremental_delete >", value, "incrementalDelete"); + return (Criteria) this; + } + + public Criteria andIncrementalDeleteGreaterThanOrEqualTo(String value) { + addCriterion("incremental_delete >=", value, "incrementalDelete"); + return (Criteria) this; + } + + public Criteria andIncrementalDeleteLessThan(String value) { + addCriterion("incremental_delete <", value, "incrementalDelete"); + return (Criteria) this; + } + + public Criteria andIncrementalDeleteLessThanOrEqualTo(String value) { + addCriterion("incremental_delete <=", value, "incrementalDelete"); + return (Criteria) this; + } + + public Criteria andIncrementalDeleteLike(String value) { + addCriterion("incremental_delete like", value, "incrementalDelete"); + return (Criteria) this; + } + + public Criteria andIncrementalDeleteNotLike(String value) { + addCriterion("incremental_delete not like", value, "incrementalDelete"); + return (Criteria) this; + } + + public Criteria andIncrementalDeleteIn(List values) { + addCriterion("incremental_delete in", values, "incrementalDelete"); + return (Criteria) this; + } + + public Criteria andIncrementalDeleteNotIn(List values) { + addCriterion("incremental_delete not in", values, "incrementalDelete"); + return (Criteria) this; + } + + public Criteria andIncrementalDeleteBetween(String value1, String value2) { + addCriterion("incremental_delete between", value1, value2, "incrementalDelete"); + return (Criteria) this; + } + + public Criteria andIncrementalDeleteNotBetween(String value1, String value2) { + addCriterion("incremental_delete not between", value1, value2, "incrementalDelete"); + return (Criteria) this; + } + + public Criteria andIncrementalAddIsNull() { + addCriterion("incremental_add is null"); + return (Criteria) this; + } + + public Criteria andIncrementalAddIsNotNull() { + addCriterion("incremental_add is not null"); + return (Criteria) this; + } + + public Criteria andIncrementalAddEqualTo(String value) { + addCriterion("incremental_add =", value, "incrementalAdd"); + return (Criteria) this; + } + + public Criteria andIncrementalAddNotEqualTo(String value) { + addCriterion("incremental_add <>", value, "incrementalAdd"); + return (Criteria) this; + } + + public Criteria andIncrementalAddGreaterThan(String value) { + addCriterion("incremental_add >", value, "incrementalAdd"); + return (Criteria) this; + } + + public Criteria andIncrementalAddGreaterThanOrEqualTo(String value) { + addCriterion("incremental_add >=", value, "incrementalAdd"); + return (Criteria) this; + } + + public Criteria andIncrementalAddLessThan(String value) { + addCriterion("incremental_add <", value, "incrementalAdd"); + return (Criteria) this; + } + + public Criteria andIncrementalAddLessThanOrEqualTo(String value) { + addCriterion("incremental_add <=", value, "incrementalAdd"); + return (Criteria) this; + } + + public Criteria andIncrementalAddLike(String value) { + addCriterion("incremental_add like", value, "incrementalAdd"); + return (Criteria) this; + } + + public Criteria andIncrementalAddNotLike(String value) { + addCriterion("incremental_add not like", value, "incrementalAdd"); + return (Criteria) this; + } + + public Criteria andIncrementalAddIn(List values) { + addCriterion("incremental_add in", values, "incrementalAdd"); + return (Criteria) this; + } + + public Criteria andIncrementalAddNotIn(List values) { + addCriterion("incremental_add not in", values, "incrementalAdd"); + return (Criteria) this; + } + + public Criteria andIncrementalAddBetween(String value1, String value2) { + addCriterion("incremental_add between", value1, value2, "incrementalAdd"); + return (Criteria) this; + } + + public Criteria andIncrementalAddNotBetween(String value1, String value2) { + addCriterion("incremental_add not between", value1, value2, "incrementalAdd"); + return (Criteria) this; + } + } + + public static class Criteria extends GeneratedCriteria { + + protected Criteria() { + super(); + } + } + + public static class Criterion { + private String condition; + + private Object value; + + private Object secondValue; + + private boolean noValue; + + private boolean singleValue; + + private boolean betweenValue; + + private boolean listValue; + + private String typeHandler; + + public String getCondition() { + return condition; + } + + public Object getValue() { + return value; + } + + public Object getSecondValue() { + return secondValue; + } + + public boolean isNoValue() { + return noValue; + } + + public boolean isSingleValue() { + return singleValue; + } + + public boolean isBetweenValue() { + return betweenValue; + } + + public boolean isListValue() { + return listValue; + } + + public String getTypeHandler() { + return typeHandler; + } + + protected Criterion(String condition) { + super(); + this.condition = condition; + this.typeHandler = null; + this.noValue = true; + } + + protected Criterion(String condition, Object value, String typeHandler) { + super(); + this.condition = condition; + this.value = value; + this.typeHandler = typeHandler; + if (value instanceof List) { + this.listValue = true; + } else { + this.singleValue = true; + } + } + + protected Criterion(String condition, Object value) { + this(condition, value, null); + } + + protected Criterion(String condition, Object value, Object secondValue, String typeHandler) { + super(); + this.condition = condition; + this.value = value; + this.secondValue = secondValue; + this.typeHandler = typeHandler; + this.betweenValue = true; + } + + protected Criterion(String condition, Object value, Object secondValue) { + this(condition, value, secondValue, null); + } + } +} \ No newline at end of file diff --git a/backend/src/main/java/io/dataease/base/mapper/DatasetTableIncrementalConfigMapper.java b/backend/src/main/java/io/dataease/base/mapper/DatasetTableIncrementalConfigMapper.java new file mode 100644 index 0000000000..dc7637adf3 --- /dev/null +++ b/backend/src/main/java/io/dataease/base/mapper/DatasetTableIncrementalConfigMapper.java @@ -0,0 +1,22 @@ +package io.dataease.base.mapper; + +import io.dataease.base.domain.DatasetTableIncrementalConfig; +import io.dataease.base.domain.DatasetTableIncrementalConfigExample; +import java.util.List; +import org.apache.ibatis.annotations.Param; + +public interface DatasetTableIncrementalConfigMapper { + long countByExample(DatasetTableIncrementalConfigExample example); + + int deleteByExample(DatasetTableIncrementalConfigExample example); + + int insert(DatasetTableIncrementalConfig record); + + int insertSelective(DatasetTableIncrementalConfig record); + + List selectByExample(DatasetTableIncrementalConfigExample example); + + int updateByExampleSelective(@Param("record") DatasetTableIncrementalConfig record, @Param("example") DatasetTableIncrementalConfigExample example); + + int updateByExample(@Param("record") DatasetTableIncrementalConfig record, @Param("example") DatasetTableIncrementalConfigExample example); +} \ No newline at end of file diff --git a/backend/src/main/java/io/dataease/base/mapper/DatasetTableIncrementalConfigMapper.xml b/backend/src/main/java/io/dataease/base/mapper/DatasetTableIncrementalConfigMapper.xml new file mode 100644 index 0000000000..b21c1704da --- /dev/null +++ b/backend/src/main/java/io/dataease/base/mapper/DatasetTableIncrementalConfigMapper.xml @@ -0,0 +1,164 @@ + + + + + + + + + + + + + + + + + + and ${criterion.condition} + + + and ${criterion.condition} #{criterion.value} + + + and ${criterion.condition} #{criterion.value} and #{criterion.secondValue} + + + and ${criterion.condition} + + #{listItem} + + + + + + + + + + + + + + + + + + and ${criterion.condition} + + + and ${criterion.condition} #{criterion.value} + + + and ${criterion.condition} #{criterion.value} and #{criterion.secondValue} + + + and ${criterion.condition} + + #{listItem} + + + + + + + + + + + id, table_id, incremental_delete, incremental_add + + + + delete from dataset_table_incremental_config + + + + + + insert into dataset_table_incremental_config (id, table_id, incremental_delete, + incremental_add) + values (#{id,jdbcType=VARCHAR}, #{tableId,jdbcType=VARCHAR}, #{incrementalDelete,jdbcType=VARCHAR}, + #{incrementalAdd,jdbcType=VARCHAR}) + + + insert into dataset_table_incremental_config + + + id, + + + table_id, + + + incremental_delete, + + + incremental_add, + + + + + #{id,jdbcType=VARCHAR}, + + + #{tableId,jdbcType=VARCHAR}, + + + #{incrementalDelete,jdbcType=VARCHAR}, + + + #{incrementalAdd,jdbcType=VARCHAR}, + + + + + + update dataset_table_incremental_config + + + id = #{record.id,jdbcType=VARCHAR}, + + + table_id = #{record.tableId,jdbcType=VARCHAR}, + + + incremental_delete = #{record.incrementalDelete,jdbcType=VARCHAR}, + + + incremental_add = #{record.incrementalAdd,jdbcType=VARCHAR}, + + + + + + + + update dataset_table_incremental_config + set id = #{record.id,jdbcType=VARCHAR}, + table_id = #{record.tableId,jdbcType=VARCHAR}, + incremental_delete = #{record.incrementalDelete,jdbcType=VARCHAR}, + incremental_add = #{record.incrementalAdd,jdbcType=VARCHAR} + + + + + \ No newline at end of file diff --git a/backend/src/main/java/io/dataease/commons/constants/ScheduleType.java b/backend/src/main/java/io/dataease/commons/constants/ScheduleType.java index 98b4fde4dd..18aeb65588 100644 --- a/backend/src/main/java/io/dataease/commons/constants/ScheduleType.java +++ b/backend/src/main/java/io/dataease/commons/constants/ScheduleType.java @@ -1,5 +1,5 @@ package io.dataease.commons.constants; public enum ScheduleType { - CRON, SIMPLE + CRON, SIMPLE, SIMPLE_COMPLETE } diff --git a/backend/src/main/java/io/dataease/commons/constants/UpdateType.java b/backend/src/main/java/io/dataease/commons/constants/UpdateType.java new file mode 100644 index 0000000000..0919e566af --- /dev/null +++ b/backend/src/main/java/io/dataease/commons/constants/UpdateType.java @@ -0,0 +1,5 @@ +package io.dataease.commons.constants; + +public enum UpdateType { + all_scope, add_scope +} diff --git a/backend/src/main/java/io/dataease/controller/dataset/DataSetTableController.java b/backend/src/main/java/io/dataease/controller/dataset/DataSetTableController.java index 827386e0bb..7a902aa505 100644 --- a/backend/src/main/java/io/dataease/controller/dataset/DataSetTableController.java +++ b/backend/src/main/java/io/dataease/controller/dataset/DataSetTableController.java @@ -2,6 +2,7 @@ package io.dataease.controller.dataset; import io.dataease.base.domain.DatasetTable; import io.dataease.base.domain.DatasetTableField; +import io.dataease.base.domain.DatasetTableIncrementalConfig; import io.dataease.controller.request.dataset.DataSetTableRequest; import io.dataease.datasource.dto.TableFiled; import io.dataease.service.dataset.DataSetTableService; @@ -70,4 +71,15 @@ public class DataSetTableController { public Map getSQLPreview(@RequestBody DataSetTableRequest dataSetTableRequest) throws Exception { return dataSetTableService.getSQLPreview(dataSetTableRequest); } + + @PostMapping("incrementalConfig") + public DatasetTableIncrementalConfig incrementalConfig(@RequestBody DatasetTableIncrementalConfig datasetTableIncrementalConfig) throws Exception { + return dataSetTableService.incrementalConfig(datasetTableIncrementalConfig); + } + + @PostMapping("save/incrementalConfig") + public void saveIncrementalConfig(@RequestBody DatasetTableIncrementalConfig datasetTableIncrementalConfig) throws Exception { + dataSetTableService.saveIncrementalConfig(datasetTableIncrementalConfig); + } + } diff --git a/backend/src/main/java/io/dataease/job/sechedule/DeScheduleJob.java b/backend/src/main/java/io/dataease/job/sechedule/DeScheduleJob.java index 8400020daa..3fa52a44d3 100644 --- a/backend/src/main/java/io/dataease/job/sechedule/DeScheduleJob.java +++ b/backend/src/main/java/io/dataease/job/sechedule/DeScheduleJob.java @@ -8,6 +8,7 @@ public abstract class DeScheduleJob implements Job { protected String datasetTableId; protected String expression; protected String taskId; + protected String updateType; @Override public void execute(JobExecutionContext context) throws JobExecutionException { @@ -16,6 +17,7 @@ public abstract class DeScheduleJob implements Job { this.datasetTableId = jobDataMap.getString("datasetTableId"); this.expression = jobDataMap.getString("expression"); this.taskId = jobDataMap.getString("taskId"); + this.updateType = jobDataMap.getString("updateType"); LogUtil.info(jobKey.getGroup() + " Running: " + datasetTableId); LogUtil.info("CronExpression: " + expression); diff --git a/backend/src/main/java/io/dataease/job/sechedule/ExtractDataJob.java b/backend/src/main/java/io/dataease/job/sechedule/ExtractDataJob.java index 2704f33a02..ec91fbdce7 100644 --- a/backend/src/main/java/io/dataease/job/sechedule/ExtractDataJob.java +++ b/backend/src/main/java/io/dataease/job/sechedule/ExtractDataJob.java @@ -16,7 +16,7 @@ public class ExtractDataJob extends DeScheduleJob{ @Override void businessExecute(JobExecutionContext context) { - extractDataService.extractData(datasetTableId, taskId); + extractDataService.extractData(datasetTableId, taskId, updateType); } } diff --git a/backend/src/main/java/io/dataease/job/sechedule/ScheduleManager.java b/backend/src/main/java/io/dataease/job/sechedule/ScheduleManager.java index 44bdf3aaad..53a2c4852d 100644 --- a/backend/src/main/java/io/dataease/job/sechedule/ScheduleManager.java +++ b/backend/src/main/java/io/dataease/job/sechedule/ScheduleManager.java @@ -369,11 +369,12 @@ public class ScheduleManager { addOrUpdateCronJob(jobKey, triggerKey, jobClass, cron, startTime, endTime, null); } - public JobDataMap getDefaultJobDataMap(String resourceId, String expression, String taskId) { + public JobDataMap getDefaultJobDataMap(String resourceId, String expression, String taskId, String updateType) { JobDataMap jobDataMap = new JobDataMap(); jobDataMap.put("datasetTableId", resourceId); jobDataMap.put("taskId", taskId); jobDataMap.put("expression", expression); + jobDataMap.put("updateType", updateType); return jobDataMap; } diff --git a/backend/src/main/java/io/dataease/service/ScheduleService.java b/backend/src/main/java/io/dataease/service/ScheduleService.java index 5885687dcb..8aa4e85735 100644 --- a/backend/src/main/java/io/dataease/service/ScheduleService.java +++ b/backend/src/main/java/io/dataease/service/ScheduleService.java @@ -1,6 +1,7 @@ package io.dataease.service; import io.dataease.base.domain.DatasetTableTask; +import io.dataease.commons.constants.ScheduleType; import io.dataease.job.sechedule.ExtractDataJob; import io.dataease.job.sechedule.ScheduleManager; import org.apache.commons.lang3.StringUtils; @@ -21,12 +22,13 @@ public class ScheduleService { private ScheduleManager scheduleManager; public void addSchedule(DatasetTableTask datasetTableTask) throws Exception { - if (StringUtils.equalsIgnoreCase(datasetTableTask.getRate(), "0")) { + if (StringUtils.equalsIgnoreCase(datasetTableTask.getRate(), ScheduleType.SIMPLE.toString())) { scheduleManager.addOrUpdateSingleJob(new JobKey(datasetTableTask.getId(), datasetTableTask.getTableId()), new TriggerKey(datasetTableTask.getId(), datasetTableTask.getTableId()), ExtractDataJob.class, - new Date(datasetTableTask.getStartTime()), scheduleManager.getDefaultJobDataMap(datasetTableTask.getTableId(), datasetTableTask.getCron(), datasetTableTask.getId())); - } else if (StringUtils.equalsIgnoreCase(datasetTableTask.getRate(), "1")) { + new Date(datasetTableTask.getStartTime()), + scheduleManager.getDefaultJobDataMap(datasetTableTask.getTableId(), datasetTableTask.getCron(), datasetTableTask.getId(), datasetTableTask.getType())); + } else if (StringUtils.equalsIgnoreCase(datasetTableTask.getRate(), ScheduleType.CRON.toString())) { Date endTime; if (datasetTableTask.getEndTime() == null || datasetTableTask.getEndTime() == 0) { endTime = null; @@ -38,7 +40,7 @@ public class ScheduleService { new TriggerKey(datasetTableTask.getId(), datasetTableTask.getTableId()), ExtractDataJob.class, datasetTableTask.getCron(), new Date(datasetTableTask.getStartTime()), endTime, - scheduleManager.getDefaultJobDataMap(datasetTableTask.getTableId(), datasetTableTask.getCron(), datasetTableTask.getId())); + scheduleManager.getDefaultJobDataMap(datasetTableTask.getTableId(), datasetTableTask.getCron(), datasetTableTask.getId(), datasetTableTask.getType())); } } diff --git a/backend/src/main/java/io/dataease/service/dataset/DataSetTableService.java b/backend/src/main/java/io/dataease/service/dataset/DataSetTableService.java index eb7e2576d4..01640780c9 100644 --- a/backend/src/main/java/io/dataease/service/dataset/DataSetTableService.java +++ b/backend/src/main/java/io/dataease/service/dataset/DataSetTableService.java @@ -2,10 +2,8 @@ package io.dataease.service.dataset; import com.google.gson.Gson; -import io.dataease.base.domain.DatasetTable; -import io.dataease.base.domain.DatasetTableExample; -import io.dataease.base.domain.DatasetTableField; -import io.dataease.base.domain.Datasource; +import io.dataease.base.domain.*; +import io.dataease.base.mapper.DatasetTableIncrementalConfigMapper; import io.dataease.base.mapper.DatasetTableMapper; import io.dataease.base.mapper.DatasourceMapper; import io.dataease.commons.utils.BeanUtils; @@ -40,6 +38,8 @@ public class DataSetTableService { private DataSetTableFieldsService dataSetTableFieldsService; @Resource private DataSetTableTaskService dataSetTableTaskService; + @Resource + private DatasetTableIncrementalConfigMapper datasetTableIncrementalConfigMapper; public void batchInsert(List datasetTable) throws Exception { for (DatasetTable table : datasetTable) { @@ -261,6 +261,20 @@ public class DataSetTableService { return data; } + public List getDataSetDataBySql(String datasourceId, String table, String sql) { + List data = new ArrayList<>(); + Datasource ds = datasourceMapper.selectByPrimaryKey(datasourceId); + DatasourceProvider datasourceProvider = ProviderFactory.getProvider(ds.getType()); + DatasourceRequest datasourceRequest = new DatasourceRequest(); + datasourceRequest.setDatasource(ds); + datasourceRequest.setQuery(sql); + try { + return datasourceProvider.getData(datasourceRequest); + } catch (Exception e) { + } + return data; + } + public void saveTableField(DatasetTable datasetTable) throws Exception { Datasource ds = datasourceMapper.selectByPrimaryKey(datasetTable.getDataSourceId()); DataSetTableRequest dataSetTableRequest = new DataSetTableRequest(); @@ -349,4 +363,35 @@ public class DataSetTableService { return 0; } } + + public DatasetTableIncrementalConfig incrementalConfig(DatasetTableIncrementalConfig datasetTableIncrementalConfig){ + if(StringUtils.isEmpty(datasetTableIncrementalConfig.getTableId())){return new DatasetTableIncrementalConfig();} + DatasetTableIncrementalConfigExample example = new DatasetTableIncrementalConfigExample(); + example.createCriteria().andTableIdEqualTo(datasetTableIncrementalConfig.getTableId()); + List configs = datasetTableIncrementalConfigMapper.selectByExample(example); + if(CollectionUtils.isNotEmpty(configs)){ + return configs.get(0); + }else { + return new DatasetTableIncrementalConfig(); + } + } + + public DatasetTableIncrementalConfig incrementalConfig(String datasetTableId){ + DatasetTableIncrementalConfig datasetTableIncrementalConfig = new DatasetTableIncrementalConfig(); + datasetTableIncrementalConfig.setTableId(datasetTableId); + return incrementalConfig(datasetTableIncrementalConfig); + } + + + public void saveIncrementalConfig(DatasetTableIncrementalConfig datasetTableIncrementalConfig){ + if(StringUtils.isEmpty(datasetTableIncrementalConfig.getId())){ + datasetTableIncrementalConfig.setId(UUID.randomUUID().toString()); + datasetTableIncrementalConfigMapper.insertSelective(datasetTableIncrementalConfig); + }else{ + DatasetTableIncrementalConfigExample example = new DatasetTableIncrementalConfigExample(); + example.createCriteria().andTableIdEqualTo(datasetTableIncrementalConfig.getTableId()); + datasetTableIncrementalConfigMapper.updateByExample(datasetTableIncrementalConfig, example); + } + } + } diff --git a/backend/src/main/java/io/dataease/service/dataset/DataSetTableTaskService.java b/backend/src/main/java/io/dataease/service/dataset/DataSetTableTaskService.java index ba494c375a..5640cd3020 100644 --- a/backend/src/main/java/io/dataease/service/dataset/DataSetTableTaskService.java +++ b/backend/src/main/java/io/dataease/service/dataset/DataSetTableTaskService.java @@ -70,6 +70,10 @@ public class DataSetTableTaskService { return datasetTableTaskMapper.selectByPrimaryKey(id); } + public void update(DatasetTableTask datasetTableTask) { + datasetTableTaskMapper.updateByPrimaryKey(datasetTableTask); + } + public List list(DatasetTableTask datasetTableTask) { DatasetTableTaskExample datasetTableTaskExample = new DatasetTableTaskExample(); DatasetTableTaskExample.Criteria criteria = datasetTableTaskExample.createCriteria(); diff --git a/backend/src/main/java/io/dataease/service/dataset/ExtractDataService.java b/backend/src/main/java/io/dataease/service/dataset/ExtractDataService.java index 248d98f497..7078f03f5f 100644 --- a/backend/src/main/java/io/dataease/service/dataset/ExtractDataService.java +++ b/backend/src/main/java/io/dataease/service/dataset/ExtractDataService.java @@ -1,19 +1,23 @@ package io.dataease.service.dataset; import com.google.gson.Gson; -import io.dataease.base.domain.DatasetTable; -import io.dataease.base.domain.DatasetTableField; -import io.dataease.base.domain.DatasetTableTaskLog; +import io.dataease.base.domain.*; import io.dataease.commons.constants.JobStatus; +import io.dataease.commons.constants.ScheduleType; +import io.dataease.commons.constants.UpdateType; import io.dataease.commons.utils.CommonBeanFactory; import io.dataease.commons.utils.LogUtil; +import io.dataease.dto.dataset.DataSetTaskLogDTO; import io.dataease.dto.dataset.DataTableInfoDTO; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hbase.TableName; import org.apache.hadoop.hbase.client.*; import org.springframework.stereotype.Service; import javax.annotation.Resource; +import java.security.MessageDigest; import java.util.List; import java.util.UUID; import java.util.concurrent.ExecutorService; @@ -28,54 +32,74 @@ public class ExtractDataService { private DataSetTableFieldsService dataSetTableFieldsService; @Resource private DataSetTableTaskLogService dataSetTableTaskLogService; + @Resource + private DataSetTableTaskService dataSetTableTaskService; private Long pageSize = 10000l; private static ExecutorService pool = Executors.newScheduledThreadPool(50); //设置连接池 private Connection connection; + private static String lastUpdateTime = "${__last_update_time__}"; + private static String currentUpdateTime = "${__current_update_time__}"; + private static String column_family = "dataease"; - public void extractData(String datasetTableId, String taskId) { + public void extractData(String datasetTableId, String taskId, String type) { DatasetTableTaskLog datasetTableTaskLog = new DatasetTableTaskLog(); + UpdateType updateType = UpdateType.valueOf(type); try { - datasetTableTaskLog.setTableId(datasetTableId); - datasetTableTaskLog.setTaskId(taskId); - datasetTableTaskLog.setStatus(JobStatus.Underway.name()); - datasetTableTaskLog.setStartTime(System.currentTimeMillis()); - dataSetTableTaskLogService.save(datasetTableTaskLog); Admin admin = getConnection().getAdmin(); DatasetTable datasetTable = dataSetTableService.get(datasetTableId); List datasetTableFields = dataSetTableFieldsService.list(DatasetTableField.builder().tableId(datasetTable.getId()).build()); String table = new Gson().fromJson(datasetTable.getInfo(), DataTableInfoDTO.class).getTable(); TableName tableName = TableName.valueOf(table + "-" + datasetTable.getDataSourceId()); - if(!admin.tableExists(tableName)){ - TableDescriptorBuilder descBuilder = TableDescriptorBuilder.newBuilder(tableName); - ColumnFamilyDescriptor hcd = ColumnFamilyDescriptorBuilder.of("cf"); - descBuilder.setColumnFamily(hcd); - TableDescriptor desc = descBuilder.build(); - admin.createTable(desc); - } - admin.disableTable(tableName); - admin.truncateTable(tableName, true); - - Table tab = getConnection().getTable(tableName); - Long total = dataSetTableService.getDataSetTotalData(datasetTable.getDataSourceId(), table); - Long pageCount = total % pageSize == 0 ? total / pageSize : (total / pageSize) + 1; - - for (Long pageIndex = 1l; pageIndex <= pageCount; pageIndex++) { - List data = dataSetTableService.getDataSetPageData(datasetTable.getDataSourceId(), table, datasetTableFields, pageIndex, pageSize); - for (String[] d : data) { - for(int i=0;i dataSetTaskLogDTOS = dataSetTableTaskLogService.list(request); + if(CollectionUtils.isEmpty(dataSetTaskLogDTOS)){ + return; + } + writeDatasetTableTaskLog(datasetTableTaskLog,datasetTableId, taskId); + + // 增量添加 + if(StringUtils.isNotEmpty(datasetTableIncrementalConfig.getIncrementalAdd())){ + String sql = datasetTableIncrementalConfig.getIncrementalAdd().replace(lastUpdateTime, dataSetTaskLogDTOS.get(0).getStartTime().toString() + .replace(currentUpdateTime, Long.valueOf(System.currentTimeMillis()).toString())); + extractIncrementalData(tableName,table,datasetTable, datasetTableFields, sql, "add"); + } + + // 增量删除 + if( StringUtils.isNotEmpty(datasetTableIncrementalConfig.getIncrementalDelete())){ + String sql = datasetTableIncrementalConfig.getIncrementalDelete().replace(lastUpdateTime, dataSetTaskLogDTOS.get(0).getStartTime().toString() + .replace(currentUpdateTime, Long.valueOf(System.currentTimeMillis()).toString())); + extractIncrementalData(tableName,table,datasetTable, datasetTableFields, sql, "delete"); + } + + datasetTableTaskLog.setStatus(JobStatus.Completed.name()); + datasetTableTaskLog.setEndTime(System.currentTimeMillis()); + dataSetTableTaskLogService.save(datasetTableTaskLog); + break; } - datasetTableTaskLog.setStatus(JobStatus.Completed.name()); - datasetTableTaskLog.setEndTime(System.currentTimeMillis()); - dataSetTableTaskLogService.save(datasetTableTaskLog); }catch (Exception e){ e.printStackTrace(); LogUtil.error("ExtractData error, dataaset: " + datasetTableId); @@ -84,8 +108,75 @@ public class ExtractDataService { datasetTableTaskLog.setEndTime(System.currentTimeMillis()); dataSetTableTaskLogService.save(datasetTableTaskLog); } + finally { + DatasetTableTask datasetTableTask = dataSetTableTaskService.get(taskId); + if (datasetTableTask != null && datasetTableTask.getRate().equalsIgnoreCase(ScheduleType.SIMPLE.toString())){ + datasetTableTask.setRate(ScheduleType.SIMPLE_COMPLETE.toString()); + dataSetTableTaskService.update(datasetTableTask); + } + } } + private void writeDatasetTableTaskLog(DatasetTableTaskLog datasetTableTaskLog, String datasetTableId, String taskId){ + datasetTableTaskLog.setTableId(datasetTableId); + datasetTableTaskLog.setTaskId(taskId); + datasetTableTaskLog.setStatus(JobStatus.Underway.name()); + datasetTableTaskLog.setStartTime(System.currentTimeMillis()); + dataSetTableTaskLogService.save(datasetTableTaskLog); + } + + private void creatHaseTable(TableName tableName, Admin admin)throws Exception{ + TableDescriptorBuilder descBuilder = TableDescriptorBuilder.newBuilder(tableName); + ColumnFamilyDescriptor hcd = ColumnFamilyDescriptorBuilder.of(column_family); + descBuilder.setColumnFamily(hcd); + TableDescriptor desc = descBuilder.build(); + admin.createTable(desc); + } + + private void extractAllData(Admin admin, TableName tableName, String table, DatasetTable datasetTable, List datasetTableFields)throws Exception{ + admin.disableTable(tableName); + admin.truncateTable(tableName, true); + + Table tab = getConnection().getTable(tableName); + Long total = dataSetTableService.getDataSetTotalData(datasetTable.getDataSourceId(), table); + Long pageCount = total % pageSize == 0 ? total / pageSize : (total / pageSize) + 1; + + for (Long pageIndex = 1l; pageIndex <= pageCount; pageIndex++) { + List data = dataSetTableService.getDataSetPageData(datasetTable.getDataSourceId(), table, datasetTableFields, pageIndex, pageSize); + insertDataToHbaseTable(data,datasetTableFields,tab); + } + } + + private void extractIncrementalData(TableName tableName, String table, DatasetTable datasetTable, List datasetTableFields, String sql, String type)throws Exception{ + Table tab = getConnection().getTable(tableName); + List data = dataSetTableService.getDataSetDataBySql(datasetTable.getDataSourceId(), table, sql); + if (type.equalsIgnoreCase("add")){ + insertDataToHbaseTable(data,datasetTableFields,tab); + }else { + deleteDataFromHbaseTable(data,datasetTableFields,tab); + } + } + + private void insertDataToHbaseTable(List data, List datasetTableFields, Table tab)throws Exception{ + for (String[] d : data) { + Put put = new Put(md5(generateStr(datasetTableFields.size(), d)).getBytes()); + for(int i=0;i data, List datasetTableFields, Table tab)throws Exception{ + for (String[] d : data) { + Delete delete = new Delete(md5(generateStr(datasetTableFields.size(), d)).getBytes()); + tab.delete(delete); + } + } private synchronized Connection getConnection() throws Exception{ if(connection == null || connection.isClosed()){ @@ -94,4 +185,43 @@ public class ExtractDataService { } return connection; } + + + private static final char[] HEX_DIGITS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; + private static final String UTF_8 = "UTF-8"; + + public static String md5(String src) { + return md5(src, UTF_8); + } + + public static String md5(String src, String charset) { + try { + byte[] strTemp = io.micrometer.core.instrument.util.StringUtils.isEmpty(charset) ? src.getBytes() : src.getBytes(charset); + MessageDigest mdTemp = MessageDigest.getInstance("MD5"); + mdTemp.update(strTemp); + + byte[] md = mdTemp.digest(); + int j = md.length; + char[] str = new char[j * 2]; + int k = 0; + + for (byte byte0 : md) { + str[k++] = HEX_DIGITS[byte0 >>> 4 & 0xf]; + str[k++] = HEX_DIGITS[byte0 & 0xf]; + } + + return new String(str); + } catch (Exception e) { + throw new RuntimeException("MD5 encrypt error:", e); + } + } + + public String generateStr(int size, String[] d ){ + String str = null; + for(int i=0;i - - - + + + + @@ -64,8 +64,13 @@ - - +
+ + + + + +
diff --git a/frontend/src/lang/zh.js b/frontend/src/lang/zh.js index 7d864f6b1d..6da2829093 100644 --- a/frontend/src/lang/zh.js +++ b/frontend/src/lang/zh.js @@ -671,7 +671,12 @@ export default { add_sql_table: '添加SQL', preview: '预览', pls_input_name: '请输入名称', - connect_mode: '连接模式' + connect_mode: '连接模式', + incremental_update_type: '增量更新方式:', + incremental_add: '增量添加:', + incremental_delete: '增量删除:', + last_update_time: '上次更新时间:', + current_update_time: '当前更新时间:' }, datasource: { create: '新建数据连接', @@ -689,6 +694,7 @@ export default { please_input_port: '请输入端口', modify: '编辑数据连接', validate_success: '校验成功', + validate: '校验', delete: '删除组织', delete_confirm: '删除该组织会关联删除该组织下的所有资源(如:相关工作空间,项目,测试用例等),确定要删除吗?', input_name: '请输入名称', diff --git a/frontend/src/views/dataset/data/UpdateInfo.vue b/frontend/src/views/dataset/data/UpdateInfo.vue index 7d061ee51e..ad18afdfef 100644 --- a/frontend/src/views/dataset/data/UpdateInfo.vue +++ b/frontend/src/views/dataset/data/UpdateInfo.vue @@ -79,12 +79,11 @@ @@ -97,22 +96,22 @@ /> - + - + - + + + + + +
{{ $t('dataset.incremental_update_type') }}
+ + + {{ $t('dataset.incremental_add') }} + {{ $t('incremental_delete.incremental_update_type') }} + + +
+
+ + + +
参数:
+ + {{ $t('dataset.last_update_time') }} + {{ $t('dataset.current_update_time') }} + +
+
+ + + + + + + + + @@ -201,9 +241,33 @@ @@ -369,4 +511,13 @@ export default { .el-form-item { margin-bottom: 10px; } + + .codemirror { + height: 160px; + overflow-y: auto; + } + .codemirror >>> .CodeMirror-scroll { + height: 160px; + overflow-y: auto; + } diff --git a/frontend/src/views/system/datasource/index.vue b/frontend/src/views/system/datasource/index.vue index 347f51134b..cb9a3e59ab 100644 --- a/frontend/src/views/system/datasource/index.vue +++ b/frontend/src/views/system/datasource/index.vue @@ -11,7 +11,7 @@ @search="search" > @@ -62,7 +62,7 @@ - + @@ -79,7 +79,8 @@ @@ -198,13 +199,12 @@ export default { this.$success(this.$t('commons.save_success')) this.search() this.dialogVisible = false - }) + }); } else { return false } }) }, - validaDatasource(datasourceForm) { this.$refs[datasourceForm].validate(valid => { if (valid) { @@ -230,7 +230,6 @@ export default { const result = {} if (condition && condition.quick) { for (const [key, value] of Object.entries(condition)) { - // console.log(`${key}`) if (`${key}` === 'quick') { const v_new = Object.assign({}, value) v_new['field'] = 'name' From 9d1a7e4e0f75691e03d2b7a6fd004bf06312ba7d Mon Sep 17 00:00:00 2001 From: fit2cloud-chenyw Date: Thu, 18 Mar 2021 18:30:10 +0800 Subject: [PATCH 10/15] =?UTF-8?q?feat:=20=E5=AE=8C=E5=96=84=E5=88=86?= =?UTF-8?q?=E4=BA=AB=E5=88=97=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../base/mapper/ext/ExtPanelShareMapper.java | 3 +- .../base/mapper/ext/ExtPanelShareMapper.xml | 7 ++- .../io/dataease/dto/panel/PanelShareDto.java | 12 ++--- .../io/dataease/dto/panel/PanelSharePo.java | 20 +++++++++ .../dataease/service/panel/ShareService.java | 14 ++++-- frontend/src/api/panel/share.js | 9 ++++ .../src/views/panel/GrantAuth/shareTree.vue | 36 +++++++++++++++ frontend/src/views/panel/index.vue | 7 +-- .../src/views/panel/list/PanelViewShow.vue | 44 +++++++++---------- 9 files changed, 110 insertions(+), 42 deletions(-) create mode 100644 backend/src/main/java/io/dataease/dto/panel/PanelSharePo.java create mode 100644 frontend/src/views/panel/GrantAuth/shareTree.vue diff --git a/backend/src/main/java/io/dataease/base/mapper/ext/ExtPanelShareMapper.java b/backend/src/main/java/io/dataease/base/mapper/ext/ExtPanelShareMapper.java index 6d2cc5acda..a3c52468e1 100644 --- a/backend/src/main/java/io/dataease/base/mapper/ext/ExtPanelShareMapper.java +++ b/backend/src/main/java/io/dataease/base/mapper/ext/ExtPanelShareMapper.java @@ -3,6 +3,7 @@ package io.dataease.base.mapper.ext; import io.dataease.base.domain.PanelShare; import io.dataease.base.mapper.ext.query.GridExample; import io.dataease.dto.panel.PanelShareDto; +import io.dataease.dto.panel.PanelSharePo; import org.apache.ibatis.annotations.Param; import java.util.List; @@ -11,7 +12,7 @@ public interface ExtPanelShareMapper { int batchInsert(@Param("shares") List shares); - List query(GridExample example); + List query(GridExample example); List queryWithResource(GridExample example); } diff --git a/backend/src/main/java/io/dataease/base/mapper/ext/ExtPanelShareMapper.xml b/backend/src/main/java/io/dataease/base/mapper/ext/ExtPanelShareMapper.xml index 35fbc15311..db4a0afc66 100644 --- a/backend/src/main/java/io/dataease/base/mapper/ext/ExtPanelShareMapper.xml +++ b/backend/src/main/java/io/dataease/base/mapper/ext/ExtPanelShareMapper.xml @@ -2,11 +2,10 @@ - + - - + @@ -18,7 +17,7 @@ - select s.panel_group_id as id, g.create_by as creator, g.name + select distinct s.panel_group_id as id, g.create_by as creator, g.name from panel_share s left join panel_group g on g.id = s.panel_group_id From 7b24b457e9c545005000b05b3c02b65aa5862c76 Mon Sep 17 00:00:00 2001 From: junjie Date: Fri, 19 Mar 2021 14:28:38 +0800 Subject: [PATCH 14/15] =?UTF-8?q?feat(=E8=A7=86=E5=9B=BE):=20=E8=A7=86?= =?UTF-8?q?=E5=9B=BEecharts=20=E6=94=AF=E6=8C=81=20=E5=A4=A7=E5=B0=8F=20?= =?UTF-8?q?=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/lang/zh.js | 24 ++- frontend/src/views/chart/chart/bar/bar.js | 22 +++ frontend/src/views/chart/chart/chart.js | 12 ++ .../src/views/chart/chart/funnel/funnel.js | 6 + frontend/src/views/chart/chart/line/line.js | 10 ++ frontend/src/views/chart/chart/pie/pie.js | 5 + .../chart/components/ChartComponentView.vue | 73 +++++++++ .../{ => shape_attr}/ColorSelector.vue | 16 +- .../components/shape_attr/SizeSelector.vue | 139 ++++++++++++++++++ frontend/src/views/chart/group/Group.vue | 5 +- frontend/src/views/chart/view/ChartEdit.vue | 49 +++--- 11 files changed, 335 insertions(+), 26 deletions(-) create mode 100644 frontend/src/views/chart/components/ChartComponentView.vue rename frontend/src/views/chart/components/{ => shape_attr}/ColorSelector.vue (93%) create mode 100644 frontend/src/views/chart/components/shape_attr/SizeSelector.vue diff --git a/frontend/src/lang/zh.js b/frontend/src/lang/zh.js index 061d89d88f..cb75360565 100644 --- a/frontend/src/lang/zh.js +++ b/frontend/src/lang/zh.js @@ -615,7 +615,29 @@ export default { color_elegant: '淡雅', color_technology: '科技', color_simple: '简洁', - not_alpha: '不透明度' + not_alpha: '不透明度', + size: '大小', + bar_width: '柱宽', + bar_gap: '柱间隔', + adapt: '自适应', + line_width: '线宽', + line_type: '线型', + line_symbol: '折点', + line_symbol_size: '折点大小', + line_type_solid: '实线', + line_type_dashed: '虚线', + line_symbol_circle: '圆形', + line_symbol_emptyCircle: '空心圆', + line_symbol_rect: '矩形', + line_symbol_roundRect: '圆角矩形', + line_symbol_triangle: '三角形', + line_symbol_diamond: '菱形', + line_symbol_pin: '钉子', + line_symbol_arrow: '箭头', + line_symbol_none: '无', + pie_inner_radius: '内径', + pie_outer_radius: '外径', + funnel_width: '宽度' }, dataset: { datalist: '数据集', diff --git a/frontend/src/views/chart/chart/bar/bar.js b/frontend/src/views/chart/chart/bar/bar.js index 1200b1d3a3..0b6f8185af 100644 --- a/frontend/src/views/chart/chart/bar/bar.js +++ b/frontend/src/views/chart/chart/bar/bar.js @@ -15,9 +15,20 @@ export function baseBarOption(chart_option, chart) { chart_option.xAxis.data = chart.data.x for (let i = 0; i < chart.data.series.length; i++) { const y = chart.data.series[i] + // color y.itemStyle = { color: hexColorToRGBA(customAttr.color.colors[i % 9], customAttr.color.alpha) } + // size + if (customAttr.size) { + if (customAttr.size.barDefault) { + y.barWidth = null + y.barGap = null + } else { + y.barWidth = customAttr.size.barWidth + y.barGap = customAttr.size.barGap + } + } y.type = 'bar' chart_option.legend.data.push(y.name) chart_option.series.push(y) @@ -55,9 +66,20 @@ export function horizontalBarOption(chart_option, chart) { chart_option.yAxis.data = chart.data.x for (let i = 0; i < chart.data.series.length; i++) { const y = chart.data.series[i] + // color y.itemStyle = { color: hexColorToRGBA(customAttr.color.colors[i % 9], customAttr.color.alpha) } + // size + if (customAttr.size) { + if (customAttr.size.barDefault) { + y.barWidth = null + y.barGap = null + } else { + y.barWidth = customAttr.size.barWidth + y.barGap = customAttr.size.barGap + } + } y.type = 'bar' chart_option.legend.data.push(y.name) chart_option.series.push(y) diff --git a/frontend/src/views/chart/chart/chart.js b/frontend/src/views/chart/chart/chart.js index 3a0e91698e..b71fc5d14f 100644 --- a/frontend/src/views/chart/chart/chart.js +++ b/frontend/src/views/chart/chart/chart.js @@ -3,6 +3,18 @@ export const DEFAULT_COLOR_CASE = { colors: ['#5470c6', '#91cc75', '#fac858', '#ee6666', '#73c0de', '#3ba272', '#fc8452', '#9a60b4', '#ea7ccc'], alpha: 100 } +export const DEFAULT_SIZE = { + barDefault: true, + barWidth: 40, + barGap: 0.4, + lineWidth: 1, + lineType: 'solid', + lineSymbol: 'emptyCircle', + lineSymbolSize: 4, + pieInnerRadius: 0, + pieOuterRadius: 60, + funnelWidth: 80 +} export const BASE_BAR = { title: { text: '' diff --git a/frontend/src/views/chart/chart/funnel/funnel.js b/frontend/src/views/chart/chart/funnel/funnel.js index 96bbcf9a96..a1356619ce 100644 --- a/frontend/src/views/chart/chart/funnel/funnel.js +++ b/frontend/src/views/chart/chart/funnel/funnel.js @@ -14,13 +14,19 @@ export function baseFunnelOption(chart_option, chart) { 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].width = customAttr.size.funnelWidth + '%' + } const valueArr = chart.data.series[0].data + // max value chart_option.series[0].max = Math.max.apply(Math, valueArr) for (let i = 0; i < valueArr.length; i++) { const y = { name: chart.data.x[i], value: valueArr[i] } + // color y.itemStyle = { color: hexColorToRGBA(customAttr.color.colors[i % 9], customAttr.color.alpha) } diff --git a/frontend/src/views/chart/chart/line/line.js b/frontend/src/views/chart/chart/line/line.js index 8fe395b7e7..91fa2210b5 100644 --- a/frontend/src/views/chart/chart/line/line.js +++ b/frontend/src/views/chart/chart/line/line.js @@ -15,9 +15,19 @@ export function baseLineOption(chart_option, chart) { chart_option.xAxis.data = chart.data.x for (let i = 0; i < chart.data.series.length; i++) { const y = chart.data.series[i] + // color y.itemStyle = { color: hexColorToRGBA(customAttr.color.colors[i % 9], customAttr.color.alpha) } + // size + if (customAttr.size) { + y.symbol = customAttr.size.lineSymbol + y.symbolSize = customAttr.size.lineSymbolSize + y.lineStyle = { + width: customAttr.size.lineWidth, + type: customAttr.size.lineType + } + } y.type = 'line' chart_option.legend.data.push(y.name) chart_option.series.push(y) diff --git a/frontend/src/views/chart/chart/pie/pie.js b/frontend/src/views/chart/chart/pie/pie.js index 8739c4a0e1..f45ed8c726 100644 --- a/frontend/src/views/chart/chart/pie/pie.js +++ b/frontend/src/views/chart/chart/pie/pie.js @@ -14,12 +14,17 @@ export function basePieOption(chart_option, chart) { 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 = { name: chart.data.x[i], value: valueArr[i] } + // color y.itemStyle = { color: hexColorToRGBA(customAttr.color.colors[i % 9], customAttr.color.alpha) } diff --git a/frontend/src/views/chart/components/ChartComponentView.vue b/frontend/src/views/chart/components/ChartComponentView.vue new file mode 100644 index 0000000000..051eba2d78 --- /dev/null +++ b/frontend/src/views/chart/components/ChartComponentView.vue @@ -0,0 +1,73 @@ + + + + + diff --git a/frontend/src/views/chart/components/ColorSelector.vue b/frontend/src/views/chart/components/shape_attr/ColorSelector.vue similarity index 93% rename from frontend/src/views/chart/components/ColorSelector.vue rename to frontend/src/views/chart/components/shape_attr/ColorSelector.vue index ba24c72721..5754baaf54 100644 --- a/frontend/src/views/chart/components/ColorSelector.vue +++ b/frontend/src/views/chart/components/shape_attr/ColorSelector.vue @@ -18,11 +18,12 @@
- - + + + {{ $t('chart.color') }} @@ -131,11 +132,20 @@ export default { padding: 6px; border: none; } +.form-item-slider>>>.el-form-item__label{ + font-size: 12px; + line-height: 38px; +} .form-item>>>.el-form-item__label{ font-size: 12px; } .el-select-dropdown__item{ padding: 0 20px; } - span{font-size: 12px} + span{ + font-size: 12px + } + .el-form-item{ + margin-bottom: 6px; + } diff --git a/frontend/src/views/chart/components/shape_attr/SizeSelector.vue b/frontend/src/views/chart/components/shape_attr/SizeSelector.vue new file mode 100644 index 0000000000..8bd0c24f4a --- /dev/null +++ b/frontend/src/views/chart/components/shape_attr/SizeSelector.vue @@ -0,0 +1,139 @@ + + + + + diff --git a/frontend/src/views/chart/group/Group.vue b/frontend/src/views/chart/group/Group.vue index a7ce7ad8cc..b07baae74e 100644 --- a/frontend/src/views/chart/group/Group.vue +++ b/frontend/src/views/chart/group/Group.vue @@ -211,7 +211,7 @@