mirror of
https://github.com/Kuingsmile/PicList.git
synced 2025-02-08 21:38:13 -05:00
✨ Feature: add batch rename , sort and more search options for gallery
This commit is contained in:
parent
76c0cfbcb3
commit
38e48dfd13
@ -65,6 +65,11 @@ GALLERY_SYNC_DELETE: Cloud Sync Delete
|
|||||||
GALLERY_SYNC_DELETE_NOTICE_TITLE: Notice
|
GALLERY_SYNC_DELETE_NOTICE_TITLE: Notice
|
||||||
GALLERY_SYNC_DELETE_NOTICE_SUCCEED: Cloud Delete Succeed
|
GALLERY_SYNC_DELETE_NOTICE_SUCCEED: Cloud Delete Succeed
|
||||||
GALLERY_SYNC_DELETE_NOTICE_FAILED: Cloud Delete Failed
|
GALLERY_SYNC_DELETE_NOTICE_FAILED: Cloud Delete Failed
|
||||||
|
GALLERY_CHANGE_URL: Rename
|
||||||
|
GALLERY_CHANGE_URL_TITLE: Batch Change Image URL
|
||||||
|
GALLERY_SEARCH_FILENAME: Search by Filename
|
||||||
|
GALLERY_SEARCH_URL: Search by URL
|
||||||
|
GALLERY_MATCHED: ' Matched: '
|
||||||
|
|
||||||
UPLOAD_PAGE_IMAGE_PROCESS_NAME: Image Processing
|
UPLOAD_PAGE_IMAGE_PROCESS_NAME: Image Processing
|
||||||
UPLOAD_PAGE_IMAGE_PROCESS_DIALOG_TITLE: Image Processing Settings
|
UPLOAD_PAGE_IMAGE_PROCESS_DIALOG_TITLE: Image Processing Settings
|
||||||
|
@ -65,6 +65,11 @@ GALLERY_SYNC_DELETE: 删除云端
|
|||||||
GALLERY_SYNC_DELETE_NOTICE_TITLE: 通知
|
GALLERY_SYNC_DELETE_NOTICE_TITLE: 通知
|
||||||
GALLERY_SYNC_DELETE_NOTICE_SUCCEED: 云端删除成功
|
GALLERY_SYNC_DELETE_NOTICE_SUCCEED: 云端删除成功
|
||||||
GALLERY_SYNC_DELETE_NOTICE_FAILED: 云端删除失败
|
GALLERY_SYNC_DELETE_NOTICE_FAILED: 云端删除失败
|
||||||
|
GALLERY_CHANGE_URL: 修改
|
||||||
|
GALLERY_CHANGE_URL_TITLE: 批量修改图片URL
|
||||||
|
GALLERY_SEARCH_FILENAME: 搜索文件名
|
||||||
|
GALLERY_SEARCH_URL: 搜索URL
|
||||||
|
GALLERY_MATCHED: ' 匹配到: '
|
||||||
|
|
||||||
UPLOAD_PAGE_IMAGE_PROCESS_NAME: 图片处理
|
UPLOAD_PAGE_IMAGE_PROCESS_NAME: 图片处理
|
||||||
UPLOAD_PAGE_IMAGE_PROCESS_DIALOG_TITLE: 图片处理设置
|
UPLOAD_PAGE_IMAGE_PROCESS_DIALOG_TITLE: 图片处理设置
|
||||||
|
@ -65,6 +65,11 @@ GALLERY_SYNC_DELETE: 刪除雲端
|
|||||||
GALLERY_SYNC_DELETE_NOTICE_TITLE: 通知
|
GALLERY_SYNC_DELETE_NOTICE_TITLE: 通知
|
||||||
GALLERY_SYNC_DELETE_NOTICE_SUCCEED: 雲端刪除成功
|
GALLERY_SYNC_DELETE_NOTICE_SUCCEED: 雲端刪除成功
|
||||||
GALLERY_SYNC_DELETE_NOTICE_FAILED: 雲端刪除失敗
|
GALLERY_SYNC_DELETE_NOTICE_FAILED: 雲端刪除失敗
|
||||||
|
GALLERY_CHANGE_URL: 修改
|
||||||
|
GALLERY_CHANGE_URL_TITLE: 批量修改圖片URL
|
||||||
|
GALLERY_SEARCH_FILENAME: 搜尋文件名
|
||||||
|
GALLERY_SEARCH_URL: 搜尋URL
|
||||||
|
GALLERY_MATCHED: ' 匹配到: '
|
||||||
|
|
||||||
UPLOAD_PAGE_IMAGE_PROCESS_NAME: 圖片處理
|
UPLOAD_PAGE_IMAGE_PROCESS_NAME: 圖片處理
|
||||||
UPLOAD_PAGE_IMAGE_PROCESS_DIALOG_TITLE: 圖片處理設置
|
UPLOAD_PAGE_IMAGE_PROCESS_DIALOG_TITLE: 圖片處理設置
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
class="handle-bar"
|
class="handle-bar"
|
||||||
:gutter="16"
|
:gutter="16"
|
||||||
>
|
>
|
||||||
<el-col :span="12">
|
<el-col :span="6">
|
||||||
<el-select
|
<el-select
|
||||||
v-model="choosedPicBed"
|
v-model="choosedPicBed"
|
||||||
multiple
|
multiple
|
||||||
@ -48,7 +48,25 @@
|
|||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="10">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="dateRange"
|
||||||
|
type="daterange"
|
||||||
|
unlink-panels
|
||||||
|
range-separator="To"
|
||||||
|
start-placeholder="Start date"
|
||||||
|
end-placeholder="End date"
|
||||||
|
size="small"
|
||||||
|
/>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="1">
|
||||||
|
<el-divider
|
||||||
|
direction="vertical"
|
||||||
|
style="height: 100%;"
|
||||||
|
border-style="hidden"
|
||||||
|
/>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="5">
|
||||||
<el-select
|
<el-select
|
||||||
v-model="pasteStyle"
|
v-model="pasteStyle"
|
||||||
size="small"
|
size="small"
|
||||||
@ -64,15 +82,40 @@
|
|||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
<el-col :span="2">
|
||||||
|
<el-dropdown>
|
||||||
|
<el-button
|
||||||
|
size="small"
|
||||||
|
type="primary"
|
||||||
|
:icon="Sort"
|
||||||
|
>
|
||||||
|
{{ $T('MANAGE_BUCKET_SORT_TITLE') }}
|
||||||
|
</el-button>
|
||||||
|
<template #dropdown>
|
||||||
|
<el-dropdown-item @click="sortFile('name')">
|
||||||
|
{{ $T('MANAGE_BUCKET_SORT_NAME') }}
|
||||||
|
</el-dropdown-item>
|
||||||
|
<el-dropdown-item @click="sortFile('ext')">
|
||||||
|
{{ $T('MANAGE_BUCKET_SORT_TYPE') }}
|
||||||
|
</el-dropdown-item>
|
||||||
|
<el-dropdown-item @click="sortFile('time')">
|
||||||
|
{{ $T('MANAGE_BUCKET_SORT_TIME') }}
|
||||||
|
</el-dropdown-item>
|
||||||
|
<el-dropdown-item @click="sortFile('check')">
|
||||||
|
{{ $T('MANAGE_BUCKET_SORT_SELECTED') }}
|
||||||
|
</el-dropdown-item>
|
||||||
|
</template>
|
||||||
|
</el-dropdown>
|
||||||
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-row
|
<el-row
|
||||||
class="handle-bar"
|
class="handle-bar"
|
||||||
:gutter="16"
|
:gutter="16"
|
||||||
>
|
>
|
||||||
<el-col :span="12">
|
<el-col :span="6">
|
||||||
<el-input
|
<el-input
|
||||||
v-model="searchText"
|
v-model="searchText"
|
||||||
:placeholder="$T('SEARCH')"
|
:placeholder="$T('GALLERY_SEARCH_FILENAME')"
|
||||||
size="small"
|
size="small"
|
||||||
>
|
>
|
||||||
<template #suffix>
|
<template #suffix>
|
||||||
@ -86,7 +129,24 @@
|
|||||||
</template>
|
</template>
|
||||||
</el-input>
|
</el-input>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="4">
|
<el-col :span="6">
|
||||||
|
<el-input
|
||||||
|
v-model="searchTextURL"
|
||||||
|
:placeholder="$T('GALLERY_SEARCH_URL')"
|
||||||
|
size="small"
|
||||||
|
>
|
||||||
|
<template #suffix>
|
||||||
|
<el-icon
|
||||||
|
class="el-input__icon"
|
||||||
|
style="cursor: pointer;"
|
||||||
|
@click="cleanSearchUrl"
|
||||||
|
>
|
||||||
|
<close />
|
||||||
|
</el-icon>
|
||||||
|
</template>
|
||||||
|
</el-input>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="3">
|
||||||
<div
|
<div
|
||||||
class="item-base copy round"
|
class="item-base copy round"
|
||||||
:class="{ active: isMultiple(choosedList) }"
|
:class="{ active: isMultiple(choosedList) }"
|
||||||
@ -95,7 +155,16 @@
|
|||||||
{{ $T('COPY') }}
|
{{ $T('COPY') }}
|
||||||
</div>
|
</div>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="4">
|
<el-col :span="3">
|
||||||
|
<div
|
||||||
|
class="item-base all-pick round"
|
||||||
|
:class="{ active: filterList.length > 0 }"
|
||||||
|
@click="() => isShowBatchRenameDialog = true"
|
||||||
|
>
|
||||||
|
{{ $T('GALLERY_CHANGE_URL') }}
|
||||||
|
</div>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="3">
|
||||||
<div
|
<div
|
||||||
class="item-base delete round"
|
class="item-base delete round"
|
||||||
:class="{ active: isMultiple(choosedList) }"
|
:class="{ active: isMultiple(choosedList) }"
|
||||||
@ -104,7 +173,7 @@
|
|||||||
{{ $T('DELETE') }}
|
{{ $T('DELETE') }}
|
||||||
</div>
|
</div>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="4">
|
<el-col :span="3">
|
||||||
<div
|
<div
|
||||||
class="item-base all-pick round"
|
class="item-base all-pick round"
|
||||||
:class="{ active: filterList.length > 0 }"
|
:class="{ active: filterList.length > 0 }"
|
||||||
@ -213,13 +282,124 @@
|
|||||||
</el-button>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
<el-dialog
|
||||||
|
v-model="isShowBatchRenameDialog"
|
||||||
|
:title="$T('CHANGE_IMAGE_URL')"
|
||||||
|
center
|
||||||
|
align-center
|
||||||
|
draggable
|
||||||
|
destroy-on-close
|
||||||
|
>
|
||||||
|
<el-link
|
||||||
|
:underline="false"
|
||||||
|
style="margin-bottom: 10px;"
|
||||||
|
>
|
||||||
|
<span>
|
||||||
|
{{ $T('MANAGE_BUCKET_RENAME_FILE_INPUT_A') + $T('GALLERY_MATCHED') + mathcedCount + ' ' }}
|
||||||
|
<el-tooltip
|
||||||
|
effect="dark"
|
||||||
|
:content="$T('MANAGE_BUCKET_RENAME_FILE_INPUT_A_TIPS')"
|
||||||
|
placement="right"
|
||||||
|
>
|
||||||
|
<el-icon
|
||||||
|
color="#409EFF"
|
||||||
|
>
|
||||||
|
<InfoFilled />
|
||||||
|
</el-icon>
|
||||||
|
</el-tooltip>
|
||||||
|
</span>
|
||||||
|
</el-link>
|
||||||
|
<el-input
|
||||||
|
v-model="batchRenameMatch"
|
||||||
|
:placeholder="$T('MANAGE_BUCKET_RENAME_FILE_INPUT_A_PLACEHOLDER')"
|
||||||
|
clearable
|
||||||
|
/>
|
||||||
|
<el-link
|
||||||
|
:underline="false"
|
||||||
|
style="margin-bottom: 10px;margin-top: 10px;"
|
||||||
|
>
|
||||||
|
<span>
|
||||||
|
{{ $T('MANAGE_BUCKET_RENAME_FILE_INPUT_B') }}
|
||||||
|
<el-popover
|
||||||
|
effect="light"
|
||||||
|
placement="right"
|
||||||
|
width="280"
|
||||||
|
>
|
||||||
|
<template #reference>
|
||||||
|
<el-icon
|
||||||
|
color="#409EFF"
|
||||||
|
>
|
||||||
|
<InfoFilled />
|
||||||
|
</el-icon>
|
||||||
|
</template>
|
||||||
|
<el-descriptions
|
||||||
|
:column="1"
|
||||||
|
style="width: 250px;"
|
||||||
|
border
|
||||||
|
>
|
||||||
|
<el-descriptions-item
|
||||||
|
v-for="(item, index) in customRenameFormatTable"
|
||||||
|
:key="index"
|
||||||
|
:label="item.placeholder"
|
||||||
|
align="center"
|
||||||
|
label-style="width: 100px;"
|
||||||
|
>
|
||||||
|
{{ item.description }}
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item
|
||||||
|
v-for="(item, index) in customRenameFormatTable.slice(0, customRenameFormatTable.length-1)"
|
||||||
|
:key="index"
|
||||||
|
:label="item.placeholderB"
|
||||||
|
align="center"
|
||||||
|
label-style="width: 100px;"
|
||||||
|
>
|
||||||
|
{{ item.descriptionB }}
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item
|
||||||
|
label="{auto}"
|
||||||
|
align="center"
|
||||||
|
label-style="width: 100px;"
|
||||||
|
>
|
||||||
|
{{ $T('MANAGE_BUCKET_RENAME_FILE_TABLE_IID') }}
|
||||||
|
</el-descriptions-item>
|
||||||
|
</el-descriptions>
|
||||||
|
</el-popover>
|
||||||
|
</span>
|
||||||
|
</el-link>
|
||||||
|
<el-input
|
||||||
|
v-model="batchRenameReplace"
|
||||||
|
placeholder="Ex. {Y}-{m}-{uuid}"
|
||||||
|
clearable
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
style="margin-top: 10px;align-items: center;display: flex;justify-content: flex-end;"
|
||||||
|
>
|
||||||
|
<el-button
|
||||||
|
type="danger"
|
||||||
|
style="margin-right: 30px;"
|
||||||
|
plain
|
||||||
|
:icon="Close"
|
||||||
|
@click="() => {isShowBatchRenameDialog = false}"
|
||||||
|
>
|
||||||
|
{{ $T('MANAGE_BUCKET_RENAME_FILE_CANCEL') }}
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
plain
|
||||||
|
:icon="Edit"
|
||||||
|
@click="handelBatchRename()"
|
||||||
|
>
|
||||||
|
{{ $T('MANAGE_BUCKET_RENAME_FILE_CONFIRM') }}
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import type { IResult } from '@picgo/store/dist/types'
|
import type { IResult } from '@picgo/store/dist/types'
|
||||||
import { PASTE_TEXT, GET_PICBEDS } from '#/events/constants'
|
import { PASTE_TEXT, GET_PICBEDS } from '#/events/constants'
|
||||||
import { CheckboxValueType, ElMessageBox, ElNotification } from 'element-plus'
|
import { CheckboxValueType, ElMessageBox, ElNotification, ElMessage } from 'element-plus'
|
||||||
import { Close, CaretBottom, Document, Edit, Delete, CaretTop } from '@element-plus/icons-vue'
|
import { InfoFilled, Close, CaretBottom, Document, Edit, Delete, CaretTop, Sort } from '@element-plus/icons-vue'
|
||||||
import {
|
import {
|
||||||
ipcRenderer,
|
ipcRenderer,
|
||||||
clipboard,
|
clipboard,
|
||||||
@ -231,6 +411,7 @@ import { onBeforeRouteUpdate } from 'vue-router'
|
|||||||
import { T as $T } from '@/i18n/index'
|
import { T as $T } from '@/i18n/index'
|
||||||
import $$db from '@/utils/db'
|
import $$db from '@/utils/db'
|
||||||
import ALLApi from '@/apis/allApi'
|
import ALLApi from '@/apis/allApi'
|
||||||
|
import { customRenameFormatTable, customStrMatch, customStrReplace } from '../manage/utils/common'
|
||||||
const images = ref<ImgInfo[]>([])
|
const images = ref<ImgInfo[]>([])
|
||||||
const dialogVisible = ref(false)
|
const dialogVisible = ref(false)
|
||||||
const imgInfo = reactive({
|
const imgInfo = reactive({
|
||||||
@ -248,7 +429,8 @@ const choosedPicBed = ref<string[]>([])
|
|||||||
const lastChoosed = ref<number>(-1)
|
const lastChoosed = ref<number>(-1)
|
||||||
const isShiftKeyPress = ref<boolean>(false)
|
const isShiftKeyPress = ref<boolean>(false)
|
||||||
const searchText = ref<string>('')
|
const searchText = ref<string>('')
|
||||||
const handleBarActive = ref<boolean>(false)
|
const searchTextURL = ref<string>('')
|
||||||
|
const handleBarActive = ref<boolean>(true)
|
||||||
const pasteStyle = ref<string>('')
|
const pasteStyle = ref<string>('')
|
||||||
const pasteStyleMap = {
|
const pasteStyleMap = {
|
||||||
Markdown: 'markdown',
|
Markdown: 'markdown',
|
||||||
@ -257,6 +439,22 @@ const pasteStyleMap = {
|
|||||||
UBB: 'UBB',
|
UBB: 'UBB',
|
||||||
Custom: 'Custom'
|
Custom: 'Custom'
|
||||||
}
|
}
|
||||||
|
const fileSortNameReverse = ref(false)
|
||||||
|
const fileSortTimeReverse = ref(false)
|
||||||
|
const fileSortExtReverse = ref(false)
|
||||||
|
const isShowBatchRenameDialog = ref(false)
|
||||||
|
const batchRenameMatch = ref('')
|
||||||
|
const batchRenameReplace = ref('')
|
||||||
|
const mathcedCount = computed(() => {
|
||||||
|
const matchedFiles = [] as any[]
|
||||||
|
images.value.forEach((item: any) => {
|
||||||
|
if (customStrMatch(item.imgUrl, batchRenameMatch.value)) {
|
||||||
|
matchedFiles.push(item)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return matchedFiles.length
|
||||||
|
})
|
||||||
|
const dateRange = ref('')
|
||||||
const picBed = ref<IPicBedType[]>([])
|
const picBed = ref<IPicBedType[]>([])
|
||||||
onBeforeRouteUpdate((to, from) => {
|
onBeforeRouteUpdate((to, from) => {
|
||||||
if (from.name === 'gallery') {
|
if (from.name === 'gallery') {
|
||||||
@ -317,18 +515,29 @@ function getPicBeds (event: IpcRendererEvent, picBeds: IPicBedType[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getGallery (): IGalleryItem[] {
|
function getGallery (): IGalleryItem[] {
|
||||||
if (searchText.value || choosedPicBed.value.length > 0) {
|
if (searchText.value || choosedPicBed.value.length > 0 || searchTextURL.value || dateRange.value) {
|
||||||
|
console.log(dateRange.value)
|
||||||
return images.value
|
return images.value
|
||||||
.filter(item => {
|
.filter(item => {
|
||||||
let isInChoosedPicBed = true
|
let isInChoosedPicBed = true
|
||||||
let isIncludesSearchText = true
|
let isIncludesSearchText = true
|
||||||
|
let isIncludesSearchTextURL = true
|
||||||
|
let isIncludesDateRange = true
|
||||||
if (choosedPicBed.value.length > 0) {
|
if (choosedPicBed.value.length > 0) {
|
||||||
isInChoosedPicBed = choosedPicBed.value.some(type => type === item.type)
|
isInChoosedPicBed = choosedPicBed.value.some(type => type === item.type)
|
||||||
}
|
}
|
||||||
if (searchText.value) {
|
if (searchText.value) {
|
||||||
isIncludesSearchText = item.fileName?.includes(searchText.value) || false
|
isIncludesSearchText = customStrMatch(item.fileName || '', searchText.value)
|
||||||
}
|
}
|
||||||
return isIncludesSearchText && isInChoosedPicBed
|
if (searchTextURL.value) {
|
||||||
|
isIncludesSearchTextURL = customStrMatch(item.imgUrl || '', searchTextURL.value)
|
||||||
|
}
|
||||||
|
if (dateRange.value) {
|
||||||
|
const [start, end] = dateRange.value
|
||||||
|
const date = new Date(item.updatedAt).getTime()
|
||||||
|
isIncludesDateRange = date >= new Date(start).getTime() && date <= new Date(end).getTime() + 86400000
|
||||||
|
}
|
||||||
|
return isIncludesSearchText && isInChoosedPicBed && isIncludesSearchTextURL && isIncludesDateRange
|
||||||
}).map(item => {
|
}).map(item => {
|
||||||
return {
|
return {
|
||||||
...item,
|
...item,
|
||||||
@ -497,6 +706,10 @@ function cleanSearch () {
|
|||||||
searchText.value = ''
|
searchText.value = ''
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function cleanSearchUrl () {
|
||||||
|
searchTextURL.value = ''
|
||||||
|
}
|
||||||
|
|
||||||
function isMultiple (obj: IObj) {
|
function isMultiple (obj: IObj) {
|
||||||
return Object.values(obj).some(item => item)
|
return Object.values(obj).some(item => item)
|
||||||
}
|
}
|
||||||
@ -623,6 +836,118 @@ async function handlePasteStyleChange (val: string) {
|
|||||||
pasteStyle.value = val
|
pasteStyle.value = val
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function sortFile (type: 'name' | 'time' | 'ext' | 'check') {
|
||||||
|
switch (type) {
|
||||||
|
case 'name':
|
||||||
|
fileSortNameReverse.value = !fileSortNameReverse.value
|
||||||
|
images.value.sort((a: any, b: any) => {
|
||||||
|
if (fileSortNameReverse.value) {
|
||||||
|
return a.fileName.localeCompare(b.fileName)
|
||||||
|
} else {
|
||||||
|
return b.fileName.localeCompare(a.fileName)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
break
|
||||||
|
case 'time':
|
||||||
|
fileSortTimeReverse.value = !fileSortTimeReverse.value
|
||||||
|
images.value.sort((a: any, b: any) => {
|
||||||
|
if (fileSortTimeReverse.value) {
|
||||||
|
return a.updatedAt - b.updatedAt
|
||||||
|
} else {
|
||||||
|
return b.updatedAt - a.updatedAt
|
||||||
|
}
|
||||||
|
})
|
||||||
|
break
|
||||||
|
case 'ext':
|
||||||
|
fileSortExtReverse.value = !fileSortExtReverse.value
|
||||||
|
images.value.sort((a: any, b: any) => {
|
||||||
|
if (fileSortExtReverse.value) {
|
||||||
|
return a.extname.localeCompare(b.extname)
|
||||||
|
} else {
|
||||||
|
return b.extname.localeCompare(a.extname)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
break
|
||||||
|
case 'check':
|
||||||
|
images.value.sort((a: any, b: any) => {
|
||||||
|
if (choosedList[a.id] && !choosedList[b.id]) {
|
||||||
|
return -1
|
||||||
|
} else if (!choosedList[a.id] && choosedList[b.id]) {
|
||||||
|
return 1
|
||||||
|
} else {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
})
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handelBatchRename () {
|
||||||
|
isShowBatchRenameDialog.value = false
|
||||||
|
if (batchRenameMatch.value === '') {
|
||||||
|
ElMessage.warning($T('MANAGE_BUCKET_BATCH_RENAME_ERROR_MSG'))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let matchedFiles = [] as any[]
|
||||||
|
images.value.forEach((item: any) => {
|
||||||
|
if (customStrMatch(item.imgUrl, batchRenameMatch.value)) {
|
||||||
|
matchedFiles.push(item)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if (matchedFiles.length === 0) {
|
||||||
|
ElMessage.warning($T('MANAGE_BUCKET_BATCH_RENAME_ERROR_MSG2'))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for (let i = 0; i < matchedFiles.length; i++) {
|
||||||
|
matchedFiles[i].newUrl = customStrReplace(matchedFiles[i].imgUrl, batchRenameMatch.value, batchRenameReplace.value)
|
||||||
|
}
|
||||||
|
matchedFiles = matchedFiles.filter((item: any) => item.imgUrl !== item.newUrl)
|
||||||
|
if (matchedFiles.length === 0) {
|
||||||
|
ElMessage.warning($T('MANAGE_BUCKET_BATCH_RENAME_ERROR_MSG3'))
|
||||||
|
}
|
||||||
|
for (let i = 0; i < matchedFiles.length; i++) {
|
||||||
|
matchedFiles[i].newUrl = matchedFiles[i].newUrl.replaceAll('{auto}', (i + 1).toString())
|
||||||
|
}
|
||||||
|
const duplicateFilesNum = matchedFiles.filter((item: any) => matchedFiles.filter((item2: any) => item2.newUrl === item.newUrl).length > 1).length
|
||||||
|
const renamefunc = async (item: any) => {
|
||||||
|
await $$db.updateById(item.id, {
|
||||||
|
imgUrl: item.newUrl
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const rename = () => {
|
||||||
|
const promiseList = [] as any[]
|
||||||
|
for (let i = 0; i < matchedFiles.length; i++) {
|
||||||
|
promiseList.push(renamefunc(matchedFiles[i]))
|
||||||
|
}
|
||||||
|
Promise.all(promiseList).then(() => {
|
||||||
|
const obj = {
|
||||||
|
title: $T('OPERATION_SUCCEED'),
|
||||||
|
body: ''
|
||||||
|
}
|
||||||
|
const myNotification = new Notification(obj.title, obj)
|
||||||
|
myNotification.onclick = () => {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
updateGallery()
|
||||||
|
}).catch(() => {
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (duplicateFilesNum > 0) {
|
||||||
|
ElMessageBox.confirm(`${$T('MANAGE_BUCKET_BATCH_RENAME_REPEATED_MSG_A')} ${duplicateFilesNum} ${$T('MANAGE_BUCKET_BATCH_RENAME_REPEATED_MSG_B')}`, $T('MANAGE_BUCKET_BATCH_RENAME_REPEATED_MSG_C'), {
|
||||||
|
confirmButtonText: $T('MANAGE_BUCKET_BATCH_RENAME_REPEATED_CONFIRM'),
|
||||||
|
cancelButtonText: $T('MANAGE_BUCKET_BATCH_RENAME_REPEATED_CANCEL'),
|
||||||
|
type: 'warning'
|
||||||
|
}).then(() => {
|
||||||
|
rename()
|
||||||
|
}).catch(() => {
|
||||||
|
ElMessage.info($T('MANAGE_BUCKET_BATCH_RENAME_CANCEL'))
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
rename()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
ipcRenderer.removeAllListeners('updateGallery')
|
ipcRenderer.removeAllListeners('updateGallery')
|
||||||
ipcRenderer.removeListener(GET_PICBEDS, getPicBeds)
|
ipcRenderer.removeListener(GET_PICBEDS, getPicBeds)
|
||||||
|
5
src/universal/types/i18n.d.ts
vendored
5
src/universal/types/i18n.d.ts
vendored
@ -63,6 +63,11 @@ interface ILocales {
|
|||||||
GALLERY_SYNC_DELETE_NOTICE_TITLE: string
|
GALLERY_SYNC_DELETE_NOTICE_TITLE: string
|
||||||
GALLERY_SYNC_DELETE_NOTICE_SUCCEED: string
|
GALLERY_SYNC_DELETE_NOTICE_SUCCEED: string
|
||||||
GALLERY_SYNC_DELETE_NOTICE_FAILED: string
|
GALLERY_SYNC_DELETE_NOTICE_FAILED: string
|
||||||
|
GALLERY_CHANGE_URL: string
|
||||||
|
GALLERY_CHANGE_URL_TITLE: string
|
||||||
|
GALLERY_SEARCH_FILENAME: string
|
||||||
|
GALLERY_SEARCH_URL: string
|
||||||
|
GALLERY_MATCHED: string
|
||||||
UPLOAD_PAGE_IMAGE_PROCESS_NAME: string
|
UPLOAD_PAGE_IMAGE_PROCESS_NAME: string
|
||||||
UPLOAD_PAGE_IMAGE_PROCESS_DIALOG_TITLE: string
|
UPLOAD_PAGE_IMAGE_PROCESS_DIALOG_TITLE: string
|
||||||
UPLOAD_PAGE_IMAGE_PROCESS_ISADDWM: string
|
UPLOAD_PAGE_IMAGE_PROCESS_ISADDWM: string
|
||||||
|
Loading…
Reference in New Issue
Block a user