riku
2025-05-14 a96e571b174fa30697f3aa6fdb22b3cf93d21b71
src/views/underwaymix/component/GridStyleTool.vue
@@ -9,91 +9,142 @@
        ></CardButton>
      </el-row>
    </el-col>
    <el-col span="2">
      <BaseCard v-show="show" direction="right" borderless="r">
        <template #content>
          <el-scrollbar class="content-wrap">
            <div v-for="(g, i) in gridCtrlList" :key="i">
              {{ g.name }}
              <div v-for="(value, t) in g.views" :key="t">
                <span v-if="value.extData.type == 0">{{ value.tag + '.' }}</span>
                {{ value.extData.name }}
                <!-- {{ key }} -->
                <!-- <el-text>{{ g.name }}</el-text> -->
                <!-- <div class="m-t-8">网格要素</div> -->
                <el-row class="m-t-8" justify="space-between">
                  <CheckButton
                    active-text="显示网格"
                    inactive-text="隐藏网格"
                    :default-value="true"
                    @change="(e) => handleGridClick(e, i, value)"
            <el-tabs
              class="grid-ctrl-card"
              v-model="activeGridCtrl"
              type="border-card"
            >
              <el-tab-pane
                v-for="(g, i) in gridCtrlList"
                :key="g.name"
                :label="g.name"
                :name="i"
              >
                <el-tabs v-model="activeGrid">
                  <el-tab-pane
                    v-for="(grid, y) in g.views"
                    :key="y"
                    :label="grid.name"
                    :name="y"
                  >
                  </CheckButton>
                  <CheckButton
                    active-text="显示排名"
                    inactive-text="隐藏排名"
                    :default-value="false"
                    @change="(e) => handleRankClick(e, i, value)"
                  >
                  </CheckButton>
                  <CheckButton
                    active-text="显示数据"
                    inactive-text="隐藏数据"
                    :default-value="false"
                    @change="(e) => handleDataClick(e, i, value)"
                  >
                  </CheckButton>
                </el-row>
                <el-row class="m-t-8" justify="space-between">
                  <CheckButton
                    active-text="绘制对比色"
                    inactive-text="绘制标准色"
                    :default-value="false"
                    @change="(e) => handleColorClick(e, i, value)"
                  >
                  </CheckButton>
                  <CheckButton
                    v-if="value.extData.type == 0"
                    active-text="显示走航轨迹"
                    inactive-text="隐藏走航轨迹"
                    :default-value="false"
                    @change="(e) => handleUnderwayClick(e, i, value)"
                  >
                  </CheckButton>
                  <CheckButton
                    v-if="value.extData.type == 1"
                    active-text="高亮融合网格"
                    :default-value="true"
                    @change="(e) => handleHighlightGridClick(e, i, value)"
                  >
                  </CheckButton>
                </el-row>
                <!-- <el-row class="m-b-8" align="middle"> -->
                <el-form-item label="透明度">
                  <!-- <div class="m-t-8">网格透明度</div> -->
                  <el-slider
                    v-model="value.opacityValue"
                    :min="0"
                    :max="1"
                    :step="0.1"
                    show-stops
                    @change="(e) => handleOpacityChange(e, i, value)"
                    style="width: 150px"
                  />
                  <el-input-number
                    class="m-l-16"
                    size="small"
                    v-model="value.opacityValue"
                    :min="0"
                    :max="1"
                    :step="0.1"
                    @change="(e) => handleOpacityChange(e, i, value)"
                  />
                </el-form-item>
                <!-- </el-row> -->
                <el-divider />
              </div>
            </div>
                    <div v-for="(value, t) in grid.views" :key="t">
                      <el-row justify="space-between" align="middle">
                        <div>
                          <span v-if="value.type == 0">{{
                            value.tag + '.'
                          }}</span>
                          {{ value.name }}
                        </div>
                        <el-button
                          class="el-button-custom"
                          type="primary"
                          icon="Close"
                          circle
                          size="small"
                          @click="handleCloseClick(i, y, t, value)"
                        />
                      </el-row>
                      <el-row class="m-t-8" justify="space-between">
                        <CheckButton
                          :loading="gridLoading"
                          v-model="value.showGrid"
                          active-text="显示网格"
                          inactive-text="隐藏网格"
                          @change="(e) => handleGridClick(e, i, value)"
                        >
                        </CheckButton>
                        <CheckButton
                          :loading="rankLoading"
                          v-if="value.type != 2"
                          v-model="value.showRank"
                          active-text="显示排名"
                          inactive-text="隐藏排名"
                          :default-value="false"
                          @change="(e) => handleRankClick(e, i, value)"
                        >
                        </CheckButton>
                        <CheckButton
                          :loading="dataLoading"
                          v-model="value.showData"
                          active-text="显示数据"
                          inactive-text="隐藏数据"
                          :default-value="false"
                          @change="(e) => handleDataClick(e, i, value)"
                        >
                        </CheckButton>
                      </el-row>
                      <el-row class="m-t-8" justify="space-between">
                        <CheckButton
                          :loading="colorLoading"
                          v-model="value.showGridCustomColor"
                          active-text="绘制对比色"
                          inactive-text="绘制标准色"
                          :default-value="false"
                          @change="(e) => handleColorClick(e, i, value)"
                        >
                        </CheckButton>
                        <CheckButton
                          :loading="heatMapLoading"
                          v-if="value.type != 2"
                          v-model="value.showHeatMap"
                          active-text="风险热力图"
                          inactive-text="风险热力图"
                          :default-value="false"
                          @change="(e) => handleHeatMapClick(e, i, value)"
                        >
                        </CheckButton>
                        <CheckButton
                          :loading="underwayLoading"
                          v-if="value.type == 0"
                          v-model="value.showUnderway"
                          active-text="显示走航轨迹"
                          inactive-text="隐藏走航轨迹"
                          :default-value="false"
                          @change="(e) => handleUnderwayClick(e, i, value)"
                        >
                        </CheckButton>
                        <CheckButton
                          :loading="highlightLoading"
                          v-if="value.type == 1"
                          v-model="value.highlightFusionGrid"
                          active-text="高亮融合网格"
                          :default-value="true"
                          @change="(e) => handleHighlightGridClick(e, i, value)"
                        >
                        </CheckButton>
                      </el-row>
                      <el-form-item label="透明度">
                        <el-slider
                          v-model="value.gridOpacityValue"
                          :min="0"
                          :max="1"
                          :step="0.1"
                          show-stops
                          @change="(e) => handleOpacityChange(e, i, value)"
                          style="width: 150px"
                        />
                        <el-input-number
                          class="m-l-16"
                          size="small"
                          v-model="value.gridOpacityValue"
                          :min="0"
                          :max="1"
                          :step="0.1"
                          @change="(e) => handleOpacityChange(e, i, value)"
                        />
                      </el-form-item>
                      <el-divider />
                    </div>
                  </el-tab-pane>
                </el-tabs>
              </el-tab-pane>
            </el-tabs>
          </el-scrollbar>
        </template>
      </BaseCard>
