index.vue 6.45 KB
<template>
  <!-- 侧边栏和数据分发处理 -->
  <div class="go-chart-common">
    <n-menu v-show="hidePackageOneCategory" class="chart-menu-width" v-model:value="selectValue"
      :options="packages.menuOptions" :icon-size="16" :indent="18" @update:value="clickItemHandle"></n-menu>
    <div class="chart-content-list">
      <n-scrollbar trigger="none">
        <charts-item-box :menuOptions="packages.selectOptions" @deletePhoto="deleteHandle"></charts-item-box>
      </n-scrollbar>
    </div>
  </div>
</template>
<script setup lang="ts">
import { ref, watch, computed, reactive } from 'vue'
import { ConfigType } from '@/packages/index.d'
import { useSettingStore } from '@/store/modules/settingStore/settingStore'
import { loadAsyncComponent } from '@/utils'
import { usePackagesStore } from '@/store/modules/packagesStore/packagesStore'
// import { PackagesCategoryEnum } from '@/packages/index.d'
import { hideAsideComponentsObj } from './config'
import { remove } from 'lodash'
import { getThreeJsModelList } from '@/api/external/contentSave/content'
import { ChartType } from '@/views/three/items'
import { isArray } from '@/utils/external/is'

const ChartsItemBox = loadAsyncComponent(() => import('../../../components/ChartsItemBox/index.vue'))
const packagesStore = usePackagesStore()

const props = defineProps({
  selectOptions: {
    type: Object,
    // eslint-disable-next-line @typescript-eslint/no-empty-function
    default: () => { }
  }
})

const t = window['$t']

// 隐藏设置
const settingStore = useSettingStore()

const hidePackageOneCategory = computed(() => {
  if (packages.categorysNum > 2) return true
  return !settingStore.getHidePackageOneCategory
})

let packages = reactive<{
  [T: string]: any
}>({
  // 侧边栏
  menuOptions: [],
  // 当前选择
  selectOptions: {},
  // 分类归档
  categorys: {
    all: []
  },
  categoryNames: {
    all: 'common.allText'
  },
  // 分类归档数量
  categorysNum: 0,
  // 存储不同类别组件进来的选中值
  saveSelectOptions: {}
})

const selectValue = ref<string>('all')

const threeJsModels = ref<Recordable[]>([])

// 设置初始列表
const setSelectOptions = (categorys: any) => {
  for (const val in categorys) {
    packages.selectOptions = categorys[val]
    break
  }
}

// THINGS_KIT修改左侧边栏隐藏部分组件(比如重写的,有问题的等需要隐藏)
const byKeyHideAside = (hideAsideComponentsObj: Record<string, string[]>, categorys: Record<string, any>) => {
  for (const key in categorys) {
    const categoryKey = key
    const categoryValue = categorys[key]
    for (const hideKey in hideAsideComponentsObj) {
      const needHideKey = hideKey
      const needCategoryValue = hideAsideComponentsObj[key]
      if (categoryKey === needHideKey) {
        remove(categoryValue, item => {
          const { chartKey } = item as any
          return needCategoryValue.includes(chartKey)
        })
      }
    }
  }
  return categorys
}

watch(
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
  // @ts-ignore
  () => props.selectOptions,
  async (newData: { list: ConfigType[] }) => {
    packages.categorysNum = 0
    if (!newData) return
    if (newData.list.map((list: ConfigType) => list.category).includes('Three')) {
      const { items } = await getThreeJsModelList({
        page: 1,
        pageSize: 999999
      })
      const { host, protocol } = location
      let threeFilePath = `${protocol}//${host}`
      const VITE_GLOB_API_URL = import.meta.env.VITE_GLOB_API_URL
      const VITE_GLOB_API_URL_PREFIX = import.meta.env.VITE_GLOB_API_URL_PREFIX
      threeJsModels.value = items
        ?.filter(filterItem => filterItem.state === 1)
        ?.map((modelItem: ChartType) => {
          return {
            category: 'Three',
            categoryName: 'business.component.THREE',
            chartFrame: 'static',
            chartKey: 'ExternalVCLoader',
            conKey: 'ExternalVCCLoader',
            image: modelItem.imageUrl ? modelItem.imageUrl : 'threeModelDefault.svg',
            key: 'Loader',
            package: 'Decorates',
            title: modelItem.name ?? modelItem.id,
            redirectComponent: 'Decorates/Three/Loader',
            isThreeModel: true,
            threeModelContent: modelItem.content,
            threeModelFilePath: modelItem.id,
            threeModelImageUrl: modelItem.imageUrl
          }
        })
    }
    const mergeList = [...newData.list, ...threeJsModels.value] as ConfigType[]
    mergeList.forEach((e: ConfigType) => {
      const value: ConfigType[] = (packages.categorys as Recordable)[e.category]
      packages.categorys[e.category] = value && value.length ? [...value, e] : [e]
      packages.categoryNames[e.category] = e.categoryName
      packages.categorys['all'].push(e)
    })
    for (const val in packages.categorys) {
      packages.categorysNum += 1
      packages.menuOptions.push({
        key: val,
        label: t(packages.categoryNames[val])
      })
    }
    setSelectOptions(packages.categorys)
    byKeyHideAside(hideAsideComponentsObj, packages.categorys)
    // 默认选中处理
    selectValue.value = packages.menuOptions[0]['key']
  },
  {
    immediate: true
  }
)

watch(
  () => packagesStore.newPhoto,
  newPhoto => {
    if (!newPhoto) return
    const newPhotoCategory = newPhoto.category
    packages.categorys[newPhotoCategory].splice(1, 0, newPhoto)
    packages.categorys['all'].splice(1, 0, newPhoto)
  }
)

// 删除图片
const deleteHandle = (item: ConfigType, index: number) => {
  packages.categorys[item.category].splice(index, 1)
  packages.categorys['all'].splice(index, 1)
}

// 处理点击事件
const clickItemHandle = (key: string) => {
  packages.selectOptions = packages.categorys[key]
}
</script>

<style lang="scss" scoped>
/* 此高度与 ContentBox 组件关联*/
$topHeight: 40px;
$menuWidth: 65px;

@include go('chart-common') {
  display: flex;
  height: calc(100vh - #{$--header-height} - #{$topHeight});

  .chart-menu-width {
    width: $menuWidth;
    flex-shrink: 0;
    @include fetch-bg-color('background-color2-shallow');
  }

  .chart-content-list {
    width: 200px;
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
  }

  @include deep() {
    .n-menu-item {
      height: 30px;

      &.n-menu-item--selected {
        &::before {
          background-color: rgba(0, 0, 0, 0);
        }
      }

      .n-menu-item-content {
        text-align: center;
        padding: 0px 14px !important;
        font-size: 12px !important;
      }
    }
  }
}
</style>