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

feat(ocr): 添加渠道筛选功能并优化详情展示

- 在OcrFavoriteView 和 OcrView 中添加渠道筛选功能
- 优化详情展示布局,提高可读性和美观性
- 添加响应式样式,确保在不同屏幕尺寸下都能良好显示
wui преди 9 месеца
родител
ревизия
1f8024adf4
променени са 2 файла, в които са добавени 300 реда и са изтрити 104 реда
  1. 150 52
      src/views/OcrFavoriteView.vue
  2. 150 52
      src/views/OcrView.vue

+ 150 - 52
src/views/OcrFavoriteView.vue

@@ -1,9 +1,20 @@
 <template>
     <PagingTable url="/ocrRecord/favorite" :query="query" ref="table">
         <template #filter>
-            <ElInput
+            <ElSelect
+                v-if="isAdmin"
                 class="!w-52"
-                placeholder="请输入"
+                v-model="query.channel"
+                placeholder="请选择渠道"
+                clearable
+                @change="table.refresh(true)"
+            >
+                <ElOption label="全部渠道" value="" />
+                <ElOption v-for="item in channelOptions" :key="item" :label="item" :value="item" />
+            </ElSelect>
+            <ElInput
+                class="!w-52 ml-2"
+                placeholder="请输入设备号"
                 clearable
                 v-model="query.deviceId"
                 @keyup.enter="table.refresh(true)"
@@ -12,6 +23,7 @@
                     <ElButton :icon="Search" @click="table.refresh(true)" />
                 </template>
             </ElInput>
+            <ElButton :icon="Refresh" @click="table.refresh(true)" circle />
         </template>
         <ElTableColumn prop="id" label="#" width="80" />
         <ElTableColumn prop="channel" label="渠道" width="150" />
@@ -54,57 +66,32 @@
 
         <ElTableColumn label="详细" align="center">
             <template #default="{ row }">
-                <div style="display: flex; justify-content: center; align-items: center; width: 100%">
-                    <div v-if="row.detail" style="text-align: center">
-                        <div v-for="(value, key) in JSON.parse(row.detail)" :key="key">
-                            <strong
-                                style="
-                                    margin-left: 3px;
-                                    background-color: #f56c6c;
-                                    padding: 2px 4px;
-                                    border-radius: 5px;
-                                    flex-grow: 1;
-                                    text-align: center;
-                                    white-space: nowrap;
-                                "
-                                >{{ key }}</strong
-                            >
-                            <span
-                                style="
-                                    background-color: #e0f7fa;
-                                    color: #00796b;
-                                    padding: 5px 10px;
-                                    border-radius: 5px;
-                                    white-space: nowrap;
-                                    margin-left: 3px;
-                                    cursor: pointer;
-                                "
-                                @click="copyText(value.address)"
-                                :title="'点击复制地址: ' + value.address"
-                                >{{ value.address }}</span
-                            >
-                            <span
-                                style="
-                                    background-color: #f1f8e9;
-                                    color: #388e3c;
-                                    padding: 5px 10px;
-                                    border-radius: 5px;
-                                    white-space: nowrap;
-                                    margin-left: 3px;
-                                "
-                                >{{ value.balance }}</span
-                            >
+                <div class="detail-container">
+                    <div v-if="row.detail" class="detail-content">
+                        <div class="detail-item">
+                            <div class="detail-left">
+                                <div v-for="(value, key) in JSON.parse(row.detail)" :key="key" class="detail-row">
+                                    <strong class="detail-key">{{ key }}</strong>
+                                    <span
+                                        class="detail-address"
+                                        @click="copyText(value.address)"
+                                        :title="'点击复制地址: ' + value.address"
+                                        >{{ value.address }}</span
+                                    >
+                                    <span class="detail-balance">{{ value.balance }}</span>
+                                </div>
+                            </div>
+                            <div class="detail-right">
+                                <ElButton
+                                    :icon="Refresh"
+                                    :loading="row._loading"
+                                    circle
+                                    size="small"
+                                    @click="updateDetail(row)"
+                                ></ElButton>
+                            </div>
                         </div>
                     </div>
-                    <div style="margin-left: 20px">
-                        <ElButton
-                            :icon="Refresh"
-                            :loading="row._loading"
-                            circle
-                            size="small"
-                            @click="updateDetail(row)"
-                        ></ElButton>
-                    </div>
                 </div>
             </template>
         </ElTableColumn>
@@ -152,7 +139,7 @@
     </EditDialog>
 </template>
 <script setup>
-import { inject, ref } from 'vue'
+import { inject, ref, onMounted } from 'vue'
 import PagingTable from '@/components/PagingTable.vue'
 import { useTimeFormatter } from '@/utils/formatter'
 import { Check, Edit, Plus, Search, Refresh, Star, StarOff, Heart, HeartBroken, DropletFilled } from '@vicons/tabler'
