feat(视图): MySQL时间字段支持按季度、周统计

This commit is contained in:
junjun 2022-12-24 18:28:54 +08:00
parent 9838359f93
commit 669f2aa235
11 changed files with 154 additions and 48 deletions

View File

@ -1,6 +1,7 @@
package io.dataease.provider.engine.mysql;
import com.alibaba.fastjson.JSONArray;
import com.sun.javafx.binding.StringFormatter;
import io.dataease.plugins.common.base.domain.ChartViewWithBLOBs;
import io.dataease.plugins.common.base.domain.DatasetTableField;
import io.dataease.plugins.common.base.domain.DatasetTableFieldExample;
@ -1141,8 +1142,12 @@ public class MysqlQueryProvider extends QueryProvider {
switch (dateStyle) {
case "y":
return "%Y";
case "y_Q":
return "CONCAT(%s,'" + split + "',%s)";
case "y_M":
return "%Y" + split + "%m";
case "y_W":
return "%Y" + split + "%u";
case "y_M_d":
return "%Y" + split + "%m" + split + "%d";
case "H_m_s":
@ -1163,7 +1168,13 @@ public class MysqlQueryProvider extends QueryProvider {
fieldName = String.format(MysqlConstants.UNIX_TIMESTAMP, originField) + "*1000";
} else if (x.getDeType() == 1) {
String format = transDateFormat(x.getDateStyle(), x.getDatePattern());
fieldName = String.format(MysqlConstants.DATE_FORMAT, originField, format);
if (StringUtils.equalsIgnoreCase(x.getDateStyle(), "y_Q")) {
fieldName = String.format(format,
String.format(MysqlConstants.DATE_FORMAT, originField, "%Y"),
String.format(MysqlConstants.QUARTER, originField));
} else {
fieldName = String.format(MysqlConstants.DATE_FORMAT, originField, format);
}
} else {
fieldName = originField;
}
@ -1171,11 +1182,23 @@ public class MysqlQueryProvider extends QueryProvider {
if (x.getDeType() == 1) {
String format = transDateFormat(x.getDateStyle(), x.getDatePattern());
if (x.getDeExtractType() == 0) {
fieldName = String.format(MysqlConstants.DATE_FORMAT, originField, format);
if (StringUtils.equalsIgnoreCase(x.getDateStyle(), "y_Q")) {
fieldName = String.format(format,
String.format(MysqlConstants.DATE_FORMAT, String.format(MysqlConstants.STR_TO_DATE, originField, MysqlConstants.DEFAULT_DATE_FORMAT), "%Y"),
String.format(MysqlConstants.QUARTER, String.format(MysqlConstants.STR_TO_DATE, originField, MysqlConstants.DEFAULT_DATE_FORMAT)));
} else {
fieldName = String.format(MysqlConstants.DATE_FORMAT, originField, format);
}
} else {
String cast = String.format(MysqlConstants.CAST, originField, MysqlConstants.DEFAULT_INT_FORMAT) + "/1000";
String from_unixtime = String.format(MysqlConstants.FROM_UNIXTIME, cast, MysqlConstants.DEFAULT_DATE_FORMAT);
fieldName = String.format(MysqlConstants.DATE_FORMAT, from_unixtime, format);
if (StringUtils.equalsIgnoreCase(x.getDateStyle(), "y_Q")) {
fieldName = String.format(format,
String.format(MysqlConstants.DATE_FORMAT, from_unixtime, "%Y"),
String.format(MysqlConstants.QUARTER, from_unixtime));
} else {
fieldName = String.format(MysqlConstants.DATE_FORMAT, from_unixtime, format);
}
}
} else if (x.getDeType() == 0 && x.getDeExtractType() == 0) {
fieldName = String.format(MysqlConstants.CAST, originField, MysqlConstants.CHAR);

View File

@ -18,8 +18,8 @@ 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.PageInfo;
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;
@ -1138,8 +1138,12 @@ public class MysqlQueryProvider extends QueryProvider {
switch (dateStyle) {
case "y":
return "%Y";
case "y_Q":
return "CONCAT(%s,'" + split + "',%s)";
case "y_M":
return "%Y" + split + "%m";
case "y_W":
return "%Y" + split + "%u";
case "y_M_d":
return "%Y" + split + "%m" + split + "%d";
case "H_m_s":
@ -1159,13 +1163,25 @@ public class MysqlQueryProvider extends QueryProvider {
if (x.getDeType() == 2 || x.getDeType() == 3) {
fieldName = String.format(MySQLConstants.UNIX_TIMESTAMP, originField) + "*1000";
} else if (x.getDeType() == 1) {
String format = transDateFormat(x.getDateStyle(), x.getDatePattern());
if (x.getType().equalsIgnoreCase("YEAR")) {
fieldName = String.format(MySQLConstants.DATE_FORMAT, "CONCAT(" + originField + ",'-01-01')", transDateFormat(x.getDateStyle(), x.getDatePattern()));
if (StringUtils.equalsIgnoreCase(x.getDateStyle(), "y_Q")) {
fieldName = String.format(format,
String.format(MySQLConstants.DATE_FORMAT, "CONCAT(" + originField + ",'-01-01')", "%Y"),
String.format(MySQLConstants.QUARTER, "CONCAT(" + originField + ",'-01-01')"));
} else {
fieldName = String.format(MySQLConstants.DATE_FORMAT, "CONCAT(" + originField + ",'-01-01')", format);
}
} else if (x.getType().equalsIgnoreCase("TIME")) {
fieldName = String.format(MySQLConstants.DATE_FORMAT, "CONCAT('1970-01-01', " + originField + ")", MySQLConstants.DEFAULT_DATE_FORMAT);
} else {
String format = transDateFormat(x.getDateStyle(), x.getDatePattern());
fieldName = String.format(MySQLConstants.DATE_FORMAT, originField, format);
if (StringUtils.equalsIgnoreCase(x.getDateStyle(), "y_Q")) {
fieldName = String.format(format,
String.format(MySQLConstants.DATE_FORMAT, originField, "%Y"),
String.format(MySQLConstants.QUARTER, originField));
} else {
fieldName = String.format(MySQLConstants.DATE_FORMAT, originField, format);
}
}
} else {
fieldName = originField;
@ -1174,11 +1190,23 @@ public class MysqlQueryProvider extends QueryProvider {
if (x.getDeType() == 1) {
String format = transDateFormat(x.getDateStyle(), x.getDatePattern());
if (x.getDeExtractType() == 0) {
fieldName = String.format(MySQLConstants.DATE_FORMAT, String.format(MySQLConstants.STR_TO_DATE, originField, StringUtils.isNotEmpty(x.getDateFormat()) ? x.getDateFormat() : MysqlConstants.DEFAULT_DATE_FORMAT), format);
if (StringUtils.equalsIgnoreCase(x.getDateStyle(), "y_Q")) {
fieldName = String.format(format,
String.format(MysqlConstants.DATE_FORMAT, String.format(MySQLConstants.STR_TO_DATE, originField, StringUtils.isNotEmpty(x.getDateFormat()) ? x.getDateFormat() : MysqlConstants.DEFAULT_DATE_FORMAT), "%Y"),
String.format(MysqlConstants.QUARTER, String.format(MySQLConstants.STR_TO_DATE, originField, StringUtils.isNotEmpty(x.getDateFormat()) ? x.getDateFormat() : MysqlConstants.DEFAULT_DATE_FORMAT)));
} else {
fieldName = String.format(MySQLConstants.DATE_FORMAT, String.format(MySQLConstants.STR_TO_DATE, originField, StringUtils.isNotEmpty(x.getDateFormat()) ? x.getDateFormat() : MysqlConstants.DEFAULT_DATE_FORMAT), format);
}
} else {
String cast = String.format(MySQLConstants.CAST, originField, MySQLConstants.DEFAULT_INT_FORMAT) + "/1000";
String from_unixtime = String.format(MySQLConstants.FROM_UNIXTIME, cast, MySQLConstants.DEFAULT_DATE_FORMAT);
fieldName = String.format(MySQLConstants.DATE_FORMAT, from_unixtime, format);
if (StringUtils.equalsIgnoreCase(x.getDateStyle(), "y_Q")) {
fieldName = String.format(format,
String.format(MySQLConstants.DATE_FORMAT, from_unixtime, "%Y"),
String.format(MySQLConstants.QUARTER, from_unixtime));
} else {
fieldName = String.format(MySQLConstants.DATE_FORMAT, from_unixtime, format);
}
}
} else {
if (x.getDeType() == DeTypeConstants.DE_INT) {

View File

@ -1179,6 +1179,8 @@ export default {
datePattern: 'Date Format',
y: 'Year',
y_M: 'Year Month',
y_Q: 'Year Quarter',
y_W: 'Year Week',
y_M_d: 'Year Month Day',
H_m_s: 'Hour Minute Second',
y_M_d_H_m: 'Year Month Day Hour Minute',

View File

@ -1178,6 +1178,8 @@ export default {
datePattern: '日期格式',
y: '年',
y_M: '年月',
y_Q: '年季度',
y_W: '年周',
y_M_d: '年月日',
H_m_s: '時分秒',
y_M_d_H_m: '年月日時分',

View File

@ -1177,6 +1177,8 @@ export default {
datePattern: '日期格式',
y: '年',
y_M: '年月',
y_Q: '年季度',
y_W: '年周',
y_M_d: '年月日',
H_m_s: '时分秒',
y_M_d_H_m: '年月日时分',

View File

@ -1133,3 +1133,5 @@ export const CHART_FONT_LETTER_SPACE = [
]
export const NOT_SUPPORT_PAGE_DATASET = ['kylin', 'sqlServer', 'es', 'presto', 'ds_doris', 'StarRocks']
export const SUPPORT_Y_M = ['y', 'y_M', 'y_M_d']

View File

@ -108,7 +108,15 @@
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item :command="beforeDateStyle('y')">{{ $t('chart.y') }}</el-dropdown-item>
<el-dropdown-item
v-if="showDateExt"
:command="beforeDateStyle('y_Q')"
>{{ $t('chart.y_Q') }}</el-dropdown-item>
<el-dropdown-item :command="beforeDateStyle('y_M')">{{ $t('chart.y_M') }}</el-dropdown-item>
<el-dropdown-item
v-if="showDateExt"
:command="beforeDateStyle('y_W')"
>{{ $t('chart.y_W') }}</el-dropdown-item>
<el-dropdown-item :command="beforeDateStyle('y_M_d')">{{ $t('chart.y_M_d') }}</el-dropdown-item>
<el-dropdown-item
:command="beforeDateStyle('H_m_s')"
@ -182,6 +190,10 @@ export default {
type: Number,
required: true
},
chart: {
type: Object,
required: true
},
dimensionData: {
type: Array,
required: true
@ -193,7 +205,8 @@ export default {
},
data() {
return {
tagType: getItemType(this.dimensionData, this.quotaData, this.item)
tagType: getItemType(this.dimensionData, this.quotaData, this.item),
showDateExt: false
}
},
watch: {
@ -202,6 +215,9 @@ export default {
},
item: function() {
this.getItemTagType()
},
chart: function() {
this.getDateExtStatus()
}
},
mounted() {
@ -278,6 +294,13 @@ export default {
},
getItemTagType() {
this.tagType = getItemType(this.dimensionData, this.quotaData, this.item)
},
getDateExtStatus() {
if (this.chart) {
this.showDateExt = this.chart.datasourceType === 'mysql' && this.chart.datasetMode === 0
} else {
this.showDateExt = false
}
}
}
}

View File

@ -116,7 +116,15 @@
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item :command="beforeDateStyle('y')">{{ $t('chart.y') }}</el-dropdown-item>
<el-dropdown-item
v-if="showDateExt"
:command="beforeDateStyle('y_Q')"
>{{ $t('chart.y_Q') }}</el-dropdown-item>
<el-dropdown-item :command="beforeDateStyle('y_M')">{{ $t('chart.y_M') }}</el-dropdown-item>
<el-dropdown-item
v-if="showDateExt"
:command="beforeDateStyle('y_W')"
>{{ $t('chart.y_W') }}</el-dropdown-item>
<el-dropdown-item :command="beforeDateStyle('y_M_d')">{{ $t('chart.y_M_d') }}</el-dropdown-item>
<el-dropdown-item
:command="beforeDateStyle('H_m_s')"
@ -215,7 +223,8 @@ export default {
data() {
return {
tagType: 'success',
formatterItem: formatterItem
formatterItem: formatterItem,
showDateExt: false
}
},
watch: {
@ -224,6 +233,9 @@ export default {
},
item: function() {
this.getItemTagType()
},
chart: function() {
this.getDateExtStatus()
}
},
mounted() {
@ -325,6 +337,14 @@ export default {
this.item.index = this.index
this.item.formatterType = 'dimension'
this.$emit('valueFormatter', this.item)
},
getDateExtStatus() {
if (this.chart) {
this.showDateExt = this.chart.datasourceType === 'mysql' && this.chart.datasetMode === 0
} else {
this.showDateExt = false
}
}
}
}

View File

@ -246,6 +246,7 @@ import FieldErrorTips from '@/views/chart/components/dragItem/components/FieldEr
import bus from '@/utils/bus'
import { formatterItem } from '@/views/chart/chart/formatter'
import { quotaViews } from '@/views/chart/chart/util'
import { SUPPORT_Y_M } from '@/views/chart/chart/chart'
export default {
name: 'QuotaExtItem',
@ -318,13 +319,13 @@ export default {
},
isEnableCompare() {
let xAxis = null
if (Object.prototype.toString.call(this.chart.xaxis) === '[object Array]') {
xAxis = JSON.parse(JSON.stringify(this.chart.xaxis))
if (Object.prototype.toString.call(this.chart.xaxisExt) === '[object Array]') {
xAxis = JSON.parse(JSON.stringify(this.chart.xaxisExt))
} else {
xAxis = JSON.parse(this.chart.xaxis)
xAxis = JSON.parse(this.chart.xaxisExt)
}
const t1 = xAxis.filter(ele => {
return ele.deType === 1
return ele.deType === 1 && SUPPORT_Y_M.includes(ele.dateStyle)
})
// /
if (t1.length > 0 && this.chart.type !== 'text' && this.chart.type !== 'label' && this.chart.type !== 'gauge' && this.chart.type !== 'liquid') {

View File

@ -246,6 +246,7 @@ import FieldErrorTips from '@/views/chart/components/dragItem/components/FieldEr
import bus from '@/utils/bus'
import { formatterItem } from '@/views/chart/chart/formatter'
import { quotaViews } from '@/views/chart/chart/util'
import { SUPPORT_Y_M } from '@/views/chart/chart/chart'
export default {
name: 'QuotaItem',
@ -321,7 +322,7 @@ export default {
xAxis = JSON.parse(this.chart.xaxis)
}
const t1 = xAxis.filter(ele => {
return ele.deType === 1
return ele.deType === 1 && SUPPORT_Y_M.includes(ele.dateStyle)
})
// /
if (t1.length > 0 && this.chart.type !== 'text' && this.chart.type !== 'label' && this.chart.type !== 'gauge' && this.chart.type !== 'liquid') {

View File

@ -192,7 +192,7 @@
@command="chartFieldEdit"
>
<span class="el-dropdown-link">
<i class="el-icon-s-tools"/>
<i class="el-icon-s-tools" />
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item
@ -267,7 +267,7 @@
@command="chartFieldEdit"
>
<span class="el-dropdown-link">
<i class="el-icon-s-tools"/>
<i class="el-icon-s-tools" />
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item
@ -362,7 +362,7 @@
style="padding: 6px;"
>
{{ $t('chart.change_chart_type') }}
<i class="el-icon-caret-bottom"/>
<i class="el-icon-caret-bottom" />
</el-button>
</el-popover>
</span>
@ -435,7 +435,7 @@
v-model="view.refreshViewEnable"
class="el-input-refresh-loading"
@change="refreshAttrChange"
></el-checkbox>
/>
{{ $t('panel.enable_refresh_view') }}
</span>
<el-row>
@ -531,6 +531,7 @@
:item="item"
:dimension-data="dimension"
:quota-data="quota"
:chart="chart"
@onDimensionItemChange="dimensionItemChange"
@onDimensionItemRemove="dimensionItemRemove"
@editItemFilter="showDimensionEditFilter"
@ -552,8 +553,8 @@
>
<span class="data-area-label">
<span v-if="view.type && view.type.includes('table')">{{
$t('chart.drag_block_table_data_column')
}}</span>
$t('chart.drag_block_table_data_column')
}}</span>
<span
v-else-if="view.type && (view.type.includes('bar') || view.type.includes('line') || view.type.includes('scatter') || view.type === 'chart-mix' || view.type === 'waterfall' || view.type === 'area')"
>{{ $t('chart.drag_block_type_axis') }}</span>
@ -561,18 +562,18 @@
v-else-if="view.type && view.type.includes('pie')"
>{{ $t('chart.drag_block_pie_label') }}</span>
<span v-else-if="view.type && view.type.includes('funnel')">{{
$t('chart.drag_block_funnel_split')
}}</span>
$t('chart.drag_block_funnel_split')
}}</span>
<span v-else-if="view.type && view.type.includes('radar')">{{
$t('chart.drag_block_radar_label')
}}</span>
$t('chart.drag_block_radar_label')
}}</span>
<span v-else-if="view.type && view.type === 'map'">{{ $t('chart.area') }}</span>
<span v-else-if="view.type && view.type.includes('treemap')">{{
$t('chart.drag_block_treemap_label')
}}</span>
$t('chart.drag_block_treemap_label')
}}</span>
<span v-else-if="view.type && view.type === 'word-cloud'">{{
$t('chart.drag_block_word_cloud_label')
}}</span>
$t('chart.drag_block_word_cloud_label')
}}</span>
<span v-else-if="view.type && view.type === 'label'">{{ $t('chart.drag_block_label') }}</span>
<span v-show="view.type !== 'richTextView'"> / </span>
<span v-if="view.type && view.type !== 'table-info'">{{ $t('chart.dimension') }}</span>
@ -673,6 +674,7 @@
:item="item"
:dimension-data="dimension"
:quota-data="quota"
:chart="chart"
@onDimensionItemChange="dimensionItemChange"
@onDimensionItemRemove="dimensionItemRemove"
@editItemFilter="showDimensionEditFilter"
@ -695,8 +697,8 @@
>
<span class="data-area-label">
<span v-if="view.type && view.type.includes('table')">{{
$t('chart.drag_block_table_data_column')
}}</span>
$t('chart.drag_block_table_data_column')
}}</span>
<span
v-else-if="view.type && (view.type.includes('bar') || view.type.includes('line') || view.type.includes('scatter') || view.type === 'waterfall' || view.type === 'area')"
>{{ $t('chart.drag_block_value_axis') }}</span>
@ -704,30 +706,30 @@
v-else-if="view.type && view.type.includes('pie')"
>{{ $t('chart.drag_block_pie_angel') }}</span>
<span v-else-if="view.type && view.type.includes('funnel')">{{
$t('chart.drag_block_funnel_width')
}}</span>
$t('chart.drag_block_funnel_width')
}}</span>
<span v-else-if="view.type && view.type.includes('radar')">{{
$t('chart.drag_block_radar_length')
}}</span>
$t('chart.drag_block_radar_length')
}}</span>
<span v-else-if="view.type && view.type.includes('gauge')">{{
$t('chart.drag_block_gauge_angel')
}}</span>
$t('chart.drag_block_gauge_angel')
}}</span>
<span
v-else-if="view.type && view.type.includes('text')"
>{{ $t('chart.drag_block_label_value') }}</span>
<span v-else-if="view.type && view.type === 'map'">{{ $t('chart.chart_data') }}</span>
<span v-else-if="view.type && view.type.includes('tree')">{{
$t('chart.drag_block_treemap_size')
}}</span>
$t('chart.drag_block_treemap_size')
}}</span>
<span v-else-if="view.type && view.type === 'chart-mix'">{{
$t('chart.drag_block_value_axis_main')
}}</span>
$t('chart.drag_block_value_axis_main')
}}</span>
<span
v-else-if="view.type && view.type === 'liquid'"
>{{ $t('chart.drag_block_progress') }}</span>
<span v-else-if="view.type && view.type === 'word-cloud'">{{
$t('chart.drag_block_word_cloud_size')
}}</span>
$t('chart.drag_block_word_cloud_size')
}}</span>
<span v-show="view.type !== 'richTextView'"> / </span>
<span>{{ $t('chart.quota') }}</span>
<i
@ -1199,7 +1201,7 @@
:title="$t('panel.position_adjust_component')"
:name="'positionAdjust'"
>
<position-adjust/>
<position-adjust />
</el-collapse-item>
</el-collapse>
</div>
@ -1355,7 +1357,7 @@
width="800px"
class="dialog-css"
>
<quota-filter-editor :item="quotaItem"/>
<quota-filter-editor :item="quotaItem" />
<div
slot="footer"
class="dialog-footer"
@ -1382,7 +1384,7 @@
width="800px"
class="dialog-css"
>
<dimension-filter-editor :item="dimensionItem"/>
<dimension-filter-editor :item="dimensionItem" />
<div
slot="footer"
class="dialog-footer"
@ -2369,6 +2371,7 @@ export default {
if (!view) return
viewEditSave(this.panelInfo.id, view).then(() => {
// this.getData(this.param.id)
this.getChart(this.param.id)
bus.$emit('view-in-cache', {
type: 'propChange',
viewId: this.param.id,
@ -3907,7 +3910,6 @@ span {
z-index: 1;
}
.el-input-refresh-time {
width: calc(50% - 4px) !important;
}