Merge branch 'dev-v2' into pr@dev-v2_dzz

This commit is contained in:
dataeaseShu 2023-11-15 09:56:18 +08:00
commit 326bd4d9c8
19 changed files with 128 additions and 60 deletions

View File

@ -71,7 +71,7 @@ public class SQLConstants {
public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
public static final String DEFAULT_INT_FORMAT = "BIGINT";
public static final String DEFAULT_INT_FORMAT = "DECIMAL(20,0)";
public static final String DEFAULT_FLOAT_FORMAT = "DECIMAL(27,8)";

View File

@ -241,7 +241,7 @@ public class DataVisualizationServer implements DataVisualizationApi {
dvType = visualizationTemplate.getDvType();
} else if (DataVisualizationConstants.NEW_PANEL_FROM.NEW_OUTER_TEMPLATE.equals(newFrom)) {
templateStyle = request.getCanvasStyleData();
templateData = request.getCanvasStyleData();
templateData = request.getComponentData();
dynamicData = request.getDynamicData();
staticResource = request.getStaticResource();
name = request.getName();

View File

@ -40,8 +40,6 @@ export function uploadFileResult(file, callback) {
export function findResourceAsBase64(params) {
return request.post({
url: '/staticResource/findResourceAsBase64',
method: 'post',
data: params,
loading: false
data: params
})
}

View File

@ -1 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1699933113241" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4024" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M426.752 344.149333v554.666667c0 23.68 19.285333 42.666667 43.093333 42.666667h84.48a42.666667 42.666667 0 0 0 43.093334-42.666667v-554.666667h84.949333c47.232 0 62.805333-30.549333 34.56-68.266666l-153.642667-204.8c-28.501333-37.973333-74.112-37.717333-102.4 0l-153.6 204.8c-28.501333 37.973333-12.8 68.266667 34.517334 68.266666h84.949333z" fill="#3D3D3D" p-id="4025"></path></svg>
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1699933113241" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4024" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M426.752 344.149333v554.666667c0 23.68 19.285333 42.666667 43.093333 42.666667h84.48a42.666667 42.666667 0 0 0 43.093334-42.666667v-554.666667h84.949333c47.232 0 62.805333-30.549333 34.56-68.266666l-153.642667-204.8c-28.501333-37.973333-74.112-37.717333-102.4 0l-153.6 204.8c-28.501333 37.973333-12.8 68.266667 34.517334 68.266666h84.949333z" p-id="4025"></path></svg>

Before

Width:  |  Height:  |  Size: 716 B

After

Width:  |  Height:  |  Size: 702 B

View File

@ -1801,7 +1801,7 @@ export default {
apply: '应用',
apply_this_template: '应用此模板',
market_network_tips:
'查看模板市场模板需要服务器与模板市场(https://dataease.io/templates)连通,请检查网络...',
'查看模板市场模板需要服务器与模板市场(https://dataease.io/templates2)连通,请检查网络...',
enter_name_tips: '请输入仪表板名称',
name: '名称',
apply_template: '应用模板',

View File

@ -134,7 +134,7 @@ export function findStaticSource(callBack) {
typeof item.propValue['url'] === 'string' &&
item.propValue['url'].indexOf('static-resource') > -1
) {
staticResource.push(item.propValue)
staticResource.push(item.propValue['url'])
}
})
if (staticResource.length > 0) {

View File

@ -1,30 +1,39 @@
<script lang="tsx" setup></script>
<template>
<div class="template-check-info">
<div class="view-panel-Mask">
<Icon class-name="item-icon" name="dv-up-arrow" />
<div>
<Icon class-name="item-icon" name="dv-up-arrow" />
<el-button style="opacity: 1 !important" type="warning" size="mini" round>
<span style="font-weight: bold; opacity: 1"> 当前为模版视图请更换数据集...</span>
</el-button>
</div>
<div>当前为模版视图请更换数据集...</div>
</div>
</template>
<style lang="less" scoped>
.template-check-info {
position: absolute;
.view-panel-Mask {
display: flex;
justify-content: center;
align-items: center;
font-size: 12px;
color: #9ea6b2;
height: calc(100vh - 148px);
width: 100%;
height: 100%;
flex-direction: column;
background-color: rgba(92, 94, 97, 0.7);
position: absolute;
top: 85px;
left: 0px;
z-index: 2;
cursor: not-allowed;
display: flex;
align-items: center;
justify-content: center;
}
.item-icon {
width: 50%;
height: 50%;
opacity: 0.3;
position: absolute;
top: 10px;
left: 300px;
width: 40px;
height: 40px;
opacity: 1;
color: #ff8800;
}
</style>

View File

@ -50,6 +50,7 @@ import DatasetSelect from '@/views/chart/components/editor/dataset-select/Datase
import { useDraggable } from '@vueuse/core'
import { set, concat, keys } from 'lodash-es'
import { Field, getFieldByDQ } from '@/api/chart'
import ChartTemplateInfo from '@/views/chart/components/editor/common/ChartTemplateInfo.vue'
const snapshotStore = snapshotStoreWithOut()
const dvMainStore = dvMainStoreWithOut()
@ -89,6 +90,11 @@ const route = useRoute()
const toolTip = computed(() => {
return props.themes === 'dark' ? 'ndark' : 'dark'
})
const templateStatusShow = computed(() => {
return view.value['dataFrom'] === 'template'
})
const { view } = toRefs(props)
let cacheId = ''
@ -226,6 +232,7 @@ const treeProps = {
}
const recordSnapshotInfo = type => {
view.value['dataFrom'] = 'calc'
snapshotStore.recordSnapshotCache(type, view.value.id)
}
@ -1982,7 +1989,7 @@ const onRefreshChange = val => {
</el-container>
</div>
</el-row>
<chart-template-info v-if="templateStatusShow"></chart-template-info>
<!--显示名修改-->
<el-dialog
:title="t('chart.show_name_set')"

View File

@ -273,7 +273,7 @@ const resourceCreateFinish = templateData => {
wsCache.set(`de-template-data`, JSON.stringify(templateData))
const baseUrl =
curCanvasType.value === 'dataV'
? '#/dvCanvas?opt=create'
? '#/dvCanvas?opt=create&createType=template'
: '#/dashboard?opt=create&createType=template'
if (state.templateCreatePid) {
window.open(baseUrl + `&pid=${state.templateCreatePid}`, '_blank')

View File

@ -93,6 +93,7 @@ const downloadH2 = type => {
}
const downloadAsAppTemplate = downloadType => {
downloadStatus.value = true
nextTick(() => {
const vueDom = previewCanvasContainer.value.querySelector('.canvas-container')
download2AppTemplate(downloadType, vueDom, state.dvInfo.name, () => {

View File

@ -15,6 +15,7 @@ import ChartStyleBatchSet from '@/views/chart/components/editor/editor-style/Cha
import DeCanvas from '@/views/canvas/DeCanvas.vue'
import { check, compareStorage } from '@/utils/CrossPermission'
import { useCache } from '@/hooks/web/useCache'
import { snapshotStoreWithOut } from '@/store/modules/data-visualization/snapshot'
const { wsCache } = useCache()
const eventCheck = e => {
if (e.key === 'panel-weight' && !compareStorage(e.oldValue, e.newValue)) {
@ -25,6 +26,7 @@ const eventCheck = e => {
}
}
const dvMainStore = dvMainStoreWithOut()
const snapshotStore = snapshotStoreWithOut()
const { componentData, curComponent, canvasStyleData, canvasViewInfo, editMode, batchOptStatus } =
storeToRefs(dvMainStore)
@ -72,6 +74,9 @@ onMounted(() => {
dvMainStore.setComponentData(JSON.parse(deTemplateData['componentData']))
dvMainStore.setCanvasStyle(JSON.parse(deTemplateData['canvasStyleData']))
dvMainStore.setCanvasViewInfo(deTemplateData['canvasViewInfo'])
setTimeout(() => {
snapshotStore.recordSnapshotCache()
}, 1500)
}
dataInitState.value = true
// preOpt

View File

@ -11,7 +11,7 @@ import { useRequestStoreWithOut } from '@/store/modules/request'
import { usePermissionStoreWithOut } from '@/store/modules/permission'
import { useMoveLine } from '@/hooks/web/useMoveLine'
import { Icon } from '@/components/icon-custom'
import { downloadCanvas } from '@/utils/imgUtils'
import { download2AppTemplate, downloadCanvas } from '@/utils/imgUtils'
const dvMainStore = dvMainStoreWithOut()
const { dvInfo } = storeToRefs(dvMainStore)
@ -83,6 +83,16 @@ const download = type => {
}, 200)
}
const downloadAsAppTemplate = downloadType => {
downloadStatus.value = true
nextTick(() => {
const vueDom = previewCanvasContainer.value.querySelector('.canvas-container')
download2AppTemplate(downloadType, vueDom, state.dvInfo.name, () => {
downloadStatus.value = false
})
})
}
const slideOpenChange = () => {
slideShow.value = !slideShow.value
}
@ -134,7 +144,12 @@ onBeforeMount(() => {
<el-icon v-else><ArrowRight /></el-icon>
</div>
<template v-if="dvInfo.name">
<preview-head v-show="showPosition === 'preview'" @reload="reload" @download="download" />
<preview-head
v-show="showPosition === 'preview'"
@reload="reload"
@download="download"
@downloadAsAppTemplate="downloadAsAppTemplate"
/>
<div ref="previewCanvasContainer" class="content">
<div class="content-outer">
<div class="content-inner">

View File

@ -179,7 +179,7 @@ onMounted(() => {
window.addEventListener('storage', eventCheck)
}
initDataset()
const { dvId, opt, pid } = window.DataEaseBi || router.currentRoute.value.query
const { dvId, opt, pid, createType } = window.DataEaseBi || router.currentRoute.value.query
if (dvId) {
state.canvasInitStatus = false
initCanvasData(dvId, 'dataV', function () {
@ -197,6 +197,17 @@ onMounted(() => {
state.canvasInitStatus = true
dvMainStore.setDataPrepareState(true)
snapshotStore.recordSnapshotCache('renderChart')
//
if (createType === 'template') {
const deTemplateDataStr = wsCache.get(`de-template-data`)
const deTemplateData = JSON.parse(deTemplateDataStr)
dvMainStore.setComponentData(JSON.parse(deTemplateData['componentData']))
dvMainStore.setCanvasStyle(JSON.parse(deTemplateData['canvasStyleData']))
dvMainStore.setCanvasViewInfo(deTemplateData['canvasViewInfo'])
setTimeout(() => {
snapshotStore.recordSnapshotCache()
}, 1500)
}
})
} else {
let url = '#/screen/index'

View File

@ -1,6 +1,35 @@
<template>
<template-manage></template-manage>
<el-row class="custom-position template-main">
{{ t('visualization.market_network_tips') }}
</el-row>
</template>
<script setup lang="ts">
import TemplateManage from '@/views/template/index.vue'
import { useI18n } from '@/hooks/web/useI18n'
const { t } = useI18n()
</script>
<style lang="less" scoped>
.custom-position {
height: 80vh;
flex: 1;
display: flex;
align-items: center;
justify-content: space-between;
font-size: 14px;
flex-flow: row nowrap;
color: #646a73;
font-weight: 400;
}
.template-main {
text-align: center;
border-radius: 4px;
padding: 0 12px 24px 12px;
height: calc(100vh - 56px) !important;
overflow-x: hidden;
overflow-y: auto;
background-color: var(--ContentBG, #ffffff);
justify-content: center;
}
</style>

View File

@ -36,18 +36,19 @@
<span class="text-template-overflow" :title="ele.name">{{ ele.name }}</span>
<span class="more" @click.stop>
<el-dropdown trigger="click" size="small" @command="type => clickMore(type, ele)">
<span class="el-dropdown-link">
<i class="el-icon-more" />
</span>
<el-icon class="el-icon-more"><MoreFilled /></el-icon>
<template #dropdown>
<el-dropdown-menu class="de-template-dropdown">
<el-dropdown-item icon="el-icon-upload2" command="import">
<el-dropdown-item command="import">
<el-icon><Upload /></el-icon>
{{ t('visualization.import') }}
</el-dropdown-item>
<el-dropdown-item icon="el-icon-edit" command="edit">
<el-dropdown-item command="edit">
<el-icon><EditPen /></el-icon>
{{ t('visualization.rename') }}
</el-dropdown-item>
<el-dropdown-item icon="el-icon-delete" command="delete">
<el-dropdown-item command="delete">
<el-icon><Delete /></el-icon>
{{ t('visualization.delete') }}
</el-dropdown-item>
</el-dropdown-menu>

View File

@ -197,12 +197,7 @@ const handlerConfirm = option => {
}
const templateDeleteConfirm = template => {
const options = {
title: 'system_parameter_setting.delete_this_template',
type: 'primary',
cb: () => templateDelete(template.id)
}
handlerConfirm(options)
templateDeleteInfo(template.id)
}
const handleClick = (tab, event) => {
@ -222,15 +217,23 @@ const showCurrentTemplate = (pid, label) => {
const templateFolderDelete = id => {
if (id) {
templateDelete(id).then(response => {
ElMessage.info(t('commons.delete_success'))
ElMessage({
message: t('commons.delete_success'),
type: 'success',
showClose: true
})
getTree()
})
}
}
const templateDelete = id => {
const templateDeleteInfo = id => {
if (id) {
templateDelete(id).then(response => {
ElMessage.info(t('commons.delete_success'))
ElMessage({
message: t('commons.delete_success'),
type: 'success',
showClose: true
})
showCurrentTemplate(state.currentTemplateId, state.currentTemplateLabel)
})
}

View File

@ -14,7 +14,7 @@ public interface TemplateManageApi {
@PostMapping("/save")
TemplateManageDTO save(@RequestBody TemplateManageRequest request);
@DeleteMapping("/delete/{id}")
@PostMapping("/delete/{id}")
void delete(@PathVariable String id);
@GetMapping("/findOne/{templateId}")

View File

@ -12,13 +12,13 @@ import java.util.Map;
public interface StaticResourceApi {
@PostMapping("upload/{fileId}")
@Operation(summary = "上传静态文件")
public void upload(@PathVariable("fileId") String fileId, @RequestPart("file") MultipartFile file);
void upload(@PathVariable("fileId") String fileId, @RequestPart("file") MultipartFile file);
@PostMapping("findResourceAsBase64")
@Operation(summary = "查找静态文件并转为Base64")
public Map<String,String> findResourceAsBase64(@RequestBody StaticResourceRequest resourceRequest);
Map<String,String> findResourceAsBase64(@RequestBody StaticResourceRequest resourceRequest);
@GetMapping("urlTest")
public Map<String,String> urlTest();
Map<String,String> urlTest();
}

View File

@ -200,10 +200,7 @@ public class HttpClientUtil {
* @return 响应结果字符串
*/
public static String post(String url, Map<String, String> body, HttpClientConfig config) {
CloseableHttpClient httpClient = null;
try {
buildHttpClient(url);
try (CloseableHttpClient httpClient = buildHttpClient(url)) {
HttpPost httpPost = new HttpPost(url);
if (config == null) {
config = new HttpClientConfig();
@ -231,14 +228,6 @@ public class HttpClientUtil {
} catch (Exception e) {
logger.error("HttpClient查询失败", e);
throw new DEException(SYSTEM_INNER_ERROR.code(), "HttpClient查询失败: " + e.getMessage());
} finally {
try {
if(httpClient != null){
httpClient.close();
}
} catch (Exception e) {
logger.error("HttpClient关闭连接失败", e);
}
}
}