소스 검색

合并组件

XueNing 5 달 전
부모
커밋
17de638448

+ 1 - 1
package.json

@@ -15,7 +15,7 @@
   },
   "dependencies": {
     "@element-plus/icons-vue": "^2.3.1",
-    "@fskj-admin/core": "^1.2.14",
+    "@fskj-admin/core": "^1.3.1",
     "@fskj-admin/micro": "^0.1.0",
     "@icon-park/vue-next": "^1.4.2",
     "@sentry/vue": "^8.9.2",

+ 5 - 5
pnpm-lock.yaml

@@ -12,8 +12,8 @@ importers:
         specifier: ^2.3.1
         version: 2.3.1(vue@3.4.29(typescript@5.3.3))
       '@fskj-admin/core':
-        specifier: ^1.2.14
-        version: 1.2.14
+        specifier: ^1.3.1
+        version: 1.3.1
       '@fskj-admin/micro':
         specifier: ^0.1.0
         version: 0.1.0
@@ -535,8 +535,8 @@ packages:
   '@floating-ui/utils@0.2.2':
     resolution: {integrity: sha512-J4yDIIthosAsRZ5CPYP/jQvUAQtlZTTD/4suA08/FEnlxqW3sKS9iAhgsa9VYLZ6vDHn/ixJgIqRQPotoBjxIw==}
 
-  '@fskj-admin/core@1.2.14':
-    resolution: {integrity: sha512-L/W/b4Ik81iOZSYdN0YExw3wCLq16d4NsggeZGHKFRzRLKBhKTD8GVNCf+yNYMJSZH6tlXRW2IXoc/fPfU67pA==}
+  '@fskj-admin/core@1.3.1':
+    resolution: {integrity: sha512-8ZGO75r5rdAttCSCLUAvXm468di9WlV2MQxG3DA4gibZS679T6sRHiDiv+Sk3xRMDJ8hi4Ngi1LQAyxwkS/Egg==}
 
   '@fskj-admin/micro@0.1.0':
     resolution: {integrity: sha512-4Dbg7mubKcDu+jaqll+oY6/7v08h9mh9BTncVkEHd9T4Aqg8ZzcCASaKvrCPhP6/ldgUBrM0MimmzJh0geVXnQ==}
@@ -4620,7 +4620,7 @@ snapshots:
 
   '@floating-ui/utils@0.2.2': {}
 
-  '@fskj-admin/core@1.2.14': {}
+  '@fskj-admin/core@1.3.1': {}
 
   '@fskj-admin/micro@0.1.0': {}
 

+ 4 - 6
src/components.d.ts

@@ -17,16 +17,14 @@ declare module 'vue' {
     ElEmployees: typeof import('./components/form/ElEmployees.vue')['default']
     Exception: typeof import('./components/Exception.vue')['default']
     FsCheckCard: typeof import('./components/FsCheckCard/index.vue')['default']
-    FsCity: typeof import('./components/FsCity/index.vue')['default']
+    FsCity: (typeof import('./components/FsCity/index.vue'))['default']
     FsCitySelect: typeof import('./components/FsCitySelect/index.vue')['default']
-    FsDot: typeof import('./components/FsDot/index.vue')['default']
-    FsImageUpload: typeof import('./components/FsImageUpload/index.vue')['default']
-    FsMap: typeof import('./components/FsMap/index.vue')['default']
+    FsImageUpload: (typeof import('./components/FsImageUpload/index.vue'))['default']
+    FsMap: (typeof import('./components/FsMap/index.vue'))['default']
     FsMapPicker: typeof import('./components/FsMapPicker/index.vue')['default']
     FsPrinter: typeof import('./components/FsPrinter/index.vue')['default']
-    FsSplitPanel: typeof import('./components/FsSplitPanel/index.vue')['default']
     FsTableSelect: typeof import('./components/FsTableSelect/index.vue')['default']
-    FsText: typeof import('./components/FsText/index.vue')['default']
+    FsText: (typeof import('./components/FsText/index.vue'))['default']
     FsTour: typeof import('./components/FsTour/index.vue')['default']
     GlobalAside: typeof import('./components/core/GlobalAside.vue')['default']
     GlobalFooter: typeof import('./components/core/GlobalFooter.vue')['default']

+ 0 - 76
src/components/FsDot/index.vue

@@ -1,76 +0,0 @@
-<script setup lang="ts">
-import type { TextProps } from './props'
-
-const props = withDefaults(defineProps<TextProps>(), {
-  type: 'primary',
-  ripple: true,
-  size: '8px'
-})
-
-const bgColor = computed(() => {
-  return props.color || `var(--el-color-${props.type})`
-})
-</script>
-
-<!-- 状态点 -->
-<template>
-  <span :class="['dot', { 'is-ripple': ripple }]">
-    <span class="dot-status" :style="{ width: size, height: size }">
-      <span class="dot-ripple" :style="{ width: size, height: size }"></span>
-    </span>
-    <span v-if="text" class="dot-text" :style="fontStyle"> {{ text }}</span>
-  </span>
-</template>
-
-<style scoped lang="scss">
-.dot {
-  display: inline-flex;
-  align-items: center;
-
-  .dot-text {
-    flex-shrink: 0;
-    margin-left: 8px;
-  }
-
-  .dot-status {
-    flex-shrink: 0;
-    background: var(--el-color-primary);
-    border-radius: 50%;
-    position: relative;
-  }
-
-  .dot-ripple {
-    position: absolute;
-    top: 0;
-    left: 0;
-    width: 100%;
-    height: 100%;
-    background: var(--el-color-primary);
-    animation: animDot 1.2s ease-in-out infinite;
-    transform-origin: center;
-    border-radius: 50%;
-    display: none;
-  }
-
-  &.is-ripple .dot-ripple {
-    display: block;
-  }
-
-  .dot-status,
-  .dot-ripple {
-    background: v-bind('bgColor');
-  }
-}
-
-@keyframes animDot {
-  from {
-    transform: scale(0.8);
-    opacity: 0.6;
-  }
-
-  to {
-    transform: scale(2.4);
-    opacity: 0;
-  }
-}
-</style>

+ 0 - 16
src/components/FsDot/props.ts

@@ -1,16 +0,0 @@
-import type { StyleValue } from 'vue'
-
-export interface TextProps {
-  //  类型
-  type?: 'primary' | 'success' | 'warning' | 'danger' | 'info'
-  // 自定义颜色
-  color?: string
-  // 是否显示水波动画
-  ripple?: boolean
-  // 文本
-  text?: string
-  // 尺寸
-  size?: string
-  // 文字样式
-  fontStyle?: StyleValue
-}

+ 0 - 310
src/components/FsImageUpload/index.vue

@@ -1,310 +0,0 @@
-<script setup lang="ts">
-import { ElMessage } from 'element-plus'
-import type { ImageUploadProps } from './props'
-import { imageUploadEmits } from './props'
-import type { UploadItem } from './types'
-import { uuid } from '@/utils/utils'
-import axios, { type AxiosProgressEvent } from 'axios'
-
-const emits = defineEmits(imageUploadEmits)
-
-const props = withDefaults(defineProps<ImageUploadProps>(), {
-  fileName: 'file',
-  autoUpload: true,
-  preview: true,
-  limit: 9,
-  fileSize: 5,
-  iconSize: 28
-})
-
-const images = ref<UploadItem[]>([])
-
-// 是否可上传
-const isUpload = computed<boolean>(() => {
-  return (
-    !props.disabled &&
-    !(typeof props.limit === 'number' && props.limit > 0 && images.value != null && images.value.length >= props.limit)
-  )
-})
-
-// 检查图片是否全部上传完毕
-const checkUpload = () => {
-  return images.value.length == 0 || (images.value.length && !images.value.some(x => x.status != 'success'))
-}
-
-// 预览图片列表
-const previewList = computed(() => {
-  if (!props.preview) {
-    return []
-  }
-  return images.value?.map(x => x.url) || []
-})
-
-/* 选择文件 */
-const onUpload = (file: File) => {
-  if (!isUpload.value || props.disabled) {
-    return false
-  }
-  if (!file.type.startsWith('image')) {
-    ElMessage.error('只能选择图片')
-    return false
-  }
-  if (file.size / 1024 / 1024 > props.fileSize) {
-    ElMessage.error(`大小不能超过 ${props.fileSize}MB`)
-    return false
-  }
-
-  const item: UploadItem = {
-    key: uuid(),
-    name: file.name,
-    status: void 0,
-    progress: 0,
-    file
-  }
-  item.url = window.URL.createObjectURL(file)
-
-  images.value.push(item)
-  // 是否自动上传
-  if (props.autoUpload) {
-    // 自动上传最后一个文件
-    uploadItem(images.value.at(-1) as UploadItem)
-  }
-  return false
-}
-
-/* 上传文件 */
-const uploadItem = (item: UploadItem) => {
-  if (!props.action && typeof props.uploadFunction != 'function') {
-    console.log('请传入action路径或者uploadFunction上传方法')
-    return false
-  }
-  // 如果配置了上传路径,TODO:awint
-  if (props.action) {
-    const formData = new FormData()
-    formData.append(props.fileName, item.file as File)
-    axios
-      .post(props.action, formData, {
-        onUploadProgress: (e: AxiosProgressEvent) => {
-          if (e.total != null) {
-            item.progress = (e.loaded / e.total) * 100
-          }
-        }
-      })
-      .then(res => {
-        item.status = 'success'
-        item.url = res.data
-      })
-      .catch(() => {
-        item.status = 'danger'
-      })
-  } else {
-    // 自定义方法上传
-    if (typeof props.uploadFunction != 'function') return false
-    ;(props.uploadFunction as Function)(item)
-  }
-}
-
-/* 手动上传文件 */
-const submit = () => {
-  if (images.value.length) {
-    images.value.forEach(item => {
-      item.status != 'success' && uploadItem(item)
-    })
-  }
-}
-
-/* 删除图片 */
-const onRemove = (index: number) => {
-  emits('remove', images.value[index])
-  images.value.splice(index, 1)
-}
-
-/* 重新上传 */
-const onRetry = (index: number) => {
-  uploadItem(images.value[index])
-}
-
-/* 修改modelValue */
-const updateModelValue = (items: any) => {
-  emits('update:modelValue', items.map((x: UploadItem) => x.url).join(',') || '')
-}
-
-watch(
-  () => props.modelValue,
-  () => {
-    // 判断modelValue存不存在,存在就是成功,不存在就没有
-    if (props.modelValue && props.modelValue != undefined) {
-      // 传进来的数据转换成内部需要数据
-      const formatData = typeof props.modelValue === 'string' ? props.modelValue.split(',').filter(x => x) : []
-      const datas: UploadItem[] = formatData.map((x: string) => {
-        return {
-          key: uuid(),
-          url: x,
-          status: 'success',
-          name: x.split('/').pop()
-        }
-      })
-      images.value = datas
-    }
-  },
-  { immediate: true }
-)
-
-watch(
-  images,
-  () => {
-    updateModelValue(images.value)
-  },
-  {
-    deep: true
-  }
-)
-
-defineExpose({
-  checkUpload,
-  submit
-})
-</script>
-
-<template>
-  <div class="upload-container">
-    <div class="upload-image" v-for="(item, index) in images" :key="item.key">
-      <el-image :src="item.url" :preview-src-list="previewList" :initial-index="index" fit="cover"></el-image>
-      <div v-if="!disabled" class="upload-remove" @click.stop="onRemove(index)">
-        <el-icon size="14">
-          <Close />
-        </el-icon>
-      </div>
-      <div v-if="item.status === 'uploading' || item.status === 'danger'" class="upload-progress">
-        <slot name="progress" :item="item">
-          <div class="upload-text">
-            {{ item.status == 'danger' ? '上传失败' : '上传中' }}
-          </div>
-          <el-progress
-            :showText="false"
-            v-bind="progressProps || {}"
-            :percentage="item.progress"
-            :status="item.status === 'danger' ? 'exception' : void 0"
-          />
-          <div v-if="!disabled">
-            <div v-if="item.status === 'danger'" class="upload-retry" @click.stop="onRetry(index)">
-              <el-icon>
-                <Refresh />
-              </el-icon>
-            </div>
-          </div>
-        </slot>
-      </div>
-    </div>
-    <div>
-      <el-upload
-        action=""
-        accept="image/*"
-        :multiple="multiple"
-        :disabled="disabled"
-        :show-file-list="false"
-        :beforeUpload="onUpload"
-        :drag="drag"
-        v-if="isUpload"
-      >
-        <div class="upload-plus">
-          <el-icon :size="iconSize">
-            <Plus />
-          </el-icon>
-        </div>
-      </el-upload>
-    </div>
-  </div>
-</template>
-
-<style lang="scss" scoped>
-.upload-container {
-  display: flex;
-  flex-wrap: wrap;
-  .upload-image {
-    position: relative;
-    width: 100px;
-    height: 100px;
-    border: 1px dashed #dcdfe6;
-    border-radius: var(--el-border-radius-base);
-    overflow: hidden;
-    margin: 0px 8px 8px 0;
-    cursor: pointer;
-    .upload-remove {
-      width: 20px;
-      height: 20px;
-      display: flex;
-      justify-content: center;
-      align-items: center;
-      position: absolute;
-      right: 0px;
-      top: 0px;
-      background-color: rgba($color: #000000, $alpha: 0.3);
-      color: #fff;
-      border-radius: 0px 0px 0px var(--el-border-radius-round);
-      z-index: 9;
-      &:hover {
-        background-color: var(--el-color-danger);
-      }
-      .el-icon {
-        margin-top: -5px;
-        margin-left: 2px;
-      }
-    }
-    .upload-progress {
-      position: absolute;
-      width: 100%;
-      height: 100%;
-      left: 0px;
-      top: 0px;
-      display: flex;
-      flex-direction: column;
-      justify-content: center;
-      padding: 10px;
-      background-color: rgba($color: #000000, $alpha: 0.4);
-      color: #fff;
-      box-sizing: border-box;
-      .upload-text {
-        text-align: center;
-        margin-bottom: 3px;
-        font-size: 12px;
-      }
-      .upload-retry {
-        text-align: center;
-        margin-top: 5px;
-      }
-    }
-    .el-image {
-      width: 100%;
-      height: 100%;
-    }
-  }
-  .upload-plus {
-    width: 100px;
-    height: 100px;
-    display: flex;
-    justify-content: center;
-    align-items: center;
-    color: var(--el-color-info);
-    border: 1px dashed #dcdfe6;
-    border-radius: var(--el-border-radius-base);
-    &:not(.disabled):hover {
-      border-color: var(--el-color-primary);
-    }
-  }
-  :deep(.el-upload-dragger) {
-    width: auto;
-    height: auto;
-    padding: 0px;
-    margin: 0px;
-    border-color: transparent;
-    border-width: 0px;
-    border-radius: 0px;
-    background-color: transparent;
-    &.is-dragover {
-      outline: 1px dashed var(--el-color-primary);
-      background-color: var(--el-color-primary-light-9);
-    }
-  }
-}
-</style>

+ 0 - 47
src/components/FsImageUpload/props.ts

@@ -1,47 +0,0 @@
-/* eslint-disable @typescript-eslint/no-unused-vars */
-import type { CSSProperties } from 'vue'
-import type { UploadItem } from './types'
-import type { ProgressProps } from 'element-plus'
-
-// 传入属性
-export interface ImageUploadProps {
-  // 已上传的列表
-  modelValue: string
-  // 上传路径
-  action?: string
-  fileName?: string
-  // 是否自动上传
-  autoUpload?: boolean
-  // 是否启用拖拽上传
-  drag?: boolean
-  // 是否禁用
-  disabled?: boolean
-  // 是否点击预览
-  preview?: boolean
-  // 上传数量
-  limit?: number
-  // 是否可以多选
-  multiple?: boolean
-  // 文件大小限制(MB)
-  fileSize?: number
-  // 宽度
-  width?: number | string
-  // 高度
-  height?: number | string
-  // 图标大小
-  iconSize?: number
-  // 进度条配置
-  progressProps?: ProgressProps
-  // 上传方法
-  uploadFunction?: (file: any) => Promise<any>
-}
-
-/* 事件 */
-export const imageUploadEmits = {
-  // 上传事件
-  upload: (_value: UploadItem) => true,
-  // 单个删除事件
-  remove: (_value: UploadItem) => true,
-  // 修改modelValue
-  'update:modelValue': (_value: UploadItem[]) => true
-}

+ 0 - 20
src/components/FsImageUpload/types/index.ts

@@ -1,20 +0,0 @@
-export interface UploadItem extends Record<keyof any, any> {
-  // 唯一标识
-  key: string | number | symbol
-  // 显示的图片地址
-  url?: string
-  // 文件名称
-  name?: string
-  // 上传状态
-  status?: UploadStatus
-  // 上传进度
-  progress?: number
-  /**  */
-  // 上传文件
-  file?: File
-}
-
-/**
- * 上传状态
- */
-export type UploadStatus = 'uploading' | 'success' | 'danger' | null

+ 0 - 490
src/components/FsSplitPanel/index.vue

@@ -1,490 +0,0 @@
-<script setup lang="ts">
-import type { SplitPanelProps } from './props'
-import { splitPanelEmits } from './props'
-
-const props = withDefaults(defineProps<SplitPanelProps>(), {})
-const emits = defineEmits(splitPanelEmits)
-
-// 根节点
-const rootRef = ref<HTMLElement | null>(null)
-
-// 侧边容器节点
-const wrapRef = ref<HTMLElement | null>(null)
-
-// 侧边节点
-const sideRef = ref<HTMLElement | null>(null)
-
-// 是否折叠
-const isCollapse = ref<boolean>(false)
-
-// 拉伸后尺寸
-const resizedSize = ref<string | null>(null)
-
-// 是否正在拉伸
-const resizing = ref<boolean>(false)
-
-/* 切换折叠状态 */
-const toggleCollapse = (collapse?: boolean) => {
-  isCollapse.value = typeof collapse === 'boolean' ? collapse : !isCollapse.value
-  emits('update:collapse', isCollapse.value)
-}
-
-/* 获取最大拉伸尺寸 */
-const getMaxSize = (el: HTMLElement) => {
-  const size = props.vertical ? el.clientHeight : el.clientWidth
-  if (!props.maxSize) {
-    return size
-  }
-  if (props.maxSize < 0) {
-    // 负值形式
-    return size + props.maxSize
-  } else if (props.maxSize < 1) {
-    // 百分比形式
-    return Math.floor(size * props.maxSize)
-  }
-  return Math.min(props.maxSize, size)
-}
-
-/* 拉伸 */
-const onResize = (event: MouseEvent) => {
-  const rootEl = rootRef.value
-  const sideEl = sideRef.value
-  if (!rootEl || !sideEl) {
-    return
-  }
-  resizing.value = true
-  // 获取原始位置
-  const downX = event.clientX
-  const downY = event.clientY
-  const downW = sideEl.clientWidth
-  const downH = sideEl.clientHeight
-  const limitMin = props.minSize || 0
-  const limitMax = getMaxSize(rootEl)
-
-  // 鼠标移动事件
-  const mousemoveFn = (e: MouseEvent) => {
-    const size = props.vertical
-      ? (props.reverse ? downY - e.clientY : e.clientY - downY) + downH
-      : (props.reverse ? downX - e.clientX : e.clientX - downX) + downW
-    resizedSize.value = (size < limitMin ? limitMin : size > limitMax ? limitMax : size) + 'px'
-  }
-
-  // 鼠标抬起事件
-  const mouseupFn = () => {
-    resizing.value = false
-    document.removeEventListener('mousemove', mousemoveFn)
-    document.removeEventListener('mouseup', mouseupFn)
-  }
-
-  // 添加鼠标事件监听
-  document.addEventListener('mousemove', mousemoveFn)
-  document.addEventListener('mouseup', mouseupFn)
-}
-
-watch(
-  [() => props.collapse, () => props.allowCollapse],
-  () => {
-    if (!props.allowCollapse) {
-      isCollapse.value = false
-    } else {
-      isCollapse.value = props.collapse
-    }
-  },
-  { immediate: true }
-)
-</script>
-
-<template>
-  <div
-    ref="rootRef"
-    :class="[
-      'split-panel',
-      { 'is-reverse': reverse },
-      { 'is-vertical': vertical },
-      { 'is-collapse': isCollapse },
-      { 'is-resizing': resizing }
-    ]"
-    :style="{
-      '--split-size': resizedSize ?? size,
-      '--split-space': space
-    }"
-  >
-    <!-- 侧边容器 -->
-    <div ref="wrapRef" class="split-panel-wrap">
-      <div ref="sideRef" class="split-panel-side" :style="customStyle">
-        <slot></slot>
-      </div>
-      <!-- 间距 -->
-      <div class="split-panel-space">
-        <div v-if="resizable" class="split-resize-line" @mousedown="onResize"></div>
-      </div>
-    </div>
-    <!-- 内容 -->
-    <div class="split-panel-body" :style="bodyStyle">
-      <slot name="body" :collapse="isCollapse"></slot>
-    </div>
-    <!-- 折叠按钮 -->
-    <div v-if="allowCollapse" :style="collapseStyle" class="split-collapse-button" @click="toggleCollapse()">
-      <slot name="collapse" :collapse="isCollapse">
-        <ElIcon class="split-collapse-icon">
-          <ArrowUp v-if="vertical" />
-          <ArrowLeft v-else />
-        </ElIcon>
-      </slot>
-    </div>
-    <!-- 小屏幕遮罩层 -->
-    <div class="split-panel-mask" @click="toggleCollapse()"></div>
-  </div>
-</template>
-
-<style scoped lang="scss">
-.split-panel {
-  display: flex;
-  position: relative;
-  --split-size: 200px;
-  --split-space: 16px;
-
-  // 侧边容器
-  & > .split-panel-wrap {
-    flex-shrink: 0;
-    box-sizing: border-box;
-    width: calc(var(--split-size) + var(--split-space));
-    display: flex;
-    justify-content: flex-end;
-    transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
-    opacity: 1;
-
-    // 侧边
-    & > .split-panel-side {
-      flex-shrink: 0;
-      width: var(--split-size);
-      border: 1px solid var(--el-border-color-light);
-      box-sizing: border-box;
-      position: relative;
-    }
-
-    // 间距
-    & > .split-panel-space {
-      flex-shrink: 0;
-      width: var(--split-space);
-      box-sizing: border-box;
-      position: relative;
-
-      // 拉伸线
-      .split-resize-line {
-        width: 12px;
-        height: 100%;
-        position: absolute;
-        left: -6px;
-        z-index: 4;
-        cursor: e-resize;
-
-        &::after {
-          content: '';
-          width: 3px;
-          height: 100%;
-          display: block;
-          margin: 0 auto;
-        }
-
-        &:hover::after {
-          background: var(--el-color-primary);
-        }
-      }
-    }
-  }
-
-  // 内容
-  & > .split-panel-body {
-    flex: 1;
-    overflow: auto;
-    box-sizing: border-box;
-    position: relative;
-  }
-
-  // 折叠按钮
-  & > .split-collapse-button {
-    width: 24px;
-    height: 24px;
-    line-height: 24px;
-    text-align: center;
-    position: absolute;
-    left: var(--split-size);
-    top: 50%;
-    margin: -12px 0 0 -12px;
-    background: var(--el-bg-color-overlay);
-    box-shadow: 0 2px 3px 0px rgba(0, 0, 0, 0.04);
-    border: 1px solid var(--el-border-color-light);
-    transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
-    border-radius: 50%;
-    cursor: pointer;
-    z-index: 5;
-
-    .split-collapse-icon {
-      font-size: 16px;
-      vertical-align: -2px;
-      color: var(--el-color-info);
-      font-weight: bold;
-      transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
-      transform: scaleX(1);
-    }
-
-    &:hover .split-collapse-icon {
-      color: var(--el-color-primary);
-    }
-  }
-
-  // 折叠状态
-  &.is-collapse {
-    & > .split-panel-wrap {
-      width: 0 !important;
-      pointer-events: none;
-      opacity: 0;
-    }
-
-    & > .split-collapse-button {
-      left: 0;
-
-      .split-collapse-icon {
-        transform: scaleX(-1);
-      }
-    }
-  }
-
-  // 垂直
-  &.is-vertical {
-    flex-direction: column;
-
-    & > .split-panel-wrap {
-      flex-direction: column;
-      height: calc(var(--split-size) + var(--split-space));
-      width: auto;
-
-      & > .split-panel-side {
-        height: var(--split-size);
-        width: auto;
-      }
-
-      & > .split-panel-space {
-        height: var(--split-space);
-        width: auto;
-
-        .split-resize-line {
-          width: 100%;
-          height: 12px;
-          left: auto;
-          top: -6px;
-          cursor: n-resize;
-
-          &::after {
-            width: 100%;
-            height: 3px;
-            margin: 4px 0 0 0;
-          }
-        }
-      }
-    }
-
-    & > .split-collapse-button {
-      top: var(--split-size);
-      left: 50%;
-
-      .split-collapse-icon {
-        transform: scaleY(1);
-      }
-    }
-
-    &.is-collapse {
-      & > .split-panel-wrap {
-        width: auto !important;
-        height: 0 !important;
-      }
-
-      & > .split-collapse-button {
-        top: 0;
-
-        .split-collapse-icon {
-          transform: scaleY(-1);
-        }
-      }
-    }
-  }
-
-  // 反向
-  &.is-reverse {
-    flex-direction: row-reverse;
-
-    & > .split-panel-wrap {
-      flex-direction: row-reverse;
-
-      & > .split-panel-space .split-resize-line {
-        left: auto;
-        right: -6px;
-      }
-    }
-
-    & > .split-collapse-button {
-      left: auto;
-      right: var(--split-size);
-      margin: -12px -12px 0 0;
-
-      .split-collapse-icon {
-        transform: scaleX(-1);
-      }
-    }
-
-    &.is-collapse > .split-collapse-button {
-      right: 0;
-
-      .split-collapse-icon {
-        transform: scaleX(1);
-      }
-    }
-
-    &.is-vertical {
-      flex-direction: column-reverse;
-
-      & > .split-panel-wrap {
-        flex-direction: column-reverse;
-
-        & > .split-panel-space .split-resize-line {
-          top: auto;
-          right: auto;
-          bottom: -6px;
-        }
-      }
-
-      & > .split-collapse-button {
-        left: 50%;
-        top: auto;
-        bottom: var(--split-size);
-        margin: 0 0 -12px -12px;
-
-        .split-collapse-icon {
-          transform: scaleY(-1);
-        }
-      }
-
-      &.is-collapse > .split-collapse-button {
-        bottom: 0;
-
-        .split-collapse-icon {
-          transform: scaleY(1);
-        }
-      }
-    }
-  }
-
-  // 拉伸状态
-  &.is-resizing {
-    user-select: none;
-
-    & > .split-panel-wrap,
-    & > .split-collapse-button {
-      transition: none;
-    }
-  }
-
-  // 遮罩层
-  .split-panel-mask {
-    position: absolute;
-    top: 0;
-    left: 0;
-    right: 0;
-    bottom: 0;
-    opacity: 0;
-    backdrop-filter: blur(6px);
-    background: rgba(158, 158, 158, 0.2);
-    transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
-    pointer-events: none;
-    display: none;
-    z-index: 2;
-  }
-
-  // 内部表格弹性布局
-  &.is-flex-table {
-    flex: 1;
-    overflow: auto;
-
-    & > .split-panel-body,
-    & > .split-panel-wrap > .split-panel-side {
-      display: flex;
-      flex-direction: column;
-
-      & > .pro-table {
-        flex: 1;
-        display: flex;
-        flex-direction: column;
-        overflow: auto;
-
-        & > .el-table {
-          flex: 1;
-          height: 100%;
-        }
-      }
-    }
-  }
-}
-
-/* 小屏幕样式 */
-@media screen and (max-width: 768px) {
-  .split-panel.is-responsive:not(.is-vertical) {
-    &:not(.is-collapse) {
-      overflow: hidden !important;
-    }
-
-    & > .split-panel-wrap {
-      position: absolute;
-      top: 0;
-      left: 0;
-      bottom: 0;
-
-      & > .split-panel-side {
-        background: var(--el-bg-color-overlay);
-        border: none;
-        z-index: 3;
-      }
-    }
-
-    & > .split-panel-body {
-      transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
-    }
-
-    & > .split-panel-mask {
-      display: block;
-    }
-
-    &:not(.is-collapse) {
-      & > .split-panel-mask {
-        left: var(--split-size);
-        pointer-events: all;
-        opacity: 1;
-      }
-
-      & > .split-panel-body {
-        transform: translateX(calc(var(--split-size) + var(--split-space)));
-        z-index: 1;
-      }
-    }
-
-    // 反向
-    &.is-reverse {
-      & > .split-panel-wrap {
-        right: 0;
-        left: auto;
-      }
-
-      &:not(.is-collapse) {
-        & > .split-panel-mask {
-          left: 0;
-          right: var(--split-size);
-        }
-
-        & > .split-panel-body {
-          transform: translateX(calc(0px - var(--split-size) - var(--split-space)));
-        }
-      }
-    }
-  }
-}
-</style>

+ 0 - 38
src/components/FsSplitPanel/props.ts

@@ -1,38 +0,0 @@
-/* eslint-disable @typescript-eslint/no-unused-vars */
-
-import type { CSSProperties } from 'vue'
-
-export interface SplitPanelProps {
-  // 默认大小
-  size?: string
-  // 最小尺寸
-  minSize?: number
-  // 最大尺寸
-  maxSize?: number
-  // 间距
-  space?: string
-  // 自定义样式
-  customStyle?: Partial<CSSProperties> | Array<Partial<CSSProperties>>
-  // 自定义内容样式
-  bodyStyle?: Partial<CSSProperties> | Array<Partial<CSSProperties>>
-  // 是否可折叠
-  allowCollapse?: boolean
-  // 折叠按钮样式
-  collapseStyle?: Record<string, any>
-  // 是否折叠
-  collapse?: boolean
-  // 是否垂直方向
-  vertical?: boolean
-  // 是否反向布局
-  reverse?: boolean
-  // 是否可拉伸宽度
-  resizable?: boolean
-}
-
-/**
- * 事件
- */
-export const splitPanelEmits = {
-  // 更新折叠状态
-  'update:collapse': (_collapse: boolean) => true
-}

+ 33 - 0
src/config/uploadConfig.ts

@@ -0,0 +1,33 @@
+import request from '@/utils/request'
+import { uuid } from '@/utils/utils'
+
+const uploadApi = '/common/upload'
+
+export default {
+  uploadApi,
+  basePath: import.meta.env.VITE_BASE_PATH,
+  uploadFunc: (file: any, onUploadProgress: any): Promise<any> => {
+    const formData = new FormData()
+    formData.append('file', file)
+
+    return request
+      .post(uploadApi, formData, {
+        onUploadProgress
+      })
+      .then((res: any) => {
+        return { data: res.data }
+      })
+  },
+  transformData: (data: string) => {
+    // 将逗号分隔的字符串转换为数组
+    return data
+      .split(',')
+      .filter((item: string) => item)
+      .map(x => ({
+        key: uuid(),
+        url: x,
+        status: 'success',
+        name: x.split('/').pop()
+      }))
+  }
+}

+ 4 - 7
src/main.ts

@@ -64,7 +64,9 @@ import router from './router'
 import './assets/main.css'
 import 'virtual:svg-icons-register'
 
-import { ossUpload } from '@/utils/utils'
+import uploadConfig from './config/uploadConfig'
+
+// import { ossUpload } from '@/utils/utils'
 
 // import WujieVue from 'wujie-vue3'
 
@@ -117,12 +119,7 @@ app.use(router)
 app.use(ElementPlus)
 app.use(useTable)
 app.use(FsAdminCore, {
-  upload: {
-    oss: true,
-    ossHost: '',
-    ossUpload,
-    baseApi: import.meta.env.VITE_BASE_API
-  }
+  upload: uploadConfig
 })
 // app.use(WujieVue)
 app.use(directives)

+ 0 - 1
src/views/extension/checkCard/index.vue

@@ -1,5 +1,4 @@
 <script setup lang="ts">
-import FsCheckCard from '@/components/FsCheckCard/index.vue'
 import type { CheckCardItem } from '@/components/FsCheckCard/types'
 
 const select = ref('React')

+ 1 - 1
src/views/extension/excel/export.vue

@@ -77,7 +77,7 @@ const exportFile = () => {
   })
   exportExcel(excelParams)
     .then(() => {
-      console.log()
+      ElMessage.success('导出成功')
     })
     .catch(e => {
       ElMessage.error(e.message)

+ 3 - 4
src/views/extension/imageUpload/index.vue

@@ -1,6 +1,5 @@
 <script setup lang="ts">
 import { ElMessage } from 'element-plus'
-import FsImageUpload from '@/components/FsImageUpload/index.vue'
 import config from '@/config/defaultSetting'
 const images = ref('')
 // 手动上传数据
@@ -43,7 +42,7 @@ const submit = () => {
 
 <template>
   <el-card header="基础示例" shadow="never">
-    <fs-image-upload
+    <el-image-upload
       v-model="images"
       :limit="5"
       :uploadFunction="uploadFunction"
@@ -64,10 +63,10 @@ const submit = () => {
     </div>
   </el-card>
   <el-card header="支持多选" shadow="never" class="mt-3">
-    <fs-image-upload v-model="images2" multiple :limit="5" :uploadFunction="uploadFunction" @remove="onRemove" />
+    <el-image-upload v-model="images2" multiple :limit="5" :uploadFunction="uploadFunction" @remove="onRemove" />
   </el-card>
   <el-card header="基础示例" shadow="never" class="mt-3">
-    <fs-image-upload
+    <el-image-upload
       v-model="images3"
       :auto-upload="false"
       :limit="5"

+ 15 - 17
src/views/extension/splitePanel/index.vue

@@ -1,17 +1,15 @@
-<script setup>
-import FsSplitPanel from '@/components/FsSplitPanel/index.vue'
-
+<script setup lang="ts">
 // 是否显示折叠按钮
-const allowCollapse = ref(true)
+const allowCollapse = ref<boolean>(true)
 
 // 是否支持自由拉伸
-const resizable = ref(false)
+const resizable = ref<boolean>(true)
 
 // 是否上下布局模式
-const vertical = ref(false)
+const vertical = ref<boolean>(false)
 
 // 是否反转布局方向
-const reverse = ref(false)
+const reverse = ref<boolean>(false)
 </script>
 
 <template>
@@ -42,7 +40,7 @@ const reverse = ref(false)
         </el-radio-group>
       </el-form-item>
     </el-form>
-    <fs-split-panel
+    <el-split-panel
       space="0px"
       size="160px"
       :allow-collapse="allowCollapse"
@@ -57,11 +55,11 @@ const reverse = ref(false)
       <template #body>
         <div>内容</div>
       </template>
-    </fs-split-panel>
+    </el-split-panel>
   </el-card>
   <el-card shadow="never" class="mt-5">
     <div style="margin: 0 0 8px 0">先左右再上下</div>
-    <fs-split-panel
+    <el-split-panel
       space="0px"
       :min-size="40"
       :max-size="-40"
@@ -77,7 +75,7 @@ const reverse = ref(false)
     >
       <div>边栏</div>
       <template #body>
-        <fs-split-panel
+        <el-split-panel
           space="0px"
           :min-size="40"
           :max-size="-40"
@@ -99,11 +97,11 @@ const reverse = ref(false)
           <template #body>
             <div>内容二</div>
           </template>
-        </fs-split-panel>
+        </el-split-panel>
       </template>
-    </fs-split-panel>
+    </el-split-panel>
     <div style="margin: 16px 0 8px 0">先上下再左右</div>
-    <fs-split-panel
+    <el-split-panel
       space="0px"
       size="120px"
       :min-size="40"
@@ -121,7 +119,7 @@ const reverse = ref(false)
     >
       <div>顶栏</div>
       <template #body>
-        <fs-split-panel
+        <el-split-panel
           space="0px"
           :min-size="40"
           :max-size="-40"
@@ -142,9 +140,9 @@ const reverse = ref(false)
           <template #body>
             <div>内容</div>
           </template>
-        </fs-split-panel>
+        </el-split-panel>
       </template>
-    </fs-split-panel>
+    </el-split-panel>
   </el-card>
 </template>
 

+ 4 - 8
src/views/extension/stausText/index.vue

@@ -1,13 +1,9 @@
-<script setup lang="ts">
-import FsDot from '@/components/FsDot/index.vue'
-</script>
-
 <template>
   <el-card header="文本状态" shadow="never">
-    <fs-dot type="primary" text="运行中"></fs-dot>
-    <fs-dot type="success" text="已上线" class="ml-5"></fs-dot>
-    <fs-dot type="warning" text="异常" class="ml-5"></fs-dot>
-    <fs-dot type="info" text="关闭" class="ml-5"></fs-dot>
+    <el-fs-dot type="primary" text="运行中"></el-fs-dot>
+    <el-fs-dot type="success" text="已上线" class="ml-5"></el-fs-dot>
+    <el-fs-dot type="warning" text="异常" class="ml-5"></el-fs-dot>
+    <el-fs-dot type="info" text="关闭" class="ml-5"></el-fs-dot>
   </el-card>
 </template>
 

+ 1 - 1
src/views/extension/tableSelect/base.vue

@@ -1,5 +1,4 @@
 <script setup lang="ts">
-import FsTableSelect from '@/components/FsTableSelect/index.vue'
 import type { TableConfig } from '@/components/FsTableSelect/types'
 
 const data = ref('')
@@ -43,6 +42,7 @@ const tableConfig: TableConfig = {
       slot: 'sex'
     }
   ],
+  /* 实际开发应传入接口方法 */
   datasource: request,
   pageSize: 5
 }

+ 0 - 1
src/views/extension/tour/index.vue

@@ -1,5 +1,4 @@
 <script setup lang="ts">
-import FsTour from '@/components/FsTour/index.vue'
 import type { TourStep } from '@/components/FsTour/types'
 import type { ElButton } from 'element-plus'
 const current = ref()