config.vue 9.19 KB
<template>
  <collapse-item :name="t('common.foundationText')" :expanded="true">
    <setting-item-box :name="t('common.languageTypeText')" :alone="true">
      <setting-item>
        <n-select size="small" v-model:value="optionData.mapOptions.lang" :options="langOptions" />
      </setting-item>
    </setting-item-box>
    <setting-item-box name="Key" :alone="true">
      <setting-item :name="t('charts.chart.gaodeKey')">
        <n-input v-model:value="optionData.mapOptions.amapKey" size="small"></n-input>
      </setting-item>
    </setting-item-box>
    <setting-item-box :name="t('charts.chart.customMapId')" :alone="true">
      <setting-item>
        <n-input size="small" v-model:value="optionData.mapOptions.amapStyleKeyCustom" />
      </setting-item>
    </setting-item-box>
  </collapse-item>
  <collapse-item :name="t('charts.chart.map')" :expanded="true">
    <setting-item-box :name="t('common.themeText')">
      <setting-item>
        <n-select size="small" v-model:value="optionData.mapOptions.amapStyleKey" :options="themeOptions" />
      </setting-item>
    </setting-item-box>
    <setting-item-box :name="t('common.contentText')" :alone="true">
      <n-checkbox-group v-model:value="optionData.mapOptions.features">
        <n-space item-style="display: flex;">
          <n-checkbox :value="item.value" :label="item.label" v-for="(item, index) in featuresOptions" :key="index" />
        </n-space>
      </n-checkbox-group>
    </setting-item-box>
    <setting-item-box :name="t('common.positionText')">
      <setting-item :name="t('common.longText')">
        <n-input-number v-model:value="optionData.mapOptions.amapLon" :show-button="false" size="small">
          <template #suffix>°</template>
        </n-input-number>
      </setting-item>
      <setting-item :name="t('common.latText')">
        <n-input-number v-model:value="optionData.mapOptions.amapLat" :show-button="false" size="small">
          <template #suffix>°</template>
        </n-input-number>
      </setting-item>
      <setting-item :name="t('charts.chart.initScaling')">
        <n-input-number v-model:value="optionData.mapOptions.amapZindex" :min="0" size="small"></n-input-number>
      </setting-item>
    </setting-item-box>
    <setting-item-box :name="t('charts.chart.mode')" :alone="true">
      <setting-item>
        <n-radio-group v-model:value="optionData.mapOptions.viewMode" name="radiogroup">
          <n-space>
            <n-radio v-for="song in viewModeOptions" :key="song.value" :value="song.value">
              {{ song.label }}
            </n-radio>
          </n-space>
        </n-radio-group>
      </setting-item>
    </setting-item-box>
    <template v-if="optionData.mapOptions.viewMode === '3D'">
      <setting-item-box>
        <setting-item :name="t('charts.chart.skyColor')">
          <n-color-picker size="small" :modes="['hex']" v-model:value="optionData.mapOptions.skyColor"></n-color-picker>
        </setting-item>
        <setting-item :name="t('charts.chart.pitch')">
          <n-input-number v-model:value="optionData.mapOptions.pitch" :min="0" :max="83" size="small"></n-input-number>
        </setting-item>
      </setting-item-box>
    </template>
  </collapse-item>
  <collapse-item :name="t('charts.chart.markerIcon')" :expanded="true">
    <setting-item-box :name="t('common.styleText')">
      <setting-item>
        <NSelect
          size="small"
          :placeholder="t('charts.chart.placeIcon')"
          style="width: 250px"
          :value="iconMarkerValue"
          :options="iconMarkerOptions"
          :render-label="renderOption"
          clearable
          filterable
          @update:value="selectHandle"
        />
      </setting-item>
    </setting-item-box>
  </collapse-item>
  <collapse-item :name="t('charts.chart.mark')" :expanded="true">
    <setting-item-box :name="t('common.styleText')">
      <setting-item :name="t('common.typeText')">
        <n-select size="small" v-model:value="optionData.mapOptions.mapMarkerType" :options="MarkerOptions" />
      </setting-item>
      <setting-item v-if="optionData.mapOptions.mapMarkerType === MarkerEnum.CIRCLE_MARKER" :name="t('common.colorText')">
        <n-color-picker v-model:value="optionData.mapOptions.marker.fillColor" size="small"></n-color-picker>
      </setting-item>
    </setting-item-box>
  </collapse-item>
  <collapse-item :name="t('charts.chart.lineText')" :expanded="true">
    <setting-item-box :name="t('common.styleText')">
      <setting-item :name="t('common.colorText')">
          <n-color-picker size="small" :show-alpha="false" v-model:value="optionData.mapOptions.lineColor"></n-color-picker>
      </setting-item>
      <setting-item :name="t('charts.chart.lineW')">
          <n-input-number v-model:value="optionData.mapOptions.lineWidth" :min="0" :max="100" size="small"></n-input-number>
      </setting-item>
      <setting-item :name="t('charts.chart.lineArrow')">
          <n-switch v-model:value="optionData.mapOptions.lineShowDir" size="small" />
      </setting-item>
      <setting-item :name="t('charts.chart.lineTransparency')">
          <n-input-number v-model:value="optionData.mapOptions.lineOpacity" :min="0" :max="1" size="small"></n-input-number>
      </setting-item>
    </setting-item-box>
  </collapse-item>
