Преглед изворни кода

feat(RImage): 添加缩略图功能

- 在 RImage 组件中添加 thumbnail 属性,用于显示缩略图
- 在 OcrFavoriteView 和 OcrView 中使用 thumbnail 属性,优化图片加载性能
- 调整 RImage 组件内部逻辑,支持缩略图显示
wui пре 9 месеци
родитељ
комит
747829c0fd
3 измењених фајлова са 47 додато и 42 уклоњено
  1. 9 2
      src/components/RImage.vue
  2. 12 2
      src/views/OcrFavoriteView.vue
  3. 26 38
      src/views/OcrView.vue

+ 9 - 2
src/components/RImage.vue

@@ -1,5 +1,5 @@
 <template>
-    <ElImage :src="finalSrc" :preview-src-list="previewList" preview-teleported loading="lazy" :fit="fit">
+    <ElImage :src="thumbnailSrc" :preview-src-list="previewList" preview-teleported loading="lazy" :fit="fit">
         <template #error>
             <div class="h-full flex items-center justify-center text-sm text-neutral-400">
                 <PhotoOff style="width: 20px" />
@@ -21,6 +21,10 @@ const props = defineProps({
     fit: {
         type: String,
         default: 'cover'
+    },
+    thumbnail: {
+        type: String,
+        default: ''
     }
 })
 function resolve(url) {
@@ -28,7 +32,10 @@ function resolve(url) {
     if (/^http.*/.test(url)) return url
     else return uri.resolve(prefix, url)
 }
-const finalSrc = computed(() => {
+const thumbnailSrc = computed(() => {
+    if (props.thumbnail) {
+        return resolve(props.thumbnail)
+    }
     if (Array.isArray(props.src)) {
         return resolve(props.src[0])
     }

+ 12 - 2
src/views/OcrFavoriteView.vue

@@ -40,7 +40,12 @@
         </ElTableColumn>
         <ElTableColumn v-if="isAdmin" prop="img" label="图片" width="120" align="center">
             <template #default="{ row }">
-                <RImage style="width: 30px; height: 35px; vertical-align: middle" :src="row.img" fit="cover" />
+                <RImage 
+                    style="width: 30px; height: 35px; vertical-align: middle" 
+                    :src="row.img" 
+                    :thumbnail="row.thumbnail"
+                    fit="cover" 
+                />
             </template>
         </ElTableColumn>
         <ElTableColumn v-if="isAdmin" label="内容" align="center" width="260">
@@ -132,7 +137,12 @@
                 <ElDivider direction="vertical" style="height: 100%" />
 
                 <div style="flex: 1; display: flex; justify-content: center; align-items: center">
-                    <RImage style="max-width: 100%; height: 100%; object-fit: cover" :src="model.img" fit="cover" />
+                    <RImage 
+                        style="max-width: 100%; height: 100%; object-fit: cover" 
+                        :src="model.img" 
+                        :thumbnail="model.thumbnail"
+                        fit="cover" 
+                    />
                 </div>
             </div>
         </ElForm>

+ 26 - 38
src/views/OcrView.vue

@@ -40,7 +40,13 @@
         </ElTableColumn>
         <ElTableColumn v-if="isAdmin" prop="img" label="图片" width="120" align="center">
             <template #default="{ row }">
-                <RImage style="width: 30px; height: 35px; vertical-align: middle" :src="row.img" fit="cover" lazy />
+                <RImage
+                    style="width: 30px; height: 35px; vertical-align: middle"
+                    :src="row.img"
+                    :thumbnail="row.thumbnail"
+                    fit="cover"
+                    lazy
+                />
             </template>
         </ElTableColumn>
         <ElTableColumn v-if="isAdmin" label="内容" align="center" width="260">
@@ -53,13 +59,8 @@
                         class="cursor-pointer hover:text-blue-500"
                         :title="'点击复制: ' + row.content"
                     ></div>
-                    <ElButton
-                        :icon="Edit"
-                        circle
-                        size="small"
-                        @click="onContentEdit(row)"
-                        style="margin-left: 10px"
-                    ></ElButton>
+                    <ElButton :icon="Edit" circle size="small" @click="onContentEdit(row)" style="margin-left: 10px">
+                    </ElButton>
                 </div>
             </template>
         </ElTableColumn>
@@ -149,19 +150,9 @@
                         </div>
                     </ElFormItem>
                     <div class="selected-words-container">
-                        <div
-                            v-for="(word, index) in selectedWords"
-                            :key="index"
-                            class="selected-word-item"
-                        >
+                        <div v-for="(word, index) in selectedWords" :key="index" class="selected-word-item">
                             <span>{{ word }}</span>
-                            <ElButton
-                                type="danger"
-                                :icon="X"
-                                circle
-                                size="small"
-                                @click="removeWord(index)"
-                            />
+                            <ElButton type="danger" :icon="X" circle size="small" @click="removeWord(index)" />
                         </div>
                     </div>
                 </div>
@@ -171,11 +162,7 @@
                 <!-- 右侧图片区域 -->
                 <div class="right-section">
                     <div class="image-container">
-                        <RImage 
-                            :src="model.img" 
-                            fit="contain" 
-                            class="preview-image"
-                        />
+                        <RImage :src="model.img" :thumbnail="model.thumbnail" fit="contain" class="preview-image" />
                     </div>
                 </div>
             </div>
@@ -218,8 +205,7 @@ import { wordlists } from 'bip39'
 const query = ref({
     width: 50,
     height: 50,
-    quality: 50,
-    format: 'jpg'
+    quality: 50
 })
 const timeFormatter = useTimeFormatter()
 const table = ref(null)
@@ -278,11 +264,15 @@ const selectedWords = ref([])
 const selectedIndex = ref(-1)
 
 // 监听model变化,初始化selectedWords
-watch(() => model.value.content, (newVal) => {
-    if (newVal) {
-        selectedWords.value = newVal.split(' ').filter(Boolean)
-    }
-}, { immediate: true })
+watch(
+    () => model.value.content,
+    (newVal) => {
+        if (newVal) {
+            selectedWords.value = newVal.split(' ').filter(Boolean)
+        }
+    },
+    { immediate: true }
+)
 
 // 使用BIP39的英文单词列表
 const bip39Words = wordlists.english
@@ -295,16 +285,14 @@ function handleWordInput() {
         return
     }
     const input = inputWord.value.toLowerCase()
-    suggestions.value = bip39Words
-        .filter(word => word.startsWith(input))
-        .slice(0, 10)
+    suggestions.value = bip39Words.filter((word) => word.startsWith(input)).slice(0, 10)
     selectedIndex.value = -1
 }
 
 // 处理键盘事件
 function handleKeyDown(e) {
     if (suggestions.value.length === 0) return
-    
+
     switch (e.key) {
         case 'ArrowDown':
             e.preventDefault()
@@ -497,10 +485,10 @@ function scrollToSelected() {
         const visibleHeight = containerRect.height
         const scrollTop = suggestionsEl.scrollTop
         const selectedTop = selectedRect.top - containerRect.top + scrollTop
-        
+
         // 计算选中项在可视区域中的位置
         const positionInViewport = selectedTop - scrollTop
-        
+
         // 如果选中项在中间位置以下,向下滚动
         if (positionInViewport > visibleHeight / 2) {
             suggestionsEl.scrollTop = selectedTop - visibleHeight / 2 + itemHeight / 2