|
@@ -0,0 +1,226 @@
|
|
|
+<template>
|
|
|
+ <el-dialog title="仅编辑 CSS选择器部分" v-model="dialogVisible" :close-on-click-modal="false" width="80%">
|
|
|
+ <div class="dialog-content">
|
|
|
+ <div class="flex gap-2">
|
|
|
+ <el-space>
|
|
|
+ <el-tag type="primary"> {{ formData.code }}</el-tag>
|
|
|
+ <el-tag type="success"> {{ formData.site }}</el-tag>
|
|
|
+ <el-tag type="info"> {{ formData.channel }}</el-tag>
|
|
|
+ <el-tag type="warning">{{ formData.href }}</el-tag>
|
|
|
+ <el-tag type="primary"> {{ formData.modifyuser }}</el-tag>
|
|
|
+ </el-space>
|
|
|
+ </div>
|
|
|
+ <div class="space"></div>
|
|
|
+ <el-form ref="form" :model="formData" label-width="120px">
|
|
|
+ <el-form-item label="URL">
|
|
|
+ <el-input v-model="formData.href"></el-input>
|
|
|
+ </el-form-item>
|
|
|
+ <el-row>
|
|
|
+ <el-col :span="8"><el-form-item label="列表延时(MS)">
|
|
|
+ <el-input v-model="formData.listDelay"></el-input>
|
|
|
+ </el-form-item></el-col>
|
|
|
+ <el-col :span="8"><el-form-item label="详情延时(MS)">
|
|
|
+ <el-input v-model="formData.contentDelay"></el-input>
|
|
|
+ </el-form-item></el-col>
|
|
|
+ <el-col :span="8"><el-form-item label="代理地址">
|
|
|
+ <el-input v-model="formData.proxyServe"></el-input>
|
|
|
+ </el-form-item></el-col>
|
|
|
+ </el-row>
|
|
|
+ <el-row>
|
|
|
+ <el-col :span="12"><el-form-item label="浏览器">
|
|
|
+ <el-radio-group v-model="formData.headless">
|
|
|
+ <el-radio :value="true">无头</el-radio>
|
|
|
+ <el-radio :value="false">显式</el-radio>
|
|
|
+ </el-radio-group> </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="12"><el-form-item label="显示图像">
|
|
|
+ <el-radio-group v-model="formData.showImage">
|
|
|
+ <el-radio :value="true">显示</el-radio>
|
|
|
+ <el-radio :value="false">不显示</el-radio>
|
|
|
+ </el-radio-group> </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+
|
|
|
+ </el-form>
|
|
|
+ <div style="text-align: center;">
|
|
|
+ <el-space>
|
|
|
+ <el-button type="primary" @click="handleDebug"><el-icon>
|
|
|
+ <VideoPlay />
|
|
|
+ </el-icon>执行</el-button>
|
|
|
+ <el-button type="primary" @click="handleStop"><el-icon>
|
|
|
+ <VideoPause />
|
|
|
+ </el-icon>终止</el-button>
|
|
|
+ <el-button type="primary" @click="handleRefersh"><el-icon>
|
|
|
+ <Refresh />
|
|
|
+ </el-icon>刷新结果</el-button>
|
|
|
+ <el-button type="primary" @click="handleCountYestday"><el-icon>
|
|
|
+ <Refresh />
|
|
|
+ </el-icon>统计昨日信息发布量</el-button>
|
|
|
+ <el-dropdown>
|
|
|
+ <el-button type="primary">
|
|
|
+ 结果导出<el-icon class="el-icon--right"><arrow-down /></el-icon>
|
|
|
+ </el-button>
|
|
|
+ <template #dropdown>
|
|
|
+ <el-dropdown-menu>
|
|
|
+ <el-dropdown-item @click="handleExportEpub">导出EPUB格式文件</el-dropdown-item>
|
|
|
+ <el-dropdown-item>导出JSON格式文件</el-dropdown-item>
|
|
|
+ <el-dropdown-item>导出Excel格式文件</el-dropdown-item>
|
|
|
+ <el-dropdown-item>补录/上推至平台</el-dropdown-item>
|
|
|
+ </el-dropdown-menu>
|
|
|
+ </template>
|
|
|
+ </el-dropdown></el-space>
|
|
|
+ </div>
|
|
|
+ <el-divider />
|
|
|
+ <div id="debugEventContian">执行日志: {{ debugLogLine }}</div>
|
|
|
+ <el-divider />
|
|
|
+ <el-table :data="tableData" style="width: 100%" height="240" @row-click="handleRowClick">
|
|
|
+ <el-table-column prop="no" label="序号" width="90" />
|
|
|
+ <el-table-column prop="title" label="标题" width="240" show-overflow-tooltip />
|
|
|
+ <el-table-column prop="href" label="链接" show-overflow-tooltip />
|
|
|
+ <el-table-column prop="contentShort" label="正文" show-overflow-tooltip />
|
|
|
+ </el-table>
|
|
|
+ </div>
|
|
|
+ <ViewArticle ref="articleDialog" />
|
|
|
+ </el-dialog>
|
|
|
+
|
|
|
+</template>
|
|
|
+<script setup>
|
|
|
+import { ref } from 'vue';
|
|
|
+import { ElMessage } from 'element-plus'
|
|
|
+import ViewArticle from "./ViewArticle.vue"
|
|
|
+
|
|
|
+import { ViewCurrentSpiderConfig, DebugSpider, StopDebugSpider } from "../../../wailsjs/go/main/App"
|
|
|
+import { ViewResultItemAll, SelectSaveFilePath, ExportEpubFile, CountYestodayArts } from "../../../wailsjs/go/main/App"
|
|
|
+import { EventsOn, EventsOff } from "../../../wailsjs/runtime"
|
|
|
+
|
|
|
+const formData = ref({
|
|
|
+ // tags
|
|
|
+ code: '',
|
|
|
+ site: '',
|
|
|
+ channel: '',
|
|
|
+ href: '',
|
|
|
+ modifyuser: '',
|
|
|
+
|
|
|
+ // form
|
|
|
+ listDelay: '',
|
|
|
+ contentDelay: '',
|
|
|
+ proxyServe: '',
|
|
|
+ contentDelay: '',
|
|
|
+ headless: false,
|
|
|
+ showImage: false,
|
|
|
+})
|
|
|
+
|
|
|
+const articleDialog = ref(null)
|
|
|
+
|
|
|
+const debugLogLine = ref("")
|
|
|
+const tableData = ref([])
|
|
|
+
|
|
|
+const dialogVisible = ref(false)
|
|
|
+
|
|
|
+const setPageData = (e) => {
|
|
|
+ console.log(e)
|
|
|
+}
|
|
|
+const getPageData = () => {}
|
|
|
+
|
|
|
+//开始调试
|
|
|
+const handleDebug = () => {
|
|
|
+ ElMessage({
|
|
|
+ message: `${[formData.value.url, formData.value.listDelay, formData.value.contentDelay,
|
|
|
+ formData.value.headless, formData.value.showImage, formData.value.proxyServe].join("//")}!`,
|
|
|
+ showClose: true,
|
|
|
+ duration: 3000,
|
|
|
+ });
|
|
|
+ DebugSpider(formData.value.url, parseInt(formData.value.listDelay), parseInt(formData.value.contentDelay),
|
|
|
+ formData.value.headless == 'true', formData.value.showImage == 'true', formData.value.proxyServe)
|
|
|
+}
|
|
|
+//停止调试
|
|
|
+const handleStop = () => {
|
|
|
+ StopDebugSpider()
|
|
|
+}
|
|
|
+//
|
|
|
+const truncateString = (str, maxLength) => {
|
|
|
+ return str.substring(0, maxLength) + "..";
|
|
|
+}
|
|
|
+//刷新加载数据
|
|
|
+const handleRefersh = () => {
|
|
|
+ ViewResultItemAll().then(result => {
|
|
|
+ result = result.slice(-20);
|
|
|
+ result.forEach((v, i) => {
|
|
|
+ v.contentShort = truncateString(v.content, 50)
|
|
|
+ })
|
|
|
+ tableData.value = result
|
|
|
+ })
|
|
|
+}
|
|
|
+//handleExportEpub导出文件
|
|
|
+const handleExportEpub = () => {
|
|
|
+ SelectSaveFilePath().then(r => {
|
|
|
+ if (r == "") return
|
|
|
+ ExportEpubFile(r).then(d => {
|
|
|
+ ElMessage({
|
|
|
+ message: `导出epub文件${r}完成!`,
|
|
|
+ showClose: true,
|
|
|
+ duration: 3000,
|
|
|
+ });
|
|
|
+ })
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+const replaceAll = function (src, search, replacement) {
|
|
|
+ return src.split(search).join(replacement);
|
|
|
+};
|
|
|
+//行点击事件
|
|
|
+const handleRowClick = (row, column, event) => {
|
|
|
+ articleDialog.value.dialogVisible = true
|
|
|
+ row.content = replaceAll(row.content, '\n', '<br/>')
|
|
|
+ articleDialog.value.formData = row
|
|
|
+ articleDialog.value.scrollTop()
|
|
|
+}
|
|
|
+//
|
|
|
+const handleCountYestday = () => {
|
|
|
+ if (formData.value.listNextPageCss != "" && formData.value.listPublishTimeCss != "") {
|
|
|
+ ElMessage({
|
|
|
+ message: `${[formData.value.url, formData.value.listDelay, formData.value.contentDelay,
|
|
|
+ formData.value.headless, formData.value.showImage, formData.value.proxyServe].join("//")}!`,
|
|
|
+ showClose: true,
|
|
|
+ duration: 3000,
|
|
|
+ });
|
|
|
+ CountYestodayArts(formData.value.url, parseInt(formData.value.listDelay), parseInt(formData.value.contentDelay),
|
|
|
+ formData.value.headless == 'true', formData.value.showImage == 'true')
|
|
|
+ } else {
|
|
|
+ ElMessage({
|
|
|
+ message: "当前爬虫设置,CSS选择器,不具备列表页发布时间+列表页翻页。",
|
|
|
+ type: 'error',
|
|
|
+ showClose: true,
|
|
|
+ duration: 3000,
|
|
|
+ });
|
|
|
+ }
|
|
|
+}
|
|
|
+//Wails事件绑定
|
|
|
+EventsOff('debug_event')
|
|
|
+EventsOn("debug_event", data => {
|
|
|
+ debugLogLine.value = data
|
|
|
+})
|
|
|
+//加载当前爬虫配置
|
|
|
+// ViewCurrentSpiderConfig().then(result => {
|
|
|
+// console.log(result)
|
|
|
+// // result['listDelay'] = 500
|
|
|
+// // result['contentDelay'] = 500
|
|
|
+// // result['proxyServe'] = ''
|
|
|
+// // result['showImage'] = 'false'
|
|
|
+// // result['headless'] = 'false'
|
|
|
+// // formData.value = { ...result }
|
|
|
+// })
|
|
|
+
|
|
|
+defineExpose({
|
|
|
+ dialogVisible,
|
|
|
+ formData,
|
|
|
+ setPageData,
|
|
|
+ getPageData,
|
|
|
+})
|
|
|
+</script>
|
|
|
+<style scoped>
|
|
|
+.dialog-content {
|
|
|
+ max-height: 60vh;
|
|
|
+ overflow-y: scroll;
|
|
|
+}
|
|
|
+</style>
|