Commit 2f3169b1 by yzh

feat:所有代码添加注释

parent 77efbf7d
<!-- 表格搜索组件 -->
<template>
<div class="box">
<div class="left"></div>
......
<!-- 综合数据页面组件 -->
<template>
<div class="text-left p-4 toolbarStyle">
<div class="formStyle">
......@@ -61,6 +62,7 @@
</div>
</div>
<div class="m-t-5" />
<!-- 综合数据表格 -->
<div>
<el-table
:data="tableData"
......
......@@ -5,17 +5,11 @@
}}</el-button>
</div>
<div class="m-t-5" />
<!-- DSN数据表格 -->
<div class="table-content">
<el-table
v-loading="!tableData"
element-loading-background="rgba(48, 65, 86, 0.7)"
:data="tableData"
style="width: 100%"
border
:row-style="{ height: '46px' }"
:header-cell-style="{ textAlign: 'center' }"
:cell-style="{ textAlign: 'center' }"
>
<el-table v-loading="!tableData" element-loading-background="rgba(48, 65, 86, 0.7)" :data="tableData"
style="width: 100%" border :row-style="{ height: '46px' }" :header-cell-style="{ textAlign: 'center' }"
:cell-style="{ textAlign: 'center' }">
<!-- <el-table-column type="selection" width="40" /> -->
<el-table-column property="number" label="序号" width="55" type="index" />
<el-table-column property="name" label="天线名称" show-overflow-tooltip />
......@@ -57,6 +51,7 @@
</el-table>
</div>
<!-- DSN数据详情对话框 -->
<div class="detailForm">
<el-dialog v-model="detailVisibleValue" center width="800px" align-center @close="handleClose" draggable>
<template #header>
......@@ -196,7 +191,7 @@ const dataTime = ref("");
const recordTime = ref("");
// 是否暂停使用
const isSuspended = ref("");
// dsn数据
interface dsnInfo {
targetName: string;
targetNam: string;
......@@ -204,7 +199,9 @@ interface dsnInfo {
const dsnInfoDialog = ref<dsnInfo>();
// 存放定时器的id
const timerId = ref<number | null>();
// 表格数据
const tableData = ref();
// 分页数据
const pageObj = ref({
total: 10,
pageSize: 1,
......@@ -212,6 +209,7 @@ const pageObj = ref({
});
// 查看数据详情的方法
const handleDetails = (row: any) => {
// 将表格中对应行的数据赋值给上面定义的变量
targetName.value = row.targets[0].name;
windSpeed.value = row.windSpeed === "" ? "--" : row.windSpeed;
antennaName.value = row.name;
......@@ -234,6 +232,7 @@ const handleDetails = (row: any) => {
const getData = async () => {
const res = await getDsnList({ page: pageObj.value.pageNo, size: pageObj.value.pageSize });
let dishesData = [];
// 构造表格数据,dsn数据的结构比较特殊,需要遍历两层才能得到每一行的数据
for (let i = 0; i < res.data.list[0].stations.length; i++) {
for (let j = 0; j < res.data.list[0].stations[i].dishes.length; j++) {
dishesData.push(res.data.list[0].stations[i].dishes[j]);
......@@ -243,6 +242,7 @@ const getData = async () => {
tableData.value = dishesData;
console.log(tableData.value);
};
// 关闭详情对话框的方法
const handleClose = () => {
detailVisibleValue.value = false;
};
......@@ -262,6 +262,7 @@ const handleRefresh = () => {
timerId.value = setInterval(async () => {
const res = await getDsnList({ page: pageObj.value.pageNo, size: pageObj.value.pageSize });
let dishesData = [];
// 构造表格数据,dsn数据的结构比较特殊,需要遍历两层才能得到每一行的数据
for (let i = 0; i < res.data.list[0].stations.length; i++) {
for (let j = 0; j < res.data.list[0].stations[i].dishes.length; j++) {
dishesData.push(res.data.list[0].stations[i].dishes[j]);
......
......@@ -13,8 +13,9 @@
<script setup lang="ts">
import { ref } from 'vue'
import dsnDataTab from './dsnDataTab.vue'
import newsDataTab from './newsDataTab.vue'
// import newsDataTab from './newsDataTab.vue'
// 定义模式和选项
const mode = ref('DSN数据')
const sizeOptions = ['DSN数据', '新闻']
......
......@@ -129,6 +129,7 @@ const newsDate = ref('')
const newsGetTime = ref('')
// 新闻内容
const newsContent = ref('')
// 表格数据
const tableData = ref([
{
number: '1',
......@@ -165,11 +166,13 @@ const tableData = ref([
name: '1',
},
])
// 分页数据
const pageObj = ref({
total: 10,
pageSize: 10,
pageNo: 1
})
// 查看详情的方法
const handleDetails = (row: any) => {
console.log(row);
detailVisibleValue.value = true
......
<template>
<div class="text-left">
<!-- 搜索工具栏 -->
<table-search>
<div class="form-content">
<div class="left">
......@@ -14,17 +15,9 @@
<div>
<span style="color: white">采集时间:</span>
<el-config-provider :locale="zhCn">
<el-date-picker
type="datetimerange"
format="YYYY-MM-DD HH:mm:ss"
v-model="searchTimeValue"
start-placeholder="开始时间"
style="width: 400px"
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 type="datetimerange" format="YYYY-MM-DD HH:mm:ss" v-model="searchTimeValue"
start-placeholder="开始时间" style="width: 400px" end-placeholder="结束时间" date-format="YYYY/MM/DD ddd"
time-format="A hh:mm:ss" value-format="YYYY-MM-DD HH:mm:ss" />
</el-config-provider>
</div>
</div>
......@@ -36,18 +29,12 @@
</table-search>
</div>
<!-- ESA数据表格 -->
<div class="m-t-5" />
<div class="table-content">
<el-table
:data="tableData"
style="width: 100%"
border
:row-style="{ height: '45.5px' }"
:header-cell-style="{ textAlign: 'center' }"
:cell-style="{ textAlign: 'center' }"
v-loading="tableLoading"
element-loading-background="rgba(48, 65, 86, 0.7)"
>
<el-table :data="tableData" style="width: 100%" border :row-style="{ height: '45.5px' }"
:header-cell-style="{ textAlign: 'center' }" :cell-style="{ textAlign: 'center' }" v-loading="tableLoading"
element-loading-background="rgba(48, 65, 86, 0.7)">
<el-table-column property="number" label="序号" width="55" type="index" />
<el-table-column property="data.mission" label="目标名称" width="86" show-overflow-tooltip />
<el-table-column property="data.station" label="站点名称" width="88" show-overflow-tooltip />
......@@ -93,23 +80,19 @@
<el-button link type="primary" size="small" @click="handleMissionDetails(scope.row.data.mission)">
目标信息
</el-button>
<el-button link type="primary" size="small" @click="handleStationDetails(scope.row.data.station)"
>站点信息</el-button
>
<el-button link type="primary" size="small"
@click="handleStationDetails(scope.row.data.station)">站点信息</el-button>
</div>
</template>
</el-table-column>
</el-table>
<div class="pagination w-full flex flex-row-reverse pr-4 m-t-4">
<Pagination
:total="pageObj.total"
v-model:page="pageObj.pageNo"
v-model:limit="pageObj.pageSize"
@pagination="getData"
/>
<Pagination :total="pageObj.total" v-model:page="pageObj.pageNo" v-model:limit="pageObj.pageSize"
@pagination="getData" />
</div>
</div>
<!-- ESA目标详情弹窗 -->
<div class="detailForm">
<el-dialog v-model="detailVisibleValue" center width="765px" align-center @close="handleClose" draggable>
<template #header>
......@@ -117,6 +100,7 @@
</template>
<el-row>
<el-col>
<!-- 目标详情的表单 -->
<el-card>
<div class="title">目标信息:</div>
<el-divider style="margin: 0"></el-divider>
......@@ -207,6 +191,7 @@
</el-dialog>
</div>
<!-- ESA站点详情弹窗 -->
<div class="detailForm">
<el-dialog v-model="stationVisibleValue" center width="880px" align-center @close="handleClose" draggable>
<template #header>
......@@ -214,6 +199,7 @@
</template>
<el-row>
<el-col>
<!-- 站点详情的表单 -->
<el-card>
<div class="title">站点信息:</div>
<el-divider style="margin: 0"></el-divider>
......@@ -343,6 +329,7 @@
</el-row>
</el-dialog>
</div>
<!-- 导出组件 -->
<exportDialog v-model:dialogVisible="showDeleteDialog" />
</template>
......@@ -367,6 +354,7 @@ zhCn.el.pagination.pageClassifier = '页'
const searchTargetName = ref('')
const searchTimeValue = ref('')
const searchStation = ref('')
// 删除的ref
const showDeleteDialog = ref(false)
const detailVisibleValue = ref(false)
const stationVisibleValue = ref(false)
......@@ -566,16 +554,21 @@ const handleStationDetails = async (id: any) => {
}
}
// 表格数据
const tableData = ref([])
// 分页对象
const pageObj = ref({
total: 0,
pageSize: 10,
pageNo: 1
})
// 时间戳格式化函数
const formatTimestamp = (timestamp: any) => {
// 判断时间戳是否有效
if (!timestamp || typeof timestamp !== 'number' || timestamp <= 0) {
return '--'
}
// 处理10位和13位时间戳
const msTimestamp = String(timestamp).length === 10 ? timestamp * 1000 : timestamp
const date = new Date(msTimestamp)
if (isNaN(date.getTime())) {
......@@ -613,6 +606,7 @@ const handleMissionDetails = async (id: any) => {
targetIsCoreMission.value = res.data.data[0].coreMission
targetSolarWindSpeed.value = res.data.data[0].solarWindSpeed
targetSolarFluxDensity.value = res.data.data[0].solarFluxDensity
// 遍历后将数据取出来
for (let i = 0; i < res.data.data[0].description.length; i++) {
targetDescription.value += res.data.data[0].description[i]
}
......@@ -631,6 +625,7 @@ const resetForm = () => {
// 获取esa数据列表的方法
const getData = async () => {
tableLoading.value = true
// 请求数据
const res = await getESAList({
spacecraft: searchTargetName.value,
station: searchStation.value,
......@@ -642,10 +637,11 @@ const getData = async () => {
tableData.value = res.data.list
tableLoading.value = false
}
// 关闭弹窗的方法
const handleClose = () => {
detailVisibleValue.value = false
}
// 组件挂载时获取数据
onMounted(() => {
getData()
})
......@@ -655,6 +651,7 @@ onMounted(() => {
:deep(.el-form-item__label) {
color: white;
}
// 调整表单项间距
.detailForm {
.el-dialog-title {
......@@ -723,6 +720,7 @@ onMounted(() => {
padding: 0 30px;
justify-content: space-between;
}
.left {
display: flex;
gap: 10px;
......
<template>
<div>
<!-- 导出记录的弹窗 -->
<el-dialog title="导出记录" v-model="dialogVisible" width="65%">
<div class="table-content">
<el-table
v-loading="tableLoading"
element-loading-background="rgba(48, 65, 86, 0.7)"
:row-style="{ height: '45px' }"
:header-cell-style="{ textAlign: 'center' }"
:cell-style="{ textAlign: 'center' }"
:data="exportRecordList"
border
>
<!-- 导出条件的表单 -->
<el-table v-loading="tableLoading" element-loading-background="rgba(48, 65, 86, 0.7)"
:row-style="{ height: '45px' }" :header-cell-style="{ textAlign: 'center' }"
:cell-style="{ textAlign: 'center' }" :data="exportRecordList" border>
<el-table-column type="index" label="序号" width="60"></el-table-column>
<el-table-column prop="begin_export_time" label="导出开始时间"></el-table-column>
<el-table-column prop="end_export_time" label="导出结束时间"></el-table-column>
......@@ -25,12 +21,8 @@
<el-table-column prop="create_time" label="记录时间"></el-table-column>
</el-table>
<div class="flex justify-end mt-2">
<el-pagination
@current-change="handleCurrentChange"
background
layout="total, prev, pager, next"
:total="pagination.total"
/>
<el-pagination @current-change="handleCurrentChange" background layout="total, prev, pager, next"
:total="pagination.total" />
</div>
</div>
</el-dialog>
......@@ -43,11 +35,13 @@ import { reactive, ref } from "vue";
const dialogVisible = ref(false);
// 打开弹窗的方法,并获取数据
const openDialog = () => {
dialogVisible.value = true;
getData();
};
// 组件暴露的方法
defineExpose({
openDialog,
});
......@@ -82,6 +76,7 @@ const getDataSourceName = (code: number) => {
//记录数据
const exportRecordList = ref<any[]>([]);
// 表格加载状态
const tableLoading = ref(false);
//获取数据
......
<template>
<div class="text-left">
<!-- 搜索工具栏 -->
<TableSearch>
<div class="form-content">
<div class="left">
......@@ -14,17 +15,9 @@
<div>
<span style="color: white">采集时间:</span>
<el-config-provider :locale="zhCn">
<el-date-picker
type="datetimerange"
format="YYYY-MM-DD HH:mm:ss"
v-model="searchTimeValue"
start-placeholder="开始时间"
style="width: 400px"
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 type="datetimerange" format="YYYY-MM-DD HH:mm:ss" v-model="searchTimeValue"
start-placeholder="开始时间" style="width: 400px" end-placeholder="结束时间" date-format="YYYY/MM/DD ddd"
time-format="A hh:mm:ss" value-format="YYYY-MM-DD HH:mm:ss" />
</el-config-provider>
</div>
</div>
......@@ -36,18 +29,12 @@
</TableSearch>
</div>
<!-- ITU数据表格 -->
<div class="m-t-5" />
<div class="itu-table">
<el-table
:data="tableData"
style="width: 100%"
border
:row-style="{ height: '45px' }"
:header-cell-style="{ textAlign: 'center' }"
:cell-style="{ textAlign: 'center' }"
v-loading="tableLoading"
element-loading-background="rgba(48, 65, 86, 0.7)"
>
<el-table :data="tableData" style="width: 100%" border :row-style="{ height: '45px' }"
:header-cell-style="{ textAlign: 'center' }" :cell-style="{ textAlign: 'center' }" v-loading="tableLoading"
element-loading-background="rgba(48, 65, 86, 0.7)">
<!-- <el-table-column type="selection" width="40" /> -->
<el-table-column property="number" label="序号" width="55" type="index" />
<el-table-column property="item.ntc_id" label="SNS Notice ID" show-overflow-tooltip />
......@@ -81,18 +68,8 @@
{{ scope.row.regulatory_status.d_reg_limit === null ? '-' : scope.row.regulatory_status.d_reg_limit }}
</template>
</el-table-column>
<el-table-column
min-width="100"
property="regulatory_status.f_biu_grps"
label="是否确认使用"
show-overflow-tooltip
/>
<el-table-column
property="regulatory_status.resumption_list"
width="140"
label="是否暂停使用"
show-overflow-tooltip
/>
<el-table-column min-width="100" property="regulatory_status.f_biu_grps" label="是否确认使用" show-overflow-tooltip />
<el-table-column property="regulatory_status.resumption_list" width="140" label="是否暂停使用" show-overflow-tooltip />
<el-table-column width="180" property="crawl_time" label="采集时间" show-overflow-tooltip />
<el-table-column label="操作" width="60">
<template #default="scope">
......@@ -101,15 +78,12 @@
</el-table-column>
</el-table>
<div class="pagination w-full flex flex-row-reverse pr-4 m-t-4">
<Pagination
:total="pageObj.total"
v-model:page="pageObj.pageNo"
v-model:limit="pageObj.pageSize"
@pagination="getData"
/>
<Pagination :total="pageObj.total" v-model:page="pageObj.pageNo" v-model:limit="pageObj.pageSize"
@pagination="getData" />
</div>
</div>
<!-- ITU数据详情的弹窗 -->
<div class="detailForm">
<el-dialog v-model="detailVisibleValue" center width="765px" align-center @close="handleClose" draggable>
<template #header>
......@@ -117,6 +91,7 @@
</template>
<el-row>
<el-col :span="12">
<!-- 身份信息 -->
<el-card>
<div class="title">身份信息:</div>
<el-divider style="margin: 0"></el-divider>
......@@ -141,6 +116,7 @@
<span class="item">{{ ntwkType }}</span>
</div>
</el-card>
<!-- 监管状态跟踪 -->
<el-card>
<div class="title">监管状态跟踪:</div>
<el-divider style="margin: 0"></el-divider>
......@@ -171,6 +147,7 @@
</el-card>
</el-col>
<el-col :span="12">
<!-- 特征信息 -->
<el-card>
<div class="title">特征信息:</div>
<el-divider style="margin: 0"></el-divider>
......@@ -195,6 +172,7 @@
<span class="item">{{ lowestAltitude }}</span>
</div>
</el-card>
<!-- 其他信息 -->
<el-card>
<div class="title">其他信息:</div>
<el-divider style="margin: 0"></el-divider>
......@@ -243,10 +221,13 @@ zhCn.el.pagination.total = '共 `{total} 条`'
zhCn.el.pagination.goto = '跳至'
zhCn.el.pagination.pagesize = '条/页'
zhCn.el.pagination.pageClassifier = '页'
// 查询参数
const searchTargetName = ref('')
const searchTimeValue = ref('')
const searchTargetId = ref('')
// 删除对话框的显示状态
const showDeleteDialog = ref(false)
// 详情对话框的显示状态
const detailVisibleValue = ref(false)
// SNS Notice ID
const snsId = ref('')
......@@ -302,7 +283,9 @@ const isRestoreUsed = ref('')
const validityPeriodSatelliteNetworkOldName = ref('')
// 最新相关 BR IFIC 发布日期
const BFIFICdate = ref('')
// 表格数据
const tableData = ref([])
// 分页参数
const pageObj = ref({
total: 0,
pageSize: 10,
......@@ -310,6 +293,7 @@ const pageObj = ref({
})
// 查看数据详情的方法
const handleDetails = async (id: any) => {
// 获取数据并赋值
const res = await getItuDetail({ id: id._id })
snsId.value = res.data.item.ntc_id
department.value = res.data.item.adm
......@@ -347,14 +331,18 @@ const tableLoading = ref(false)
// 获取itu数据列表的方法
//重置搜索条件
const resetForm = () => {
// 清空
searchTargetName.value = ''
searchTargetId.value = ''
searchTimeValue.value = ''
pageObj.value.pageNo = 1
// 重新获取数据
getData()
}
// 获取itu数据列表的方法
const getData = async () => {
tableLoading.value = true
// 发送请求获取数据并赋值
const res = await await getItuList({
sat_name: searchTargetName.value,
ntc_id: searchTargetId.value,
......@@ -366,10 +354,11 @@ const getData = async () => {
tableData.value = res.data.list
tableLoading.value = false
}
// 关闭详情弹窗的方法
const handleClose = () => {
detailVisibleValue.value = false
}
// 组件挂载时获取数据
onMounted(() => {
getData()
})
......@@ -379,6 +368,7 @@ onMounted(() => {
:deep(.el-form-item__label) {
color: white;
}
// 调整表单项间距
.detailForm {
.el-dialog-title {
......@@ -429,6 +419,7 @@ onMounted(() => {
display: flex;
gap: 10px;
}
.info-item {
display: flex;
align-items: center;
......@@ -443,6 +434,7 @@ onMounted(() => {
.item {
color: #eee;
}
.form-content {
display: flex;
height: 80px;
......
<template>
<div class="text-left">
<!-- 搜索工具栏 -->
<table-search>
<div class="form-content">
<div class="left">
......@@ -36,6 +37,7 @@
</table-search>
</div>
<!-- ST数据表格 -->
<div class="m-t-5" />
<div class="table-content">
<el-table
......@@ -80,6 +82,7 @@
</div>
</div>
<!-- ITU目标详情弹窗 -->
<div class="detailForm">
<el-dialog v-model="detailVisibleValue" center width="765px" align-center @close="handleClose" draggable>
<template #header>
......@@ -87,6 +90,7 @@
</template>
<el-row>
<el-col>
<!-- 目标信息 -->
<el-card>
<div class="title">目标信息:</div>
<el-divider style="margin: 0"></el-divider>
......@@ -169,6 +173,7 @@
</div>
</el-col>
</el-row>
<!-- TLE数据 -->
<div class="title">TLE数据:</div>
<el-divider style="margin: 0"></el-divider>
<el-row>
......@@ -210,6 +215,7 @@
</el-row>
</el-dialog>
</div>
<!-- 数据导出弹窗 -->
<exportDialog v-model:dialogVisible="showDeleteDialog" />
</template>
......@@ -230,15 +236,21 @@ zhCn.el.pagination.total = '共 `{total} 条`'
zhCn.el.pagination.goto = '跳至'
zhCn.el.pagination.pagesize = '条/页'
zhCn.el.pagination.pageClassifier = '页'
// 查询参数
const searchTargetName = ref('')
// 搜索条件
const noradCatId = ref('')
// 删除弹窗显示状态
const showDeleteDialog = ref(false)
// 时间参数
const timeValue = ref('')
// 详情弹窗显示状态
const detailVisibleValue = ref(false)
// NoradCatID
const NoradCatID = ref('')
// 目标名称
const targetName = ref('')
// 目标类型
const objectType = ref('')
// INTLDES
const intleds = ref('')
......@@ -278,11 +290,14 @@ const meanAnomaly = ref('')
const rcsSize = ref('')
//LAUNCH_DATE
const launchDate = ref('')
// 国家代码
const countryCode = ref('')
// 轨道速度微调器
const meanMotionDot = ref('')
// 轨道加速度变化率
const meanMotionDdot = ref('')
// 轨道圈数计数器
const revAtEpoch = ref('')
//半长轴SEMIMAJOR_AXIS
const semimajorAxis = ref('')
//第一行数据 TLE_LINE0
......@@ -291,8 +306,9 @@ const tleLine0 = ref('')
const tleLine1 = ref('')
//第三行数据 TLE_LINE0
const tleLine2 = ref('')
// 表格数据
const tableData = ref([])
// 分页数据
const pageObj = ref({
total: 10,
pageSize: 10,
......@@ -300,9 +316,9 @@ const pageObj = ref({
})
// 查看数据详情的方法
const handleDetails = async (row: any) => {
// 发送请求获取数据
const res = await getStDetail({ id: row._id })
console.log(res)
// 将数据赋值给对应的变量
NoradCatID.value = res.data.NORAD_CAT_ID
rcsSize.value = res.data.RCS_SIZE
launchDate.value = res.data.LAUNCH_DATE
......@@ -327,6 +343,7 @@ const handleDetails = async (row: any) => {
apogee.value = res.data.APOAPSIS
rcs.value = res.data.RCS_SIZE
site.value = res.data.SITE
// 将TLE数据拼接成一行显示
tle.value = `${res.data.TLE_LINE0}
${res.data.TLE_LINE1}
${res.data.TLE_LINE2}`
......@@ -341,15 +358,18 @@ ${res.data.TLE_LINE2}`
const tableLoading = ref(false)
//重置搜索条件
const resetForm = () => {
// 清空
noradCatId.value = ''
searchTargetName.value = ''
timeValue.value = ''
pageObj.value.pageNo = 1
// 重新获取数据
getData()
}
// 获取st数据列表的方法
const getData = async () => {
tableLoading.value = true
// 发送请求获取数据并赋值
const res = await getStList({
norad_cat_id: noradCatId.value,
object_name: searchTargetName.value,
......@@ -361,10 +381,11 @@ const getData = async () => {
tableData.value = res.data.list
tableLoading.value = false
}
// 关闭详情弹窗的方法
const handleClose = () => {
detailVisibleValue.value = false
}
// 组件挂载时获取数据
onMounted(() => {
getData()
})
......
<template>
<div>
<!-- 页面标题 -->
<MenuTitle title="数据展示" subtitle="Data Display" />
<div class="backStyle" v-if="route.query.jump === 'yes'" @click="goToStatus" />
<!-- 导出按钮 -->
<div class="segment-content">
<div class="custom-style flex justify-between">
<div class="flex gap-4">
......@@ -22,7 +24,9 @@
<stDataTab v-if="mode === 'ST数据'"></stDataTab>
<!-- ESA数据页面组件 -->
<esDataTab v-if="mode === 'ESA数据'"></esDataTab>
<!-- 导出弹窗组件 -->
<exportDialog v-model:dialogVisible="showDeleteDialog" @confirm="handleExportConfirm" />
<!-- 导出记录弹窗组件 -->
<exportRecord ref="expRec" />
</div>
</template>
......@@ -40,33 +44,39 @@ import MenuTitle from '@/components/MenuTitle.vue'
import exportRecord from './components/exportRecord.vue'
import { ElNotification } from 'element-plus'
// 数据展示模式
const mode = ref(sessionStorage.getItem('dataDisplayMode') || 'DSN数据')
// 删除弹窗显示状态
const showDeleteDialog = ref(false)
// 数据源选择器选项配置
const sizeOptions = ['DSN数据', 'ITU数据', 'ST数据', 'ESA数据']
// 路由对象
const route = useRoute()
const router = useRouter()
// 路由参数中的mode值,用于设置初始数据展示模式
const modeValue = ref<any>('数据展示')
//导出记录组件引用
const expRec = ref<any>(null)
// 跳转到状态页面
const goToStatus = () => {
router.push({
path: '/osStatus/list'
})
}
// 打开导出弹窗的方法
const handleExport = () => {
showDeleteDialog.value = true
}
// 消息通知
const noticeImpl = ref()
const handleExportConfirm = () => {}
// 组件挂载时显示消息通知
onMounted(() => {
if (route.query.mode) {
modeValue.value = route.query.mode
mode.value = modeValue.value
}
// 显示消息通知
noticeImpl.value = ElNotification({
title: '温馨提示',
message: h('i', { style: 'color: teal' }, '爬虫数据可导出至本地,请点击【导出】按钮执行数据导出'),
......@@ -79,6 +89,7 @@ const handleExportRecord = () => {
expRec.value.openDialog()
}
// 监听mode变化,更新sessionStorage中的数据展示模式
watch(
mode,
(newVal) => {
......@@ -89,7 +100,7 @@ watch(
immediate: true
}
)
// 组件卸载时关闭消息通知
onUnmounted(() => {
if (noticeImpl.value) {
noticeImpl.value.close()
......
<template>
<div>
<!-- 页面标题 -->
<MenuTitle title="爬虫管理" subtitle="Spider Manager" />
<!-- 爬虫管理数据表格 -->
<div class="table-content">
<el-table
:data="tableData"
style="width: 100%"
border
:header-cell-style="{ textAlign: 'center' }"
:cell-style="{ textAlign: 'center' }"
:row-style="{ height: '60px' }"
v-loading="tableData.length == 0"
element-loading-background="rgba(48, 65, 86, 0.7)"
>
<el-table :data="tableData" style="width: 100%" border :header-cell-style="{ textAlign: 'center' }"
:cell-style="{ textAlign: 'center' }" :row-style="{ height: '60px' }" v-loading="tableData.length == 0"
element-loading-background="rgba(48, 65, 86, 0.7)">
<!-- 表头配置 -->
<el-table-column property="number" label="序号" type="index" width="80" />
<el-table-column property="spider" label="爬虫代号" show-overflow-tooltip />
<el-table-column property="spider_name" label="爬虫名称" show-overflow-tooltip />
......@@ -26,39 +22,20 @@
</el-table-column>
</el-table>
<div class="pagination w-full flex flex-row-reverse pr-4 m-t-4">
<Pagination
:total="pageObj.total"
v-model:page="pageObj.pageNo"
v-model:limit="pageObj.pageSize"
@pagination="getData"
/>
<Pagination :total="pageObj.total" v-model:page="pageObj.pageNo" v-model:limit="pageObj.pageSize"
@pagination="getData" />
</div>
</div>
<el-dialog
style="z-index: 999999"
draggable
v-model="editDialogVisible"
title="指定下载以下卫星"
width="550"
@close="handleDialogClose"
>
<!-- ST详情对话框 -->
<el-dialog style="z-index: 999999" draggable v-model="editDialogVisible" title="指定下载以下卫星" width="550"
@close="handleDialogClose">
<div class="No-Content" ref="noContentRef">
<TransitionGroup
enter-active-class="animate__animated animate__slideInRight"
leave-active-class="animate__animated animate__slideOutRight"
enter-from-class="animate__opacity-0"
leave-to-class="animate__opacity-0"
>
<NoItem
v-for="(no, index) in sateNoList"
:key="index"
class="no-item-row"
:-no="no.norad_cat_id"
@add-no="handleSateAdd"
@del-no="handleSateDel"
:reset-selected="resetSelected"
></NoItem>
<TransitionGroup enter-active-class="animate__animated animate__slideInRight"
leave-active-class="animate__animated animate__slideOutRight" enter-from-class="animate__opacity-0"
leave-to-class="animate__opacity-0">
<NoItem v-for="(no, index) in sateNoList" :key="index" class="no-item-row" :-no="no.norad_cat_id"
@add-no="handleSateAdd" @del-no="handleSateDel" :reset-selected="resetSelected"></NoItem>
</TransitionGroup>
</div>
<div class="footer">
......@@ -74,16 +51,12 @@
</template>
<template #actions="{ confirm, cancel }">
<el-button size="small" @click="cancel">取消</el-button>
<el-button
type="danger"
size="small"
@click="
<el-button type="danger" size="small" @click="
(e: MouseEvent) => {
confirm(e)
delNoList()
}
"
>
">
确定
</el-button>
</template>
......@@ -103,14 +76,19 @@ import NoItem from './components/NoItem.vue'
import { ElMessage, type UploadProps, type UploadRawFile } from 'element-plus'
import MenuTitle from '@/components/MenuTitle.vue'
// 路由对象
const router = useRouter()
// 表格数据
const tableData = ref([])
// 分页参数
const pageObj = ref({
total: 10,
pageSize: 10,
pageNo: 1
})
// 跳转到任务详情页面
const handleDetails = (row: any) => {
// 路由跳转并传递参数进行筛选
router.push({
path: '/osTaskInformation/list',
query: {
......@@ -125,7 +103,7 @@ const getData = async () => {
const res = await getSpiderList({ scrapydServerId: '1', project: 'spiders' })
tableData.value = res.data
}
// 详情对话框显示状态
const editDialogVisible = ref(false)
//编号item类型定义
......@@ -134,15 +112,15 @@ interface noradItem {
norad_cat_id: string
create_time: string
}
// 当前输入的编号
const sateNoList = ref<noradItem[]>([])
// 当前选中的编号列表
const curSateNo = ref('')
// 当前选中的编号列表
const curSelSateNo = ref<string[]>([])
// 重置选中状态的标志
const resetSelected = ref(false)
// 关闭对话框时的处理函数
const handleDialogClose = () => {
// 清空已选中的编号
curSelSateNo.value = []
......@@ -180,6 +158,7 @@ const addNoToList = async () => {
//编号文件导入后发送到后端
const fileImptAddNoList = async () => {
try {
// 调用添加接口,传递读取的编号列表
const res = await addSateNoList({ norad_id: textFileNumbers.value })
if (res.code === 0) {
ElMessage.success('导入编号成功')
......@@ -193,6 +172,7 @@ const fileImptAddNoList = async () => {
//删除选中编号
const delNoList = async () => {
try {
// 调用删除接口,传递选中的编号列表
const res = await deleteSateNoList({ norad_id: curSelSateNo.value })
if (res.code === 0) {
ElMessage.success('删除编号成功')
......@@ -207,7 +187,6 @@ const delNoList = async () => {
ElMessage.error(error.message)
}
}
const noContentRef = ref<HTMLDivElement | null>(null)
//新添加滚动到底部
......@@ -228,12 +207,12 @@ const checkNoLeSix = (no: number | string): boolean => {
}
return true
}
// 添加编号后滚动到底部
const handleNumInput = (value: string) => {
const filtered = value.replace(/\D/g, '')
curSateNo.value = filtered.slice(0, 6)
}
// 打开编辑对话框的方法
const handleEditSateId = async () => {
editDialogVisible.value = true
getSateNoList()
......@@ -257,7 +236,7 @@ const textFileNumbers = ref<string[]>([])
//监听导入文件的数组变化
watch(textFileNumbers, (newVal) => {
if (newVal.length > 0) {
newVal.forEach((num) => {})
newVal.forEach((num) => { })
fileImptAddNoList()
}
})
......@@ -337,7 +316,7 @@ const parseTextToNumbers = (text: string): number[] => {
return numbers
}
// 组件挂载时获取数据
onMounted(() => {
getData()
})
......@@ -347,6 +326,7 @@ onMounted(() => {
:deep(.el-input__inner) {
color: black;
}
/* 去除按钮边框 */
.el-button:focus {
outline: none;
......@@ -379,6 +359,7 @@ onMounted(() => {
text-align: left;
margin-left: 20px;
}
.divider {
margin-top: 15px;
}
......@@ -443,6 +424,7 @@ onMounted(() => {
white-space: nowrap;
justify-content: center;
}
.btn-group .el-button {
flex-shrink: 0;
}
......
<!-- 数据卡片组件 -->
<template>
<div class="flex">
<span class="textStyle" :class="{ toRight0: slideState }">数据统计</span>
......@@ -9,6 +10,7 @@
<div class="wordStyle">
<span>总数据量(条):</span>
<span class="total-num" v-if="totalDataNumber !== null">{{
// 格式化大数字,保留两位小数,并添加单位
formatExactLargeNum(totalDataNumber) ?? '--'
}}</span>
<span class="loading" v-else></span>
......@@ -16,15 +18,15 @@
<div class="wordStyle">
<span>采集的页面数量(个):</span>
<span class="total-num" v-if="totalPageNumber !== null">
{{ formatExactLargeNum(totalPageNumber) ?? '--' }}</span
>
<!-- 格式化数据并兜底 -->
{{ formatExactLargeNum(totalPageNumber) ?? '--' }}</span>
<span class="loading" v-else></span>
</div>
<div class="wordStyle">
<span>采集的目标数量(个):</span>
<span class="total-num" v-if="totalTargetNumber !== null">
{{ formatExactLargeNum(totalTargetNumber) ?? '--' }}</span
>
<!-- 格式化数据并兜底 -->
{{ formatExactLargeNum(totalTargetNumber) ?? '--' }}</span>
<span class="loading" v-else></span>
</div>
</div>
......@@ -36,11 +38,13 @@
<div class="items">
<div class="wordStyle">
<span>任务执行成功统计(个):</span>
<!-- 格式化数据并兜底 -->
<span class="total-num" v-if="successTask !== null">{{ formatExactLargeNum(successTask) ?? '--' }}</span>
<span class="loading" v-else></span>
</div>
<div class="wordStyle">
<span>任务执行失败统计(个):</span>
<!-- 格式化数据并兜底 -->
<span class="total-num" v-if="failTask !== null">{{ formatExactLargeNum(failTask) ?? '--' }}</span>
<span class="loading" v-else></span>
</div>
......@@ -54,12 +58,13 @@
<div class="wordStyle">
<span>平均成功率:</span>
<span class="total-num" v-if="speed !== null">
{{ `${Number(Math.floor(speed * 100) / 100).toFixed(2)}%` }}</span
>
<!-- 格式化数据 -->
{{ `${Number(Math.floor(speed * 100) / 100).toFixed(2)}%` }}</span>
<span class="loading" v-else></span>
</div>
<div class="wordStyle">
<span>平均错误率: </span>
<!-- 格式化数据 -->
<span class="total-num" v-if="errorRate !== null">{{
`${Number(Math.ceil(errorRate * 100) / 100).toFixed(2)}%`
}}</span>
......@@ -78,20 +83,31 @@ import formatExactLargeNum from '@/utils/formatExactLargeNum'
import { useSlideStateStore } from '@/store/slideState'
import { storeToRefs } from 'pinia'
// 格式化大数字的工具函数
const slideStateStore = useSlideStateStore()
// 从store中获取侧边栏状态
const { slideState } = storeToRefs(slideStateStore)
// 路由对象
const router = useRouter()
// 数据统计相关的响应式变量
const totalDataNumber = ref(null)
// 采集的页面数量
const totalPageNumber = ref(null)
// 采集的目标数量
const totalTargetNumber = ref(null)
// 任务执行成功统计
const successTask = ref(null)
// 任务执行失败统计
const failTask = ref(null)
// 性能统计相关的响应式变量
const unusualTask = ref(null)
// 平均成功率
const speed = ref(null)
// 错误率
const errorRate = ref(null)
// 异常率
const unusualRate = ref(null)
// 跳转到DSN数据页面的方法
const goToAllDataPage = () => {
router.push({
path: '/osDataDisplay/list',
......@@ -101,7 +117,7 @@ const goToAllDataPage = () => {
}
})
}
// 跳转到任务记录页面的方法
const goToTaskRecordPage = () => {
router.push({
path: '/osTaskRecord/list',
......@@ -114,6 +130,7 @@ const goToTaskRecordPage = () => {
// 获取数据统计数据的方法
const getData = async () => {
// 调用接口获取数据统计数据
const staticData = await getStatsDataList({})
const spiderTask = await getSpiderTaskList({})
const performance = await getPerformanceList({})
......@@ -125,13 +142,12 @@ const getData = async () => {
unusualTask.value = spiderTask.data.exceptionCount
speed.value = performance.data.success
errorRate.value = performance.data.error
console.log(errorRate.value)
unusualRate.value = performance.data.exception
}
//sidebarStatus
// 组件挂载时获取数据
onMounted(() => {
getData()
})
......@@ -193,9 +209,11 @@ onMounted(() => {
0% {
opacity: 0;
}
50% {
opacity: 0.5;
}
100% {
opacity: 1;
}
......@@ -224,6 +242,7 @@ onMounted(() => {
background-size: calc(100% / 3) 50%;
animation: l3 1s infinite linear;
}
@keyframes l3 {
20% {
background-position:
......@@ -231,18 +250,21 @@ onMounted(() => {
50% 50%,
100% 50%;
}
40% {
background-position:
0% 100%,
50% 0%,
100% 50%;
}
60% {
background-position:
0% 50%,
50% 100%,
100% 0%;
}
80% {
background-position:
0% 50%,
......
<!-- 错误日志统计表格组件 -->
<template>
<div class="dataCard">
<div class="titleStyle">错误日志统计</div>
<div class="chart-container" ref="chartRef"></div>
<!-- 错误详情弹窗 -->
<el-dialog draggable v-model="DialogVisible" :title="`错误详情丨${curDate}`" @close="tableData = []">
<div class="table-content">
<!-- 错误详情表格 -->
<el-table :data="curTableData" border style="width: 100%">
<el-table-column width="55" label="序号" type="index" />
<el-table-column width="150" property="spider" label="爬虫名称" />
......@@ -15,13 +18,8 @@
<el-table-column width="160" property="timestamp" label="记录时间" />
</el-table>
<div class="pagination w-full flex flex-row-reverse pr-4 m-t-4">
<Pagination
:total="pageObj.total"
v-model:page="pageObj.pageNo"
v-model:limit="pageObj.pageSize"
@pagination="getData"
v-model:pagerCount="pageObj.pagerCount"
/>
<Pagination :total="pageObj.total" v-model:page="pageObj.pageNo" v-model:limit="pageObj.pageSize"
@pagination="getData" v-model:pagerCount="pageObj.pagerCount" />
</div>
</div>
</el-dialog>
......@@ -39,7 +37,7 @@ const chartRef = useTemplateRef<HTMLElement | null>("chartRef");
//详情弹窗状态
const DialogVisible = ref(false);
// 分页参数
const pageObj = ref({
total: 0,
pageNo: 1,
......@@ -49,7 +47,7 @@ const pageObj = ref({
//弹窗表格数据
const tableData = ref<any[]>([]);
// 当前页表格数据
const curTableData = ref<any[]>([]);
//数据项定义
......@@ -130,12 +128,14 @@ const setChartData = async () => {
type: "shadow",
},
},
// 调整图表边距,确保内容不被遮挡
grid: {
left: "3%",
right: "4%",
bottom: "3%",
containLabel: true,
},
// x轴配置
xAxis: [
{
type: "category",
......@@ -155,6 +155,7 @@ const setChartData = async () => {
},
},
],
// y轴配置
yAxis: [
{
type: "value",
......@@ -171,6 +172,7 @@ const setChartData = async () => {
},
},
],
// 数据系列配置
series: [
{
name: "日志数量",
......@@ -191,6 +193,7 @@ const setChartData = async () => {
const handleClickChart = (params: any) => {
DialogVisible.value = true;
curDate.value = params.name;
// 根据点击的日期筛选出对应的日志数据,展示在弹窗表格中
rawLogList.value.forEach((item) => {
if (item.timestamp.split(" ")[0] === params.name) {
tableData.value.push(item);
......
......@@ -32,11 +32,13 @@
import { useRouter } from "vue-router";
import { storeToRefs } from "pinia";
import { useSlideStateStore } from "@/store/slideState";
// 引入数据格式化工具函数s
const slideStateStore = useSlideStateStore();
// 从store中获取侧边栏状态
const { slideState } = storeToRefs(slideStateStore);
// 获取路由对象
const router = useRouter();
// 跳转到综合数据页面
defineProps({
totalDataNumber: {
type: String,
......@@ -71,7 +73,7 @@ defineProps({
default: "",
},
});
// 跳转到综合数据页面
const goToAllDataPage = () => {
router.push({
path: "/osDataDisplay/list",
......@@ -81,6 +83,7 @@ const goToAllDataPage = () => {
},
});
};
// 跳转到DSN数据页面
const goToDSNDataPage = () => {
router.push({
path: "/osDataDisplay/list",
......@@ -90,6 +93,7 @@ const goToDSNDataPage = () => {
},
});
};
// 跳转到ITU数据页面
const goToITUDataPage = () => {
router.push({
path: "/osDataDisplay/list",
......@@ -99,6 +103,7 @@ const goToITUDataPage = () => {
},
});
};
// 跳转到ST数据页面
const goToSTDataPage = () => {
router.push({
path: "/osDataDisplay/list",
......@@ -108,6 +113,7 @@ const goToSTDataPage = () => {
},
});
};
// 跳转到ESA数据页面
const goToESADataPage = () => {
router.push({
path: "/osDataDisplay/list",
......
<template>
<div class="monitor-container">
<div class="card-container">
......@@ -30,6 +31,7 @@ import qbCard from "@/views/os-status/components/qbDataMonitor.vue";
import errorMessageChart from "./errorMessageChart.vue";
import { onMounted } from "vue";
//prop组件
defineProps({
title: {
type: String,
......
<!-- 任务统计卡片 -->
<template>
<div class="flex">
<span class="textStyle" :class="{ toRight0: slideState }">任务统计</span>
<!-- DSN任务数据统计 -->
<div class="dataCard" @click="goToDSNTaskRecordPage">
<div class="titleStyle">
<span>DSN爬取任务</span>
......@@ -36,6 +38,7 @@
</div>
</div>
</div>
<!-- ITU任务数据统计 -->
<div class="dataCard" @click="goToITUTaskRecordPage">
<div class="titleStyle">
<span>ITU爬取任务</span>
......@@ -71,6 +74,7 @@
</div>
</div>
</div>
<!-- ST任务数据统计 -->
<div class="dataCard" @click="goToSTTaskRecordPage">
<div class="titleStyle">
<span>ST爬取任务</span>
......@@ -106,6 +110,7 @@
</div>
</div>
</div>
<!-- ESA任务数据统计 -->
<div class="dataCard" @click="goToESATaskRecordPage">
<div class="titleStyle">
<span>ESA爬取任务</span>
......@@ -149,28 +154,46 @@ import { useSlideStateStore } from '@/store/slideState'
import { storeToRefs } from 'pinia'
import formatExactLargeNum from '@/utils/formatExactLargeNum'
// 获取侧边栏状态
const slideStateStore = useSlideStateStore()
// 从store中获取侧边栏状态
const { slideState } = storeToRefs(slideStateStore)
// 路由对象
const router = useRouter()
// dsn任务统计数据
const dsnTotalTaskNumber = ref(null)
// dsn任务成功数
const dsnTaskSuccessNumber = ref(null)
// dsn任务失败数
const dsnTaskFailNumber = ref(null)
// dsn任务错误率
const dsnErrorRate = ref(null)
// itu任务统计数据
const ituTotalTaskNumber = ref(null)
// itu任务成功数
const ituTaskSuccessNumber = ref(null)
// itu任务失败数
const ituTaskFailNumber = ref(null)
// itu任务错误率
const ituErrorRate = ref(null)
// st任务统计数据
const stTotalTaskNumber = ref(null)
// st任务成功数
const stTaskSuccessNumber = ref(null)
// st任务失败数
const stTaskFailNumber = ref(null)
// st任务错误率
const stErrorRate = ref(null)
// esa任务统计数据
const esaTotalCount = ref(null)
// esa任务成功数
const esaSuccessCount = ref(null)
// esa任务失败数
const esaErrorRate = ref(null)
// esa任务错误率
const esaFailCount = ref(null)
// 跳转到DSN任务记录页面
const goToDSNTaskRecordPage = () => {
router.push({
path: '/osTaskInformation/list',
......@@ -181,6 +204,7 @@ const goToDSNTaskRecordPage = () => {
}
})
}
// 跳转到ITU任务记录页面
const goToITUTaskRecordPage = () => {
router.push({
path: '/osTaskInformation/list',
......@@ -191,6 +215,7 @@ const goToITUTaskRecordPage = () => {
}
})
}
// 跳转到ST任务记录页面
const goToSTTaskRecordPage = () => {
router.push({
path: '/osTaskInformation/list',
......@@ -201,7 +226,7 @@ const goToSTTaskRecordPage = () => {
}
})
}
// 跳转到ESA任务记录页面
const goToESATaskRecordPage = () => {
router.push({
path: '/osTaskInformation/list',
......@@ -225,7 +250,7 @@ const getData = async () => {
const [ituTask, dsnTask, esaTask, stTask] = await Promise.all(tasks)
const allTask = await getAllTaskStatistics()
// 解析接口返回的数据,更新响应式变量
dsnTotalTaskNumber.value = dsnTask.data.length
dsnTaskSuccessNumber.value = res.data.dsn_now.successCount
dsnTaskFailNumber.value = res.data.dsn_now.failCount
......
......@@ -13,6 +13,7 @@
<script lang="ts" setup>
import taskMonitoringCard from './taskCard.vue'
// 组件的props定义
defineProps({
title: {
type: String,
......
<template>
<div>
<!-- 页面标题 -->
<MenuTitle title="状态监控" subtitle="Status Monitor" />
<div>
<div class="text-left timeStyle" />
<div class="border-100">
<!-- 状态监控组件 -->
<statusMonitor />
</div>
</div>
......
<template>
<div class="sys-content">
<!-- 页面标题组件 -->
<MenuTitle title="系统管理" subtitle="System Manager" />
<!-- 工具栏 -->
<el-card>
<div class="btns">
<el-button
test-element="userSystem-AddUser"
type="primary"
v-if="uRole === UserRole.ADMIN"
plain
@click="openAddUserDialog"
>创建用户</el-button
>
<el-button type="danger" plain @click="handleBatchDelete" class="" v-if="uRole === UserRole.ADMIN"
>批量删除</el-button
>
<el-button test-element="userSystem-AddUser" type="primary" v-if="uRole === UserRole.ADMIN" plain
@click="openAddUserDialog">创建用户</el-button>
<el-button type="danger" plain @click="handleBatchDelete" class=""
v-if="uRole === UserRole.ADMIN">批量删除</el-button>
</div>
</el-card>
<!-- 用户数据表格 -->
<div class="table-content">
<el-table
:data="tableData"
border
:header-cell-style="{ textAlign: 'center' }"
:cell-style="{ textAlign: 'center' }"
:row-style="{ height: '58px' }"
@selection-change="handleSelectionChange"
v-loading="tableLoading"
element-loading-background="rgba(48, 65, 86, 0.7)"
>
<el-table-column
type="selection"
width="40"
:selectable="() => uRole === UserRole.ADMIN"
v-if="uRole === UserRole.ADMIN"
/>
<el-table :data="tableData" border :header-cell-style="{ textAlign: 'center' }"
:cell-style="{ textAlign: 'center' }" :row-style="{ height: '58px' }" @selection-change="handleSelectionChange"
v-loading="tableLoading" element-loading-background="rgba(48, 65, 86, 0.7)">
<el-table-column type="selection" width="40" :selectable="() => uRole === UserRole.ADMIN"
v-if="uRole === UserRole.ADMIN" />
<el-table-column property="number" label="序号" width="55" type="index" />
<el-table-column property="username" label="用户账号" show-overflow-tooltip />
<el-table-column property="nickname" label="用户名称" show-overflow-tooltip />
......@@ -49,14 +34,8 @@
<el-table-column property="create_time" label="创建时间" width="280" show-overflow-tooltip />
<el-table-column label="操作" width="220">
<template #default="scope">
<el-button
link
type="primary"
plain
@click="handleEdit(scope.row)"
id="editUser"
v-if="uRole === UserRole.ADMIN"
>
<el-button link type="primary" plain @click="handleEdit(scope.row)" id="editUser"
v-if="uRole === UserRole.ADMIN">
编辑
</el-button>
<el-button link type="danger" plain @click="handleDelete(scope.row)" v-if="uRole === UserRole.ADMIN">
......@@ -67,35 +46,18 @@
</el-table-column>
</el-table>
<div class="pagination w-full flex flex-row-reverse pr-4 m-t-4">
<Pagination
:total="pageObj.total"
v-model:page="pageObj.pageNo"
v-model:limit="pageObj.pageSize"
@pagination="getUserListData"
/>
<Pagination :total="pageObj.total" v-model:page="pageObj.pageNo" v-model:limit="pageObj.pageSize"
@pagination="getUserListData" />
</div>
</div>
<!-- 删除弹窗组件 -->
<deleteDialog
v-model:dialogVisible="showDeleteDialog"
@get-user-list="getUserListData"
:ids="userIds"
:deleteMode="deleteMode"
:id="userId"
/>
<deleteDialog v-model:dialogVisible="showDeleteDialog" @get-user-list="getUserListData" :ids="userIds"
:deleteMode="deleteMode" :id="userId" />
<!-- 创建用户弹窗组件 -->
<addUserDialog
v-model:dialogVisible="dialogVisible"
:mode="mode"
:nickName="nickName"
:userName="userName"
:id="userId"
:userRole="userRole"
:userStatus="userStatus"
:userPassword="userPassword"
@get-user-list="getUserListData"
/>
<addUserDialog v-model:dialogVisible="dialogVisible" :mode="mode" :nickName="nickName" :userName="userName"
:id="userId" :userRole="userRole" :userStatus="userStatus" :userPassword="userPassword"
@get-user-list="getUserListData" />
</div>
</template>
......@@ -109,18 +71,31 @@ import { DeleteMode } from '@/components/Delete/enum.ts'
import { AddMode } from './components/enum.ts'
import { ElMessage } from 'element-plus'
import MenuTitle from '@/components/MenuTitle.vue'
// 用户id
const userId = ref<number>(-1)
// 用户id列表(批量删除时使用)
const userIds = ref<number[]>([])
// 用户昵称
const nickName = ref<string>('')
// 用户名
const userName = ref<string>('')
// 用户角色
const userRole = ref<number>(0)
// 用户状态
const userStatus = ref<boolean>(true)
// 用户密码
const userPassword = ref<string>('')
// 用户列表数据
const showDeleteDialog = ref(false)
// 删除模式(单个删除或批量删除)
const deleteMode = ref<DeleteMode>(DeleteMode.SINGLE_DELETE)
// 数据展示模式(添加用户或编辑用户)
const dialogVisible = ref<boolean>(false)
// 用户角色枚举
const mode = ref<AddMode>(AddMode.ADD_MODE)
// 表格数据
const tableData = ref([])
// 分页参数
const pageObj = ref({
total: 0,
pageSize: 10,
......@@ -164,17 +139,18 @@ const handleSelectionChange = (data: any) => {
}
userIds.value = array
}
// 打开添加用户弹窗的方法
const openAddUserDialog = () => {
mode.value = AddMode.ADD_MODE
dialogVisible.value = true
}
// 用户列表数据加载状态
const tableLoading = ref(false)
// 获取用户列表数据的方法
const getUserListData = async () => {
tableLoading.value = true
// 调用接口获取用户列表数据并更新响应式变量
const userList = await getUserList({
page: pageObj.value.pageNo,
size: pageObj.value.pageSize
......@@ -183,14 +159,14 @@ const getUserListData = async () => {
tableData.value = userList.data.list
pageObj.value.total = userList.data.total
}
// 用户角色枚举
const uRole = ref<UserRole>(UserRole.NORMAL_USER)
// 查询用户角色
const getURole = async () => {
const res = await getUserRole()
uRole.value = res.data
}
// 组件挂载时获取用户角色和用户列表数据
onMounted(async () => {
await getURole()
getUserListData()
......@@ -202,20 +178,24 @@ onMounted(async () => {
.el-button:focus {
outline: none;
}
.title {
text-align: left;
font-size: 18px;
font-weight: 500;
color: white;
}
.low-titme {
color: #ccc;
text-align: left;
margin-left: 20px;
}
.divider {
margin-top: 15px;
}
.btns {
display: flex;
justify-content: end;
......
<template>
<el-dialog
v-model="currentVisible"
:title="currentMode === AddMode.ADD_TASK ? '新增' : '修改'"
width="710"
center
align-center
@close="handleClose"
draggable
>
<!-- 新增/修改任务的弹框 -->
<el-dialog v-model="currentVisible" :title="currentMode === AddMode.ADD_TASK ? '新增' : '修改'" width="710" center
align-center @close="handleClose" draggable>
<!-- 爬虫任务的表单内容 -->
<el-form :model="ruleForm" :rules="rules" ref="ruleFormRef" label-width="100px">
<el-form-item label="任务名称:" v-if="currentMode === AddMode.ADD_TASK" prop="taskName">
<el-input v-model="ruleForm.taskName" placeholder="请输入任务名称" style="width: 90%" />
</el-form-item>
<el-form-item label="选择爬虫:" v-if="currentMode === AddMode.ADD_TASK" prop="spiderTypeValue">
<el-select v-model="ruleForm.spiderTypeValue" placeholder="请选择爬虫" style="width: 90%">
<el-option
v-for="item in spiderTypeOptions"
:key="item.spider"
:label="item.spider"
:value="item.spider"
:id="item.spider"
/>
<el-option v-for="item in spiderTypeOptions" :key="item.spider" :label="item.spider" :value="item.spider"
:id="item.spider" />
</el-select>
</el-form-item>
<el-form-item label="执行频率:">
<!-- <Crontab v-model="ruleForm.cronExpression" style="width: 90%"/> -->
<div class="gap-units">
<div class="gap-unit">
<el-input-number
v-model="exGaps.day"
class="gap-ipt"
:min="0"
:precision="0"
size="small"
></el-input-number>
<el-input-number v-model="exGaps.day" class="gap-ipt" :min="0" :precision="0"
size="small"></el-input-number>
<span class="unit-num"></span>
</div>
<div class="gap-unit">
<el-input-number
v-model="exGaps.hour"
class="gap-ipt"
:min="0"
:precision="0"
size="small"
></el-input-number>
<el-input-number v-model="exGaps.hour" class="gap-ipt" :min="0" :precision="0"
size="small"></el-input-number>
<span class="unit-num">小时</span>
</div>
<div class="gap-unit">
<el-input-number
v-model="exGaps.minute"
class="gap-ipt"
:min="0"
:precision="0"
size="small"
></el-input-number>
<el-input-number v-model="exGaps.minute" class="gap-ipt" :min="0" :precision="0"
size="small"></el-input-number>
<span class="unit-num">分钟</span>
</div>
<div class="gap-unit">
<el-input-number
v-model="exGaps.second"
class="gap-ipt"
:min="0"
:precision="2"
size="small"
></el-input-number>
<el-input-number v-model="exGaps.second" class="gap-ipt" :min="0" :precision="2"
size="small"></el-input-number>
<span class="unit-num"></span>
</div>
</div>
......@@ -86,16 +56,19 @@ import { AddMode } from "./enum";
import type { FormInstance, FormRules } from "element-plus";
import { ElMessage } from "element-plus";
import { getSpiderList } from "@/api/system.ts";
// 定义表单数据的类型
interface RuleForm {
taskName: string;
spiderTypeValue: string;
}
// 表单验证规则的定义
const ruleFormRef = ref<FormInstance>();
// 定义表单验证规则类型
const ruleForm = ref<RuleForm>({
taskName: "",
spiderTypeValue: "",
});
// 定义组件的类型
interface addDialogPropType {
dialogVisible: boolean;
mode: AddMode;
......@@ -104,7 +77,9 @@ interface addDialogPropType {
spiderType: string;
options: string;
}
// 定义组件的props类型
const props = defineProps<addDialogPropType>();
// 定义表单的验证规则
const rules = ref<FormRules<RuleForm>>({
taskName: [
{ required: true, message: "请输入任务名称", trigger: "blur" },
......@@ -124,6 +99,7 @@ const emit = defineEmits(["update:dialogVisible", "confirm", "update:mode", "get
const currentVisible = ref(props.dialogVisible);
const currentMode = ref(props.mode);
const spiderTypeOptions = ref();
// 任务参数
const taskParams = ref({
scrapyd_server_id: "1",
schedule_type: "0",
......@@ -132,6 +108,7 @@ const taskParams = ref({
// 关闭的方法
const handleClose = () => {
// 清空表单数据和验证状态
ruleForm.value.taskName = "";
ruleForm.value.spiderTypeValue;
ruleFormRef.value?.resetFields();
......@@ -200,7 +177,7 @@ const checkExGap = (exGaps: any) => {
return true;
}
};
// 获取爬虫任务列表的方法
const getData = async () => {
const res = await getSpiderList({ scrapydServerId: "1", project: "spiders" });
spiderTypeOptions.value = res.data;
......@@ -221,6 +198,7 @@ watch(
}
);
// 监听props.mode变化,同步给组件内部currentMode
watch(
() => props.mode,
(newVal) => {
......@@ -228,12 +206,15 @@ watch(
}
);
// 监听currentMode变化,同步给父组件,这样父组件才能知道当前是新增还是修改模式,以便在打开对话框时进行相应的处理
watch(
() => currentMode.value,
(newVal) => {
emit("update:mode", newVal);
}
);
// 监听props.exGap变化,同步给组件内部的exGaps
watch(
() => props.exGap,
(newVal) => {
......@@ -244,6 +225,7 @@ watch(
},
{ immediate: true }
);
// 组件挂载时获取爬虫任务列表数据
onMounted(() => {
getData();
});
......@@ -281,6 +263,7 @@ onMounted(() => {
align-items: center;
margin-right: 10px;
}
.unit-num {
color: white;
}
......
......@@ -19,12 +19,16 @@ import { ref, watch } from 'vue'
import { defineProps } from 'vue';
import { deleteSpiderTask } from '@/api/spiderTask.ts'
import { ElMessage } from 'element-plus';
// 定义删除对话框的数据类型
interface deleteDialogPropType {
dialogVisible: boolean,
jobId: string
}
// 定义组件的props类型
const props = defineProps<deleteDialogPropType>()
// 定义组件的事件
const emit = defineEmits(['update:dialogVisible', 'confirm', 'getUserList', 'update:deleteMode'])
// 删除对话框的显示状态
const deleteDialogVisible = ref(props.dialogVisible)
// 删除方法
const handleDelelte = async () => {
......
<!-- 任务执行统计卡片组件 -->
<template>
<div>
<!-- 搜索区域 -->
<TableSearch>
<div class="form-content">
<div class="ipt">
<span style="color: white">选择爬虫:</span>
<el-select
v-model="searchCondition.spiders"
placeholder="请选择"
style="width: 220px"
:disabled="!taskSelectOptions.length"
>
<el-option
v-for="item in taskSelectOptions || []"
:key="item?.spider"
:label="item?.spider || '未知'"
:value="item?.spider"
/>
<el-select v-model="searchCondition.spiders" placeholder="请选择" style="width: 220px"
:disabled="!taskSelectOptions.length">
<el-option v-for="item in taskSelectOptions || []" :key="item?.spider" :label="item?.spider || '未知'"
:value="item?.spider" />
</el-select>
</div>
<div class="btns">
......@@ -26,34 +19,27 @@
</div>
</div>
</TableSearch>
<!-- 卡片信息 -->
<div class="cardStyle" v-loading="isLoading" element-loading-background="rgba(48, 65, 86, 0.7)">
<div v-if="taskList.length === 0 && !isLoading" class="empty-tip">暂无任务数据</div>
<div class="taskCard p-2" v-for="task in taskList || []" :key="task?.id || task?.taskId">
<div class="header">
<span class="task-name"
>任务名称: {{ (task?.kwargs?.options && JSON.parse(task.kwargs.options).jobName) || "无名称" }}</span
>
<span class="task-name">任务名称: {{ (task?.kwargs?.options && JSON.parse(task.kwargs.options).jobName) || "无名称"
}}</span>
<el-divider style="margin-top: 5px"></el-divider>
</div>
<div class="btns">
<el-button plain type="primary" @click="editTask(task)" class="editButton" :disabled="!task?.id"
>编辑</el-button
>
<el-button plain type="danger" @click="deleteTask(task)" class="deleteButton" :disabled="!task?.id"
>删除</el-button
>
<el-button plain type="primary" @click="editTask(task)" class="editButton"
:disabled="!task?.id">编辑</el-button>
<el-button plain type="danger" @click="deleteTask(task)" class="deleteButton"
:disabled="!task?.id">删除</el-button>
</div>
<div class="info">
<div class="item">
<span class="wordStyle">启用/停止: </span>
<el-switch
v-model="task.status"
:active-value="'running'"
:inactive-value="'paused'"
@change="(newStatus: any) => changeStatus(task, newStatus)"
:disabled="!task?.id"
/>
<el-switch v-model="task.status" :active-value="'running'" :inactive-value="'paused'"
@change="(newStatus: any) => changeStatus(task, newStatus)" :disabled="!task?.id" />
</div>
<div class="item">
<span class="wordStyle">爬虫名称: </span>
......@@ -61,9 +47,9 @@
</div>
<div class="item">
<span class="wordStyle">执行频率: </span>
<span class="wordStyle"
>{{
`${task.kwargs.interval[3]} 天 ${task.kwargs.interval[2]} 小时 ${task.kwargs.interval[1]} 分钟 ${task.kwargs.interval[0]} 秒`
<span class="wordStyle">{{
`${task.kwargs.interval[3]} 天 ${task.kwargs.interval[2]} 小时 ${task.kwargs.interval[1]} 分钟
${task.kwargs.interval[0]} 秒`
}}
</span>
</div>
......@@ -74,17 +60,10 @@
</div>
</div>
</div>
<addTaskDialog
v-model:dialogVisible="showTaskDialog"
@confirm="handleEdit"
:mode="editMode"
@getTaskList="getData"
:jobId="jobId"
:exGap="frequency || []"
:spiderType="belongSpiderType || ''"
:options="taskOptions || ''"
/>
<addTaskDialog v-model:dialogVisible="showTaskDialog" @confirm="handleEdit" :mode="editMode" @getTaskList="getData"
:jobId="jobId" :exGap="frequency || []" :spiderType="belongSpiderType || ''" :options="taskOptions || ''" />
<!-- 删除对话框 -->
<deleteDialog v-model:dialogVisible="showDeleteDialog" @get-user-list="getData" :jobId="jobId" :disabled="!jobId" />
</div>
</template>
......@@ -101,7 +80,7 @@ import { ElMessage } from "element-plus";
import { getSpiderList } from "@/api/system.ts";
import formatExactLargeNum from "@/utils/formatExactLargeNum";
import TableSearch from "@/components/TableSearch.vue";
// 定义组件的props类型
const props = defineProps({
spiderType: {
type: String,
......@@ -119,29 +98,41 @@ const props = defineProps({
// 所有响应式变量初始化时避免 undefined
const taskSelectOptions = ref<any[]>([]); // 初始化为空数组
// 搜索条件
const searchCondition = ref({
spiders: "",
options: "",
});
// 任务名称
const taskName = ref("");
const taskValue = ref("");
// 所属爬虫类型
const belongSpiderType = ref("");
// 路由对象
const router = useRouter();
const frequency = ref([]); // 初始化为空字符串,解决 cron 类型错误
// 初始化为空字符串,解决 cron 类型错误
const frequency = ref([]);
// 编辑模式和删除模式的响应式变量
const editMode = ref(AddMode.UPDATE_TASK);
// 删除模式默认为单个删除
const deleteMode = ref(DeleteMode.SINGLE_DELETE);
// 删除对话框的显示状态
const showDeleteDialog = ref(false);
// 任务对话框的显示状态
const showTaskDialog = ref(false);
const taskSwitch = ref(false);
// 任务选项的响应式变量,初始化为字符串类型的空对象
const taskOptions = ref("");
// 任务id的响应式变量,初始化为字符串类型的空字符串
const jobId = ref("");
// 任务列表数据的响应式变量,初始化为数组类型的空数组
const taskList = ref<any[]>([]);
const isLoading = ref(false); // 新增专门的加载状态变量
// 新增专门的加载状态变量
const isLoading = ref(false);
// 删除任务的方法
const deleteTask = (task: any) => {
if (!task?.id) return; // 避免 task 为 undefined
// 避免 task 为 undefined
if (!task?.id) return;
jobId.value = task.id;
deleteMode.value = DeleteMode.SINGLE_DELETE;
showDeleteDialog.value = true;
......@@ -149,7 +140,8 @@ const deleteTask = (task: any) => {
// 编辑任务的方法
const editTask = (task: any) => {
if (!task?.id) return; // 避免 task 为 undefined
// 避免 task 为 undefined
if (!task?.id) return;
jobId.value = task.id;
// 安全处理 JSON 字符串,避免解析失败
try {
......@@ -158,15 +150,18 @@ const editTask = (task: any) => {
taskOptions.value = "{}";
}
belongSpiderType.value = task?.kwargs?.spider || "";
frequency.value = task?.kwargs?.interval || []; // 兜底空字符串
// 兜底空字符串
frequency.value = task?.kwargs?.interval || [];
editMode.value = AddMode.UPDATE_TASK;
showTaskDialog.value = true;
};
// 启动与停止任务的方法
const changeStatus = async (task: any, newStatus: string) => {
if (!task?.id) return; // 避免 task 为 undefined
// 避免 task 为 undefined
if (!task?.id) return;
try {
// 根据新的状态调用不同的接口,并提供用户反馈
if (newStatus === "running") {
await resumeSpiderTask({ job_id: task.id });
ElMessage.success("任务已启动");
......@@ -205,16 +200,21 @@ const getData = async () => {
// 遍历赋值时兜底
taskList.value = taskData.map((item: any) => ({
...item,
count: countData[item?.id] ?? 0, // 执行次数兜底 0
status: item?.status || "paused", // 状态兜底
kwargs: item?.kwargs || {}, // kwargs 兜底空对象
// 执行次数兜底 0
count: countData[item?.id] ?? 0,
// 状态兜底
status: item?.status || "paused",
// kwargs 兜底空对象
kwargs: item?.kwargs || {},
}));
} catch (err) {
ElMessage.error("获取任务列表失败");
console.error(err);
taskList.value = []; // 错误时置空数组
// 错误时置空数组
taskList.value = [];
} finally {
isLoading.value = false; // 结束加载
// 结束加载
isLoading.value = false;
}
};
......@@ -223,6 +223,7 @@ const resetData = async () => {
searchCondition.value.spiders = "";
isLoading.value = true;
try {
// 重置时获取所有任务列表数据,避免因搜索条件导致的空数据问题
const res = await getSpiderTaskList({ spiders: [], options: JSON.stringify({ jobName: taskName.value }) });
const resId = await getTaskCount({});
const taskData = res?.data || [];
......@@ -250,6 +251,7 @@ const search = async () => {
}
isLoading.value = true;
try {
// 搜索时根据选择的爬虫类型和任务名称获取任务列表数据,避免因搜索条件导致的空数据问题
const res = await getSpiderTaskList({
spiders: [searchCondition.value.spiders],
options: JSON.stringify({ jobName: taskName.value }),
......@@ -276,14 +278,15 @@ const search = async () => {
const getSpiderTypeList = async () => {
try {
const res = await getSpiderList({ scrapydServerId: "1", project: "spiders" });
taskSelectOptions.value = res?.data || []; // 兜底空数组
// 兜底空数组
taskSelectOptions.value = res?.data || [];
} catch (err) {
ElMessage.error("获取爬虫列表失败");
console.error(err);
taskSelectOptions.value = [];
}
};
// 挂载时获取任务列表数据和爬虫类型列表数据
onMounted(() => {
if (props.spiderType !== "") {
searchCondition.value.spiders = props.spiderType;
......@@ -297,9 +300,11 @@ onMounted(() => {
:deep(.el-select__selected-item) {
color: white !important;
}
:deep(.el-form-item__label) {
color: white;
}
.cardStyle {
padding: 18px;
gap: 15px;
......
<!-- 任务信息页面 -->
<template>
<div>
<!-- 菜单标题 -->
<MenuTitle title="任务信息" subtitle="Task Information" />
<div class="backStyle" v-if="route.query.jump === 'yes'" @click="goToTaskInformation" />
<div class="m-t-8" />
<div>
<!-- 任务卡片 -->
<taskCard :spiderType="spiderType" failTask="10" unusualTask="1" />
</div>
</div>
......@@ -16,10 +19,12 @@ import { useRouter } from "vue-router";
import { useRoute } from "vue-router";
import MenuTitle from "@/components/MenuTitle.vue";
// 从路由参数中获取爬虫类型
const route = useRoute();
const router = useRouter();
const spiderType = ref<any>(route.query.spiderType);
// 跳转到任务信息页面的方法
const goToTaskInformation = () => {
if (route.query.page === "spiderManager") {
router.push({ path: "/osSpiderManager/list" });
......
<!-- 任务执行记录页面 -->
<template>
<div>
<!-- 页面标题 -->
<MenuTitle title="任务执行记录" subtitle="Task Record" />
<div class="backStyle" v-if="route.query.jump === 'yes'" @click="goToStatus" />
<div class="m-t-8" />
<!-- 搜索工具栏 -->
<table-search>
<div class="form-content">
<div class="timer">
<span style="color: white">采集日期:</span>
<el-config-provider :locale="zhCn">
<el-date-picker
v-model="timeValue"
type="daterange"
start-placeholder="开始日期"
end-placeholder="结束日期"
format="YYYY-MM-DD"
date-format="YYYY/MM/DD ddd"
time-format="A hh:mm:ss"
value-format="YYYY-MM-DD"
style="width: 250px"
/>
<el-date-picker v-model="timeValue" type="daterange" start-placeholder="开始日期" end-placeholder="结束日期"
format="YYYY-MM-DD" date-format="YYYY/MM/DD ddd" time-format="A hh:mm:ss" value-format="YYYY-MM-DD"
style="width: 250px" />
</el-config-provider>
</div>
<div class="spider w-[300px] flex items-center">
<span style="color: white" class="w-[100px]">任务名称:</span>
<el-select v-model="jobname" placeholder="请选择任务名称">
<el-option
v-for="item in jobNameOptions"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
<el-option v-for="item in jobNameOptions" :key="item.value" :label="item.label"
:value="item.value"></el-option>
</el-select>
</div>
<div class="spider w-[300px] flex items-center">
<span style="color: white" class="w-[100px]">所属爬虫:</span>
<el-select v-model="spidername" placeholder="请选择爬虫">
<el-option
v-for="item in spideOptions"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
<el-option v-for="item in spideOptions" :key="item.value" :label="item.label"
:value="item.value"></el-option>
</el-select>
</div>
<div class="btns">
......@@ -49,17 +36,11 @@
</div>
</div>
</table-search>
<!-- 任务执行记录表格数据 -->
<div class="table-content">
<div>
<el-table
v-loading="tableLoading"
element-loading-background="rgba(48, 65, 86, 0.7)"
:data="tableData"
style="width: 100%"
border
:header-cell-style="{ textAlign: 'center' }"
:cell-style="{ textAlign: 'center' }"
>
<el-table v-loading="tableLoading" element-loading-background="rgba(48, 65, 86, 0.7)" :data="tableData"
style="width: 100%" border :header-cell-style="{ textAlign: 'center' }" :cell-style="{ textAlign: 'center' }">
<el-table-column property="number" label="序号" width="55" type="index" />
<el-table-column label="任务名称" show-overflow-tooltip>
<template #default="scope">
......@@ -93,13 +74,8 @@
</el-table>
</div>
<div class="pagination w-full flex flex-row-reverse pr-4 m-t-4">
<Pagination
:total="pageObj.total"
v-model:page="pageObj.pageNo"
v-model:limit="pageObj.pageSize"
@pagination="searchData"
v-model:pagerCount="pageObj.pagerCount"
/>
<Pagination :total="pageObj.total" v-model:page="pageObj.pageNo" v-model:limit="pageObj.pageSize"
@pagination="searchData" v-model:pagerCount="pageObj.pagerCount" />
</div>
</div>
</div>
......@@ -129,14 +105,16 @@ const route = useRoute()
const router = useRouter()
//初始数据为近七天
const timeValue = ref<string[]>([])
// 表格数据
const tableData = ref([])
// 分页参数
const pageObj = ref({
total: 10,
pageSize: 10,
pageNo: 1,
pagerCount: 5
})
// 跳转至状态监控页面的方法
const goToStatus = () => {
if (route.query.mode === '状态监控') {
router.push({
......@@ -148,7 +126,7 @@ const goToStatus = () => {
})
}
}
// 爬虫名称下拉框选项
const spideOptions = [
{
label: 'dsn_now',
......@@ -176,6 +154,7 @@ const tableLoading = ref(false)
//重置查询
const resetQuery = () => {
// 重置查询条件
timeValue.value = []
spidername.value = ''
jobname.value = ''
......@@ -190,6 +169,7 @@ const taskList = ref([])
const getTaskList = async () => {
const res = await getSpiderTaskList({})
taskList.value = res.data
// 根据任务列表数据构建任务名称下拉框选项
jobNameOptions.value = taskList.value
.filter((task: any) => task.id)
.map((task: any) => ({
......@@ -201,9 +181,10 @@ const getTaskList = async () => {
// 获取任务执行记录列表
const getData = async () => {
let resTime: any[] = []
// 如果时间范围不为空,则将时间范围转换为字符串格式并添加到请求参数中
resTime.push(dayjs().subtract(7, 'day').format('YYYY-MM-DD HH:mm:ss'))
resTime.push(dayjs().format('YYYY-MM-DD HH:mm:ss'))
// 根据选择的爬虫类型和任务名称获取任务执行记录列表数据,避免因查询条件导致的空数据问题
tableLoading.value = true
const res = await getSpiderTaskRecord({
page: pageObj.value.pageNo,
......@@ -211,11 +192,13 @@ const getData = async () => {
status: 'total',
times: resTime
})
// 根据接口返回的数据更新表格数据和分页参数
pageObj.value.total = res.data.total
tableData.value = res.data.list
tableLoading.value = false
}
// 爬虫名称和任务名称
const spidername = ref('')
const jobname = ref('')
......@@ -228,7 +211,9 @@ const searchData = async () => {
resTime.push(dayjs(startTime).format('YYYY-MM-DD HH:mm:ss'))
resTime.push(dayjs(endTime).format('YYYY-MM-DD HH:mm:ss'))
}
// 打开表格加载状态
tableLoading.value = true
// 发送请求获取数据
const res = await getSpiderTaskRecord({
page: pageObj.value.pageNo,
size: pageObj.value.pageSize,
......@@ -237,11 +222,13 @@ const searchData = async () => {
schedule_job_id: jobname.value,
times: resTime
})
// 根据接口返回的数据更新表格数据和分页参数
pageObj.value.total = res.data.total
tableData.value = res.data.list
tableLoading.value = false
}
// 挂载时获取任务执行记录列表数据
onMounted(() => {
getData()
getTaskList()
......@@ -252,6 +239,7 @@ onMounted(() => {
:deep(.el-form-item__label) {
color: white;
}
/* 工具栏样式 */
.toolbarStyle {
background-image: url('@/assets/picture/box3.png');
......@@ -301,6 +289,7 @@ onMounted(() => {
text-align: left;
margin-left: 20px;
}
.divider {
margin-top: 15px;
}
......@@ -313,6 +302,7 @@ onMounted(() => {
align-items: center;
padding: 0 30px;
}
.btns {
position: absolute;
right: 30px;
......
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