ananzhusen 2 жил өмнө
parent
commit
57d6995853

+ 2 - 1
package.json

@@ -16,7 +16,7 @@
     "jszip": "^3.10.0",
     "localforage": "^1.10.0",
     "monaco-editor": "^0.37.1",
-    "tdesign-vue-next": "^1.3.0",
+    "tdesign-vue-next": "^1.3.2",
     "vue": "^3.2.37",
     "vue-router": "^4.1.3"
   },
@@ -27,6 +27,7 @@
     "@vitejs/plugin-vue": "^4.0.0",
     "@vitejs/plugin-vue-jsx": "^3.0.0",
     "autoprefixer": "^10.4.13",
+    "formidable": "^2.0.1",
     "postcss": "^8.4.6",
     "postcss-import": "^14.1.0",
     "postcss-nested": "^6.0.1",

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 187 - 195
pnpm-lock.yaml


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
public/png/废气治理/储罐.svg


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
public/png/废气治理/单向阀.svg


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
public/png/废气治理/过滤器.svg


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
public/png/智慧城市/充电桩.svg


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
public/png/智慧城市/草地.svg


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
public/png/智慧港口/堆取料机.svg


BIN
public/png/电信机房/服务器.gif


BIN
public/png/电信机房/防火墙.gif


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
public/png/采暖系统/板式换热器.svg


BIN
public/png/采暖系统/采暖系统.gif


+ 2 - 0
src/global.d.ts

