Commit 1838255a by liucan

feat:新增状态监控页loading效果,重写表单搜索栏组件,调整文字排版

parent 56d11da4
<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="0 0 20 20"><g fill="none"><path fill="url(#SVG4JAgqc9r)" d="M16 17V5.5a.5.5 0 0 0-.812-.39l-4.735 3.787l-3.205-1.831a.5.5 0 0 0-.451-.023L3 8.731V17z"/><path fill="url(#SVGazSFLmzC)" fill-opacity="0.3" d="M16 17V5.5a.5.5 0 0 0-.812-.39l-4.735 3.787l-3.205-1.831a.5.5 0 0 0-.451-.023L3 8.731V17z"/><path fill="url(#SVGctjeee0c)" fill-opacity="0.3" d="M16 17V5.5a.5.5 0 0 0-.812-.39l-4.735 3.787l-3.205-1.831a.5.5 0 0 0-.451-.023L3 8.731V17z"/><path fill="url(#SVGZhcbtstm)" fill-opacity="0.3" d="M16 17V5.5a.5.5 0 0 0-.812-.39l-4.735 3.787l-3.205-1.831a.5.5 0 0 0-.451-.023L3 8.731V17z"/><path fill="url(#SVGaypZDdDD)" d="M2.75 2a.75.75 0 0 1 .75.75v12.5c0 .69.56 1.25 1.25 1.25h12.5a.75.75 0 0 1 0 1.5H4.75A2.75 2.75 0 0 1 2 15.25V2.75A.75.75 0 0 1 2.75 2"/><defs><linearGradient id="SVG4JAgqc9r" x1="-1.5" x2="20" y1="6.5" y2="19" gradientUnits="userSpaceOnUse"><stop offset=".164" stop-color="#3bd5ff"/><stop offset=".537" stop-color="#9c6cfe"/><stop offset=".908" stop-color="#e656eb"/></linearGradient><linearGradient id="SVGctjeee0c" x1="9.5" x2="9.5" y1="15" y2="17" gradientUnits="userSpaceOnUse"><stop stop-color="#163697" stop-opacity="0"/><stop offset="1" stop-color="#163697"/></linearGradient><linearGradient id="SVGZhcbtstm" x1="5" x2="3" y1="13.5" y2="13.5" gradientUnits="userSpaceOnUse"><stop stop-color="#163697" stop-opacity="0"/><stop offset="1" stop-color="#163697"/></linearGradient><linearGradient id="SVGaypZDdDD" x1="16.5" x2="2.498" y1="3" y2="23.849" gradientUnits="userSpaceOnUse"><stop stop-color="#70777d"/><stop offset="1" stop-color="#b9c0c7"/></linearGradient><radialGradient id="SVGazSFLmzC" cx="0" cy="0" r="1" gradientTransform="matrix(-10.00002 8.99995 -9.1043 -10.11597 14 7)" gradientUnits="userSpaceOnUse"><stop offset=".636" stop-color="#0fafff" stop-opacity="0"/><stop offset=".962" stop-color="#0067bf"/></radialGradient></defs></g></svg>
\ No newline at end of file
<template>
<div style="margin-bottom: 0" class="menu-title">
<div class="title">{{ props.title }}</div>
<div class="low-titme">{{ props.subtitle }}</div>
</div>
</template>
<script setup lang="ts">
const props = defineProps<{
title?: string;
subtitle?: string;
}>();
</script>
<style scoped>
.title {
text-align: left;
font-size: 18px;
font-weight: 500;
color: white;
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
}
.low-titme {
color: rgba(255, 255, 255, 0.8);
text-align: left;
margin-left: 20px;
text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
}
.menu-title {
padding: 20px 0 10px 20px;
user-select: none;
background: rgba(255, 255, 255, 0.1);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.15);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1), inset 0 0 10px rgba(255, 255, 255, 0.05);
}
</style>
<template>
<div class="box">
<div class="left"></div>
<div class="content">
<slot></slot>
</div>
<div class="right"></div>
</div>
</template>
<script setup lang="ts"></script>
<style scoped>
.box {
position: relative;
}
.content {
width: 95%;
height: 80px;
margin: auto;
border: 1.5px solid #0270b6;
border-top-left-radius: 20px;
border-bottom-left-radius: 20px;
border-bottom-right-radius: 20px;
border-top-right-radius: 20px;
border-left: none;
border-right: none;
background-image: linear-gradient(
120deg,
rgba(7, 47, 70, 0.6) 0%,
/* 起始色:80% 透明度 */ rgba(6, 20, 37, 0.4) 100% /* 结束色:60% 透明度 */
);
}
.left {
width: 50px;
height: 40px;
background-color: white;
position: absolute;
top: 50%;
transform: translateY(-50%);
background-image: linear-gradient(to right, #00a8ff, #003366);
}
.right {
width: 50px;
height: 40px;
background-color: white;
position: absolute;
top: 50%;
right: 0;
transform: translateY(-50%);
background-image: linear-gradient(to left, #00a8ff, #003366);
}
</style>
<script setup lang="ts"> <script setup lang="ts">
import { computed } from 'vue' import { computed } from "vue";
import { useRouter } from 'vue-router' import { useRouter } from "vue-router";
import { useUserStore } from '@/store/user' import { useUserStore } from "@/store/user";
import { useAppStore } from '@/store/app' import { useAppStore } from "@/store/app";
import { storeToRefs } from 'pinia' import { storeToRefs } from "pinia";
import Breadcrumb from '@/components/Breadcrumb/index.vue' import Breadcrumb from "@/components/Breadcrumb/index.vue";
import Hamburger from '@/components/Hamburger/index.vue' import Hamburger from "@/components/Hamburger/index.vue";
const router = useRouter() const router = useRouter();
const userStore = useUserStore() const userStore = useUserStore();
const appStore = useAppStore() const appStore = useAppStore();
const { sidebar } = storeToRefs(appStore) const { sidebar } = storeToRefs(appStore);
const avatar = computed(() => userStore.avatar || 'user-avatar.gif') const avatar = computed(() => userStore.avatar || "user-avatar.gif");
const toggleSideBar = () => { const toggleSideBar = () => {
appStore.toggleSidebar() appStore.toggleSidebar();
} };
const logout = async () => { const logout = async () => {
await userStore.logout() await userStore.logout();
router.push(`/login?redirect=${router.currentRoute.value.fullPath}`) router.push(`/login?redirect=${router.currentRoute.value.fullPath}`);
} };
</script> </script>
<template> <template>
...@@ -30,18 +30,16 @@ const logout = async () => { ...@@ -30,18 +30,16 @@ const logout = async () => {
<div class="right-menu"> <div class="right-menu">
<el-dropdown class="avatar-container" trigger="click"> <el-dropdown class="avatar-container" trigger="click">
<div class="avatar-wrapper"> <div class="avatar-wrapper">
<img :src="avatar" class="user-avatar"> <img :src="avatar" class="user-avatar" />
<el-icon><CaretBottom /></el-icon> <el-icon><CaretBottom /></el-icon>
</div> </div>
<template #dropdown> <template #dropdown>
<el-dropdown-menu class="user-dropdown"> <el-dropdown-menu class="user-dropdown">
<router-link to="/"> <router-link to="/">
<el-dropdown-item> <el-dropdown-item> 首页 </el-dropdown-item>
首页
</el-dropdown-item>
</router-link> </router-link>
<el-dropdown-item divided @click="logout"> <el-dropdown-item divided @click="logout">
<span style="display:block;">退出</span> <span style="display: block">退出</span>
</el-dropdown-item> </el-dropdown-item>
</el-dropdown-menu> </el-dropdown-menu>
</template> </template>
...@@ -56,18 +54,18 @@ const logout = async () => { ...@@ -56,18 +54,18 @@ const logout = async () => {
overflow: hidden; overflow: hidden;
position: relative; position: relative;
background: #fff; background: #fff;
box-shadow: 0 1px 4px rgba(0,21,41,.08); box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
.hamburger-container { .hamburger-container {
line-height: 46px; line-height: 46px;
height: 100%; height: 100%;
float: left; float: left;
cursor: pointer; cursor: pointer;
transition: background .3s; transition: background 0.3s;
-webkit-tap-highlight-color:transparent; -webkit-tap-highlight-color: transparent;
&:hover { &:hover {
background: rgba(0, 0, 0, .025) background: rgba(0, 0, 0, 0.025);
} }
} }
...@@ -94,10 +92,10 @@ const logout = async () => { ...@@ -94,10 +92,10 @@ const logout = async () => {
&.hover-effect { &.hover-effect {
cursor: pointer; cursor: pointer;
transition: background .3s; transition: background 0.3s;
&:hover { &:hover {
background: rgba(0, 0, 0, .025) background: rgba(0, 0, 0, 0.025);
} }
} }
} }
......
...@@ -53,6 +53,7 @@ const logo = ""; // 暂时为空 ...@@ -53,6 +53,7 @@ const logo = ""; // 暂时为空
& .sidebar-title { & .sidebar-title {
display: inline-block; display: inline-block;
letter-spacing: 2px;
margin: 0; margin: 0;
color: #fff; color: #fff;
font-weight: 600; font-weight: 600;
......
interface ISettings { interface ISettings {
title: string title: string;
fixedHeader: boolean fixedHeader: boolean;
sidebarLogo: boolean sidebarLogo: boolean;
} }
const settings: ISettings = { const settings: ISettings = {
title: 'Spider Admin Pro', title: "互联网信息采集",
fixedHeader: true, fixedHeader: true,
sidebarLogo: true sidebarLogo: true,
} };
export default settings export default settings;
import { defineStore } from 'pinia' import { defineStore } from "pinia";
import { useSlideStateStore } from "./slideState";
interface AppState { interface AppState {
sidebar: { sidebar: {
opened: boolean opened: boolean;
withoutAnimation: boolean withoutAnimation: boolean;
}, };
device: 'desktop' | 'mobile' device: "desktop" | "mobile";
} }
export const useAppStore = defineStore('app', { export const useAppStore = defineStore("app", {
state: (): AppState => ({ state: (): AppState => ({
sidebar: { sidebar: {
opened: localStorage.getItem('sidebarStatus') opened: localStorage.getItem("sidebarStatus")
? !!+localStorage.getItem('sidebarStatus')! // 将获取到的值转换为布尔值 其中 + 为先转为数字 !! 为转成 bool 值 ? !!+localStorage.getItem("sidebarStatus")! // 将获取到的值转换为布尔值 其中 + 为先转为数字 !! 为转成 bool 值
: true, : true,
withoutAnimation: false withoutAnimation: false,
}, },
device: 'desktop', device: "desktop",
}), }),
actions: { actions: {
toggleSidebar() { toggleSidebar() {
this.sidebar.opened = !this.sidebar.opened const slideStateStore = useSlideStateStore();
this.sidebar.withoutAnimation = false this.sidebar.opened = !this.sidebar.opened;
this.sidebar.withoutAnimation = false;
if (this.sidebar.opened) { if (this.sidebar.opened) {
localStorage.setItem('sidebarStatus', '1') localStorage.setItem("sidebarStatus", "1");
} else { } else {
localStorage.setItem('sidebarStatus', '0') localStorage.setItem("sidebarStatus", "0");
} }
slideStateStore.setSlideState(this.sidebar.opened ? "1" : "0");
}, },
closeSideBar(options: { withoutAnimation: boolean }) { closeSideBar(options: { withoutAnimation: boolean }) {
this.sidebar.opened = false this.sidebar.opened = false;
this.sidebar.withoutAnimation = options.withoutAnimation this.sidebar.withoutAnimation = options.withoutAnimation;
localStorage.setItem('sidebarStatus', '0') localStorage.setItem("sidebarStatus", "0");
const slideStateStore = useSlideStateStore();
slideStateStore.setSlideState("0");
}, },
toggleDevice(device: 'desktop' | 'mobile') { toggleDevice(device: "desktop" | "mobile") {
this.device = device this.device = device;
} },
} },
}) });
import { defineStore } from "pinia";
import { ref } from "vue";
export const useSlideStateStore = defineStore("slideState", () => {
const slideState = ref<boolean>(localStorage.getItem("sidebarStatus") == "1");
function getSlideState(): boolean {
return slideState.value;
}
function setSlideState(state: any) {
slideState.value = state == "1" ? true : false;
}
return {
slideState,
getSlideState,
setSlideState,
};
});
const formatExactLargeNum = (num: number | string) => { const formatExactLargeNum = (num: number | string | null) => {
if (num === null || num === undefined) return num; if (num === null || num === undefined) return "";
if (typeof num !== "number" && typeof num !== "string") return num; if (typeof num !== "number" && typeof num !== "string") return num;
const parsedNum = typeof num === "string" ? Number(num.replace(/,/g, "")) : num; const parsedNum = typeof num === "string" ? Number(num.replace(/,/g, "")) : num;
......
...@@ -311,7 +311,7 @@ onMounted(async () => { ...@@ -311,7 +311,7 @@ onMounted(async () => {
} }
.title { .title {
color: white; color: #4edaff;
font-size: 18px; font-size: 18px;
font-weight: 500; font-weight: 500;
} }
...@@ -324,7 +324,7 @@ onMounted(async () => { ...@@ -324,7 +324,7 @@ onMounted(async () => {
} }
.item-title { .item-title {
color: #fff; color: #b0dfff;
} }
.item { .item {
......
<template> <template>
<div class="text-left p-4 toolbarStyle"> <div class="text-left">
<div class="formStyle"> <table-search>
<el-form inline> <div class="form-content">
<el-form-item label="目标名称:"> <div class="left">
<div> <div>
<span style="color: white">目标名称:</span>
<el-input placeholder="请输入目标名称:" v-model="searchTargetName" style="width: 180px" /> <el-input placeholder="请输入目标名称:" v-model="searchTargetName" style="width: 180px" />
</div> </div>
</el-form-item> <div>
<el-form-item label="获取时间:"> <span style="color: white">时间范围:</span>
<el-config-provider :locale="zhCn"> <el-config-provider :locale="zhCn">
<el-date-picker <el-date-picker
type="datetimerange" type="datetimerange"
format="YYYY-MM-DD HH:mm:ss" format="YYYY-MM-DD HH:mm:ss"
v-model="searchTimeValue" v-model="searchTimeValue"
start-placeholder="开始时间" start-placeholder="开始时间"
style="width: 200px" style="width: 200px"
end-placeholder="结束时间" end-placeholder="结束时间"
date-format="YYYY/MM/DD ddd" date-format="YYYY/MM/DD ddd"
time-format="A hh:mm:ss" time-format="A hh:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss"
/> />
</el-config-provider> </el-config-provider>
</el-form-item> </div>
<el-form-item label="站点名称:"> <div>
<el-input placeholder="请输入" v-model="searchStation" style="width: 170.5px" /> <span style="color: white">站点名称:</span>
</el-form-item> <el-input placeholder="请输入" v-model="searchStation" style="width: 170.5px" />
<el-form-item> </div>
<el-space> </div>
<el-button plain type="primary" @click="handleSearch">查询</el-button>
<el-button plain @click="getData">重置表格</el-button> <div class="btns">
</el-space> <el-button plain type="primary" @click="handleSearch">查询</el-button>
</el-form-item> <el-button plain @click="getData">重置表格</el-button>
</el-form> </div>
</div> </div>
</table-search>
</div> </div>
<div class="m-t-5" /> <div class="m-t-5" />
...@@ -354,6 +356,7 @@ import { ElMessage } from "element-plus"; ...@@ -354,6 +356,7 @@ import { ElMessage } from "element-plus";
import { ElConfigProvider } from "element-plus"; import { ElConfigProvider } from "element-plus";
// 引入中文包 // 引入中文包
import zhCn from "element-plus/es/locale/lang/zh-cn"; import zhCn from "element-plus/es/locale/lang/zh-cn";
import TableSearch from "@/components/TableSearch.vue";
defineOptions({ name: "Pagination" }); defineOptions({ name: "Pagination" });
// 更改分页文字 // 更改分页文字
zhCn.el.pagination.total = "共 `{total} 条`"; zhCn.el.pagination.total = "共 `{total} 条`";
...@@ -679,7 +682,7 @@ onMounted(() => { ...@@ -679,7 +682,7 @@ onMounted(() => {
} }
.title { .title {
color: white; color: #4edaff;
font-size: 18px; font-size: 18px;
font-weight: 500; font-weight: 500;
} }
...@@ -692,7 +695,7 @@ onMounted(() => { ...@@ -692,7 +695,7 @@ onMounted(() => {
} }
.item-title { .item-title {
color: #fff; color: #b0dfff;
} }
.item { .item {
...@@ -705,11 +708,24 @@ onMounted(() => { ...@@ -705,11 +708,24 @@ onMounted(() => {
} }
.target-desc { .target-desc {
color: white; color: #d0e8ff;
} }
.btns { .btns {
display: flex; display: flex;
justify-content: center;
}
.form-content {
display: flex;
height: 80px;
align-items: center;
padding: 0 30px;
justify-content: space-between;
}
.left {
display: flex;
gap: 10px;
} }
</style> </style>
......
<template> <template>
<div class="text-left p-4 toolbarStyle"> <div class="text-left">
<div class="formStyle"> <TableSearch>
<el-form inline> <div class="form-content">
<el-form-item label="目标名称:"> <div class="left">
<div> <div>
<span style="color: white">目标名称:</span>
<el-input placeholder="请输入目标名称" v-model="searchTargetName" style="width: 180px" /> <el-input placeholder="请输入目标名称" v-model="searchTargetName" style="width: 180px" />
</div> </div>
</el-form-item> <div>
<el-form-item label="获取时间:"> <span style="color: white">时间范围:</span>
<el-config-provider :locale="zhCn"> <el-config-provider :locale="zhCn">
<el-date-picker <el-date-picker
type="datetimerange" type="datetimerange"
format="YYYY-MM-DD HH:mm:ss" format="YYYY-MM-DD HH:mm:ss"
v-model="searchTimeValue" v-model="searchTimeValue"
start-placeholder="开始时间" start-placeholder="开始时间"
style="width: 200px" style="width: 200px"
end-placeholder="结束时间" end-placeholder="结束时间"
date-format="YYYY/MM/DD ddd" date-format="YYYY/MM/DD ddd"
time-format="A hh:mm:ss" time-format="A hh:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss"
/> />
</el-config-provider> </el-config-provider>
</el-form-item> </div>
<el-form-item label="SNS Notice ID:"> <div>
<el-input placeholder="请输入ID" v-model="searchTargetId" style="width: 170.5px" /> <span style="color: white">SNS Notice ID:</span>
</el-form-item> <el-input placeholder="请输入ID" v-model="searchTargetId" style="width: 170.5px" />
<el-form-item> </div>
</div>
<div class="btns">
<el-button plain type="primary" @click="handleSearch">查询</el-button> <el-button plain type="primary" @click="handleSearch">查询</el-button>
<el-button plain="" @click="getData">重置</el-button> <el-button plain="" @click="getData">重置</el-button>
</el-form-item> </div>
</el-form> </div>
</div> </TableSearch>
</div> </div>
<div class="m-t-5" /> <div class="m-t-5" />
...@@ -48,7 +51,7 @@ ...@@ -48,7 +51,7 @@
<!-- <el-table-column type="selection" width="40" /> --> <!-- <el-table-column type="selection" width="40" /> -->
<el-table-column property="number" label="序号" width="55" type="index" /> <el-table-column property="number" label="序号" width="55" type="index" />
<el-table-column property="item.ntc_id" label="SNS Notice ID" show-overflow-tooltip /> <el-table-column property="item.ntc_id" label="SNS Notice ID" show-overflow-tooltip />
<el-table-column property="identity.adm_name_e" label="主管部门" show-overflow-tooltip /> <el-table-column min-width="100" property="identity.adm_name_e" label="主管部门" show-overflow-tooltip />
<el-table-column property="identity.sat_name" label="目标名称" show-overflow-tooltip /> <el-table-column property="identity.sat_name" label="目标名称" show-overflow-tooltip />
<el-table-column property="item.plan_txt" label="计划/非计划类型" show-overflow-tooltip /> <el-table-column property="item.plan_txt" label="计划/非计划类型" show-overflow-tooltip />
<el-table-column property="identity.ntc_type" label="是否为同步" show-overflow-tooltip> <el-table-column property="identity.ntc_type" label="是否为同步" show-overflow-tooltip>
...@@ -78,7 +81,12 @@ ...@@ -78,7 +81,12 @@
{{ 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> </template>
</el-table-column> </el-table-column>
<el-table-column property="regulatory_status.f_biu_grps" 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" label="是否暂停使用" show-overflow-tooltip /> <el-table-column property="regulatory_status.resumption_list" label="是否暂停使用" show-overflow-tooltip />
<el-table-column label="操作" width="60"> <el-table-column label="操作" width="60">
<template #default="scope"> <template #default="scope">
...@@ -218,6 +226,7 @@ import Pagination from "@/components/pagination/index.vue"; ...@@ -218,6 +226,7 @@ import Pagination from "@/components/pagination/index.vue";
import exportDialog from "@/components/Export/index.vue"; import exportDialog from "@/components/Export/index.vue";
import { getItuList, getItuDetail } from "@/api/spiderData"; import { getItuList, getItuDetail } from "@/api/spiderData";
import { ElMessage } from "element-plus"; import { ElMessage } from "element-plus";
import TableSearch from "@/components/TableSearch.vue";
// ElConfigProvider 组件 // ElConfigProvider 组件
import { ElConfigProvider } from "element-plus"; import { ElConfigProvider } from "element-plus";
// 引入中文包 // 引入中文包
...@@ -402,11 +411,15 @@ onMounted(() => { ...@@ -402,11 +411,15 @@ onMounted(() => {
} }
.title { .title {
color: white; color: #4edaff;
font-size: 18px; font-size: 18px;
font-weight: 500; font-weight: 500;
} }
.left {
display: flex;
gap: 10px;
}
.info-item { .info-item {
display: flex; display: flex;
align-items: center; align-items: center;
...@@ -415,12 +428,19 @@ onMounted(() => { ...@@ -415,12 +428,19 @@ onMounted(() => {
} }
.item-title { .item-title {
color: #fff; color: #b0dfff;
} }
.item { .item {
color: #eee; color: #eee;
} }
.form-content {
display: flex;
height: 80px;
justify-content: space-between;
align-items: center;
padding: 0 30px;
}
</style> </style>
<style> <style>
......
<template> <template>
<div class="text-left p-4 toolbarStyle"> <div class="text-left">
<div class="formStyle"> <table-search>
<el-form inline> <div class="form-content">
<el-form-item label="目标名称:"> <div class="left">
<el-input placeholder="请输入目标名称" style="width: 180px" v-model="searchTargetName" /> <div>
</el-form-item> <span style="color: white">目标名称:</span>
<el-form-item label="获取时间:"> <el-input placeholder="请输入目标名称" style="width: 180px" v-model="searchTargetName" />
<el-config-provider :locale="zhCn"> </div>
<el-date-picker <div>
v-model="timeValue" <span style="color: white">时间范围:</span>
type="datetimerange" <el-config-provider :locale="zhCn">
format="YYYY-MM-DD HH:mm:ss" <el-date-picker
start-placeholder="开始时间" v-model="timeValue"
end-placeholder="结束时间" type="datetimerange"
date-format="YYYY/MM/DD ddd" format="YYYY-MM-DD HH:mm:ss"
time-format="A hh:mm:ss" start-placeholder="开始时间"
style="width: 200px" end-placeholder="结束时间"
value-format="YYYY-MM-DD HH:mm:ss" date-format="YYYY/MM/DD ddd"
/> time-format="A hh:mm:ss"
</el-config-provider> style="width: 200px"
</el-form-item> value-format="YYYY-MM-DD HH:mm:ss"
<el-form-item label="NORAD CAT ID:"> />
<el-input placeholder="请输入ID" style="width: 170.5px" v-model="noradCatId" /> </el-config-provider>
</el-form-item> </div>
<!-- <el-form-item> <div>
<el-space> <span style="color: white">Norad Cat ID:</span>
<el-button type="primary" @click="handleExport">导出最近</el-button> <el-input placeholder="请输入ID" style="width: 170.5px" v-model="noradCatId" />
</el-space> </div>
</el-form-item> --> </div>
<el-form-item> <div class="btns">
<el-space> <el-button plain type="primary" @click="handleSearch">查询</el-button>
<el-button plain type="primary" @click="handleSearch">查询</el-button> <el-button plain @click="getData">重置表格</el-button>
<el-button plain @click="getData">重置表格</el-button> </div>
</el-space> </div>
</el-form-item> </table-search>
</el-form>
</div>
</div> </div>
<div class="m-t-5" /> <div class="m-t-5" />
...@@ -137,6 +135,12 @@ ...@@ -137,6 +135,12 @@
<span class="item-title">雷达截面积:</span> <span class="item-title">雷达截面积:</span>
<span class="item">{{ rcsSize }}</span> <span class="item">{{ rcsSize }}</span>
</div> </div>
</el-col>
</el-row>
<div class="title">TLE数据:</div>
<el-divider style="margin: 0"></el-divider>
<el-row>
<el-col>
<div class="info-item"> <div class="info-item">
<span class="item-title">TLE第一行数据:</span> <span class="item-title">TLE第一行数据:</span>
<span class="item">{{ tleLine0 }}</span> <span class="item">{{ tleLine0 }}</span>
...@@ -167,6 +171,7 @@ import { getStList, getStDetail } from "@/api/spiderData"; ...@@ -167,6 +171,7 @@ import { getStList, getStDetail } from "@/api/spiderData";
import { ElMessage } from "element-plus"; import { ElMessage } from "element-plus";
// ElConfigProvider 组件 // ElConfigProvider 组件
import { ElConfigProvider } from "element-plus"; import { ElConfigProvider } from "element-plus";
import TableSearch from "@/components/TableSearch.vue";
// 引入中文包 // 引入中文包
import zhCn from "element-plus/es/locale/lang/zh-cn"; import zhCn from "element-plus/es/locale/lang/zh-cn";
defineOptions({ name: "Pagination" }); defineOptions({ name: "Pagination" });
...@@ -340,9 +345,9 @@ onMounted(() => { ...@@ -340,9 +345,9 @@ onMounted(() => {
} }
.title { .title {
color: white;
font-size: 18px; font-size: 18px;
font-weight: 500; font-weight: 500;
color: #4edaff;
} }
.info-item { .info-item {
...@@ -353,12 +358,23 @@ onMounted(() => { ...@@ -353,12 +358,23 @@ onMounted(() => {
} }
.item-title { .item-title {
color: #fff; color: #b0dfff;
} }
.item { .item {
color: #eee; color: #eee;
} }
.form-content {
display: flex;
height: 80px;
align-items: center;
padding: 0 30px;
justify-content: space-between;
}
.left {
display: flex;
gap: 10px;
}
</style> </style>
<style> <style>
......
<template> <template>
<div> <div>
<el-card style="margin-bottom: 0"> <MenuTitle title="数据展示" subtitle="Data Display" />
<div class="title">数据展示</div>
<div class="low-titme">Data Display</div>
<el-divider class="divider" style="margin-bottom: 0" />
</el-card>
<div class="backStyle" v-if="route.query.jump === 'yes'" @click="goToStatus" /> <div class="backStyle" v-if="route.query.jump === 'yes'" @click="goToStatus" />
<div class="segment-content"> <div class="segment-content">
<div class="custom-style flex gap-4"> <div class="custom-style flex gap-4">
...@@ -37,6 +33,7 @@ import dsnDataTab from "./components/dsnData/dsnTab.vue"; ...@@ -37,6 +33,7 @@ import dsnDataTab from "./components/dsnData/dsnTab.vue";
import esDataTab from "./components/esDataTab.vue"; import esDataTab from "./components/esDataTab.vue";
import exportDialog from "@/components/Export/index.vue"; import exportDialog from "@/components/Export/index.vue";
import type { UploadInstance } from "element-plus"; import type { UploadInstance } from "element-plus";
import MenuTitle from "@/components/MenuTitle.vue";
const mode = ref(sessionStorage.getItem("dataDisplayMode") || "DSN数据"); const mode = ref(sessionStorage.getItem("dataDisplayMode") || "DSN数据");
const showDeleteDialog = ref(false); const showDeleteDialog = ref(false);
...@@ -44,7 +41,6 @@ const sizeOptions = ["DSN数据", "ITU数据", "ST数据", "ESA数据"]; ...@@ -44,7 +41,6 @@ const sizeOptions = ["DSN数据", "ITU数据", "ST数据", "ESA数据"];
const route = useRoute(); const route = useRoute();
const router = useRouter(); const router = useRouter();
const modeValue = ref<any>("数据展示"); const modeValue = ref<any>("数据展示");
const upload = ref<UploadInstance>();
const goToStatus = () => { const goToStatus = () => {
router.push({ router.push({
......
<template> <template>
<div> <div>
<el-card> <MenuTitle title="爬虫管理" subtitle="Spider Manager" />
<div class="title">爬虫管理</div>
<div class="low-titme">Spider Manager</div>
<el-divider class="divider" />
</el-card>
<div class="table-content"> <div class="table-content">
<el-table <el-table
:data="tableData" :data="tableData"
...@@ -24,7 +20,7 @@ ...@@ -24,7 +20,7 @@
<template #default="scope"> <template #default="scope">
<div class="btn-group"> <div class="btn-group">
<el-button type="primary" plain @click="handleDetails(scope.row)">查看任务</el-button> <el-button type="primary" plain @click="handleDetails(scope.row)">查看任务</el-button>
<el-button type="primary" plain @click="handleEditSateId">编辑</el-button> <el-button type="primary" plain @click="handleEditSateId" v-if="scope.row.editable">编辑</el-button>
</div> </div>
</template> </template>
</el-table-column> </el-table-column>
...@@ -104,6 +100,7 @@ import { useRouter } from "vue-router"; ...@@ -104,6 +100,7 @@ import { useRouter } from "vue-router";
import { getSpiderList, addSateNo, getSateIdList } from "@/api/system.ts"; import { getSpiderList, addSateNo, getSateIdList } from "@/api/system.ts";
import NoItem from "./components/NoItem.vue"; import NoItem from "./components/NoItem.vue";
import { ElMessage } from "element-plus"; import { ElMessage } from "element-plus";
import MenuTitle from "@/components/MenuTitle.vue";
const router = useRouter(); const router = useRouter();
const tableData = ref([]); const tableData = ref([]);
...@@ -126,6 +123,7 @@ const handleDetails = (row: any) => { ...@@ -126,6 +123,7 @@ const handleDetails = (row: any) => {
const getData = async () => { const getData = async () => {
const res = await getSpiderList({ scrapydServerId: "1", project: "spiders" }); const res = await getSpiderList({ scrapydServerId: "1", project: "spiders" });
tableData.value = res.data; tableData.value = res.data;
console.log(res.data);
}; };
const editDialogVisible = ref(false); const editDialogVisible = ref(false);
...@@ -238,6 +236,7 @@ onMounted(() => { ...@@ -238,6 +236,7 @@ onMounted(() => {
.table-content { .table-content {
padding: 10px; padding: 10px;
margin-top: 30px;
} }
.title { .title {
......
<template> <template>
<div class="flex"> <div class="flex">
<span class="textStyle">数据统计</span> <span class="textStyle" :class="{ toRight0: slideState }">数据统计</span>
<div class="dataCard" @click="goToAllDataPage"> <div class="dataCard" @click="goToAllDataPage">
<div class="titleStyle"> <div class="titleStyle">
<span>数据统计</span> <span>数据统计</span>
</div> </div>
<div class="wordStyle"> <div class="items">
<span>总数据量:</span> <div class="wordStyle">
<span class="total-num">{{ formatExactLargeNum(totalDataNumber) }}</span> <span>总数据量:</span>
</div> <span class="total-num" v-if="totalDataNumber != null">{{ formatExactLargeNum(totalDataNumber) }}</span>
<div class="wordStyle"> <span class="loading" v-else></span>
<span>采集的页面数量:</span> </div>
<span class="total-num"> {{ formatExactLargeNum(totalPageNumber) }}</span> <div class="wordStyle">
</div> <span>采集的页面数量:</span>
<div class="wordStyle"> <span class="total-num" v-if="totalPageNumber != null"> {{ formatExactLargeNum(totalPageNumber) }}</span>
<span>采集的目标数量:</span> <span class="loading" v-else></span>
<span class="total-num"> {{ formatExactLargeNum(totalTargetNumber) }}</span> </div>
<div class="wordStyle">
<span>采集的目标数量:</span>
<span class="total-num" v-if="totalTargetNumber != null"> {{ formatExactLargeNum(totalTargetNumber) }}</span>
<span class="loading" v-else></span>
</div>
</div> </div>
</div> </div>
<div class="dataCard" @click="goToTaskRecordPage"> <div class="dataCard" @click="goToTaskRecordPage">
<div class="titleStyle"> <div class="titleStyle">
<span>任务执行统计</span> <span>任务执行统计</span>
</div> </div>
<div class="wordStyle"> <div class="items">
<span>任务执行成功统计:</span> <div class="wordStyle">
<span class="total-num">{{ formatExactLargeNum(successTask) }}</span> <span>任务执行成功统计:</span>
</div> <span class="total-num" v-if="successTask != null">{{ formatExactLargeNum(successTask) }}</span>
<div class="wordStyle"> <span class="loading" v-else></span>
<span>任务执行失败统计:</span> </div>
<span class="total-num">{{ formatExactLargeNum(failTask) }}</span> <div class="wordStyle">
</div> <span>任务执行失败统计:</span>
<div class="wordStyle"> <span class="total-num" v-if="failTask != null">{{ formatExactLargeNum(failTask) }}</span>
<span>任务异常数统计:</span> <span class="loading" v-else></span>
<span class="total-num">{{ formatExactLargeNum(unusualTask) }}</span> </div>
<div class="wordStyle">
<span>任务异常数统计:</span>
<span class="total-num" v-if="unusualTask != null">{{ formatExactLargeNum(unusualTask) }}</span>
<span class="loading" v-else></span>
</div>
</div> </div>
</div> </div>
<div class="dataCard"> <div class="dataCard">
<div class="titleStyle"> <div class="titleStyle">
<span>性能统计</span> <span>性能统计</span>
</div> </div>
<div class="wordStyle"> <div class="items">
<span>平均成功率:</span> <div class="wordStyle">
<span class="total-num"> {{ speed !== "" ? speed : "加载中..." }}</span> <span>平均成功率:</span>
</div> <span class="total-num" v-if="speed != null"> {{ speed }}</span>
<div class="wordStyle"> <span class="loading" v-else></span>
<span>平均错误率: </span> </div>
<span class="total-num">{{ errorRate !== "" ? errorRate : "加载中..." }}</span> <div class="wordStyle">
</div> <span>平均错误率: </span>
<div class="wordStyle"> <span class="total-num" v-if="errorRate != null">{{ errorRate }}</span>
<span>平均异常率:</span> <span class="loading" v-else></span>
<span class="total-num">{{ unusualRate !== "" ? unusualRate : "加载中..." }}</span> </div>
<div class="wordStyle">
<span>平均异常率:</span>
<span class="total-num" v-if="unusualRate != null">{{ unusualRate }}</span>
<span class="loading" v-else></span>
</div>
</div> </div>
</div> </div>
</div> </div>
...@@ -60,18 +75,22 @@ import { useRouter } from "vue-router"; ...@@ -60,18 +75,22 @@ import { useRouter } from "vue-router";
import { getStatsDataList, getSpiderTaskList, getPerformanceList } from "@/api/staticData"; import { getStatsDataList, getSpiderTaskList, getPerformanceList } from "@/api/staticData";
import { onMounted, ref } from "vue"; import { onMounted, ref } from "vue";
import formatExactLargeNum from "@/utils/formatExactLargeNum"; import formatExactLargeNum from "@/utils/formatExactLargeNum";
import { ElSkeleton } from "element-plus"; import { useSlideStateStore } from "@/store/slideState";
import { storeToRefs } from "pinia";
const slideStateStore = useSlideStateStore();
const { slideState } = storeToRefs(slideStateStore);
const router = useRouter(); const router = useRouter();
const totalDataNumber = ref(""); const totalDataNumber = ref(null);
const totalPageNumber = ref(""); const totalPageNumber = ref(null);
const totalTargetNumber = ref(""); const totalTargetNumber = ref(null);
const successTask = ref(""); const successTask = ref(null);
const failTask = ref(""); const failTask = ref(null);
const unusualTask = ref(""); const unusualTask = ref(null);
const speed = ref(""); const speed = ref(null);
const errorRate = ref(""); const errorRate = ref(null);
const unusualRate = ref(""); const unusualRate = ref(null);
const goToAllDataPage = () => { const goToAllDataPage = () => {
router.push({ router.push({
...@@ -109,6 +128,8 @@ const getData = async () => { ...@@ -109,6 +128,8 @@ const getData = async () => {
unusualRate.value = performance.data.exception; unusualRate.value = performance.data.exception;
}; };
//sidebarStatus
onMounted(() => { onMounted(() => {
getData(); getData();
}); });
...@@ -121,8 +142,7 @@ onMounted(() => { ...@@ -121,8 +142,7 @@ onMounted(() => {
background-repeat: no-repeat; background-repeat: no-repeat;
// background: #c6ebfc; // background: #c6ebfc;
// border: 1.5px solid rgb(193, 188, 188); // border: 1.5px solid rgb(193, 188, 188);
width: 360px; width: 500px;
height: 100%;
border-radius: 5px; border-radius: 5px;
} }
...@@ -134,7 +154,7 @@ onMounted(() => { ...@@ -134,7 +154,7 @@ onMounted(() => {
text-align: center; text-align: center;
text-shadow: 0 0 8px rgba(100, 200, 255, 0.8); text-shadow: 0 0 8px rgba(100, 200, 255, 0.8);
letter-spacing: 2px; letter-spacing: 2px;
margin-top: 10px; margin-top: 15px;
} }
.wordStyle { .wordStyle {
...@@ -151,9 +171,10 @@ onMounted(() => { ...@@ -151,9 +171,10 @@ onMounted(() => {
writing-mode: vertical-lr; writing-mode: vertical-lr;
font-size: 22px; font-size: 22px;
letter-spacing: 3px; letter-spacing: 3px;
margin-left: 0.5%;
color: #ffffff; color: #ffffff;
font-weight: 500; font-weight: 500;
transform: translateX(-30px);
transition: 0.2s;
} }
.total-num { .total-num {
...@@ -163,5 +184,53 @@ onMounted(() => { ...@@ -163,5 +184,53 @@ onMounted(() => {
text-shadow: 0 0 10px rgba(0, 200, 255, 0.5); text-shadow: 0 0 10px rgba(0, 200, 255, 0.5);
letter-spacing: 1px; letter-spacing: 1px;
margin-right: 30px; margin-right: 30px;
animation: visible 0.6s;
}
@keyframes visible {
0% {
opacity: 0;
}
50% {
opacity: 0.5;
}
100% {
opacity: 1;
}
}
.toRight0 {
transform: translateX(-10px);
}
.items {
display: flex;
flex-direction: column;
padding-left: 15px;
padding-top: 20px;
}
.loading {
width: 45px;
aspect-ratio: 2;
margin-right: 30px;
--_g: no-repeat radial-gradient(circle closest-side, #4edaff 90%, #0000);
background: var(--_g) 0% 50%, var(--_g) 50% 50%, var(--_g) 100% 50%;
background-size: calc(100% / 3) 50%;
animation: l3 1s infinite linear;
}
@keyframes l3 {
20% {
background-position: 0% 0%, 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%, 50% 50%, 100% 100%;
}
} }
</style> </style>
<template> <template>
<div class="flex"> <div class="flex">
<span class="textStyle">QB数据管理</span> <span class="textStyle" :class="{ toRight0: !slideState }">数据管理</span>
<!-- <div class="dataCard" @click="goToAllDataPage">
<div class="titleStyle">
<span>综合数据</span>
</div>
<div class="iconStyle" />
</div> -->
<div class="dataCard" @click="goToDSNDataPage"> <div class="dataCard" @click="goToDSNDataPage">
<div class="titleStyle"> <div class="titleStyle">
<span>DSN数据</span> <span>DSN数据</span>
...@@ -25,11 +19,22 @@ ...@@ -25,11 +19,22 @@
</div> </div>
<div class="iconStyle" /> <div class="iconStyle" />
</div> </div>
<div class="dataCard" @click="goToESADataPage">
<div class="titleStyle">
<span>ESA数据</span>
</div>
<div class="iconStyle" />
</div>
</div> </div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { useRouter } from "vue-router"; import { useRouter } from "vue-router";
import { storeToRefs } from "pinia";
import { useSlideStateStore } from "@/store/slideState";
const slideStateStore = useSlideStateStore();
const { slideState } = storeToRefs(slideStateStore);
const router = useRouter(); const router = useRouter();
defineProps({ defineProps({
...@@ -103,14 +108,23 @@ const goToSTDataPage = () => { ...@@ -103,14 +108,23 @@ const goToSTDataPage = () => {
}, },
}); });
}; };
const goToESADataPage = () => {
router.push({
path: "/osDataDisplay/list",
query: {
mode: "ESA数据",
jump: "yes",
},
});
};
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.iconStyle { .iconStyle {
background-image: url("@/assets/picture/wenjianjia.png"); background-image: url("@/assets/picture/data-icon.svg");
background-size: 100% 120%; background-size: 100% 100%;
background-repeat: no-repeat; background-repeat: no-repeat;
margin-top: -5%; margin-top: 5%;
display: flex; display: flex;
// border: 1.5px solid rgb(193, 188, 188); // border: 1.5px solid rgb(193, 188, 188);
height: 65%; height: 65%;
...@@ -118,12 +132,13 @@ const goToSTDataPage = () => { ...@@ -118,12 +132,13 @@ const goToSTDataPage = () => {
} }
.dataCard { .dataCard {
cursor: pointer;
background-image: url("@/assets/picture/box2.png"); background-image: url("@/assets/picture/box2.png");
background-size: 100% 100%; background-size: 100% 100%;
background-repeat: no-repeat; background-repeat: no-repeat;
// background: #c6ebfc; // background: #c6ebfc;
// border: 1.5px solid rgb(193, 188, 188); // border: 1.5px solid rgb(193, 188, 188);
width: 360px; width: 375px;
height: 100%; height: 100%;
border-radius: 5px; border-radius: 5px;
display: flex; display: flex;
...@@ -133,9 +148,13 @@ const goToSTDataPage = () => { ...@@ -133,9 +148,13 @@ const goToSTDataPage = () => {
} }
.titleStyle { .titleStyle {
font-size: 24px; color: #dff6ff;
margin-top: 5%; font-size: 18px;
color: #ffffff; font-weight: 600;
text-align: center;
text-shadow: 0 0 8px rgba(100, 200, 255, 0.8);
letter-spacing: 2px;
margin-top: 15px;
} }
.wordStyle { .wordStyle {
...@@ -148,9 +167,13 @@ const goToSTDataPage = () => { ...@@ -148,9 +167,13 @@ const goToSTDataPage = () => {
writing-mode: vertical-lr; writing-mode: vertical-lr;
font-size: 22px; font-size: 22px;
letter-spacing: 3px; letter-spacing: 3px;
margin-left: 0.5%;
color: #ffffff; color: #ffffff;
font-weight: 500; font-weight: 500;
// display: flex; transform: translateX(-10px);
transition: 0.2s;
}
.toRight0 {
transform: translateX(-25px);
} }
</style> </style>
...@@ -21,24 +21,23 @@ ...@@ -21,24 +21,23 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import dataCard from './dataCard.vue' import dataCard from "./dataCard.vue";
import taskCard from '@/views/os-status/components/taskCard.vue'; import taskCard from "@/views/os-status/components/taskCard.vue";
import qbCard from '@/views/os-status/components/qbDataMonitor.vue'; import qbCard from "@/views/os-status/components/qbDataMonitor.vue";
import { onMounted } from 'vue'; import { onMounted } from "vue";
defineProps({ defineProps({
title: { title: {
type: String, type: String,
default: '' default: "",
}, },
desc: { desc: {
type: String, type: String,
default: '' default: "",
} },
}) });
onMounted(() => { onMounted(() => {});
})
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
...@@ -50,14 +49,13 @@ onMounted(() => { ...@@ -50,14 +49,13 @@ onMounted(() => {
align-items: center; align-items: center;
padding: 10px; padding: 10px;
gap: 30px; gap: 30px;
} }
.monitoringCard { .monitoringCard {
background-image: url("@/assets/picture/box1.png"); background-image: url("@/assets/picture/box1.png");
background-size: 100% 100%; background-size: 100% 100%;
background-repeat: no-repeat; background-repeat: no-repeat;
height: 22.5vh; height: 20vh;
width: 96%; width: 96%;
display: flex; display: flex;
gap: 21.5px; gap: 21.5px;
...@@ -68,7 +66,7 @@ onMounted(() => { ...@@ -68,7 +66,7 @@ onMounted(() => {
background-image: url("@/assets/picture/box1.png"); background-image: url("@/assets/picture/box1.png");
background-size: 100% 100%; background-size: 100% 100%;
background-repeat: no-repeat; background-repeat: no-repeat;
height: 26.5vh; height: 25vh;
width: 96%; width: 96%;
display: flex; display: flex;
gap: 21.5px; gap: 21.5px;
...@@ -90,7 +88,7 @@ onMounted(() => { ...@@ -90,7 +88,7 @@ onMounted(() => {
font-size: 26px; font-size: 26px;
letter-spacing: 3px; letter-spacing: 3px;
margin-left: 2%; margin-left: 2%;
color: #FFFFFF; color: #ffffff;
// display: flex; // display: flex;
} }
...@@ -100,6 +98,5 @@ onMounted(() => { ...@@ -100,6 +98,5 @@ onMounted(() => {
justify-content: center; justify-content: center;
/* 水平居中 */ /* 水平居中 */
// gap: 20px; // gap: 20px;
} }
</style> </style>
\ No newline at end of file
<template> <template>
<div class="flex"> <div class="flex">
<span class="textStyle">任务统计</span> <span class="textStyle" :class="{ toRight0: slideState }">任务统计</span>
<div class="dataCard" @click="goToDSNTaskRecordPage"> <div class="dataCard" @click="goToDSNTaskRecordPage">
<div class="titleStyle"> <div class="titleStyle">
<span>DSN爬取任务</span> <span>DSN爬取任务</span>
</div> </div>
<div class="wordStyle"> <div class="items">
<span>DSN爬虫任务数:</span> <div class="wordStyle">
<span class="total-num">{{ <span>DSN爬虫任务数:</span>
dsnTotalTaskNumber !== "" ? formatExactLargeNum(dsnTotalTaskNumber) : "加载中..." <span class="total-num" v-if="dsnTotalTaskNumber != null">{{ dsnTotalTaskNumber }}</span>
}}</span> <span class="loading" v-else></span>
</div> </div>
<div class="wordStyle"> <div class="wordStyle">
<span>任务执行成功统计:</span> <span>任务执行成功统计:</span>
<span class="total-num">{{ <span class="total-num" v-if="dsnTaskSuccessNumber != null">{{ dsnTaskSuccessNumber }}</span>
dsnTaskSuccessNumber !== "" ? formatExactLargeNum(dsnTaskSuccessNumber) : "加载中..." <span class="loading" v-else></span>
}}</span> </div>
</div> <div class="wordStyle">
<div class="wordStyle"> <span>任务执行失败统计:</span>
<span>任务执行失败统计:</span> <span class="total-num" v-if="dsnTaskFailNumber != null">{{ dsnTaskFailNumber }}</span>
<span class="total-num">{{ <span class="loading" v-else></span>
dsnTaskFailNumber !== "" ? formatExactLargeNum(dsnTaskFailNumber) : "加载中..." </div>
}}</span> <div class="wordStyle">
</div> <span>错误率: {{ dsnErrorRate }} </span>
<div class="wordStyle"> <span class="total-num" v-if="dsnErrorRate != null">{{ dsnErrorRate }}</span>
<span>错误率: {{ dsnErrorRate }} </span> <span class="loading" v-else></span>
<span class="total-num">{{ dsnErrorRate !== "" ? dsnErrorRate : "加载中..." }}</span> </div>
</div> </div>
</div> </div>
<div class="dataCard" @click="goToITUTaskRecordPage"> <div class="dataCard" @click="goToITUTaskRecordPage">
<div class="titleStyle"> <div class="titleStyle">
<span>ITU爬取任务</span> <span>ITU爬取任务</span>
</div> </div>
<div class="wordStyle"> <div class="items">
<span>ITU爬虫任务数:</span> <div class="wordStyle">
<span class="total-num">{{ <span>ITU爬虫任务数:</span>
ituTotalTaskNumber !== "" ? formatExactLargeNum(ituTotalTaskNumber) : "加载中..." <span class="total-num" v-if="ituTotalTaskNumber != null">{{ ituTotalTaskNumber }}</span>
}}</span> <span class="loading" v-else></span>
</div> </div>
<div class="wordStyle"> <div class="wordStyle">
<span>任务执行成功统计:</span> <span>任务执行成功统计:</span>
<span class="total-num">{{ <span class="total-num" v-if="ituTaskSuccessNumber != null">{{ ituTaskSuccessNumber }}</span>
ituTaskSuccessNumber !== "" ? formatExactLargeNum(ituTaskSuccessNumber) : "加载中..." <span class="loading" v-else></span>
}}</span> </div>
</div> <div class="wordStyle">
<div class="wordStyle"> <span>任务执行失败统计:</span>
<span>任务执行失败统计:</span> <span class="total-num" v-if="ituTaskFailNumber != null">{{ ituTaskFailNumber }}</span>
<span class="total-num">{{ <span class="loading" v-else></span>
ituTaskFailNumber !== "" ? formatExactLargeNum(ituTaskFailNumber) : "加载中..." </div>
}}</span> <div class="wordStyle">
</div> <span>任务执行失败统计:</span>
<div class="wordStyle"> <span class="total-num" v-if="ituTaskFailNumber != null">{{ ituTaskFailNumber }}</span>
<span>错误率:</span> <span class="loading" v-else></span>
<span class="total-num">{{ ituErrorRate !== "" ? ituErrorRate : "加载中..." }}</span> </div>
<div class="wordStyle">
<span>错误率:</span>
<span class="total-num" v-if="ituErrorRate != null">{{ ituErrorRate }}</span>
<span class="loading" v-else></span>
</div>
</div> </div>
</div> </div>
<div class="dataCard" @click="goToSTTaskRecordPage"> <div class="dataCard" @click="goToSTTaskRecordPage">
<div class="titleStyle"> <div class="titleStyle">
<span>ST爬取任务</span> <span>ST爬取任务</span>
</div> </div>
<div class="wordStyle"> <div class="items">
<span>ST爬虫任务数:</span> <div class="wordStyle">
<span class="total-num">{{ <span>ST爬虫任务数:</span>
stTotalTaskNumber !== "" ? formatExactLargeNum(stTotalTaskNumber) : "加载中..." <span class="total-num" v-if="stTotalTaskNumber != null">{{ stTotalTaskNumber }}</span>
}}</span> <span class="loading" v-else></span>
</div> </div>
<div class="wordStyle"> <div class="wordStyle">
<span>任务执行成功统计:</span> <span>任务执行成功统计:</span>
<span class="total-num">{{ <span class="total-num" v-if="stTaskSuccessNumber != null">{{ stTaskSuccessNumber }}</span>
stTaskSuccessNumber !== "" ? formatExactLargeNum(stTaskSuccessNumber) : "加载中..." <span class="loading" v-else></span>
}}</span> </div>
</div> <div class="wordStyle">
<div class="wordStyle"> <span>采集速度:</span>
<span>采集速度:</span> <span class="total-num" v-if="stTaskFailNumber != null">{{ stTaskFailNumber }}</span>
<span class="total-num">{{ <span class="loading" v-else></span>
stTaskFailNumber !== "" ? formatExactLargeNum(stTaskFailNumber) : "加载中..." </div>
}}</span> <div class="wordStyle">
</div> <span>错误率:</span>
<div class="wordStyle"> <span class="total-num" v-if="stErrorRate != null">{{ stErrorRate }}</span>
<span>错误率:</span> <span class="loading" v-else></span>
<span class="total-num">{{ stErrorRate !== "" ? stErrorRate : "加载中..." }}</span> </div>
</div> </div>
</div> </div>
</div> </div>
...@@ -90,22 +95,26 @@ import { useRouter } from "vue-router"; ...@@ -90,22 +95,26 @@ import { useRouter } from "vue-router";
import { getAllSpiderTaskStatistics } from "@/api/staticData"; import { getAllSpiderTaskStatistics } from "@/api/staticData";
import { onMounted, ref } from "vue"; import { onMounted, ref } from "vue";
import { getSpiderTaskList } from "@/api/spiderTask"; import { getSpiderTaskList } from "@/api/spiderTask";
import formatExactLargeNum from "@/utils/formatExactLargeNum"; import { useSlideStateStore } from "@/store/slideState";
import { storeToRefs } from "pinia";
const slideStateStore = useSlideStateStore();
const { slideState } = storeToRefs(slideStateStore);
const router = useRouter(); const router = useRouter();
const dsnTotalTaskNumber = ref(""); const dsnTotalTaskNumber = ref(null);
const dsnTaskSuccessNumber = ref(""); const dsnTaskSuccessNumber = ref(null);
const dsnTaskFailNumber = ref(""); const dsnTaskFailNumber = ref(null);
const dsnErrorRate = ref(""); const dsnErrorRate = ref(null);
const ituTotalTaskNumber = ref(""); const ituTotalTaskNumber = ref(null);
const ituTaskSuccessNumber = ref(""); const ituTaskSuccessNumber = ref(null);
const ituTaskFailNumber = ref(""); const ituTaskFailNumber = ref(null);
const ituErrorRate = ref(""); const ituErrorRate = ref(null);
const stTotalTaskNumber = ref(""); const stTotalTaskNumber = ref(null);
const stTaskSuccessNumber = ref(""); const stTaskSuccessNumber = ref(null);
const stTaskFailNumber = ref(""); const stTaskFailNumber = ref(null);
const stErrorRate = ref(""); const stErrorRate = ref(null);
const goToDSNTaskRecordPage = () => { const goToDSNTaskRecordPage = () => {
router.push({ router.push({
...@@ -169,7 +178,7 @@ onMounted(() => { ...@@ -169,7 +178,7 @@ onMounted(() => {
background-repeat: no-repeat; background-repeat: no-repeat;
// background: #c6ebfc; // background: #c6ebfc;
// border: 1.5px solid rgb(193, 188, 188); // border: 1.5px solid rgb(193, 188, 188);
width: 360px; width: 500px;
height: 100%; height: 100%;
border-radius: 5px; border-radius: 5px;
} }
...@@ -181,7 +190,7 @@ onMounted(() => { ...@@ -181,7 +190,7 @@ onMounted(() => {
text-align: center; text-align: center;
text-shadow: 0 0 8px rgba(100, 200, 255, 0.8); text-shadow: 0 0 8px rgba(100, 200, 255, 0.8);
letter-spacing: 2px; letter-spacing: 2px;
margin-top: 10px; margin-top: 15px;
} }
.wordStyle { .wordStyle {
...@@ -198,9 +207,10 @@ onMounted(() => { ...@@ -198,9 +207,10 @@ onMounted(() => {
writing-mode: vertical-lr; writing-mode: vertical-lr;
font-size: 22px; font-size: 22px;
letter-spacing: 3px; letter-spacing: 3px;
margin-left: 0.5%;
color: #ffffff; color: #ffffff;
font-weight: 500; font-weight: 500;
transform: translateX(-25px);
transition: 0.2s;
} }
.total-num { .total-num {
...@@ -210,5 +220,53 @@ onMounted(() => { ...@@ -210,5 +220,53 @@ onMounted(() => {
text-shadow: 0 0 10px rgba(0, 200, 255, 0.5); text-shadow: 0 0 10px rgba(0, 200, 255, 0.5);
letter-spacing: 1px; letter-spacing: 1px;
margin-right: 30px; margin-right: 30px;
animation: visible 0.6s;
}
.toRight0 {
transform: translateX(-10px);
}
.items {
display: flex;
flex-direction: column;
padding-left: 15px;
padding-top: 20px;
}
.loading {
width: 45px;
aspect-ratio: 2;
margin-right: 30px;
--_g: no-repeat radial-gradient(circle closest-side, #4edaff 90%, #0000);
background: var(--_g) 0% 50%, var(--_g) 50% 50%, var(--_g) 100% 50%;
background-size: calc(100% / 3) 50%;
animation: l3 1s infinite linear;
}
@keyframes l3 {
20% {
background-position: 0% 0%, 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%, 50% 50%, 100% 100%;
}
}
@keyframes visible {
0% {
opacity: 0;
}
50% {
opacity: 0.5;
}
100% {
opacity: 1;
}
} }
</style> </style>
<template> <template>
<div> <div>
<MenuTitle title="状态监控" subtitle="Status Monitor" />
<div> <div>
<el-card style="margin-bottom: 0">
<div class="title">状态监控</div>
<div class="low-titme">Status Monitor</div>
<el-divider class="divider" style="margin-bottom: 0" />
</el-card>
<div class="text-left timeStyle" /> <div class="text-left timeStyle" />
<div class="border-100"> <div class="border-100">
<statusMonitor /> <statusMonitor />
...@@ -16,6 +12,7 @@ ...@@ -16,6 +12,7 @@
<script setup lang="ts"> <script setup lang="ts">
import statusMonitor from "./components/statusMonitor.vue"; import statusMonitor from "./components/statusMonitor.vue";
import MenuTitle from "@/components/MenuTitle.vue";
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
......
<template> <template>
<div class="sys-content"> <div class="sys-content">
<MenuTitle title="系统管理" subtitle="System Manager" />
<el-card> <el-card>
<div class="title">系统管理</div>
<div class="low-titme">System Manager</div>
<el-divider class="divider" />
<div class="btns"> <div class="btns">
<el-button test-element="userSystem-AddUser" type="primary" plain @click="openAddUserDialog" <el-button test-element="userSystem-AddUser" type="primary" plain @click="openAddUserDialog"
>创建用户</el-button >创建用户</el-button
...@@ -86,6 +84,7 @@ import { getUserList } from "@/api/user.ts"; ...@@ -86,6 +84,7 @@ import { getUserList } from "@/api/user.ts";
import { DeleteMode } from "@/components/Delete/enum.ts"; import { DeleteMode } from "@/components/Delete/enum.ts";
import { AddMode } from "./components/enum.ts"; import { AddMode } from "./components/enum.ts";
import { ElMessage } from "element-plus"; import { ElMessage } from "element-plus";
import MenuTitle from "@/components/MenuTitle.vue";
const userId = ref<number>(-1); const userId = ref<number>(-1);
const userIds = ref<number[]>([]); const userIds = ref<number[]>([]);
const nickName = ref<string>(""); const nickName = ref<string>("");
......
<!-- 任务执行统计卡片组件 --> <!-- 任务执行统计卡片组件 -->
<template> <template>
<div> <div>
<div class="m-t-2" /> <TableSearch>
<div class="text-left p-4 toolbarStyle"> <div class="form-content">
<div class="formStyle"> <div class="ipt">
<el-form inline> <span style="color: white">所属爬虫:</span>
<el-row> <el-select
<el-col :span="16" style="display: flex; padding-left: 40px"> v-model="searchCondition.spiders"
<el-form-item label="所属爬虫:"> placeholder="请选择"
<div> style="width: 220px"
<el-select :disabled="!taskSelectOptions.length"
v-model="searchCondition.spiders" >
placeholder="请选择" <el-option
style="width: 220px" v-for="item in taskSelectOptions || []"
:disabled="!taskSelectOptions.length" :key="item?.spider"
> :label="item?.spider || '未知'"
<el-option :value="item?.spider"
v-for="item in taskSelectOptions || []" />
:key="item?.spider" </el-select>
:label="item?.spider || '未知'" </div>
:value="item?.spider" <div class="btns">
/> <el-button plain type="primary" @click="search">查询</el-button>
</el-select> <el-button @click="resetData" style="margin-right: 20px">重置</el-button>
</div> <el-button plain type="primary" @click="openTaskDialog">新建任务</el-button>
</el-form-item> </div>
</el-col>
<el-col :span="8" style="display: flex; justify-content: end">
<el-form-item>
<el-button plain type="primary" @click="search">查询</el-button>
<el-button @click="resetData" style="margin-right: 20px">重置</el-button>
<el-button plain type="primary" @click="openTaskDialog">新建任务</el-button>
</el-form-item>
</el-col>
</el-row>
</el-form>
</div> </div>
</div> </TableSearch>
<div class="cardStyle"> <div class="cardStyle">
<div v-if="taskList.length === 0 && !isLoading" class="empty-tip">暂无任务数据</div> <div v-if="taskList.length === 0 && !isLoading" class="empty-tip">暂无任务数据</div>
<div <div
v-loading="taskList.length == 0" v-loading="taskList.length == 0"
element-loading-background="rgba(48, 65, 86, 0.7)" element-loading-background="rgba(48, 65, 86, 0.7)"
class="taskCard p-6" class="taskCard p-2"
v-for="task in taskList || []" v-for="task in taskList || []"
:key="task?.id || task?.taskId" :key="task?.id || task?.taskId"
> >
...@@ -81,7 +71,6 @@ ...@@ -81,7 +71,6 @@
</div> </div>
</div> </div>
</div> </div>
<addTaskDialog <addTaskDialog
v-model:dialogVisible="showTaskDialog" v-model:dialogVisible="showTaskDialog"
@confirm="handleEdit" @confirm="handleEdit"
...@@ -108,6 +97,7 @@ import deleteDialog from "./deleteDialog.vue"; ...@@ -108,6 +97,7 @@ import deleteDialog from "./deleteDialog.vue";
import { ElMessage } from "element-plus"; import { ElMessage } from "element-plus";
import { getSpiderList } from "@/api/system.ts"; import { getSpiderList } from "@/api/system.ts";
import formatExactLargeNum from "@/utils/formatExactLargeNum"; import formatExactLargeNum from "@/utils/formatExactLargeNum";
import TableSearch from "@/components/TableSearch.vue";
const props = defineProps({ const props = defineProps({
spiderType: { spiderType: {
...@@ -343,7 +333,6 @@ onMounted(() => { ...@@ -343,7 +333,6 @@ onMounted(() => {
color: white; color: white;
} }
.cardStyle { .cardStyle {
margin-top: 1.5%;
padding: 18px; padding: 18px;
gap: 15px; gap: 15px;
width: auto !important; width: auto !important;
...@@ -363,6 +352,8 @@ onMounted(() => { ...@@ -363,6 +352,8 @@ onMounted(() => {
.task-name { .task-name {
color: #fff !important; color: #fff !important;
font-size: 18px;
font-weight: 500;
} }
/* 任务卡片样式 */ /* 任务卡片样式 */
...@@ -371,7 +362,6 @@ onMounted(() => { ...@@ -371,7 +362,6 @@ onMounted(() => {
background-size: 100% 100%; background-size: 100% 100%;
background-repeat: no-repeat; background-repeat: no-repeat;
font-size: 20px; font-size: 20px;
min-height: 240px;
min-width: 300px; min-width: 300px;
border-radius: 7px; border-radius: 7px;
} }
...@@ -431,4 +421,16 @@ onMounted(() => { ...@@ -431,4 +421,16 @@ onMounted(() => {
color: #fff; color: #fff;
padding: 50px 0; padding: 50px 0;
} }
.header {
margin-top: 10px;
}
.form-content {
height: 80px;
padding: 0 30px;
justify-content: space-between;
display: flex;
align-items: center;
}
</style> </style>
<template> <template>
<div> <div>
<el-card style="margin-bottom: 0"> <MenuTitle title="任务信息" subtitle="Task Information" />
<div class="title">任务信息</div>
<div class="low-titme">Task Information</div>
<el-divider class="divider" style="margin-bottom: 0" />
</el-card>
<div class="backStyle" v-if="route.query.jump === 'yes'" @click="goToTaskInformation" /> <div class="backStyle" v-if="route.query.jump === 'yes'" @click="goToTaskInformation" />
<div class="m-t-8" /> <div class="m-t-8" />
<div> <div>
...@@ -18,6 +14,7 @@ import { ref } from "vue"; ...@@ -18,6 +14,7 @@ import { ref } from "vue";
import taskCard from "./components/taskCard.vue"; import taskCard from "./components/taskCard.vue";
import { useRouter } from "vue-router"; import { useRouter } from "vue-router";
import { useRoute } from "vue-router"; import { useRoute } from "vue-router";
import MenuTitle from "@/components/MenuTitle.vue";
const route = useRoute(); const route = useRoute();
const router = useRouter(); const router = useRouter();
......
<template> <template>
<div> <div>
<el-card style="margin-bottom: 0"> <MenuTitle title="任务执行记录" subtitle="Task Record" />
<div class="title">任务执行记录</div>
<div class="low-titme">Task Record</div>
<el-divider class="divider" style="margin-bottom: 0" />
</el-card>
<div class="backStyle" v-if="route.query.jump === 'yes'" @click="goToStatus" /> <div class="backStyle" v-if="route.query.jump === 'yes'" @click="goToStatus" />
<div class="m-t-7" /> <div class="m-t-8" />
<div class="text-left toolbarStyle"> <table-search>
<div class="formStyle"> <div class="form-content">
<div class="form-content"> <div class="timer">
<el-form inline> <span style="color: white">时间:</span>
<el-row> <el-config-provider :locale="zhCn">
<el-col :span="12"> <el-date-picker
<el-form-item label="时间:"> v-model="timeValue"
<el-config-provider :locale="zhCn"> type="datetimerange"
<el-date-picker start-placeholder="开始时间"
v-model="timeValue" end-placeholder="结束时间"
type="datetimerange" format="YYYY-MM-DD HH:mm:ss"
start-placeholder="开始时间" date-format="YYYY/MM/DD ddd"
end-placeholder="结束时间" time-format="A hh:mm:ss"
format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss"
date-format="YYYY/MM/DD ddd" />
time-format="A hh:mm:ss" </el-config-provider>
value-format="YYYY-MM-DD HH:mm:ss" </div>
/> <div class="btns">
</el-config-provider> <el-button plain type="primary" @click="searchData">查询</el-button>
</el-form-item> <el-button plain @click="getData">重置</el-button>
</el-col>
<el-col :span="12" style="display: flex; justify-content: end">
<el-form-item>
<el-button plain type="primary" @click="searchData">查询</el-button>
<el-button plain @click="getData">重置</el-button>
</el-form-item>
</el-col>
</el-row>
</el-form>
</div> </div>
</div> </div>
</div> </table-search>
<div class="m-t-10" />
<div class="table-content"> <div class="table-content">
<div> <div>
<el-table <el-table
...@@ -93,6 +79,8 @@ import { useRoute } from "vue-router"; ...@@ -93,6 +79,8 @@ import { useRoute } from "vue-router";
import { useRouter } from "vue-router"; import { useRouter } from "vue-router";
import { getSpiderTaskRecord } from "@/api/spiderTask.ts"; import { getSpiderTaskRecord } from "@/api/spiderTask.ts";
import { ElMessage } from "element-plus"; import { ElMessage } from "element-plus";
import MenuTitle from "@/components/MenuTitle.vue";
import TableSearch from "@/components/TableSearch.vue";
// ElConfigProvider 组件 // ElConfigProvider 组件
import { ElConfigProvider } from "element-plus"; import { ElConfigProvider } from "element-plus";
// 引入中文包 // 引入中文包
...@@ -203,11 +191,7 @@ onMounted(() => { ...@@ -203,11 +191,7 @@ onMounted(() => {
.table-content { .table-content {
padding: 0 10px; padding: 0 10px;
} margin-top: 18px;
.form-content {
margin-top: 20px;
padding-left: 50px;
} }
.backStyle { .backStyle {
...@@ -235,6 +219,14 @@ onMounted(() => { ...@@ -235,6 +219,14 @@ onMounted(() => {
.divider { .divider {
margin-top: 15px; margin-top: 15px;
} }
.form-content {
height: 80px;
justify-content: space-between;
display: flex;
align-items: center;
padding: 0 30px;
}
</style> </style>
<style> <style>
/* 修改el选择器的样式 */ /* 修改el选择器的样式 */
......
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