Pārlūkot izejas kodu

build: 删除多余

chaooo 2 gadi atpakaļ
vecāks
revīzija
7096513536

+ 5 - 5
src/App.vue

@@ -1,11 +1,11 @@
 <script setup lang="ts">
-import { ElConfigProvider } from 'element-plus';
-import { useAppStore } from '@/store/modules/app';
+import { ElConfigProvider } from "element-plus";
+import { useAppStore } from "@/store/modules/app";
 const appStore = useAppStore();
 </script>
 
 <template>
-  <el-config-provider :locale="appStore.locale" :size="appStore.size">
-    <router-view />
-  </el-config-provider>
+  <!--  <el-config-provider :locale="appStore.locale" :size="appStore.size">-->
+  <router-view />
+  <!--  </el-config-provider>-->
 </template>

+ 0 - 165
src/components/IconSelect/index.vue

@@ -1,165 +0,0 @@
-<script setup lang="ts">
-const props = defineProps({
-  modelValue: {
-    type: String,
-    require: false,
-    default: "",
-  },
-});
-
-const emit = defineEmits(["update:modelValue"]);
-const inputValue = toRef(props, "modelValue");
-
-const visible = ref(false); // 弹窗显示状态
-
-const allIconNames: string[] = []; // 所有的图标名称集合
-
-const filterValue = ref(""); // 筛选的值
-const filterIconNames = ref<string[]>([]); // 过滤后的图标名称集合
-
-const iconSelectorRef = ref();
-const iconSelectorDialogRef = ref();
-/**
- * icon 加载
- */
-function loadIcons() {
-  const icons = import.meta.glob("../../assets/icons/*.svg");
-  for (const icon in icons) {
-    const iconName = icon.split("assets/icons/")[1].split(".svg")[0];
-    allIconNames.push(iconName);
-  }
-  filterIconNames.value = allIconNames;
-}
-
-/**
- * icon 筛选
- */
-function handleFilter() {
-  if (filterValue.value) {
-    filterIconNames.value = allIconNames.filter((iconName) =>
-      iconName.includes(filterValue.value)
-    );
-  } else {
-    filterIconNames.value = allIconNames;
-  }
-}
-
-/**
- * icon 选择
- */
-function handleSelect(iconName: string) {
-  emit("update:modelValue", iconName);
-  visible.value = false;
-}
-
-/**
- * 点击容器外的区域关闭弹窗 VueUse onClickOutside
- */
-onClickOutside(iconSelectorRef, () => (visible.value = false), {
-  ignore: [iconSelectorDialogRef],
-});
-
-onMounted(() => {
-  loadIcons();
-});
-</script>
-
-<template>
-  <div ref="iconSelectorRef" class="iconselect-container">
-    <el-input
-      v-model="inputValue"
-      readonly
-      placeholder="点击选择图标"
-      @click="visible = !visible"
-    >
-      <template #prepend>
-        <svg-icon :icon-class="inputValue" />
-      </template>
-    </el-input>
-
-    <el-popover
-      shadow="none"
-      :visible="visible"
-      placement="bottom-end"
-      trigger="click"
-      width="400"
-    >
-      <template #reference>
-        <div
-          class="cursor-pointer text-[#999] absolute right-[10px] top-0 height-[32px] leading-[32px]"
-          @click="visible = !visible"
-        >
-          <i-ep-caret-top v-show="visible"></i-ep-caret-top>
-          <i-ep-caret-bottom v-show="!visible"></i-ep-caret-bottom>
-        </div>
-      </template>
-
-      <!-- 下拉选择弹窗 -->
-      <div ref="iconSelectorDialogRef">
-        <el-input
-          v-model="filterValue"
-          class="p-2"
-          placeholder="搜索图标"
-          clearable
-          @input="handleFilter"
-        />
-        <el-divider border-style="dashed" />
-
-        <el-scrollbar height="300px">
-          <ul class="icon-list">
-            <li
-              v-for="(iconName, index) in filterIconNames"
-              :key="index"
-              class="icon-item"
-              @click="handleSelect(iconName)"
-            >
-              <el-tooltip :content="iconName" placement="bottom" effect="light">
-                <svg-icon
-                  color="var(--el-text-color-regular)"
-                  :icon-class="iconName"
-                />
-              </el-tooltip>
-            </li>
-          </ul>
-        </el-scrollbar>
-      </div>
-    </el-popover>
-  </div>
-</template>
-
-<style scoped lang="scss">
-.el-divider--horizontal {
-  margin: 10px auto !important;
-}
-
-.iconselect-container {
-  position: relative;
-  width: 400px;
-}
-
-.icon-list {
-  display: flex;
-  flex-wrap: wrap;
-  padding-left: 10px;
-  margin-top: 10px;
-
-  .icon-item {
-    display: flex;
-    flex-direction: column;
-    align-items: center;
-    justify-items: center;
-    width: 10%;
-    padding: 5px;
-    margin: 0 10px 10px 0;
-    cursor: pointer;
-    border: 1px solid #ccc;
-
-    &:hover {
-      color: var(--el-color-primary);
-      border-color: var(--el-color-primary);
-      transition: all 0.2s;
-      transform: scaleX(1.1);
-    }
-  }
-}
-</style>

+ 0 - 136
src/components/RightPanel/index.vue

