DdataeaseShufix: 样式优化
6b3f1a84创建于 4月17日历史提交
<template>
  <el-dialog
    v-loading="state.loading"
    ref="enlargeDialog"
    :append-to-body="true"
    :title="t('visualization.jump_set')"
    v-model="dialogShow"
    width="70vw"
    top="10vh"
    trigger="click"
  >
    <div @keydown.stop @keyup.stop v-if="state.initState" style="height: 550px">
      <el-row style="flex-direction: row">
        <div class="top-area">
          <span class="top-area-text">{{ t('visualization.selected_view') }}:</span>
          <span class="top-area-value">
            <Icon class-name="view-type-icon"
              ><component
                class="svg-icon view-type-icon"
                :is="iconChartMap[state.curJumpViewInfo.type]"
              ></component
            ></Icon>
            {{ state.curJumpViewInfo.title }}</span
          >
          <span class="top-area-text margin-left">{{ t('visualization.used_dataset') }}:</span>
          <span class="top-area-value">
            <Icon name="dataset-outline"
              ><datasetOutline style="vertical-align: -0.2em" class="svg-icon view-type-icon"
            /></Icon>
            {{ state.curDatasetInfo.name }}</span
          >
        </div>
      </el-row>
      <el-row v-loading="state.loading">
        <el-row class="preview">
          <el-col :span="8" style="height: 100%; overflow-y: auto">
            <el-row class="tree-head">
              <span class="head-text">{{ t('visualization.to_select_view') }}</span>
              <span class="head-filter">
                {{ t('visualization.show_selected_only') }}
                <el-switch size="small" v-model="state.showSelected" />
              </span>
            </el-row>
            <el-tree
              menu
              ref="linkJumpInfoTree"
              :filter-node-method="filterNodeMethod"
              :data="state.linkJumpInfoXArray"
              node-key="sourceFieldId"
              highlight-current
              :props="state.treeProp"
              @node-click="nodeClick"
            >
              <template #default="{ data }">
                <span class="custom-tree-node">
                  <span>
                    <div @click.stop>
                      <span class="auth-span">
                        <el-checkbox
                          v-model="data.checked"
                          @change="sourceFieldCheckedChange(data)"
                        />
                      </span>
                    </div>
                  </span>
                  <span :title="data.sourceFieldName">
                    <span class="tree-select-field">
                      <el-icon style="margin-right: 4px">
                        <Icon
                          ><component
                            class="svg-icon"
                            :class="`field-icon-${fieldType[data.sourceDeType]}`"
                            :is="iconFieldMap[fieldType[data.sourceDeType]]"
                          ></component
                        ></Icon>
                      </el-icon>
                      {{ data.sourceFieldName }}
                    </span>
                  </span>
                </span>
              </template>
            </el-tree>
          </el-col>
          <el-col :span="16" class="preview-show">
            <el-container class="settings-container">
              <el-header class="settings-header">
                <el-form-item class="radio-group-box">
                  <template #label>
                    <span class="title">{{ t('visualization.link_type') }}</span>
                  </template>
                  <el-radio-group
                    class="larger-radio"
                    v-if="state.linkJumpInfo"
                    v-model="state.linkJumpInfo.linkType"
                  >
                    <el-radio value="outer">{{ t('visualization.link_outer') }}</el-radio>
                    <el-radio value="inner">{{ t('visualization.dashboard_dataV') }}</el-radio>
                  </el-radio-group>
                  <el-radio-group class="larger-radio" v-if="!state.linkJumpInfo" disabled>
                    <el-radio value="outer">{{ t('visualization.link_outer') }}</el-radio>
                    <el-radio value="inner">{{ resourceType }}</el-radio>
                  </el-radio-group>
                </el-form-item>
                <el-form-item class="radio-group-box">
                  <template #label>
                    <span class="title">{{ t('visualization.open_model') }}</span>
                  </template>
                  <el-radio-group
                    class="larger-radio"
                    v-if="state.linkJumpInfo"
                    v-model="state.linkJumpInfo.jumpType"
                  >
                    <el-radio value="_self">{{ t('visualization.now_window') }}</el-radio>
                    <el-radio value="_blank">{{ t('visualization.new_window') }}</el-radio>
                    <el-radio value="newPop">{{ t('visualization.pop_window') }}</el-radio>
                  </el-radio-group>
                  <el-radio-group class="larger-radio" v-if="!state.linkJumpInfo" disabled>
                    <el-radio value="_self">{{ t('visualization.now_window') }}</el-radio>
                    <el-radio value="_blank">{{ t('visualization.new_window') }}</el-radio>
                    <el-radio value="newPop">{{ t('visualization.pop_window') }}</el-radio>
                  </el-radio-group>
                </el-form-item>

                <el-form-item
                  class="radio-group-box"
                  v-if="state.linkJumpInfo?.jumpType === 'newPop'"
                >
                  <template #label>
                    <span class="title">{{ t('visualization.window_size') }}</span>
                  </template>
                  <el-radio-group class="larger-radio" v-model="state.linkJumpInfo.windowSize">
                    <el-radio value="large">{{ t('visualization.window_size_large') }}</el-radio>
                    <el-radio value="middle">{{ t('visualization.window_size_middle') }}</el-radio>
                    <el-radio value="small">{{ t('visualization.window_size_small') }}</el-radio>
                  </el-radio-group>
                </el-form-item>
              </el-header>

              <el-main class="settings-main">
                <template v-if="state.linkJumpInfo">
                  <template v-if="state.linkJumpInfo.linkType === 'inner'">
                    <el-form label-position="top" class="main-form">
                      <div class="m-row">
                        <div style="flex: 1">
                          <el-form-item>
                            <template #label>
                              {{
                                dvInfo.type === 'dashboard'
                                  ? t('visualization.cur_dashboard')
                                  : t('visualization.cur_screen')
                              }}
                            </template>
                            <el-select style="width: 100%" v-model="dvInfo.name" disabled>
                              <el-option
                                :key="dvInfo.name"
                                :label="dvInfo.name"
                                :value="dvInfo.name"
                              >
                              </el-option>
                            </el-select>
                          </el-form-item>
                        </div>
                        <div class="icon-center">
                          <Icon name="dv-link-target"
                            ><dvLinkTarget style="width: 20px; height: 20px" class="svg-icon"
                          /></Icon>
                        </div>
                        <div style="flex: 1">
                          <el-form-item>
                            <template #label>
                              {{ targetSource }}
                            </template>
                            <el-tree-select
                              v-model="state.linkJumpInfo.targetDvId"
                              :data="state.panelList"
                              :props="state.dvSelectProps"
                              :render-after-expand="false"
                              filterable
                              @node-click="dvNodeClick"
                              class="dv-selector"
                            >
                              <template #default="{ node, data }">
                                <div class="label-content-details">
                                  <el-icon
                                    size="18px"
                                    style="display: inline-block"
                                    v-if="data.leaf"
                                  >
                                    <Icon name="dv-dashboard-spine"
                                      ><dvDashboardSpine
                                        v-if="data.type === 'dashboard'"
                                        class="svg-icon"
                                      />
                                      <dvScreenSpine v-else class="svg-icon"> </dvScreenSpine>
                                    </Icon>
                                  </el-icon>
                                  <el-icon size="18px" style="display: inline-block" v-else>
                                    <Icon name="dv-folder"><dvFolder class="svg-icon" /></Icon>
                                  </el-icon>
                                  <span
                                    style="margin-left: 8px; font-size: 14px"
                                    :title="node.label"
                                    >{{ node.label }}</span
                                  >
                                </div>
                              </template>
                            </el-tree-select>
                          </el-form-item>
                        </div>
                      </div>
                      <template v-if="state.linkJumpInfo.targetDvId">
                        <div class="jump-com-list">
                          <el-tabs size="small" v-model="state.activeCollapse">
                            <el-tab-pane
                              v-if="!isIndicator"
                              :label="t('visualization.linkage_view')"
                              name="view"
                            >
                            </el-tab-pane>
                            <el-tab-pane
                              :label="t('visualization.with_filter_params')"
                              name="filter"
                            >
                            </el-tab-pane>
                          </el-tabs>
                        </div>
                        <template v-if="state.activeCollapse === 'view'">
                          <el-row style="margin-bottom: 8px" :gutter="8">
                            <el-col :span="7"> {{ t('visualization.source_field') }} </el-col>
                            <el-col :span="2"></el-col>
                            <el-col :span="7" style="margin-left: -2.9%">
                              {{ t('visualization.link_view_field') }}
                            </el-col>
                            <el-col :span="8"></el-col>
                          </el-row>
                          <div
                            class="main-scrollbar-container"
                            :class="{
                              'main-scrollbar-container-min':
                                state.linkJumpInfo?.jumpType === 'newPop'
                            }"
                          >
                            <el-scrollbar
                              height="fit-content"
                              :max-height="
                                state.linkJumpInfo?.jumpType === 'newPop' ? '138px' : '178px'
                              "
                            >
                              <div
                                style="display: flex; margin-bottom: 6px"
                                v-for="(
                                  targetViewInfo, index
                                ) in state.linkJumpInfo.targetViewInfoList.filter(
                                  item => item.targetType === 'view'
                                )"
                                :key="index"
                              >
                                <div style="flex: 1">
                                  <el-select
                                    v-model="targetViewInfo.sourceFieldActiveId"
                                    :placeholder="t('chart.pls_select_field')"
                                    style="width: 100%"
                                  >
                                    <el-option
                                      v-for="curViewField in state.linkJumpCurViewFieldArray"
                                      :key="curViewField.id"
                                      :label="curViewField.name"
                                      :value="curViewField.id"
                                    >
                                      <span class="custom-option">
                                        <Icon
                                          ><component
                                            class="svg-icon"
                                            style="width: 14px; height: 14px"
                                            :class="`field-icon-${fieldType[curViewField.deType]}`"
                                            :is="iconFieldMap[fieldType[curViewField.deType]]"
                                          ></component
                                        ></Icon>
                                        <span
                                          style="float: left; margin-left: 4px; font-size: 14px"
                                          >{{ curViewField.name }}</span
                                        >
                                      </span>
                                    </el-option>
                                  </el-select>
                                </div>
                                <div class="icon-center">
                                  <Icon name="dv-link-target"
                                    ><dvLinkTarget
                                      style="width: 20px; height: 20px"
                                      class="svg-icon"
                                  /></Icon>
                                </div>
                                <div style="flex: 1">
                                  <el-select
                                    v-model="targetViewInfo.targetViewId"
                                    :disabled="!targetViewInfo.sourceFieldActiveId"
                                    :placeholder="t('visualization.select_view')"
                                    style="width: 100%"
                                    @change="viewInfoOnChange(targetViewInfo)"
                                  >
                                    <el-option
                                      v-for="item in state.currentLinkPanelViewArray.filter(
                                        item => item.type !== 'outerParams'
                                      )"
                                      :key="item.id"
                                      :label="item.title"
                                      :value="item.id"
                                    >
                                      <span class="custom-option">
                                        <Icon
                                          ><component
                                            class="svg-icon view-type-icon"
                                            style="width: 14px; height: 14px"
                                            :is="iconChartMap[item.type]"
                                          ></component
                                        ></Icon>
                                        <span
                                          style="float: left; margin-left: 4px; font-size: 14px"
                                          >{{ item.title }}</span
                                        >
                                      </span>
                                    </el-option>
                                  </el-select>
                                </div>
                                <div style="flex: 1; margin: 0 8px">
                                  <el-select
                                    v-model="targetViewInfo.targetFieldId"
                                    :placeholder="t('chart.pls_select_field')"
                                    :disabled="fieldIdDisabledCheck(targetViewInfo)"
                                    style="width: 100%"
                                  >
                                    <el-option
                                      v-for="viewField in state.viewIdFieldArrayMap[
                                        targetViewInfo.targetViewId
                                      ]"
                                      :key="viewField.id"
                                      :label="viewField.name"
                                      :value="viewField.id"
                                    >
                                      <span class="custom-option">
                                        <Icon
                                          ><component
                                            class="svg-icon"
                                            style="width: 14px; height: 14px"
                                            :class="`field-icon-${fieldType[viewField.deType]}`"
                                            :is="iconFieldMap[fieldType[viewField.deType]]"
                                          ></component
                                        ></Icon>
                                        <span
                                          style="float: left; margin-left: 4px; font-size: 14px"
                                          >{{ viewField.name }}</span
                                        >
                                      </span>
                                    </el-option>
                                  </el-select>
                                </div>

                                <el-button
                                  class="m-del-icon-btn"
                                  text
                                  @click="deleteLinkJumpFieldById(targetViewInfo.targetId)"
                                >
                                  <el-icon size="20px">
                                    <Icon name="icon_delete-trash_outlined"
                                      ><icon_deleteTrash_outlined class="svg-icon"
                                    /></Icon>
                                  </el-icon>
                                </el-button>
                              </div>
                            </el-scrollbar>
                            <el-button
                              style="margin-top: 8px"
                              :disabled="!state.linkJumpInfo.targetDvId"
                              type="primary"
                              icon="Plus"
                              text
                              @click="addLinkJumpField('view')"
                            >
                              {{ t('visualization.add_jump_field') }}
                            </el-button>
                          </div>
                        </template>
                        <template v-if="state.activeCollapse === 'filter'">
                          <template v-if="state.currentOutParams.length === 0">
                            <span
                              >{{ t('visualization.link_target_tips1')
                              }}<a
                                class="target_jump"
                                @click="resourceEdit(state.linkJumpInfo.targetDvId)"
                                >{{ t('visualization.link_target_tips2') }}</a
                              ></span
                            >
                          </template>
                          <template v-else-if="state.linkJumpCurFilterFieldArray.length === 0">
                            <span>{{ t('visualization.jump_no_banding_tips') }}</span>
                          </template>
                          <template v-else-if="state.currentOutParams.length > 0">
                            <el-row style="margin-bottom: 8px" :gutter="8">
                              <el-col :span="12"> {{ t('visualization.source_filter') }} </el-col>
                              <el-col :span="1"></el-col>
                              <el-col :span="10" style="margin-left: -2.9%">
                                {{ t('visualization.link_outer_params') }}
                              </el-col>
                            </el-row>
                            <div
                              class="main-scrollbar-container"
                              :class="{
                                'main-scrollbar-container-min':
                                  state.linkJumpInfo?.jumpType === 'newPop'
                              }"
                            >
                              <el-scrollbar height="fit-content" max-height="178px">
                                <div
                                  style="display: flex; margin-bottom: 6px"
                                  v-for="(
                                    targetViewInfo, index
                                  ) in state.linkJumpInfo.targetViewInfoList.filter(
                                    item => item.targetType === 'outerParams'
                                  )"
                                  :key="index"
                                >
                                  <div style="flex: 1">
                                    <el-select
                                      v-model="targetViewInfo.sourceFieldActiveId"
                                      :placeholder="t('chart.pls_select_field')"
                                      style="width: 100%"
                                    >
                                      <el-option
                                        v-for="curFilterField in state.linkJumpCurFilterFieldArray"
                                        :key="curFilterField.id"
                                        :label="curFilterField.name"
                                        :value="curFilterField.id"
                                      >
                                        <span class="custom-option">
                                          <Icon
                                            ><component
                                              class="svg-icon"
                                              style="width: 14px; height: 14px"
                                              :is="iconChartMap['filter']"
                                            ></component
                                          ></Icon>
                                          <span
                                            style="float: left; margin-left: 4px; font-size: 14px"
                                            >{{ curFilterField.name }}</span
                                          >
                                        </span>
                                      </el-option>
                                    </el-select>
                                  </div>
                                  <div class="icon-center">
                                    <Icon name="dv-link-target"
                                      ><dvLinkTarget
                                        style="width: 20px; height: 20px"
                                        class="svg-icon"
                                    /></Icon>
                                  </div>
                                  <div style="flex: 1">
                                    <el-select
                                      v-model="targetViewInfo.targetViewId"
                                      :disabled="!targetViewInfo.sourceFieldActiveId"
                                      :placeholder="t('visualization.select_param')"
                                      style="width: 100%"
                                      @change="viewInfoOnChange(targetViewInfo)"
                                    >
                                      <el-option
                                        v-for="item in state.currentOutParams"
                                        :key="item.id"
                                        :label="item.title"
                                        :value="item.id"
                                      >
                                        <span class="custom-option">
                                          <Icon
                                            ><component
                                              class="svg-icon view-type-icon"
                                              style="width: 14px; height: 14px"
                                              :is="iconChartMap[item.type]"
                                            ></component
                                          ></Icon>
                                          <span
                                            style="float: left; margin-left: 4px; font-size: 14px"
                                            >{{ item.title }}</span
                                          >
                                        </span>
                                      </el-option>
                                    </el-select>
                                  </div>

                                  <el-button
                                    class="m-del-icon-btn"
                                    text
                                    @click="deleteLinkJumpFieldById(targetViewInfo.targetId)"
                                  >
                                    <el-icon size="20px">
                                      <Icon name="icon_delete-trash_outlined"
                                        ><icon_deleteTrash_outlined class="svg-icon"
                                      /></Icon>
                                    </el-icon>
                                  </el-button>
                                </div>
                              </el-scrollbar>
                              <el-button
                                style="margin-top: 8px"
                                :disabled="!state.linkJumpInfo.targetDvId"
                                type="primary"
                                icon="Plus"
                                text
                                @click="addLinkJumpField('outerParams')"
                              >
                                {{ t('visualization.add_jump_field') }}
                              </el-button>
                            </div>
                          </template>
                        </template>
                      </template>
                      <template v-else>
                        <empty-background
                          style="height: auto"
                          :description="selectSourceTips"
                          img-type="noneWhite"
                        />
                      </template>
                    </el-form>
                  </template>

                  <template v-if="outerContentShow">
                    <el-row :gutter="8" class="main-form">
                      <el-col :span="16" style="height: 100%">
                        <div class="url-text">
                          {{ t('visualization.target_url') }}
                          <el-tooltip class="item" effect="dark" placement="bottom">
                            <template #content>
                              {{ $t('visualization.target_url_tips') }}
                            </template>
                            <el-icon size="16px" class="hint-icon">
                              <Icon name="icon_info_outlined"
                                ><icon_info_outlined class="svg-icon"
                              /></Icon>
                            </el-icon>
                          </el-tooltip>
                        </div>
                        <div class="outer-content-mirror">
                          <jump-set-outer-content-editor
                            ref="outerContentEditor"
                            :link-jump-info="state.linkJumpInfo"
                            :link-jump-info-array="state.linkJumpInfoArray"
                          />
                        </div>
                      </el-col>
                      <el-col :span="8" style="height: 100%">
                        <div class="url-text">
                          {{ t('visualization.select_world') }}
                          <el-tooltip class="item" effect="dark" placement="bottom">
                            <template #content>
                              <span v-html="$t('chart.reference_field_tip')"></span>
                            </template>
                            <el-icon size="16px" class="hint-icon">
                              <Icon name="icon_info_outlined"
                                ><icon_info_outlined class="svg-icon"
                              /></Icon>
                            </el-icon>
                          </el-tooltip>
                        </div>
                        <div class="outer-content-right">
                          <el-input
                            v-model="state.searchField"
                            :placeholder="t('dataset.search')"
                            :prefix-icon="Search"
                            clearable
                          />
                          <el-scrollbar style="margin-top: 12px" height="250px">
                            <span
                              v-for="item in state.linkJumpInfoArray.filter(
                                item =>
                                  !state.searchField ||
                                  item.sourceFieldName.indexOf(state.searchField) > -1
                              )"
                              :key="item.sourceFieldId"
                              class="item-dimension"
                              :title="item.sourceFieldName"
                              @click="insertFieldToCodeMirror('[' + item.sourceFieldName + ']')"
                            >
                              <el-icon>
                                <Icon
                                  ><component
                                    class="svg-icon"
                                    :class="`field-icon-${fieldType[item.sourceDeType]}`"
                                    :is="iconFieldMap[fieldType[item.sourceDeType]]"
                                  ></component
                                ></Icon>
                              </el-icon>
                              {{ item.sourceFieldName }}
                            </span>
                          </el-scrollbar>
                        </div>
                      </el-col>
                    </el-row>
                  </template>
                </template>
                <div v-else class="empty">
                  <empty-background
                    :description="t('visualization.select_dimension_hint')"
                    img-type="noneWhite"
                  />
                </div>
              </el-main>
            </el-container>
          </el-col>
        </el-row>
      </el-row>
      <el-row class="root-class">
        <el-button size="mini" @click="cancel()">{{ t('common.cancel') }} </el-button>
        <el-button type="primary" size="mini" @click="save()"
          >{{ t('dataset.confirm') }}
        </el-button>
      </el-row>
    </div>
    <XpackComponent
      ref="openHandler"
      jsname="L2NvbXBvbmVudC9lbWJlZGRlZC1pZnJhbWUvT3BlbkhhbmRsZXI="
    />
  </el-dialog>
