Преглед на файлове

fix: 修复问题,优化图片资源功能

jiaxing.liao преди 2 седмици
родител
ревизия
6a0a4b05e6

+ 0 - 49
electron.vite.config.1772589627417.mjs

@@ -1,49 +0,0 @@
-// electron.vite.config.ts
-import { resolve } from "path";
-import { defineConfig, externalizeDepsPlugin, bytecodePlugin } from "electron-vite";
-import vue from "@vitejs/plugin-vue";
-import monacoEditorPlugin from "vite-plugin-monaco-editor";
-import AutoImport from "unplugin-auto-import/vite";
-import Components from "unplugin-vue-components/vite";
-import { ElementPlusResolver } from "unplugin-vue-components/resolvers";
-import UnoCSS from "unocss/vite";
-import vueJsx from "@vitejs/plugin-vue-jsx";
-import AppLoading from "vite-plugin-app-loading";
-var electron_vite_config_default = defineConfig({
-  main: {
-    plugins: [externalizeDepsPlugin(), bytecodePlugin()]
-  },
-  preload: {
-    plugins: [externalizeDepsPlugin(), bytecodePlugin()]
-  },
-  renderer: {
-    resolve: {
-      alias: {
-        "@": resolve("src/renderer/src"),
-        "~@": resolve("src/renderer/src")
-      }
-    },
-    plugins: [
-      vue(),
-      monacoEditorPlugin.default({
-        languageWorkers: ["editorWorkerService", "json"],
-        customDistPath: (root) => {
-          return `${root}/dist/monaco-editor`;
-        }
-      }),
-      // 自定引入插件
-      AutoImport({
-        resolvers: [ElementPlusResolver()]
-      }),
-      Components({
-        resolvers: [ElementPlusResolver()]
-      }),
-      UnoCSS(),
-      vueJsx(),
-      AppLoading("src/renderer/loading.html")
-    ]
-  }
-});
-export {
-  electron_vite_config_default as default
-};

+ 1 - 1
src/renderer/src/lvgl-widgets/switch/index.ts

