index.vue 8.26 KB
<template>
  <div class="go-edit-bottom">
    <!-- THINGS_KIT 修改多画布切换相关代码 -->
    <n-button v-if="chartEditStore.getPageList.length > 3" size="tiny" type="primary" ghost @click="pageContainerLeft">
      <template #icon>
        <n-icon>
          <ArrowBackIcon />
        </n-icon>
      </template>
    </n-button>
    <div class="page-bottom-container">
      <n-scrollbar x-scrollable ref="scrollBarRef">
        <div class="page-scroll-container">
          <template v-for="(pageItem) in chartEditStore.getPageList" :key="pageItem.id">
            <n-button :color="chartEditStore.pageConfig.currentActiveId === pageItem.id ? 'green' : ''" size="small"
              icon-placement="right" secondary strong>
              <template #icon>
                <n-dropdown trigger="click" @select="(key: string) => handleOperateMenu(key, pageItem)"
                  :options="getMenuDisableOptions">
                  <n-icon>
                    <list-icon />
                  </n-icon>
                </n-dropdown>
              </template>
              <n-input v-if="pageItem.id === renamePageId" class="rename-input" v-model:value="pageRenameValue"
                @keypress.enter="handleRenameBlur" @blur="handleRenameBlur(pageItem)" autofocus size="small"
                placeholder="请输入页面名称"></n-input>
              <span v-else @click="pageOperateCurrent(pageItem)">
                {{ pageItem.title }}
              </span>
            </n-button>
          </template>
        </div>
      </n-scrollbar>
    </div>
    <n-button v-if="chartEditStore.getPageList.length > 3" size="tiny" type="primary" ghost @click="pageContainerRight">
      <template #icon>
        <n-icon>
          <ArrowForwardIcon />
        </n-icon>
      </template>
    </n-button>
    <n-button v-if="chartEditStore.getPageList.length < 20" size="small" secondary strong @click="pageOperateAdd">
      <template #icon>
        <n-icon><duplicate-icon /></n-icon>
      </template>
    </n-button>

    <n-space>
      <!-- THINGS_KIT 修改多画布切换相关代码 -->
      <!-- 历史记录 -->
      <edit-history></edit-history>
      <!-- CTRL按键触发展示 -->
      <n-text id="keyboard-dress-show" depth="3"></n-text>
    </n-space>

    <n-space class="bottom-ri">
      <!-- 快捷键提示 -->
      <edit-shortcut-key />

      <!-- 缩放比例 -->
      <n-select ref="selectInstRef" class="scale-btn" v-model:value="filterValue" size="mini" :disabled="lockScale"
        :options="filterOptions" @update:value="selectHandle"></n-select>

      <!-- 锁定缩放 -->
      <n-tooltip trigger="hover">
        <template #trigger>
          <n-button @click="lockHandle" text>
            <n-icon class="lock-icon" :class="{ color: lockScale }" size="18" :depth="2">
              <lock-closed-outline-icon v-if="lockScale"></lock-closed-outline-icon>
              <lock-open-outline-icon v-else></lock-open-outline-icon>
            </n-icon>
          </n-button>
        </template>
        <span>{{ lockScale ? '解锁' : '锁定' }}当前比例</span>
      </n-tooltip>

      <!-- 拖动 -->
      <n-slider class="scale-slider" v-model:value="sliderValue" :default-value="50" :min="10" :max="200" :step="5"
        :format-tooltip="sliderFormatTooltip" :disabled="lockScale" :marks="sliderMaks"
        @update:value="sliderHandle"></n-slider>
    </n-space>
  </div>
</template>

<script setup lang="ts">
import { SelectInst } from 'naive-ui'
import { computed, reactive, ref, toRefs, unref, watchEffect } from 'vue'
import { icon } from '@/plugins'
import { EditHistory } from '../EditHistory/index'
import EditShortcutKey from '../EditShortcutKey/index.vue'
import { useDesignStore } from '@/store/modules/designStore/designStore'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
import { EditCanvasTypeEnum, PageChartEditStoreType } from '@/store/modules/chartEditStore/chartEditStore.d'
import { useChartLayoutStore } from '@/store/modules/chartLayoutStore/chartLayoutStore'
import { ChartLayoutStoreEnum } from '@/store/modules/chartLayoutStore/chartLayoutStore.d'
import type { MenuOption } from 'naive-ui'
import { PageOperateEnum, PageOperateNameEnum } from '@/enums/external/pageOperateEnum'

const { LockClosedOutlineIcon, LockOpenOutlineIcon, ListIcon, DuplicateIcon, ArrowBackIcon, ArrowForwardIcon } = icon.ionicons5