@@ -1,136 +0,0 @@
-<script setup lang="ts">
-import { onBeforeUnmount, onMounted, ref, watch } from "vue";
-
-import { addClass, removeClass } from "@/utils/index";
-
-const show = ref(false);
-
-defineProps({
-  buttonTop: {
-    default: 250,
-    type: Number,
-  },
-});
-
-watch(show, (value) => {
-  if (value) {
-    addEventClick();
-  }
-  if (value) {
-    addClass(document.body, "showRightPanel");
-  } else {
-    removeClass(document.body, "showRightPanel");
-  }
-});
-
-function addEventClick() {
-  window.addEventListener("click", closeSidebar, { passive: true });
-}
-
-function closeSidebar(evt: any) {
-  // 主题选择点击不关闭
-  let parent = evt.target.closest(".right-panel-container");
-  if (!parent) {
-    show.value = false;
-    window.removeEventListener("click", closeSidebar);
-  }
-}
-
-const rightPanel = ref();
-
-function insertToBody() {
-  const body = document.querySelector("body") as any;
-  body.insertBefore(rightPanel.value, body.firstChild);
-}
-
-onMounted(() => {
-  insertToBody();
-});
-
-onBeforeUnmount(() => {
-  rightPanel.value.remove();
-});
-</script>
-
-<template>
-  <div ref="rightPanel" :class="{ show: show }">
-    <div class="right-panel-overlay" />
-    <div class="right-panel-container">
-      <div
-        class="right-panel-btn"
-        :style="{
-          top: buttonTop + 'px',
-        }"
-        @click="show = !show"
-      >
-        <i-ep-close v-show="show" />
-        <i-ep-setting v-show="!show" />
-      </div>
-      <div>
-        <slot />
-      </div>
-    </div>
-  </div>
-</template>
-
-<style lang="scss" scoped>
-.showRightPanel {
-  position: relative;
-  width: calc(100% - 15px);
-  overflow: hidden;
-}
-
-.right-panel-overlay {
-  position: fixed;
-  top: 0;
-  left: 0;
-  background: rgb(0 0 0 / 20%);
-}
-
-.right-panel-container {
-  position: fixed;
-  top: 0;
-  right: 0;
-  z-index: 999;
-  width: 100%;
-  max-width: 300px;
-  height: 100vh;
-  background-color: var(--el-bg-color-overlay);
-  box-shadow: 0 0 15px 0 rgb(0 0 0 / 5%);
-  transition: all 0.25s cubic-bezier(0.7, 0.3, 0.1, 1);
-  transform: translate(100%);
-}
-
-.show {
-  transition: all 0.3s cubic-bezier(0.7, 0.3, 0.1, 1);
-
-  .right-panel-overlay {
-    z-index: 99;
-    width: 100%;
-    height: 100%;
-    opacity: 1;
-  }
-
-  .right-panel-container {
-    transform: translate(0);
-  }
-}
-
-.right-panel-btn {
-  position: absolute;
-  left: -36px;
-  width: 36px;
-  height: 36px;
-  color: var(--el-color-white);
-  text-align: center;
-  cursor: pointer;
-  background-color: var(--el-color-primary);
-  border-radius: 6px 0 0 6px;
-
-  svg {
-    width: 20px;
-    height: 20px;
-    vertical-align: -10px;
-  }
-}
-</style>

+ 0 - 492
src/components/TagInput/index.vue