@@ -28,7 +28,7 @@ export default {
     }
   ],
   defaultSchema: {
-    name: 'button',
+    name: 'switch',
     props: {
       x: 0,
       y: 0,

+ 45 - 51
src/renderer/src/views/designer/sidebar/Resource.vue

@@ -2,29 +2,32 @@
   <SplitterCollapse>
     <SplitterCollapseItem title="图片">
       <template #header-right>
-        <el-tooltip content="添加">
-          <el-button type="text" class="mr-12px" @click.capture.stop="handleAddImage"
-            ><LuPlus size="14px"
-          /></el-button>
-        </el-tooltip>
+        <div class="flex items-center">
+          <el-tooltip content="清除未使用图片">
+            <span @click.stop>
+              <el-popconfirm class="box-item" title="确认清除?" @confirm="handleClearUnusedImage">
+                <template #reference>
+                  <el-button type="danger" link class="mr-12px">
+                    <LuTrash2 size="14px" />
+                  </el-button>
+                </template>
+              </el-popconfirm>
+            </span>
+          </el-tooltip>
+          <el-tooltip content="添加">
+            <el-button type="text" class="mr-12px" @click.capture.stop="handleAddImage">
+              <LuPlus size="14px" />
+            </el-button>
+          </el-tooltip>
+        </div>
       </template>
       <div class="w-full h-full flex flex-col">
         <div class="p-12px flex gap-8px shrink-0">
-          <el-input
-            spellcheck="false"
-            v-model="imageSearch"
-            size="small"
-            placeholder="输入搜索..."
-          />
+          <el-input spellcheck="false" v-model="imageSearch" size="small" placeholder="输入搜索..." />
         </div>
         <el-scrollbar class="flex-1">
-          <ResourceItem
-            v-for="item in getImages || []"
-            :key="item.id"
-            :data="item"
-            type="image"
-            @delete="deleteResource(item, 'images')"
-          />
+          <ResourceItem v-for="item in getImages || []" :key="item.id" :data="item" type="image"
+            @delete="deleteResource(item, 'images')" />
           <div v-if="!getImages?.length" class="text-center text-text-secondary">暂无图片~</div>
         </el-scrollbar>
       </div>
@@ -32,28 +35,18 @@
     <SplitterCollapseItem title="字体">
       <template #header-right>
         <el-tooltip content="添加">
-          <el-button type="text" class="mr-12px" @click.capture.stop="handleAddFont"
-            ><LuPlus size="14px"
-          /></el-button>
+          <el-button type="text" class="mr-12px" @click.capture.stop="handleAddFont">
+            <LuPlus size="14px" />
+          </el-button>
         </el-tooltip>
       </template>
       <div class="w-full h-full flex flex-col">
         <div class="p-12px flex gap-8px shrink-0">
-          <el-input
-            spellcheck="false"
-            v-model="fontSearch"
-            size="small"
-            placeholder="输入搜索..."
-          />
+          <el-input spellcheck="false" v-model="fontSearch" size="small" placeholder="输入搜索..." />
         </div>
         <el-scrollbar class="flex-1">
-          <ResourceItem
-            v-for="item in getFonts || []"
-            :key="item.id"
-            :data="item"
-            type="font"
-            @delete="deleteResource(item, 'fonts')"
-          />
+          <ResourceItem v-for="item in getFonts || []" :key="item.id" :data="item" type="font"
+            @delete="deleteResource(item, 'fonts')" />
           <div v-if="!getFonts?.length" class="text-center text-text-secondary">暂无字体~</div>
         </el-scrollbar>
       </div>
@@ -61,28 +54,18 @@
     <SplitterCollapseItem title="其他资源">
       <template #header-right>
         <el-tooltip content="添加">
-          <el-button type="text" class="mr-12px" @click.capture.stop="handleAddOther"
-            ><LuPlus size="14px"
-          /></el-button>
+          <el-button type="text" class="mr-12px" @click.capture.stop="handleAddOther">
+            <LuPlus size="14px" />
+          </el-button>
         </el-tooltip>
       </template>
       <div class="w-full h-full flex flex-col">
         <div class="p-12px flex gap-8px shrink-0">
-          <el-input
-            spellcheck="false"
-            v-model="otherSearch"
-            size="small"
-            placeholder="输入搜索..."
-          />
+          <el-input spellcheck="false" v-model="otherSearch" size="small" placeholder="输入搜索..." />
         </div>
         <el-scrollbar class="flex-1">
-          <ResourceItem
-            v-for="item in getOthers || []"
-            :key="item.id"
-            :data="item"
-            type="other"
-            @delete="deleteResource(item, 'others')"
-          />
+          <ResourceItem v-for="item in getOthers || []" :key="item.id" :data="item" type="other"
+            @delete="deleteResource(item, 'others')" />
           <div v-if="!getOthers?.length" class="text-center text-text-secondary">暂无资源~</div>
         </el-scrollbar>
       </div>
@@ -95,7 +78,7 @@ import type { FontResource, ImageResource, OtherResource, Resource } from '@/typ
 
 import { ref, computed } from 'vue'
 import { SplitterCollapse, SplitterCollapseItem } from '@/components/SplitterCollapse'
-import { LuPlus } from 'vue-icons-plus/lu'
+import { LuPlus, LuTrash2 } from 'vue-icons-plus/lu'
 import { useProjectStore } from '@/store/modules/project'
 import { createFileResource } from '@/model'
 import ResourceItem from './components/ResourceItem.vue'
@@ -213,6 +196,17 @@ const deleteResource = async (resource: Resource, type: 'images' | 'fonts' | 'ot
     projectStore.project?.resources[type].splice(index, 1)
   }
 }
+
+// 清除未使用图片
+const handleClearUnusedImage = () => {
+  projectStore.project?.resources.images.forEach((item) => {
+    const str = JSON.stringify(projectStore.project?.screens ?? [])
+    const count = str.split(item.id).length - 1
+    if (count === 0) {
+      deleteResource(item, 'images')
+    }
+  })
+}
 </script>
 
 <style scoped></style>

+ 65 - 36
src/renderer/src/views/designer/sidebar/components/ResourceItem.vue

@@ -1,58 +1,45 @@
 <template>
-  <p
-    ref="listBoxRef"
+  <p ref="listBoxRef"
     class="h-32px flex items-center justify-between gap-4px px-4 py-2 m-0 overflow-hidden group/item hover:bg-bg-tertiary"
-    @click="handleClick"
-    @contextmenu="handleContextmenu"
-  >
+    @click="handleClick" @contextmenu="handleContextmenu">
     <span v-if="type === 'font'" class="w-32px h-32px grid place-items-center">
       <BsFiletypeTtf v-if="data.fielType === 'ttf'" size="16px" />
       <BsFiletypeWoff v-else-if="data.fielType === 'woff'" size="16px" />
       <img v-else :src="fontImg" class="w-16px h-16px" />
     </span>
-    <span
-      v-if="type === 'image'"
-      class="w-32px h-32px rounded-4px bg-bg-tertiary grid place-items-center"
-    >
-      <LocalImage
-        :src="projectStore.projectPath + data.path"
-        class="h-full w-full object-contain"
-      />
+    <span v-if="type === 'image'" class="shrink-0 w-32px h-32px rounded-4px bg-bg-tertiary grid place-items-center">
+      <LocalImage :src="projectStore.projectPath + data.path" class="h-full w-full object-contain" />
     </span>
-    <span class="flex-1 truncate" :title="data.fileName">{{ data.fileName }}</span>
+    <span class="flex-1 flex items-center gap-4px">
+      <span class="truncate max-w-120px" :title="data.fileName">{{ data.fileName }}</span>
+      <span class="flex flex-col gap-2px w-80px text-8px text-text-secondary">
+        <span>分辨率:{{ imageInfo.width }}x{{ imageInfo.height }}</span>
+        <span>使用次数:{{ imageInfo.useCount }}</span>
+      </span>
+    </span>
+
 
     <span class="items-center gap-8px shrink-0 hidden group-hover/item:flex">
       <el-tooltip content="编辑" :append-to="listBoxRef">
-        <span v-if="type !== 'other'" class="cursor-pointer" @click="handleEdit"
-          ><LuPencilLine size="14px"
-        /></span>
+        <span v-if="type !== 'other'" class="cursor-pointer" @click="handleEdit">
+          <LuPencilLine size="14px" />
+        </span>
       </el-tooltip>
       <el-tooltip content="删除" :append-to="listBoxRef">
         <span>
-          <el-popconfirm
-            :append-to="listBoxRef"
-            class="box-item"
-            title="确认删除?"
-            @confirm="$emit('delete')"
-          >
+          <el-popconfirm :append-to="listBoxRef" class="box-item" title="确认删除?" @confirm="$emit('delete')">
             <template #reference>
-              <span class="cursor-pointer"><LuTrash2 size="14px" /></span>
+              <span class="cursor-pointer">
+                <LuTrash2 size="14px" />
+              </span>
             </template>
           </el-popconfirm>
         </span>
       </el-tooltip>
     </span>
-    <el-dropdown
-      ref="dropdownRef"
-      :virtual-ref="triggerRef"
-      :show-arrow="false"
-      :popper-options="{
-        modifiers: [{ name: 'offset', options: { offset: [0, 0] } }]
-      }"
-      virtual-triggering
-      trigger="contextmenu"
-      placement="bottom-start"
-    >
+    <el-dropdown ref="dropdownRef" :virtual-ref="triggerRef" :show-arrow="false" :popper-options="{
+      modifiers: [{ name: 'offset', options: { offset: [0, 0] } }]
+    }" virtual-triggering trigger="contextmenu" placement="bottom-start">
       <template #dropdown>
         <el-dropdown-menu>
           <el-dropdown-item @click="openInExplorer">在资源管理器中打开</el-dropdown-item>
