修改资源数据处理

This commit is contained in:
zyj
2025-10-23 18:17:46 +08:00
parent 211f4f9615
commit 20bda19a81
11 changed files with 250 additions and 97 deletions

View File

@@ -85,14 +85,15 @@
<!-- 结果统计和筛选 --> <!-- 结果统计和筛选 -->
<div class="results-meta"> <div class="results-meta">
<div class="meta-info"> <div class="meta-info">
约为 {{ searchResults.length }} 条结果用时 {{ searchTime }} 用时 {{ searchTime }}
</div> </div>
<div class="filter-options"> <div class="filter-options">
<a-radio-group v-model:value="filterType" size="small"> <a-radio-group v-model:value="filterType" size="small">
<a-radio-button value="all">全部</a-radio-button> <a-radio-button value="all">全部</a-radio-button>
<a-radio-button value="images">图片</a-radio-button> <a-radio-button value="images">图片</a-radio-button>
<a-radio-button value="news">新闻</a-radio-button> <a-radio-button value="news">样式</a-radio-button>
<a-radio-button value="videos">视频</a-radio-button> <a-radio-button value="videos">脚本</a-radio-button>
<a-radio-button value="videos">媒体</a-radio-button>
</a-radio-group> </a-radio-group>
</div> </div>
</div> </div>
@@ -102,36 +103,60 @@
<a-card class="results-card" :bordered="false"> <a-card class="results-card" :bordered="false">
<a-list <a-list
item-layout="vertical" item-layout="vertical"
:data-source="searchResults"
:loading="searchLoading" :loading="searchLoading"
:pagination="paginationConfig" :pagination="paginationConfig"
> >
<template #renderItem="{ item, index }"> <a-list-item class="result-item">
<a-list-item class="result-item"> <a-list-item-meta description="页面文件过多可能是当前站点包含博客、教程页面。">
<div class="result-number">{{ index + 1 }}</div> <template #title>
<a-list-item-meta :description="item.description"> <a class="result-title">页面文件</a>
<template #title> </template>
<a :href="item.url" target="_blank" class="result-title"> </a-list-item-meta>
{{ item.title }} <div class="result-content">
<span class="external-icon"></span> <div class="result-snippet">可下载{{ searchResults?.dom.length }}</div>
</a> </div>
</template> </a-list-item>
<template #avatar>
<div class="result-avatar">
<span class="result-url">{{ item.displayUrl }}</span>
</div>
</template>
</a-list-item-meta>
<div class="result-content">
<div class="result-snippet">{{ item.snippet }}</div>
<div class="result-meta">
<span class="publish-date">{{ item.date }}</span>
<a-tag v-if="item.featured" color="blue" class="feature-tag">精选</a-tag>
</div>
</div>
</a-list-item>
</template>
<a-list-item class="result-item">
<a-list-item-meta description="统计包含站点所有图片资源,包含站外、站内,默认只下载站内资源。">
<template #title>
<a class="result-title">图片文件</a>
</template>
</a-list-item-meta>
<div class="result-content">
<div class="result-snippet">可下载{{ searchResults?.image.length }}</div>
</div>
</a-list-item>
<a-list-item class="result-item">
<a-list-item-meta description="统计包含站点所有CSS资源包含站外、站内默认只下载站内资源。">
<template #title>
<a class="result-title">样式文件</a>
</template>
</a-list-item-meta>
<div class="result-content">
<div class="result-snippet">可下载{{ searchResults?.css.length }}</div>
</div>
</a-list-item>
<a-list-item class="result-item">
<a-list-item-meta description="统计包含站点所有脚本资源,包含站外、站内,默认只下载站内资源。">
<template #title>
<a class="result-title">脚本文件</a>
</template>
</a-list-item-meta>
<div class="result-content">
<div class="result-snippet">可下载{{ searchResults?.script.length }}</div>
</div>
</a-list-item>
<a-list-item class="result-item">
<a-list-item-meta description="统计包含站点所有媒体资源,包含站外、站内,默认只下载站内资源。">
<template #title>
<a class="result-title">媒体文件</a>
</template>
</a-list-item-meta>
<div class="result-content">
<div class="result-snippet">可下载{{ searchResults?.video.length }}</div>
</div>
</a-list-item>
<template #loadMore> <template #loadMore>
<div v-if="searchLoading" class="loading-more"> <div v-if="searchLoading" class="loading-more">
<a-spin /> <a-spin />
@@ -165,7 +190,8 @@
import { ref, onMounted, nextTick } from 'vue' import { ref, onMounted, nextTick } from 'vue'
import { SearchOutlined, SettingOutlined, MenuOutlined } from '@ant-design/icons-vue' import { SearchOutlined, SettingOutlined, MenuOutlined } from '@ant-design/icons-vue'
import {App} from "../../../bindings/go-site-clone"; import {App} from "../../../bindings/go-site-clone";
const { $message } = useNuxtApp();
const [messageApi, contextHolder] = $message.useMessage();
// 搜索状态 // 搜索状态
const searchKeyword = ref('') const searchKeyword = ref('')
const hasSearched = ref(false) const hasSearched = ref(false)
@@ -199,12 +225,33 @@ const relatedSearches = [
] ]
// 模拟搜索结果 // 模拟搜索结果
const searchResults = ref([]) const searchResults = ref({
script: [],
css: [],
image: [],
dom: [],
video: [],
})
const resourceData = ref({
script: [],
scriptD: [],
css: [],
cssD: [],
image: [],
imageD: [],
video: [],
videoD: []
})
const isValidURL = (str) => { try { new URL(str); return true; } catch { return false; }} const isValidURL = (str) => { try { new URL(str); return true; } catch { return false; }}
// 搜索处理函数 // 搜索处理函数
const handleSearch = async () => { const handleSearch = async () => {
if (searchLoading.value == true) {
messageApi.info('当前已有网址在获取详情!');
return
}
if (!searchKeyword.value.trim()) { if (!searchKeyword.value.trim()) {
return return
@@ -215,59 +262,16 @@ const handleSearch = async () => {
searchLoading.value = true searchLoading.value = true
const startTime = Date.now() const startTime = Date.now()
// 模拟搜索延迟
await new Promise(resolve => setTimeout(resolve, 1200))
searchTime.value = (Date.now() - startTime) / 1000
hasSearched.value = true
searchLoading.value = false
// 生成模拟搜索结果
searchResults.value = [
{
title: 'Vue.js - 渐进式 JavaScript 框架 | 最新版本特性详解',
description: '官方文档 • 最新更新',
url: 'https://vuejs.org',
displayUrl: 'https://vuejs.org',
snippet: 'Vue.js 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是Vue 被设计为可以自底向上逐层应用。Vue 3 引入了 Composition API、性能优化等新特性。',
date: '2024年10月15日',
featured: true
},
{
title: 'Nuxt.js - 直观的 Vue 框架 | 服务端渲染解决方案',
description: 'Nuxt.js 官方网站',
url: 'https://nuxtjs.org',
displayUrl: 'https://nuxtjs.org',
snippet: 'Nuxt.js 是一个基于 Vue.js 的轻量级应用框架,可用来创建服务端渲染 (SSR) 应用也可作为静态站点生成器。Nuxt 4 带来了更好的性能和开发体验。',
date: '2024年9月20日',
featured: false
},
{
title: 'Ant Design Vue - 企业级 Vue UI 组件库',
description: 'Ant Design 的 Vue 实现',
url: 'https://antdv.com',
displayUrl: 'https://antdv.com',
snippet: 'Ant Design Vue 为 Web 应用提供了丰富的基础 UI 组件,助力设计人员快速构建美观统一的产品。',
date: '2024年8月15日',
featured: true
},
{
title: 'Google 搜索首页的演变与设计理念',
description: '设计历史文章',
url: 'https://example.com/google-design',
displayUrl: 'https://example.com/google-design',
snippet: '了解 Google 搜索首页从简单到现代的设计演变过程,探索其用户体验设计理念和简约美学。',
date: '2024年7月22日',
featured: false
}
]
nextTick(() => { nextTick(() => {
setTimeout(() => { setTimeout(() => {
searchInputRef.value?.focus() searchInputRef.value?.focus()
App.GetResources(searchKeyword.value.trim()).then((res) => { App.GetResources(searchKeyword.value.trim()).then((res) => {
console.log(res); if(res) {
searchResults.value = res
}
searchTime.value = (Date.now() - startTime) / 1000
hasSearched.value = true
searchLoading.value = false
}) })
}, 400) }, 400)
}) })

View File

@@ -1,8 +1,9 @@
import { defineNuxtPlugin } from '#app' import { defineNuxtPlugin } from '#app'
import Antd, { notification } from 'ant-design-vue' import Antd, { notification, message } from 'ant-design-vue'
import 'ant-design-vue/dist/reset.css' // v4 使用新样式重置文件 import 'ant-design-vue/dist/reset.css' // v4 使用新样式重置文件
export default defineNuxtPlugin((nuxtApp) => { export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.vueApp.use(Antd) nuxtApp.vueApp.use(Antd)
nuxtApp.provide('notification', notification) nuxtApp.provide('notification', notification)
nuxtApp.provide('message', message)
}) })

View File

@@ -0,0 +1,32 @@
// @ts-check
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// This file is automatically generated. DO NOT EDIT
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Unused imports
import { Call as $Call, CancellablePromise as $CancellablePromise, Create as $Create } from "@wailsio/runtime";
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Unused imports
import * as services$0 from "./services/models.js";
/**
* @returns {$CancellablePromise<void>}
*/
export function DownloadSite() {
return $Call.ByID(2539977978);
}
/**
* @param {string} rawURL
* @returns {$CancellablePromise<services$0.ResourcesList | null>}
*/
export function GetResources(rawURL) {
return $Call.ByID(2167352808, rawURL).then(/** @type {($result: any) => any} */(($result) => {
return $$createType1($result);
}));
}
// Private type creation functions
const $$createType0 = services$0.ResourcesList.createFrom;
const $$createType1 = $Create.Nullable($$createType0);

View File

@@ -0,0 +1,15 @@
// @ts-check
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// This file is automatically generated. DO NOT EDIT
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Unused imports
import { Call as $Call, CancellablePromise as $CancellablePromise, Create as $Create } from "@wailsio/runtime";
/**
* @param {string} name
* @returns {$CancellablePromise<string>}
*/
export function Greet(name) {
return $Call.ByID(1411160069, name);
}

View File

@@ -0,0 +1,10 @@
// @ts-check
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// This file is automatically generated. DO NOT EDIT
import * as App from "./app.js";
import * as GreetService from "./greetservice.js";
export {
App,
GreetService
};

View File

@@ -0,0 +1,7 @@
// @ts-check
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// This file is automatically generated. DO NOT EDIT
export {
ResourcesList
} from "./models.js";

View File

@@ -0,0 +1,86 @@
// @ts-check
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// This file is automatically generated. DO NOT EDIT
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Unused imports
import { Create as $Create } from "@wailsio/runtime";
export class ResourcesList {
/**
* Creates a new ResourcesList instance.
* @param {Partial<ResourcesList>} [$$source = {}] - The source object to create the ResourcesList.
*/
constructor($$source = {}) {
if (!("script" in $$source)) {
/**
* @member
* @type {string[]}
*/
this["script"] = [];
}
if (!("css" in $$source)) {
/**
* @member
* @type {string[]}
*/
this["css"] = [];
}
if (!("image" in $$source)) {
/**
* @member
* @type {string[]}
*/
this["image"] = [];
}
if (!("dom" in $$source)) {
/**
* @member
* @type {string[]}
*/
this["dom"] = [];
}
if (!("video" in $$source)) {
/**
* @member
* @type {string[]}
*/
this["video"] = [];
}
Object.assign(this, $$source);
}
/**
* Creates a new ResourcesList instance from a string or object.
* @param {any} [$$source = {}]
* @returns {ResourcesList}
*/
static createFrom($$source = {}) {
const $$createField0_0 = $$createType0;
const $$createField1_0 = $$createType0;
const $$createField2_0 = $$createType0;
const $$createField3_0 = $$createType0;
const $$createField4_0 = $$createType0;
let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source;
if ("script" in $$parsedSource) {
$$parsedSource["script"] = $$createField0_0($$parsedSource["script"]);
}
if ("css" in $$parsedSource) {
$$parsedSource["css"] = $$createField1_0($$parsedSource["css"]);
}
if ("image" in $$parsedSource) {
$$parsedSource["image"] = $$createField2_0($$parsedSource["image"]);
}
if ("dom" in $$parsedSource) {
$$parsedSource["dom"] = $$createField3_0($$parsedSource["dom"]);
}
if ("video" in $$parsedSource) {
$$parsedSource["video"] = $$createField4_0($$parsedSource["video"]);
}
return new ResourcesList(/** @type {Partial<ResourcesList>} */($$parsedSource));
}
}
// Private type creation functions
const $$createType0 = $Create.Array($Create.Any);

1
go.mod
View File

@@ -8,7 +8,6 @@ require (
github.com/go-rod/stealth v0.4.9 github.com/go-rod/stealth v0.4.9
github.com/mattn/go-sqlite3 v1.14.32 github.com/mattn/go-sqlite3 v1.14.32
github.com/wailsapp/wails/v3 v3.0.0-alpha.27 github.com/wailsapp/wails/v3 v3.0.0-alpha.27
github.com/webview/webview_go v0.0.0-20240831120633-6173450d4dd6
gopkg.in/yaml.v3 v3.0.1 gopkg.in/yaml.v3 v3.0.1
) )

2
go.sum
View File

@@ -117,8 +117,6 @@ github.com/wailsapp/mimetype v1.4.1 h1:pQN9ycO7uo4vsUUuPeHEYoUkLVkaRntMnHJxVwYhw
github.com/wailsapp/mimetype v1.4.1/go.mod h1:9aV5k31bBOv5z6u+QP8TltzvNGJPmNJD4XlAL3U+j3o= github.com/wailsapp/mimetype v1.4.1/go.mod h1:9aV5k31bBOv5z6u+QP8TltzvNGJPmNJD4XlAL3U+j3o=
github.com/wailsapp/wails/v3 v3.0.0-alpha.27 h1:Y3D/GTNYPq0AxeKX7lwId+mjBLck6x4XtbCleuebJ5A= github.com/wailsapp/wails/v3 v3.0.0-alpha.27 h1:Y3D/GTNYPq0AxeKX7lwId+mjBLck6x4XtbCleuebJ5A=
github.com/wailsapp/wails/v3 v3.0.0-alpha.27/go.mod h1:UZpnhYuju4saspCJrIHAvC0H5XjtKnqd26FRxJLrQ0M= github.com/wailsapp/wails/v3 v3.0.0-alpha.27/go.mod h1:UZpnhYuju4saspCJrIHAvC0H5XjtKnqd26FRxJLrQ0M=
github.com/webview/webview_go v0.0.0-20240831120633-6173450d4dd6 h1:VQpB2SpK88C6B5lPHTuSZKb2Qee1QWwiFlC5CKY4AW0=
github.com/webview/webview_go v0.0.0-20240831120633-6173450d4dd6/go.mod h1:yE65LFCeWf4kyWD5re+h4XNvOHJEXOCOuJZ4v8l5sgk=
github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw=
github.com/ysmood/fetchup v0.2.3 h1:ulX+SonA0Vma5zUFXtv52Kzip/xe7aj4vqT5AJwQ+ZQ= github.com/ysmood/fetchup v0.2.3 h1:ulX+SonA0Vma5zUFXtv52Kzip/xe7aj4vqT5AJwQ+ZQ=

View File

@@ -1,18 +1,18 @@
package libs package libs
import webview "github.com/webview/webview_go" // import webview "github.com/webview/webview_go"
type Pack struct{} // type Pack struct{}
func (Pack) Test() { // func (Pack) Test() {
debug := true // debug := true
w := webview.New(debug) // w := webview.New(debug)
defer w.Destroy() // defer w.Destroy()
w.SetTitle("Go + WebView2 应用") // w.SetTitle("Go + WebView2 应用")
w.SetSize(1024, 768, webview.HintNone) // w.SetSize(1024, 768, webview.HintNone)
// 加载远程网页 // // 加载远程网页
w.Navigate("https://www.baidu.com") // w.Navigate("https://www.baidu.com")
w.Run() // w.Run()
} // }

View File

@@ -59,6 +59,7 @@ func (s SiteService) GetAllResources(rawURL string) ([]RequestParams, []string)
} }
list := deduplicationRequest(RequestParamsAll) list := deduplicationRequest(RequestParamsAll)
browser.Close() browser.Close()
Browser.CancelBrowser(host)
return list, RouterAll return list, RouterAll
} }