@@ -1,492 +0,0 @@
-<template>
-  <div :class="['tagInputarea', className]">
-    <div
-      ref="cmEle"
-      :class="[
-        'tagInputareaIuput',
-        'ThemeBorderColor3',
-        !!readonly ? 'readonlyBg' : '',
-      ]"
-    ></div>
-  </div>
-</template>
-<script lang="ts" setup>
-import CodeMirror from "codemirror";
-import "codemirror/lib/codemirror.css";
-import { getRePosFromStr, MODE } from "./util";
-
-const props = defineProps({
-  mode: {
-    type: Number,
-    default: MODE.TEXT,
-  },
-  className: {
-    type: String,
-    default: "",
-  },
-  defaultValue: {
-    type: String,
-    default: "",
-    required: true,
-  },
-  renderTag: {
-    type: Function,
-    required: true,
-  },
-  minHeight: {
-    type: Number,
-    default: 20,
-  },
-  readonly: {
-    type: Boolean,
-    default: false,
-  },
-  noCursor: {
-    type: Boolean,
-    default: false,
-  },
-  operatorsSetMargin: {
-    type: Boolean,
-    default: false,
-  },
-  autoComma: {
-    type: Boolean,
-    default: false,
-  },
-  // 是否禁用复制
-  disabledCopy: {
-    type: Boolean,
-    required: false,
-    default: false,
-  },
-});
-const emit = defineEmits(["onChange", "onBlur", "onFocus"]);
-//编辑器挂载dom节点
-const cmEle = ref();
-
-//编辑器实例
-let cmInstance: any = null;
-
-onMounted(() => {
-  if (cmEle.value) {
-    //编辑器初始化
-    cmInstance = CodeMirror(cmEle.value, {
-      value: props.defaultValue,
-      mode: "",
-      lineWrapping: true,
-      cursorHeight: props.noCursor || props.readonly ? 0 : 1,
-    });
-    //最小高度初始化
-    if (props.minHeight) {
-      let height =
-        typeof props.minHeight === "number"
-          ? `${props.minHeight}px`
-          : props.minHeight;
-      //编辑器高度
-      cmInstance.setSize("100%", height);
-      //编辑内容高度
-      let codeEle = cmEle.value.getElementsByClassName("CodeMirror-code")[0];
-      codeEle && codeEle.setAttribute("style", `min-height:${height}`);
-    }
-    //默认值初始化
-    if (props.defaultValue) {
-      updateTextareaView();
-      cmInstance.execCommand("goDocEnd");
-    }
-    //监听 value change
-    cmInstance.on("change", cmChange);
-    //监听 value beforeChange
-    cmInstance.on("beforeChange", cmBeforeChange);
-    //监听表单聚焦
-    cmInstance.on("focus", () => {
-      cmEle.value.classList.add("active");
-      cmFocus();
-    });
-
-    //监听表单失焦
-    cmInstance.on("blur", () => {
-      if (cmEle.value) {
-        cmEle.value.classList.remove("active");
-      }
-      cmBlur();
-    });
-    if (props.disabledCopy) {
-      // 禁止复制,防止tag复制的是id
-      cmInstance.on("copy", (cm: any, e: Event) => {
-        e.preventDefault();
-      });
-    }
-  }
-});
-
-//编辑器change
-const cmChange = (cm: any, obj: any): void => {
-  let value = cm.getValue();
-  if (obj.origin !== "setValue") {
-    emit("onChange", null, value, obj);
-  }
-
-  updateTextareaView();
-};
-
-//编辑器beforeChange
-const cmBeforeChange = (cm: any, obj: any): any => {
-  let { text } = obj;
-  // 如果是自定义公式,只能允许数字+、-、*、/、( \ ) , .,大写字符
-  if (
-    props.mode === MODE.FORMULA &&
-    (obj.origin === "paste" ||
-      obj.origin === "+input" ||
-      obj.origin === "*compose")
-  ) {
-    text = text.map((t: string) =>
-      t.replace(/[^+\-*\/0-9/a-z/A-Z\(\)\,\.]/gm, "").toUpperCase()
-    );
-    // 最大输入10000字符
-    if (text.map((t: string) => t).join("").length > 10000) {
-      text = text
-        .map((t: string) => t)
-        .join("")
-        .slice(0, 10000)
-        .split(",");
-      obj.update(obj.from, obj.to, text);
-      obj.cancel();
-    }
-  }
-
-  if (obj.origin === "undo" || obj.origin === "redo") {
-    return;
-  }
-  // 事件内,mode只能从每次props取,不然取不到最新
-  if (
-    props.readonly ||
-    (props.mode === MODE.ONLYTAG &&
-      obj.origin !== "+delete" &&
-      obj.origin !== "inserttag" &&
-      obj.origin !== "setValue")
-  ) {
-    obj.cancel();
-  }
-
-  // 事件内,mode只能从每次props取,不然取不到最新
-  if (
-    props.mode === MODE.FORMULA &&
-    obj.origin !== "+delete" &&
-    obj.origin !== "inserttag" &&
-    obj.origin !== "setValue"
-  ) {
-    text = text.map((t: any) =>
-      t
-        .toUpperCase()
-        .split("")
-        .filter((t: any) =>
-          (obj.origin === "paste"
-            ? /[0-9A-Z\+\-\*\/\(\)\,\.\$]/
-            : /[0-9A-Z\+\-\*\/\(\)\,\.]/
-          ).test(t)
-        )
-        .join("")
-    );
-  }
-  if (
-    props.mode === MODE.DATE &&
-    obj.origin !== "+delete" &&
-    obj.origin !== "inserttag" &&
-    obj.origin !== "setValue"
-  ) {
-    text = text.map((t: any) =>
-      t
-        .split("")
-        .filter((t: any) =>
-          (obj.origin === "paste" ? /[0-9YMdhm\+\-\$]/ : /[0-9YMdhm\+\-]/).test(
-            t
-          )
-        )
-        .join("")
-    );
-  }
-  obj.update(obj.from, obj.to, text);
-};
-
-//编辑器 foucus
-const cmFocus = (): void => {
-  emit("onFocus");
-};
-
-//编辑器 blur
-const cmBlur = (): void => {
-  emit("onBlur");
-};
-
-//设置 value
-const setValue = (value: string): void => {
-  // const position = cmInstance.getCursor()
-  cmInstance.setValue(value || "");
-  // const newPosition = {
-  //     line: position.line,
-  //     ch: position.ch + value.length - 2,
-  // }
-
-  // cmInstance.focus()
-  // cmInstance.setCursor(newPosition)
-  // cmInstance.execCommand('goDocEnd')
-};
-const getValue = () => {
-  return cmInstance.getValue();
-};
-//回显,更新渲染
-let markers: any = null;
-const updateTextareaView = () => {
-  const { mode, operatorsSetMargin } = props;
-  const value = cmInstance.getValue();
-  if (markers) {
-    markers.forEach((marker: any) => marker.clear());
-  }
-  markers = [];
-  markColumns(markers, value);
-  if (mode === MODE.FORMULA || operatorsSetMargin) {
-    markOperators(markers, value);
-  }
-};
-
-//光标行
-const markColumns = (markers: any, value: any) => {
-  const poss = getRePosFromStr(value);
-  poss.forEach((pos: any, i: number) => {
-    renderColumnTag(pos.tag, { isLast: i === poss.length - 1 }, (node: any) => {
-      markers.push(
-        cmInstance.markText(
-          { line: pos.line, ch: pos.start },
-          { line: pos.line, ch: pos.stop },
-          { replacedWith: node, handleMouseEvents: true }
-        )
-      );
-    });
-  });
-};
-
-//光标操作
-const markOperators = (markers: any, value: any) => {
-  const poss = getRePosFromStr(value, /\+|\-|\*|\/|\(|\)|,/g);
-  poss.forEach((pos: any, i: number) => {
-    const operatorEle = document.createElement("span");
-    operatorEle.classList.add("operator");
-    operatorEle.innerHTML = pos.tag;
-    markers.push(
-      cmInstance.markText(
-        { line: pos.line, ch: pos.start },
-        { line: pos.line, ch: pos.stop },
-        { replacedWith: operatorEle, handleMouseEvents: true }
-      )
-    );
-  });
-};
-
-//渲染 tag
-const renderColumnTag = (id: any, options: any, cb: any) => {
-  const node = document.createElement("div");
-  node.classList.add("columnTagCon");
-  //自定义渲染tag
-  if (props.renderTag) {
-    const tag = props.renderTag(id, options);
-    if (tag instanceof HTMLElement) {
-      node.appendChild(tag);
-      cb(node);
-      return;
-    }
-  }
-  node.append(id);
-  cb(node);
-  return;
-};
-
-//插入 tag
-const insertColumnTag = (id: string) => {
-  const { mode, autoComma } = props;
-  const position = cmInstance.getCursor();
-  const editorValue = cmInstance.getValue();
-
-  cmInstance.replaceRange(
-    `${
-      mode === MODE.FORMULA && autoComma && editorValue[position.ch - 1] === "$"
-        ? ","
-        : ""
-    }$${id}$`,
-    position,
-    undefined,
-    "inserttag"
-  );
-  cmInstance.focus();
-  cmInstance.execCommand("goDocEnd");
-  if (cmEle.value) {
-    cmEle.value.scrollTop = cmEle.value.scrollHeight - cmEle.value.clientHeight;
-  }
-};
-// 获取光标位置
-const getCursor = () => {
-  return cmInstance.getCursor();
-};
-// 设置光标位置
-const setCustomCursor = (position: { line: number; ch: number }) => {
-  cmInstance.setCursor(position);
-};
-// 插入公式
-const insertFormula = (value: string) => {
-  const { mode, autoComma } = props;
-  const position = cmInstance.getCursor();
-
-  cmInstance.replaceRange(value, position, undefined, "insertFormula");
-  setTimeout(() => {
-    const newPosition = {
-      line: position.line,
-      ch: position.ch + value.length - 2,
-    };
-
-    cmInstance.focus();
-    cmInstance.setCursor(newPosition);
-    // cmInstance.execCommand('goDocEnd')
-  }, 0);
-  if (cmEle.value) {
-    cmEle.value.scrollTop = cmEle.value.scrollHeight - cmEle.value.clientHeight;
-  }
-};
-defineExpose({
-  insertColumnTag,
-});
-</script>
-
-<style lang="scss" scoped>
-.tagInputarea {
-  min-width: 0;
-  :deep {
-    .tagInputareaIuput {
-      border-radius: 3px;
-      border: 1px solid #409eff;
-      overflow: auto;
-
-      &:not(.active) {
-        border-color: #ccc !important;
-      }
-      // &.hasRightIcon {
-      //   border-radius: 3px 0 0 3px;
-      // }
-      &.readonlyBg {
-        .CodeMirror {
-          background-color: #eee !important;
-        }
-      }
-    }
-    // .rightIcon {
-    //   background-color: #f5f5f5;
-    //   font-size: 20px;
-    //   color: #757575;
-    //   height: 34px;
-    //   line-height: 33px;
-    //   padding: 0 7px;
-    //   border: 1px solid #ccc;
-    //   border-left: none;
-    //   border-radius: 0 3px 3px 0;
-    // }
-    .CodeMirror {
-      font-family: inherit !important;
-      box-sizing: border-box;
-      height: auto !important;
-
-      .CodeMirror-vscrollbar {
-        display: none !important;
-      }
-
-      // .CodeMirror-scroll {
-      //     height: auto;
-      //     overflow-y: hidden;
-      //     overflow-x: auto;
-      // }
-
-      .CodeMirror-lines {
-        padding: 6px 0;
-        min-height: 35px;
-      }
-      .CodeMirror-line {
-        padding: 0 10px;
-      }
-      .columnTagCon {
-        position: relative;
-        display: inline-flex;
-        // box-sizing: border-box;
-        // padding: 2px 4px;
-        // max-width: 100%;
-        // background: #d8eeff;
-        // color: #174c76;
-        // border: 1px solid #bbd6ea;
-        // border-radius: 5px;
-      }
-      .columnTag {
-        position: relative;
-        display: inline-flex;
-        box-sizing: border-box;
-        cursor: pointer;
-        height: 24px;
-        font-size: 12px;
-        border: 1px solid #90caf9;
-        border-radius: 24px;
-        .columnName,
-        .columnValue {
-          display: inline-block;
-          height: 22px;
-          line-height: 22px;
-          padding: 0 10px;
-          overflow: hidden;
-        }
-        .columnName {
-          color: #2196f3;
-          background-color: rgba(33, 150, 243, 0.06);
-        }
-        .columnValue {
-          color: #fff;
-          border-radius: 0 22px 22px 0;
-          background-color: #249eff;
-          .ellipsis {
-            max-width: 9em;
-          }
-        }
-        &.onlytag {
-          margin-right: 6px;
-          &:after {
-            content: ",";
-            position: absolute;
-            right: -6px;
-            top: 6px;
-          }
-        }
-        &.deleted {
-          border-color: #f44336;
-          .columnName {
-            color: #f44336;
-            background-color: rgba(244, 67, 54, 0.06);
-          }
-          &:hover {
-            border-color: #f44336;
-            .columnName {
-              color: #f44336;
-              background-color: rgba(244, 67, 54, 0.12);
-            }
-          }
-        }
-        &:hover {
-          border-color: #ddd;
-          .columnName {
-            color: #9e9e9e;
-            background-color: rgba(158, 158, 158, 0.06);
-          }
-          .columnValue {
-            background-color: #bdbdbd;
-          }
-        }
-      }
-      .operator {
-        margin: 0 4px;
-      }
-    }
-  }
-}
-</style>