@@ -104,7 +155,19 @@
/**
 * 网格样式控制工具
 */
import { ref, reactive, onMounted, onUnmounted, computed, toRaw } from 'vue';
import {
  ref,
  reactive,
  onMounted,
  onUnmounted,
  watch,
  computed,
  toRaw
} from 'vue';
import gridApi from '@/api/gridApi';
import { useGridStore } from '@/stores/grid-info';
const gridStore = useGridStore();
const props = defineProps({
  // 网格管理对象[SatelliteGrid]数组
@@ -114,91 +177,181 @@
  }
});
const emits = defineEmits(['showUnderway']);
const activeGridCtrl = ref(0);
const activeGrid = ref(0);
const gridCtrlList = computed(() => {
  return props.gridCtrls.map((g) => {
    return reactive({
const gridLoading = ref(false);
const rankLoading = ref(false);
const dataLoading = ref(false);
const colorLoading = ref(false);
const heatMapLoading = ref(false);
const underwayLoading = ref(false);
const highlightLoading = ref(false);
const emits = defineEmits(['showUnderway', 'onDelete']);
const gridCtrlList = ref([]);
const show = ref(false);
watch(
  () => props.gridCtrls,
  (nV, oV) => {
    if (nV) {
      show.value = true;
      refreshValue();
    }
  }
);
function refreshValue() {
  gridCtrlList.value = props.gridCtrls.map((g) => {
    const _tempMap = new Map();
    if (g.gridState) {
      _tempMap.set('卫星网格', [g.gridState]);
    }
    Array.from(g.gridStateMap).map((v) => {
      const key = girdTypeToName(v[1].type);
      if (!_tempMap.has(key)) {
        _tempMap.set(key, []);
      }
      _tempMap.get(key).push({
        tag: v[0],
        ...v[1]
      });
    });
    const res = {
      name: g.name,
      views: Array.from(g.mapViewsMap).map((v) => {
      views: Array.from(_tempMap).map((v) => {
        return {
          tag: v[0],
          extData: v[1].extData,
          opacityValue: 1
          name: v[0],
          views: reactive(v[1])
        };
      })
    });
    };
    console.log(res);
    return res;
  });
});
}
const show = ref(true);
function girdTypeToName(type) {
  switch (type) {
    case 0:
      return '走航网格';
    case 1:
      return '融合网格';
    case 2:
      return '热力图';
  }
}
// const gridVisible = ref(false);
// const rankVisible = ref(false);
// const dataVisible = ref(false);
// const isStandardColor = ref(true);
// const isOpacity = ref(false);
// const opacityValue = ref(0.7);
// const emits = defineEmits([
//   'showRank',
//   'showData',
//   'changeColor',
//   'changeOpacity'
// ]);
function handleCloseClick(index, y, t, value) {
  const key = value.tag;
  toRaw(props.gridCtrls[index]).deleteTagGrid([key]);
  gridCtrlList.value[index].views[y].views.splice(t, 1);
  emits('onDelete', index, key);
}
function handleGridClick(e, index, value) {
  gridLoading.value = true;
  const key = value.tag;
  toRaw(props.gridCtrls[index]).changeVisibility({
    tags: [key],
    showGridViews: e
  });
  gridLoading.value = false;
}
function handleRankClick(e, index, value) {
  rankLoading.value = true;
  const key = value.tag;
  toRaw(props.gridCtrls[index]).changeVisibility({
    tags: [key],
    showRankTxt: e
  });
  rankLoading.value = false;
}
function handleDataClick(e, index, value) {
  dataLoading.value = true;
  const key = value.tag;
  toRaw(props.gridCtrls[index]).changeVisibility({
    tags: [key],
    showDataTxt: e
  });
  dataLoading.value = false;
}
function handleColorClick(e, index, value) {
  colorLoading.value = true;
  const key = value.tag;
  toRaw(props.gridCtrls[index]).changeGridColor({
    tag: key,
    tags: [key],
    useCustomColor: e
  });
  colorLoading.value = false;
}
function handleOpacityChange(e, index, value) {
  console.log(e, index, value);
  const key = value.tag;
  // value.opacityValue = e;
  toRaw(props.gridCtrls[index]).changeGridOpacity({
    tag: key,
    opacityValue: toRaw(value.opacityValue)
    opacityValue: toRaw(value.gridOpacityValue)
  });
}
function handleUnderwayClick(e, index, value) {
  underwayLoading.value = true;
  emits('showUnderway', {
    isShow: e,
    dataId: value.tag
    dataId: value.tag,
    done: () => (underwayLoading.value = false)
  });
}
function handleHighlightGridClick(e, index, value) {
  toRaw(props.gridCtrls[index]).mixGrid(value.tag.split('-'), e);
  highlightLoading.value = true;
  toRaw(props.gridCtrls[index]).mixGrid2({
    tags: value.tag.split('-'),
    isMixGridHighlight: e
  });
  highlightLoading.value = false;
}
let heatTag;
const heatMapSearchLength = 4;
function handleHeatMapClick(e, index, value) {
  heatMapLoading.value = true;
  const _satelliteGrid = toRaw(props.gridCtrls[index]);
  _satelliteGrid.changeVisibility({
    showGridViews: false,
    showDataTxt: false,
    showRankTxt: false
  });
  if (e) {
    const data = _satelliteGrid.gridDataDetailMap.get(value.tag);
    gridApi
      .buildUnderwayHeatmap(
        _satelliteGrid.gridGroupId,
        data,
        heatMapSearchLength
      )
      .then((res) => {
        heatTag = _satelliteGrid.drawHeatGrid2(value.tag, res.data);
        _satelliteGrid.setDefaultGridClickEvent([heatTag]);
        refreshValue();
      })
      .finally(() => (heatMapLoading.value = false));
  } else {
    _satelliteGrid.changeVisibility({
      tags: [value.tag],
      showGridViews: true
    });
    heatMapLoading.value = false;
    refreshValue();
  }
}
</script>
<style scoped>
@@ -213,4 +366,44 @@
:deep(.el-input-number) {
  width: 80px;
}
:deep(.el-tabs__item) {
  color: rgba(221, 221, 221, 0.806);
}
:deep(.el-tabs__nav > .is-active) {
  color: #f0ff1d;
}
:deep(.el-tabs--border-card) {
  background: transparent;
  border: 0px;
}
:deep(.grid-ctrl-card > .el-tabs__content) {
  padding: 0;
}
:deep(.grid-ctrl-card > .el-tabs__header) {
  background: transparent;
  border-bottom: 0px solid var(--el-border-color-light);
}
:deep(
    .grid-ctrl-card
      > .el-tabs__header
      .el-tabs__nav-wrap
      .el-tabs__nav-scroll
      .el-tabs__nav
  ) {
  border: 1px solid var(--el-border-color-light);
}
:deep(.grid-ctrl-card > .el-tabs__header .el-tabs__item.is-active) {
  color: var(--font-color);
  background-color: transparent;
  border-right-color: transparent;
  border-left-color: transparent;
}
:deep(.el-tabs--border-card > .el-tabs__header .el-tabs__item) {
  margin-top: 0px;
}
:deep(.el-tabs--border-card > .el-tabs__header .el-tabs__item:first-child) {
  margin-left: 0px;
}
</style>