</template>

<script lang="ts" setup>
import { iconFieldMap } from '@/components/icon-group/field-list'
import { iconChartMap } from '@/components/icon-group/chart-list'
import datasetOutline from '@/assets/svg/dataset-outline.svg'
import dvLinkTarget from '@/assets/svg/dv-link-target.svg'
import dvDashboardSpine from '@/assets/svg/dv-dashboard-spine.svg'
import dvFolder from '@/assets/svg/dv-folder.svg'
import icon_deleteTrash_outlined from '@/assets/svg/icon_delete-trash_outlined.svg'
import icon_info_outlined from '@/assets/svg/icon_info_outlined.svg'
import dvScreenSpine from '@/assets/svg/dv-screen-spine.svg'
import {
  queryVisualizationJumpInfo,
  queryWithViewId,
  updateJumpSet,
  viewTableDetailList
} from '@/api/visualization/linkJump'
import { reactive, ref, nextTick, computed, watch } from 'vue'
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
import { fieldType } from '@/utils/attr'
import { storeToRefs } from 'pinia'
import { findDvType, queryTreeApi } from '@/api/visualization/dataVisualization'
import { ElMessage, ElScrollbar } from 'element-plus-secondary'
import { useI18n } from '@/hooks/web/useI18n'
import { getDatasetDetails, listFieldByDatasetGroup } from '@/api/dataset'
import { BusiTreeRequest } from '@/models/tree/TreeNode'
import JumpSetOuterContentEditor from '@/components/visualization/JumpSetOuterContentEditor.vue'
import { Search } from '@element-plus/icons-vue'
import { snapshotStoreWithOut } from '@/store/modules/data-visualization/snapshot'
import EmptyBackground from '@/components/empty-background/src/EmptyBackground.vue'
import { filterEmptyFolderTree } from '@/utils/canvasUtils'
import { useEmitt } from '@/hooks/web/useEmitt'
import { useAppStoreWithOut } from '@/store/modules/app'
import { XpackComponent } from '@/components/plugin'
import { useCache } from '@/hooks/web/useCache'
import { useEmbedded } from '@/store/modules/embedded'
import { guid } from '@/views/visualized/data/dataset/form/util'
import treeSort from '@/utils/treeSortUtils'
const dvMainStore = dvMainStoreWithOut()
const { dvInfo, canvasViewInfo, componentData } = storeToRefs(dvMainStore)
const linkJumpInfoTree = ref(null)
const { t } = useI18n()
const dialogShow = ref(false)
const snapshotStore = snapshotStoreWithOut()
const appStore = useAppStoreWithOut()
const embeddedStore = useEmbedded()