+ 0 - 34
src/components/TagInput/util.ts

@@ -1,34 +0,0 @@
-/**
- * getRePosFromStr 正则匹配字段返回位置信息
- * */
-export function getRePosFromStr(text: any = '', re: any = /\$.+?\$/g) {
-    const lines = text.split('\n')
-    const positions: any = []
-    let m
-    for (let i = 0; i < lines.length; i++) {
-        const l = lines[i]
-        while ((m = re.exec(l)) !== null) {
-            var tag = m[0].substring(1, m[0].length - 1)
-            positions.push({
-                line: i,
-                start: m.index,
-                stop: m.index + m[0].length,
-                tag,
-            })
-        }
-    }
-    return positions
-}
-/**
- * 输入框模式
- */
-export enum MODE {
-    // 文本
-    TEXT = 1,
-    // 公式
-    FORMULA,
-    // 只允许选择tag
-    ONLYTAG,
-    // 日期
-    DATE
-}

+ 0 - 139
src/components/Upload/MultiUpload.vue

@@ -1,139 +0,0 @@
-<!--
-  多图上传组件
-  @author: youlaitech
-  @date 2022/11/20
--->
-
-<template>
-  <el-upload
-    v-model:file-list="fileList"
-    list-type="picture-card"
-    :before-upload="handleBeforeUpload"
-    :http-request="handleUpload"
-    :on-remove="handleRemove"
-    :on-preview="previewImg"
-    :limit="props.limit"
-  >
-    <i-ep-plus />
-  </el-upload>
-
-  <el-dialog v-model="dialogVisible">
-    <img w-full :src="previewImgUrl" alt="Preview Image" />
-  </el-dialog>
-</template>
-
-<script setup lang="ts">
-import {
-  UploadRawFile,
-  UploadRequestOptions,
-  UploadUserFile,
-  UploadFile,
-  UploadProps,
-} from "element-plus";
-import { uploadFileApi, deleteFileApi } from "@/api/file";
-
-const emit = defineEmits(["update:modelValue"]);
-
-const props = defineProps({
-  /**
-   * 文件路径集合
-   */
-  modelValue: {
-    type: Array<string>,
-    default: [] as Array<string>,
-  },
-  /**
-   * 文件上传数量限制
-   */
-  limit: {
-    type: Number,
-    default: 10,
-  },
-});
-
-const previewImgUrl = ref("");
-const dialogVisible = ref(false);
-
-const fileList = ref([] as UploadUserFile[]);
-watch(
-  () => props.modelValue,
-  (newVal: string[]) => {
-    const filePaths = fileList.value.map((file) => file.url);
-    // 监听modelValue文件集合值未变化时,跳过赋值
-    if (
-      filePaths.length > 0 &&
-      filePaths.length === newVal.length &&
-      filePaths.every((x) => newVal.some((y) => y === x)) &&
-      newVal.every((y) => filePaths.some((x) => x === y))
-    ) {
-      return;
-    }
-
-    fileList.value = newVal.map((filePath) => {
-      return { url: filePath } as UploadUserFile;
-    });
-  },
-  { immediate: true }
-);
-
-/**
- * 自定义图片上传
- *
- * @param params
- */
-async function handleUpload(options: UploadRequestOptions): Promise<any> {
-  // 上传API调用
-  const { data: fileInfo } = await uploadFileApi(options.file);
-
-  // 上传成功需手动替换文件路径为远程URL,否则图片地址为预览地址 blob:http://
-  const fileIndex = fileList.value.findIndex(
-    (file) => file.uid == (options.file as any).uid
-  );
-
-  fileList.value.splice(fileIndex, 1, {
-    name: fileInfo.name,
-    url: fileInfo.url,
-  } as UploadUserFile);
-
-  emit(
-    "update:modelValue",
-    fileList.value.map((file) => file.url)
-  );
-}
-
-/**
- * 删除图片
- */
-function handleRemove(removeFile: UploadFile) {
-  const filePath = removeFile.url;
-
-  if (filePath) {
-    deleteFileApi(filePath).then(() => {
-      // 删除成功回调
-      emit(
-        "update:modelValue",
-        fileList.value.map((file) => file.url)
-      );
-    });
-  }
-}
-
-/**
- * 限制用户上传文件的格式和大小
- */
-function handleBeforeUpload(file: UploadRawFile) {
-  if (file.size > 2 * 1048 * 1048) {
-    ElMessage.warning("上传图片不能大于2M");
-    return false;
-  }
-  return true;
-}
-
-/**
- * 预览图片
- */
-const previewImg: UploadProps["onPreview"] = (uploadFile) => {
-  previewImgUrl.value = uploadFile.url!;
-  dialogVisible.value = true;
-};
-</script>