// 全局颜色
const designStore = useDesignStore()
const themeColor = ref(designStore.getAppTheme)
const chartLayoutStore = useChartLayoutStore()
const chartEditStore = useChartEditStore()
const { lockScale, scale } = toRefs(chartEditStore.getEditCanvas)
const selectInstRef = ref<SelectInst | null>(null)

// 缩放选项
let filterOptions = [
  {
    label: '200%',
    value: 200
  },
  {
    label: '150%',
    value: 150
  },
  {
    label: '100%',
    value: 100
  },
  {
    label: '50%',
    value: 50
  },
  {
    label: '自适应',
    value: 0
  }
]

// 选择值
const filterValue = ref('')

// 用户自选择
const selectHandle = (v: number) => {
  selectInstRef.value?.blur()
  if (v === 0) {
    chartLayoutStore.setItemUnHandle(ChartLayoutStoreEnum.RE_POSITION_CANVAS, true)
    chartEditStore.computedScale()
    return
  }
  chartEditStore.setScale(v / 100)
}

// 点击锁处理
const lockHandle = () => {
  chartEditStore.setEditCanvas(EditCanvasTypeEnum.LOCK_SCALE, !lockScale.value)
}

// 拖动
const sliderValue = ref(100)

// 拖动格式化
const sliderFormatTooltip = (v: string) => `${v}%`

// 拖动处理
const sliderHandle = (v: number) => {
  chartEditStore.setScale(v / 100)
}

const sliderMaks = reactive({
  100: ''
})

// 监听 scale 变化
watchEffect(() => {
  const value = (scale.value * 100).toFixed(0)
  filterValue.value = `${value}%`
  sliderValue.value = parseInt(value)
})

// THINGS_KIT 修改多画布切换相关代码

const pageRenameValue = ref('')

const renamePageId = ref('')

const getMenuDisableOptions = computed<MenuOption[]>(() => {
  return [
    {
      label: PageOperateNameEnum.PAGE_OPERATE_REMOVE,
      key: PageOperateEnum.PAGE_OPERATE_REMOVE,
      disabled: chartEditStore.pageConfig.pageList.length <= 1
    },
    {
      label: PageOperateNameEnum.PAGE_OPERATE_COPY,
      key: PageOperateEnum.PAGE_OPERATE_COPY,
    },
    {
      label: PageOperateNameEnum.PAGE_OPERATE_RENAME,
      key: PageOperateEnum.PAGE_OPERATE_RENAME,
    },
  ]
})

const handleOperateMenu = (key: string, pageItem: PageChartEditStoreType) => {
  switch (key) {
    case PageOperateEnum.PAGE_OPERATE_REMOVE:
      chartEditStore.pageIdRemovePageItem(pageItem)
      break;
    case PageOperateEnum.PAGE_OPERATE_COPY:
      chartEditStore.copyPage(pageItem)
      break;
    case PageOperateEnum.PAGE_OPERATE_RENAME:
      pageRenameValue.value = pageItem.title
      renamePageId.value = pageItem.id
      break;
  }
}

const handleRenameBlur = (pageItem: PageChartEditStoreType) => {
  pageItem.title = unref(pageRenameValue)
  renamePageId.value = ''
}

const pageOperateAdd = () => chartEditStore.addPageList()

const pageOperateCurrent = (currentItem: PageChartEditStoreType) => {
  chartEditStore.setCurrentPageSelectId(currentItem.id)
}

const scrollBarRef = ref()

const movePageContainer = (left: number) => {
  scrollBarRef.value.scrollBy({
    left
  })
}

const pageContainerLeft = () => movePageContainer(-30)

const pageContainerRight = () => movePageContainer(30)

// THINGS_KIT 修改多画布切换相关代码
</script>

<style lang="scss" scoped>
$min-width: 500px;
$max-width: 670px;

@include go('edit-bottom') {
  width: 100%;
  min-width: $min-width;
  min-width: $max-width;
  padding: 0 10px;
  display: flex;
  align-items: center;
  justify-content: space-between;

  .page-bottom-container {
    max-width: 400px;

    .page-scroll-container {
      white-space: nowrap;
      padding: 12px;
      display: flex;
      gap: 10px
    }
  }

  .bottom-ri {
    position: relative;
    top: 15px;

    .lock-icon {
      padding-top: 4px;

      &.color {
        color: v-bind('themeColor');
      }
    }

    .scale-btn {
      width: 90px;
      font-size: 12px;

      @include deep() {
        .n-base-selection-label {
          padding: 3px;
        }
      }
    }

    .scale-slider {
      position: relative;
      top: -4px;
      width: 100px;
    }
  }
}

.rename-input {
  width: 80px !important;
  max-width: 80px !important;
}
</style>