const resourceType = computed(() =>
  dvInfo.value.type === 'dashboard' ? t('work_branch.dashboard') : t('work_branch.big_data_screen')
)

const selectSourceTips = t('visualization.select_target_resource')

const targetSource = t('visualization.target_dashboard_dataV')

const state = reactive({
  curDataVWeight: 0,
  activeCollapse: 'view',
  loading: false,
  showSelected: false,
  curJumpViewInfo: {},
  curDatasetInfo: {},
  tempId: null,
  initState: false,
  viewId: null,
  viewType: null,
  name2Auto: [],
  searchField: '',
  searchFunction: '',
  inputType: 'self',
  fieldName: 'name',
  tableRadio: null,
  keyWordSearch: '',
  columnLabel: t('visualization.belong_to_category'),
  templateList: [],
  importTemplateInfo: {
    snapshot: ''
  },
  sourceViewFields: [],
  dvSelectProps: {
    label: 'name',
    children: 'children',
    value: 'id',
    isLeaf: 'leaf',
    disabled: 'disabled'
  },
  treeProp: {
    id: 'sourceFieldId',
    label: 'sourceFieldName',
    children: 'children'
  },
  linkJump: null,
  linkJumpInfoArray: [],
  linkJumpInfoXArray: [],
  linkJumpCurViewFieldArray: [],
  linkJumpCurFilterFieldArray: [], //当前过滤条件明细
  mapJumpInfoArray: {},
  panelList: [],
  linkJumpInfo: null,
  currentFiledTreeNode: null,
  defaultLinkJumpInfo: {
    linkType: 'outer',
    jumpType: '_self',
    targetViewInfoList: []
  },
  defaultTargetViewInfo: {
    targetViewId: null,
    targetFieldId: null
  },
  currentLinkPanelViewArray: [],
  viewIdFieldArrayMap: {},
  dimensionData: [],
  dimensionList: [],
  quotaList: [],
  quotaData: [],
  dimension: [],
  quota: [],
  currentOutParams: []
})
const { wsCache } = useCache()

