mirror of
https://github.com/certd/certd.git
synced 2026-05-18 14:27:36 +08:00
perf: 首页证书数量支持点击跳转
This commit is contained in:
@@ -167,6 +167,7 @@ function useMixedMenu() {
|
|||||||
* @param path 路由路径
|
* @param path 路由路径
|
||||||
*/
|
*/
|
||||||
function calcSideMenus(path: string = route.path) {
|
function calcSideMenus(path: string = route.path) {
|
||||||
|
debugger;
|
||||||
let { rootMenu } = findRootMenuByPath(menus.value, path);
|
let { rootMenu } = findRootMenuByPath(menus.value, path);
|
||||||
if (!rootMenu) {
|
if (!rootMenu) {
|
||||||
rootMenu = menus.value.find((item: any) => item.path === path);
|
rootMenu = menus.value.find((item: any) => item.path === path);
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
import type { RouteRecordNormalized } from "vue-router";
|
import type { RouteRecordNormalized } from "vue-router";
|
||||||
|
|
||||||
import { useRouter } from "vue-router";
|
import { useRoute, useRouter } from "vue-router";
|
||||||
|
|
||||||
import { isHttpUrl, openRouteInNewWindow, openWindow } from "../../../utils";
|
import { isHttpUrl, openRouteInNewWindow, openWindow } from "../../../utils";
|
||||||
|
|
||||||
function useNavigation() {
|
function useNavigation() {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
const route1 = useRoute();
|
||||||
const routes = router.getRoutes();
|
const routes = router.getRoutes();
|
||||||
|
|
||||||
const routeMetaMap = new Map<string, RouteRecordNormalized>();
|
const routeMetaMap = new Map<string, RouteRecordNormalized>();
|
||||||
@@ -15,6 +16,9 @@ function useNavigation() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const navigation = async (path: string) => {
|
const navigation = async (path: string) => {
|
||||||
|
if (route1.path === path) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const route = routeMetaMap.get(path);
|
const route = routeMetaMap.get(path);
|
||||||
const { openInNewWindow = false, query = {} as any } = route?.meta ?? {};
|
const { openInNewWindow = false, query = {} as any } = route?.meta ?? {};
|
||||||
if (isHttpUrl(path)) {
|
if (isHttpUrl(path)) {
|
||||||
|
|||||||
@@ -33,7 +33,6 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
|||||||
const res = await api.AddObj(form);
|
const res = await api.AddObj(form);
|
||||||
return res;
|
return res;
|
||||||
};
|
};
|
||||||
const { openCrudFormDialog } = useFormWrapper();
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
const settingStore = useSettingStore();
|
const settingStore = useSettingStore();
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<template #header>
|
<template #header>
|
||||||
<div class="title">
|
<div class="title">
|
||||||
{{ t("certd.myPipelines") }}
|
{{ t("certd.myPipelines") }}
|
||||||
<div class="sub">{{ t("certd.pipelinePage.myPipelinesDesc") }}</div>
|
<span class="sub">{{ t("certd.pipelinePage.myPipelinesDesc") }}</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<!-- <a-alert v-if="settingStore.sysPublic.notice" type="warning" show-icon>
|
<!-- <a-alert v-if="settingStore.sysPublic.notice" type="warning" show-icon>
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-if="data.length !== 0" class="expiring-pipeline-list">
|
<div v-if="data.length !== 0" class="expiring-pipeline-list">
|
||||||
<div v-for="item of data" class="pipeline-row">
|
<div v-for="item of data" :key="item.id" class="pipeline-row">
|
||||||
<div class="title" :title="item.title">
|
<div class="title" :title="item.title">
|
||||||
<pi-status-show :status="item.status"></pi-status-show> <a @click="goDetail(item)">{{ item.title }}</a>
|
<pi-status-show :status="item.status"></pi-status-show> <a @click="goDetail(item)">{{ item.title }}</a>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -67,7 +67,7 @@
|
|||||||
<div class="statistic-data m-20">
|
<div class="statistic-data m-20">
|
||||||
<a-row :gutter="20" class="flex-wrap">
|
<a-row :gutter="20" class="flex-wrap">
|
||||||
<a-col :md="6" :xs="24">
|
<a-col :md="6" :xs="24">
|
||||||
<statistic-card icon="fluent-color:data-line-24" :title="t('certd.dashboard.pipelineCount')" :count="count.pipelineCount" :sub-counts="count.pipelineEnableCount">
|
<statistic-card icon="fluent-color:data-line-24" :title="t('certd.dashboard.pipelineCount')" :count="count.pipelineCount" link="/certd/pipeline" :sub-counts="count.pipelineEnableCount">
|
||||||
<template v-if="count.pipelineCount === 0" #default>
|
<template v-if="count.pipelineCount === 0" #default>
|
||||||
<div class="flex-center flex-1 flex-col">
|
<div class="flex-center flex-1 flex-col">
|
||||||
<div style="font-size: 18px; font-weight: 700">{{ t("certd.dashboard.noPipeline") }}</div>
|
<div style="font-size: 18px; font-weight: 700">{{ t("certd.dashboard.noPipeline") }}</div>
|
||||||
@@ -85,7 +85,7 @@
|
|||||||
</statistic-card>
|
</statistic-card>
|
||||||
</a-col> -->
|
</a-col> -->
|
||||||
<a-col :md="6" :xs="24">
|
<a-col :md="6" :xs="24">
|
||||||
<statistic-card icon="fluent-color:certificate-24" :title="t('certd.dashboard.certCount')" :count="count.certCount" :sub-counts="count.certStatusCount">
|
<statistic-card icon="fluent-color:certificate-24" :title="t('certd.dashboard.certCount')" :count="count.certCount" link="/certd/monitor/cert" :sub-counts="count.certStatusCount">
|
||||||
<template v-if="count.certCount === 0" #default>
|
<template v-if="count.certCount === 0" #default>
|
||||||
<div class="flex-center flex-1 flex-col">
|
<div class="flex-center flex-1 flex-col">
|
||||||
<div style="font-size: 18px; font-weight: 700">{{ t("certd.dashboard.noCert") }}</div>
|
<div style="font-size: 18px; font-weight: 700">{{ t("certd.dashboard.noCert") }}</div>
|
||||||
@@ -216,6 +216,9 @@ const siteInfo: Ref<SiteInfo> = computed(() => {
|
|||||||
return settingStore.siteInfo;
|
return settingStore.siteInfo;
|
||||||
});
|
});
|
||||||
const settingsStore = useSettingStore();
|
const settingsStore = useSettingStore();
|
||||||
|
const defaultExpireDays = computed(() => {
|
||||||
|
return settingsStore.sysPublic.defaultCertRenewDays || settingsStore.sysPublic.defaultWillExpireDays || 15;
|
||||||
|
});
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
const userInfo: ComputedRef<UserInfoRes> = computed(() => {
|
const userInfo: ComputedRef<UserInfoRes> = computed(() => {
|
||||||
return userStore.getUserInfo;
|
return userStore.getUserInfo;
|
||||||
@@ -266,9 +269,16 @@ function transformStatusCount() {
|
|||||||
];
|
];
|
||||||
const certCount = count.value.certCount;
|
const certCount = count.value.certCount;
|
||||||
count.value.certStatusCount = [
|
count.value.certStatusCount = [
|
||||||
{ name: t("certd.dashboard.certExpiredCount"), value: certCount.expired, color: "red", checkIcon: "mingcute:warning-fill:#f44336" },
|
{ name: t("certd.dashboard.certExpiredCount"), value: certCount.expired, color: "red", checkIcon: "mingcute:warning-fill:#f44336", link: { path: "/certd/monitor/cert", query: { expireStatus: "expired" } } },
|
||||||
{ name: t("certd.dashboard.certExpiringCount"), value: certCount.expiring, color: "yellow", checkIcon: "mingcute:alert-fill:#ff9800", title: "到期不足15天" },
|
{
|
||||||
{ name: t("certd.dashboard.certNoExpireCount"), value: certCount.notExpired, color: "green" },
|
name: t("certd.dashboard.certExpiringCount"),
|
||||||
|
value: certCount.expiring,
|
||||||
|
color: "yellow",
|
||||||
|
checkIcon: "mingcute:alert-fill:#ff9800",
|
||||||
|
title: `到期不足${defaultExpireDays.value}天`,
|
||||||
|
link: { path: "/certd/monitor/cert", query: { expireStatus: "expiring" } },
|
||||||
|
},
|
||||||
|
{ name: t("certd.dashboard.certNoExpireCount"), value: certCount.notExpired, color: "green", link: { path: "/certd/monitor/cert", query: { expireStatus: "noExpired" } } },
|
||||||
];
|
];
|
||||||
count.value.certCount = certCount.total;
|
count.value.certCount = certCount.total;
|
||||||
}
|
}
|
||||||
@@ -380,6 +390,12 @@ const { tour, tourHandleOpen } = useTour();
|
|||||||
|
|
||||||
<style lang="less">
|
<style lang="less">
|
||||||
.dashboard-user {
|
.dashboard-user {
|
||||||
|
.ant-card-head {
|
||||||
|
padding: 0px 18px;
|
||||||
|
}
|
||||||
|
.ant-card-body {
|
||||||
|
padding: 15px 18px;
|
||||||
|
}
|
||||||
.warning {
|
.warning {
|
||||||
.ant-alert {
|
.ant-alert {
|
||||||
border-left: 0;
|
border-left: 0;
|
||||||
|
|||||||
@@ -12,13 +12,13 @@
|
|||||||
<div class="content">
|
<div class="content">
|
||||||
<div v-if="!slots.default" class="statistic">
|
<div v-if="!slots.default" class="statistic">
|
||||||
<div v-if="count !== 0" class="value flex items-center w-full">
|
<div v-if="count !== 0" class="value flex items-center w-full">
|
||||||
<div class="total flex-center flex-1 flex-col">
|
<div class="total flex-center flex-1 flex-col pointer" @click="goDetail(link)">
|
||||||
<span>{{ count }}</span>
|
<span>{{ count }}</span>
|
||||||
<span class="sub-title">{{ title }}</span>
|
<span class="sub-title">{{ title }}</span>
|
||||||
</div>
|
</div>
|
||||||
<a-divider type="vertical h-10"></a-divider>
|
<a-divider type="vertical h-10"></a-divider>
|
||||||
<div class="sub flex-1 flex-col h-[80%] flex-evenly pl-4">
|
<div class="sub flex-1 flex-col h-[80%] flex-evenly pl-1 2xl:pl-4">
|
||||||
<div v-for="item in subCounts" :key="item.name" class="sub-item flex justify-center w-full" :title="item.title">
|
<div v-for="item in subCounts" :key="item.name" class="sub-item flex justify-center w-full pointer" :title="item.title" @click="goDetail(item.link)">
|
||||||
<div class="flex items-center w-[60%] ellipsis overflow-hidden">
|
<div class="flex items-center w-[60%] ellipsis overflow-hidden">
|
||||||
<div class="status-indicator" :class="`bg-${item.color}`"></div>
|
<div class="status-indicator" :class="`bg-${item.color}`"></div>
|
||||||
{{ item.name }}:
|
{{ item.name }}:
|
||||||
@@ -45,27 +45,37 @@
|
|||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { FsIcon } from "@fast-crud/fast-crud";
|
import { FsIcon } from "@fast-crud/fast-crud";
|
||||||
|
import { useRouter } from "vue-router";
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
icon: string;
|
icon: string;
|
||||||
title: string;
|
title: string;
|
||||||
count?: number;
|
count?: number;
|
||||||
|
link?: any;
|
||||||
subCounts?: {
|
subCounts?: {
|
||||||
name: string;
|
name: string;
|
||||||
value: number;
|
value: number;
|
||||||
color: string;
|
color: string;
|
||||||
checkIcon?: string;
|
checkIcon?: string;
|
||||||
title?: string;
|
title?: string;
|
||||||
|
link?: any;
|
||||||
}[];
|
}[];
|
||||||
}>();
|
}>();
|
||||||
const slots = defineSlots();
|
const slots = defineSlots();
|
||||||
|
const router = useRouter();
|
||||||
|
function goDetail(link: any) {
|
||||||
|
if (!link) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (typeof link === "string") {
|
||||||
|
router.push({ path: link });
|
||||||
|
} else {
|
||||||
|
router.push(link);
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
<style lang="less">
|
<style lang="less">
|
||||||
.statistic-card {
|
.statistic-card {
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
|
|
||||||
.ant-card-body {
|
|
||||||
padding: 15px 24px;
|
|
||||||
}
|
|
||||||
.icon-text {
|
.icon-text {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
justify-content: left;
|
justify-content: left;
|
||||||
|
|||||||
Reference in New Issue
Block a user