@@ -169,6 +156,16 @@ const model = ref({})
 const { showEditDialog } = setupEditDialog(model)
 const { copy } = useClipboard({ legacy: true })
 const isAdmin = inject('isAdminAndOperator')
+const channelOptions = ref([])
+
+onMounted(async () => {
+    try {
+        const response = await http.post('/ocrChannel/names')
+        channelOptions.value = response.data || []
+    } catch (error) {
+        console.error('获取渠道列表失败:', error)
+    }
+})
 
 function formatRecord(record) {
     return record
@@ -264,3 +261,104 @@ async function handleFavoriteClick(row) {
     }
 }
 </script>
+
+<style scoped>
+.detail-container {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    width: 100%;
+}
+
+.detail-content {
+    width: 100%;
+    text-align: center;
+}
+
+.detail-item {
+    display: flex;
+    align-items: flex-start;
+    width: 100%;
+}
+
+.detail-left {
+    flex: 1;
+    display: flex;
+    flex-direction: column;
+    gap: 4px;
+    padding-right: 8px;
+}
+
+.detail-row {
+    display: flex;
+    align-items: center;
+    gap: 4px;
+    width: 100%;
+}
+
+.detail-right {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    flex-shrink: 0;
+    margin-top: 24px; /* 调整这个值来对齐第二行 */
+}
+
+.detail-key {
+    background-color: #f56c6c;
+    padding: 2px 4px;
+    border-radius: 5px;
+    color: white;
+    font-size: 12px;
+    white-space: nowrap;
+}
+
+.detail-address {
+    background-color: #e0f7fa;
+    color: #00796b;
+    padding: 2px 4px;
+    border-radius: 5px;
+    font-size: 12px;
+    cursor: pointer;
+    word-break: break-all;
+    flex: 1;
+    min-width: 0;
+}
+
+.detail-balance {
+    background-color: #f1f8e9;
+    color: #388e3c;
+    padding: 2px 4px;
+    border-radius: 5px;
+    font-size: 12px;
+    white-space: nowrap;
+}
+
+@media (max-width: 768px) {
+    .detail-item {
+        flex-direction: column;
+        align-items: center;
+    }
+    
+    .detail-left {
+        padding-right: 0;
+        margin-bottom: 8px;
+    }
+    
+    .detail-row {
+        flex-direction: column;
+        gap: 4px;
+    }
+    
+    .detail-key,
+    .detail-address,
+    .detail-balance {
+        width: 100%;
+        text-align: center;
+    }
+    
+    .detail-right {
+        margin-top: 8px;
+    }
+}
+</style>

+ 150 - 52
src/views/OcrView.vue

@@ -1,9 +1,19 @@
 <template>
     <PagingTable url="/ocrRecord" :query="query" ref="table">
         <template #filter>
+            <ElSelect
+                class="!w-52 ml-2"
+                v-model="query.channel"
+                placeholder="请选择渠道"
+                clearable
+                @change="table.refresh(true)"
+            >
+                <ElOption label="全部渠道" value="" />
+                <ElOption v-for="item in channelOptions" :key="item" :label="item" :value="item" />
+            </ElSelect>
             <ElInput
                 class="!w-52"
-                placeholder="请输入"
+                placeholder="请输入设备号"
                 clearable
                 v-model="query.deviceId"
                 @keyup.enter="table.refresh(true)"
@@ -13,9 +23,10 @@
                 </template>
             </ElInput>
             <ElButton :icon="ClearAll" @click="exportDialog">清理图片</ElButton>
+            <ElButton :icon="Refresh" @click="table.refresh(true)" circle />
         </template>
         <ElTableColumn prop="id" label="#" width="80" />
-        <ElTableColumn prop="channel" label="渠道" width="150" />
+        <ElTableColumn prop="channel" label="渠道" min-width="10" />
         <ElTableColumn prop="deviceId" label="设备" width="150" align="center">
             <template #default="{ row }">
                 <span
@@ -55,57 +66,32 @@
 
         <ElTableColumn label="详细" align="center">
             <template #default="{ row }">