const outerContentEditor = ref(null)

const resetParams = () => {
  state.linkJump = null
  state.linkJumpInfoArray = []
  state.linkJumpInfoXArray = []
  state.linkJumpCurViewFieldArray = []
  state.linkJumpCurFilterFieldArray = []
  state.mapJumpInfoArray = {}
  state.linkJumpInfo = null
}

const dialogInit = viewItem => {
  resetParams()
  state.showSelected = false
  dialogShow.value = true
  state.initState = false
  init(viewItem)
}

const initCurFilterFieldArray = componentDataCheck => {
  componentDataCheck.forEach(componentItem => {
    if (componentItem.component === 'VQuery' && componentItem.propValue instanceof Array) {
      componentItem.propValue.forEach(filterItem => {
        if (filterItem.checkedFields.includes(state.viewId)) {
          state.linkJumpCurFilterFieldArray.push({
            id: filterItem.id,
            name: filterItem.name,
            deType: 'filter'
          })
        }
      })
    } else if (componentItem.component === 'Group') {
      initCurFilterFieldArray(componentItem.propValue)
    } else if (componentItem.component === 'DeTabs') {
      componentItem.propValue.forEach(tabItem => {
        initCurFilterFieldArray(tabItem.componentData)
      })
    }
  })
}

const isIndicator = computed(() => 'indicator' === state.viewType)