@@ -70,7 +57,7 @@
 import type { FontResource, ImageResource, Resource } from '@/types/resource'
 import type { DropdownInstance } from 'element-plus'
 
-import { ref } from 'vue'
+import { ref, watch } from 'vue'
 import LocalImage from '@/components/LocalImage/index.vue'
 import { useProjectStore } from '@/store/modules/project'
 import { LuTrash2, LuPencilLine } from 'vue-icons-plus/lu'
@@ -78,6 +65,7 @@ import { BsFiletypeTtf, BsFiletypeWoff } from 'vue-icons-plus/bs'
 import fontImg from '@/assets/font.svg'
 import EditImageModal from './EditImageModal.vue'
 import EditFontModal from './EditFontModal.vue'
+import { getImageByPath } from '@/utils'
 
 defineEmits<{
   delete: []
@@ -105,6 +93,47 @@ const triggerRef = ref({
   getBoundingClientRect: () => position.value
 })
 
+const imageInfo = ref<{
+  width?: number
+  height?: number
+  useCount?: number
+}>({
+  width: 0,
+  height: 0,
+  useCount: 0
+})
+
+watch(
+  () => props.type,
+  async () => {
+    if (props.type === 'image') {
+      const resouce = props.data as ImageResource
+      const res = await getImageByPath(projectStore.projectPath + resouce.path)
+      imageInfo.value.width = res?.dimensions.width
+      imageInfo.value.height = res?.dimensions.height
+    }
+  },
+  {
+    immediate: true
+  }
+)
+
+watch(
+  () => projectStore.project,
+  async () => {
+    if (projectStore.project && props.type === 'image') {
+      const str = JSON.stringify(projectStore.project.screens)
+      // 判断图片id出现的次数
+      const count = str.split(props.data.id).length - 1
+      imageInfo.value.useCount = count
+    }
+  },
+  {
+    immediate: true,
+    deep: true
+  }
+)
+
 const handleClick = () => {
   dropdownRef.value?.handleClose()
 }