+ 0 - 81
src/components/Upload/SingleUpload.vue

@@ -1,81 +0,0 @@
-<template>
-  <!-- 上传组件 -->
-  <el-upload
-    v-model="imgUrl"
-    class="single-uploader"
-    :show-file-list="false"
-    list-type="picture-card"
-    :before-upload="handleBeforeUpload"
-    :http-request="uploadFile"
-  >
-    <img v-if="imgUrl" :src="imgUrl" class="single" />
-    <el-icon v-else class="single-uploader-icon"><i-ep-plus /></el-icon>
-  </el-upload>
-</template>
-
-<script setup lang="ts">
-import { UploadRawFile, UploadRequestOptions } from "element-plus";
-import { uploadFileApi } from "@/api/file";
-
-const props = defineProps({
-  modelValue: {
-    type: String,
-    default: "",
-  },
-});
-
-const emit = defineEmits(["update:modelValue"]);
-const imgUrl = useVModel(props, "modelValue", emit);
-
-/**
- * 自定义图片上传
- *
- * @param options
- */
-async function uploadFile(options: UploadRequestOptions): Promise<any> {
-  const { data: fileInfo } = await uploadFileApi(options.file);
-  imgUrl.value = fileInfo.url;
-}
-
-/**
- * 限制用户上传文件的格式和大小
- */
-function handleBeforeUpload(file: UploadRawFile) {
-  if (file.size > 2 * 1048 * 1048) {
-    ElMessage.warning("上传图片不能大于2M");
-    return false;
-  }
-  return true;
-}
-</script>
-
-<style scoped>
-.single-uploader .single {
-  display: block;
-  width: 178px;
-  height: 178px;
-}
-</style>
-
-<style>
-.single-uploader .el-upload {
-  position: relative;
-  overflow: hidden;
-  cursor: pointer;
-  border: 1px dashed var(--el-border-color);
-  border-radius: 6px;
-  transition: var(--el-transition-duration-fast);
-}
-
-.single-uploader .el-upload:hover {
-  border-color: var(--el-color-primary);
-}
-
-.el-icon.single-uploader-icon {
-  width: 178px;
-  height: 178px;
-  font-size: 28px;
-  color: #8c939d;
-  text-align: center;
-}
-</style>