const init = viewItem => {
  state.initState = false
  state.viewId = viewItem.id
  state.viewType = viewItem.type
  state.activeCollapse = isIndicator.value ? 'filter' : 'view'
  const chartDetails = canvasViewInfo.value[state.viewId] as ChartObj
  state.curJumpViewInfo = chartDetails
  let checkAllAxisStr =
    JSON.stringify(chartDetails.xAxis) +
    JSON.stringify(chartDetails.xAxisExt) +
    JSON.stringify(chartDetails.drillFields)
  let checkJumpStr
  // 堆叠图的可选参数分两种情况 1.如果有堆叠项 则指标只有第一个可选 2.如果没有堆叠项泽所有指标都可以选
  if (chartDetails.type.indexOf('stack') > -1 && chartDetails.extStack.length > 2) {
    const yAxisArray = chartDetails.yAxis
    const yAxisNew = yAxisArray.length > 0 ? JSON.stringify(yAxisArray[0]) : '[]'
    checkAllAxisStr =
      JSON.stringify(chartDetails.xAxis) +
      JSON.stringify(chartDetails.xAxisExt) +
      JSON.stringify(yAxisNew) +
      JSON.stringify(chartDetails.yAxisExt) +
      JSON.stringify(chartDetails.drillFields)
    checkJumpStr = checkAllAxisStr
  } else if (
    ['table-normal', 'table-info', 'table-pivot', 'indicator'].includes(chartDetails.type)
  ) {
    checkJumpStr =
      checkAllAxisStr + JSON.stringify(chartDetails.yAxis) + JSON.stringify(chartDetails.yAxisExt)
  } else if (chartDetails.type === 'multi-scatter') {
    // 多维散点图跳转字段只列出维度,引用字段可选所有轴字段
    const multiScatterExtra =
      JSON.stringify(chartDetails.yAxis || []) +
      JSON.stringify(chartDetails.extColor || []) +
      JSON.stringify(chartDetails.extBubble || []) +
      JSON.stringify(chartDetails.yAxisExt || [])
    checkAllAxisStr = checkAllAxisStr + multiScatterExtra
    checkJumpStr = JSON.stringify(chartDetails.extColor || [])
  } else {
    checkJumpStr = checkAllAxisStr
  }
  const request = { busiFlag: 'dashboard-dataV' } as BusiTreeRequest
  // 获取可关联的仪表板
  queryTreeApi(request).then(rsp => {
    if (rsp && rsp[0]?.id === '0') {
      state.panelList = rsp[0].children
    } else {
      state.panelList = rsp
    }
    state.panelList = filterEmptyFolderTree(state.panelList)
    const curSortType = wsCache.get(`TreeSort-${dvInfo.value.type}`) || 'time_asc'
    state.panelList = treeSort(state.panelList, curSortType)
  })

  // 获取当前过滤条件明细 过滤原则:1.在当前仪表板或者大屏 2.作用于当前图表
  state.linkJumpCurFilterFieldArray = []
  initCurFilterFieldArray(componentData.value)

  if (chartDetails.tableId) {
    // 获取当前数据集信息
    getDatasetDetails(chartDetails.tableId).then(res => {
      state.curDatasetInfo = res || {}
    })
    // 获取当前图表的字段信息
    listFieldByDatasetGroup(chartDetails.tableId).then(rsp => {
      state.linkJumpCurViewFieldArray = []
      const sourceCurViewFieldArray = rsp.data
      sourceCurViewFieldArray.forEach(fieldItem => {
        if (checkAllAxisStr.indexOf(fieldItem.id) > -1) {
          state.linkJumpCurViewFieldArray.push(fieldItem)
        }
      })
    })

    // 获取当前图表的关联信息
    queryWithViewId(dvInfo.value.id, state.viewId).then(rsp => {
      state.linkJump = rsp.data
      state.linkJumpInfoArray = []
      state.linkJumpInfoXArray = []
      state.linkJump.linkJumpInfoArray.forEach(linkJumpInfo => {
        if (checkJumpStr.indexOf(linkJumpInfo.sourceFieldId) > -1) {
          state.mapJumpInfoArray[linkJumpInfo.sourceFieldId] = linkJumpInfo
          state.linkJumpInfoArray.push(linkJumpInfo)
          state.linkJumpInfoXArray.push(linkJumpInfo)
        } else if (checkAllAxisStr.indexOf(linkJumpInfo.sourceFieldId) > -1) {
          state.linkJumpInfoArray.push(linkJumpInfo)
        }
      })
      const firstNode = state.linkJumpInfoArray[0]
      state.initState = true
      nextTick(() => {
        linkJumpInfoTree.value.setCurrentKey(firstNode?.sourceFieldId)
        nodeClick(firstNode)
      })
    })
  }
}