-                <div style="display: flex; justify-content: center; align-items: center; width: 100%">
-                    <div v-if="row.detail" style="text-align: center">
-                        <div v-for="(value, key) in JSON.parse(row.detail)" :key="key">
-                            <strong
-                                style="
-                                    margin-left: 3px;
-                                    background-color: #f56c6c;
-                                    padding: 2px 4px;
-                                    border-radius: 5px;
-                                    flex-grow: 1;
-                                    text-align: center;
-                                    white-space: nowrap;
-                                "
-                                >{{ key }}</strong
-                            >
-                            <span
-                                style="
-                                    background-color: #e0f7fa;
-                                    color: #00796b;
-                                    padding: 5px 10px;
-                                    border-radius: 5px;
-                                    white-space: nowrap;
-                                    margin-left: 3px;
-                                    cursor: pointer;
-                                "
-                                @click="copyText(value.address)"
-                                :title="'点击复制地址: ' + value.address"
-                                >{{ value.address }}</span
-                            >
-                            <span
-                                style="
-                                    background-color: #f1f8e9;
-                                    color: #388e3c;
-                                    padding: 5px 10px;
-                                    border-radius: 5px;
-                                    white-space: nowrap;
-                                    margin-left: 3px;
-                                "
-                                >{{ value.balance }}</span
-                            >
+                <div class="detail-container">
+                    <div v-if="row.detail" class="detail-content">
+                        <div class="detail-item">
+                            <div class="detail-left">
+                                <div v-for="(value, key) in JSON.parse(row.detail)" :key="key" class="detail-row">
+                                    <strong class="detail-key">{{ key }}</strong>
+                                    <span
+                                        class="detail-address"
+                                        @click="copyText(value.address)"
+                                        :title="'点击复制地址: ' + value.address"
+                                        >{{ value.address }}</span
+                                    >
+                                    <span class="detail-balance">{{ value.balance }}</span>
+                                </div>
+                            </div>
+                            <div class="detail-right">
+                                <ElButton
+                                    :icon="Refresh"
+                                    :loading="row._loading"
+                                    circle
+                                    size="small"
+                                    @click="updateDetail(row)"
+                                ></ElButton>
+                            </div>
                         </div>
                     </div>
-                    <div style="margin-left: 20px">
-                        <ElButton
-                            :icon="Refresh"
-                            :loading="row._loading"
-                            circle
-                            size="small"
-                            @click="updateDetail(row)"
-                        ></ElButton>
-                    </div>
                 </div>
             </template>
         </ElTableColumn>
@@ -173,7 +159,7 @@
     </ElDialog>
 </template>
 <script setup>
-import { inject, ref } from 'vue'
+import { inject, ref, onMounted } from 'vue'
 import PagingTable from '@/components/PagingTable.vue'
 import { useTimeFormatter } from '@/utils/formatter'
 import { Check, Edit, Plus, Search, Refresh, Star, StarOff, ClearAll } from '@vicons/tabler'
@@ -238,6 +224,17 @@ const shortcuts = [
     }
 ]
 
+const channelOptions = ref([])
+
+onMounted(async () => {
+    try {
+        const response = await http.post('/ocrChannel/names')
+        channelOptions.value = response.data || []
+    } catch (error) {
+        console.error('获取渠道列表失败:', error)
+    }
+})
+
 function formatRecord(record) {
     return record
         .split('\n')
@@ -368,3 +365,104 @@ async function confirmExport() {
     exportDialog()
 }
 </script>
+
+<style scoped>
+.detail-container {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    width: 100%;
+}
+
+.detail-content {
+    width: 100%;
+    text-align: center;
+}
+
+.detail-item {
+    display: flex;
+    align-items: flex-start;
+    width: 100%;
+}
+
+.detail-left {
+    flex: 1;
+    display: flex;
+    flex-direction: column;
+    gap: 4px;
+    padding-right: 8px;
+}
+
+.detail-row {
+    display: flex;
+    align-items: center;
+    gap: 4px;
+    width: 100%;
+}
+
+.detail-right {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    flex-shrink: 0;
+    margin-top: 24px; /* 调整这个值来对齐第二行 */
+}
+
+.detail-key {
+    background-color: #f56c6c;
+    padding: 2px 4px;
+    border-radius: 5px;
+    color: white;
+    font-size: 12px;
+    white-space: nowrap;
+}
+
+.detail-address {
+    background-color: #e0f7fa;
+    color: #00796b;
+    padding: 2px 4px;
+    border-radius: 5px;
+    font-size: 12px;
+    cursor: pointer;
+    word-break: break-all;
+    flex: 1;
+    min-width: 0;
+}
+
+.detail-balance {
+    background-color: #f1f8e9;
+    color: #388e3c;
+    padding: 2px 4px;
+    border-radius: 5px;
+    font-size: 12px;
+    white-space: nowrap;
+}
+
+@media (max-width: 768px) {
+    .detail-item {
+        flex-direction: column;
+        align-items: center;
+    }
+
+    .detail-left {
+        padding-right: 0;
+        margin-bottom: 8px;
+    }
+
+    .detail-row {
+        flex-direction: column;
+        gap: 4px;
+    }
+
+    .detail-key,
+    .detail-address,
+    .detail-balance {
+        width: 100%;
+        text-align: center;
+    }
+
+    .detail-right {
+        margin-top: 8px;
+    }
+}
+</style>