diff --git a/components.d.ts b/components.d.ts index 5760033..e62d0ea 100755 --- a/components.d.ts +++ b/components.d.ts @@ -14,13 +14,10 @@ declare module 'vue' { ElFormItem: typeof import('element-plus/es')['ElFormItem'] ElHeader: typeof import('element-plus/es')['ElHeader'] ElIcon: typeof import('element-plus/es')['ElIcon'] - ElInput: typeof import('element-plus/es')['ElInput'] ElMain: typeof import('element-plus/es')['ElMain'] ElMenu: typeof import('element-plus/es')['ElMenu'] ElMenuItem: typeof import('element-plus/es')['ElMenuItem'] - ElOption: typeof import('element-plus/es')['ElOption'] ElRow: typeof import('element-plus/es')['ElRow'] - ElSelect: typeof import('element-plus/es')['ElSelect'] ElTableColumn: typeof import('element-plus/es')['ElTableColumn'] Footer: typeof import('./src/components/layout/Footer.vue')['default'] Index: typeof import('./src/components/layout/Index.vue')['default'] diff --git a/electron/main/const.ts b/electron/main/const.ts index 010b209..ecb586d 100755 --- a/electron/main/const.ts +++ b/electron/main/const.ts @@ -22,7 +22,7 @@ export default { CERT_PUBLIC_PATH: path.join(EXECUTABLE_PATH, './keys/public.pem'), INSTALL_CERT_FLAG: path.join(HOME_PATH, './installed.lock'), WIN_CERT_INSTALL_HELPER: path.join(EXECUTABLE_PATH, './w_c.exe'), - APP_CN_NAME: '资源下载器', + APP_CN_NAME: '爱享素材下载器', APP_EN_NAME: 'ResDownloader', REGEDIT_VBS_PATH: path.join(EXECUTABLE_PATH, './regedit-vbs'), OPEN_SSL_BIN_PATH: path.join(EXECUTABLE_PATH, './openssl/openssl.exe'), diff --git a/electron/main/ipc.ts b/electron/main/ipc.ts index 54a2ca1..84c8d3b 100755 --- a/electron/main/ipc.ts +++ b/electron/main/ipc.ts @@ -1,13 +1,14 @@ import {ipcMain, dialog, BrowserWindow, app, shell} from 'electron' import {startServer} from './proxyServer' import {installCert, checkCertInstalled} from './cert' -import {downloadFile} from './utils' +import {downloadFile, decodeWxFile} from './utils' // @ts-ignore import {hexMD5} from '../../src/common/md5' import fs from "fs" import CryptoJS from 'crypto-js' import {closeProxy, setProxy} from "./setProxy" import log from "electron-log" +import {floor} from "lodash"; let getMac = require("getmac").default let win: BrowserWindow @@ -17,16 +18,6 @@ let isOpenProxy = false let aesKey = "as5d45as4d6qe6wqfar6gt4749q6y7w6h34v64tv7t37ty5qwtv6t6qv" -const toSize = (size: number) => { - if (size > 1048576) { - return (size / 1048576).toFixed(2) + "MB" - } - if (size > 1024) { - return (size / 1024).toFixed(2) + "KB" - } - return size + 'b' -} - const suffix = (type: string) => { switch (type) { case "video/mp4": @@ -104,6 +95,16 @@ export default function initIPC() { return result?.[0] }) + ipcMain.handle('invoke_select_wx_file', async (event, {index, data}) => { + // 选择下载位置 + const result = dialog.showOpenDialogSync({title: '保存', properties: ['openFile']}) + if (!result?.[0]) { + return false + } + return decodeWxFile(result?.[0], data.decode_key, result?.[0].replace(".mp4", "_解密.mp4")) + }) + + ipcMain.handle('invoke_file_exists', async (event, {save_path, url}) => { let url_sign = hexMD5(url) let res = fs.existsSync(`${save_path}/${url_sign}.mp4`) @@ -131,7 +132,7 @@ export default function initIPC() { data.decode_key, save_path_file, (res) => { - return save_path_file + win?.webContents.send('on_down_file_schedule', {schedule: floor(res * 100)}) } ).catch(err => { // console.log('invoke_down_file:err', err) @@ -167,8 +168,8 @@ export default function initIPC() { shell.openExternal(url).then(r => {}) }) - ipcMain.handle('invoke_open_dir', (event, {dir}) => { - shell.openPath(dir).then(r => {}) + ipcMain.handle('invoke_open_file_dir', (event, {save_path}) => { + shell.showItemInFolder(save_path) }) } diff --git a/electron/main/proxyServer.ts b/electron/main/proxyServer.ts index 6e51866..b8c090f 100755 --- a/electron/main/proxyServer.ts +++ b/electron/main/proxyServer.ts @@ -201,7 +201,7 @@ export async function startServer({ progress_bar: '', save_path: '', downing: false, - decode_key: req.json.decode_key, + decode_key: '', description: '', uploader: '', }) @@ -219,7 +219,7 @@ export async function startServer({ progress_bar: '', save_path: '', downing: false, - decode_key: req.json.decode_key, + decode_key: '', description: '', uploader: '', }) @@ -237,7 +237,7 @@ export async function startServer({ progress_bar: '', save_path: '', downing: false, - decode_key: req.json.decode_key, + decode_key: '', description: '', uploader: '', }) diff --git a/electron/main/utils.ts b/electron/main/utils.ts index effe658..f80938c 100755 --- a/electron/main/utils.ts +++ b/electron/main/utils.ts @@ -66,6 +66,22 @@ function downloadFile(url, decodeKey, fullFileName, progressCallback) { }); } +function decodeWxFile(fileName, decodeKey, fullFileName) { + let xorStream = xorTransform(getDecryptionArray(decodeKey)); + let data = fs.createReadStream(fileName); + + return new Promise((resolve, reject) => { + data.on('error', err => reject(err)); + data.pipe(xorStream).pipe( + fs.createWriteStream(fullFileName).on('finish', () => { + resolve({ + fullFileName, + }); + }), + ); + }); +} + function toSize(size: number) { if (size > 1048576) { return (size / 1048576).toFixed(2) + "MB" @@ -76,4 +92,4 @@ function toSize(size: number) { return size + 'b' } -export {downloadFile, toSize} +export {downloadFile, toSize, decodeWxFile} diff --git a/electron/res/index.html b/electron/res/index.html index b973636..4d8db9e 100755 --- a/electron/res/index.html +++ b/electron/res/index.html @@ -3,7 +3,7 @@ - 资源下载器 + 爱享素材下载器 diff --git a/index.html b/index.html index 630dcca..0cebc55 100644 --- a/index.html +++ b/index.html @@ -5,7 +5,7 @@ - 资源下载器 + 爱享素材下载器
diff --git a/package.json b/package.json index 91ce938..b0b3a8f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "res-downloader", - "version": "1.0.3", + "version": "1.0.4", "main": "dist-electron/main/index.js", "description": "Electron + Vue + Vite 实现的资源下载软件,支持微信视频号下载、抖音视频下载、快手视频下载、酷狗音乐下载等", "author": "putyy@qq.com", diff --git a/src/components/layout/Footer.vue b/src/components/layout/Footer.vue index c70fc52..2e2216a 100755 --- a/src/components/layout/Footer.vue +++ b/src/components/layout/Footer.vue @@ -6,7 +6,7 @@ const jump = (scene: number)=>{ switch (scene) { case 1: ipcRenderer.invoke('invoke_open_default_browser', { - url: "https://github.com/putyy/res-downloader" + url: "https://s.gowas.cn/d/4089-quan-ping-tai-zi-yuan-xia-zai-ruan-jian" }) break; case 2: @@ -24,6 +24,16 @@ const jump = (scene: number)=>{ url: "https://github.com/putyy/res-downloader/issues" }) break; + case 5: + ipcRenderer.invoke('invoke_open_default_browser', { + url: "https://haokawx.lot-ml.com/Product/Index/22550" + }) + break; + case 6: + ipcRenderer.invoke('invoke_open_default_browser', { + url: "https://github.com/putyy/res-downloader" + }) + break; } } @@ -33,8 +43,11 @@ div.line a.item 站长邮箱: gowas.work@gmail.com a.item(@click="jump(1)") 获取更新 a.item(@click="jump(2)") 云盘资源 - a.item(@click="jump(3)") 图片压缩 +div.line + a.item(@click="jump(3)") 图片无损压缩 a.item(@click="jump(4)") 问题反馈 + a.item(@click="jump(5)") 流量卡推荐 + a.item(@click="jump(6)") 软件源码 \ No newline at end of file diff --git a/src/views/Index.vue b/src/views/Index.vue index 7130016..d1aa179 100755 --- a/src/views/Index.vue +++ b/src/views/Index.vue @@ -56,7 +56,7 @@ onMounted(() => { } }) - const loading = ElLoading.service({ + let loading = ElLoading.service({ lock: true, text: 'Loading', background: 'rgba(0, 0, 0, 0.7)', @@ -87,9 +87,13 @@ onUnmounted(() => { // console.log(res) }) - ipcRenderer.invoke('invoke_close_proxy').then((res) => { + ipcRenderer.removeListener('on_down_file_schedule', (res) => { + // console.log(res) }) + // ipcRenderer.invoke('invoke_close_proxy').then((res) => { + // }) + localStorageCache.set("res-table-data", tableData.value, -1) localStorageCache.set("res-type", resType.value, -1) }) @@ -119,6 +123,10 @@ const handleBatchDown = async () => { background: 'rgba(0, 0, 0, 0.7)', }) + ipcRenderer.on('on_down_file_schedule', (res: any, data: any) => { + loading.setText(`已下载 ${data.schedule}%`) + }) + for (const item of multipleSelection.value) { let result = await ipcRenderer.invoke('invoke_file_exists', { save_path: save_dir, @@ -182,6 +190,10 @@ const handleDown = async (index: number, row: any, high: boolean) => { return } + ipcRenderer.on('on_down_file_schedule', (res: any, data: any) => { + loading.setText(`已下载 ${data.schedule}%`) + }) + ipcRenderer.invoke('invoke_down_file', { index: index, data: Object.assign({}, tableData.value[index]), @@ -199,18 +211,49 @@ const handleDown = async (index: number, row: any, high: boolean) => { } loading.close() }).catch((err) => { - // console.log('invoke_down_file err', err) ElMessage({ message: "下载失败", type: 'warning', }) loading.close() }) +} +const decodeWxFile = (index: number) => { + let loading = ElLoading.service({ + lock: true, + text: "解密中", + background: 'rgba(0, 0, 0, 0.7)', + }) + + ipcRenderer.invoke('invoke_select_wx_file', { + index: index, + data: Object.assign({}, tableData.value[index]), + }).then((res) => { + if (res !== false) { + ElMessage({ + message: "解密成功: " + res.fullFileName, + type: 'success', + }) + tableData.value[index].progress_bar = "100%" + tableData.value[index].save_path = res.fullFileName + }else{ + ElMessage({ + message: "解密失败", + type: 'warning', + }) + } + loading.close() + }).catch((err) => { + ElMessage({ + message: "解密失败", + type: 'warning', + }) + loading.close() + }) } const handlePreview = (index: number, row: any) => { - // console.log('row.down_url',row) ipcRenderer.invoke('invoke_resources_preview', {url: row.down_url}).catch(() => { }) } @@ -239,19 +282,9 @@ const handleDel = (index: number)=>{ tableData.value = arr } -const openDir = ()=>{ - let save_dir = localStorageCache.get("save_dir") - - if (!save_dir) { - ElMessage({ - message: '目录不存在', - type: 'warning' - }) - return - } - - ipcRenderer.invoke('invoke_open_dir', { - dir: save_dir +const openFileDir = (index: number)=>{ + ipcRenderer.invoke('invoke_open_file_dir', { + save_path: tableData.value[index].save_path }) } @@ -287,14 +320,14 @@ el-container.container el-button(@click="resType.m3u8=!resType.m3u8" :type="resType.m3u8 ? 'primary' : 'info'" ) m3u8 a(style="color: red")    点击左边选项,选择需要拦截的资源类型 el-main - el-table(ref="multipleTableRef" @selection-change="handleSelectionChange" :data="tableData" max-height="100%" stripe style="max-content") - el-table-column(type="selection" width="55") - el-table-column(label="预览" show-overflow-tooltip width="350px") + el-table(ref="multipleTableRef" @selection-change="handleSelectionChange" :data="tableData" max-height="100%" stripe) + el-table-column(type="selection") + el-table-column(label="预览" show-overflow-tooltip width="300px") template(#default="scope") div.show_res - video(v-if="scope.row.type_str === 'video'" :src="scope.row.down_url" controls preload="none" style="width: 100%;height: auto;") 您的浏览器不支持 video 标签。 + video.video(v-if="scope.row.type_str === 'video'" :src="scope.row.down_url" controls preload="none") 您的浏览器不支持 video 标签。 img.img(v-if="scope.row.type_str === 'image'" :src="scope.row.down_url") - audio(v-if="scope.row.type_str === 'audio'" controls preload="none") + audio.audio(v-if="scope.row.type_str === 'audio'" controls preload="none") source(:src="scope.row.down_url" :type="scope.row.type") div {{scope.row.description}} el-table-column(prop="type_str" label="类型" show-overflow-tooltip) @@ -302,14 +335,16 @@ el-container.container el-table-column(prop="size" label="资源大小") el-table-column(prop="save_path" label="保存目录") el-table-column(prop="progress_bar" label="下载进度") - el-table-column(label="操作") + el-table-column(label="操作" width="135px" ) template(#default="scope") - template(v-if="scope.row.type_str !== 'm3u8'" ) - el-button(v-if="!scope.row.save_path" link type="primary" @click="handleDown(scope.$index, scope.row, false)") {{scope.row.decode_key ? "解密下载" : "下载"}} - el-button(link type="primary" @click="handlePreview(scope.$index, scope.row)") 窗口预览 - el-button(link type="primary" @click="handleCopy(scope.row.down_url)") 复制链接 - el-button(link type="primary" @click="handleDel(scope.$index)") 删 除 - el-button(link type="primary" @click="openDir()") 打开目录 + div.actions + template(v-if="scope.row.type_str !== 'm3u8'" ) + el-button(v-if="!scope.row.save_path" link type="primary" @click="handleDown(scope.$index, scope.row, false)") {{scope.row.decode_key ? "解密下载(视频号)" : "下载"}} + el-button(v-if="scope.row.decode_key" link type="primary" @click="decodeWxFile(scope.$index)") 视频解密(视频号) + el-button(link type="primary" @click="handlePreview(scope.$index, scope.row)") 窗口预览 + el-button(link type="primary" @click="handleCopy(scope.row.down_url)") 复制链接 + el-button(link type="primary" @click="handleDel(scope.$index)") 删除 + el-button(v-if="scope.row.save_path" link type="primary" @click="openFileDir(scope.$index)") 打开文件目录 diff --git a/src/views/VipParse.vue b/src/views/VipParse.vue deleted file mode 100755 index 0d3e4e2..0000000 --- a/src/views/VipParse.vue +++ /dev/null @@ -1,99 +0,0 @@ - - - \ No newline at end of file