const save = () => {
  // 字段检查
  let subCheckCountAll = 0
  state.linkJump.linkJumpInfoArray.forEach(linkJumpInfo => {
    if (linkJumpInfo.checked) {
      let subCheckCount = 0
      if (linkJumpInfo.linkType === 'inner') {
        if (!linkJumpInfo.targetDvId) {
          subCheckCount++
          subCheckCountAll++
        }
        linkJumpInfo.targetViewInfoList &&
          linkJumpInfo.targetViewInfoList.forEach(function (link) {
            if (!(link.sourceFieldActiveId && link.targetFieldId && link.targetViewId)) {
              subCheckCount++
              subCheckCountAll++
            }
          })
      }
      if (linkJumpInfo.linkType === 'outer') {
        if (!linkJumpInfo.content) {
          subCheckCount++
          subCheckCountAll++
        }
      }
      if (subCheckCount > 0) {
        ElMessage.error(t('visualization.jump_null_tips', [linkJumpInfo.sourceFieldName]))
      }
    }
  })
  if (subCheckCountAll) {
    return
  }
  state.loading = true
  updateJumpSet(state.linkJump)
    .then(() => {
      snapshotStore.recordSnapshotCache('updateJumpSet')
      ElMessage.success(t('common.save_success'))
      // 刷新跳转信息
      queryVisualizationJumpInfo(dvInfo.value.id).then(rsp => {
        dvMainStore.setNowPanelJumpInfo(rsp.data)
        cancel()
      })
      state.loading = false
    })
    .catch(() => {
      state.loading = false
    })
}
const nodeClick = data => {
  if (!data) {
    return
  }
  state.linkJumpInfo = state.mapJumpInfoArray[data.sourceFieldId]
  if (!state.linkJumpInfo.windowSize) {
    state.linkJumpInfo.windowSize = 'middle'
  }
  if (!state.linkJumpInfo.linkType) {
    state.linkJumpInfo.linkType = 'outer'
  }
  if (!state.linkJumpInfo.jumpType) {
    state.linkJumpInfo.jumpType = '_blank'
  }
  if (!state.linkJumpInfo.content) {
    state.linkJumpInfo.content = 'http://'
  }
  if (!state.linkJumpInfo.attachParams) {
    state.linkJumpInfo.attachParams = false
  }
  if (state.linkJumpInfo.targetDvId) {
    getPanelViewList(state.linkJumpInfo.targetDvId)
  }
  codeMirrorContentSet(state.linkJumpInfo.content)
}

const codeMirrorContentSet = content => {
  nextTick(() => {
    outerContentEditor.value?.editorInit(content)
  })
}

// 获取当前图表字段 关联仪表板的图表信息列表
const getPanelViewList = dvId => {
  viewTableDetailList(dvId).then(rsp => {
    state.viewIdFieldArrayMap = {}
    state.currentLinkPanelViewArray = rsp.data.visualizationViewTables
    if (state.currentLinkPanelViewArray) {
      state.currentLinkPanelViewArray.forEach(view => {
        state.viewIdFieldArrayMap[view.id] = view.tableFields
      })
    }
    // 外部参数 currentLinkPanelViewArray 也加入
    // 在图表侧进行隐藏 保存的时候直接保存currentLinkPanelViewArray 方便处理
    state.currentOutParams = rsp.data.outParamsJumpInfo || []
    if (state.currentOutParams && state.currentOutParams.length > 0) {
      state.currentOutParams.forEach(outerParamsItem => {
        state.currentLinkPanelViewArray.push(outerParamsItem)
        state.viewIdFieldArrayMap[outerParamsItem.id] = [
          { id: '1000001', name: t('visualization.out_params_no_select') }
        ]
      })
    }
    // 增加过滤组件匹配
    JSON.parse(rsp.data.bashComponentData).forEach(componentItem => {
      if (componentItem.component === 'VQuery' && componentItem.propValue instanceof Array) {
        componentItem.propValue.forEach(filterItem => {
          state.currentLinkPanelViewArray.push({
            id: filterItem.id,
            type: 'filter',
            name: filterItem.name,
            title: filterItem.name
          })
          state.viewIdFieldArrayMap[filterItem.id] = [
            { id: '1000001', name: t('visualization.filter_no_select') }
          ]
        })
      }
    })
  })
}

const dvNodeClick = data => {
  if (data.leaf) {
    state.curDataVWeight = data.weight
    state.linkJumpInfo.targetViewInfoList = []
    if (!isIndicator.value) {
      addLinkJumpField()
    }
    getPanelViewList(data.id)
  }
}
const addLinkJumpField = (type = 'view') => {
  state.linkJumpInfo.targetViewInfoList.push({
    targetId: guid(),
    targetViewId: '',
    targetType: type,
    targetFieldId: ''
  })
}

const deleteLinkJumpFieldById = targetId => {
  if (targetId) {
    let indexResult
    state.linkJumpInfo.targetViewInfoList.forEach((item, index) => {
      if (targetId === item.targetId) {
        indexResult = index
      }
    })
    if (indexResult !== undefined) {
      state.linkJumpInfo.targetViewInfoList.splice(indexResult, 1)
    }
  }
}

