Merge remote-tracking branch 'origin/dev' into dev

This commit is contained in:
wisonic-s 2024-07-19 17:39:51 +08:00
commit 1843ad9589
18 changed files with 219 additions and 66 deletions

View File

@ -109,7 +109,16 @@ public class MysqlExtDDLProvider extends DefaultExtDDLProvider {
StringBuilder builder = new StringBuilder("WHERE 1 = 1 ");
for (TableField searchField : searchFields) {
//目前只考虑等于
builder.append("AND $Column_Field$ = ? ".replace("$Column_Field$", searchField.getFieldName()));
if (searchField.getInCount() > 1) {
List<String> pList = new ArrayList<>();
for (int i = 0; i < searchField.getInCount(); i++) {
pList.add("?");
}
String str = "AND $Column_Field$ IN (" + String.join(", ", pList) + ")";
builder.append(str.replace("$Column_Field$", searchField.getFieldName()));
} else {
builder.append("AND $Column_Field$ = ? ".replace("$Column_Field$", searchField.getFieldName()));
}
}
return builder.toString();
}

View File

@ -435,9 +435,7 @@ public class OracleQueryProvider extends QueryProvider {
xAxis.add(chartViewFieldDTO);
List<ChartFieldCustomFilterDTO> fieldCustomFilter = new ArrayList<>();
// for (ChartFieldCustomFilterDTO chartFieldCustomFilterDTO : OrgFieldCustomFilter) {
// fieldCustomFilter.add(chartFieldCustomFilterDTO);
// }
ChartFieldCustomFilterDTO chartFieldCustomFilterDTO = new ChartFieldCustomFilterDTO();
DatasetTableField datasetTableField = new DatasetTableField();
datasetTableField.setOriginName("ROWNUM");
@ -463,7 +461,6 @@ public class OracleQueryProvider extends QueryProvider {
} else {
if (pageInfo.getGoPage() != null && pageInfo.getPageSize() != null) {
System.out.println("SELECT * FROM (" + sqlFix(originalTableInfo("(" + sqlFix(table) + ")", xAxis, OrgFieldCustomFilter, rowPermissionsTree, extFilterRequestList, ds, view, fieldCustomFilter)) + ") DE_RESULT_TMP " + " WHERE DE_ROWNUM > " + (pageInfo.getGoPage() - 1) * pageInfo.getPageSize());
return "SELECT * FROM (" + sqlFix(originalTableInfo("(" + sqlFix(table) + ")", xAxis, OrgFieldCustomFilter, rowPermissionsTree, extFilterRequestList, ds, view, fieldCustomFilter)) + ") DE_RESULT_TMP " + " WHERE DE_ROWNUM > " + (pageInfo.getGoPage() - 1) * pageInfo.getPageSize();
} else {
return "SELECT * FROM (" + sqlFix(originalTableInfo("(" + sqlFix(table) + ")", xAxis, OrgFieldCustomFilter, rowPermissionsTree, extFilterRequestList, ds, view, fieldCustomFilter)) + ") DE_RESULT_TMP ";
@ -525,10 +522,12 @@ public class OracleQueryProvider extends QueryProvider {
List<SQLObj> fields = new ArrayList<>();
fields.addAll(xFields);
List<String> wheres = new ArrayList<>();
List<String> pageWheres = new ArrayList<>();
if (customWheres != null) wheres.add(customWheres);
if (extWheres != null) wheres.add(extWheres);
if (whereTrees != null) wheres.add(whereTrees);
if (oldWhere != null) wheres.add(oldWhere);
if (oldWhere != null) pageWheres.add(oldWhere);
List<SQLObj> groups = new ArrayList<>();
groups.addAll(xFields);
// 外层再次套sql
@ -539,6 +538,7 @@ public class OracleQueryProvider extends QueryProvider {
ST st_sql = stg.getInstanceOf("previewSql");
st_sql.add("isGroup", false);
if (CollectionUtils.isNotEmpty(xFields)) st_sql.add("groups", xFields);
if (CollectionUtils.isNotEmpty(wheres)) st_sql.add("filters", wheres);
if (CollectionUtils.isNotEmpty(orders)) st_sql.add("orders", orders);
if (ObjectUtils.isNotEmpty(tableObj)) st_sql.add("table", tableObj);
String sql = st_sql.render();
@ -571,7 +571,7 @@ public class OracleQueryProvider extends QueryProvider {
.tableName(String.format(OracleConstants.BRACKETS, sql))
.tableAlias(String.format(TABLE_ALIAS_PREFIX, 2))
.build();
if (CollectionUtils.isNotEmpty(wheres)) st2.add("filters", wheres);
if (CollectionUtils.isNotEmpty(pageWheres)) st2.add("filters", pageWheres);
if (ObjectUtils.isNotEmpty(tableSQL)) st2.add("table", tableSQL2);
return st2.render();

View File

@ -343,6 +343,7 @@ public class ChartViewService {
//downloadType = dataset 为下载原始名字 这里做数据转换模拟 table-info类型图表导出
if ("dataset".equals(request.getDownloadType())) {
view.setType("table-info");
view.setIsPlugin(false);
List<DatasetTableField> sourceFields = dataSetTableFieldsService.getFieldsByTableId(view.getTableId());
dsHeader = sourceFields.stream()
.map(DatasetTableField::getName)

View File

@ -227,16 +227,29 @@ public class DataFillDataService {
String whereSql = "";
if (StringUtils.isNotBlank(searchRequest.getPrimaryKeyValue())) {
whereSql = extDDLProvider.whereSql(dataFillForm.getTableName(), List.of(pk));
}
String countSql = extDDLProvider.countSql(dataFillForm.getTableName(), searchFields, whereSql);
if (StringUtils.isNotBlank(searchRequest.getPrimaryKeyValue())) {
datasourceRequest.setTableFieldWithValues(List.of(new DatasourceRequest.TableFieldWithValue()
.setValue(searchRequest.getPrimaryKeyValue())
.setFiledName(pk.getFieldName())
.setTypeName(pk.getFieldType())
.setType(pk.getType())));
}
if (CollectionUtils.isNotEmpty(searchRequest.getPrimaryKeyValueList())) {
pk.setInCount(searchRequest.getPrimaryKeyValueList().size());
whereSql = extDDLProvider.whereSql(dataFillForm.getTableName(), List.of(pk));
List<DatasourceRequest.TableFieldWithValue> ids = new ArrayList<>();
for (String s : searchRequest.getPrimaryKeyValueList()) {
ids.add(new DatasourceRequest.TableFieldWithValue()
.setValue(s)
.setFiledName(pk.getFieldName())
.setTypeName(pk.getFieldType())
.setType(pk.getType()));
}
datasourceRequest.setTableFieldWithValues(ids);
}
String countSql = extDDLProvider.countSql(dataFillForm.getTableName(), searchFields, whereSql);
datasourceRequest.setQuery(countSql);
List<String[]> countData = datasourceProvider.getData(datasourceRequest);
long count = NumberUtils.toLong(countData.get(0)[0]);
@ -1022,6 +1035,10 @@ public class DataFillDataService {
datasourceRequest.setDatasource(ds);
datasourceRequest.setTable(dataFillForm.getTableName());
Provider datasourceProvider = ProviderFactory.getProvider(ds.getType());
ExtDDLProvider extDDLProvider = ProviderFactory.gerExtDDLProvider(ds.getType());
setLowerCaseRequest(ds, datasourceProvider, extDDLProvider, datasourceRequest);
List<TableField> tableFields = datasourceProvider.getTableFields(datasourceRequest);
for (TableField tableField : tableFields) {

View File

@ -1,6 +1,6 @@
{
"name": "dataease",
"version": "1.18.22",
"version": "1.18.23",
"description": "dataease front",
"private": true,
"scripts": {

View File

@ -15,17 +15,20 @@
>
<PasswordUpdateForm />
</el-dialog>
<ExportExcel ref="ExportExcelRef" />
</div>
</template>
<script>
import ExportExcel from '@/views/dataset/exportExcel/index.vue'
import PluginCom from '@/views/system/plugin/PluginCom'
import { mapState } from 'vuex'
import PasswordUpdateForm from '@/views/system/user/PasswordUpdateForm.vue'
import bus from '@/utils/bus'
export default {
name: 'App',
components: { PluginCom, PasswordUpdateForm },
components: { PluginCom, PasswordUpdateForm, ExportExcel },
data() {
return {
showPasswordModifiedDialog: false,
@ -46,11 +49,20 @@ export default {
}
},
mounted() {
bus.$on('data-export-center', this.downloadClick)
const passwordModified = JSON.parse(localStorage.getItem('passwordModified'))
this.defaultPwd = localStorage.getItem('defaultPwd')
if (typeof passwordModified === 'boolean') {
this.$store.commit('user/SET_PASSWORD_MODIFIED', passwordModified)
}
},
beforeDestroy() {
bus.$off('data-export-center', this.downloadClick)
},
methods: {
downloadClick() {
this.$refs.ExportExcelRef.init()
}
}
}
</script>

View File

@ -489,8 +489,7 @@ export default {
this.$message({
message: h('p', null, [
this.$t('data_export.exporting'),
this.showEditPosition === 'bar-main-preview'
? h(
h(
Button,
{
props: {
@ -504,7 +503,7 @@ export default {
}
},
this.$t('data_export.export_center')
) : this.$t('data_export.export_center'),
),
this.$t('data_export.export_info')
]),
iconClass,

View File

@ -172,7 +172,7 @@
<el-button
v-if="showChartInfoType==='details' && showChartInfo.dataFrom !== 'template' && !userId && hasDataPermission('export',panelInfo.privileges)"
size="mini"
:disabled="$store.getters.loadingMap[$store.getters.currentPath] || dialogLoading"
:disabled="$store.getters.loadingMap[$store.getters.currentPath]"
@click="exportSourceDetails"
>
<svg-icon
@ -191,12 +191,11 @@
:open-type="showChartInfoType"
/>
</el-dialog>
<ExportExcel ref="ExportExcelRef" />
</div>
</template>
<script>
import ExportExcel from '@/views/dataset/exportExcel/index.vue'
import { Button } from 'element-ui'
import { getStyle } from '@/components/canvas/utils/style'
import { mapState } from 'vuex'
import ComponentWrapper from './ComponentWrapper'
@ -222,7 +221,7 @@ import LinkOptBar from '@/components/canvas/components/editor/LinkOptBar'
const erd = elementResizeDetectorMaker()
export default {
components: { LinkOptBar, UserViewDialog, ComponentWrapper, CanvasOptBar, PDFPreExport, ExportExcel },
components: { LinkOptBar, UserViewDialog, ComponentWrapper, CanvasOptBar, PDFPreExport },
model: {
prop: 'show',
event: 'change'
@ -564,10 +563,8 @@ export default {
bus.$on('trigger-search-button', this.triggerSearchButton)
bus.$on('trigger-reset-button', this.triggerResetButton)
this.initPdfTemplate()
bus.$on('data-export-center', this.downloadClick)
},
beforeDestroy() {
bus.$off('data-export-center', this.downloadClick)
if (this.$refs[this.previewTempRefId]) {
erd.uninstall(this.$refs[this.previewTempRefId])
}
@ -582,9 +579,6 @@ export default {
bus.$off('trigger-reset-button', this.triggerResetButton)
},
methods: {
downloadClick() {
this.$refs.ExportExcelRef.init()
},
reloadWatermark() {
if (this.screenShotStatues) {
this.initWatermark('preview-temp-canvas-main')
@ -881,11 +875,89 @@ export default {
this.$nextTick(() => (eventBus.$emit('resizing', '')))
}
},
openMessageLoading(cb) {
const h = this.$createElement
const iconClass = `el-icon-loading`
const customClass = `de-message-loading de-message-export`
this.$message({
message: h('p', null, [
this.$t('data_export.exporting'),
h(
Button,
{
props: {
type: 'text',
},
class: 'btn-text',
on: {
click: () => {
cb()
}
}
},
this.$t('data_export.export_center')
),
this.$t('data_export.export_info')
]),
iconClass,
showClose: true,
customClass
})
},
openMessageSuccess(text, type, cb) {
const h = this.$createElement
const iconClass = `el-icon-${type || 'success'}`
const customClass = `de-message-${type || 'success'} de-message-export`
this.$message({
message: h('p', null, [
h('span', null, text),
h(
Button,
{
props: {
type: 'text',
},
class: 'btn-text',
on: {
click: () => {
cb()
}
}
},
this.$t('data_export.export_center')
)
]),
iconClass,
showClose: true,
customClass
})
},
exportData() {
bus.$emit('data-export-center')
},
exportExcel() {
this.$refs['userViewDialog-canvas-main'].exportExcel()
this.$refs['userViewDialog-canvas-main'].exportExcel((val) => {
if (val && val.success) {
this.openMessageLoading(this.exportData)
}
if (val && val.success === false) {
this.openMessageSuccess(`${this.showChartTableInfo.title ? this.showChartTableInfo.title : this.showChartTableInfo.name} 导出失败,前往`, 'error', this.exportData)
}
this.dialogLoading = false
})
},
exportSourceDetails() {
this.$refs['userViewDialog-canvas-main'].exportExcel()
this.$refs['userViewDialog-canvas-main'].exportExcel((val) => {
if (val && val.success) {
this.openMessageLoading(this.exportData)
}
if (val && val.success === false) {
this.openMessageSuccess(`${this.showChartTableInfo.title ? this.showChartTableInfo.title : this.showChartTableInfo.name} 导出失败,前往`, 'error', this.exportData)
}
this.dialogLoading = false
})
},
exportViewImg() {
this.imageDownloading = true

View File

@ -778,8 +778,7 @@ export default {
this.$message({
message: h('p', null, [
this.$t('data_export.exporting'),
this.editMode === 'preview'
? h(
h(
Button,
{
props: {
@ -793,7 +792,7 @@ export default {
}
},
this.$t('data_export.export_center')
) : this.$t('data_export.export_center'),
),
this.$t('data_export.export_info')
]),
iconClass,

View File

@ -469,7 +469,10 @@ export function getCacheTree(treeName) {
}
export function exportExcelDownload(chart, snapshot, width, height, loadingWrapper, downloadParams, callBack) {
if ((chart.render === 'echarts' || ['text', 'label'].includes(chart.type)) && !(chart.data?.series?.length && chart.data?.series[0].data?.length)) {
if (chart.type === 'race-bar' && !chart.data?.data?.length) {
callBack()
return
} else if ((chart.render === 'echarts' && chart.type !== 'race-bar' && chart.type.indexOf('table') === -1 || ['text', 'label'].includes(chart.type)) && !(chart.data?.series?.length && chart.data?.series[0].data?.length)) {
callBack()
return
} else if ((chart.render === 'antv' && !['text', 'label', 'flow-map'].includes(chart.type)) && !chart.data?.data?.length) {

View File

@ -671,6 +671,7 @@ export default {
form_update_rule_none: 'Update Rules cannot be null',
form_components_cannot_null: 'Form components cannot be null',
option_list_cannot_empty: 'Option list cannot be empty',
option_list_datasource_cannot_empty: 'Datasource Settings of option list cannot be empty',
component_setting_error: 'Component setting error',
table_name: 'Table',
form_column: 'Form Column',

View File

@ -671,6 +671,7 @@ export default {
form_update_rule_none: '請配置更新規則',
form_components_cannot_null: '請添加表單組件',
option_list_cannot_empty: '選項值不能為空',
option_list_datasource_cannot_empty: '選項值綁定數據源配置不能為空',
component_setting_error: '組件設置錯誤',
table_name: '數據庫表名',
form_column: '表單字段',

View File

@ -669,6 +669,7 @@ export default {
form_update_rule_none: '请配置更新规则',
form_components_cannot_null: '请添加表单组件',
option_list_cannot_empty: '选项值不能为空',
option_list_datasource_cannot_empty: '选项值绑定数据源配置不能为空',
component_setting_error: '组件设置错误',
table_name: '数据库表名',
form_column: '表单字段',

View File

@ -1,7 +1,5 @@
<template>
<span
style="display: inline-block;"
>
<span style="display: inline-block">
<el-popover
placement="bottom"
trigger="hover"
@ -11,37 +9,66 @@
>
<div
class="remark-style"
:style="{backgroundColor:remarkCfg.bgFill}"
v-html="$xss(remarkCfg.content)"
:style="{ backgroundColor: remarkCfg.bgFill }"
v-html="xssRemarkCfgContent"
/>
<i
slot="reference"
class="el-icon-info"
style="cursor: pointer;color: gray;font-size: 12px;position: relative;
z-index: 10;"
style="
cursor: pointer;
color: gray;
font-size: 12px;
position: relative;
z-index: 10;
"
/>
</el-popover>
</span>
</template>
<script>
import { mapState } from 'vuex'
import { mapState } from "vuex";
import xss from "xss";
export default {
name: 'TitleRemark',
name: "TitleRemark",
props: {
remarkCfg: {
type: Object,
required: true
}
required: true,
},
},
computed: {
...mapState(['previewVisible'])
}
}
...mapState(["previewVisible"]),
xssRemarkCfgContent() {
const myXss = new xss.FilterXSS({
css: {
whiteList: {
"background-color": true,
"text-align": true,
color: true,
"margin-top": true,
"margin-bottom": true,
"line-height": true,
"box-sizing": true,
"padding-top": true,
"padding-bottom": true,
},
},
whiteList: {
...xss.whiteList,
p: ["style"],
span: ["style"],
},
});
return myXss.process(this.remarkCfg.content);
},
},
};
</script>
<style scoped>
.remark-style{
.remark-style {
position: relative;
z-index: 10;
min-height: 100px;
@ -52,29 +79,29 @@ export default {
border-radius: 4px;
}
::-webkit-scrollbar {
width: 0px!important;
height: 0px!important;
width: 0px !important;
height: 0px !important;
}
::v-deep ol {
display: block!important;
display: block !important;
list-style-type: decimal;
margin-block-start: 1em!important;
margin-block-end: 1em!important;
margin-inline-start: 0px!important;
margin-inline-end: 0px!important;
padding-inline-start: 40px!important;
margin-block-start: 1em !important;
margin-block-end: 1em !important;
margin-inline-start: 0px !important;
margin-inline-end: 0px !important;
padding-inline-start: 40px !important;
}
::v-deep ul {
display: block!important;
display: block !important;
list-style-type: disc;
margin-block-start: 1em!important;
margin-block-end: 1em!important;
margin-inline-start: 0px!important;
margin-inline-end: 0px!important;
padding-inline-start: 40px!important;
margin-block-start: 1em !important;
margin-block-end: 1em !important;
margin-inline-start: 0px !important;
margin-inline-end: 0px !important;
padding-inline-start: 40px !important;
}
::v-deep li {
display: list-item!important;
text-align: -webkit-match-parent!important;
display: list-item !important;
text-align: -webkit-match-parent !important;
}
</style>

View File

@ -722,6 +722,18 @@ export default {
}
}
}
} else {
if (f.settings.optionDatasource === undefined ||
f.settings.optionTable === undefined ||
f.settings.optionColumn === undefined) {
this.selectItem(f.id)
this.$message({
message: this.$t('data_fill.form.option_list_datasource_cannot_empty'),
type: 'error',
showClose: true
})
return
}
}
}
}
@ -746,7 +758,7 @@ export default {
forEach(this.formSettings.forms, f => {
const temp = find(this.tempForms, tf => tf.id === f.id)
if (temp) {
f.settings.updateRuleCheck = temp.updateRuleCheck
this.$set(f.settings, 'updateRuleCheck', temp.updateRuleCheck)
}
})
this.closeEditCommitRule()

View File

@ -226,7 +226,6 @@ export default {
}
},
created() {
this.handleClick()
},
mounted() {
bus.$on('task-export-topic-call', this.taskExportTopicCall)

View File

@ -1,6 +1,6 @@
{
"name": "dataease-mobile",
"version": "1.18.22",
"version": "1.18.23",
"private": true,
"scripts": {
"serve": "npm run dev:h5",

View File

@ -9,7 +9,7 @@
<packaging>pom</packaging>
<properties>
<dataease.version>1.18.22</dataease.version>
<dataease.version>1.18.23</dataease.version>
<poi.version>4.1.1</poi.version>
<xmlbeans.version>3.1.0</xmlbeans.version>
</properties>