完善文档、新增一些功能

This commit is contained in:
putyy
2025-02-10 15:40:32 +08:00
parent 3c0e51a9e2
commit 69f8224453
30 changed files with 323 additions and 34 deletions

44
.github/ISSUE_TEMPLATE /bug_report.yml vendored Normal file
View File

@@ -0,0 +1,44 @@
name: Bug Report \ 问题反馈
description: Create a report to help us improve \ 帮助改进
labels: ["Bug"]
body:
- type: input
id: title
attributes:
label: Title \ 标题
description: A brief summary of the bug. \ 对于该错误的简要总结。
placeholder: Enter the bug title here. \ 在此输入错误标题。
validations:
required: true
- type: textarea
id: reproduce
attributes:
label: To Reproduce \ 操作流程
description: Steps to reproduce the behaviour. \ 重现该行为的步骤。
placeholder: |
1. Go to '...' \ 1. 进入 '...'
2. Click on '....' \ 2. 点击 '....'
3. Scroll down to '....' \ 3. 向下滚动到 '....'
4. See error \ 4. 查看错误
validations:
required: true
- type: textarea
id: expected-behaviour
attributes:
label: Expected Behaviour \ 预期结果
description: A clear and concise description of what you expected to happen. \ 对您期望发生的事情的清晰简明描述。
placeholder: A clear and concise description of what you expected to happen. \ 对您期望发生的事情的清晰简明描述。
validations:
required: true
- type: textarea
id: software-version
attributes:
label: Software Version \ 软件版本
description: Please specify the version of the software you are using. \ 请指定您使用的软件版本。
placeholder: Enter the software version here. \ 在此输入软件版本。
validations:
required: true

1
.github/ISSUE_TEMPLATE /config.yml vendored Normal file
View File

@@ -0,0 +1 @@
blank_issues_enabled: true

View File

@@ -0,0 +1,31 @@
name: Feature Request \ 功能建议
description: Suggest an idea for this project \ 为这个项目提出一个新想法
labels: ["Enhancement"]
body:
- type: input
id: title
attributes:
label: Title \ 标题
description: A brief summary of your feature request. \ 对您功能建议的简要总结。
placeholder: Enter the feature title here. \ 在此输入功能标题。
validations:
required: true
- type: textarea
id: feature-suggestion
attributes:
label: Feature Suggestion \ 功能建议
description: A clear and concise description of the feature you would like to suggest. \ 对您想要建议的功能的清晰简明描述。
placeholder: Describe your feature suggestion here. \ 在此描述您的功能建议。
validations:
required: true
- type: textarea
id: proposed-solution
attributes:
label: Proposed Solution \ 你的方案
description: A clear and concise description of your proposed solution. \ 对您提议的解决方案的清晰简明描述。
placeholder: Describe your proposed solution here. \ 在此描述您的提议方案。
validations:
required: true

View File

@@ -1,6 +1,6 @@
## Mac
```bash
wails build -platform "darwin/universal" --dmg-name
wails build -platform "darwin/universal"
create-dmg 'build/bin/res-downloader.app' \
--overwrite --dmg-title="res-downloader" \
--dmg-name "res-downloader_$(jq -r '.info.productVersion' wails.json).dmg" \

View File

@@ -14,7 +14,7 @@
!define INFO_PRODUCTNAME "res-downloader"
!endif
!ifndef INFO_PRODUCTVERSION
!define INFO_PRODUCTVERSION "3.0.2"
!define INFO_PRODUCTVERSION "3.0.3"
!endif
!ifndef INFO_COPYRIGHT
!define INFO_COPYRIGHT "Copyright © 2023"

View File

@@ -7,6 +7,7 @@ import (
"github.com/wailsapp/wails/v2/pkg/runtime"
"os"
"path/filepath"
"regexp"
sysRuntime "runtime"
"strconv"
"strings"
@@ -37,12 +38,18 @@ var (
httpServerOnce *HttpServer
)
func GetApp(assets embed.FS) *App {
func GetApp(assets embed.FS, wjs string) *App {
if appOnce == nil {
matches := regexp.MustCompile(`"productVersion":\s*"([\d.]+)"`).FindStringSubmatch(wjs)
version := "1.0.1"
if len(matches) > 0 {
version = matches[1]
}
appOnce = &App{
assets: assets,
AppName: "res-downloader",
Version: "3.0.2",
Version: version,
Description: "res-downloader是一款集网络资源嗅探 + 高速下载功能于一体的软件,高颜值、高性能和多样化,提供个人用户下载自己上传到各大平台的网络资源功能!",
Copyright: "Copyright © 2023~" + strconv.Itoa(time.Now().Year()),
PublicCrt: []byte(`

