Commit 518e8e10 by yzh

feat:任务信息接口接上

parent 33062b3a
......@@ -15,6 +15,7 @@
"@types/nprogress": "^0.2.3",
"@types/uuid": "^10.0.0",
"axios": "^1.9.0",
"cron-parser": "^5.4.0",
"echarts": "^5.6.0",
"element-plus": "^2.9.10",
"js-cookie": "^3.0.5",
......
......@@ -26,6 +26,9 @@ importers:
axios:
specifier: ^1.9.0
version: 1.9.0
cron-parser:
specifier: ^5.4.0
version: 5.4.0
echarts:
specifier: ^5.6.0
version: 5.6.0
......@@ -706,6 +709,10 @@ packages:
resolution: {integrity: sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==}
engines: {node: '>=12.13'}
cron-parser@5.4.0:
resolution: {integrity: sha512-HxYB8vTvnQFx4dLsZpGRa0uHp6X3qIzS3ZJgJ9v6l/5TJMgeWQbLkR5yiJ5hOxGbc9+jCADDnydIe15ReLZnJA==}
engines: {node: '>=18'}
css-tree@3.1.0:
resolution: {integrity: sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==}
engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0}
......@@ -918,6 +925,10 @@ packages:
lodash@4.17.21:
resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
luxon@3.7.2:
resolution: {integrity: sha512-vtEhXh/gNjI9Yg1u4jX/0YVPMvxzHuGgCm6tC5kZyb08yjGWGnqAjGJvcXbqQR2P3MyMEFnRbpcdFS6PBcLqew==}
engines: {node: '>=12'}
magic-string@0.30.17:
resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==}
......@@ -1967,6 +1978,10 @@ snapshots:
dependencies:
is-what: 4.1.16
cron-parser@5.4.0:
dependencies:
luxon: 3.7.2
css-tree@3.1.0:
dependencies:
mdn-data: 2.12.2
......@@ -2179,6 +2194,8 @@ snapshots:
lodash@4.17.21: {}
luxon@3.7.2: {}
magic-string@0.30.17:
dependencies:
'@jridgewell/sourcemap-codec': 1.5.0
......
......@@ -95,6 +95,7 @@ export const spiderTaskApi = {
pauseJob: '/schedule/pauseJob',
resumeJob: '/schedule/resumeJob',
jobDetail: '/schedule/jobDetail',
taskCount:'/schedule/getAllJobCount'
} as const
// 爬虫数据相关接口
......@@ -108,6 +109,7 @@ export const spiderDataApi = {
stList: '/spaceTrack/list',
stDetail: '/spaceTrack/detail',
stDataDelete: '/sspaceTrackt/delete',
exportSpiderData: '/export/downloadFile',
} as const
......@@ -116,6 +118,6 @@ export const dataApi = {
dataStatistics: '/statistic/dataStatistics',
taskStatistics: '/statistic/taskStatistics',
performanceStatistics: '/statistic/performanceStatistics',
allSpiderTaskStatistics: '/statistic/getAllTaskStatistics',
} as const
......@@ -82,3 +82,12 @@ export function deleteStData(data: UserQueryParams) {
data
}) as unknown as Promise<ApiResponse>
}
// 导出爬虫数据
export function esportSpiderData(data: UserQueryParams) {
return request({
url: spiderDataApi.exportSpiderData,
method: POST,
data
}) as unknown as Promise<ApiResponse>
}
\ No newline at end of file
......@@ -64,3 +64,12 @@ export function getTaskData(data: UserQueryParams) {
data
}) as unknown as Promise<ApiResponse>
}
// 获取爬虫任务统计
export function getTaskCount(data: UserQueryParams) {
return request({
url: spiderTaskApi.taskCount,
method: POST,
data
}) as unknown as Promise<ApiResponse>
}
\ No newline at end of file
......@@ -20,7 +20,7 @@ export function getSpiderTaskList(params: QueryParams): Promise<ApiResponse> {
}) as unknown as Promise<ApiResponse>
}
// 获取爬虫任务列表
// 获取性能统计列表
export function getPerformanceList(params: QueryParams): Promise<ApiResponse> {
return request({
url: dataApi.performanceStatistics,
......@@ -28,3 +28,12 @@ export function getPerformanceList(params: QueryParams): Promise<ApiResponse> {
params
}) as unknown as Promise<ApiResponse>
}
// 获取爬虫任务统计列表
export function getAllSpiderTaskStatistics(params: QueryParams): Promise<ApiResponse> {
return request({
url: dataApi.allSpiderTaskStatistics,
method: POST,
params
}) as unknown as Promise<ApiResponse>
}
\ No newline at end of file
......@@ -4,12 +4,12 @@
<!-- <span style="color: #fff;font-size: 15px;">请选择导出数据时间与数据类型。</span>
<br> -->
<el-date-picker v-model="timeValue" type="datetimerange" format="YYYY-MM-DD HH:mm:ss" start-placeholder="开始时间"
end-placeholder="结束时间" date-format="YYYY/MM/DD ddd" time-format="A hh:mm:ss" style="width: 270px"
end-placeholder="结束时间" date-format="YYYY/MM/DD ddd" time-format="A hh:mm:ss" style="width: 280px"
value-format="YYYY-MM-DD HH:mm:ss" />
<el-checkbox-group v-model="checkList">
<el-checkbox label="DSN数据" value="dsn" />
<el-checkbox label="ITU数据" value="itu" />
<el-checkbox label="ST数据" value="st" />
<el-checkbox label="ST数据" value="spaceTrack" />
</el-checkbox-group>
</div>
<template #footer>
......@@ -26,7 +26,8 @@
<script lang="ts" setup>
import { ref, watch } from 'vue'
import { defineProps } from 'vue';
import { esportSpiderData } from '@/api/spiderData';
import axios from 'axios'
const props = defineProps({
dialogVisible: {
type: Boolean,
......@@ -42,8 +43,28 @@ const exportDialogVisible = ref(props.dialogVisible)
const checkList = ref([])
const timeValue = ref('')
// 导出方法
const handleExport = () => {
emit('confirm')
const handleExport = async () => {
const result = await esportSpiderData({ times: timeValue.value, filters: checkList.value })
// aaa(result)
// axios({
// method: 'post',
// url: 'http://localhost:5001/api/export/downloadFile',
// responseType: 'blob',
// data: { times: timeValue.value, filters: checkList.value }
// // he
// })
// .then(res => {
// // 假设 data 是返回来的二进制数据
// const url = window.URL.createObjectURL(new Blob([res], { type: "application/zip" }))
// const link = document.createElement('a')
// link.style.display = 'none'
// link.href = url
// link.setAttribute('download', '333.zip')
// document.body.appendChild(link)
// link.click()
// document.body.removeChild(link)
// })
exportDialogVisible.value = false
}
// 关闭弹窗的方法
......@@ -62,4 +83,89 @@ watch(() => exportDialogVisible.value,
emit('update:dialogVisible', newVal)
}
)
// const triggerDownload = (blobData: any) => {
// const zipFile = new File([blobData], 'archive.zip', {
// type: 'application/zip',
// });
// console.log(zipFile);
// const fileUrl = URL.createObjectURL(zipFile);
// // 创建下载链接
// const downloadLink = document.createElement('a');
// downloadLink.href = fileUrl;
// // 使用File对象的名称作为下载文件名
// downloadLink.download = zipFile.name;
// // 将链接添加到页面并触发点击
// document.body.appendChild(downloadLink);
// downloadLink.click();
// // 清理资源
// setTimeout(() => {
// // 移除链接元素
// document.body.removeChild(downloadLink);
// // 释放临时URL
// URL.revokeObjectURL(fileUrl);
// }, 0);
// }
// const aaa = (res: any) => {
// // const blob = new Blob([res], { type: 'application/zip' })
// // const link = document.createElement('a')
// // link.style.display = 'none'
// // link.href = URL.createObjectURL(blob)
// // link.setAttribute('download', `${'111'}.zip`)
// // document.body.appendChild(link)
// // link.click()
// // document.body.removeChild(link)
// // const url = window.URL.createObjectURL(new Blob([res], { type: "application/zip" }))
// // const link = document.createElement('a')
// // link.style.display = 'none'
// // link.href = url
// // link.setAttribute('download', '222.zip')
// // document.body.appendChild(link)
// // link.click()
// // document.body.removeChild(link)
// const url = window.URL.createObjectURL(res);
// const a = document.createElement('a');
// a.style.display = 'none';
// a.href = url;
// a.download = 'example.zip';
// document.body.appendChild(a);
// a.click();
// window.URL.revokeObjectURL(url);
// }
// function downloadZipFromBinary(binaryString: any, fileName: string) {
// try {
// if (!fileName.endsWith('.zip')) {
// fileName += '.zip';
// }
// const uint8Array = new Uint8Array(binaryString);
// const blob = new Blob([uint8Array], { type: 'application/zip' });
// const url = URL.createObjectURL(blob);
// const a = document.createElement('a');
// a.href = url;
// a.download = fileName;
// document.body.appendChild(a);
// a.click();
// setTimeout(() => {
// document.body.removeChild(a);
// URL.revokeObjectURL(url);
// }, 100);
// } catch (error) {
// console.error('下载ZIP文件时发生错误:', error);
// throw error;
// }
// }
</script>
\ No newline at end of file
......@@ -63,3 +63,37 @@
--el-segmented-item-hover-color: #FFFFFF;
--el-segmented-item-active-bg-color: #1977d5d7;
}
.el-dialog {
background-image: url("@/assets/picture/dialog1.png");
background-size: 100% 100%;
background-repeat: no-repeat;
.el-form-item__label {
color: #ffffff;
}
.el-dialog__header {
color: #ffffff;
}
.el-dialog__title {
color: #ffffff;
}
.el-textarea__inner {
background-color: #1d5484;
color: #ffffff;
box-shadow: none;
}
}
// .el-date-editor {
// .el-date-editor {
// color: #ffffff;
// }
// }
.el-date-editor .el-range-input{
color: #ffffff;
}
\ No newline at end of file
......@@ -7,7 +7,7 @@ const instance = axios.create({
baseURL: import.meta.env.VITE_APP_BASE_API || '',
timeout: 10000, // 毫秒
headers: {
'Content-Type': 'application/json; charset=utf-8'
'Content-Type': 'application/zip; charset=utf-8'
}
})
......@@ -120,4 +120,5 @@ export interface UserQueryParams {
options?: string
sat_name?: string
ntc_id?: string
filters?: any
}
\ No newline at end of file
......@@ -14,9 +14,9 @@
<el-text class="mx-1">获取时间:</el-text>
</el-form-item>
<el-form-item>
<el-date-picker v-model="timeValue" type="datetimerange" format="YYYY-MM-DD HH:mm:ss" start-placeholder="开始时间"
style="width: 250px" end-placeholder="结束时间" date-format="YYYY/MM/DD ddd" time-format="A hh:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss" />
<el-date-picker v-model="timeValue" type="datetimerange" format="YYYY-MM-DD HH:mm:ss"
start-placeholder="开始时间" style="width: 250px" end-placeholder="结束时间"
date-format="YYYY/MM/DD ddd" time-format="A hh:mm:ss" value-format="YYYY-MM-DD HH:mm:ss" />
</el-form-item>
<el-form-item>
<el-text class="mx-1">SNS Notice ID:</el-text>
......@@ -90,9 +90,10 @@
</el-table-column>
<el-table-column property="regulatory_status.active_status" label="状态" show-overflow-tooltip />
<el-table-column property="regulatory_status.prd_valid" label="有效期" show-overflow-tooltip />
<el-table-column property="regulatory_status.d_reg_limit" label="最早使用日期" show-overflow-tooltip >
<el-table-column property="regulatory_status.d_reg_limit" label="最早使用日期" show-overflow-tooltip>
<template #default="scope">
{{ scope.row.regulatory_status.d_reg_limit === null ? '-' : scope.row.regulatory_status.d_reg_limit }}
{{ scope.row.regulatory_status.d_reg_limit === null ? '-' : scope.row.regulatory_status.d_reg_limit
}}
</template>
</el-table-column>
<el-table-column property="regulatory_status.f_biu_grps" label="是否确认使用" show-overflow-tooltip />
......@@ -334,9 +335,8 @@ const handleDetails = async (id: any) => {
// console.log(id._id);
const res = await getItuDetail({ id: id._id })
console.log(res);
detailVisibleValue.value = true
snsId.value = res.data.item.ntc_id
department.value = res.data.item.notifying_adm_tooltip
department.value = res.data.item.adm
targetName.value = res.data.identity.sat_name
planType.value = res.data.identity.plan_type
syncType.value = res.data.identity.ntc_type
......@@ -349,15 +349,17 @@ const handleDetails = async (id: any) => {
highestFrequency.value = res.data.item.freq_max === null ? '无' : res.data.item.freq_max
status.value = res.data.regulatory_status.active_status
validityPeriod.value = res.data.regulatory_status.prd_valid
earliestUsageDate.value = res.data.regulatory_status.d_reg_limit
earliestUsageDate.value = res.data.regulatory_status.d_reg_limit === null ? '无' : res.data.regulatory_status.d_reg_limit
isUsed.value = res.data.regulatory_status.f_biu_grps
isPauseUsed.value = res.data.regulatory_status.resumption_list
// recordTime.value = res.data.regulatory_status.d_inuse_list
recordTime.value = res.data.crawl_time
IsInTheInternationalFrequencyList.value = res.data.regulatory_status.mifr
earliestRegulatoryDate.value = JSON.parse(res.data.regulatory_status.d_inuse_list)
earliestRegulatoryDate.value = res.data.regulatory_status.d_inuse_list
isRestoreUsed.value = res.data.regulatory_status.resumption_list
validityPeriodSatelliteNetworkOldName.value = res.data.regulatory_status.old_satellite_network_name
BFIFICdate.value = res.data.regulatory_status.d_wic
BFIFICdate.value = res.data.regulatory_status.d_wic === null ? '无' : res.data.regulatory_status.d_wic
detailVisibleValue.value = true
}
const getData = async () => {
const res = await getItulist({ page: pageObj.value.pageNo, size: pageObj.value.pageSize })
......@@ -397,6 +399,9 @@ onMounted(() => {
<style scoped lang="scss">
// 调整表单项间距
.detailForm {
// background-image: url("@/assets/picture/dialog1.png");
// background-size: 100% 100%;
// background-repeat: no-repeat;
.el-dialog-title {
font-size: 180px;
}
......@@ -425,9 +430,11 @@ onMounted(() => {
.el-text {
color: #FFFFFF;
}
</style>
<style>
.el-input {
--el-input-text-color: #FFFFFF;
}
......
......@@ -338,4 +338,6 @@ onMounted(() => {
.el-button:focus {
outline: none;
}
</style>
\ No newline at end of file
......@@ -2,10 +2,9 @@
<div>
<div class="backStyle" v-if="route.query.jump === 'yes'" @click="goToStatus" />
<div class="text-left p-4 ">
<div class="custom-style">
<div class="custom-style flex gap-4">
<el-segmented v-model="mode" :options="sizeOptions" style="margin-bottom: 1rem" size="default" />
<el-button type="primary" @click="handleExport
">导出最近</el-button>
<el-button type="primary" @click="handleExport" class="m-r-10">导出</el-button>
</div>
</div>
<!-- 综合数据页面组件 -->
......
......@@ -96,9 +96,6 @@ const getData = async () => {
speed.value = performance.data.success
errorRate.value = performance.data.error
unusualRate.value = performance.data.exception
console.log(staticData);
console.log(spiderTask);
console.log(performance);
}
onMounted(() => {
......
......@@ -6,16 +6,16 @@
<span>DSN爬取任务</span>
</div>
<div class="wordStyle">
<span>任务采集目标数: {{ totalDataNumber }} 638</span>
<span>DSN爬虫任务数: {{ dsnTotalTaskNumber }} </span>
</div>
<div class="wordStyle">
<span>任务执行成功统计: {{ totalPageNumber }} 79</span>
<span>任务执行成功统计: {{ dsnTaskSuccessNumber }} </span>
</div>
<div class="wordStyle">
<span>采集速度: {{ totalTargetNumber }} 324</span>
<span>任务执行失败统计: {{ dsnTaskFailNumber }} </span>
</div>
<div class="wordStyle">
<span>错误率: {{ totalTargetNumber }} 1%</span>
<span>错误率: {{ dsnErrorRate }} </span>
</div>
</div>
<div class="dataCard" @click="goToITUTaskRecordPage">
......@@ -23,16 +23,16 @@
<span>ITU爬取任务</span>
</div>
<div class="wordStyle">
<span>任务采集目标数: {{ totalDataNumber }} 148</span>
<span>ITU爬虫任务数: {{ ituTotalTaskNumber }} </span>
</div>
<div class="wordStyle">
<span>任务执行成功统计: {{ totalPageNumber }} 98</span>
<span>任务执行成功统计: {{ ituTaskSuccessNumber }} </span>
</div>
<div class="wordStyle">
<span>采集速度: {{ totalTargetNumber }} 322</span>
<span>任务执行失败统计: {{ ituTaskFailNumber }} </span>
</div>
<div class="wordStyle">
<span>错误率: {{ totalTargetNumber }} 1%</span>
<span>错误率: {{ ituErrorRate }} </span>
</div>
</div>
<div class="dataCard" @click="goToSTTaskRecordPage">
......@@ -40,16 +40,16 @@
<span>ST爬取任务</span>
</div>
<div class="wordStyle">
<span>任务采集目标数: {{ totalDataNumber }} 136</span>
<span>ST爬虫任务数: {{ stTotalTaskNumber }} </span>
</div>
<div class="wordStyle">
<span>任务执行成功统计: {{ totalPageNumber }} 86</span>
<span>任务执行成功统计: {{ stTaskSuccessNumber }} </span>
</div>
<div class="wordStyle">
<span>采集速度: {{ totalTargetNumber }} 342</span>
<span>采集速度: {{ stTaskFailNumber }} </span>
</div>
<div class="wordStyle">
<span>错误率: {{ totalTargetNumber }} 0%</span>
<span>错误率: {{ stErrorRate }} </span>
</div>
</div>
</div>
......@@ -57,41 +57,24 @@
<script lang="ts" setup>
import { useRouter } from 'vue-router'
import { getAllSpiderTaskStatistics } from '@/api/staticData';
import { onMounted,ref } from 'vue';
const router = useRouter()
defineProps({
totalDataNumber: {
type: String,
default: ''
},
totalPageNumber: {
type: String,
default: ''
},
totalTargetNumber: {
type: String,
default: ''
},
successTask: {
type: String,
default: ''
},
failTask: {
type: String,
default: ''
},
unusualTask: {
type: String,
default: ''
},
speed: {
type: String,
default: ''
},
errorRate: {
type: String,
default: ''
}
})
const dsnTotalTaskNumber = ref('')
const dsnTaskSuccessNumber = ref('')
const dsnTaskFailNumber = ref('')
const dsnErrorRate = ref('')
const ituTotalTaskNumber = ref('')
const ituTaskSuccessNumber = ref('')
const ituTaskFailNumber = ref('')
const ituErrorRate = ref('')
const stTotalTaskNumber = ref('')
const stTaskSuccessNumber = ref('')
const stTaskFailNumber = ref('')
const stErrorRate = ref('')
const goToDSNTaskRecordPage = () => {
router.push({
......@@ -122,6 +105,25 @@ const goToSTTaskRecordPage = () => {
}
})
}
const getData = async () => {
const res = await getAllSpiderTaskStatistics({})
console.log(res);
dsnTotalTaskNumber.value = res.data.dsn_now.totalCount
dsnTaskSuccessNumber.value = res.data.dsn_now.successCount
dsnTaskFailNumber.value = res.data.dsn_now.failCount
dsnErrorRate.value = res.data.dsn_now.errorRate
ituTotalTaskNumber.value = res.data.itu_space_explorer.totalCount
ituTaskSuccessNumber.value = res.data.itu_space_explorer.successCount
ituTaskFailNumber.value = res.data.itu_space_explorer.failCount
ituErrorRate.value = res.data.itu_space_explorer.errorRate
stTotalTaskNumber.value = res.data.space_track.totalCount
stTaskSuccessNumber.value = res.data.space_track.successCount
stTaskFailNumber.value = res.data.space_track.failCount
stErrorRate.value = res.data.space_track.errorRate
}
onMounted(() => {
getData()
})
</script>
<style lang="scss" scoped>
......
<!-- 任务执行统计卡片组件 -->
<template>
<div>
<div class="text-left p-4 toolbarStyle ">
<div class="formStyle">
<el-form inline>
......@@ -9,7 +10,8 @@
<el-form-item>
<div>
<el-select v-model="searchCondition.spiders" placeholder="请选择" style="width: 220px">
<el-option v-for="item in taskSelectOptions" :key="item.value" :label="item.label" :value="item.value" />
<el-option v-for="item in taskSelectOptions" :key="item.value" :label="item.label"
:value="item.value" />
</el-select>
</div>
</el-form-item>
......@@ -22,59 +24,62 @@
<el-form-item>
<el-space>
<el-button type="primary" @Click="search">查询</el-button>
</el-space>
</el-form-item>
<el-form-item>
<el-space>
<el-button type="primary" @Click="resetData">重置列表</el-button>
<el-button type="primary" @click="openTaskDialog">新建任务</el-button>
</el-space>
</el-form-item>
</el-form>
</div>
</div>
<div class="cardStyle">
<div class="taskCard p-6 " v-for="task in taskList" :key="task.taskId">
<div class="taskCard p-6" v-for="task in taskList" :key="task.taskId">
<div class="taskContent">
<div>
<el-form-item>
<el-form-item class="form-item">
<span class="titleStyle">{{ task.kwargs.options === '' ? '无名称' : JSON.parse(task.kwargs.options).jobName
}}</span>
</el-form-item>
</div>
<div>
<el-form-item>
<el-form-item class="form-item">
<el-button type="primary" @click="editTask(task)" class="editButton">编辑</el-button>
<el-button type="success" @click="goToTaskRecord" class="recordButton">执行记录 </el-button>
<el-button type="danger" @click="deleteTask(task)" class="deleteButton">删除</el-button>
</el-form-item>
</div>
<div class="wordStyle">
<el-form-item>
<el-form-item class="form-item">
<el-space>
<span class="wordStyle">启用/停止: </span>
<el-switch v-model="task.status" :active-value="'running'" :inactive-value="'paused'"
@change="(newStatus: any) => changeStatus(task, newStatus)" />
<span class="wordStyle">执行频率: {{ task.frequency }} </span>
</el-space>
</el-form-item>
</div>
<div class="wordStyle">
<el-form-item>
<el-form-item class="form-item">
<el-space>
<span class="wordStyle">执行次数: 个; </span>
<span class="wordStyle">成功次数: 个</span>
<span class="wordStyle">执行频率: {{ task.frequency }} </span>
<span class="wordStyle">执行次数: {{ task.count }} </span>
</el-space>
</el-form-item>
</div>
<div class="wordStyle ">
<el-form-item>
<div class="wordStyle">
<el-form-item class="form-item">
<el-space>
<span class="wordStyle">失败次数: 个; </span>
<span class="wordStyle">异常记录: 个</span>
<span class="wordStyle">所属爬虫: </span>
<span class="wordStyle">所属爬虫: {{ task.kwargs.spider }}</span>
</el-space>
</el-form-item>
</div>
<!-- <div class="wordStyle">
<el-form-item class="form-item">
<el-space>
<span class="wordStyle">失败次数: </span>
<span class="wordStyle">异常记录: </span>
</el-space>
</el-form-item>
</div> -->
</div>
</div>
</div>
......@@ -83,6 +88,10 @@
:jobId="jobId" :cron="frequency" :spiderType="belongSpiderType" :options="taskOptions" />
<deleteDialog v-model:dialogVisible="showDeleteDialog" @get-user-list="getData" :jobId="jobId" />
</div>
</template>
......@@ -90,10 +99,12 @@
import { ref, onMounted, watch } from 'vue'
import { useRouter } from 'vue-router'
import addTaskDialog from './addTaskDialog.vue'
import { getSpiderTaskList, resumeSpiderTask, pauseSpiderTask } from '@/api/spiderTask'
import { getSpiderTaskList, resumeSpiderTask, pauseSpiderTask, getTaskCount } from '@/api/spiderTask'
import { DeleteMode } from '@/components/Delete/enum.ts'
import { AddMode } from './enum'
import deleteDialog from './deleteDialog.vue'
import { CronExpressionParser } from 'cron-parser';
import { log } from 'echarts/types/src/util/log.js'
const props = defineProps({
spiderType: {
type: String,
......@@ -126,6 +137,7 @@ const searchCondition = ref({
spiders: '',
options: ''
})
const belongSpider = ref('')
const taskName = ref('')
const taskValue = ref('')
const belongSpiderType = ref('')
......@@ -181,13 +193,22 @@ const openTaskDialog = () => {
showTaskDialog.value = true
}
const getData = async () => {
if (props.spiderType !== '') {
const res = await getSpiderTaskList({ spiders: props.spiderType, options: JSON.stringify({ jobName: taskName.value }) })
const res = await getSpiderTaskList({ spiders: searchCondition.value.spiders ? [searchCondition.value.spiders] : [] })
// for (let i = 0; i < res.data.length; i++) {
// const resId = await getTaskCount({id:res.data[i].id})
// res.data[i].count = resId.data.count
// }
const resId = await getTaskCount({})
for(let i = 0; i < res.data.length; i++){
res.data[i].count = resId.data[res.data[i].id] === undefined ? 0 : resId.data[res.data[i].id]
}
taskList.value = res.data
}else{
const res = await getSpiderTaskList({ spiders: searchCondition.value.spiders ? [searchCondition.value.spiders] : [], options: JSON.stringify({ jobName: taskName.value }) })
}
const resetData = async () => {
searchCondition.value.spiders = ''
const res = await getSpiderTaskList({ spiders: [], options: JSON.stringify({ jobName: taskName.value }) })
taskList.value = res.data
}
}
const search = async () => {
const res = await getSpiderTaskList({ spiders: searchCondition.value.spiders ? [searchCondition.value.spiders] : [], options: JSON.stringify({ jobName: taskName.value }) })
......@@ -198,77 +219,94 @@ onMounted(() => {
searchCondition.value.spiders = props.spiderType
}
getData()
const interval = CronExpressionParser.parse('*/2 * * * *');
console.log(interval);
})
// const parseCronExpression=(cronExpression: string)=> {
// try {
// const interval = cronParser.parseExpression(cronExpression);
// const nextDate = interval.next().toDate();
// const hours = nextDate.getHours();
// const minutes = nextDate.getMinutes();
// const seconds = nextDate.getSeconds();
// return {
// hours,
// minutes,
// seconds
// };
// } catch (err) {
// console.error('Error parsing cron expression:', err);
// return null;
// }
// }
</script>
<style lang="scss" scoped>
.taskContent {
display: flex;
flex-direction: column; // 垂直排列
align-items: center; // 水平居中
justify-content: center; // 垂直居中
height: 100%;
gap: -15px;
padding: 10px 0;
}
// .editButton{
// background: none;
// background-image: url("@/assets/picture/button1.png");
// background-size: 100% 100%;
// background-repeat: no-repeat;
// }
// .recordButton{
// background: none;
// background-image: url("@/assets/picture/button2.png");
// background-size: 100% 100%;
// background-repeat: no-repeat;
// }
// .deleteButton{
// background: none;
// background-image: url("@/assets/picture/button3.png");
// background-size: 100% 100%;
// background-repeat: no-repeat;
// }
.cardStyle {
display: flex;
flex-wrap: wrap;
// justify-content:center;
justify-content: space-between;
margin-top: 1.5%;
padding: 18px;
height: 26vh;
gap: 15px;
width: auto !important;
justify-content: space-between;
}
.taskContent {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100%;
gap: 6px;
/* 进一步减小项目之间的间距 */
padding: 5px 0;
}
// 任务卡片样式
/* 任务卡片样式 */
.taskCard {
margin-left: 1%;
background-image: url("@/assets/picture/box2.png");
background-size: 100% 100%;
background-repeat: no-repeat;
margin-bottom: 20px;
margin-bottom: 10px;
width: 380px;
font-size: 20px;
height: 100%;
min-height: 240px;
border-radius: 7px;
display: flex;
flex-direction: column;
.titleStyle {
}
/* 减小表单的间距 */
.form-item {
margin-bottom: 3px !important;
}
.taskCard .titleStyle {
font-size: 22px;
margin-top: -5px;
color: #FFFFFF;
}
}
.wordStyle {
.taskCard .wordStyle {
font-size: 16px;
color: #FFFFFF;
}
}
/* 按钮样式微调 */
.editButton,
.recordButton,
.deleteButton {
margin: 0 3px !important;
}
/* 工具栏样式 */
.toolbarStyle {
background-image: url("@/assets/picture/box3.png");
......
......@@ -2,7 +2,7 @@
<div>
<div class="backStyle" v-if="route.query.jump === 'yes'" @click="goToTaskInformation" />
<div class="m-t-8" />
<div >
<div>
<taskCard :spiderType="spiderType" failTask="10" unusualTask="1" />
<!-- <div class="pagination w-full flex flex-row-reverse pr-18 m-t-0">
<Pagination :total="pageObj.total" v-model:page="pageObj.pageNo" v-model:limit="pageObj.pageSize"
......
......@@ -30,7 +30,7 @@ export default defineConfig({
proxy: {
// 代理API请求,使用更精确的路径匹配
'/api': {
target: 'http://192.168.0.200:5001/',
target: 'http://127.0.0.1:5001/',
changeOrigin: true,
},
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment