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

This commit is contained in:
taojinlong 2024-06-03 19:25:09 +08:00
commit 2382b3164f
22 changed files with 205 additions and 82 deletions

View File

@ -93,10 +93,13 @@ const saveCanvasWithCheck = () => {
const saveResource = () => {
wsCache.delete('DE-DV-CATCH-' + dvInfo.value.id)
if (styleChangeTimes.value > 0) {
snapshotStore.resetStyleChangeTimes()
canvasSave(() => {
ElMessage.success('保存成功')
window.history.pushState({}, '', `#/dvCanvas?dvId=${dvInfo.value.id}`)
eventBus.emit('hideArea-canvas-main')
nextTick(() => {
snapshotStore.resetStyleChangeTimes()
canvasSave(() => {
ElMessage.success('保存成功')
window.history.pushState({}, '', `#/dvCanvas?dvId=${dvInfo.value.id}`)
})
})
}
}

View File

@ -207,7 +207,11 @@ const deepScale = computed(() => scale.value / 100)
@userViewEnlargeOpen="opt => emits('userViewEnlargeOpen', opt)"
></component-edit-bar>
<component-selector
v-if="props.isSelector && config.component === 'UserView'"
v-if="
props.isSelector &&
config.component === 'UserView' &&
config.propValue?.innerType !== 'rich-text'
"
:resource-id="config.id"
/>
<div class="wrapper-inner" ref="componentWrapperInnerRef" :style="componentBackgroundStyle">

View File

@ -1,6 +1,5 @@
<template>
<el-row>
--{{ linkInfo }}
<el-form @submit.prevent ref="form" size="small" style="width: 100%">
<el-form-item :effect="themes" :label="t('visualization.auto_play')">
<el-switch

View File

@ -81,14 +81,14 @@ const clearStyle = e => {
}
const handleBlur = e => {
element.value.propValue = e.target.innerHTML || '&nbsp;'
element.value.propValue = e.target.innerHTML || ''
const html = e.target.innerHTML
if (html !== '') {
element.value.propValue = e.target.innerHTML
} else {
element.value.propValue = ''
nextTick(function () {
element.value.propValue = '&nbsp;'
element.value.propValue = ''
})
}
canEdit.value = false

View File

@ -389,7 +389,7 @@ const autoStyle = computed(() => {
</script>
<template>
<div class="v-query-container" :style="autoStyle">
<div class="v-query-container" :style="autoStyle" @keydown.stop @keyup.stop>
<p v-if="customStyle.titleShow" class="title" :style="titleStyle">
{{ customStyle.title }}
</p>

View File

@ -501,7 +501,6 @@ const validate = () => {
const isMultiple = +ele.displayType === 7 || ele.multiple
ele.selectValue = isMultiple ? [] : undefined
ele.defaultValue = isMultiple ? [] : undefined
return false
}
if (ele.displayType === '1') {
@ -587,7 +586,7 @@ const validate = () => {
return false
}
if (ele.optionValueSource === 2 && !ele.valueSource?.length) {
if (ele.optionValueSource === 2 && !ele.valueSource?.filter(ele => !!ele).length) {
ElMessage.error('手工输入-选项值不能为空')
return true
}
@ -687,6 +686,19 @@ const setConditionOut = () => {
init(conditions.value[conditions.value.length - 1].id)
}
const setActiveSelectTab = (arr, id) => {
let activelist = 'dimensionList'
arr.some((ele, index) => {
if ((ele || []).some(itx => itx.id === id)) {
activelist = ['dimensionList', 'quotaList', 'parameterList'][index]
return true
}
return false
})
return activelist
}
const init = (queryId: string) => {
if (!datasetTree.value.length) {
initDataset()
@ -725,7 +737,12 @@ const init = (queryId: string) => {
fields.value = datasetFieldList.value
.map(ele => {
if (!datasetMap[ele.tableId]) return null
return { ...datasetMap[ele.tableId], componentId: ele.id }
const activeCom = datasetMap[ele.tableId].fields || {}
const activelist = setActiveSelectTab(
[activeCom.dimensionList, activeCom.quotaList, activeCom.parameterList],
curComponent.value.checkedFieldsMap[ele.id]
)
return { ...datasetMap[ele.tableId], componentId: ele.id, activelist }
})
.filter(ele => !!ele)
})
@ -813,6 +830,13 @@ const handleCondition = item => {
idMap.includes(ele)
)
if (!!fields.value?.length) {
fields.value.forEach(ele => {
const activeCom = ele.fields
ele.activelist = setActiveSelectTab(
[activeCom.dimensionList, activeCom.quotaList, activeCom.parameterList],
curComponent.value.checkedFieldsMap[ele.componentId]
)
})
handleCheckedFieldsChange(curComponent.value.checkedFields)
}
multipleChange(curComponent.value.multiple)
@ -1337,7 +1361,7 @@ defineExpose({
value="1"
/>
<el-option
:disabled="!['1', '7'].includes(curComponent.displayType)"
:disabled="!['1', '7'].includes(curComponent.displayType) || isTimeParameter"
label="时间范围"
value="7"
/>
@ -1544,11 +1568,7 @@ defineExpose({
</el-icon>
</template>
<el-option
v-for="ele in curComponent.dataset.fields.filter(
ele =>
ele.deType === +curComponent.displayType ||
([3, 4].includes(ele.deType) && +curComponent.displayType === 2)
)"
v-for="ele in curComponent.dataset.fields"
:key="ele.id"
:label="ele.name"
:value="ele.id"
@ -1603,6 +1623,13 @@ defineExpose({
<div :key="index" v-for="(_, index) in valueSource" class="select-item">
<el-input
maxlength="20"
v-if="curComponent.displayType === '2'"
@blur="weightlessness"
v-model.number="valueSource[index]"
></el-input>
<el-input
maxlength="20"
v-else
@blur="weightlessness"
v-model="valueSource[index]"
></el-input>

View File

@ -334,15 +334,19 @@ watch(
watch(
() => config.value.optionValueSource,
val => {
debounceOptions(val)
(valNew, newOld) => {
if ([valNew, newOld].includes(2)) {
selectValue.value = Array.isArray(selectValue.value) ? [] : undefined
config.value.selectValue = cloneDeep(selectValue.value)
config.value.defaultValue = cloneDeep(selectValue.value)
}
debounceOptions(valNew)
}
)
watch(
[() => config.value.checkedFields, () => config.value.checkedFieldsMap],
() => {
if (!props.isConfig) return
debounceOptions(config.value.optionValueSource)
},
{

View File

@ -125,8 +125,14 @@ export const customAttrTrans = {
'wordSizeRange',
'wordSpacing'
],
label: ['fontSize'],
tooltip: ['fontSize'],
label: {
fontSize: '',
seriesLabelFormatter: ['fontSize']
},
tooltip: {
fontSize: '',
seriesTooltipFormatter: ['fontSize']
},
indicator: ['fontSize', 'suffixFontSize'],
indicatorName: ['fontSize', 'nameValueSpacing']
}
@ -296,15 +302,25 @@ export function recursionTransObj(template, infoObj, scale, terminal) {
// 如果是数组 进行赋值计算
if (template[templateKey] instanceof Array) {
template[templateKey].forEach(templateProp => {
if (infoObj[templateKey] && infoObj[templateKey][templateProp]) {
if (
infoObj[templateKey] &&
(infoObj[templateKey][templateProp] || infoObj[templateKey].length)
) {
// 移动端特殊属性值设置
if (terminal === 'mobile' && mobileSpecialProps[templateProp] !== undefined) {
infoObj[templateKey][templateProp] = mobileSpecialProps[templateProp]
} else {
infoObj[templateKey][templateProp] = getScaleValue(
infoObj[templateKey][templateProp],
scale
)
// 数组依次设置
if (infoObj[templateKey] instanceof Array) {
infoObj[templateKey].forEach(v => {
v[templateProp] = getScaleValue(v[templateProp], scale)
})
} else {
infoObj[templateKey][templateProp] = getScaleValue(
infoObj[templateKey][templateProp],
scale
)
}
}
}
})

View File

@ -152,7 +152,7 @@ export function initCanvasDataPrepare(dvId, busiFlag, callBack) {
})
}
export function initCanvasData(dvId, busiFlag, callBack) {
export async function initCanvasData(dvId, busiFlag, callBack) {
initCanvasDataPrepare(
dvId,
busiFlag,

View File

@ -64,10 +64,15 @@ const changeThreshold = () => {
const changeSplitThreshold = (threshold: string) => {
// check input
if (threshold) {
const regex = /^(\d+)(,\d+)*$/
if (!regex.test(threshold)) {
ElMessage.error(t('chart.gauge_threshold_format_error'))
return
}
const arr = threshold.split(',')
for (let i = 0; i < arr.length; i++) {
const ele = arr[i]
if (parseFloat(ele).toString() === 'NaN' || parseFloat(ele) <= 0 || parseFloat(ele) >= 100) {
if (parseFloat(ele) <= 0 || parseFloat(ele) >= 100) {
ElMessage.error(t('chart.gauge_threshold_format_error'))
return
}

View File

@ -560,7 +560,7 @@ onMounted(() => {
:effect="themes"
v-model="state.basicStyleForm.showZoom"
:predefine="predefineColors"
@change="changeBasicStyle('zoomShow')"
@change="changeBasicStyle('showZoom')"
>
{{ t('chart.show_zoom') }}
</el-checkbox>

View File

@ -33,6 +33,12 @@ const state = reactive({
const emit = defineEmits(['onChangeYAxisForm'])
const splitLineStyle = [
{ label: t('chart.line_type_solid'), value: 'solid' },
{ label: t('chart.line_type_dashed'), value: 'dashed' },
{ label: t('chart.line_type_dotted'), value: 'dotted' }
]
watch(
() => props.form,
() => {
@ -284,10 +290,26 @@ onMounted(() => {
is-custom
/>
</el-form-item>
<el-form-item class="form-item" :class="'form-item-' + themes" style="padding: 0 4px">
<el-select
:disabled="!state.axisForm.splitLine.show"
style="width: 62px"
:effect="props.themes"
v-model="state.axisForm.splitLine.lineStyle.style"
@change="changeAxisStyle('splitLine.lineStyle.style')"
>
<el-option
v-for="option in splitLineStyle"
:key="option.value"
:value="option.value"
:label="option.label"
></el-option>
</el-select>
</el-form-item>
<el-form-item class="form-item" :class="'form-item-' + themes" style="padding-left: 4px">
<el-input-number
:disabled="!state.axisForm.splitLine.show"
style="width: 108px"
style="width: 74px"
:effect="props.themes"
v-model="state.axisForm.splitLine.lineStyle.width"
:min="1"

View File

@ -316,10 +316,26 @@ onMounted(() => {
is-custom
/>
</el-form-item>
<el-form-item class="form-item" :class="'form-item-' + themes" style="padding: 0 4px">
<el-select
:disabled="!state.axisForm.splitLine.show"
style="width: 62px"
:effect="props.themes"
v-model="state.axisForm.splitLine.lineStyle.style"
@change="changeAxisStyle('splitLine.lineStyle.style')"
>
<el-option
v-for="option in splitLineStyle"
:key="option.value"
:value="option.value"
:label="option.label"
></el-option>
</el-select>
</el-form-item>
<el-form-item class="form-item" :class="'form-item-' + themes" style="padding-left: 4px">
<el-input-number
:disabled="!state.axisForm.splitLine.show"
style="width: 108px"
style="width: 74px"
:effect="props.themes"
v-model="state.axisForm.splitLine.lineStyle.width"
:min="1"
@ -330,22 +346,6 @@ onMounted(() => {
/>
</el-form-item>
</div>
<el-form-item class="form-item" :class="'form-item-' + themes">
<el-select
:disabled="!state.axisForm.splitLine.show"
style="width: 108px"
:effect="props.themes"
v-model="state.axisForm.splitLine.lineStyle.style"
@change="changeAxisStyle('splitLine.lineStyle')"
>
<el-option
v-for="option in splitLineStyle"
:key="option.value"
:value="option.value"
:label="option.label"
></el-option>
</el-select>
</el-form-item>
</div>
<el-divider class="m-divider" :class="'m-divider--' + themes" />
<el-form-item

View File

@ -298,10 +298,26 @@ onMounted(() => {
is-custom
/>
</el-form-item>
<el-form-item class="form-item" :class="'form-item-' + themes" style="padding: 0 4px">
<el-select
:disabled="!state.axisForm.splitLine.show"
style="width: 62px"
:effect="props.themes"
v-model="state.axisForm.splitLine.lineStyle.style"
@change="changeAxisStyle('splitLine.lineStyle.style')"
>
<el-option
v-for="option in splitLineStyle"
:key="option.value"
:value="option.value"
:label="option.label"
></el-option>
</el-select>
</el-form-item>
<el-form-item class="form-item" :class="'form-item-' + themes" style="padding-left: 4px">
<el-input-number
:disabled="!state.axisForm.splitLine.show"
style="width: 108px"
style="width: 74px"
:effect="props.themes"
v-model="state.axisForm.splitLine.lineStyle.width"
:min="1"
@ -312,22 +328,6 @@ onMounted(() => {
/>
</el-form-item>
</div>
<el-form-item class="form-item" :class="'form-item-' + themes">
<el-select
:disabled="!state.axisForm.splitLine.show"
style="width: 108px"
:effect="props.themes"
v-model="state.axisForm.splitLine.lineStyle.style"
@change="changeAxisStyle('splitLine.lineStyle')"
>
<el-option
v-for="option in splitLineStyle"
:key="option.value"
:value="option.value"
:label="option.label"
></el-option>
</el-select>
</el-form-item>
</div>
<el-divider
v-if="showProperty('axisLabel')"

View File

@ -530,7 +530,8 @@ export function getYAxisExt(chart: Chart) {
line: {
style: {
stroke: yAxis.splitLine.lineStyle.color,
lineWidth: yAxis.splitLine.lineStyle.width
lineWidth: yAxis.splitLine.lineStyle.width,
lineDash: getLineDash(yAxis.splitLine.lineStyle.style)
}
}
}
@ -780,7 +781,7 @@ export function getAnalyseHorizontal(chart: Chart) {
return assistLine
}
function getLineDash(type) {
export function getLineDash(type) {
switch (type) {
case 'solid':
return [0, 0]

View File

@ -325,6 +325,18 @@ export function getStyle(chart: Chart): Style {
p[n.fieldId] = n
return p
}, {}) || {}
// 下钻字段使用入口字段的宽度
if (chart.drill) {
const { xAxis } = parseJson(chart)
const curDrillField = chart.drillFields[chart.drillFilters.length]
const drillEnterFieldIndex = xAxis.findIndex(
item => item.id === chart.drillFilters[0].fieldId
)
const drillEnterField = xAxis[drillEnterFieldIndex]
fieldMap[curDrillField.dataeaseName] = {
width: fieldMap[drillEnterField.dataeaseName]?.width
}
}
style.colCfg.width = node => {
const width = node.spreadsheet.container.cfg.el.offsetWidth
if (!basicStyle.tableFieldWidth?.length) {

View File

@ -79,7 +79,7 @@ const dvLayout = ref(null)
const canvasCenterRef = ref(null)
const state = reactive({
datasetTree: [],
scaleHistory: 100,
scaleHistory: null,
canvasId: 'canvas-main',
canvasInitStatus: false,
sourcePid: null,
@ -204,10 +204,10 @@ const doUseCache = flag => {
}
}
const initLocalCanvasData = () => {
const initLocalCanvasData = async () => {
const { opt, sourcePid, resourceId } = state
const busiFlg = opt === 'copy' ? 'dataV-copy' : 'dataV'
initCanvasData(resourceId, busiFlg, function () {
await initCanvasData(resourceId, busiFlg, function () {
state.canvasInitStatus = true
// afterInit
nextTick(() => {
@ -238,7 +238,9 @@ watch(
() => editMode.value,
val => {
if (val === 'edit') {
canvasStyleData.value.scale = state.scaleHistory
if (state.scaleHistory) {
canvasStyleData.value.scale = state.scaleHistory
}
initScroll()
} else {
previewScaleChange()
@ -288,7 +290,7 @@ onMounted(async () => {
if (canvasCache) {
canvasCacheOutRef.value?.dialogInit({ canvasType: 'dataV', resourceId: dvId })
} else {
initLocalCanvasData()
await initLocalCanvasData()
}
} else if (opt && opt === 'create') {
state.canvasInitStatus = false

View File

@ -347,7 +347,7 @@ defineExpose({
<el-tab-pane v-for="tab in tabList" :key="tab.name" :label="tab.label" :name="tab.name" />
</el-tabs>
<el-button
v-show="activeName === 'SUCCESS' && multipleSelection.length === 0"
v-if="activeName === 'SUCCESS' && multipleSelection.length === 0"
secondary
@click="downLoadAll"
>
@ -357,15 +357,15 @@ defineExpose({
{{ $t('data_export.download_all') }}
</el-button>
<el-button
v-show="activeName === 'SUCCESS' && multipleSelection.length !== 0"
v-if="activeName === 'SUCCESS' && multipleSelection.length !== 0"
secondary
@click="downLoadAll"
><template #icon> <Icon name="de-delete"></Icon> </template>{{ $t('data_export.download') }}
</el-button>
<el-button v-show="multipleSelection.length === 0" secondary @click="delAll"
<el-button v-if="multipleSelection.length === 0" secondary @click="delAll"
><template #icon> <Icon name="de-delete"></Icon> </template>{{ $t('data_export.del_all') }}
</el-button>
<el-button v-show="multipleSelection.length !== 0" secondary @click="delAll"
<el-button v-if="multipleSelection.length !== 0" secondary @click="delAll"
><template #icon> <Icon name="de-delete"></Icon> </template>{{ $t('commons.delete') }}
</el-button>
<div class="table-container" :class="!tableData.length && 'hidden-bottom'">

View File

@ -35,7 +35,9 @@ import type { TabPaneName } from 'element-plus-secondary'
import { timestampFormatDate } from './form/util'
import { interactiveStoreWithOut } from '@/store/modules/interactive'
import { XpackComponent } from '@/components/plugin'
import { useCache } from '@/hooks/web/useCache'
const interactiveStore = interactiveStoreWithOut()
const { wsCache } = useCache()
interface Field {
fieldShortName: string
name: string
@ -86,6 +88,7 @@ let originResourceTree = []
const sortTypeChange = sortType => {
state.datasetTree = treeSort(originResourceTree, sortType)
state.curSortType = sortType
wsCache.set('TreeSort-dataset', state.curSortType)
}
const resourceCreate = (pid, name) => {
@ -211,10 +214,12 @@ const getData = () => {
rootManage.value = nodeData[0]['weight'] >= 7
state.datasetTree = nodeData[0]['children'] || []
originResourceTree = cloneDeep(unref(state.datasetTree))
sortTypeChange(state.curSortType)
return
}
state.datasetTree = nodeData
originResourceTree = cloneDeep(unref(state.datasetTree))
sortTypeChange(state.curSortType)
})
.finally(() => {
dtLoading.value = false
@ -252,6 +257,7 @@ const dfsDatasetTree = (ds, id) => {
onBeforeMount(() => {
nodeInfo.id = (route.params.id as string) || ''
loadInit()
getData()
})
@ -471,6 +477,13 @@ const sortList = [
}
]
const loadInit = () => {
const historyTreeSort = wsCache.get('TreeSort-dataset')
if (historyTreeSort) {
state.curSortType = historyTreeSort
}
}
const sortTypeTip = computed(() => {
return sortList.find(ele => ele.value === state.curSortType).name
})

View File

@ -73,8 +73,8 @@ const selectDsType = (type: string) => {
currentDsType.value = type
activeStep.value = 1
activeApiStep.value = 1
detail.value.initForm(type)
nextTick(() => {
detail.value.initForm(type)
if (!dsTree.value) return
currentTypeList.value
.map(ele => ele.dbList)
@ -493,7 +493,9 @@ const init = (nodeInfo: Form | Param, id?: string, res?: object) => {
excel.value.appendReplaceExcel(res)
})
}
detail.value.clearForm()
nextTick(() => {
detail.value.clearForm()
})
})
}
}
@ -653,7 +655,7 @@ defineExpose({
:form="form"
:editDs="editDs"
:active-step="activeApiStep"
v-show="activeStep !== 0 && currentDsType && currentDsType !== 'Excel'"
v-if="activeStep !== 0 && currentDsType && currentDsType !== 'Excel' && visible"
></editor-detail>
<template v-if="activeStep !== 0 && currentDsType == 'Excel'">
<excel-detail :editDs="editDs" ref="excel" :param="form2"></excel-detail>

View File

@ -42,6 +42,7 @@ import { useMoveLine } from '@/hooks/web/useMoveLine'
import { cloneDeep } from 'lodash-es'
import { interactiveStoreWithOut } from '@/store/modules/interactive'
import treeSort from '@/utils/treeSortUtils'
import { useCache } from '@/hooks/web/useCache'
const route = useRoute()
const interactiveStore = interactiveStoreWithOut()
interface Field {
@ -51,7 +52,7 @@ interface Field {
originName: string
deType: number
}
const { wsCache } = useCache()
const { t } = useI18n()
const router = useRouter()
const appStore = useAppStoreWithOut()
@ -165,6 +166,7 @@ let originResourceTree = []
const sortTypeChange = sortType => {
state.datasourceTree = treeSort(originResourceTree, sortType)
state.curSortType = sortType
wsCache.set('TreeSort-datasource', state.curSortType)
}
const handleSizeChange = pageSize => {
state.paginationConfig.currentPage = 1
@ -391,10 +393,12 @@ const listDs = () => {
rootManage.value = nodeData[0]['weight'] >= 7
state.datasourceTree = nodeData[0]['children'] || []
originResourceTree = cloneDeep(unref(state.datasourceTree))
sortTypeChange(state.curSortType)
return
}
originResourceTree = cloneDeep(unref(state.datasourceTree))
state.datasourceTree = nodeData
sortTypeChange(state.curSortType)
})
.finally(() => {
mounted.value = true
@ -734,8 +738,17 @@ const defaultProps = {
children: 'children',
label: 'name'
}
const loadInit = () => {
const historyTreeSort = wsCache.get('TreeSort-datasource')
if (historyTreeSort) {
state.curSortType = historyTreeSort
}
}
onMounted(() => {
nodeInfo.id = (route.params.id as string) || ''
loadInit()
listDs()
const { opt } = router.currentRoute.value.query
if (opt && opt === 'create') {

@ -1 +1 @@
Subproject commit 448c319f8e519be5f4b47663258136bcb6fc3faa
Subproject commit e66bdc3a8d18a29287be512a7c929f1f1659cf0f