+ 0 - 90
src/components/WangEditor/index.vue

@@ -1,90 +0,0 @@
-<template>
-  <div class="editor-wrapper">
-    <!-- 工具栏 -->
-    <Toolbar
-      id="toolbar-container"
-      :editor="editorRef"
-      :default-config="toolbarConfig"
-      :mode="mode"
-    />
-    <!-- 编辑器 -->
-    <Editor
-      id="editor-container"
-      v-model="modelValue"
-      :default-config="editorConfig"
-      :mode="mode"
-      @on-change="handleChange"
-      @on-created="handleCreated"
-    />
-  </div>
-</template>
-
-<script setup lang="ts">
-import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
-
-// API 引用
-import { uploadFileApi } from "@/api/file";
-
-const props = defineProps({
-  modelValue: {
-    type: [String],
-    default: "",
-  },
-});
-
-const emit = defineEmits(["update:modelValue"]);
-
-const modelValue = useVModel(props, "modelValue", emit);
-
-const editorRef = shallowRef(); // 编辑器实例,必须用 shallowRef
-const mode = ref("default"); // 编辑器模式
-const toolbarConfig = ref({}); // 工具条配置
-// 编辑器配置
-const editorConfig = ref({
-  placeholder: "请输入内容...",
-  MENU_CONF: {
-    uploadImage: {
-      // 自定义图片上传
-      async customUpload(file: any, insertFn: any) {
-        uploadFileApi(file).then((response) => {
-          const url = response.data.url;
-          insertFn(url);
-        });
-      },
-    },
-  },
-});
-
-const handleCreated = (editor: any) => {
-  editorRef.value = editor; // 记录 editor 实例,重要!
-};
-
-function handleChange(editor: any) {
-  modelValue.value = editor.getHtml();
-}
-
-// 组件销毁时,也及时销毁编辑器
-onBeforeUnmount(() => {
-  const editor = editorRef.value;
-  if (editor == null) return;
-  editor.destroy();
-});
-</script>
-
-<style src="@wangeditor/editor/dist/css/style.css"></style>
-
-<style lang="scss" scoped>
-.editor-wrapper {
-  display: flex;
-  flex-direction: column;
-  border: 1px solid #ccc;
-
-  #toolbar-container {
-    border-bottom: 1px solid #ccc;
-  }
-
-  #editor-container {
-    flex-grow: 1;
-  }
-}
-</style>

