mirror of
				https://github.com/continew-org/continew-admin-ui.git
				synced 2025-11-04 10:57:08 +08:00 
			
		
		
		
	feat: 新增左树右表布局组件GiLeftRightPane封装,分割面板组件GiSplitPaneButton封装,以及代码优化(同步 GiDemo 更新)
This commit is contained in:
		
							
								
								
									
										60
									
								
								src/components/GiLeftRightPane/index.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								src/components/GiLeftRightPane/index.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,60 @@
 | 
				
			|||||||
 | 
					<template>
 | 
				
			||||||
 | 
					  <a-row align="stretch" :gutter="14" class="gi-left-right-pane">
 | 
				
			||||||
 | 
					    <a-col
 | 
				
			||||||
 | 
					      :xs="0" :sm="8" :md="7" :lg="6" :xl="5" :xxl="4" flex="260px" v-bind="props.leftColProps"
 | 
				
			||||||
 | 
					      class="h-full overflow-hidden"
 | 
				
			||||||
 | 
					    >
 | 
				
			||||||
 | 
					      <div class="gi-left-right-pane__left">
 | 
				
			||||||
 | 
					        <slot name="left"></slot>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    </a-col>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <a-col
 | 
				
			||||||
 | 
					      :xs="24" :sm="16" :md="17" :lg="18" :xl="19" :xxl="20" flex="1" v-bind="props.rightColProps"
 | 
				
			||||||
 | 
					      class="h-full overflow-hidden"
 | 
				
			||||||
 | 
					    >
 | 
				
			||||||
 | 
					      <div class="gi-left-right-pane__right">
 | 
				
			||||||
 | 
					        <slot></slot>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    </a-col>
 | 
				
			||||||
 | 
					  </a-row>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<script lang='ts' setup>
 | 
				
			||||||
 | 
					import type { ColProps } from '@arco-design/web-vue'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					interface Props {
 | 
				
			||||||
 | 
					  leftColProps?: ColProps
 | 
				
			||||||
 | 
					  rightColProps?: ColProps
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					defineOptions({ name: 'GiLeftRightPane' })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const props = withDefaults(defineProps<Props>(), {
 | 
				
			||||||
 | 
					  leftColProps: () => ({}),
 | 
				
			||||||
 | 
					  rightColProps: () => ({}),
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 一般用于左树右表结构页面
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					defineSlots<{
 | 
				
			||||||
 | 
					  left: () => void
 | 
				
			||||||
 | 
					}>()
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<style lang='scss' scoped>
 | 
				
			||||||
 | 
					.gi-left-right-pane {
 | 
				
			||||||
 | 
					  flex: 1;
 | 
				
			||||||
 | 
					  overflow: hidden;
 | 
				
			||||||
 | 
					  padding: $margin;
 | 
				
			||||||
 | 
					  box-sizing: border-box;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  &__left,
 | 
				
			||||||
 | 
					  &__right {
 | 
				
			||||||
 | 
					    height: 100%;
 | 
				
			||||||
 | 
					    display: flex;
 | 
				
			||||||
 | 
					    flex-direction: column;
 | 
				
			||||||
 | 
					    overflow: hidden;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					</style>
 | 
				
			||||||
							
								
								
									
										83
									
								
								src/components/GiSpace/index.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								src/components/GiSpace/index.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,83 @@
 | 
				
			|||||||
 | 
					<template>
 | 
				
			||||||
 | 
					  <div class="gi-space" :class="getClass" :style="getStyle">
 | 
				
			||||||
 | 
					    <slot></slot>
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<script setup lang="ts">
 | 
				
			||||||
 | 
					import type { CSSProperties } from 'vue'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					interface Props {
 | 
				
			||||||
 | 
					  size?: number | [number, number] | 'mini' | 'small' | 'medium' | 'large'
 | 
				
			||||||
 | 
					  direction?: 'horizontal' | 'vertical'
 | 
				
			||||||
 | 
					  justify?: 'start' | 'center' | 'end' | 'space-between' | 'space-around'
 | 
				
			||||||
 | 
					  align?: 'start' | 'center' | 'end' | 'baseline' | 'stretch'
 | 
				
			||||||
 | 
					  wrap?: boolean
 | 
				
			||||||
 | 
					  fill?: boolean // 充满整行
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const props = withDefaults(defineProps<Props>(), {
 | 
				
			||||||
 | 
					  size: 'small',
 | 
				
			||||||
 | 
					  direction: 'horizontal',
 | 
				
			||||||
 | 
					  justify: 'start',
 | 
				
			||||||
 | 
					  align: 'center',
 | 
				
			||||||
 | 
					  wrap: true,
 | 
				
			||||||
 | 
					  fill: false,
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const getClass = computed(() => {
 | 
				
			||||||
 | 
					  const arr: string[] = []
 | 
				
			||||||
 | 
					  if (props.wrap) {
 | 
				
			||||||
 | 
					    arr.push('gi-space-wrap')
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  if (props.direction) {
 | 
				
			||||||
 | 
					    arr.push(`gi-space-direction-${props.direction}`)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  if (props.fill) {
 | 
				
			||||||
 | 
					    arr.push('gi-space-fill')
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return arr.join(' ')
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const getStyle = computed(() => {
 | 
				
			||||||
 | 
					  const obj: CSSProperties = {}
 | 
				
			||||||
 | 
					  if (Array.isArray(props.size)) {
 | 
				
			||||||
 | 
					    const [colGap = 0, rowGap = 0] = props.size
 | 
				
			||||||
 | 
					    obj.gap = props.wrap ? `${rowGap}px ${colGap}px` : `0 ${colGap}px`
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    const sizeMap: Record<'mini' | 'small' | 'medium' | 'large', number> = {
 | 
				
			||||||
 | 
					      mini: 4,
 | 
				
			||||||
 | 
					      small: 8,
 | 
				
			||||||
 | 
					      medium: 16,
 | 
				
			||||||
 | 
					      large: 24,
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    const size = sizeMap[props.size] || props.size
 | 
				
			||||||
 | 
					    obj.gap = props.wrap ? `${size}px` : `0 ${size}px`
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  obj['justify-content'] = props.justify
 | 
				
			||||||
 | 
					  obj['align-items'] = props.align
 | 
				
			||||||
 | 
					  return obj
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<style lang="scss" scoped>
 | 
				
			||||||
 | 
					.gi-space {
 | 
				
			||||||
 | 
					  display: inline-flex;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  &.gi-space-wrap {
 | 
				
			||||||
 | 
					    flex-wrap: wrap;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  &.gi-space-fill {
 | 
				
			||||||
 | 
					    display: flex;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  &.gi-space-direction-horizontal {
 | 
				
			||||||
 | 
					    flex-direction: row;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  &.gi-space-direction-vertical {
 | 
				
			||||||
 | 
					    flex-direction: column;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					</style>
 | 
				
			||||||
							
								
								
									
										58
									
								
								src/components/GiSplitButton/index.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								src/components/GiSplitButton/index.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,58 @@
 | 
				
			|||||||
 | 
					<template>
 | 
				
			||||||
 | 
					  <div class="gi-split-button" :class="getClass" @click="emit('click')">
 | 
				
			||||||
 | 
					    <icon-right v-if="props.collapsed" />
 | 
				
			||||||
 | 
					    <icon-left v-else />
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<script lang='ts' setup>
 | 
				
			||||||
 | 
					interface Props {
 | 
				
			||||||
 | 
					  collapsed: boolean
 | 
				
			||||||
 | 
					  type?: 'default' | 'circle'
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const props = withDefaults(defineProps<Props>(), {
 | 
				
			||||||
 | 
					  collapsed: false,
 | 
				
			||||||
 | 
					  type: 'circle',
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const emit = defineEmits<{
 | 
				
			||||||
 | 
					  (e: 'click'): void
 | 
				
			||||||
 | 
					}>()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const getClass = computed(() => {
 | 
				
			||||||
 | 
					  return `gi-split-button--${props.type}`
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<style lang='scss' scoped>
 | 
				
			||||||
 | 
					.gi-split-button {
 | 
				
			||||||
 | 
					  position: absolute;
 | 
				
			||||||
 | 
					  top: 50%;
 | 
				
			||||||
 | 
					  transform: translateY(-50%);
 | 
				
			||||||
 | 
					  display: flex;
 | 
				
			||||||
 | 
					  justify-content: center;
 | 
				
			||||||
 | 
					  align-items: center;
 | 
				
			||||||
 | 
					  z-index: 999;
 | 
				
			||||||
 | 
					  border: 1px solid var(--color-border-2);
 | 
				
			||||||
 | 
					  background-color: var(--color-bg-1);
 | 
				
			||||||
 | 
					  cursor: pointer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  &--default {
 | 
				
			||||||
 | 
					    width: 18px;
 | 
				
			||||||
 | 
					    height: 40px;
 | 
				
			||||||
 | 
					    left: 0;
 | 
				
			||||||
 | 
					    box-shadow: 2px 0 6px rgba(0, 0, 0, 0.1);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  &--circle {
 | 
				
			||||||
 | 
					    width: 24px;
 | 
				
			||||||
 | 
					    height: 24px;
 | 
				
			||||||
 | 
					    border-radius: 50%;
 | 
				
			||||||
 | 
					    left: -12px;
 | 
				
			||||||
 | 
					    z-index: 999;
 | 
				
			||||||
 | 
					    overflow: hidden;
 | 
				
			||||||
 | 
					    box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					</style>
 | 
				
			||||||
@@ -0,0 +1,47 @@
 | 
				
			|||||||
 | 
					<template>
 | 
				
			||||||
 | 
					  <div ref="boxRef" class="gi-flexible-box" :style="getStyle">
 | 
				
			||||||
 | 
					    <slot></slot>
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<script setup lang="ts">
 | 
				
			||||||
 | 
					import { type CSSProperties, computed, ref } from 'vue'
 | 
				
			||||||
 | 
					import { useBreakpoint } from '@/hooks'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					interface Props {
 | 
				
			||||||
 | 
					  visible: boolean
 | 
				
			||||||
 | 
					  direction?: 'left' | 'right'
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const props = withDefaults(defineProps<Props>(), {
 | 
				
			||||||
 | 
					  visible: false,
 | 
				
			||||||
 | 
					  direction: 'left',
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const emit = defineEmits<{
 | 
				
			||||||
 | 
					  (e: 'update:visible', value: boolean): void
 | 
				
			||||||
 | 
					}>()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const boxRef = ref<HTMLElement | null>()
 | 
				
			||||||
 | 
					const { breakpoint } = useBreakpoint()
 | 
				
			||||||
 | 
					watch(() => breakpoint.value, (val) => {
 | 
				
			||||||
 | 
					  if (['xs'].includes(val)) {
 | 
				
			||||||
 | 
					    emit('update:visible', false)
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    emit('update:visible', true)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}, { immediate: true })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const getStyle = computed(() => {
 | 
				
			||||||
 | 
					  const obj: CSSProperties = {}
 | 
				
			||||||
 | 
					  obj[`margin-${props.direction}`]
 | 
				
			||||||
 | 
					    = !props.visible && boxRef.value && boxRef.value.clientWidth ? `-${boxRef.value.clientWidth}px` : 0
 | 
				
			||||||
 | 
					  return obj
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<style lang="scss" scoped>
 | 
				
			||||||
 | 
					.gi-flexible-box {
 | 
				
			||||||
 | 
					  transition: all 0.36s;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					</style>
 | 
				
			||||||
							
								
								
									
										62
									
								
								src/components/GiSplitPane/index.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								src/components/GiSplitPane/index.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,62 @@
 | 
				
			|||||||
 | 
					<template>
 | 
				
			||||||
 | 
					  <div class="gi-split-pane">
 | 
				
			||||||
 | 
					    <GiSplitPaneFlexibleBox v-model:visible="visible">
 | 
				
			||||||
 | 
					      <div class="gi-split-pane__left">
 | 
				
			||||||
 | 
					        <slot name="left"></slot>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    </GiSplitPaneFlexibleBox>
 | 
				
			||||||
 | 
					    <div class="gi-split-pane__line">
 | 
				
			||||||
 | 
					      <GiSplitButton :collapsed="!visible" @click="handleClick"></GiSplitButton>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					    <div class="gi-split-pane__right">
 | 
				
			||||||
 | 
					      <slot></slot>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<script setup lang='ts'>
 | 
				
			||||||
 | 
					defineSlots<{
 | 
				
			||||||
 | 
					  left: () => void
 | 
				
			||||||
 | 
					}>()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const visible = ref(true)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const handleClick = () => {
 | 
				
			||||||
 | 
					  visible.value = !visible.value
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<style lang='scss' scoped>
 | 
				
			||||||
 | 
					.gi-split-pane {
 | 
				
			||||||
 | 
					  flex: 1;
 | 
				
			||||||
 | 
					  display: flex;
 | 
				
			||||||
 | 
					  align-items: stretch;
 | 
				
			||||||
 | 
					  overflow: hidden;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  &__left,
 | 
				
			||||||
 | 
					  &__right {
 | 
				
			||||||
 | 
					    height: 100%;
 | 
				
			||||||
 | 
					    display: flex;
 | 
				
			||||||
 | 
					    flex-direction: column;
 | 
				
			||||||
 | 
					    position: relative;
 | 
				
			||||||
 | 
					    overflow: hidden;
 | 
				
			||||||
 | 
					    box-sizing: border-box;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  &__left {
 | 
				
			||||||
 | 
					    padding-right: $padding;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  &__right {
 | 
				
			||||||
 | 
					    flex: 1;
 | 
				
			||||||
 | 
					    padding-left: $padding;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  &__line {
 | 
				
			||||||
 | 
					    width: 1px;
 | 
				
			||||||
 | 
					    height: auto;
 | 
				
			||||||
 | 
					    background-color: var(--color-border-2);
 | 
				
			||||||
 | 
					    position: relative;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					</style>
 | 
				
			||||||
@@ -1,7 +1,7 @@
 | 
				
			|||||||
import type { TableData, TableInstance } from '@arco-design/web-vue'
 | 
					import type { TableData, TableInstance } from '@arco-design/web-vue'
 | 
				
			||||||
import { Message, Modal } from '@arco-design/web-vue'
 | 
					import { Message, Modal } from '@arco-design/web-vue'
 | 
				
			||||||
import type { Options as paginationOptions } from './usePagination'
 | 
					import type { Options as paginationOptions } from './usePagination'
 | 
				
			||||||
import { usePagination } from '@/hooks'
 | 
					import { useBreakpoint, usePagination } from '@/hooks'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
interface Options<T, U> {
 | 
					interface Options<T, U> {
 | 
				
			||||||
  formatResult?: (data: T[]) => U[]
 | 
					  formatResult?: (data: T[]) => U[]
 | 
				
			||||||
@@ -94,5 +94,32 @@ export function useTable<T extends U, U = T>(api: Api<T>, options?: Options<T, U
 | 
				
			|||||||
    })
 | 
					    })
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return { loading, tableData, getTableData, search, pagination, selectedKeys, select, selectAll, handleDelete, refresh }
 | 
					  const { breakpoint } = useBreakpoint()
 | 
				
			||||||
 | 
					  // 表格操作列在小屏下不固定在右侧
 | 
				
			||||||
 | 
					  const fixed = computed(() => !['xs', 'sm'].includes(breakpoint.value) ? 'right' : undefined)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return {
 | 
				
			||||||
 | 
					    /** 表格加载状态 */
 | 
				
			||||||
 | 
					    loading,
 | 
				
			||||||
 | 
					    /** 表格数据 */
 | 
				
			||||||
 | 
					    tableData,
 | 
				
			||||||
 | 
					    /** 获取表格数据 */
 | 
				
			||||||
 | 
					    getTableData,
 | 
				
			||||||
 | 
					    /** 搜索,页码会重置为1 */
 | 
				
			||||||
 | 
					    search,
 | 
				
			||||||
 | 
					    /** 分页的传参 */
 | 
				
			||||||
 | 
					    pagination,
 | 
				
			||||||
 | 
					    /** 选择的行keys */
 | 
				
			||||||
 | 
					    selectedKeys,
 | 
				
			||||||
 | 
					    /** 选择行 */
 | 
				
			||||||
 | 
					    select,
 | 
				
			||||||
 | 
					    /** 全选行 */
 | 
				
			||||||
 | 
					    selectAll,
 | 
				
			||||||
 | 
					    /** 处理删除、批量删除 */
 | 
				
			||||||
 | 
					    handleDelete,
 | 
				
			||||||
 | 
					    /** 刷新表格数据,页码会缓存 */
 | 
				
			||||||
 | 
					    refresh,
 | 
				
			||||||
 | 
					    /** 操作列在小屏场景下不固定在右侧 */
 | 
				
			||||||
 | 
					    fixed,
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -30,7 +30,7 @@
 | 
				
			|||||||
      </a-popover>
 | 
					      </a-popover>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      <!-- 全屏切换组件 -->
 | 
					      <!-- 全屏切换组件 -->
 | 
				
			||||||
      <a-tooltip v-if="!isMobile()" content="全屏切换" position="bottom">
 | 
					      <a-tooltip v-if="!['xs', 'sm'].includes(breakpoint)" content="全屏切换" position="bottom">
 | 
				
			||||||
        <a-button size="mini" class="gi_hover_btn" @click="toggle">
 | 
					        <a-button size="mini" class="gi_hover_btn" @click="toggle">
 | 
				
			||||||
          <template #icon>
 | 
					          <template #icon>
 | 
				
			||||||
            <icon-fullscreen v-if="!isFullscreen" :size="18" />
 | 
					            <icon-fullscreen v-if="!isFullscreen" :size="18" />
 | 
				
			||||||
@@ -76,10 +76,12 @@ import Message from './Message.vue'
 | 
				
			|||||||
import SettingDrawer from './SettingDrawer.vue'
 | 
					import SettingDrawer from './SettingDrawer.vue'
 | 
				
			||||||
import { getUnreadMessageCount } from '@/apis'
 | 
					import { getUnreadMessageCount } from '@/apis'
 | 
				
			||||||
import { useUserStore } from '@/stores'
 | 
					import { useUserStore } from '@/stores'
 | 
				
			||||||
import { isMobile } from '@/utils'
 | 
					 | 
				
			||||||
import { getToken } from '@/utils/auth'
 | 
					import { getToken } from '@/utils/auth'
 | 
				
			||||||
 | 
					import { useBreakpoint } from '@/hooks'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
defineOptions({ name: 'HeaderRight' })
 | 
					defineOptions({ name: 'HeaderRight' })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const { breakpoint } = useBreakpoint()
 | 
				
			||||||
let socket: WebSocket
 | 
					let socket: WebSocket
 | 
				
			||||||
onBeforeUnmount(() => {
 | 
					onBeforeUnmount(() => {
 | 
				
			||||||
  if (socket) {
 | 
					  if (socket) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
    <router-view v-slot="{ Component, route }">
 | 
					    <router-view v-slot="{ Component, route }">
 | 
				
			||||||
      <transition :name="appStore.transitionName" mode="out-in" appear>
 | 
					      <transition :name="appStore.transitionName" mode="out-in" appear>
 | 
				
			||||||
        <keep-alive :include="(tabsStore.cacheList as string[])">
 | 
					        <keep-alive :include="(tabsStore.cacheList as string[])">
 | 
				
			||||||
          <component :is="Component" :key="route.path + String(tabsStore.reloadFlag)" />
 | 
					          <component :is="Component" v-if="tabsStore.reloadFlag" :key="route.path" />
 | 
				
			||||||
        </keep-alive>
 | 
					        </keep-alive>
 | 
				
			||||||
      </transition>
 | 
					      </transition>
 | 
				
			||||||
    </router-view>
 | 
					    </router-view>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -57,15 +57,3 @@ a:hover {
 | 
				
			|||||||
  color: inherit;
 | 
					  color: inherit;
 | 
				
			||||||
  text-decoration: none;
 | 
					  text-decoration: none;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
.w-full {
 | 
					 | 
				
			||||||
  width: 100%;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.h-full {
 | 
					 | 
				
			||||||
  height: 100%;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.ov-hidden {
 | 
					 | 
				
			||||||
  overflow: hidden;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,22 @@
 | 
				
			|||||||
/* 全局样式 */
 | 
					/* 全局样式 */
 | 
				
			||||||
@import './var.scss';
 | 
					@import './var.scss';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.w-full {
 | 
				
			||||||
 | 
					  width: 100%;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.h-full {
 | 
				
			||||||
 | 
					  height: 100%;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.overflow-hidden {
 | 
				
			||||||
 | 
					  overflow: hidden;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.flex-1 {
 | 
				
			||||||
 | 
					  flex: 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 通用外边距
 | 
					// 通用外边距
 | 
				
			||||||
.gi_margin {
 | 
					.gi_margin {
 | 
				
			||||||
  margin: $margin;
 | 
					  margin: $margin;
 | 
				
			||||||
@@ -223,10 +240,12 @@
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.gi_table_box {
 | 
					// 表格类名 高度自适应
 | 
				
			||||||
  max-height: 100%;
 | 
					.gi_table {
 | 
				
			||||||
 | 
					  flex: 1;
 | 
				
			||||||
  overflow: hidden;
 | 
					  overflow: hidden;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.detail{
 | 
					.detail{
 | 
				
			||||||
  height: 100%;
 | 
					  height: 100%;
 | 
				
			||||||
  display: flex;
 | 
					  display: flex;
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										5
									
								
								src/types/components.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								src/types/components.d.ts
									
									
									
									
										vendored
									
									
								
							@@ -29,9 +29,14 @@ declare module 'vue' {
 | 
				
			|||||||
    GiForm: typeof import('./../components/GiForm/src/GiForm.vue')['default']
 | 
					    GiForm: typeof import('./../components/GiForm/src/GiForm.vue')['default']
 | 
				
			||||||
    GiIconSelector: typeof import('./../components/GiIconSelector/index.vue')['default']
 | 
					    GiIconSelector: typeof import('./../components/GiIconSelector/index.vue')['default']
 | 
				
			||||||
    GiIframe: typeof import('./../components/GiIframe/index.vue')['default']
 | 
					    GiIframe: typeof import('./../components/GiIframe/index.vue')['default']
 | 
				
			||||||
 | 
					    GiLeftRightPane: typeof import('./../components/GiLeftRightPane/index.vue')['default']
 | 
				
			||||||
    GiOption: typeof import('./../components/GiOption/index.vue')['default']
 | 
					    GiOption: typeof import('./../components/GiOption/index.vue')['default']
 | 
				
			||||||
    GiOptionItem: typeof import('./../components/GiOptionItem/index.vue')['default']
 | 
					    GiOptionItem: typeof import('./../components/GiOptionItem/index.vue')['default']
 | 
				
			||||||
    GiOverFlowTags: typeof import('./../components/GiOverFlowTags/index.vue')['default']
 | 
					    GiOverFlowTags: typeof import('./../components/GiOverFlowTags/index.vue')['default']
 | 
				
			||||||
 | 
					    GiSpace: typeof import('./../components/GiSpace/index.vue')['default']
 | 
				
			||||||
 | 
					    GiSplitButton: typeof import('./../components/GiSplitButton/index.vue')['default']
 | 
				
			||||||
 | 
					    GiSplitPane: typeof import('./../components/GiSplitPane/index.vue')['default']
 | 
				
			||||||
 | 
					    GiSplitPaneFlexibleBox: typeof import('./../components/GiSplitPane/components/GiSplitPaneFlexibleBox.vue')['default']
 | 
				
			||||||
    GiSvgIcon: typeof import('./../components/GiSvgIcon/index.vue')['default']
 | 
					    GiSvgIcon: typeof import('./../components/GiSvgIcon/index.vue')['default']
 | 
				
			||||||
    GiTable: typeof import('./../components/GiTable/index.vue')['default']
 | 
					    GiTable: typeof import('./../components/GiTable/index.vue')['default']
 | 
				
			||||||
    GiTag: typeof import('./../components/GiTag/index.tsx')['default']
 | 
					    GiTag: typeof import('./../components/GiTag/index.tsx')['default']
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,7 +11,7 @@
 | 
				
			|||||||
      </template>
 | 
					      </template>
 | 
				
			||||||
      <template #main>
 | 
					      <template #main>
 | 
				
			||||||
        <a-row align="stretch" :gutter="14" class="h-full page_content">
 | 
					        <a-row align="stretch" :gutter="14" class="h-full page_content">
 | 
				
			||||||
          <a-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" :xxl="24" flex="1" class="h-full ov-hidden">
 | 
					          <a-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" :xxl="24" flex="1" class="h-full overflow-hidden">
 | 
				
			||||||
            <GiTable
 | 
					            <GiTable
 | 
				
			||||||
              row-key="id"
 | 
					              row-key="id"
 | 
				
			||||||
              :data="dataList"
 | 
					              :data="dataList"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,9 +1,9 @@
 | 
				
			|||||||
<template>
 | 
					<template>
 | 
				
			||||||
  <a-row align="stretch" :gutter="14" class="file-manage">
 | 
					  <a-row align="stretch" :gutter="14" class="file-manage">
 | 
				
			||||||
    <a-col :xs="0" :sm="8" :md="7" :lg="6" :xl="5" :xxl="4" flex="220px" class="h-full ov-hidden">
 | 
					    <a-col :xs="0" :sm="8" :md="7" :lg="6" :xl="5" :xxl="4" flex="220px" class="h-full overflow-hidden">
 | 
				
			||||||
      <FileAside></FileAside>
 | 
					      <FileAside></FileAside>
 | 
				
			||||||
    </a-col>
 | 
					    </a-col>
 | 
				
			||||||
    <a-col :xs="24" :sm="16" :md="17" :lg="18" :xl="19" :xxl="20" flex="1" class="h-full ov-hidden">
 | 
					    <a-col :xs="24" :sm="16" :md="17" :lg="18" :xl="19" :xxl="20" flex="1" class="h-full overflow-hidden">
 | 
				
			||||||
      <FileMain></FileMain>
 | 
					      <FileMain></FileMain>
 | 
				
			||||||
    </a-col>
 | 
					    </a-col>
 | 
				
			||||||
  </a-row>
 | 
					  </a-row>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,7 +11,7 @@
 | 
				
			|||||||
      </template>
 | 
					      </template>
 | 
				
			||||||
      <template #main>
 | 
					      <template #main>
 | 
				
			||||||
        <a-row align="stretch" :gutter="14" class="h-full page_content">
 | 
					        <a-row align="stretch" :gutter="14" class="h-full page_content">
 | 
				
			||||||
          <a-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" :xxl="24" class="h-full ov-hidden">
 | 
					          <a-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" :xxl="24" class="h-full overflow-hidden">
 | 
				
			||||||
            <GiTable
 | 
					            <GiTable
 | 
				
			||||||
              row-key="id"
 | 
					              row-key="id"
 | 
				
			||||||
              :data="dataList"
 | 
					              :data="dataList"
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user