</template>

<script setup lang="ts">
import { PropType, ref, computed, h, onMounted } from 'vue'
import { option, MarkerEnum, ThemeEnum, LangEnum, ViewModeEnum, FeaturesEnum } from './config'
import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
import { NEllipsis, NImage,NSelect, NSpace, SelectOption } from 'naive-ui'
import { getUrlBase64 } from '@/utils/external/imageUrlToBase64'

const props = defineProps({
  optionData: {
    type: Object as PropType<typeof option>,
    required: true
  }
})

const t = window['$t']

const themeOptions = [
  {
    value: ThemeEnum.NORMAL,
    label: t('charts.chart.standard')
  },
  {
    value: ThemeEnum.DARK,
    label: t('charts.chart.phantom')
  },
  {
    value: ThemeEnum.LIGHT,
    label: t('charts.chart.moonlight')
  },
  {
    value: ThemeEnum.WHITES_MOKE,
    label: t('charts.chart.yuanshan')
  },
  {
    value: ThemeEnum.FRESH,
    label: t('charts.chart.grass')
  },
  {
    value: ThemeEnum.GREY,
    label: t('charts.chart.yashi')
  },
  {
    value: ThemeEnum.GRAFFITI,
    label: t('charts.chart.graffiti')
  },
  {
    value: ThemeEnum.MACARON,
    label: t('charts.chart.macarone')
  },
  {
    value: ThemeEnum.BLUE,
    label: t('charts.chart.indigo')
  },
  {
    value: ThemeEnum.DARKBLUE,
    label: t('charts.chart.polar')
  },
  {
    value: ThemeEnum.WINE,
    label: t('charts.chart.soy')
  },
  {
    value: ThemeEnum.WEIXIN,
    label: t('charts.chart.satellite')
  }
]

const langOptions = [
  {
    value: LangEnum.ZH_CN,
    label: t('charts.chart.chinese')
  },
  {
    value: LangEnum.EN,
    label: t('charts.chart.english')
  },
  {
    value: LangEnum.ZH_EN,
    label: t('charts.chart.chineseEnglish')
  }
]

const viewModeOptions = [
  {
    value: ViewModeEnum.PLANE,
    label: '2D'
  },
  {
    value: ViewModeEnum.STEREOSCOPIC,
    label: '3D'
  }
]

const featuresOptions = [
  {
    value: FeaturesEnum.BG,
    label: t('charts.chart.showMaoBg')
  },
  {
    value: FeaturesEnum.POINT,
    label: t('charts.chart.showIden')
  },
  {
    value: FeaturesEnum.ROAD,
    label: t('charts.chart.showRoad')
  },
  {
    value: FeaturesEnum.BUILDING,
    label: t('charts.chart.showBuilding')
  }
]

const MarkerOptions = [
  // {
  //   value: MarkerEnum.CIRCLE_MARKER,
  //   label: '圆形标点' //在地图里点击无效,所以注释,有需要自行打开即可
  // },
  {
    value: MarkerEnum.MARKER,
    label: t('charts.chart.marker')
  },
  {
    value: MarkerEnum.NONE,
    label: t('charts.chart.hideMarker')
  }
]

const iconMarkerValue = ref<string | null>('1.png')

const isHref = (url: string) => {
  try {
    new URL(url)
    return true
  } catch (error) {
    return false
  }
}

// import.meta.glob 这个不能封装,必须是字符串,不能通过传值传进去
const iconMarkerOptions = computed(() => {
  const pathList = import.meta.glob('../../../../../../assets/external/marker/*')
  return Object.keys(pathList).map(item => {
    const imgName = item.split('/').at(-1)
    return {
      label: imgName,
      value: imgName
    } as SelectOption
  })
})

const getMarkerImagePath = (name: string) => {
  return isHref(name) ? name : new URL(`../../../../../../assets/external/marker/${name}`, import.meta.url).href
}

const renderOption = (option: SelectOption) => {
  return h(NSpace, { justify: 'space-between', style: 'padding: 0 15px; height: 28px; line-height: 28px;' }, () => [
    h(NImage, {
      width: 25,
      src: getMarkerImagePath(option.value as string),
      previewDisabled: true,
      style: { height: '25px' }
    } as Recordable),
    h(NEllipsis, null, () => option.label)
  ])
}

const selectHandle = (value: string) => {
  iconMarkerValue.value = value
   getUrlBase64(getMarkerImagePath(value),'png',(baseEncodeText: string)=>{
    props.optionData.mapOptions.iconMarker =baseEncodeText
  })
}
onMounted(() => {
  getUrlBase64(getMarkerImagePath(props.optionData.mapOptions.iconMarker),'png',(baseEncodeText: string) => {
    props.optionData.mapOptions.iconMarker = baseEncodeText
  })
})
</script>