+ 1 - 9
src/layout/admin.vue

@@ -1,9 +1,8 @@
 <script setup lang="ts">
 import { computed, watchEffect } from "vue";
 import { useWindowSize } from "@vueuse/core";
-import { AppMain, Navbar, Settings, TagsView } from "./components/index";
+import { AppMain, Navbar, TagsView } from "./components/index";
 import Sidebar from "./components/Sidebar/index.vue";
-import RightPanel from "@/components/RightPanel/index.vue";
 
 import { useAppStore } from "@/store/modules/app";
 import { useSettingsStore } from "@/store/modules/settings";
@@ -21,10 +20,8 @@ const WIDTH = 992;
 
 const appStore = useAppStore();
 const settingsStore = useSettingsStore();
-
 const fixedHeader = computed(() => settingsStore.fixedHeader);
 const showTagsView = computed(() => settingsStore.tagsView);
-const showSettings = computed(() => settingsStore.showSettings);
 
 const classObj = computed(() => ({
   hideSidebar: !appStore.sidebar.opened,
@@ -73,11 +70,6 @@ function handleOutsideClick() {
 
       <!--主页面-->
       <app-main />
-
-      <!-- 设置面板 -->
-      <RightPanel v-if="showSettings">
-        <settings />
-      </RightPanel>
     </div>
   </div>
 </template>

+ 0 - 61
src/layout/components/Settings/index.vue

@@ -1,61 +0,0 @@
-<script setup lang="ts">
-import { useSettingsStore } from "@/store/modules/settings";
-
-const settingsStore = useSettingsStore();
-// 主题颜色
-const themeColors = ref<string[]>([
-  "#409EFF",
-  "#304156",
-  "#11a983",
-  "#13c2c2",
-  "#6959CD",
-  "#f5222d",
-]);
-/**
- * 切换主题颜色
- */
-function changeThemeColor(color: string) {
-  document.documentElement.style.setProperty("--el-color-primary", color);
-  settingsStore.changeSetting({ key: "layout", value: color });
-}
-</script>
-
-<template>
-  <div class="settings-container">
-    <h3 class="text-base font-bold">项目配置</h3>
-    <el-divider>界面设置</el-divider>
-
-    <div class="py-[8px] flex justify-between">
-      <span class="text-xs">开启 Tags-View</span>
-      <el-switch v-model="settingsStore.tagsView" />
-    </div>
-
-    <div class="py-[8px] flex justify-between">
-      <span class="text-xs">固定 Header</span>
-      <el-switch v-model="settingsStore.fixedHeader" />
-    </div>
-
-    <div class="py-[8px] flex justify-between">
-      <span class="text-xs">侧边栏 Logo</span>
-      <el-switch v-model="settingsStore.sidebarLogo" />
-    </div>
-
-    <el-divider>主题颜色</el-divider>
-
-    <ul class="w-full space-x-2 flex justify-center py-2">
-      <li
-        v-for="(color, index) in themeColors"
-        :key="index"
-        class="inline-block w-[30px] h-[30px] cursor-pointer"
-        :style="{ background: color }"
-        @click="changeThemeColor(color)"
-      />
-    </ul>
-  </div>
-</template>
-
-<style lang="scss" scoped>
-.settings-container {
-  padding: 16px;
-}
-</style>

+ 2 - 1
src/layout/components/Sidebar/SidebarItem.vue

@@ -1,9 +1,10 @@
 <script setup lang="ts">
-import { useRouter, onBeforeRouteUpdate } from "vue-router";
+import { useRouter } from "vue-router";
 import path from "path-browserify";
 import { isExternal } from "@/utils/index";
 import AppLink from "./Link.vue";
 import SvgIcon from "@/components/SvgIcon/index.vue";
+
 const router = useRouter();
 const props = defineProps({
   /**

+ 3 - 4
src/layout/components/index.ts

@@ -1,4 +1,3 @@
-export { default as Navbar } from './Navbar.vue';
-export { default as AppMain } from './AppMain.vue';
-export { default as Settings } from './Settings/index.vue';
-export { default as TagsView } from './TagsView/index.vue';
+export { default as Navbar } from "./Navbar.vue";
+export { default as AppMain } from "./AppMain.vue";
+export { default as TagsView } from "./TagsView/index.vue";

+ 1 - 9
src/layout/school.vue

@@ -1,9 +1,8 @@
 <script setup lang="ts">
 import { computed, watchEffect } from "vue";
 import { useWindowSize } from "@vueuse/core";
-import { AppMain, Navbar, Settings, TagsView } from "./components/index";
+import { AppMain, Navbar, TagsView } from "./components/index";
 import Sidebar from "./components/Sidebar/index.vue";
-import RightPanel from "@/components/RightPanel/index.vue";
 
 import { useAppStore } from "@/store/modules/app";
 import { useSettingsStore } from "@/store/modules/settings";
@@ -21,10 +20,8 @@ const WIDTH = 992;
 
 const appStore = useAppStore();
 const settingsStore = useSettingsStore();
-
 const fixedHeader = computed(() => settingsStore.fixedHeader);
 const showTagsView = computed(() => settingsStore.tagsView);
-const showSettings = computed(() => settingsStore.showSettings);
 
 const classObj = computed(() => ({
   hideSidebar: !appStore.sidebar.opened,
@@ -73,11 +70,6 @@ function handleOutsideClick() {
 
       <!--主页面-->
       <app-main />
-
-      <!-- 设置面板 -->
-      <RightPanel v-if="showSettings">
-        <settings />
-      </RightPanel>
     </div>
   </div>
 </template>

+ 0 - 6
src/settings.ts

@@ -4,11 +4,6 @@ interface DefaultSettings {
    * 系统title
    */
   title: string;
-
-  /**
-   * 是否显示设置
-   */
-  showSettings: boolean;
   /**
    * 是否显示多标签导航
    */
@@ -33,7 +28,6 @@ interface DefaultSettings {
 
 const defaultSettings: DefaultSettings = {
   title: "水母星球数据看板系统",
-  showSettings: false,
   tagsView: false,
   fixedHeader: false,
   sidebarLogo: true,

+ 0 - 29
src/store/modules/settings.ts

@@ -5,43 +5,14 @@ import { useStorage } from "@vueuse/core";
 export const useSettingsStore = defineStore("setting", () => {
   // state
   const tagsView = useStorage<boolean>("tagsView", defaultSettings.tagsView);
-
-  const showSettings = ref<boolean>(defaultSettings.showSettings);
   const fixedHeader = ref<boolean>(defaultSettings.fixedHeader);
   const sidebarLogo = ref<boolean>(defaultSettings.sidebarLogo);
-
   const layout = useStorage<string>("layout", defaultSettings.layout);
 
-  // actions
-  function changeSetting(param: { key: string; value: any }) {
-    const { key, value } = param;
-    switch (key) {
-      case "showSettings":
-        showSettings.value = value;
-        break;
-      case "fixedHeader":
-        fixedHeader.value = value;
-        break;
-      case "tagsView":
-        tagsView.value = value;
-        break;
-      case "sidevarLogo":
-        sidebarLogo.value = value;
-        break;
-      case "layout":
-        layout.value = value;
-        break;
-      default:
-        break;
-    }
-  }
-
   return {
-    showSettings,
     tagsView,
     fixedHeader,
     sidebarLogo,
     layout,
-    changeSetting,
   };
 });

+ 3 - 11
src/types/components.d.ts

@@ -9,7 +9,6 @@ export {};
 
 declare module "@vue/runtime-core" {
   export interface GlobalComponents {
-    Breadcrumb: typeof import("./../components/Breadcrumb/index.vue")["default"];
     ElAlert: typeof import("element-plus/es")["ElAlert"];
     ElBreadcrumb: typeof import("element-plus/es")["ElBreadcrumb"];
     ElBreadcrumbItem: typeof import("element-plus/es")["ElBreadcrumbItem"];
@@ -46,9 +45,6 @@ declare module "@vue/runtime-core" {
     ElTree: typeof import("element-plus/es")["ElTree"];
     ElTreeSelect: typeof import("element-plus/es")["ElTreeSelect"];
     ElUpload: typeof import("element-plus/es")["ElUpload"];
-    GithubCorner: typeof import("./../components/GithubCorner/index.vue")["default"];
-    Hamburger: typeof import("./../components/Hamburger/index.vue")["default"];
-    IconSelect: typeof import("./../components/IconSelect/index.vue")["default"];
     IEpCaretBottom: typeof import("~icons/ep/caret-bottom")["default"];
     IEpCaretTop: typeof import("~icons/ep/caret-top")["default"];
     IEpClose: typeof import("~icons/ep/close")["default"];
@@ -64,16 +60,12 @@ declare module "@vue/runtime-core" {
     IEpSetting: typeof import("~icons/ep/setting")["default"];
     IEpTop: typeof import("~icons/ep/top")["default"];
     IEpUploadFilled: typeof import("~icons/ep/upload-filled")["default"];
-    LangSelect: typeof import("./../components/LangSelect/index.vue")["default"];
-    MultiUpload: typeof import("./../components/Upload/MultiUpload.vue")["default"];
-    Pagination: typeof import("./../components/Pagination/index.vue")["default"];
-    RightPanel: typeof import("./../components/RightPanel/index.vue")["default"];
     RouterLink: typeof import("vue-router")["RouterLink"];
     RouterView: typeof import("vue-router")["RouterView"];
-    SingleUpload: typeof import("./../components/Upload/SingleUpload.vue")["default"];
+    Breadcrumb: typeof import("./../components/Breadcrumb/index.vue")["default"];
+    Hamburger: typeof import("./../components/Hamburger/index.vue")["default"];
     SvgIcon: typeof import("./../components/SvgIcon/index.vue")["default"];
-    TagInput: typeof import("./../components/TagInput/index.vue")["default"];
-    WangEditor: typeof import("./../components/WangEditor/index.vue")["default"];
+    Pagination: typeof import("./../components/Pagination/index.vue")["default"];
   }
   export interface ComponentCustomProperties {
     vLoading: typeof import("element-plus/es")["ElLoadingDirective"];