const fieldIdDisabledCheck = targetViewInfo => {
  return (
    (state.viewIdFieldArrayMap[targetViewInfo.targetViewId] &&
      state.viewIdFieldArrayMap[targetViewInfo.targetViewId].length === 1 &&
      state.viewIdFieldArrayMap[targetViewInfo.targetViewId][0].id === '1000001') ||
    !targetViewInfo.sourceFieldActiveId
  )
}

const viewInfoOnChange = targetViewInfo => {
  if (
    state.viewIdFieldArrayMap[targetViewInfo.targetViewId] &&
    state.viewIdFieldArrayMap[targetViewInfo.targetViewId].length === 1 &&
    state.viewIdFieldArrayMap[targetViewInfo.targetViewId][0].id === '1000001'
  ) {
    targetViewInfo.targetFieldId = '1000001'
  } else {
    targetViewInfo.targetFieldId = null
  }
}
const sourceFieldCheckedChange = data => {
  nextTick(() => {
    linkJumpInfoTree.value.setCurrentKey(data.sourceFieldId)
    nodeClick(data)
  })
}
const cancel = () => {
  dialogShow.value = false
  state.initState = false
}

const insertFieldToCodeMirror = (value: string) => {
  outerContentEditor.value.insertFieldToCodeMirror(value)
}

const outerContentShow = computed(() => {
  return state.linkJumpInfo && state.linkJumpInfo.linkType === 'outer' && dialogShow.value
})

const filterNodeMethod = (value, data) => {
  return !value || data.checked
}

const isEmbedded = computed(() => appStore.getIsDataEaseBi || appStore.getIsIframe)
const openType = '_blank'

const resourceEdit = async resourceId => {
  if (state.curDataVWeight && state.curDataVWeight < 7) {
    ElMessage.error(t('visualization.no_edit_auth'))
    return
  }
  let busiFlagResult
  await findDvType(resourceId).then(res => {
    busiFlagResult = res.data
  })
  const baseUrl = busiFlagResult === 'dataV' ? '#/dvCanvas?dvId=' : '#/dashboard?resourceId='
  if (isEmbedded.value) {
    embeddedStore.clearState()
    if (dvInfo.value.type === 'dataV') {
      embeddedStore.setDvId(resourceId)
    } else {
      embeddedStore.setResourceId(resourceId)
    }
    useEmitt().emitter.emit(
      'changeCurrentComponent',
      dvInfo.value.type === 'dataV' ? 'VisualizationEditor' : 'DashboardEditor'
    )
    return
  }
  const newWindow = window.open(baseUrl + resourceId, openType)
  initOpenHandler(newWindow)
}

const openHandler = ref(null)
const initOpenHandler = newWindow => {
  if (openHandler?.value) {
    const pm = {
      methodName: 'initOpenHandler',
      args: newWindow
    }
    openHandler.value.invokeMethod(pm)
  }
}

watch(
  () => state.showSelected,
  newValue => {
    linkJumpInfoTree.value?.filter(newValue)
  }
)

watch(
  () => outerContentShow.value,
  newValue => {
    if (newValue) {
      codeMirrorContentSet(state.linkJumpInfo.content)
    }
  }
)

defineExpose({
  dialogInit
})
</script>

<style scoped lang="less">
.root-class {
  margin: 15px 0px 5px;
  justify-content: right;
}

.preview {
  margin-top: 5px;
  border: 1px solid #e6e6e6;
  border-radius: 6px;
  height: 470px !important;
  overflow: hidden;
  background-size: 100% 100% !important;
}

.preview-show {
  border-left: 1px solid #e6e6e6;
  height: 470px;
  background-size: 100% 100% !important;
}

.top_border {
  border-top: 1px solid #e6e6e6;
}

.slot-class {
  color: white;
}

.bottom {
  margin-top: 10px;
  justify-content: center;
}

.ellip {
  margin-left: 10px;
  margin-right: 10px;
  overflow: hidden; /*超出部分隐藏*/
  white-space: nowrap; /*不换行*/
  text-overflow: ellipsis; /*超出部分文字以...显示*/
  text-align: center;
  background-color: #f7f8fa;
  color: #3d4d66;
  font-size: 12px;
  line-height: 24px;
  height: 24px;
  border-radius: 3px;
}

.select-filed {
  margin-right: 8px;
  overflow: hidden; /*超出部分隐藏*/
  white-space: nowrap; /*不换行*/
  text-overflow: ellipsis; /*超出部分文字以...显示*/
  color: #3d4d66;
  font-size: 12px;
  line-height: 35px;
  height: 35px;
  border-radius: 3px;
}

.custom-position {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 14px;
  flex-flow: row nowrap;
  color: #9ea6b2;
}

.tree-style {
  padding: 10px 15px;
  height: 100%;
  overflow-y: auto;
}

.custom-tree-node {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 14px;
}

.auth-span {
  float: left;
  width: 30px;
  margin-left: -8px;
}

.tree-head {
  height: 40px;
  line-height: 40px;
  font-size: 12px;
  color: #3d4d66;
  .head-text {
    margin-left: 16px;
    font-weight: 500;
    font-size: 14px;
    color: #1f2329;
  }
  .head-filter {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: end;
    margin-right: 16px;
    font-weight: 400;
    font-size: 12px;
    color: #646a73;
    .ed-switch {
      margin-left: 8px;
    }
  }
}

.padding-lr {
  padding: 0 4px;
}

.field-height {
  height: calc(100% - 25px);
  margin-top: 12px;
}

.drag-list {
  height: calc(100% - 26px);
  overflow: auto;
}