View File

@@ -15,6 +15,8 @@ type Config struct {
Port string `json:"Port"`
Quality int `json:"Quality"`
SaveDirectory string `json:"SaveDirectory"`
FilenameLen int `json:"FilenameLen"`
FilenameTime bool `json:"FilenameTime"`
UpstreamProxy string `json:"UpstreamProxy"`
OpenProxy bool `json:"OpenProxy"`
DownloadProxy bool `json:"DownloadProxy"`
@@ -33,6 +35,8 @@ func initConfig() *Config {
"Theme": "lightTheme",
"Quality": 0,
"SaveDirectory": "",
"FilenameLen": 0,
"FilenameTime": true,
"UpstreamProxy": "",
"OpenProxy": false,
"DownloadProxy": false,
@@ -64,6 +68,8 @@ func (c *Config) setConfig(config Config) {
c.Theme = config.Theme
c.Quality = config.Quality
c.SaveDirectory = config.SaveDirectory
c.FilenameLen = config.FilenameLen
c.FilenameTime = config.FilenameTime
c.UpstreamProxy = config.UpstreamProxy
c.UserAgent = config.UserAgent
c.OpenProxy = config.OpenProxy

View File

@@ -113,13 +113,22 @@ func (r *Resource) download(mediaInfo MediaInfo, decodeStr string) {
fileName := Md5(rawUrl)
if mediaInfo.Description != "" {
fileName = regexp.MustCompile(`[^\w\p{Han}]`).ReplaceAllString(mediaInfo.Description, "")
fileLen := globalConfig.FilenameLen
if fileLen <= 0 {
fileLen = 10
}
runes := []rune(fileName)
if len(runes) > 10 {
fileName = string(runes[:10])
if len(runes) > fileLen {
fileName = string(runes[:fileLen])
}
}
mediaInfo.SavePath = filepath.Join(globalConfig.SaveDirectory, fileName+"_"+GetCurrentDateTimeFormatted()+mediaInfo.Suffix)
if globalConfig.FilenameTime {
mediaInfo.SavePath = filepath.Join(globalConfig.SaveDirectory, fileName+"_"+GetCurrentDateTimeFormatted()+mediaInfo.Suffix)
} else {
mediaInfo.SavePath = filepath.Join(globalConfig.SaveDirectory, fileName+mediaInfo.Suffix)
}
if strings.Contains(rawUrl, "qq.com") {
if globalConfig.Quality == 1 &&

View File

@@ -4,4 +4,3 @@
* [功能演示](examples.md)
* [更多说明](more.md)
* [常见问题](troubleshooting.md)
* [贡献指南](contribution.md)

View File

@@ -1 +0,0 @@
1

View File

@@ -12,7 +12,7 @@
- 这里演示打开百度这个网站https://www.baidu.com/
![](images/examples-4.png ':size=50%')
### 小程序、公众号、抖音、小红书等操作方法都差不多!
### 小程序、公众号、抖音、小红书、qq音乐、酷狗等应用内资源获取方式都差不多!
## 下载资源到本地
- 选择你想下载的视频 点击下载即可

BIN
docs/images/config.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

BIN
docs/images/more-1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB

BIN
docs/images/more-2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB

BIN
docs/images/more-3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

BIN
docs/images/more-4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

View File

@@ -2,7 +2,7 @@
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<title>res-downloader</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="description" content="Description">
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0">

View File

@@ -1,7 +1,18 @@
## 下载安装文件
- windows下载.exe结尾的根据自己的系统架构下载合适的安装文件通常下载带有“x64-installer.exe”结尾的文件
- Mac下载.dmg结尾即可
- Linux根据系统类型下载对应的执行文件或安装文件
## Windows安装过程
todo
- 双击下载好的exe 正常安装即可,首次打开记得右键管理员运行
## Mac安装过程
todo
- 双击下载好的dmg文件将res-downloader拖入应用即可如图:
![installation-mac-1.png](images/installation-mac-1.png ':size=50%')
## Linux安装过程
todo
- 执行文件运行方式举例
> chmod +x ./res-downloader_3.0.2_linux_x64
> sudo ./res-downloader_3.0.2_linux_x64

View File

@@ -1 +1,21 @@
1
## 隐藏功能
- 导出\导入 数据1秒内连续点击空白处5次即可开启(单次有效)
![more-4.png](images/more-4.png ':size=30%')
## 清空列表、类型筛选
- 当资源列表过大时,无法快速找到需要的资源,这时可以先清空列表再去刷新需要的资源页面
- 资源列表过多,可以快速根据需要的资源类型进行筛选
![more-4.png](images/more-1.png ':size=30%')
## 拦截想要的资源类型、批量下载
- 比如只需要视频时就选择视频类型,可以多选
![more-1.png](images/more-2.png ':size=30%')
## 复制链接、视频解密
- 复制链接可用于第三方软件进行下载,下载完成后对该视频解密,点击“视频解密”选择用其他软件下载完成后的视频文件进行解密
![more-3.png](images/more-3.png ':size=30%')
## 设置说明
!> 修改完成后记得点保存
- 几乎每项配置在软件中都有说明(鼠标悬浮在?处即可查看),此处就不进行多余讲解
![config.png](images/config.png ':size=30%')

View File

@@ -1 +1,46 @@
1
## Mac 提示“已损坏,无法打开”, 打开命令行执行如下命令:
> sudo xattr -d com.apple.quarantine /Applications/res-downloader.app
## 打开本软件,无法正常拦截获取
> 检查系统证书是否安装
> 关闭网络防火墙
> 系统代理是否正确设置(代理地址127.0.0.1 端口8899)
## 关闭软件后无法正常上网
> 手动关闭系统代理设置
## 链接不是私密链接
> 通常是证书未正确安装,最新版证书下载:软件左下角?点击后有下载地址
> 根据自己系统进行安装证书操作(不懂的自行百度),手动安装需安装到受信任的根证书
- Mac手动安装证书(V3+版本支持),打开终端复制以下命令 粘贴到终端回车 按照提示输入密码,完成后再打开软件:
```shell
sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain /Users/$(whoami)/Library/Preferences/res-downloader/cert.crt && touch /Users/$(whoami)/Library/Preferences/res-downloader/install.lock && echo "安装完成"
```
## 拦截不到小程序中的资源
清理微信缓存,删除小程序后,重新打开
> 设置->存储空间->缓存
## 只拦截打开的视频号视频
关闭全量拦截,打开视频号视频详情,通常分享好友后打开的页面属于详情页
## 拦截视频号账号视频
打开对应作者个人主页,浏览即可
## 下载慢、大视频下载失败
推荐使用如下工具加速下载,视频号可以下载完成后再到对应视频操作项选择 “视频解密” 按钮
> [Neat Download Manager](https://www.neatdownloadmanager.com/index.php/en/)、[Motrix](https://motrix.app/download)等软件进行下载
## 直播流: 预览和录制:
> [使用obs进行预览和录制 使用教程自行百度, 点击下载obs]( https://obsproject.com/)
## m3u8: 预览和下载:
> [在线下载](https://m3u8-down.gowas.cn/)、[在线预览](https://m3u8play.com/)
## 安装证书后还会提示安装
使用命令行打开本软件,查看 “lockfile:” 这串字符后面的锁文件路径,然后创建该文件即可
例如 mac系统下终端执行如下命令即可创建
> touch /Users/你的用户名/Library/Preferences/res-downloader/install.lock
## 更多问题 请前往github进行[反馈](https://github.com/putyy/res-downloader/issues)

View File

@@ -8,6 +8,7 @@ export {}
declare module 'vue' {
export interface GlobalComponents {
Footer: typeof import('./src/components/Footer.vue')['default']
ImportJson: typeof import('./src/components/ImportJson.vue')['default']
Index: typeof import('./src/components/layout/Index.vue')['default']
NaiveProvider: typeof import('./src/components/NaiveProvider.vue')['default']
NButton: typeof import('naive-ui')['NButton']

View File

@@ -0,0 +1,36 @@
<template>
<NModal
:show="showModal"
:on-update:show="changeShow"
style="--wails-draggable:no-drag"
preset="card"
class="w-[640px]"
title="导入数据"
>
<NForm
size="medium"
label-placement="left"
label-width="auto"
require-mark-placement="right-hanging"
style="--wails-draggable:no-drag"
>
<NFormItem>
<NInput type="textarea" v-model:value="content" rows="8" :autosize="false" placeholder="添加多个时,请确保每行只有一个(每个链接回车换行)"></NInput>
</NFormItem>
<NFormItem>
<NButton strong secondary type="success" @click="emits('submit', content)" class="w-20">提交</NButton>
</NFormItem>
</NForm>
</NModal>
</template>
<script setup lang="ts">
import {ref} from "vue"
const content = ref("")
const props = defineProps<{
showModal: boolean
}>()
const emits = defineEmits(["update:showModal", "submit"])
const changeShow = (value: boolean) => emits("update:showModal", value)
</script>

View File

@@ -12,6 +12,9 @@
<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>
<NButton type="error" :tertiary="true" size="small" @click="action('delete')">
删除
</NButton>
@@ -19,6 +22,7 @@
</template>
<script setup lang="ts">
import {inject} from "vue"
const props = defineProps<{
row: any,
@@ -27,6 +31,8 @@ const props = defineProps<{
const emits = defineEmits(["action"])
const isDebug = inject('isDebug')
const action = (type: string) => {
emits('action', props.row, props.index, type)
}

View File

@@ -19,6 +19,8 @@ export const useIndexStore = defineStore("index-store", () => {
Quality: 0,
SaveDirectory: "",
UpstreamProxy: "",
FilenameLen: 0,
FilenameTime: false,
OpenProxy: false,
DownloadProxy: false,
AutoProxy: false,

View File

@@ -12,6 +12,8 @@ export namespace appType {
Port: string
Quality: number
SaveDirectory: string
FilenameLen: number
FilenameTime: boolean
UpstreamProxy: string
OpenProxy: boolean
DownloadProxy: boolean

View File

@@ -1,12 +1,13 @@
<template>
<div class="flex flex-col px-5 py-5">
<div class="pb-2 z-40">
<div class="pb-2 z-40" @click="triggerEvent">
<NSpace>
<NButton v-if="isProxy" secondary type="primary" @click="close" style="--wails-draggable:no-drag">关闭代理</NButton>
<NButton v-else tertiary type="tertiary" @click="open" style="--wails-draggable:no-drag">开启代理</NButton>
<NButton tertiary type="info" @click="batchDown" style="--wails-draggable:no-drag">批量下载</NButton>
<NButton tertiary type="error" @click="clear" style="--wails-draggable:no-drag">清空列表</NButton>
<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>
</NSpace>
</div>
<div class="flex-1">
@@ -25,12 +26,13 @@
</div>
<Preview v-model:showModal="showPreviewRow" :previewRow="previewRow"/>
<ShowLoading :loadingText="loadingText" :isLoading="loading"/>
<ImportJson v-model:showModal="showImport" @submit="handleImport"/>
</div>
</template>
<script lang="ts" setup>
import {NButton, NImage, NTooltip} from "naive-ui"
import {computed, h, onMounted, ref, watch} from "vue"
import {computed, h, onMounted, ref, watch, provide} from "vue"
import type {appType} from "@/types/app"
import type {DataTableRowKey, ImageRenderToolbarProps} from "naive-ui"
@@ -42,23 +44,19 @@ import {useIndexStore} from "@/stores"
import appApi from "@/api/app"
import {DwStatus} from "@/const"
import ResAction from "@/components/ResAction.vue"
import ImportJson from "@/components/ImportJson.vue"
import {useEventStore} from "@/stores/event"
import {BrowserOpenURL, ClipboardSetText} from "../../wailsjs/runtime"
const eventStore = useEventStore()
const isProxy = computed(() => {
return store.isProxy
})
const data = ref<any[]>([])
const store = useIndexStore()
const tableHeight = computed(() => {
return store.tableHeight - 132
})
const resourcesType = ref<string[]>(["all"])
const options = [
{
@@ -216,12 +214,17 @@ const columns = ref<any[]>([
}
])
const downIndex = ref(0)
const checkedRowKeysValue = ref<DataTableRowKey[]>([])
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);
onMounted(() => {
const temp = localStorage.getItem("resources-type")
@@ -297,6 +300,15 @@ const dataAction = (row: appType.MediaInfo, index: number, type: string) => {
}
})
break
case "json":
ClipboardSetText(JSON.stringify(row)).then((is: boolean) => {
if (is) {
window?.$message?.success("复制成功")
} else {
window?.$message?.error("复制失败")
}
})
break
case "open":
BrowserOpenURL(row.Url)
break;
@@ -444,4 +456,40 @@ 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 {
let res = JSON.parse(line)
console.log("handleImport", res)
if (res && res?.Id) {
res.Id = res.Id + Math.floor(Math.random() * 100000)
res.SavePath = ""
res.Status = "ready"
data.value.unshift(res)
}
}catch (e) {
console.log(e)
}
});
localStorage.setItem("resources-data", JSON.stringify(data.value))
showImport.value = false
}
</script>

View File

@@ -10,7 +10,7 @@
class="px-5 py-5"
>
<NFormItem label="代理Host" path="Port" size="small">
<NInput v-model:value="formValue.Host" placeholder="0.0.0.0" style="width:256px"/>
<NInput v-model:value="formValue.Host" placeholder="127.0.0.1" style="width:256px"/>
<NTooltip trigger="hover">
<template #trigger>
<NIcon size="20" class="pl-1">
@@ -37,6 +37,25 @@
<NButton strong secondary type="success" @click="selectDir">选择</NButton>
</NSpace>
</NFormItem>
<NFormItem label="文件命名" path="FilenameLen" size="small">
<NInputNumber v-model:value="formValue.FilenameLen" :min="0" :max="9999" placeholder="0" style="width:256px"/>
<NSwitch class="pl-1" v-model:value="formValue.FilenameTime" aria-placeholder="随机数">
<template #checked>
</template>
<template #unchecked>
</template>
</NSwitch>
<NTooltip trigger="hover">
<template #trigger>
<NIcon size="20" class="pl-1">
<HelpCircleOutline />
</NIcon>
</template>
<span>输入框控制文件命名的长度(不含时间0为无效此选项有描述信息时有效)开关控制文件末尾是否添加时间标识</span>
</NTooltip>
</NFormItem>
<NFormItem label="主题" path="theme" size="small">
<NRadio :checked="formValue.Theme === 'lightTheme'" value="lightTheme" name="theme" @change="handleChange">浅色主题</NRadio>
<NRadio :checked="formValue.Theme === 'darkTheme'" value="darkTheme" name="theme" @change="handleChange">深色主题</NRadio>
@@ -76,6 +95,7 @@
</NFormItem>
<NFormItem label="上游代理" path="UpstreamProxy" size="small">
<NInput v-model:value="formValue.UpstreamProxy" placeholder="例如: http://127.0.0.1:7890" style="width:256px"/>
<NSwitch class="pl-1" v-model:value="formValue.OpenProxy" />
<NTooltip trigger="hover">
<template #trigger>
<NIcon size="20" class="pl-1">
@@ -85,9 +105,6 @@
<span>可结合其他代理工具用于访问国外网站以及正常网络无法访问的资源(格式http://username:password@your.proxy.server:port)</span>
</NTooltip>
</NFormItem>
<NFormItem label="开启代理" path="OpenProxy" size="small">
<NSwitch v-model:value="formValue.OpenProxy" />
</NFormItem>
<NFormItem label="下载代理" path="DownloadProxy" size="small">
<NSwitch v-model:value="formValue.DownloadProxy" />
<NTooltip trigger="hover">

View File

@@ -23,9 +23,12 @@ var assets embed.FS
//go:embed build/appicon.png
var icon []byte
//go:embed wails.json
var wailsJson string
func main() {
// Create an instance of the app structure
app := core.GetApp(assets)
app := core.GetApp(assets, wailsJson)
isMac := runtime.GOOS == "darwin"
// menu
appMenu := menu.NewMenu()
@@ -58,6 +61,8 @@ func main() {
|_| \___| |___/ \__,_| \___/ \_/\_/ |_| |_| |_| \___/ \__ ,_| \__,_| \___| |_|`
log.Println(logo)
fmt.Println("version", app.Version)
fmt.Println("lockfile:", app.LockFile)
app.Startup(ctx)
},
OnShutdown: func(ctx context.Context) {

View File

@@ -13,7 +13,7 @@
"info": {
"companyName": "res-downloader",
"productName": "res-downloader",
"productVersion": "3.0.2",
"productVersion": "3.0.3",
"copyright": "Copyright © 2023",
"comments": "This is a high-value, high-performance, and diverse resource downloader called res-downloader."
}