mirror of
https://github.com/putyy/res-downloader.git
synced 2026-01-12 06:04:55 +08:00
perf: optimization download、Proxy settings, add batch export
This commit is contained in:
1
frontend/components.d.ts
vendored
1
frontend/components.d.ts
vendored
@@ -37,6 +37,7 @@ declare module 'vue' {
|
||||
NSpace: typeof import('naive-ui')['NSpace']
|
||||
NSwitch: typeof import('naive-ui')['NSwitch']
|
||||
NTooltip: typeof import('naive-ui')['NTooltip']
|
||||
Password: typeof import('./src/components/Password.vue')['default']
|
||||
Preview: typeof import('./src/components/Preview.vue')['default']
|
||||
ResAction: typeof import('./src/components/ResAction.vue')['default']
|
||||
RouterLink: typeof import('vue-router')['RouterLink']
|
||||
|
||||
@@ -1,6 +1,13 @@
|
||||
import request from '@/api/request'
|
||||
|
||||
export default {
|
||||
setSystemPassword(data: object) {
|
||||
return request({
|
||||
url: 'api/set-system-password',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
},
|
||||
openSystemProxy() {
|
||||
return request({
|
||||
url: 'api/proxy-open',
|
||||
@@ -93,4 +100,11 @@ export default {
|
||||
data: data
|
||||
})
|
||||
},
|
||||
batchImport(data: object) {
|
||||
return request({
|
||||
url: 'api/batch-import',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
},
|
||||
}
|
||||
46
frontend/src/components/Password.vue
Normal file
46
frontend/src/components/Password.vue
Normal file
@@ -0,0 +1,46 @@
|
||||
<template>
|
||||
<n-modal
|
||||
:show="showModal"
|
||||
:on-update:show="changeShow"
|
||||
style="--wails-draggable:no-drag"
|
||||
preset="dialog"
|
||||
title="管理员授权"
|
||||
content=""
|
||||
:show-icon="false"
|
||||
:mask-closable="false"
|
||||
class="rounded-lg"
|
||||
>
|
||||
<n-form>
|
||||
<div class="text-red-500 text-base">
|
||||
本操作需要管理员授权,仅对本次运行期间有效!
|
||||
</div>
|
||||
<n-form-item path="password" label="">
|
||||
<n-input
|
||||
v-model:value="password"
|
||||
type="password"
|
||||
placeholder="请输入你的电脑密码"
|
||||
class="w-full"
|
||||
/>
|
||||
</n-form-item>
|
||||
</n-form>
|
||||
<template #action>
|
||||
<div class="flex justify-end gap-4">
|
||||
<n-button @click="emits('update:showModal', false)">取消操作</n-button>
|
||||
<n-button type="primary" @click="emits('submit', password)">确认操作</n-button>
|
||||
</div>
|
||||
</template>
|
||||
</n-modal>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import {ref, computed} from 'vue'
|
||||
import {NModal, NForm, NFormItem, NInput, NButton} from 'naive-ui'
|
||||
|
||||
const props = defineProps({
|
||||
showModal: Boolean,
|
||||
})
|
||||
const password = ref("")
|
||||
|
||||
const emits = defineEmits(["update:showModal", "submit"])
|
||||
const changeShow = (value: boolean) => emits("update:showModal", value)
|
||||
</script>
|
||||
@@ -12,7 +12,7 @@
|
||||
<NButton v-if="row.DecodeKey" type="warning" :tertiary="true" size="small" @click="action('decode')">
|
||||
视频解密
|
||||
</NButton>
|
||||
<NButton v-if="isDebug" type="info" :tertiary="true" size="small" @click="action('json')">
|
||||
<NButton type="info" :tertiary="true" size="small" @click="action('json')">
|
||||
复制数据
|
||||
</NButton>
|
||||
<NButton type="error" :tertiary="true" size="small" @click="action('delete')">
|
||||
@@ -22,8 +22,6 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import {inject} from "vue"
|
||||
|
||||
const props = defineProps<{
|
||||
row: any,
|
||||
index: number,
|
||||
@@ -31,8 +29,6 @@ const props = defineProps<{
|
||||
|
||||
const emits = defineEmits(["action"])
|
||||
|
||||
const isDebug = inject('isDebug')
|
||||
|
||||
const action = (type: string) => {
|
||||
emits('action', props.row, props.index, type)
|
||||
}
|
||||
|
||||
6
frontend/src/types/app.d.ts
vendored
6
frontend/src/types/app.d.ts
vendored
@@ -57,4 +57,10 @@ export namespace appType {
|
||||
type: string
|
||||
event: any
|
||||
}
|
||||
|
||||
interface Res<T = any> {
|
||||
code: number;
|
||||
message: string;
|
||||
data: T; // T will be the specific type of your data
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,14 @@
|
||||
<template>
|
||||
<div class="flex flex-col px-5 py-5">
|
||||
<div class="pb-2 z-40" @click="triggerEvent">
|
||||
<div class="pb-2 z-40">
|
||||
<NSpace>
|
||||
<NButton v-if="isProxy" secondary type="primary" @click.stop="close" style="--wails-draggable:no-drag">关闭代理</NButton>
|
||||
<NButton v-else tertiary type="tertiary" @click.stop="open" style="--wails-draggable:no-drag">开启代理</NButton>
|
||||
<NButton tertiary type="info" @click.stop="batchDown" style="--wails-draggable:no-drag">批量下载</NButton>
|
||||
<NButton tertiary type="error" @click.stop="clear" style="--wails-draggable:no-drag">清空列表</NButton>
|
||||
<NSelect style="min-width: 100px;--wails-draggable:no-drag" placeholder="拦截类型" v-model:value="resourcesType" multiple clearable :max-tag-count="3" :options="options"></NSelect>
|
||||
<NButton v-if="isDebug" tertiary type="info" @click.stop="showImport=true" style="--wails-draggable:no-drag">导入数据</NButton>
|
||||
<NButton tertiary type="info" @click.stop="batchDown" style="--wails-draggable:no-drag">批量下载</NButton>
|
||||
<NButton tertiary type="info" @click.stop="batchImport" style="--wails-draggable:no-drag">批量导出</NButton>
|
||||
<NButton tertiary type="info" @click.stop="showImport=true" style="--wails-draggable:no-drag">批量导入</NButton>
|
||||
</NSpace>
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
@@ -27,6 +28,7 @@
|
||||
<Preview v-model:showModal="showPreviewRow" :previewRow="previewRow"/>
|
||||
<ShowLoading :loadingText="loadingText" :isLoading="loading"/>
|
||||
<ImportJson v-model:showModal="showImport" @submit="handleImport"/>
|
||||
<Password v-model:showModal="showPassword" @submit="handlePassword"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -47,6 +49,7 @@ import ResAction from "@/components/ResAction.vue"
|
||||
import ImportJson from "@/components/ImportJson.vue"
|
||||
import {useEventStore} from "@/stores/event"
|
||||
import {BrowserOpenURL, ClipboardSetText} from "../../wailsjs/runtime"
|
||||
import Password from "@/components/Password.vue"
|
||||
|
||||
const eventStore = useEventStore()
|
||||
const isProxy = computed(() => {
|
||||
@@ -219,12 +222,8 @@ const showPreviewRow = ref(false)
|
||||
const previewRow = ref<appType.MediaInfo>()
|
||||
const loading = ref(false)
|
||||
const loadingText = ref("")
|
||||
const isDebug = ref(false)
|
||||
const showImport = ref(false)
|
||||
let clickCount = 0
|
||||
let clickTimeout: any = null
|
||||
|
||||
provide('isDebug', isDebug);
|
||||
const showPassword = ref(false)
|
||||
|
||||
onMounted(() => {
|
||||
const temp = localStorage.getItem("resources-type")
|
||||
@@ -361,6 +360,35 @@ const batchDown = async () => {
|
||||
}
|
||||
}
|
||||
|
||||
const batchImport = ()=>{
|
||||
if (checkedRowKeysValue.value.length <= 0) {
|
||||
window?.$message?.error('请选择需要导出的数据')
|
||||
return
|
||||
}
|
||||
if (!store.globalConfig.SaveDirectory) {
|
||||
window?.$message?.error("请设置保存目录")
|
||||
return
|
||||
}
|
||||
loadingText.value = "导出中"
|
||||
loading.value = true
|
||||
let jsonData = []
|
||||
for (let i = 0; i < data.value.length; i++) {
|
||||
jsonData.push(encodeURIComponent(JSON.stringify(data.value[i])))
|
||||
}
|
||||
appApi.batchImport({content: jsonData.join("\n")}).then((res: appType.Res) => {
|
||||
loading.value = false
|
||||
if (res.code === 0) {
|
||||
window?.$message?.error(res.message)
|
||||
return
|
||||
}
|
||||
window?.$message?.success("导出成功")
|
||||
window?.$message?.info("文件路径:" + res.data?.file_name, {
|
||||
duration: 5000
|
||||
})
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
const uint8ArrayToBase64 = (bytes: any) => {
|
||||
let binary = '';
|
||||
const len = bytes.byteLength;
|
||||
@@ -390,14 +418,14 @@ const download = (row: appType.MediaInfo, index: number) => {
|
||||
loading.value = true
|
||||
downIndex.value = index
|
||||
if (row.DecodeKey) {
|
||||
appApi.download({...row, decodeStr: uint8ArrayToBase64(getDecryptionArray(row.DecodeKey))}).then((res: any) => {
|
||||
appApi.download({...row, decodeStr: uint8ArrayToBase64(getDecryptionArray(row.DecodeKey))}).then((res: appType.Res) => {
|
||||
if (res.code === 0) {
|
||||
loading.value = false
|
||||
window?.$message?.error(res.message)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
appApi.download({...row, decodeStr: ""}).then((res: any) => {
|
||||
appApi.download({...row, decodeStr: ""}).then((res: appType.Res) => {
|
||||
if (res.code === 0) {
|
||||
loading.value = false
|
||||
window?.$message?.error(res.message)
|
||||
@@ -407,13 +435,25 @@ const download = (row: appType.MediaInfo, index: number) => {
|
||||
}
|
||||
|
||||
const open = () => {
|
||||
appApi.openSystemProxy().then((res: any) => {
|
||||
appApi.openSystemProxy().then((res: appType.Res) => {
|
||||
if (res.code === 0 ){
|
||||
if (store.envInfo.platform === "darwin") {
|
||||
showPassword.value = true
|
||||
return
|
||||
}
|
||||
window?.$message?.error(res.message)
|
||||
return
|
||||
}
|
||||
store.updateProxyStatus(res.data)
|
||||
})
|
||||
}
|
||||
|
||||
const close = () => {
|
||||
appApi.unsetSystemProxy().then((res: any) => {
|
||||
appApi.unsetSystemProxy().then((res: appType.Res) => {
|
||||
if (res.code === 0 ){
|
||||
window?.$message?.error(res.message)
|
||||
return
|
||||
}
|
||||
store.updateProxyStatus(res.data)
|
||||
})
|
||||
}
|
||||
@@ -429,7 +469,7 @@ const decodeWxFile = (row: appType.MediaInfo, index: number) => {
|
||||
window?.$message?.error("无法解密")
|
||||
return
|
||||
}
|
||||
appApi.openFileDialog().then((res: any) => {
|
||||
appApi.openFileDialog().then((res: appType.Res) => {
|
||||
if (res.code === 0) {
|
||||
window?.$message?.error(res.message)
|
||||
return
|
||||
@@ -441,7 +481,7 @@ const decodeWxFile = (row: appType.MediaInfo, index: number) => {
|
||||
...row,
|
||||
filename: res.data.file,
|
||||
decodeStr: uint8ArrayToBase64(getDecryptionArray(row.DecodeKey))
|
||||
}).then((res: any) => {
|
||||
}).then((res: appType.Res) => {
|
||||
loading.value = false
|
||||
if (res.code === 0) {
|
||||
window?.$message?.error(res.message)
|
||||
@@ -456,24 +496,6 @@ const decodeWxFile = (row: appType.MediaInfo, index: number) => {
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
const triggerEvent = ()=>{
|
||||
if(isDebug.value) {
|
||||
return
|
||||
}
|
||||
clickCount++
|
||||
if (clickCount === 5) {
|
||||
// 连续点击5次开启debug
|
||||
isDebug.value = true
|
||||
clickCount = 0
|
||||
} else {
|
||||
clearTimeout(clickTimeout);
|
||||
clickTimeout = setTimeout(() => {
|
||||
clickCount = 0
|
||||
}, 1000)
|
||||
}
|
||||
}
|
||||
|
||||
const handleImport = (content: string)=>{
|
||||
content.split("\n").forEach((line, index) => {
|
||||
try {
|
||||
@@ -491,4 +513,14 @@ const handleImport = (content: string)=>{
|
||||
localStorage.setItem("resources-data", JSON.stringify(data.value))
|
||||
showImport.value = false
|
||||
}
|
||||
|
||||
const handlePassword = (password: string)=>{
|
||||
appApi.setSystemPassword({password: password}).then((res: appType.Res)=>{
|
||||
if (res.code === 0) {
|
||||
window?.$message?.error(res.message)
|
||||
return
|
||||
}
|
||||
open()
|
||||
})
|
||||
}
|
||||
</script>
|
||||
Reference in New Issue
Block a user