.item-dimension {
  display: flex;
  height: 28px;
  padding: 1px 8px;
  align-items: center;
  gap: 4px;
  flex-shrink: 0;

  word-break: break-all;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;

  border-radius: 6px;
  border: 1px solid #dee0e3;

  background: #fff;

  color: var(--neutral-900, #1f2329);
  /* 中文/桌面端/正文 14 22 Regular */
  font-family: var(--de-custom_font, 'PingFang');
  font-size: 14px;
  font-style: normal;
  font-weight: 400;
  line-height: 22px;

  cursor: pointer;
}

.item-dimension + .item-dimension {
  margin-top: 4px;
}

.item-dimension:hover {
  border: 1px solid var(--ed-color-primary, #3370ff);
  background: var(--ed-color-primary-1a, rgba(51, 112, 255, 0.1));
}

.item-quota {
  padding: 2px 10px;
  margin: 2px 2px 0 2px;
  border: solid 1px #eee;
  text-align: left;
  color: #606266;
  background-color: white;
  display: block;
  word-break: break-all;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.item-quota + .item-quota {
  margin-top: 2px;
}

.item-quota:hover {
  color: #67c23a;
  background: #f0f9eb;
  border-color: #b2d3a3;
  cursor: pointer;
}

.blackTheme .item-quota:hover {
}

span {
  font-size: 12px;
}

.set-name-area {
  font-weight: 600;
  margin-right: 20px;
}

:deep(.ed-row) {
  width: 100%;
}

.dv-selector {
  width: 100%;
}

.top-area {
  float: left;
  line-height: 33px;
  display: flex;
  flex-direction: row;
  align-items: center;
}

.top-area-text {
  font-weight: 400;
  font-size: 14px;
  color: #646a73;

  &.margin-left {
    margin-left: 24px;
  }
}
.settings-container {
  height: 100%;

  .settings-header {
    height: auto;
    border-bottom: 1px solid #e6e6e6;

    .radio-group-box {
      margin-top: 8px;
      margin-bottom: 8px;

      .title {
        color: #646a73;
        font-size: 14px;
        font-style: normal;
        font-weight: 400;
      }

      :deep(.ed-radio__label) {
        color: #1f2329;
        font-size: 14px;
        font-style: normal;
        font-weight: 400;
      }
    }
  }

  .settings-main {
    padding: 16px;
    overflow: hidden;
    .empty {
      width: 100%;
      height: 100%;
      display: flex;
      flex-direction: row;
      justify-content: center;
      align-items: center;
    }
    .main-form {
      height: 100%;
      width: 100%;

      .m-row {
        width: 100%;
        display: flex;
      }

      .icon-center {
        padding: 0 8px;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
      }

      .main-scrollbar-container {
        height: calc(100% - 132px);

        :deep(.ed-scrollbar) {
          height: fit-content;
          max-height: 208px;
        }
      }
    }
  }
}

.main-scrollbar-container-min {
  :deep(.ed-scrollbar) {
    height: fit-content;
    max-height: 138px !important;
  }
}

.top-area-value {
  font-weight: 400;
  font-size: 14px;
  color: #1f2329;
  display: flex;
  flex-direction: row;
  align-items: center;
}
.view-type-icon {
  color: var(--ed-color-primary);
  width: 22px;
  height: 16px;
}
.content-head {
  height: 30px;
  margin-top: 10px;
  .content-head-text {
    margin-left: 16px;
    font-weight: 400;
    font-size: 14px;
    color: #646a73;
    line-height: 32px;
    margin-right: 16px;
  }
}
.link-icon-area {
  text-align: center;
  line-height: 35px;
}
.inner-content {
  width: 100%;
  padding: 16px 16px 8px 16px;
  font-size: 14px !important;
}

.outer-content {
  height: 340px;
  border-radius: 6px;
}

.padding-lr {
  height: 500px;
  border: 1px solid var(--deCardStrokeColor, #dee0e3);
  border-radius: 6px;
  padding: 12px;
  box-sizing: border-box;
  margin-left: 12px;
  width: 214px;
  overflow-y: hidden;
}

.mb8 {
  margin-bottom: 8px;
  display: inline-flex;
  align-items: center;

  i {
    margin-left: 4.67px;
  }
}

.field-height {
  height: calc(50% - 41px);
  margin-top: 4px;
  overflow-y: auto;
}

.class-na {
  margin-top: 8px;
  text-align: center;
  font-size: 14px;
  color: var(--deTextDisable);
}
.outer-content-mirror {
  border: 1px solid #d9dcdf;
  border-radius: 6px;
  height: calc(100% - 30px);
  width: 100%;
  overflow: hidden;
}
.url-text {
  width: 100%;
  line-height: 22px;
  margin-bottom: 8px;
  font-size: 14px;
  font-style: normal;
  font-weight: 400;
  color: #1f2329;
  display: flex;
  align-items: center;
}

.outer-content-right {
  border: 1px solid #d9dcdf;
  border-radius: 6px;
  height: calc(100% - 30px);
  width: 100%;
  padding: 12px;
}

.tree-select-field {
  font-size: 14px;
  display: flex;
  align-items: center;
  overflow: hidden;
}

.label-content-details {
  width: 100%;
  display: flex;
  align-items: center;
}
.hint-icon {
  margin-left: 4px;
  cursor: pointer;
  color: #646a73;
}
.m-del-icon-btn {
  color: #646a73;
  margin-top: 2px;
  margin-left: -4px;

  &:hover {
    background: rgba(31, 35, 41, 0.1) !important;
  }
  &:focus {
    background: rgba(31, 35, 41, 0.1) !important;
  }
  &:active {
    background: rgba(31, 35, 41, 0.2) !important;
  }
}
.larger-radio {
  .ed-radio__inner {
    width: 16px;
    height: 16px;
  }
}

.custom-option {
  font-size: 14px;
  display: flex;
  align-items: center;
}

.jump-com-list {
  width: 100%;
  margin-top: -18px;
  :deep(.ed-collapse) {
    --ed-collapse-header-font-size: 14px;
    --ed-collapse-content-font-size: 14px;
  }
  :deep(.ed-tabs__active-bar) {
    height: 2px;
  }

  & > :deep(.ed-tabs) {
    --ed-tabs-header-height: 36px;
    margin-bottom: 12px;
    position: sticky;
    background: #fff;
    .ed-tabs__header {
      &::before {
        content: '';
        width: 8px;
        height: 1px;
        position: absolute;
        bottom: 0;
        left: 0;
        background: #1f232926;
      }
    }
  }

  :deep(.ed-tabs__item) {
    font-size: 14px;
  }

  :deep(.ed-tabs__item):not(.is-active) {
    color: #646a73;
  }
}

.target_jump {
  color: var(--ed-color-primary);
  cursor: pointer;
}
</style>