@@ -3,6 +3,8 @@ import { Meta2d } from "@meta2d/core";
 declare global {
   var meta2d: Meta2d;
   var C2S: any;
+  var folderJson: any;
+  var fileJson: any;
 }
 
 declare interface Window {

+ 18 - 16
src/http.ts

@@ -1,7 +1,7 @@
-import { MessagePlugin } from 'tdesign-vue-next';
-import axios from 'axios';
-import { getCookie } from '@/services/cookie';
-import router from './router';
+import { MessagePlugin } from "tdesign-vue-next";
+import axios from "axios";
+import { getCookie } from "@/services/cookie";
+import router from "./router";
 
 // axios 配置
 axios.defaults.timeout = 60000;
@@ -13,9 +13,11 @@ const requestThrottleSet = new Set();
 // http request 拦截器
 axios.interceptors.request.use(
   (config: any) => {
-    config.baseURL = '/api';
+    if (!config.url.startsWith("/png")) {
+      config.baseURL = "/api";
+    }
     config.headers.Authorization =
-      'Bearer ' + (localStorage.token || getCookie('token') || '');
+      "Bearer " + (localStorage.token || getCookie("token") || "");
 
     if (config.params) {
       // 防抖, 比如输入搜索
@@ -45,7 +47,7 @@ axios.interceptors.request.use(
         const url = config.method + config.url;
         // 已经存在,取消重复请求
         if (requestThrottleSet.has(url)) {
-          return Promise.reject('Repeated request.');
+          return Promise.reject("Repeated request.");
         }
         requestThrottleSet.add(url);
         setTimeout(() => {
@@ -79,7 +81,7 @@ axios.interceptors.response.use(
       return;
     }
     if (error && error.response) {
-      if (error.response.config.url === '/account/profile') {
+      if (error.response.config.url === "/account/profile") {
         return;
       }
 
@@ -95,26 +97,26 @@ axios.interceptors.response.use(
 
       switch (error.response.status) {
         case 401:
-          sessionStorage.setItem('cb', encodeURIComponent(location.href));
-          router.replace({ path: '/login' });
+          sessionStorage.setItem("cb", encodeURIComponent(location.href));
+          router.replace({ path: "/login" });
           break;
         case 403:
-          MessagePlugin.error('请求错误,不合法的请求!');
+          MessagePlugin.error("请求错误,不合法的请求!");
 
           break;
         case 404:
-          if (error.response.config.url.indexOf('/data/') !== 0) {
-            MessagePlugin.error('访问数据不存在,请检查后重试!');
+          if (error.response.config.url.indexOf("/data/") !== 0) {
+            MessagePlugin.error("访问数据不存在,请检查后重试!");
           }
           break;
         case 500:
-          MessagePlugin.error('请求服务错误,请稍后重试!');
+          MessagePlugin.error("请求服务错误,请稍后重试!");
           break;
         case 504:
-          MessagePlugin.error('网络超时,请检测你的网络!');
+          MessagePlugin.error("网络超时,请检测你的网络!");
           break;
         default:
-          MessagePlugin.error('未知网络错误!');
+          MessagePlugin.error("未知网络错误!");
           break;
       }
     }

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 3368 - 1
src/services/defaults.ts


+ 71 - 0
src/services/png.ts

@@ -0,0 +1,71 @@
+import axios from "@/http";
+
+const cdn = import.meta.env.VITE_ROUTER_BASE
+  ? ""
+  : "https://assets.le5lecdn.com";
+
+const market = import.meta.env.VITE_MARKET;
+
+const normalFolder = market ? "/2d/png/" : "/png/";
+/**
+ * 请求 png 的目录
+ * @returns
+ */
+export async function getPngFolders() {
+  return await getFolders(normalFolder);
+}
+
+/**
+ * 请求 png 目录下的所有 png
+ * @param name 目录名
+ * @returns
+ */
+export async function getPngs(name: string) {
+  const files = (await axios.get(normalFolder + name + "/")) as any[];
+  if (!files || !files.map) {
+    return [];
+  }
+  return files.map((f) => {
+    let fname = filename(f.name);
+    return {
+      name: globalThis.fileJson
+        ? globalThis.fileJson[fname]
+          ? globalThis.fileJson[fname]
+          : fname
+        : fname,
+      pinyin: globalThis.fileJson ? fname : null,
+      image: cdn + normalFolder + name + "/" + f.name,
+    };
+  });
+}
+
+export async function getFolders(folderName: string) {
+  const ret = (await axios.get(folderName)) as any[];
+
+  if (!ret || !ret.map) {
+    return [];
+  }
+  return await Promise.all(
+    ret.map(async (c: any) => {
+      const files = (await axios.get(folderName + c.name + "/")) as any[];
+      return {
+        name: globalThis.folderJson
+          ? globalThis.folderJson[c.name]
+            ? globalThis.folderJson[c.name]
+            : c.name
+          : c.name,
+        pinyin: globalThis.folderJson ? c.name : null,
+        show: true,
+        list: [],
+        count: files.length,
+        // 用于区别 png 与 svg 文件夹
+        svgFolder: folderName === normalFolder ? true : false,
+      };
+    })
+  );
+}
+
+export function filename(str: string) {
+  const i = str.lastIndexOf(".");
+  return str.substring(0, i);
+}

+ 133 - 116
src/views/components/Graphics.vue

@@ -10,7 +10,7 @@
       <div class="sub-groups">
         <div
           v-for="group in groups"
-          :class="group.active ? 'active' : ''"
+          :class="group.name === activeGroup ? 'active' : ''"
           @click="groupChange(group.name)"
         >
           <t-icon :name="group.icon" />
@@ -18,129 +18,121 @@
         </div>
       </div>
       <div class="list">
-        <div
-          class="show-item"
-          v-for="item in showList"
-          :draggable="true"
-          @dragstart="dragStart($event, item)"
-          @drag="drag($event, item)"
-          @dragend="dragEnd()"
-        >
-          <t-image
-            v-if="item.image"
-            :src="item.image"
-            fit="cover"
-            :style="{ width: '88px', height: '88px' }"
-          />
-          <i v-else class="t-icon" :class="item.icon"></i>
-          <p>{{ item.name }}</p>
-        </div>
+        <t-collapse @change="handlePanelChange">
+          <t-collapse-panel
+            :value="item.name"
+            :header="item.name"
+            v-for="item in showList"
+          >
+            <div
+              class="show-item"
+              v-for="iItem in item.list"
+              :draggable="true"
+              @dragstart="dragStart($event, iItem)"
+              @drag="drag($event, iItem)"
+              @dragend="dragEnd()"
+            >
+              <t-image v-if="iItem.image" :src="iItem.image" fit="cover" />
+              <!-- <i v-else class="t-icon" :class="iItem.icon"></i> -->
+              <svg v-else class="l-icon" aria-hidden="true">
+                <use :xlink:href="'#' + iItem.icon"></use>
+              </svg>
+              <p>{{ iItem.name }}</p>
+            </div>
+          </t-collapse-panel>
+        </t-collapse>
       </div>
     </div>
   </div>
 </template>
 
 <script lang="ts" setup>
-import { onMounted, onUnmounted, reactive } from 'vue';
+import { onMounted, onUnmounted, reactive, ref } from "vue";
+import { shapeLib, chartLib, formLib } from "@/services/defaults";
+import { getPngFolders } from "@/services/png";
 
+const activeGroup = ref("图形");
 const groups = reactive([
   {
-    icon: 'desktop',
-    name: '场景',
-    key: '',
-    active: false,
+    icon: "desktop",
+    name: "场景",
+    key: "",
+  },
+  {
+    icon: "root-list",
+    name: "模板",
+    key: "",
   },
   {
-    icon: 'root-list',
-    name: '模板',
-    key: '',
-    active: false,
+    icon: "chart",
+    name: "图表",
+    key: "chart",
   },
   {
-    icon: 'chart',
-    name: '图表',
-    key: '',
-    active: false,
+    icon: "control-platform",
+    name: "控件",
+    key: "",
   },
   {
-    icon: 'control-platform',
-    name: '控件',
-    key: '',
-    active: false,
+    icon: "image",
+    name: "素材",
+    key: "",
   },
   {
-    icon: 'file-icon',
-    name: '图标',
-    key: '',
-    active: false,
+    icon: "file-icon",
+    name: "图标",
+    key: "",
   },
   {
-    icon: 'chart-bubble',
-    name: '图形',
-    key: '',
-    active: true,
+    icon: "chart-bubble",
+    name: "图形",
+    key: "shape",
   },
   {
-    icon: 'app',
-    name: '我的',
-    key: '',
-    active: false,
+    icon: "app",
+    name: "我的",
+    key: "",
   },
 ]);
 
-const groupChange = (name: string) => {
-  if (name === '图形') {
+const getSceneLib = () => {};
+
+const getCommponentsLib = () => {};
+
+const getMaterialLib = async () => {
+  const [pngs] = await Promise.all([getPngFolders()]);
+  console.log("png", pngs);
+  return pngs;
+};
+let materialLib: any[] = [];
+
+const groupChange = async (name: string) => {
+  activeGroup.value = name;
+  switch (name) {
+    case "图形":
+      showList.value = shapeLib;
+      break;
+    case "图表":
+      showList.value = chartLib;
+      break;
+    case "控件":
+      showList.value = formLib;
+      break;
+    case "素材":
+      if (materialLib.length === 0) {
+        materialLib = await getMaterialLib();
+      }
+      console.log(materialLib);
+      showList.value = materialLib;
+      break;
   }
 };
 
-const showList = [
-  {
-    name: 'square',
-    icon: 't-icon t-rect',
-    id: '',
-    data: {
-      text: '正方形',
-      width: 100,
-      height: 100,
-      name: 'square',
-    },
-  },
-  {
-    name: 'rectangle',
-    icon: 't-icon t-rectangle',
-    id: 2,
-    data: {
-      text: '圆角矩形',
-      width: 200,
-      height: 50,
-      borderRadius: 0.1,
-      name: 'rectangle',
-    },
-  },
-  {
-    name: 'circle',
-    icon: 't-icon t-circle',
-    image: '',
-    id: 3,
-    data: {
-      text: '圆',
-      width: 100,
-      height: 100,
-      name: 'circle',
-    },
-  },
-  {
-    name: 'triangle',
-    icon: 't-icon t-triangle',
-    id: 4,
-    data: {
-      text: '三角形',
-      width: 100,
-      height: 100,
-      name: 'triangle',
-    },
-  },
-];
+const showList = ref<any[]>([]);
+
+const handlePanelChange = (e) => {
+  console.log("change", e);
+};
 
 const dragStart = (event: DragEvent, item: any) => {
   if (!item || !event.dataTransfer) {
@@ -148,7 +140,7 @@ const dragStart = (event: DragEvent, item: any) => {
   }
 
   event.dataTransfer.setData(
-    'Meta2d',
+    "Meta2d",
     JSON.stringify(item.componentData || item.data)
   );
   event.stopPropagation();
@@ -167,13 +159,14 @@ const dragend = (event: any) => {
 };
 
 onMounted(() => {
-  document.removeEventListener('dragstart', dragstart);
-  document.removeEventListener('dragend', dragend);
+  groupChange("图形");
+  document.removeEventListener("dragstart", dragstart);
+  document.removeEventListener("dragend", dragend);
 });
 
 onUnmounted(() => {
-  document.addEventListener('dragstart', dragstart, false);
-  document.addEventListener('dragend', dragend, false);
+  document.addEventListener("dragstart", dragstart, false);
+  document.addEventListener("dragend", dragend, false);
 });
 </script>
 <style lang="postcss" scoped>
@@ -221,32 +214,56 @@ onUnmounted(() => {
     }
 
     .list {
-      background-color: var(--color-background-active);
-      padding: 12px;
-      display: grid;
-      grid-template-columns: 112px 112px;
-      grid-template-rows: 142px;
+      overflow-y: auto;
+      max-height: calc(100vh - 100px);
+      :deep(.t-collapse) {
+        border: 0px;
+      }
+      :deep(.t-collapse-panel__header) {
+        border: 0px;
+      }
 
+      :deep(.t-collapse-panel__body) {
+        border: 0px;
+      }
+      :deep(.t-collapse-panel__content) {
+        background-color: var(--color-background-active);
+        /* padding: 12px; */
+        padding: 0px;
+        display: grid;
+        grid-template-columns: 61px 61px 61px 61px;
+        grid-template-rows: 90px;
+        padding-bottom: 20px;
+      }
       .show-item {
-        padding: 12px;
+        /* padding: 10px; */
+
         p {
-          margin-top: 10px;
-          height: 20px;
-          line-height: 20px;
+          /* margin-top: 10px; */
+          height: 10px;
+          line-height: 10px;
           text-align: center;
-          font-size: 14px;
+          font-size: 12px;
         }
 
-        i {
+        /* i {
           background-color: #fff;
           border-radius: 4px;
-          height: 88px;
-          width: 88px;
-        }
+          height: 40px;
+          width: 40px;
+          margin: 10px;
+        } */
         .t-image {
           background-color: #fff;
           border-radius: 4px;
         }
+
+        svg {
+          color: var(--color);
+          height: 32px;
+          width: 32px;
+          margin: 10px 14px;
+        }
       }
     }
   }

+ 52 - 2
vite.config.ts

@@ -1,12 +1,14 @@
-import { defineConfig } from "vite";
+import { defineConfig, Plugin, ViteDevServer } from "vite";
 import vue from "@vitejs/plugin-vue";
 import vueJsx from "@vitejs/plugin-vue-jsx";
 import * as path from "path";
 import monacoEditorPlugin from "vite-plugin-monaco-editor";
+import * as fs from "fs";
+import formidable from "formidable";
 
 // https://vitejs.dev/config/
 export default defineConfig({
-  plugins: [vue(), vueJsx(), monacoEditorPlugin({})],
+  plugins: [vue(), vueJsx(), monacoEditorPlugin({}), fileList()],
   resolve: {
     alias: {
       "@": path.resolve(__dirname, "./src/"),
@@ -24,3 +26,51 @@ export default defineConfig({
     },
   },
 });
+
+function fileList(): Plugin {
+  return {
+    name: "vite-plugin-svg-png-files",
+    configureServer(server: ViteDevServer) {
+      server.middlewares.use((req, res, next) => {
+        const url = req.url as string;
+
+        if (
+          (url.startsWith("/svg/") || url.startsWith("/png/")) &&
+          url.endsWith("/")
+        ) {
+          const pwd = decodeURI(path.join(__dirname, "public", url));
+          const files = fs.readdirSync(pwd, {
+            withFileTypes: true,
+          });
+
+          const list: {
+            name: string;
+            type?: string;
+          }[] = [];
+          for (const item of files) {
+            if (item.isDirectory()) {
+              list.push({ name: item.name, type: "directory" });
+            } else {
+              list.push({ name: item.name });
+            }
+          }
+          res.end(JSON.stringify(list));
+        } else if (url === "/img" && req.method === "POST") {
+          const form = formidable({
+            uploadDir: decodeURI(path.join(__dirname, "public", "/img")),
+            keepExtensions: true,
+          });
+          form.parse(req, (err, fields, files) => {
+            if (!err) {
+              res.end(
+                JSON.stringify({ url: "/img/" + files.file.newFilename })
+              );
+            }
+          });
+        } else {
+          next();
+        }
+      });
+    },
+  };
+}

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно